aboutsummaryrefslogtreecommitdiffstats
path: root/src/boot/boot.stage2.a20.asm
diff options
context:
space:
mode:
authorkotorifan <kotorifan05@gmail.com>2026-01-31 15:22:00 +0100
committerkotorifan <kotorifan05@gmail.com>2026-02-04 09:01:10 +0100
commite5c28a46a731a79d02266aa690a90a8f809d0f70 (patch)
tree3dfc555f1ca98c97b3f48f035e897e3d0cca07ba /src/boot/boot.stage2.a20.asm
parentdfe4a33865ef01c5068804f77da844cdebd87f00 (diff)
downloadkotori-os-e5c28a46a731a79d02266aa690a90a8f809d0f70.tar.gz
A20 enable code added
Diffstat (limited to 'src/boot/boot.stage2.a20.asm')
-rw-r--r--src/boot/boot.stage2.a20.asm147
1 files changed, 147 insertions, 0 deletions
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