Skip to content

Instantly share code, notes, and snippets.

@xavery
Created July 25, 2015 23:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xavery/cb36264f173575215c80 to your computer and use it in GitHub Desktop.
Save xavery/cb36264f173575215c80 to your computer and use it in GitHub Desktop.
A bootloader for x86 demonstrating how to detect if the A20 line is enabled
bits 16
cpu 8086
org 0x7c00
init:
xor ax, ax
mov ss, ax
mov sp, 0x7c00
mov ds, ax
mov es, ax
cli
call a20_enabled
; AH = 0x0E ("Teletype Output"), AL = ASCII-fied retval of a20_enabled.
or ax, (((0x0e) << 8) | '0')
int 10h
.kill:
hlt
jmp .kill
; returns 1 in ax if the A20 line is enabled, 0 otherwise.
a20_enabled:
pushf
push ds
push es
push di
push si
xor ax, ax ; ax = 0
mov es, ax
not ax ; ax = 0xFFFF
mov ds, ax
xor ax, ax
; 0500 and 0510 are chosen since they are guaranteed to be free for use at
; any point of time after BIOS initialization.
mov di, 0x0500
mov si, 0x0510
; save the original values found at these addresses.
mov al, byte [es:di]
push ax
mov al, byte [ds:si]
push ax
; [es:di] is 0:0500, [ds:si] is FFFF:0510. the respective physical addresses
; for those will be 00500 and 100500.
mov byte [es:di], 0x00
mov byte [ds:si], 0xFF
; if the A20 line is disabled, [es:di] will contain 0xFF, as the write to
; [ds:si] really occured to 00500.
cmp byte [es:di], 0xFF
; restore original values
pop ax
mov byte [ds:si], al
pop ax
mov byte [es:di], al
mov ax, 0
je .exit ; A20 disabled - [es:di] equal to 0xFF.
mov ax, 1 ; A20 enabled.
.exit:
pop si
pop di
pop es
pop ds
popf
ret
times (510-($-$$)) db 0h
db 0x55, 0xaa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment