[FREELDR] Several changes regarding chainloading and Linux boot.
[reactos.git] / boot / freeldr / freeldr / arch / realmode / helpers.inc
1
2 Empty8042:
3 .word HEX(00eb), HEX(00eb) // jmp $+2, jmp $+2
4 in al, HEX(64)
5 cmp al, HEX(0ff) // legacy-free machine without keyboard
6 jz Empty8042_ret // controllers on Intel Macs read back 0xFF
7 test al, 2
8 jnz Empty8042
9 Empty8042_ret:
10 ret
11
12 EnableA20:
13 pusha
14 call Empty8042
15 mov al, HEX(0D1) // command write
16 out HEX(064), al
17 call Empty8042
18 mov al, HEX(0DF) // A20 on
19 out HEX(060), al
20 call Empty8042
21 mov al, HEX(0FF) // pulse output port
22 out HEX(064), al
23 call Empty8042
24 popa
25 ret
26
27 DisableA20:
28 pusha
29 call Empty8042
30 mov al, HEX(0D1) // command write
31 out HEX(064), al
32 call Empty8042
33 mov al, HEX(0DD) // A20 off
34 out HEX(060), al
35 call Empty8042
36 mov al, HEX(0FF) // pulse output port
37 out HEX(064), al
38 call Empty8042
39 popa
40 ret
41
42 /*
43 * writestr
44 * si = pointer to zero terminated string
45 */
46 writestr:
47 pushfd
48 pushad
49 writestr_top:
50 lodsb
51 and al, al
52 jz writestr_end
53 call writechr
54 jmp short writestr_top
55 writestr_end:
56 popad
57 popfd
58 ret
59
60 /*
61 * writechr
62 * al = character to output
63 */
64 writechr:
65 pushf
66 pusha
67 mov ah, HEX(0E)
68 xor bx, bx
69 int HEX(10)
70 popa
71 popf
72 ret
73
74 //
75 // writehex[248]: Write a hex number in (AL, AX, EAX) to the console
76 //
77 writehex2:
78 pushfd
79 pushad
80 shl eax, 24
81 mov cx, 2
82 jmp short writehex_common
83 writehex4:
84 pushfd
85 pushad
86 shl eax, 16
87 mov cx, 4
88 jmp short writehex_common
89 writehex8:
90 pushfd
91 pushad
92 mov cx, 8
93 writehex_common:
94 .loop:
95 rol eax, 4
96 push eax
97 and al, HEX(0F)
98 cmp al, 10
99 jae .high
100 .low:
101 add al, '0'
102 jmp short .ischar
103 .high:
104 add al, 'A'-10
105 .ischar:
106 call writechr
107 pop eax
108 loop .loop
109 popad
110 popfd
111 ret
112
113
114 Reboot:
115 cli
116
117 /* Disable A20 address line */
118 call DisableA20
119
120 /* Set the video back to 80x25 text mode */
121 mov ax, HEX(0003)
122 int HEX(10)
123
124 /* Set the word at location 40h:72h to 0 (cold reboot) */
125 mov word ptr ds:[HEX(0472)], HEX(0)
126
127 /* and jump to location F000h:FFF0h in ROM */
128 ljmp16 HEX(0F000), HEX(0FFF0)
129
130
131 Relocator16Boot:
132 cli
133
134 /* Disable A20 address line */
135 call DisableA20
136
137 /* Set the video back to 80x25 text mode */
138 mov ax, HEX(0003)
139 int HEX(10)
140
141 /* Get current EFLAGS and mask CF, ZF and SF */
142 pushf
143 pop cx
144 and cx, not (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
145
146 /* Get flags CF, ZF and SF from the REGS structure */
147 mov ax, word ptr cs:[BSS_RegisterSet + REGS_EFLAGS]
148 and ax, (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
149
150 /* Combine flags and set them */
151 or ax, cx
152 push ax
153 popf
154
155 /* Setup the segment registers */
156 mov ax, word ptr cs:[BSS_RegisterSet + REGS_DS]
157 mov ds, ax
158 mov ax, word ptr cs:[BSS_RegisterSet + REGS_ES]
159 mov es, ax
160 mov ax, word ptr cs:[BSS_RegisterSet + REGS_FS]
161 mov fs, ax
162 mov ax, word ptr cs:[BSS_RegisterSet + REGS_GS]
163 mov gs, ax
164
165 /* Patch the jump address (segment:offset) */
166 mov eax, dword ptr cs:[BSS_RealModeEntry]
167 mov dword ptr cs:[Relocator16Address], eax
168
169 /* Switch the stack (segment:offset) */
170 mov eax, dword ptr cs:[BSS_CallbackReturn]
171 shr eax, 16
172 mov ss, ax
173 mov eax, dword ptr cs:[BSS_CallbackReturn]
174 and eax, HEX(0FFFF)
175 mov esp, eax
176
177 /* Setup the registers */
178 mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EAX]
179 mov ebx, dword ptr cs:[BSS_RegisterSet + REGS_EBX]
180 mov ecx, dword ptr cs:[BSS_RegisterSet + REGS_ECX]
181 mov edx, dword ptr cs:[BSS_RegisterSet + REGS_EDX]
182 mov esi, dword ptr cs:[BSS_RegisterSet + REGS_ESI]
183 mov edi, dword ptr cs:[BSS_RegisterSet + REGS_EDI]
184 // Don't setup ebp, we only use it as output! <-- FIXME!
185
186 /* Jump to the new CS:IP (e.g. jump to bootsector code...) */
187 .byte HEX(0EA) // ljmp16 segment:offset
188 Relocator16Address:
189 .word HEX(7C00) // Default offset
190 .word HEX(0000) // Default segment
191 nop