xref: /plan9/sys/src/boot/pc/pbslbadebug.s (revision 42dedc50a943b5d120c8c26dac13fc4664b65146)
1*42dedc50SDavid du Colombier/*
2*42dedc50SDavid du Colombier * Debugging boot sector.  Reads the first directory
3*42dedc50SDavid du Colombier * sector from disk and displays it.
4*42dedc50SDavid du Colombier *
5*42dedc50SDavid du Colombier * It relies on the _volid field in the FAT header containing
6*42dedc50SDavid du Colombier * the LBA of the root directory.
7*42dedc50SDavid du Colombier */
8*42dedc50SDavid du Colombier#include "x16.h"
9*42dedc50SDavid du Colombier
10*42dedc50SDavid du Colombier#define DIROFF		0x00200		/* where to read the root directory (offset) */
11*42dedc50SDavid du Colombier#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
12*42dedc50SDavid du Colombier#define LOADOFF		0
13*42dedc50SDavid du Colombier
14*42dedc50SDavid du Colombier/*
15*42dedc50SDavid du Colombier * FAT directory entry.
16*42dedc50SDavid du Colombier */
17*42dedc50SDavid du Colombier#define Dname		0x00
18*42dedc50SDavid du Colombier#define Dext		0x08
19*42dedc50SDavid du Colombier#define Dattr		0x0B
20*42dedc50SDavid du Colombier#define Dtime		0x16
21*42dedc50SDavid du Colombier#define Ddate		0x18
22*42dedc50SDavid du Colombier#define Dstart		0x1A
23*42dedc50SDavid du Colombier#define Dlengthlo	0x1C
24*42dedc50SDavid du Colombier#define Dlengthhi	0x1E
25*42dedc50SDavid du Colombier
26*42dedc50SDavid du Colombier#define Dirsz		0x20
27*42dedc50SDavid du Colombier
28*42dedc50SDavid du Colombier/*
29*42dedc50SDavid du Colombier * We keep data on the stack, indexed by rBP.
30*42dedc50SDavid du Colombier */
31*42dedc50SDavid du Colombier#define Xdrive		0x00		/* boot drive, passed by BIOS in rDL */
32*42dedc50SDavid du Colombier#define Xrootlo		0x02		/* offset of root directory */
33*42dedc50SDavid du Colombier#define Xroothi		0x04
34*42dedc50SDavid du Colombier#define Xrootsz		0x06		/* file data area */
35*42dedc50SDavid du Colombier#define Xtotal		0x08		/* sum of allocated data above */
36*42dedc50SDavid du Colombier#define Xdap		0x00		/* disc address packet */
37*42dedc50SDavid du Colombier
38*42dedc50SDavid du ColombierTEXT _magic(SB), $0
39*42dedc50SDavid du Colombier	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
40*42dedc50SDavid du Colombier	BYTE $0x90			/* nop */
41*42dedc50SDavid du ColombierTEXT _version(SB), $0
42*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
43*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
44*42dedc50SDavid du ColombierTEXT _sectsize(SB), $0
45*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
46*42dedc50SDavid du ColombierTEXT _clustsize(SB), $0
47*42dedc50SDavid du Colombier	BYTE $0x00
48*42dedc50SDavid du ColombierTEXT _nresrv(SB), $0
49*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
50*42dedc50SDavid du ColombierTEXT _nfats(SB), $0
51*42dedc50SDavid du Colombier	BYTE $0x00
52*42dedc50SDavid du ColombierTEXT _rootsize(SB), $0
53*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
54*42dedc50SDavid du ColombierTEXT _volsize(SB), $0
55*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
56*42dedc50SDavid du ColombierTEXT _mediadesc(SB), $0
57*42dedc50SDavid du Colombier	BYTE $0x00
58*42dedc50SDavid du ColombierTEXT _fatsize(SB), $0
59*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
60*42dedc50SDavid du ColombierTEXT _trksize(SB), $0
61*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
62*42dedc50SDavid du ColombierTEXT _nheads(SB), $0
63*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
64*42dedc50SDavid du ColombierTEXT _nhiddenlo(SB), $0
65*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00
66*42dedc50SDavid du ColombierTEXT _nhiddenhi(SB), $0
67*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00;
68*42dedc50SDavid du ColombierTEXT _bigvolsize(SB), $0
69*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
70*42dedc50SDavid du ColombierTEXT _driveno(SB), $0
71*42dedc50SDavid du Colombier	BYTE $0x00
72*42dedc50SDavid du ColombierTEXT _reserved0(SB), $0
73*42dedc50SDavid du Colombier	BYTE $0x00
74*42dedc50SDavid du ColombierTEXT _bootsig(SB), $0
75*42dedc50SDavid du Colombier	BYTE $0x00
76*42dedc50SDavid du ColombierTEXT _volid(SB), $0
77*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
78*42dedc50SDavid du ColombierTEXT _label(SB), $0
79*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
80*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
81*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00
82*42dedc50SDavid du ColombierTEXT _type(SB), $0
83*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
84*42dedc50SDavid du Colombier	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
85*42dedc50SDavid du Colombier
86*42dedc50SDavid du Colombier_start0x3E:
87*42dedc50SDavid du Colombier	CLI
88*42dedc50SDavid du Colombier	CLR(rAX)
89*42dedc50SDavid du Colombier	MTSR(rAX, rSS)			/* 0000 -> rSS */
90*42dedc50SDavid du Colombier	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
91*42dedc50SDavid du Colombier	MTSR(rAX, rES)
92*42dedc50SDavid du Colombier	LWI(_magic-Xtotal(SB), rSP)
93*42dedc50SDavid du Colombier	MW(rSP, rBP)			/* set the indexed-data pointer */
94*42dedc50SDavid du Colombier
95*42dedc50SDavid du Colombier	SBPB(rDL, Xdrive)		/* save the boot drive */
96*42dedc50SDavid du Colombier
97*42dedc50SDavid du Colombier	STI
98*42dedc50SDavid du Colombier
99*42dedc50SDavid du Colombier	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
100*42dedc50SDavid du Colombier	CALL(BIOSputs(SB))
101*42dedc50SDavid du Colombier
102*42dedc50SDavid du Colombier	LBI(0x41, rAH)			/* check extensions present */
103*42dedc50SDavid du Colombier	LWI(0x55AA, rBX)
104*42dedc50SDavid du Colombier	LXB(Xdrive, xBP, rDL)		/* drive */
105*42dedc50SDavid du Colombier	SYSCALL(0x13)			/* CF set on failure */
106*42dedc50SDavid du Colombier	JCS _jmp01
107*42dedc50SDavid du Colombier	CMPI(0xAA55, rBX)
108*42dedc50SDavid du Colombier	JNE _jmp01
109*42dedc50SDavid du Colombier	ANDI(0x0001, rCX)
110*42dedc50SDavid du Colombier	JEQ _jmp01
111*42dedc50SDavid du Colombier
112*42dedc50SDavid du Colombier					/* rCX contains 0x0001 */
113*42dedc50SDavid du Colombier	SBPWI(0x0010, Xdap+0)		/* reserved + packet size */
114*42dedc50SDavid du Colombier	SBPW(rCX, Xdap+2)		/* reserved + # of blocks to transfer */
115*42dedc50SDavid du Colombier
116*42dedc50SDavid du Colombier	DEC(rCX)
117*42dedc50SDavid du Colombier	SBPW(rCX, Xdap+12)
118*42dedc50SDavid du Colombier	SBPW(rCX, Xdap+14)
119*42dedc50SDavid du Colombier
120*42dedc50SDavid du Colombier/* BIOSread will do this 	CALL(dreset(SB)) */
121*42dedc50SDavid du Colombier
122*42dedc50SDavid du Colombier_jmp00:
123*42dedc50SDavid du Colombier	LW(_volid(SB), rAX)		/* Xrootlo */
124*42dedc50SDavid du Colombier	LW(_volid+2(SB), rDX)		/* Xroothi */
125*42dedc50SDavid du Colombier
126*42dedc50SDavid du Colombier	LWI(_magic+DIROFF(SB), rBX)
127*42dedc50SDavid du Colombier	CALL(BIOSread(SB))		/* read the root directory */
128*42dedc50SDavid du Colombier
129*42dedc50SDavid du Colombier	CALL(printnl(SB))
130*42dedc50SDavid du Colombier	LWI(_magic+DIROFF(SB), rBX)
131*42dedc50SDavid du Colombier	LWI((512/2), rCX)
132*42dedc50SDavid du Colombier	CALL(printbuf(SB))
133*42dedc50SDavid du Colombier
134*42dedc50SDavid du Colombierxloop:
135*42dedc50SDavid du Colombier	JMP xloop
136*42dedc50SDavid du Colombier
137*42dedc50SDavid du Colombier
138*42dedc50SDavid du Colombier_jmp01:
139*42dedc50SDavid du Colombier
140*42dedc50SDavid du ColombierTEXT buggery(SB), $0
141*42dedc50SDavid du Colombier	LWI(error(SB), rSI)
142*42dedc50SDavid du Colombier	CALL(BIOSputs(SB))
143*42dedc50SDavid du Colombier
144*42dedc50SDavid du Colombierxbuggery:
145*42dedc50SDavid du Colombier	JMP xbuggery
146*42dedc50SDavid du Colombier
147*42dedc50SDavid du Colombier/*
148*42dedc50SDavid du Colombier * Read a sector from a disc. On entry:
149*42dedc50SDavid du Colombier *   rDX:rAX	sector number
150*42dedc50SDavid du Colombier *   rES:rBX	buffer address
151*42dedc50SDavid du Colombier */
152*42dedc50SDavid du ColombierTEXT BIOSread(SB), $0
153*42dedc50SDavid du Colombier	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
154*42dedc50SDavid du Colombier_retry:
155*42dedc50SDavid du Colombier	PUSHA				/* may be trashed by SYSCALL */
156*42dedc50SDavid du Colombier
157*42dedc50SDavid du Colombier	SBPW(rBX, Xdap+4)		/* transfer buffer :offset */
158*42dedc50SDavid du Colombier	MFSR(rES, rDI)			/* transfer buffer seg: */
159*42dedc50SDavid du Colombier	SBPW(rDI, Xdap+6)
160*42dedc50SDavid du Colombier	SBPW(rAX, Xdap+8)		/* LBA (64-bits) */
161*42dedc50SDavid du Colombier	SBPW(rDX, Xdap+10)
162*42dedc50SDavid du Colombier
163*42dedc50SDavid du Colombier	MW(rBP, rSI)			/* disk address packet */
164*42dedc50SDavid du Colombier	LBI(0x42, rAH)			/* extended read */
165*42dedc50SDavid du Colombier	LBPB(Xdrive, rDL)		/* form drive */
166*42dedc50SDavid du Colombier	SYSCALL(0x13)			/* CF set on failure */
167*42dedc50SDavid du Colombier	JCC _BIOSreadret
168*42dedc50SDavid du Colombier
169*42dedc50SDavid du Colombier	POPA
170*42dedc50SDavid du Colombier	DEC(rDI)			/* too many retries? */
171*42dedc50SDavid du Colombier	JEQ _ioerror
172*42dedc50SDavid du Colombier
173*42dedc50SDavid du Colombier	CALL(dreset(SB))
174*42dedc50SDavid du Colombier	JMP _retry
175*42dedc50SDavid du Colombier
176*42dedc50SDavid du Colombier_ioerror:
177*42dedc50SDavid du Colombier	LWI(ioerror(SB), rSI)
178*42dedc50SDavid du Colombier	CALL(BIOSputs(SB))
179*42dedc50SDavid du Colombier	JMP xbuggery
180*42dedc50SDavid du Colombier
181*42dedc50SDavid du Colombier_BIOSreadret:
182*42dedc50SDavid du Colombier	POPA
183*42dedc50SDavid du Colombier	RET
184*42dedc50SDavid du Colombier
185*42dedc50SDavid du ColombierTEXT dreset(SB), $0
186*42dedc50SDavid du Colombier	PUSHA
187*42dedc50SDavid du Colombier	CLR(rAX)			/* rAH == 0 == reset disc system */
188*42dedc50SDavid du Colombier	LBPB(Xdrive, rDL)
189*42dedc50SDavid du Colombier	SYSCALL(0x13)
190*42dedc50SDavid du Colombier	ORB(rAH, rAH)			/* status (0 == success) */
191*42dedc50SDavid du Colombier	POPA
192*42dedc50SDavid du Colombier	JNE _ioerror
193*42dedc50SDavid du Colombier	RET
194*42dedc50SDavid du Colombier
195*42dedc50SDavid du Colombier
196*42dedc50SDavid du ColombierTEXT printsharp(SB), $0
197*42dedc50SDavid du Colombier	LWI(sharp(SB), rSI)
198*42dedc50SDavid du Colombier_doprint:
199*42dedc50SDavid du Colombier	CALL(BIOSputs(SB))
200*42dedc50SDavid du Colombier	RET
201*42dedc50SDavid du Colombier
202*42dedc50SDavid du ColombierTEXT printspace(SB), $0
203*42dedc50SDavid du Colombier	LWI(space(SB), rSI)
204*42dedc50SDavid du Colombier	JMP _doprint
205*42dedc50SDavid du Colombier
206*42dedc50SDavid du ColombierTEXT printnl(SB), $0
207*42dedc50SDavid du Colombier	LWI(nl(SB), rSI)
208*42dedc50SDavid du Colombier	JMP _doprint
209*42dedc50SDavid du Colombier
210*42dedc50SDavid du Colombier/*
211*42dedc50SDavid du Colombier * Output a string to the display.
212*42dedc50SDavid du Colombier * String argument is in rSI.
213*42dedc50SDavid du Colombier */
214*42dedc50SDavid du ColombierTEXT BIOSputs(SB), $0
215*42dedc50SDavid du Colombier	PUSHA
216*42dedc50SDavid du Colombier	CLR(rBX)
217*42dedc50SDavid du Colombier_BIOSputs:
218*42dedc50SDavid du Colombier	LODSB
219*42dedc50SDavid du Colombier	ORB(rAL, rAL)
220*42dedc50SDavid du Colombier	JEQ _BIOSputsret
221*42dedc50SDavid du Colombier
222*42dedc50SDavid du Colombier	LBI(0x0E, rAH)
223*42dedc50SDavid du Colombier	SYSCALL(0x10)
224*42dedc50SDavid du Colombier	JMP _BIOSputs
225*42dedc50SDavid du Colombier
226*42dedc50SDavid du Colombier_BIOSputsret:
227*42dedc50SDavid du Colombier	POPA
228*42dedc50SDavid du Colombier	RET
229*42dedc50SDavid du Colombier
230*42dedc50SDavid du Colombier/*
231*42dedc50SDavid du Colombier * Output a register to the display.
232*42dedc50SDavid du Colombier */
233*42dedc50SDavid du ColombierTEXT printAX(SB), $0
234*42dedc50SDavid du Colombier	PUSHW(rAX)
235*42dedc50SDavid du Colombier	PUSHW(rBX)
236*42dedc50SDavid du Colombier	PUSHW(rCX)
237*42dedc50SDavid du Colombier	PUSHW(rDI)
238*42dedc50SDavid du Colombier
239*42dedc50SDavid du Colombier	LWI(4, rCX)
240*42dedc50SDavid du Colombier	LWI(numbuf+4(SB), rSI)
241*42dedc50SDavid du Colombier
242*42dedc50SDavid du Colombier_nextchar:
243*42dedc50SDavid du Colombier	DEC(rSI)
244*42dedc50SDavid du Colombier	MW(rAX, rBX)
245*42dedc50SDavid du Colombier	ANDI(0x000F, rBX)
246*42dedc50SDavid du Colombier	ADDI(0x30, rBX)	/* 0x30 = '0' */
247*42dedc50SDavid du Colombier	CMPI(0x39, rBX)	/* 0x39 = '9' */
248*42dedc50SDavid du Colombier	JLE _dowrite
249*42dedc50SDavid du Colombier	ADDI(0x07, rBX)	/* 0x07 = 'A'-(1+'9')*/
250*42dedc50SDavid du Colombier
251*42dedc50SDavid du Colombier_dowrite:
252*42dedc50SDavid du Colombier	SXB(rBL, 0, xSI)
253*42dedc50SDavid du Colombier	SHRI(4, rAX)
254*42dedc50SDavid du Colombier
255*42dedc50SDavid du Colombier	DEC(rCX)
256*42dedc50SDavid du Colombier	JNE _nextchar
257*42dedc50SDavid du Colombier
258*42dedc50SDavid du Colombier	LWI(numbuf(SB), rSI)
259*42dedc50SDavid du Colombier	CALL(BIOSputs(SB))
260*42dedc50SDavid du Colombier
261*42dedc50SDavid du Colombier	POPW(rDI)
262*42dedc50SDavid du Colombier	POPW(rCX)
263*42dedc50SDavid du Colombier	POPW(rBX)
264*42dedc50SDavid du Colombier	POPW(rAX)
265*42dedc50SDavid du Colombier
266*42dedc50SDavid du Colombier	CALL(printspace(SB))
267*42dedc50SDavid du Colombier	RET
268*42dedc50SDavid du Colombier
269*42dedc50SDavid du ColombierTEXT printDXAX(SB), $0
270*42dedc50SDavid du Colombier	PUSHW(rAX)
271*42dedc50SDavid du Colombier	MW(rDX, rAX)
272*42dedc50SDavid du Colombier	CALL(printAX(SB))
273*42dedc50SDavid du Colombier	POPW(rAX)
274*42dedc50SDavid du Colombier	CALL(printAX(SB))
275*42dedc50SDavid du Colombier	RET
276*42dedc50SDavid du Colombier
277*42dedc50SDavid du ColombierTEXT printBX(SB), $0
278*42dedc50SDavid du Colombier	PUSHW(rAX)
279*42dedc50SDavid du Colombier	MW(rBX, rAX)
280*42dedc50SDavid du Colombier	CALL(printAX(SB))
281*42dedc50SDavid du Colombier	POPW(rAX)
282*42dedc50SDavid du Colombier	RET
283*42dedc50SDavid du Colombier
284*42dedc50SDavid du Colombier/*
285*42dedc50SDavid du Colombier * Output some number of words to the display
286*42dedc50SDavid du Colombier * rDS:rDI - buffer
287*42dedc50SDavid du Colombier * rCX: number of words
288*42dedc50SDavid du Colombier */
289*42dedc50SDavid du ColombierTEXT printbuf(SB), $0
290*42dedc50SDavid du Colombier	PUSHW(rAX)
291*42dedc50SDavid du Colombier	PUSHW(rBX)
292*42dedc50SDavid du Colombier	PUSHW(rCX)
293*42dedc50SDavid du Colombier
294*42dedc50SDavid du Colombier_nextword:
295*42dedc50SDavid du Colombier	LXW(0, xBX, rAX)
296*42dedc50SDavid du Colombier	CALL(printAX(SB))
297*42dedc50SDavid du Colombier	INC(rBX)
298*42dedc50SDavid du Colombier	INC(rBX)
299*42dedc50SDavid du Colombier	DEC(rCX)
300*42dedc50SDavid du Colombier	JNE _nextword
301*42dedc50SDavid du Colombier
302*42dedc50SDavid du Colombier	POPW(rCX)
303*42dedc50SDavid du Colombier	POPW(rBX)
304*42dedc50SDavid du Colombier	POPW(rAX)
305*42dedc50SDavid du Colombier	RET
306*42dedc50SDavid du Colombier
307*42dedc50SDavid du ColombierTEXT error(SB), $0
308*42dedc50SDavid du Colombier	BYTE $'E';
309*42dedc50SDavid du Colombier
310*42dedc50SDavid du ColombierTEXT ioerror(SB), $0
311*42dedc50SDavid du Colombier	BYTE $'I';
312*42dedc50SDavid du Colombier
313*42dedc50SDavid du ColombierTEXT nl(SB), $0
314*42dedc50SDavid du Colombier	BYTE $'\r';
315*42dedc50SDavid du Colombier	BYTE $'\n';
316*42dedc50SDavid du Colombier	BYTE $'\z';
317*42dedc50SDavid du Colombier
318*42dedc50SDavid du ColombierTEXT numbuf(SB), $0
319*42dedc50SDavid du Colombier	BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';
320*42dedc50SDavid du Colombier	BYTE $'\z';
321*42dedc50SDavid du Colombier
322*42dedc50SDavid du ColombierTEXT space(SB), $0
323*42dedc50SDavid du Colombier	BYTE $' ';
324*42dedc50SDavid du Colombier	BYTE $'\z';
325*42dedc50SDavid du Colombier
326*42dedc50SDavid du ColombierTEXT sharp(SB), $0
327*42dedc50SDavid du Colombier	BYTE $'#'; BYTE $'\z';
328