DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

494 lines
12 KiB

4 years ago
  1. ;------------------------------------------------------------------------
  2. ; :
  3. ; File: ms96tpi.asm :
  4. ; :
  5. ; This file contains code to support the 96 tpi drives. The code :
  6. ; is included in the bio if the machine has at least one drive with :
  7. ; changeline support. If the machine has no changeline drives then :
  8. ; the code is not kept in the bio at system initialization time. :
  9. ; :
  10. ;------------------------------------------------------------------------
  11. ;------------------------------------------------------------------------
  12. ; :
  13. ; DISK OPEN/CLOSE ROUTINES :
  14. ; :
  15. ;------------------------------------------------------------------------
  16. DSK$OPEN:
  17. PUBLIC DSK$OPEN
  18. Message fTestDisk,<"Disk Open "> ; print debug messages
  19. MNUM fTestDisk,AX
  20. Message fTestDisk,<CR,LF>
  21. ; AL is logical drive
  22. call SetDrive ; Get BDS for drive
  23. inc WORD PTR ds:[di].opcnt
  24. jmp EXIT
  25. DSK$CLOSE:
  26. PUBLIC DSK$CLOSE
  27. Message fTestDisk,<"Disk Close "> ; print debug messages
  28. MNUM fTestDisk,AX
  29. Message fTestDisk,<CR,LF>
  30. ; AL is logical drive
  31. call SetDrive ; Get BDS for drive
  32. cmp WORD PTR ds:[di].opcnt,0
  33. jz EXITJX ; Watch out for wrap
  34. dec WORD PTR ds:[di].opcnt
  35. EXITJX:
  36. jmp EXIT
  37. ;
  38. ; ChkOpCnt checks the number of open files on drive.
  39. ;
  40. ; Input : DS:DI points to current BDS for drive.
  41. ;
  42. ; Return : zero set if no open files
  43. ; zero reset if open files
  44. ;
  45. ChkOpCnt:
  46. Message fTest96,<"Check open count "> ; print debug messages
  47. MNUM fTest96,AX
  48. Message fTest96,<CR,LF>
  49. cmp WORD PTR ds:[di].opcnt,0
  50. ret
  51. ;
  52. ; At media check time, we need to really get down and check what the change is.
  53. ; This is GUARANTEED to be expensive.
  54. ;
  55. ; On entry AL contains logical drive number
  56. ;
  57. public mediacheck
  58. MediaCheck:
  59. call CheckSingle ; make sure correct disk is in place
  60. xor SI,SI
  61. call HasChange
  62. jz MediaRet
  63. call CheckROMChange
  64. jnz MediaDoVOLID
  65. push AX
  66. push DX
  67. ; see if changeline has been triggered
  68. ;;Rev 3.30 Modification
  69. mov DL, DS:[DI.drivenum] ; set logical drive number
  70. mov AH, 16h ; get changeline status
  71. int 13h ; call rom diskette routine
  72. ;;End of Modification
  73. pop DX
  74. pop AX
  75. jc MediaDoVolid ; if changeline was triggered jmp
  76. mov SI,1 ; else signal no change
  77. ; There are some drives with changeline that "lose" the changeline indication
  78. ; if a different drive is accessed after the current one. In order to avoid
  79. ; missing a media change, we return an "I don't know" to DOS if the changeline
  80. ; is not active AND we are accessing a different drive from the last one.
  81. ; If we are accessing the same drive, then we can safely rely on the changeline
  82. ; status.
  83. PUBLIC LOSECHNG
  84. LOSECHNG:
  85. mov bl,cs:[Tim_Drv] ; get last drive accessed
  86. cmp byte ptr [di].DriveNum,bl
  87. jz MediaRet
  88. ; Do the 2 second twiddle. If time >= 2 seconds, do a volid check.
  89. ; Otherwise return "I don't know" (Strictly speaking, we should return a
  90. ; "Not Changed" here since the 2 second test said no change.) - RS.
  91. SaveReg <AX,CX,DX>
  92. call Check_Time_Of_Access
  93. RestoreReg <DX,CX,AX>
  94. or si,si
  95. jz MediaDoVolid ; Check_Time says ">= 2 secs passed"
  96. xor si,si ; return "I don't know"
  97. Public MediaRet
  98. MediaRet:
  99. ret
  100. ;
  101. ; MediaDoVolid: if this is called somehow the media was changed. Look at
  102. ; VID to see. We do not look at FAT because this may be different since we
  103. ; only set MedByt when doing a READ or WRITE.
  104. ;
  105. MediaDoVolid:
  106. call GETBP ; build a new BPB in current BDS
  107. jc MediaRet
  108. call Check_VID
  109. jnc MediaRet
  110. call MapError ; fix up AL for return to DOS
  111. ret
  112. ;
  113. ; Checklatchio:
  114. ;
  115. ; Simple, quick check of latched change. If no indication, then return
  116. ; otherwise do expensive check. If the expensive test fails, POP off the
  117. ; return and set AL = 15 (for invalid media change) which will be returned to
  118. ; DOS.
  119. ;
  120. public checklatchio
  121. CheckLatchIO:
  122. ; If returning fake BPB then assume the disk has not changed
  123. ; test word ptr ds:[di].flags, RETURN_FAKE_BPB
  124. ; jnz CheckRet
  125. ;;Rev 3.30 Modification
  126. call HasChange ;change line supported?
  127. jz CheckRet ;No. Just return
  128. ;;End of Modification
  129. call ChkOpCnt
  130. jnz CheckROM
  131. CheckRet:
  132. ret
  133. ;
  134. ; Check for past ROM indications. If no ROM change indicated, then return OK.
  135. ;
  136. public checkrom
  137. CheckROM:
  138. call CheckROMChange
  139. jz CheckRet ; no change
  140. ;
  141. ; We now see that a change line has been seen in the past. Let's do the
  142. ; expensive verification.
  143. ;
  144. Message fTest96,<"CheckROMChange says yes...",CR,LF>
  145. call GETBP ; build BPB in current BDS
  146. jc Ret_No_Error_Map ; GETBP has already called MapError
  147. call Check_VID
  148. jc CheckLatchRet ; disk error trying to read in.
  149. or SI,SI ; Is changed for sure?
  150. jns CheckRet
  151. call ReturnVid
  152. CheckLatchRet:
  153. call MapError ; fix up AL for return to DOS
  154. Ret_No_Error_Map:
  155. stc ; indicate an error
  156. pop si ; pop off return address
  157. ret
  158. ;
  159. ; CheckFatVID:
  160. ;
  161. ; Check the FAT and the VID. Return in DI -1 or 0. Return with carry set
  162. ; ONLY if there was a disk error. Return that error code in AX.
  163. ;
  164. public checkfatvid
  165. CheckFATVID:
  166. Message fTest96,<"Check FAT",CR,LF>
  167. call FAT_Check
  168. or SI,SI
  169. js Changed_Drv
  170. ;
  171. ; The fat was the same. How about the volume ID?
  172. ;
  173. Check_VID:
  174. Message fTest96,<"Check VID",CR,LF>
  175. call Read_volume_ID
  176. jc CheckFatRet
  177. call Check_Volume_id
  178. or SI,SI
  179. jnz Changed_Drv
  180. Message fTest96,<"VID not changed",CR,LF>
  181. call ResetChanged
  182. CheckFatRet:
  183. ret
  184. Changed_Drv:
  185. mov cs:[Tim_Drv],-1 ; Ensure that we ask ROM for media
  186. ret ; check next time round
  187. ;
  188. ; CheckIO: At I/O time the rom-bios returned an error. We need to
  189. ; determine if the error is due to a media change. If error code is not
  190. ; change-line error (06h) we just return. We pop off the call and jmp to
  191. ; harderr if we see an error.
  192. ;
  193. ; On entry: AH contains error code returned from rom-bios.
  194. ;
  195. public checkio
  196. CheckIO:
  197. cmp AH,06 ; change line error?
  198. jnz CheckFatRet ; no - just return
  199. call ChkOpCnt
  200. jz CheckFATRet ; no open files
  201. ; If returning fake BPB then ignore disk changes
  202. ; test word ptr ds:[di].flags, RETURN_FAKE_BPB
  203. ; jnz IgnoreChange
  204. call GETBP ; build up a new BPB in current BDS
  205. jc No_Error_Map ; GETBP has already called MapError
  206. call CheckFATVID
  207. jc CheckIORet ; disk error trying to read in.
  208. or SI,SI ; Is changed for sure?
  209. js CheckIOErr ; yes changed
  210. IgnoreChange:
  211. inc BP ; allow a retry
  212. ret
  213. CheckIOErr:
  214. call ReturnVid
  215. CheckIORet:
  216. stc ; make sure carry gets passed through
  217. jmp HardErr
  218. No_Error_Map:
  219. jmp HardErr2
  220. ;
  221. ; Return VID sets up the VID for a return to DOS.
  222. ;
  223. Public ReturnVID
  224. ReturnVID:
  225. Message fTest96,<"Return VID",cr,lf>
  226. push DS ; save pointer to current BDS
  227. push di
  228. push cx
  229. call init_vid_loop ; Sets ES:DI -> vid
  230. lds BX,cs:[PTRSAV]
  231. mov [BX.EXTRA],DI
  232. mov [BX.EXTRA+2],ES
  233. pop cx
  234. pop di ; restore current BDS
  235. pop DS
  236. ;; MOV AH,6 ; INVALID MEDIA CHANGE
  237. mov AH, 0Fh ; set error as 'invalid media change'
  238. stc ; indicate error by setting carry flag
  239. ret
  240. ;
  241. ; Media_Set_VID:
  242. ;
  243. ; Moves the pointer to the volid for the drive into the original request packet
  244. ; On entry, DS:BX points to the original packet.
  245. ; No attempt is made to preserve registers.
  246. ;
  247. MEDIA_SET_VID:
  248. PUBLIC MEDIA_SET_VID ;;Rev 3.30 Modification
  249. call init_vid_loop ; Sets ES:DI -> vid ;;End of Modification
  250. lds bx,cs:[PtrSav] ; get pointer to packet
  251. mov word ptr [BX.TRANS+1],DI
  252. mov word ptr [BX.TRANS+3],ES
  253. ret
  254. ;
  255. ; HiDensity - examine a drive/media descriptor to set the media type. If
  256. ; the media descriptor is NOT F9 (not 96tpi or 3 1/2), we return and let the
  257. ; caller do the rest. Otherwise, we pop off the return and jump to the tail
  258. ; of GETBP. For 3.5" media, we just return.
  259. ;
  260. ; Inputs: DS:DI point to correct BDS for this drive
  261. ; AH has media byte
  262. ;
  263. ; Outputs: Carry clear
  264. ; No registers modified
  265. ; Carry set
  266. ; AL = sectors/fat
  267. ; BH = number of root directory entries
  268. ; BL = sectors per track
  269. ; CX = number of sectors
  270. ; DH = sectors per allocation unit
  271. ; DL = number of heads
  272. ;
  273. hidensity:
  274. PUBLIC HIDENSITY ;;Rev 3.30 Modification
  275. ;;End of Modification
  276. ; Check for correct drive
  277. ;
  278. test word ptr ds:[di].flags,fChangeline ; is it special?
  279. jz DoFloppy ; no, do normal floppy test
  280. ;
  281. ; We have a media byte that is pretty complex. Examine drive information
  282. ; table to see what kind it is.
  283. ;
  284. cmp byte ptr ds:[di].FormFactor,ffSmall; Is it single-media?
  285. jz DoFloppy ; yes, use fatid...
  286. ;
  287. ; 96 tpi drive
  288. ;
  289. cmp AH,0F9h
  290. jnz DoFloppy
  291. mov al,7 ; seven sectors / fat
  292. mov bx,224*256+0fh ; 224 root dir entries & 0f sector max
  293. mov cx,80*15*2 ; 80 tracks, 15 sectors/track, 2 sides
  294. mov dx,01*256+2 ; sectors/allocation unit & head max
  295. popr:
  296. add SP,2 ; pop off return address
  297. jmp has1_res ; return to tail of GETBP
  298. DoFloppy:
  299. ret
  300. PATHSTART 001,TPI96 ;;Rev 3.30 Modification
  301. ;;End of Modification
  302. ;
  303. ; Certain poorly designed programs avoid DOS altogether and use INT 13 directly.
  304. ; These programs even retry operations and, thus, will ignore the disk change
  305. ; logic.
  306. ;
  307. ; We hook INT 13 and note all errors.
  308. ;
  309. assume ds:nothing,es:nothing,ss:nothing
  310. Public REAL13
  311. Real13 dd ?
  312. OldInt dd ?
  313. dmy dw ?
  314. PATHEND 001,TPI96 ;;Rev 3.30 Modification
  315. ;;End of Modification
  316. Public Int13
  317. Int13 proc FAR
  318. pop word ptr OldInt
  319. pop word ptr OldInt+2
  320. pop DMY
  321. MESSAGE FTEST13,<"*"> ;;Rev 3.30 Modification
  322. pushf ;;End of Modification
  323. call REAL13 ; simulate another INT 13
  324. jc Err13 ; did an error occur?
  325. jmp OldInt ; no, return and pop off flags
  326. Err13:
  327. MESSAGE FTEST13,<"INT 13 ERROR "> ;;Rev 3.30 Modification
  328. MNUM FTEST13,AX
  329. MESSAGE FTEST13,<CR,LF>
  330. pushf ; save state
  331. cmp AH,06h ; is error a 'change' error?
  332. jz GOTERR ; yes, jump down
  333. B: popf ; no, some other error, ignore it ;;End of Modification
  334. jmp OldInt ; return and pop off flags
  335. GotErr: or DL,DL ; is this for the hard disk?
  336. js B ; yes, ignore
  337. mov word ptr cs:[FlagBits],fChanged
  338. call Set_Changed_DL
  339. jmp B
  340. INT13 endp
  341. ;
  342. ; Set_Changed_DL - Sets flag bits according to bits set in [FlagBits].
  343. ; Essentially used to indicate Changeline, or Format.
  344. ;
  345. ; Inputs: DL contains physical drive number
  346. ; [FlagBits] contains bits to set in the flag field in the BDSs
  347. ; Outputs: None
  348. ; Registers modified: Flags
  349. ;
  350. Set_Changed_DL:
  351. PUBLIC SET_CHANGED_DL ;;Rev 3.30 Modification
  352. Message ftest96,<"Set Changed",cr,lf> ;;End of Modification
  353. push BX
  354. push DX
  355. mov BL,DL
  356. ALL_SET:
  357. mov dx,cs:[FlagBits] ; get bits to set in flag field
  358. xor BH,BH
  359. ;
  360. ; In the virtual drive system we *must* flag the other drives as being changed
  361. ;
  362. ; assume first BDS is in this segment
  363. push ax
  364. push ds ; save current BDS
  365. push di
  366. lds di,dword ptr cs:[Start_BDS]
  367. Scan_BDS:
  368. cmp di,-1
  369. jz SkipSet
  370. cmp byte ptr [di].DriveNum,bl
  371. jnz Get_Next_BDS
  372. ;
  373. ; Someone may complain, but this *always* must be done when a disk change is
  374. ; noted. There are *no* other compromising circumstances.
  375. ;
  376. SetChanged:
  377. or word ptr ds:[di].flags,dx ; signal change on other drive
  378. Get_Next_BDS:
  379. mov ax,word ptr [di].link+2 ; go to next BDS
  380. mov di,word ptr [di].link
  381. mov ds,ax
  382. jmp short Scan_BDS
  383. SkipSet:
  384. pop di ; restore current BDS
  385. pop ds
  386. pop ax
  387. pop DX
  388. pop BX
  389. ret
  390. ;
  391. ; CheckROMChange - see if external program has diddled ROM change line.
  392. ;
  393. ; Inputs: DS:DI points to current BDS.
  394. ; Outputs: Zero set - no change
  395. ; Zero reset - change
  396. ; Registers modified: none
  397. CheckROMChange:
  398. MESSAGE FTEST13,<"CHECKROM "> ;;Rev 3.30 Modification
  399. MNUM FTEST13
  400. MESSAGE FTEST13,<CR,LF> ;;End of Modification
  401. test word ptr [di].flags,fChanged
  402. ret
  403. ;
  404. ; ResetChanged - restore value of change line
  405. ;
  406. ; Inputs: DS:DI points to current BDS
  407. ; Outputs: none
  408. ; Registers modified: none
  409. ResetChanged:
  410. MESSAGE FTEST13,<"RESETCHANGED "> ;;Rev 3.30 Modification
  411. MNUM FTEST13
  412. MESSAGE FTEST13,<CR,LF> ;;End of Modification
  413. and word ptr ds:[di].flags,NOT fChanged
  414. ret
  415. ;
  416. ; HasChange - see if drive can supply change line
  417. ;
  418. ; Inputs: DS:DI points to current BDS
  419. ; Outputs: Zero set - no change line available
  420. ; Zero reset - change line available
  421. ; Registers modified: none
  422. PUBLIC HASCHANGE ;;Rev 3.30 Modification
  423. HasChange:
  424. MESSAGE FTEST13,<"HASCHANGE ">
  425. MNUM FTEST13
  426. MESSAGE FTEST13,<CR,LF> ;;End of Modification
  427. test word ptr [di].flags,fChangeline
  428. ret
  429. ASSUME DS:CODE
  430. include msvolid.inc
  431. Public End96tpi
  432. End96tpi Label Byte