Skip to content

Commit fa3616e

Browse files
iLauncherDevbinarymaster
authored andcommitted
Avoid int 10h on xbox builds
1 parent 5adda5f commit fa3616e

File tree

3 files changed

+190
-4
lines changed

3 files changed

+190
-4
lines changed

boot/freeldr/freeldr/arch/realmode/helpers.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ Reboot:
121121
mov ax, HEX(0003)
122122
int HEX(10)
123123

124-
/* Set the word at location 40h:72h to 0 (cold reboot) */
124+
/* Set the BIOS Data Area variable at 40h:72h to 0 (cold reboot) */
125125
mov word ptr ds:[HEX(0472)], HEX(0)
126126

127-
/* and jump to location F000h:FFF0h in ROM */
127+
/* and jump to the Reset Vector F000h:FFF0h in the ROM */
128128
ljmp16 HEX(0F000), HEX(0FFF0)
129129

130130

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* PROJECT: FreeLoader
3+
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4+
* PURPOSE: Real mode helper code for Original Xbox
5+
* COPYRIGHT: Copyright 2011 Timo Kreuzer <timo.kreuzer@reactos.org>
6+
* Copyright 2012-2019 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7+
* Copyright 2026 Daniel Victor <ilauncherdeveloper@gmail.com>
8+
*/
9+
10+
Empty8042:
11+
.word HEX(00eb), HEX(00eb) /* jmp $+2, jmp $+2 */
12+
in al, HEX(64)
13+
cmp al, HEX(0ff) /* legacy-free machine without keyboard */
14+
jz Empty8042_ret /* controllers on Intel Macs read back 0xFF */
15+
test al, 2
16+
jnz Empty8042
17+
Empty8042_ret:
18+
ret
19+
20+
EnableA20:
21+
pusha
22+
call Empty8042
23+
mov al, HEX(0D1) /* command write */
24+
out HEX(064), al
25+
call Empty8042
26+
mov al, HEX(0DF) /* A20 on */
27+
out HEX(060), al
28+
call Empty8042
29+
mov al, HEX(0FF) /* pulse output port */
30+
out HEX(064), al
31+
call Empty8042
32+
popa
33+
ret
34+
35+
DisableA20:
36+
pusha
37+
call Empty8042
38+
mov al, HEX(0D1) /* command write */
39+
out HEX(064), al
40+
call Empty8042
41+
mov al, HEX(0DD) /* A20 off */
42+
out HEX(060), al
43+
call Empty8042
44+
mov al, HEX(0FF) /* pulse output port */
45+
out HEX(064), al
46+
call Empty8042
47+
popa
48+
ret
49+
50+
/*
51+
* writestr
52+
* si = pointer to zero terminated string
53+
*/
54+
writestr:
55+
pushfd
56+
pushad
57+
writestr_top:
58+
lodsb
59+
and al, al
60+
jz writestr_end
61+
call writechr
62+
jmp short writestr_top
63+
writestr_end:
64+
popad
65+
popfd
66+
ret
67+
68+
/*
69+
* writechr
70+
* al = character to output
71+
*/
72+
writechr:
73+
/* no-op on Xbox, as it doesn't have INT 10h / VGA BIOS
74+
* FIXME: This could be made to output to the serial port */
75+
ret
76+
77+
/*
78+
* writehex[248]: Write a hex number in (AL, AX, EAX) to the console
79+
*/
80+
writehex2:
81+
pushfd
82+
pushad
83+
shl eax, 24
84+
mov cx, 2
85+
jmp short writehex_common
86+
writehex4:
87+
pushfd
88+
pushad
89+
shl eax, 16
90+
mov cx, 4
91+
jmp short writehex_common
92+
writehex8:
93+
pushfd
94+
pushad
95+
mov cx, 8
96+
writehex_common:
97+
.loop:
98+
rol eax, 4
99+
push eax
100+
and al, HEX(0F)
101+
cmp al, 10
102+
jae .high
103+
.low:
104+
add al, '0'
105+
jmp short .ischar
106+
.high:
107+
add al, 'A'-10
108+
.ischar:
109+
call writechr
110+
pop eax
111+
loop .loop
112+
popad
113+
popfd
114+
ret
115+
116+
117+
Reboot:
118+
/* FIXME: perform reboot via SMC on I2C bus */
119+
cli
120+
121+
/* Disable A20 address line */
122+
call DisableA20
123+
124+
/* and jump to the Reset Vector in the ROM */
125+
ljmp16 HEX(0F000), HEX(0FFF0)
126+
127+
128+
Relocator16Boot:
129+
cli
130+
131+
/* Disable A20 address line */
132+
call DisableA20
133+
134+
/* Get current EFLAGS and mask CF, ZF and SF */
135+
pushf
136+
pop cx
137+
and cx, not (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
138+
139+
/* Get flags CF, ZF and SF from the REGS structure */
140+
mov ax, word ptr cs:[BSS_RegisterSet + REGS_EFLAGS]
141+
and ax, (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
142+
143+
/* Combine flags and set them */
144+
or ax, cx
145+
push ax
146+
popf
147+
148+
/* Setup the segment registers */
149+
mov ax, word ptr cs:[BSS_RegisterSet + REGS_DS]
150+
mov ds, ax
151+
mov ax, word ptr cs:[BSS_RegisterSet + REGS_ES]
152+
mov es, ax
153+
mov ax, word ptr cs:[BSS_RegisterSet + REGS_FS]
154+
mov fs, ax
155+
mov ax, word ptr cs:[BSS_RegisterSet + REGS_GS]
156+
mov gs, ax
157+
158+
/* Patch the jump address (segment:offset) */
159+
mov eax, dword ptr cs:[BSS_RealModeEntry]
160+
mov dword ptr cs:[Relocator16Address], eax
161+
162+
/* Switch the stack (segment:offset) */
163+
mov eax, dword ptr cs:[BSS_CallbackReturn]
164+
shr eax, 16
165+
mov ss, ax
166+
mov eax, dword ptr cs:[BSS_CallbackReturn]
167+
and eax, HEX(0FFFF)
168+
mov esp, eax
169+
170+
/* Setup the registers */
171+
mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EAX]
172+
mov ebx, dword ptr cs:[BSS_RegisterSet + REGS_EBX]
173+
mov ecx, dword ptr cs:[BSS_RegisterSet + REGS_ECX]
174+
mov edx, dword ptr cs:[BSS_RegisterSet + REGS_EDX]
175+
mov esi, dword ptr cs:[BSS_RegisterSet + REGS_ESI]
176+
mov edi, dword ptr cs:[BSS_RegisterSet + REGS_EDI]
177+
/* FIXME: Don't setup ebp, we only use it as output! */
178+
179+
/* Jump to the new CS:IP (e.g. jump to bootsector code...) */
180+
.byte HEX(0EA) /* ljmp16 segment:offset */
181+
Relocator16Address:
182+
.word HEX(7C00) /* Default offset */
183+
.word HEX(0000) /* Default segment */
184+
nop

boot/freeldr/freeldr/arch/realmode/i386.S

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,11 @@ rmode_idtptr:
202202
#include "int386.inc"
203203
#include "relocator.inc"
204204
#if defined(SARCH_PC98)
205-
#include "helpers_pc98.inc"
205+
#include "helpers_pc98.inc"
206+
#elif defined(SARCH_XBOX)
207+
#include "helpers_xbox.inc"
206208
#else
207-
#include "helpers.inc"
209+
#include "helpers.inc"
208210
#endif
209211
#include "pxe.inc"
210212
#include "pnp.inc"

0 commit comments

Comments
 (0)