See my public domain BOOTCFG project. I have mastered detecting the state of the A20 line and enabling/disabling it via KBC/Fast A20/BIOS to a fair degree:
http://f.osdev.org/viewtopic.php?p=276636Look at the root directory of the source code, there is a fully 16-bit program called "
01_64_rm.asm" that is able to detect whether the A20 line is enabled or not, solely by manipulating memory in the first Megabyte+65536-16 area, so it's safe to use even under very old machines, in pure 16-bit mode without Unreal Mode, very important to avoid locking up under, say, a 286, or dealing unnecessarily with A20 enabling circuits to detect, enable or disable.
Here is the current version of that program at this time. You can find the rest of A20 enabling option snippets in the project's ZIP file:
Code:
_01_64_RM:
bits 16
org 100h
cld
;Compare:
;
;DS:SI==0000:0000 (phys. 000000-00FFF0)
;ES:DI==FFFF:0010 (phys. 100000-10FFF0)
;
;(Those are 65536-16 bytes to test).
;If they are different, then A20 is currently enabled.
;
;They are potentially the same address in a contiguous
;even/odd Megabyte pair, if A20 is disabled.
;;
push ds
push es
push word 0
pop ds
xor si,si
push word 0xFFFF
pop es
mov di,16
mov cx,65536-16
;Use the LOOP instruction to give
;these memory regions more time
;to become more altered which
;will help to differentiate them
;even more (remember that the LOOP
;instruction is extremely slow even in
;the newest CPUs):
;;
.loop1:
cmpsb
jne .loop1_END
loop .loop1
.loop1_END:
pop es
pop ds
test cx,cx
jnz .A20On
;If CX is 0, then the A20 line
;is disabled because the first and second
;Megabytes were identical despite being
;tested for differences in the first 65536-16 bytes
;via the CMPSB instruction:
;;
mov ah,9
mov dx,strA20Off
int 21h
mov al,0 ;Return code==enabled FALSE
jmp .END
.A20On:
mov ah,9
mov dx,strA20On
int 21h
mov al,1 ;Return code==enabled TRUE
.END:
;Exit to DOS:
;;
mov ah,4Ch
int 21h
strAppName db "01_64_RM.COM: $"
strA20On db "01_64_RM.COM: A20 detected enabled from pure 16-bit Real Mode...",13,10,"$"
strA20Off db "01_64_RM.COM: A20 detected disabled from pure 16-bit Real Mode...",13,10,"$"
;EOF