96 lines
2.3 KiB
NASM
Executable File
96 lines
2.3 KiB
NASM
Executable File
|
|
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
|