Charles.Forsyth20060303644188019 years agoHistory
327 lines · 5.9 KB · Assembly
RawDownload
/* * Debugging boot sector.  Reads the first directory * sector from disk and displays it. * * It relies on the _volid field in the FAT header containing * the LBA of the root directory. */#include "x16.h" #define DIROFF		0x00200		/* where to read the root directory (offset) */#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */#define LOADOFF		0 /* * FAT directory entry. */#define Dname		0x00#define Dext		0x08#define Dattr		0x0B#define Dtime		0x16#define Ddate		0x18#define Dstart		0x1A#define Dlengthlo	0x1C#define Dlengthhi	0x1E #define Dirsz		0x20 /* * We keep data on the stack, indexed by rBP. */#define Xdrive		0x00		/* boot drive, passed by BIOS in rDL */#define Xrootlo		0x02		/* offset of root directory */#define Xroothi		0x04#define Xrootsz		0x06		/* file data area */#define Xtotal		0x08		/* sum of allocated data above */#define Xdap		0x00		/* disc address packet */ TEXT _magic(SB), $0	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */	BYTE $0x90			/* nop */TEXT _version(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00TEXT _sectsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _clustsize(SB), $0	BYTE $0x00TEXT _nresrv(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nfats(SB), $0	BYTE $0x00TEXT _rootsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _volsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _mediadesc(SB), $0	BYTE $0x00TEXT _fatsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _trksize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nheads(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nhiddenlo(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nhiddenhi(SB), $0	BYTE $0x00; BYTE $0x00;TEXT _bigvolsize(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;TEXT _driveno(SB), $0	BYTE $0x00TEXT _reserved0(SB), $0	BYTE $0x00TEXT _bootsig(SB), $0	BYTE $0x00TEXT _volid(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;TEXT _label(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00	BYTE $0x00; BYTE $0x00; BYTE $0x00TEXT _type(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00; _start0x3E:	CLI	CLR(rAX)	MTSR(rAX, rSS)			/* 0000 -> rSS */	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */	MTSR(rAX, rES)	LWI(_magic-Xtotal(SB), rSP)	MW(rSP, rBP)			/* set the indexed-data pointer */ 	SBPB(rDL, Xdrive)		/* save the boot drive */ 	STI 	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */	CALL(BIOSputs(SB)) 	LBI(0x41, rAH)			/* check extensions present */	LWI(0x55AA, rBX)	LXB(Xdrive, xBP, rDL)		/* drive */	SYSCALL(0x13)			/* CF set on failure */	JCS _jmp01	CMPI(0xAA55, rBX)	JNE _jmp01	ANDI(0x0001, rCX)	JEQ _jmp01 					/* rCX contains 0x0001 */	SBPWI(0x0010, Xdap+0)		/* reserved + packet size */	SBPWI(rCX, Xdap+2)		/* reserved + # of blocks to transfer */ 	DEC(rCX)	SBPW(rCX, Xdap+12)	SBPW(rCX, Xdap+14) /* BIOSread will do this 	CALL(dreset(SB)) */ _jmp00:	LW(_volid(SB), rAX)		/* Xrootlo */	LW(_volid+2(SB), rDX)		/* Xroothi */ 	LWI(_magic+DIROFF(SB), rBX)	CALL(BIOSread(SB))		/* read the root directory */ 	CALL(printnl(SB))	LWI(_magic+DIROFF(SB), rBX)	LWI((512/2), rCX)	CALL(printbuf(SB)) xloop:	JMP xloop  _jmp01: TEXT buggery(SB), $0	LWI(error(SB), rSI)	CALL(BIOSputs(SB)) xbuggery:	JMP xbuggery /* * Read a sector from a disc. On entry: *   rDX:rAX	sector number *   rES:rBX	buffer address */TEXT BIOSread(SB), $0	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */_retry:	PUSHA				/* may be trashed by SYSCALL */ 	SBPW(rBX, Xdap+4)		/* transfer buffer :offset */	MFSR(rES, rDI)			/* transfer buffer seg: */	SBPW(rDI, Xdap+6)	SBPW(rAX, Xdap+8)		/* LBA (64-bits) */	SBPW(rDX, Xdap+10) 	MW(rBP, rSI)			/* disk address packet */	LBI(0x42, rAH)			/* extended read */	LBPB(Xdrive, rDL)		/* form drive */	SYSCALL(0x13)			/* CF set on failure */	JCC _BIOSreadret 	POPA	DEC(rDI)			/* too many retries? */	JEQ _ioerror 	CALL(dreset(SB))	JMP _retry _ioerror:	LWI(ioerror(SB), rSI)	CALL(BIOSputs(SB))	JMP xbuggery _BIOSreadret:	POPA	RET TEXT dreset(SB), $0	PUSHA	CLR(rAX)			/* rAH == 0 == reset disc system */	LBPB(Xdrive, rDL)	SYSCALL(0x13)	ORB(rAH, rAH)			/* status (0 == success) */	POPA	JNE _ioerror	RET  TEXT printsharp(SB), $0	LWI(sharp(SB), rSI)_doprint:	CALL(BIOSputs(SB))	RET TEXT printspace(SB), $0	LWI(space(SB), rSI)	JMP _doprint TEXT printnl(SB), $0	LWI(nl(SB), rSI)	JMP _doprint /* * Output a string to the display. * String argument is in rSI. */TEXT BIOSputs(SB), $0	PUSHA	CLR(rBX)_BIOSputs:	LODSB	ORB(rAL, rAL)	JEQ _BIOSputsret 	LBI(0x0E, rAH)	SYSCALL(0x10)	JMP _BIOSputs _BIOSputsret:	POPA	RET /* * Output a register to the display. */TEXT printAX(SB), $0	PUSHW(rAX)	PUSHW(rBX)	PUSHW(rCX)	PUSHW(rDI) 	LWI(4, rCX)	LWI(numbuf+4(SB), rSI) _nextchar:	DEC(rSI)	MW(rAX, rBX)	ANDI(0x000F, rBX)	ADDI(0x30, rBX)	/* 0x30 = '0' */	CMPI(0x39, rBX)	/* 0x39 = '9' */	JLE _dowrite	ADDI(0x07, rBX)	/* 0x07 = 'A'-(1+'9')*/ _dowrite:	SXB(rBL, 0, xSI)	SHRI(4, rAX) 	DEC(rCX)	JNE _nextchar 	LWI(numbuf(SB), rSI)	CALL(BIOSputs(SB)) 	POPW(rDI)	POPW(rCX)	POPW(rBX)	POPW(rAX) 	CALL(printspace(SB))	RET TEXT printDXAX(SB), $0	PUSHW(rAX)	MW(rDX, rAX)	CALL(printAX(SB))	POPW(rAX)	CALL(printAX(SB))	RET TEXT printBX(SB), $0	PUSHW(rAX)	MW(rBX, rAX)	CALL(printAX(SB))	POPW(rAX)	RET /* * Output some number of words to the display * rDS:rDI - buffer * rCX: number of words */TEXT printbuf(SB), $0	PUSHW(rAX)	PUSHW(rBX)	PUSHW(rCX) _nextword:	LXW(0, xBX, rAX)	CALL(printAX(SB))	INC(rBX)	INC(rBX)	DEC(rCX)	JNE _nextword 	POPW(rCX)	POPW(rBX)	POPW(rAX)	RET TEXT error(SB), $0	BYTE $'E';  TEXT ioerror(SB), $0	BYTE $'I';  TEXT nl(SB), $0	BYTE $'\r';	BYTE $'\n';	BYTE $'\z'; TEXT numbuf(SB), $0	BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';	BYTE $'\z'; TEXT space(SB), $0	BYTE $' ';	BYTE $'\z'; TEXT sharp(SB), $0	BYTE $'#'; BYTE $'\z';