My boot loader has passed control to second stage in protected mode. This example shows how to determine if A20 is on or not, by probing memory. I will eventually use color saved @ [A20_STATUS]. Colors conform to
BIOS/DOS color mapping.
Test_A20:
; Now we can turn A20 on. Point to a pair of locations where wrap around can be determined.
mov esi, 0x7d2c ; Point to any volatile place in boot sector
mov edi, esi
bts edi, 20 ; Point to same address in next meg of memory
; Procedure will set of 4 colors.
; (1) Green, A20 was already on
; (2) Yellow, Fast A20 gate succeeded, but took ECX times
; (3) Brown, A20 activated using fast method
; (4) Red, couldn't turn on A20 so alternate method must be implemented
mov dl, GREEN ; Assume A20 is already.
or ecx, -1 ; Large retry count, but probably won't be needed.
; Will loop back to here until retry count in ECX is exhausted.
.Retry:
push esi
push edi
lodsd ; Read dword from boot sector
not eax ; Invert 32 bits
stosd ; Write back
cmp [esi - 4], eax ; Are they the same
pop esi
pop edi
jnz .Ok ; ZF = 1, A20 is already on. Probably in BOCHS.
; Set color to YELLOW indicating gate was not active, but this method succeeded.
mov dl, YELLOW
in al, A20_GATE
or al, 2
out A20_GATE, al
dec ecx
jnz .Retry
; *** TO DO ***
; This is where an alternate method would be implemented, but all my test computers
; succeeded with this method, so I'll assume most others will work too.
mov dl, RED ; All methods will fall through to here if they fail.
jmp @F
.Ok: inc ecx ; Bump ECX. It will be NULL if gate was already on
jz @F
; We will always get to this point unless in BOCHS or another emulator where A20 is
; already on. If method only needed to be used once, color will not be changed
not ecx ; Indicates actual number of retries
or ecx, ecx
jz @F ; Don't change if we only tried Fast A20 gate once.
mov dl, BROWN ; Indicates there were retrys with fast method
@@: mov [A20_STATUS], dl ; Write status of operation to scatch area