From e5c28a46a731a79d02266aa690a90a8f809d0f70 Mon Sep 17 00:00:00 2001 From: kotorifan Date: Sat, 31 Jan 2026 15:22:00 +0100 Subject: A20 enable code added --- src/boot/boot.stage2.a20.asm | 147 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/boot/boot.stage2.a20.asm (limited to 'src/boot/boot.stage2.a20.asm') diff --git a/src/boot/boot.stage2.a20.asm b/src/boot/boot.stage2.a20.asm new file mode 100644 index 0000000..6a9c250 --- /dev/null +++ b/src/boot/boot.stage2.a20.asm @@ -0,0 +1,147 @@ + ;; boot.stage2.a20.asm + +_enable_a20: + call _check_a20 + test ax, ax + jnz .end + + call _enable_a20_bios + call _check_a20 + test ax, ax + jnz .end + + call _enable_a20_keyb + call _check_a20 + test ax, ax + jnz .end + + call _enable_a20_io92 + call _check_a20 + test ax, ax + jnz .end + + .halt: hlt + jmp .halt + .end + ret + +_check_a20: + pushf + push ds + push es + push di + push si + cli ; Clear Interrupts + + xor ax, ax + mov es, ax + not ax + mov ds, ax + ;; 0500 and 0510 are guaranteed to be free + mov di, 0x0500 + mov si, 0x0510 + + ;; Save the original values + mov dl, byte [es:di] + push dx + mov dl, byte [ds:si] + push dx + + mov byte [es:di], 0x00 + mov byte [ds:si], 0xFF + cmp byte [es:di], 0xFF + + mov ax, 0 ; The A20 is disabled + je .a20_disabled + mov ax, 1 ; The A20 is enabled + .a20_disabled: + pop dx + mov byte [ds:si], dl + pop dx + mov byte [es:di], dl + + pop si + pop di + pop es + pop ds + popf + sti ; Enable interrupts again + ret + +_enable_a20_bios: + mov ax, 0x2401 + int 0x15 + jc .fast_gate + test ah, ah + jnz .failed + call _check_a20 + test ax, ax + jnz .done + + .fast_gate: + in al, 0x92 + test al, 2 + jnz .done + + or al, 2 + and al, 0xfe + out 0x92, al + + call _check_a20 + test ax, ax + jnz .done + + .done: + mov ax, 1 + ret + + .failed: + mov ax, 0 + ret + +_enable_a20_keyb: + cli + call .wait_io1 + mov al, 0xad + out 0x64, al + + call .wait_io1 + mov al, 0x0d0 + out 0x64, al + + call .wait_io2 + in al, 0x60 + push eax + + call .wait_io1 + mov al, 0xd1 + out 0x64, al + + call .wait_io1 + mov al, 0xae + out 0x64, al + + sti + ret + + .wait_io1: + in al, 0x64 + test al, 2 + jnz .wait_io1 + ret + + .wait_io2: + in al, 0x64 + test al, 1 + jz .wait_io2 + ret + +_enable_a20_io92: + in al, 0x92 ; Read from port 0x92 + test al, 2 ; Check if bit 1 + jnz .end + or al, 2 + and al, 0xfe + out 0x92, al + .end + ret -- cgit v1.3