123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- /*
- * 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 $0x00
- TEXT _sectsize(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _clustsize(SB), $0
- BYTE $0x00
- TEXT _nresrv(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _nfats(SB), $0
- BYTE $0x00
- TEXT _rootsize(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _volsize(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _mediadesc(SB), $0
- BYTE $0x00
- TEXT _fatsize(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _trksize(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _nheads(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _nhiddenlo(SB), $0
- BYTE $0x00; BYTE $0x00
- TEXT _nhiddenhi(SB), $0
- BYTE $0x00; BYTE $0x00;
- TEXT _bigvolsize(SB), $0
- BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
- TEXT _driveno(SB), $0
- BYTE $0x00
- TEXT _reserved0(SB), $0
- BYTE $0x00
- TEXT _bootsig(SB), $0
- BYTE $0x00
- TEXT _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 $0x00
- TEXT _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 */
- /* VMware starts us at 7C0:0. Move to 0:7C00 */
- PUSHR(rAX)
- LWI(_nxt(SB), rAX)
- PUSHR(rAX)
- BYTE $0xCB /* FAR RET */
- TEXT _nxt(SB), $0
- STI
- LWI(confidence(SB), rSI) /* for that warm, fuzzy feeling */
- CALL16(BIOSputs(SB))
- CALL16(dreset(SB))
- _jmp00:
- LW(_volid(SB), rAX) /* Xrootlo */
- LW(_volid+2(SB), rDX) /* Xroothi */
- LWI(_magic+DIROFF(SB), rBX)
- CALL16(BIOSread(SB)) /* read the root directory */
- CALL16(printnl(SB))
- LWI(_magic+DIROFF(SB), rBX)
- LWI((512/2), rCX)
- CALL16(printbuf(SB))
- xloop:
- JMP xloop
- TEXT buggery(SB), $0
- LWI(error(SB), rSI)
- CALL16(BIOSputs(SB))
- TEXT quietbuggery(SB), $0
- xbuggery:
- JMP xbuggery
- /*
- * Read a sector from a disc. On entry:
- * rDX:rAX sector number
- * rES:rBX buffer address
- * For BIOSCALL(0x13):
- * rAH 0x02
- * rAL number of sectors to read (1)
- * rCH low 8 bits of cylinder
- * rCL high 2 bits of cylinder (7-6), sector (5-0)
- * rDH head
- * rDL drive
- * rES:rBX buffer address
- */
- TEXT BIOSread(SB), $0
- LWI(5, rDI) /* retry count (ATAPI ZIPs suck) */
- _retry:
- PUSHA /* may be trashed by BIOSCALL */
- PUSHR(rBX)
- LW(_trksize(SB), rBX)
- LW(_nheads(SB), rDI)
- IMUL(rDI, rBX)
- OR(rBX, rBX)
- JZ _ioerror
- _okay:
- DIV(rBX) /* cylinder -> rAX, track,sector -> rDX */
- MW(rAX, rCX) /* save cylinder */
- ROLI(0x08, rCX) /* swap rC[HL] */
- SHLBI(0x06, rCL) /* move high bits up */
- MW(rDX, rAX)
- CLR(rDX)
- LW(_trksize(SB), rBX)
- DIV(rBX) /* head -> rAX, sector -> rDX */
- INC(rDX) /* sector numbers are 1-based */
- ANDI(0x003F, rDX) /* should not be necessary */
- OR(rDX, rCX)
- MW(rAX, rDX)
- SHLI(0x08, rDX) /* form head */
- LBPB(Xdrive, rDL) /* form drive */
- POPR(rBX)
- LWI(0x0201, rAX) /* form command and sectors */
- BIOSCALL(0x13) /* CF set on failure */
- JCC _BIOSreadret
- POPA
- DEC(rDI) /* too many retries? */
- JEQ _ioerror
- CALL16(dreset(SB))
- JMP _retry
- _ioerror:
- LWI(ioerror(SB), rSI)
- CALL16(BIOSputs(SB))
- JMP xbuggery
- _BIOSreadret:
- POPA
- RET
- TEXT dreset(SB), $0
- PUSHA
- CLR(rAX) /* rAH == 0 == reset disc system */
- LBPB(Xdrive, rDL)
- BIOSCALL(0x13)
- ORB(rAH, rAH) /* status (0 == success) */
- POPA
- JNE _ioerror
- RET
- TEXT printsharp(SB), $0
- LWI(sharp(SB), rSI)
- _doprint:
- CALL16(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)
- BIOSCALL(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)
- CALL16(BIOSputs(SB))
- POPW(rDI)
- POPW(rCX)
- POPW(rBX)
- POPW(rAX)
- CALL16(printspace(SB))
- RET
- TEXT printDXAX(SB), $0
- PUSHW(rAX)
- MW(rDX, rAX)
- CALL16(printAX(SB))
- POPW(rAX)
- CALL16(printAX(SB))
- RET
- TEXT printBX(SB), $0
- PUSHW(rAX)
- MW(rBX, rAX)
- CALL16(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)
- CALL16(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';
- TEXT confidence(SB), $0
- BYTE $'P'; BYTE $'\z'
|