]> git.dujemihanovic.xyz Git - nameless-os.git/blob - boot/x86/a20.s
b1c86cee6fb9521693c5e91ce146f78e585f3748
[nameless-os.git] / boot / x86 / a20.s
1 ; Some routines for managing the A20 line
2
3 ; Check if A20 is enabled
4 ; Based on <https://wiki.osdev.org/A20_Line#Testing_the_A20_line>
5 check_a20:
6 pushf
7 push ds
8 push es
9 push di
10 push si
11
12 cli
13
14 xor ax, ax
15 mov es, ax
16
17 not ax
18 mov ds, ax
19
20 mov di, 500h
21 mov si, 510h
22
23 mov al, byte [es:di]
24 push ax
25
26 mov al, byte [ds:si]
27 push ax
28
29 mov byte [es:di], 0
30 mov byte [ds:si], 0FFh
31
32 cmp byte [es:di], 0FFh
33
34 pop ax
35 mov byte [ds:si], al
36
37 pop ax
38 mov byte [es:di], al
39
40 mov ax, 0
41 je .exit
42 mov ax, 1
43
44 .exit
45 pop si
46 pop di
47 pop es
48 pop ds
49 popf
50 ret
51
52 a20_i8042_wait
53 in al, 64h
54 test al, 2
55 jnz a20_i8042_wait
56 ret
57
58 a20_i8042_wait2
59 in al, 64h
60 test al, 1
61 jnz a20_i8042_wait2
62 ret
63
64 enable_a20
65 mov ax, 2401h
66 int 15h
67 call check_a20
68 cmp ax, 1
69 jne .fail
70 .success
71 ret
72 .fail
73 cli ; disable interrupts
74
75 call a20_i8042_wait
76 mov al, 0ADh ; disable 1st PS/2 port
77 out 64h, al
78
79 call a20_i8042_wait
80 mov al, 0D0h ; read controller output port
81 out 64h, al
82
83 call a20_i8042_wait2
84 in al, 60h ; do the actual read
85 push ax ; save the register
86
87 call a20_i8042_wait
88 mov al, 0D1h ; write byte to output port
89 out 64h, al
90
91 call a20_i8042_wait
92 pop ax ; restore the register
93 or al, 2 ; toggle A20 bit
94 out 60h, al
95
96 call a20_i8042_wait
97 mov al, 0AEh ; reenable 1st PS/2 port
98 out 64h, al
99
100 call a20_i8042_wait
101 sti ; enable interrupts
102 ret
103
104 call check_a20
105 cmp ax, 1
106 jne .fail2
107 ret
108 .fail2
109 mov si, A20_FAIL
110 call print
111 jmp $
112
113 A20_FAIL db "A20 enable fail, not booting!", 0