wok-6.x view syslinux/stuff/iso2exe/a20.c @ rev 16069

syslinux/iso2exe: add a20 support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Mar 13 08:22:47 2014 +0000 (2014-03-13)
parents
children 3e7ad70145ce
line source
1 #ifndef __A20
2 #define __A20
4 // http://www.win.tue.nl/~aeb/linux/kbd/A20.html
5 static void a20enable(void)
6 {
7 #asm
8 call a20test
10 in al, 0x92 // fast A20
11 test al, #0x2
12 jnz no92
13 or al, #0x2 // Enable A20
14 and al, #0xFE // Do not reset machine
15 out 0x92, al
16 call a20test
17 no92:
18 call empty_8042
19 mov al, #0xD1 // command write
20 out 0x64, al
21 call empty_8042
22 mov al, #0xDF // Enable A20
23 out 0x60, al
24 call empty_8042
26 mov al, #0xFF // Null command, but UHCI wants it
27 out 0x64, al
28 call empty_8042
29 call a20test
31 mov ax, #0x2401
32 int 0x15
33 call a20test
35 in al, 0xEE // fast enable A20
36 jmp a20test
38 empty_8042:
39 mov ah, #-32
40 wait_8042:
41 in al, 0x64
42 inc ax // FF 32x : no kbd
43 jz enabled
44 dec ax
45 shr ax, #1 // Bit 0: input data
46 jc data
47 shr ax, #1 // Bit 1: buffer empty
48 jc wait_8042
49 ret
50 data:
51 in al, 0x60 // read data
52 jmp wait_8042
53 a20test:
54 push ds
55 xor cx, cx
56 xor bx, bx
57 mov ds, cx // ds = 0000
58 dec cx
59 mov gs, cx // gs = FFFF
60 cli
61 a1:
62 mov ax, [bx]
63 not ax
64 mov dx, ax
65 seg gs
66 xchg dx, [bx+10]
67 cmp ax, [bx]
68 seg gs
69 mov [bx+10], dx
70 loopne a1
71 pop ds
72 xchg ax, cx
73 sti
74 jne enabled
75 pop cx // quit a20enable
76 enabled:
77 ret // ax != 0 : enabled
78 #endasm
79 }
81 #define A20HOLDBUFFER 0x80000
82 static int a20buffer = 0;
83 static void movehia20(void)
84 {
85 if ((mem.base - 0x100000UL) >= 0x10000UL) {
86 movehi();
87 return;
88 }
89 a20buffer = 1;
90 #asm
91 pusha
92 push #A20HOLDBUFFER/16
93 pop es
94 mov di, _mem // mem.base & 0xFFFF
95 mov si, #_buffer
96 mov cx, #BUFFERSZ/2
97 cld
98 rep
99 movsw
100 popa
101 #endasm
102 }
103 #define movehi movehia20
105 #define REALMODE_SWITCH _realmode_switch_a20
106 static void realmode_switch_a20(void)
107 {
108 if (!a20buffer) return;
109 a20enable();
110 #asm
111 pusha
112 xor di, di // 30
113 mov cx, #9 // 2E..1E
114 a20z1:
115 push di
116 loop a20z1
117 push #0x10
118 push di // 1A 0x100000
119 push #-1 // 18
120 push di // 16
121 push #A20HOLDBUFFER/0x10000
122 push di // 12 A20HOLDBUFFER
123 push #-1 // 10
124 mov cl, #8 // 0E..00
125 a20z2:
126 push di
127 loop a20z2
128 mov ch, #0x10000/512
129 push ss
130 pop es
131 mov si, sp
132 mov ax, #0x8793
133 mov [si+0x15], al
134 xchg [si+0x1D], al
135 xchg [si+0x1F], al // bits 24..31
136 int 0x15
137 add sp, #0x30
138 popa
139 #endasm
140 }
142 #endif