pbsdisklba.s 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. STI
  90. LWI(confidence(SB), rSI) /* for that warm, fuzzy feeling */
  91. CALL(BIOSputs(SB))
  92. LBI(0x41, rAH) /* check extensions present */
  93. LWI(0x55AA, rBX)
  94. LXB(Xdrive, xBP, rDL) /* drive */
  95. SYSCALL(0x13) /* CF set on failure */
  96. JCS _jmp01
  97. CMPI(0xAA55, rBX)
  98. JNE _jmp01
  99. ANDI(0x0001, rCX)
  100. JEQ _jmp01
  101. /* rCX contains 0x0001 */
  102. SBPWI(0x0010, Xdap+0) /* reserved + packet size */
  103. SBPWI(rCX, Xdap+2) /* reserved + # of blocks to transfer */
  104. DEC(rCX)
  105. SBPW(rCX, Xdap+12)
  106. SBPW(rCX, Xdap+14)
  107. /* BIOSread will do this CALL(dreset(SB)) */
  108. _jmp00:
  109. LW(_volid(SB), rAX) /* Xrootlo */
  110. LW(_volid+2(SB), rDX) /* Xroothi */
  111. LWI(_magic+DIROFF(SB), rBX)
  112. CALL(BIOSread(SB)) /* read the root directory */
  113. CALL(printnl(SB))
  114. LWI(_magic+DIROFF(SB), rBX)
  115. LWI((512/2), rCX)
  116. CALL(printbuf(SB))
  117. xloop:
  118. JMP xloop
  119. _jmp01:
  120. TEXT buggery(SB), $0
  121. LWI(error(SB), rSI)
  122. CALL(BIOSputs(SB))
  123. xbuggery:
  124. JMP xbuggery
  125. /*
  126. * Read a sector from a disc. On entry:
  127. * rDX:rAX sector number
  128. * rES:rBX buffer address
  129. */
  130. TEXT BIOSread(SB), $0
  131. LWI(5, rDI) /* retry count (ATAPI ZIPs suck) */
  132. _retry:
  133. PUSHA /* may be trashed by SYSCALL */
  134. SBPW(rBX, Xdap+4) /* transfer buffer :offset */
  135. MFSR(rES, rDI) /* transfer buffer seg: */
  136. SBPW(rDI, Xdap+6)
  137. SBPW(rAX, Xdap+8) /* LBA (64-bits) */
  138. SBPW(rDX, Xdap+10)
  139. MW(rBP, rSI) /* disk address packet */
  140. LBI(0x42, rAH) /* extended read */
  141. LBPB(Xdrive, rDL) /* form drive */
  142. SYSCALL(0x13) /* CF set on failure */
  143. JCC _BIOSreadret
  144. POPA
  145. DEC(rDI) /* too many retries? */
  146. JEQ _ioerror
  147. CALL(dreset(SB))
  148. JMP _retry
  149. _ioerror:
  150. LWI(ioerror(SB), rSI)
  151. CALL(BIOSputs(SB))
  152. JMP xbuggery
  153. _BIOSreadret:
  154. POPA
  155. RET
  156. TEXT dreset(SB), $0
  157. PUSHA
  158. CLR(rAX) /* rAH == 0 == reset disc system */
  159. LBPB(Xdrive, rDL)
  160. SYSCALL(0x13)
  161. ORB(rAH, rAH) /* status (0 == success) */
  162. POPA
  163. JNE _ioerror
  164. RET
  165. TEXT printsharp(SB), $0
  166. LWI(sharp(SB), rSI)
  167. _doprint:
  168. CALL(BIOSputs(SB))
  169. RET
  170. TEXT printspace(SB), $0
  171. LWI(space(SB), rSI)
  172. JMP _doprint
  173. TEXT printnl(SB), $0
  174. LWI(nl(SB), rSI)
  175. JMP _doprint
  176. /*
  177. * Output a string to the display.
  178. * String argument is in rSI.
  179. */
  180. TEXT BIOSputs(SB), $0
  181. PUSHA
  182. CLR(rBX)
  183. _BIOSputs:
  184. LODSB
  185. ORB(rAL, rAL)
  186. JEQ _BIOSputsret
  187. LBI(0x0E, rAH)
  188. SYSCALL(0x10)
  189. JMP _BIOSputs
  190. _BIOSputsret:
  191. POPA
  192. RET
  193. /*
  194. * Output a register to the display.
  195. */
  196. TEXT printAX(SB), $0
  197. PUSHW(rAX)
  198. PUSHW(rBX)
  199. PUSHW(rCX)
  200. PUSHW(rDI)
  201. LWI(4, rCX)
  202. LWI(numbuf+4(SB), rSI)
  203. _nextchar:
  204. DEC(rSI)
  205. MW(rAX, rBX)
  206. ANDI(0x000F, rBX)
  207. ADDI(0x30, rBX) /* 0x30 = '0' */
  208. CMPI(0x39, rBX) /* 0x39 = '9' */
  209. JLE _dowrite
  210. ADDI(0x07, rBX) /* 0x07 = 'A'-(1+'9')*/
  211. _dowrite:
  212. SXB(rBL, 0, xSI)
  213. SHRI(4, rAX)
  214. DEC(rCX)
  215. JNE _nextchar
  216. LWI(numbuf(SB), rSI)
  217. CALL(BIOSputs(SB))
  218. POPW(rDI)
  219. POPW(rCX)
  220. POPW(rBX)
  221. POPW(rAX)
  222. CALL(printspace(SB))
  223. RET
  224. TEXT printDXAX(SB), $0
  225. PUSHW(rAX)
  226. MW(rDX, rAX)
  227. CALL(printAX(SB))
  228. POPW(rAX)
  229. CALL(printAX(SB))
  230. RET
  231. TEXT printBX(SB), $0
  232. PUSHW(rAX)
  233. MW(rBX, rAX)
  234. CALL(printAX(SB))
  235. POPW(rAX)
  236. RET
  237. /*
  238. * Output some number of words to the display
  239. * rDS:rDI - buffer
  240. * rCX: number of words
  241. */
  242. TEXT printbuf(SB), $0
  243. PUSHW(rAX)
  244. PUSHW(rBX)
  245. PUSHW(rCX)
  246. _nextword:
  247. LXW(0, xBX, rAX)
  248. CALL(printAX(SB))
  249. INC(rBX)
  250. INC(rBX)
  251. DEC(rCX)
  252. JNE _nextword
  253. POPW(rCX)
  254. POPW(rBX)
  255. POPW(rAX)
  256. RET
  257. TEXT error(SB), $0
  258. BYTE $'E';
  259. TEXT ioerror(SB), $0
  260. BYTE $'I';
  261. TEXT nl(SB), $0
  262. BYTE $'\r';
  263. BYTE $'\n';
  264. BYTE $'\z';
  265. TEXT numbuf(SB), $0
  266. BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';
  267. BYTE $'\z';
  268. TEXT space(SB), $0
  269. BYTE $' ';
  270. BYTE $'\z';
  271. TEXT sharp(SB), $0
  272. BYTE $'#'; BYTE $'\z';