; * MEMORYA.ASM - Contains low level memory handling functions. ; * Copyright (C) 1998, 1999 Prashant TR ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * See the file COPYING.TR for more details. _TEXT SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_TEXT, DS:NOTHING .386P PUBLIC _make_large_sel, _make_normal_sel, _a20, _time_memory PUBLIC _get_memory_size, _time_no_cache_memory, _check_pm_controller GDT DB 0, 0, 0, 0, 0, 0, 0, 0 ; Null Selector. DB 0FFH, 0FFH, 0, 0, 0, 92H, 8FH, 0 ; 4G Selector. DB 0FFH, 0FFH, 0, 0, 0, 93H, 0 , 0 ; 64K Selector. GDTPTR EQU THIS FWORD GDTLEN DW ? GDTADD DD ? _check_pm_controller PROC FAR PUSH EBX PUSH ECX PUSH EDX PUSH ESI ; Detect PCI bus. MOV AX, 0B101H INT 1AH OR AH, AH JNZ _no_pmc CMP EDX, 20494350H JNZ _no_pmc JC _no_pmc MOV AX, 0B102H MOV CX, 7113H MOV DX, 8086H XOR SI, SI INT 1AH JC _no_pmc POP ESI POP EDX POP ECX POP EBX MOV AX, 1 RET _no_pmc: POP ESI POP EDX POP ECX POP EBX XOR AX, AX RET _check_pm_controller ENDP _make_large_sel PROC FAR SMSW AX AND AX, 1 JNZ _large_sel_return ; Load the GDT. MOV AX, SEG GDT MOVZX EAX, AX SHL EAX, 4 XOR EBX, EBX MOV BX, OFFSET GDT ADD EAX, EBX MOV CS:[GDTADD], EAX MOV CS:[GDTLEN], 17H LGDT CS:[GDTPTR] ; Switch to protected mode. PUSH DS MOV EAX, CR0 OR AL, 1 MOV CR0, EAX JMP SHORT nxtlbl_1 nxtlbl_1: MOV AX, 8 MOV DS, AX MOV ES, AX ; Come back to real mode. MOV EAX, CR0 AND AL, 0FEH MOV CR0, EAX JMP SHORT nxtlbl_2 nxtlbl_2: POP DS MOV AX, 1 RET _large_sel_return: DEC AX NEG AX RET _make_large_sel ENDP _make_normal_sel PROC FAR SMSW AX AND AX, 1 JNZ _normal_sel_return ; Load the GDT. MOV AX, SEG GDT MOVZX EAX, AX SHL EAX, 4 XOR EBX, EBX MOV BX, OFFSET GDT ADD EAX, EBX MOV CS:[GDTADD], EAX MOV CS:[GDTLEN], 0FFH LGDT CS:[GDTPTR] ; Switch to protected mode. PUSH DS MOV EAX, CR0 OR AL, 1 MOV CR0, EAX JMP SHORT nxtlbl_3 nxtlbl_3: MOV AX, 10H MOV DS, AX MOV ES, AX ; Come back to real mode. MOV EAX, CR0 AND AL, 0FEH MOV CR0, EAX JMP SHORT nxtlbl_4 nxtlbl_4: POP DS MOV AX, 1 RET _normal_sel_return: DEC AX NEG AX RET _make_normal_sel ENDP _keywait PROC XOR CX, CX _a20_output_buffer: IN AL, 64H TEST AL, 2 LOOPNZ _a20_output_buffer RET _keywait ENDP _a20 PROC FAR PUSH BP MOV BP, SP ; Wait for output buffer full. CALL _keywait OR CX, CX JZ _a20_error ; Enable A20. MOV AL, 0D1H OUT 64H, AL OR CX, CX JZ _a20_error CMP WORD PTR [BP + 6], 0 JNZ _a20_enable_signal MOV AL, 0DDH JMP _a20_signal _a20_enable_signal: MOV AL, 0DFH _a20_signal: OUT 60H, AL CALL _keywait OR CX, CX JZ _a20_error MOV AX, 1 POP BP RET _a20_error: XOR AX, AX POP BP RET _a20 ENDP _start_timer PROC MOV AL,0B6H OUT 43H,AL XOR AX, AX OUT 42H,AL MOV AL,AL OUT 42H,AL IN AL,61H OR AL,1 OUT 61H,AL RET _start_timer ENDP _stop_timer PROC MOV AX,86H OUT 43H,AL IN AL,61H AND AL,0FCH OUT 61H,AL IN AL,42H MOV AH,AL IN AL,42H XCHG AL, AH MOVZX EAX, AX NEG AX SHR AX, 1 RET _stop_timer ENDP _time_memory PROC FAR PUSH BP MOV BP, SP PUSH DS PUSH SI CLD XOR AX, AX MOV DS, AX MOV ESI, 100000H MOV ECX, 100000H SHR ECX, 2 REP LODS DWORD PTR DS:[ESI] MOV EDX, ECX XOR EBX, EBX CLI MOV CX, 2 _read_mem_loop: PUSH CX MOV ESI, [BP + 6] MOV ECX, [BP + 10] SHR ECX, 2 MOV EDX, ECX XOR EBX, EBX CMP ECX, 4096 JB _read_memory MOV ECX, 4096 _read_memory: SUB EDX, ECX CALL _start_timer REP LODS DWORD PTR DS:[ESI] CALL _stop_timer ADD EBX, EAX MOV ECX, 4096 OR EDX, EDX JZ _memory_read_over CMP EDX, 4096 JNB _read_memory MOV ECX, EDX JMP _read_memory _memory_read_over: POP CX LOOP _read_mem_loop STI POP SI POP DS MOV AX, BX SHR EBX, 16 MOV DX, BX POP BP RET _time_memory ENDP _time_no_cache_memory PROC FAR PUSH BP MOV BP, SP PUSH DS PUSH SI CLD XOR AX, AX MOV DS, AX MOV ESI, 100000H MOV ECX, 100000H SHR ECX, 2 REP LODS DWORD PTR DS:[ESI] MOV EDX, ECX XOR EBX, EBX CLI MOV ESI, [BP + 6] MOV ECX, [BP + 10] SHR ECX, 2 MOV EDX, ECX XOR EBX, EBX CMP ECX, 4096 JB _cread_memory MOV ECX, 4096 _cread_memory: SUB EDX, ECX CALL _start_timer REP LODS DWORD PTR DS:[ESI] CALL _stop_timer ADD EBX, EAX MOV ECX, 4096 OR EDX, EDX JZ _cmemory_read_over CMP EDX, 4096 JNB _cread_memory MOV ECX, EDX JMP _cread_memory _cmemory_read_over: STI POP SI POP DS MOV AX, BX SHR EBX, 16 MOV DX, BX POP BP RET _time_no_cache_memory ENDP _get_memory_size PROC FAR XOR AX, AX MOV ES, AX MOV EBX, 100000H _read_memory_forcibly: MOV EAX, ES:[EBX] MOV ECX, EAX INC EAX MOV ES:[EBX], EAX MOV EAX, ES:[EBX] CMP EAX, ECX JZ _memory_read_force_over MOV ES:[EBX], ECX ADD EBX, 1024 JMP _read_memory_forcibly _memory_read_force_over: MOV AX, BX SHR EBX, 16 MOV DX, BX RET _get_memory_size ENDP _TEXT ENDS END