📄 pbsdisklba.s
字号:
/* * 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 RETTEXT 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 RETTEXT printsharp(SB), $0 LWI(sharp(SB), rSI)_doprint: CALL(BIOSputs(SB)) RETTEXT printspace(SB), $0 LWI(space(SB), rSI) JMP _doprintTEXT 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)) RETTEXT printDXAX(SB), $0 PUSHW(rAX) MW(rDX, rAX) CALL(printAX(SB)) POPW(rAX) CALL(printAX(SB)) RETTEXT 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) RETTEXT 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';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -