Nightloader/i386/loader/src-asm/memory/a20.asm

96 lines
2.3 KiB
NASM
Raw Normal View History

check_a20_wraparound:
.prolog:
push dword esi
sub esp, 64
mov esi, esp
; EAX is used for the return value,
; so it doesn't have to be preserved.
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], edi
.test_a20:
; Save the values which are going to be overwritten
mov edi, 0x0800
mov eax, [edi]
mov edi, 0x00100800
mov ebx, [edi]
; Write to two locations which, if A20 wraps around,
; will both be written to by the second statement.
; Write 0 to 0x08000 to avoid the unlikely case that
; those bytes are there coincidentally and A20 is on.
mov edi, 0x0800
mov [edi], dword 0x00000000
mov edi, 0x00100800
mov [edi], dword 0xffaa00dd
; Check the lower address (which should NOT contain)
; this value for the value. If it does contain it, the
; memory space wraps around to 0 every 2^19 bytes.
cmp [0x0800], dword 0xffaa00dd
je .return_a20_not_enabled ; If the value at 0x0800
; was written to instead
; (or at the same time) of
; writing to 0x100800,
; the A20 wasn't enabled.
; Reset the values at the addresses to which the test
; values were written znd return that A20 is enabled.
mov edi, 0x0800
mov [edi], eax
mov edi, 0x00100800
mov [edi], ebx
.return_a20_enabled:
mov eax, 1
; Restore the one used register which
; doesn't contain the return value.
mov ebx, [esi + (64 - 8)]
add esp, 64
pop dword esi
ret
.return_a20_not_enabled:
; It's only necessary to write to one of the addresses
; as both of them are equal either way.
mov edi, 0x0800
mov [edi], eax
mov eax, 0
; Restore the one used register which
; doesn't contain the return value.
mov ebx, [esi + (64 - 12)]
mov edi, [esi + (64 - 8)]
add esp, 64
pop dword esi
ret
enable_a20_through_keyboard_controller:
.prolog:
push dword esi
sub esp, 64
mov esi, esp
mov [esi + (64 - 8)], ebx
mov [esi + (64 - 12)], ecx
mov [esi + (64 - 16)], edx
mov [esi + (64 - 20)], edi
.epilog:
mov ebx, [esi + (64 - 8)]
mov ecx, [esi + (64 - 12)]
mov edx, [esi + (64 - 16)]
mov edi, [esi + (64 - 20)]
add esp, 64
pop dword esi
ret