pbsdisk.s 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * Debugging boot sector. Reads the first directory
  3. * sector from disk and displays it.
  4. *
  5. * It relies on the _volid field in the FAT header containing
  6. * the LBA of the root directory.
  7. */
  8. #include "x16.h"
  9. #define DIROFF 0x00200 /* where to read the root directory (offset) */
  10. #define LOADSEG (0x10000/16) /* where to load code (64KB) */
  11. #define LOADOFF 0
  12. /*
  13. * FAT directory entry.
  14. */
  15. #define Dname 0x00
  16. #define Dext 0x08
  17. #define Dattr 0x0B
  18. #define Dtime 0x16
  19. #define Ddate 0x18
  20. #define Dstart 0x1A
  21. #define Dlengthlo 0x1C
  22. #define Dlengthhi 0x1E
  23. #define Dirsz 0x20
  24. /*
  25. * We keep data on the stack, indexed by rBP.
  26. */
  27. #define Xdrive 0x00 /* boot drive, passed by BIOS in rDL */
  28. #define Xrootlo 0x02 /* offset of root directory */
  29. #define Xroothi 0x04
  30. #define Xrootsz 0x06 /* file data area */
  31. #define Xtotal 0x08 /* sum of allocated data above */
  32. #define Xdap 0x00 /* disc address packet */
  33. TEXT _magic(SB), $0
  34. BYTE $0xEB; BYTE $0x3C; /* jmp .+ 0x3C (_start0x3E) */
  35. BYTE $0x90 /* nop */
  36. TEXT _version(SB), $0
  37. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
  38. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
  39. TEXT _sectsize(SB), $0
  40. BYTE $0x00; BYTE $0x00
  41. TEXT _clustsize(SB), $0
  42. BYTE $0x00
  43. TEXT _nresrv(SB), $0
  44. BYTE $0x00; BYTE $0x00
  45. TEXT _nfats(SB), $0
  46. BYTE $0x00
  47. TEXT _rootsize(SB), $0
  48. BYTE $0x00; BYTE $0x00
  49. TEXT _volsize(SB), $0
  50. BYTE $0x00; BYTE $0x00
  51. TEXT _mediadesc(SB), $0
  52. BYTE $0x00
  53. TEXT _fatsize(SB), $0
  54. BYTE $0x00; BYTE $0x00
  55. TEXT _trksize(SB), $0
  56. BYTE $0x00; BYTE $0x00
  57. TEXT _nheads(SB), $0
  58. BYTE $0x00; BYTE $0x00
  59. TEXT _nhiddenlo(SB), $0
  60. BYTE $0x00; BYTE $0x00
  61. TEXT _nhiddenhi(SB), $0
  62. BYTE $0x00; BYTE $0x00;
  63. TEXT _bigvolsize(SB), $0
  64. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
  65. TEXT _driveno(SB), $0
  66. BYTE $0x00
  67. TEXT _reserved0(SB), $0
  68. BYTE $0x00
  69. TEXT _bootsig(SB), $0
  70. BYTE $0x00
  71. TEXT _volid(SB), $0
  72. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
  73. TEXT _label(SB), $0
  74. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
  75. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
  76. BYTE $0x00; BYTE $0x00; BYTE $0x00
  77. TEXT _type(SB), $0
  78. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
  79. BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
  80. _start0x3E:
  81. CLI
  82. CLR(rAX)
  83. MTSR(rAX, rSS) /* 0000 -> rSS */
  84. MTSR(rAX, rDS) /* 0000 -> rDS, source segment */
  85. MTSR(rAX, rES)
  86. LWI(_magic-Xtotal(SB), rSP)
  87. MW(rSP, rBP) /* set the indexed-data pointer */
  88. SBPB(rDL, Xdrive) /* save the boot drive */
  89. /* VMware starts us at 7C0:0. Move to 0:7C00 */
  90. PUSHR(rAX)
  91. LWI(_nxt(SB), rAX)
  92. PUSHR(rAX)
  93. BYTE $0xCB /* FAR RET */
  94. TEXT _nxt(SB), $0
  95. STI
  96. LWI(confidence(SB), rSI) /* for that warm, fuzzy feeling */
  97. CALL16(BIOSputs(SB))
  98. CALL16(dreset(SB))
  99. _jmp00:
  100. LW(_volid(SB), rAX) /* Xrootlo */
  101. LW(_volid+2(SB), rDX) /* Xroothi */
  102. LWI(_magic+DIROFF(SB), rBX)
  103. CALL16(BIOSread(SB)) /* read the root directory */
  104. CALL16(printnl(SB))
  105. LWI(_magic+DIROFF(SB), rBX)
  106. LWI((512/2), rCX)
  107. CALL16(printbuf(SB))
  108. xloop:
  109. JMP xloop
  110. TEXT buggery(SB), $0
  111. LWI(error(SB), rSI)
  112. CALL16(BIOSputs(SB))
  113. TEXT quietbuggery(SB), $0
  114. xbuggery:
  115. JMP xbuggery
  116. /*
  117. * Read a sector from a disc. On entry:
  118. * rDX:rAX sector number
  119. * rES:rBX buffer address
  120. * For BIOSCALL(0x13):
  121. * rAH 0x02
  122. * rAL number of sectors to read (1)
  123. * rCH low 8 bits of cylinder
  124. * rCL high 2 bits of cylinder (7-6), sector (5-0)
  125. * rDH head
  126. * rDL drive
  127. * rES:rBX buffer address
  128. */
  129. TEXT BIOSread(SB), $0
  130. LWI(5, rDI) /* retry count (ATAPI ZIPs suck) */
  131. _retry:
  132. PUSHA /* may be trashed by BIOSCALL */
  133. PUSHR(rBX)
  134. LW(_trksize(SB), rBX)
  135. LW(_nheads(SB), rDI)
  136. IMUL(rDI, rBX)
  137. OR(rBX, rBX)
  138. JZ _ioerror
  139. _okay:
  140. DIV(rBX) /* cylinder -> rAX, track,sector -> rDX */
  141. MW(rAX, rCX) /* save cylinder */
  142. ROLI(0x08, rCX) /* swap rC[HL] */
  143. SHLBI(0x06, rCL) /* move high bits up */
  144. MW(rDX, rAX)
  145. CLR(rDX)
  146. LW(_trksize(SB), rBX)
  147. DIV(rBX) /* head -> rAX, sector -> rDX */
  148. INC(rDX) /* sector numbers are 1-based */
  149. ANDI(0x003F, rDX) /* should not be necessary */
  150. OR(rDX, rCX)
  151. MW(rAX, rDX)
  152. SHLI(0x08, rDX) /* form head */
  153. LBPB(Xdrive, rDL) /* form drive */
  154. POPR(rBX)
  155. LWI(0x0201, rAX) /* form command and sectors */
  156. BIOSCALL(0x13) /* CF set on failure */
  157. JCC _BIOSreadret
  158. POPA
  159. DEC(rDI) /* too many retries? */
  160. JEQ _ioerror
  161. CALL16(dreset(SB))
  162. JMP _retry
  163. _ioerror:
  164. LWI(ioerror(SB), rSI)
  165. CALL16(BIOSputs(SB))
  166. JMP xbuggery
  167. _BIOSreadret:
  168. POPA
  169. RET
  170. TEXT dreset(SB), $0
  171. PUSHA
  172. CLR(rAX) /* rAH == 0 == reset disc system */
  173. LBPB(Xdrive, rDL)
  174. BIOSCALL(0x13)
  175. ORB(rAH, rAH) /* status (0 == success) */
  176. POPA
  177. JNE _ioerror
  178. RET
  179. TEXT printsharp(SB), $0
  180. LWI(sharp(SB), rSI)
  181. _doprint:
  182. CALL16(BIOSputs(SB))
  183. RET
  184. TEXT printspace(SB), $0
  185. LWI(space(SB), rSI)
  186. JMP _doprint
  187. TEXT printnl(SB), $0
  188. LWI(nl(SB), rSI)
  189. JMP _doprint
  190. /*
  191. * Output a string to the display.
  192. * String argument is in rSI.
  193. */
  194. TEXT BIOSputs(SB), $0
  195. PUSHA
  196. CLR(rBX)
  197. _BIOSputs:
  198. LODSB
  199. ORB(rAL, rAL)
  200. JEQ _BIOSputsret
  201. LBI(0x0E, rAH)
  202. BIOSCALL(0x10)
  203. JMP _BIOSputs
  204. _BIOSputsret:
  205. POPA
  206. RET
  207. /*
  208. * Output a register to the display.
  209. */
  210. TEXT printAX(SB), $0
  211. PUSHW(rAX)
  212. PUSHW(rBX)
  213. PUSHW(rCX)
  214. PUSHW(rDI)
  215. LWI(4, rCX)
  216. LWI(numbuf+4(SB), rSI)
  217. _nextchar:
  218. DEC(rSI)
  219. MW(rAX, rBX)
  220. ANDI(0x000F, rBX)
  221. ADDI(0x30, rBX) /* 0x30 = '0' */
  222. CMPI(0x39, rBX) /* 0x39 = '9' */
  223. JLE _dowrite
  224. ADDI(0x07, rBX) /* 0x07 = 'A'-(1+'9')*/
  225. _dowrite:
  226. SXB(rBL, 0, xSI)
  227. SHRI(4, rAX)
  228. DEC(rCX)
  229. JNE _nextchar
  230. LWI(numbuf(SB), rSI)
  231. CALL16(BIOSputs(SB))
  232. POPW(rDI)
  233. POPW(rCX)
  234. POPW(rBX)
  235. POPW(rAX)
  236. CALL16(printspace(SB))
  237. RET
  238. TEXT printDXAX(SB), $0
  239. PUSHW(rAX)
  240. MW(rDX, rAX)
  241. CALL16(printAX(SB))
  242. POPW(rAX)
  243. CALL16(printAX(SB))
  244. RET
  245. TEXT printBX(SB), $0
  246. PUSHW(rAX)
  247. MW(rBX, rAX)
  248. CALL16(printAX(SB))
  249. POPW(rAX)
  250. RET
  251. /*
  252. * Output some number of words to the display
  253. * rDS:rDI - buffer
  254. * rCX: number of words
  255. */
  256. TEXT printbuf(SB), $0
  257. PUSHW(rAX)
  258. PUSHW(rBX)
  259. PUSHW(rCX)
  260. _nextword:
  261. LXW(0, xBX, rAX)
  262. CALL16(printAX(SB))
  263. INC(rBX)
  264. INC(rBX)
  265. DEC(rCX)
  266. JNE _nextword
  267. POPW(rCX)
  268. POPW(rBX)
  269. POPW(rAX)
  270. RET
  271. TEXT error(SB), $0
  272. BYTE $'E';
  273. TEXT ioerror(SB), $0
  274. BYTE $'I';
  275. TEXT nl(SB), $0
  276. BYTE $'\r';
  277. BYTE $'\n';
  278. BYTE $'\z';
  279. TEXT numbuf(SB), $0
  280. BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';
  281. BYTE $'\z';
  282. TEXT space(SB), $0
  283. BYTE $' ';
  284. BYTE $'\z';
  285. TEXT sharp(SB), $0
  286. BYTE $'#'; BYTE $'\z';
  287. TEXT confidence(SB), $0
  288. BYTE $'P'; BYTE $'\z'