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.

1039 lines
30 KiB

5 years ago
  1. include ioctl.inc
  2. ;
  3. ; Generic IOCTL dispatch tables
  4. ;
  5. IOReadJumpTable db 2
  6. dw offset GetDeviceParameters
  7. dw offset ReadTrack
  8. dw offset VerifyTrack
  9. IOWriteJumpTable db 2
  10. dw offset SetDeviceParameters
  11. dw offset WriteTrack
  12. dw offset FormatTrack
  13. MAX_SECTORS_CURR_SUP EQU 63 ; CURRENT MAXIMUM SEC/TRK THAT ;3.30
  14. ; WE SUPPORT (Was 40 in DOS 3.2) ;3.30
  15. ;
  16. ; TrackTable is an area for saving information passwd by the set device
  17. ; parameter function for laster use my Read/Write/Format/Verify.
  18. ;
  19. ; Entries are 4-Tuples (C,H,R,N) where:
  20. ; C = Cylinder, H = Head, R = Sector, N = Bytes/Sector
  21. ;
  22. ; fixed for bug0016 - initialised table with values - sp
  23. TrackTable db 0,0,1,2
  24. db 0,0,2,2
  25. db 0,0,3,2
  26. db 0,0,4,2
  27. db 0,0,5,2
  28. db 0,0,6,2
  29. db 0,0,7,2
  30. db 0,0,8,2
  31. db 0,0,9,2
  32. db 0,0,10,2
  33. db 0,0,11,2
  34. db 0,0,12,2
  35. db 0,0,13,2
  36. db 0,0,14,2
  37. db 0,0,15,2
  38. db 0,0,16,2
  39. db 0,0,17,2
  40. db 0,0,18,2
  41. db MAX_SECTORS_CURR_SUP * size a_SectorTable - ($-tracktable) dup (0)
  42. sectorsPerTrack dw 15
  43. ; This is a real ugly place to put this
  44. ; it should really go in the BDS
  45. mediaType db 0
  46. Media_Set_For_Format db 0 ; 1 if we have done an Int 13 Set Media
  47. ; Type for Format call
  48. ; Rev 3.30 *****************************************************************
  49. Had_Format_Error db 0 ; 1 if the previous format operation
  50. ; failed.
  51. Dsk_time_out_Err equ 80h ; Time out error (No media present).
  52. Dsk_change_line_Err equ 6h ; Change line error
  53. Dsk_illegal_combination equ 0Ch ; Return code of ah=18h function.
  54. ; Rev 3.30 *****************************************************************
  55. ;
  56. ; TempDPT is a temporary place to hold a pointer to the original
  57. ; Disk Parameter Table while DPT is made to point to a table returned
  58. ; by a BIOS call. A value of -1 indicateds no value has been saved.
  59. ;
  60. TempDPT DD -1
  61. ;
  62. ; Generic$IOCTL:
  63. ; Perform Generic IOCTL request
  64. ; Input:
  65. ; al - unit number
  66. ; Output:
  67. ; if carry set then al contains error code
  68. ;
  69. Public Generic$IOCTL
  70. Generic$IOCTL:
  71. Message ftestdisk,<"Generic IOCTL",cr,lf>
  72. les bx,cs:[PTRSAV] ; es:bx points to request header.
  73. call SetDrive ; ds:di points to BDS for drive.
  74. ;
  75. ; At this point:
  76. ; es:bx - points to the Request Header
  77. ; ds:di points to the BDS for the drive
  78. ;
  79. cmp es:[bx].MajorFunction, RAWIO
  80. jne IOCTL_Func_Err
  81. mov al, es:[bx].MinorFunction
  82. mov si, offset IOReadJumpTable
  83. test al, GEN_IOCTL_FN_TST ; Test of req. function
  84. jnz NotGenericIoctlWrite ; function is a Read.
  85. mov si, offset IOWriteJumpTable
  86. NotGenericIoctlWrite:
  87. and al, 0fH
  88. cmp al, cs:[si]
  89. ja IOCTL_Func_Err
  90. cbw
  91. shl ax, 1
  92. inc si
  93. add si,ax
  94. les bx, es:[bx].GenericIOCTL_Packet
  95. call cs:[si]
  96. jc FailGeneric$IOCTL
  97. jmp exit
  98. FailGeneric$IOCTL:
  99. jmp err$exit
  100. IOCTL_Func_Err:
  101. jmp CMDERR
  102. ;
  103. ; GetDeviceParameters:
  104. ;
  105. ; Input: DS:DI points to BDS for drive
  106. ; ES:BX points to device parameter packet
  107. ;
  108. PUBLIC GETDEVICEPARAMETERS ;3.30
  109. GetDeviceParameters proc near
  110. ; Copy info from BDS to the device parameters packet
  111. mov al, byte ptr ds:[di].FormFactor
  112. mov byte ptr es:[bx].DP_DeviceType, al
  113. mov ax, word ptr ds:[di].Flags
  114. and ax,fNon_Removable+fChangeline ; mask off other bits
  115. mov word ptr es:[bx].DP_DeviceAttributes, ax
  116. mov ax, word ptr ds:[di].cCyln
  117. mov word ptr es:[bx].DP_Cylinders, ax
  118. ; Set media type to default
  119. xor al, al
  120. mov byte ptr es:[bx].DP_MediaType, al
  121. ; Copy recommended BPB
  122. lea si, byte ptr [di].RBytePerSec
  123. test byte ptr es:[bx].DP_SpecialFunctions, BUILD_DEVICE_BPB
  124. jz use_BPB_present
  125. ; Get the correct disk in the drive
  126. call CheckSingle
  127. ; Build the BPB from scratch
  128. call GETBP
  129. jc Get_Parm_Ret
  130. lea si,byte ptr [di].BytePerSec
  131. use_BPB_present:
  132. lea di, byte ptr [bx].DP_BPB
  133. mov cx, size BPB_Type ; for now use 'small' BPB
  134. rep movsb
  135. clc
  136. Get_Parm_Ret:
  137. ret
  138. GetDeviceParameters endp
  139. ;
  140. ; SetDeviceParameters:
  141. ;
  142. ; Input: DS:DI points to BDS for drive
  143. ; ES:BX points to device parameter packet
  144. ;
  145. PUBLIC SETDEVICEPARAMETERS ;3.30
  146. SetDeviceParameters proc near
  147. ; Make sure the fChanged_By_Format flag gets set to kick DOS into looking at
  148. ; the BPB
  149. or word ptr ds:[di].Flags, fChanged_By_Format or fChanged
  150. test byte ptr es:[bx].DP_SpecialFunctions, ONLY_SET_TRACKLAYOUT
  151. jz short SetDevParm_1
  152. jmp SetTrackTable ; Originally TrackLayout
  153. SetDevParm_1:
  154. ; Copy info from the device parameters packet to BDS
  155. mov al, byte ptr es:[bx].DP_DeviceType
  156. mov byte ptr ds:[di].FormFactor, al
  157. mov ax, word ptr es:[bx].DP_Cylinders
  158. mov word ptr ds:[di].cCyln, ax
  159. ; If change line is not loaded then ignore changeling flag
  160. mov ax, word ptr es:[bx].DP_DeviceAttributes
  161. cmp cs:[fHave96],0
  162. jnz Have_Change
  163. and ax,not fChangeline
  164. Have_Change:
  165. ; ignore all bits except Non_removable and Changeline
  166. and ax,fNon_Removable or fChangeline
  167. mov cx, word ptr ds:[di].Flags
  168. and cx, not (fNon_Removable or fChangeline or GOOD_TRACKLAYOUT)
  169. or ax, cx
  170. mov word ptr ds:[di].Flags, ax
  171. ; Set media type
  172. mov al, byte ptr es:[bx].DP_MediaType
  173. mov cs:mediaType, al
  174. ; the media changed (maybe) so we will have to do a SetDASD the next time
  175. ; we format a track
  176. or word ptr ds:[di].Flags, SET_DASD_true
  177. SaveReg <ds,di,es,bx>
  178. ; Figure out what we are supposed to do with the BPB
  179. ; Were we asked to install a fake BPB?
  180. test byte ptr es:[bx].DP_SpecialFunctions, INSTALL_FAKE_BPB
  181. jnz short InstallFakeBPB
  182. ; Were we returning a fake BPB when asked to build a BPB?
  183. test word ptr ds:[di].Flags, RETURN_FAKE_BPB
  184. jz short InstallRecommendedBPB
  185. ; We were returning a fake BPB but we can stop now
  186. and word ptr ds:[di].Flags, not RETURN_FAKE_BPB
  187. jmp DoneWithBPBstuff
  188. InstallRecommendedBPB:
  189. mov cx, size a_BPB
  190. lea di, byte ptr [di].RBytePerSec
  191. jmp short CopyTheBPB
  192. InstallFakeBPB:
  193. mov cx, size BPB_Type ; move 'smaller' BPB
  194. lea di, byte ptr [di].BytePerSec
  195. CopyTheBPB:
  196. lea si, byte ptr [bx].DP_BPB
  197. ; exchange es and ds
  198. push es
  199. push ds
  200. pop es
  201. pop ds
  202. rep movsb
  203. DoneWithBPBstuff:
  204. Call RestoreOldDPT
  205. RestoreReg <bx,es,di,ds>
  206. ; Set up track table (if neccessary)
  207. SetTrackTable:
  208. mov cx, word ptr es:[bx].DP_TrackTableEntries
  209. mov cs:sectorsPerTrack, cx
  210. and word ptr ds:[di].Flags, not GOOD_TRACKLAYOUT
  211. test byte ptr es:[bx].DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD
  212. jz UglyTrackLayout
  213. or word ptr ds:[di].Flags, GOOD_TRACKLAYOUT
  214. UglyTrackLayout:
  215. cmp cx, MAX_SECTORS_IN_TRACK
  216. ja TooManySectorsPerTrack
  217. jcxz SectorInfoSaved ; if no value don't copy table
  218. ; save information in the track table
  219. push BX ; get ES:BX to point to sector
  220. add BX, DP_SectorTable ; table in Device param. struct
  221. push DI
  222. mov DI, offset TrackTable + 2 ; CS:DI now points to sector id
  223. ; of the first track table entry
  224. push AX ; preserve AX value
  225. ; For MAX_SECTORS_IN_TRACK
  226. TrackLoop: ; DO:
  227. mov AX, word ptr ES:[BX] ; get sector number
  228. mov byte ptr CS:[DI], AL ; save in track table
  229. mov AX, word ptr ES:[BX]+2 ; get sector size
  230. call SectorSizeToSectorIndex ; convert size to index number
  231. mov byte ptr CS:[DI]+1, AL ; save size in track table
  232. add BX, size a_sectorTable ; advance pointers to next
  233. add DI, size a_sectorTable ; entries
  234. loopnz TrackLoop ; End FOR
  235. pop AX ; restore the saved values
  236. pop DI
  237. pop BX
  238. SectorInfoSaved:
  239. clc
  240. ret
  241. TooManySectorsPerTrack:
  242. mov al, 0cH
  243. stc
  244. ret
  245. SetDeviceParameters endp
  246. ;
  247. ; FormatTrack:
  248. ; If SpecialFunction byte is 1, then this is a status call to see if there is
  249. ; ROM support for the combination of sec/trk and # of cyln, and if the
  250. ; combination is legal. If SpecialFunction byte is 0, then format the track.
  251. ;
  252. ; Input: DS:DI points to BDS for drive
  253. ; ES:BX points to format packet
  254. ;
  255. ; Output:
  256. ; For status call:
  257. ; SpecialFunction byte set to:
  258. ; 0 - ROM support + legal combination
  259. ; 1 - No ROM support
  260. ; 2 - Illegal Combination
  261. ; 3 - no media present ;Rev 3.30
  262. ; Carry cleared.
  263. ;
  264. ; For format track:
  265. ; Carry set if error
  266. ;
  267. ;
  268. ; Flags also may be altered. All other registers preserved.
  269. ; If the call to ROM returns no error, then the current DPT is "replaced" by
  270. ; the one returned by the ROM. This is done by changing the pointer in [DPT]
  271. ; to the one returned. The original pointer to the disk base table is stored
  272. ; in TempDPT, until it is restored.
  273. ;
  274. ; This proc was changed to force a status for format call if we are on the
  275. ; new ROM.
  276. ;
  277. ;
  278. FormatTrack proc near
  279. test byte ptr es:[bx].DP_SpecialFunctions,Status_For_Format
  280. jz SkipStatusOnly
  281. Do_Status_Only:
  282. call FormatStatus
  283. mov byte ptr es:[bx].DP_SpecialFunctions,al
  284. ret
  285. SkipStatusOnly: ; for a hard disk only do the verify
  286. cmp byte ptr ds:[di].FormFactor, DEV_HARDDISK
  287. jnz SkipVerify
  288. jmp DoVerifyTrack
  289. SkipVerify:
  290. SaveReg <ds,di,es,bx> ; Format a Track
  291. call FormatStatus ; SetDASD checks media_set_for_format
  292. cmp al,3 ; Check for time out
  293. je Format_Failed ; Fail if time out
  294. call SetDASD
  295. ;
  296. ; Store Cylinder,Head in track table
  297. ; ***** ASSUMPTION *******
  298. ; Since format requests on Fixed Media are converted to Verifies, we
  299. ; assume that we are formatting a floppy and hence have 255 or less
  300. ; tracks and heads. We therefore must change the Cylinder, Head data
  301. ; from the Request Packet Size to that of the TrackTable (see Int 13
  302. ; interface in IBM's Tech Ref.).
  303. ; Check to ensure correct disk is in drive
  304. call CheckSingle
  305. mov ax, word ptr es:[bx].FP_Cylinder
  306. mov word ptr cs:[TRKNUM],ax
  307. mov cx, word ptr es:[bx].FP_Head
  308. mov byte ptr cs:[HDNUM],cl
  309. mov ah,cl
  310. ; this next piece of code copies the correct head
  311. ; and cylinder numbers to the tracktable
  312. push di ; preserve DI
  313. mov di, offset TrackTable
  314. mov CX, cs:SectorsPerTrack ; get number of sectors
  315. jcxz EndSetUpTrackTable ; if nothing to do skip down
  316. SetUpLoop:
  317. mov cs:[di], AX ; set head and track value
  318. add di, 4 ; move to next entry
  319. loopnz SetUpLoop ; loop if not done yet
  320. EndSetUpTrackTable:
  321. pop di ; restore DI (BDS pointer)
  322. mov cx, MAXERR ; Set up retry count
  323. FormatRetry:
  324. push cx
  325. ; set up registers for format call to TO_ROM
  326. mov AX, word ptr CS:SectorsPerTrack ; set number of sectors
  327. mov AH, ROMFormat
  328. push cs ; set ES:BX to point to
  329. pop es ; the track table
  330. mov BX, offset TrackTable
  331. ; don't need to set CL on format
  332. call to_rom
  333. jnc FormatOk
  334. pop cx
  335. mov cs:[Had_Format_Error],1 ; Mark the error
  336. push ax ;3.30
  337. push cx ;3.30
  338. push dx ;3.30
  339. call ResetDisk
  340. call FormatStatus ;3.30
  341. cmp al, 1 ;3.30
  342. jnz While_Err ;3.30
  343. call SetDASD ;3.30
  344. While_Err: ;3.30
  345. pop dx ;3.30
  346. pop cx ;3.30
  347. pop ax ;3.30
  348. loop FormatRetry
  349. ; Format failed
  350. Format_Failed:
  351. mov cs:[Had_Format_Error],1 ; Indicate a format error
  352. cmp ah,Dsk_Change_Line_Err ; Convert change line to
  353. jne Map_Err ; to time out.
  354. mov ah,Dsk_Time_Out_Err
  355. Map_Err:
  356. call MapError
  357. RestoreReg <bx,es,di,ds>
  358. ret
  359. FormatOk:
  360. mov cs:[Had_Format_Error],0 ; Reset format error flag
  361. pop cx ; clean up stack after bailing out
  362. ; of FormatRetry loop early
  363. RestoreReg <bx,es,di,ds>
  364. DoVerifyTrack:
  365. call VerifyTrack ; Will reset DPT entries.
  366. ret
  367. FormatTrack endp
  368. ;
  369. ; FormatStatus:
  370. ; If SpecialFunction byte is 1, then this routine is called to see if there is
  371. ; ROM support for the combination of sec/trk and # of cyln, and if the
  372. ; combination is legal.
  373. ;
  374. ; Input: DS:DI points to BDS for drive
  375. ; ES:BX points to format packet
  376. ;
  377. ; Output:
  378. ; SpecialFunction byte set to:
  379. ; 0 - ROM support + legal combination
  380. ; 1 - No ROM support
  381. ; 2 - Illegal Combination
  382. ; 3 - No media present, ROM support exists but can't determine
  383. ; media
  384. ; Carry cleared.
  385. ;
  386. ; For format track:
  387. ; Carry set if error
  388. ;
  389. ;
  390. ; Flags also may be altered. All other registers preserved.
  391. ; If the call to ROM returns no error, then the current DPT is "replaced" by
  392. ; the one returned by the ROM. This is done by changing the pointer in [DPT]
  393. ; to the one returned. The original pointer to the disk base table is stored
  394. ; in TempDPT, until it is restored.
  395. ;
  396. ;
  397. FormatStatus proc near
  398. SaveReg <cx,dx>
  399. cmp cs:[Had_Format_Error],1 ; Are we here because of a format err
  400. je Fstat01
  401. cmp byte ptr cs:[Media_Set_For_Format],1
  402. jnz FStat03
  403. jmp Stat_Ret
  404. Fstat03:
  405. mov byte ptr cs:[Media_Set_For_Format],0
  406. ;
  407. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  408. ; modification - sp001
  409. ;
  410. ; remove check for new rom from here. we shall just assume the
  411. ; prescence of the new rom and go ahead and issue the int13 call
  412. ; anyway. later on if there is an error we shall check this to
  413. ; see if it is there because of lack of rom support, in which
  414. ; case the appropriate error will be indicated by setting al to 1
  415. ;
  416. ; I would ideally like to see the new rom testing code shifted to
  417. ; msinit and this code reintroduced. however for this version we
  418. ; are aiming to stick close to the IBM variety.
  419. ;
  420. ; More changes to support this commenting out will follow. All
  421. ; will be marked as modification sp001
  422. ;
  423. ; mov al,1 ; No ROM support available error code
  424. ; test byte ptr cs:[New_ROM],1
  425. ; jnz FStat01
  426. ; jmp Stat_Ret
  427. Fstat01:
  428. SaveReg <ds,si>
  429. xor ax,ax
  430. mov ds,ax
  431. lds si, dword ptr ds:[DskAdr] ; DS:SI := pDPT
  432. mov word ptr cs:[DPT],si ; cs:[DPT] := pDPT
  433. mov word ptr cs:[DPT + 2],ds
  434. RestoreReg <si,ds>
  435. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  436. ; modification sp001
  437. ;
  438. ; the following instruction introduced for the new rom modification
  439. ;
  440. mov cs:[New_Rom],1 ; assume new rom
  441. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  442. mov ax,word ptr [di].cCyln
  443. mov cx,word ptr [di].Seclim
  444. ; set up registers for format status call
  445. and AH, 03h ; 'and' out unneeded track bits
  446. ror AH, 1 ; get track and sector values correct
  447. ror AH, 1
  448. or AH, CL ; set sector number
  449. xchg AH, AL
  450. mov CX, AX
  451. dec CH
  452. mov DL, byte ptr [DI].DriveNum ; get drive number
  453. mov AH, 18h ; set command to "sec/trk supported?"
  454. SaveReg <ES,DI,DS,SI>
  455. int 13h ; call rom bios to see if supported
  456. jc Format_Stat_Err ; if carry, combination is not supported
  457. ; ES:DI points to new Disk Base Table
  458. ; combination for this drive replace
  459. ; current (DskAdr) pointer with new one,
  460. ; saving the old one in TempDPT.
  461. cmp cs:[Had_Format_Error],1 ; Are we here because of a format err
  462. jnz Fstat02 ; Then skip the disk base setup
  463. xor al,al ; Supported and OK
  464. mov cs:[Had_Format_Error],al ; Clear format error
  465. jmp Pop_Stat_Ret ; Back to work
  466. Fstat02:
  467. xor ax,ax
  468. mov ds,ax
  469. lds si, dword ptr ds:[DskAdr] ; DS:SI := pDPT
  470. mov word ptr cs:[TempDPT],si
  471. mov word ptr cs:[TempDPT + 2],ds ; Save pDPT
  472. mov word ptr ds:[DskAdr],DI ; Setup New DPT returned by
  473. mov word ptr ds:[DskAdr + 2],ES ; ROM
  474. mov byte ptr cs:[Media_Set_For_Format],1 ; set flag
  475. xor al,al ; Legal combination + ROM support code
  476. jmp short Pop_Stat_Ret
  477. Format_Stat_Err:
  478. mov al,3 ; Assume a time out
  479. cmp ah,Dsk_Time_Out_Err ; Was it a time out???
  480. jz Pop_Stat_Ret ; Yes - then done
  481. dec al ; Assume an illegal comb.
  482. cmp ah,Dsk_illegal_combination ; Was it an illegal comb???
  483. jz Pop_Stat_Ret ; Yes - then done
  484. dec al ; Assume No ROM Support
  485. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  486. ; modification sp001
  487. ;
  488. ; the following instruction was introduced for the new_rom modification
  489. ;
  490. mov cs:[New_Rom],0 ; the old rom
  491. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  492. ; Return result of status call
  493. Pop_Stat_Ret:
  494. RestoreReg <SI,DS,DI,ES>
  495. Stat_Ret:
  496. clc
  497. RestoreReg <dx,cx>
  498. ret
  499. FormatStatus endp
  500. ;
  501. ; VerifyTrack:
  502. ;
  503. ; Input: DS:DI points to BDS for drive
  504. ; ES:BX points to verify packet
  505. ;
  506. PUBLIC VERIFYTRACK ;3.30
  507. VerifyTrack proc near
  508. mov cs:RFLAG, ROMverify
  509. mov ax, word ptr es:[bx].VP_Cylinder
  510. mov cs:curtrk, ax
  511. mov ax, word ptr es:[bx].VP_Head
  512. ; ****** ASSUMPTION ******
  513. ; we assume that we have less than 256 heads, and that the Request
  514. ; Header Data Structure is unneccessarily big
  515. mov cs:curhd, al
  516. xor ax, ax
  517. mov cx, cs:sectorsPerTrack
  518. ; Use 0:0 as the transfer address for verify
  519. xor bx, bx
  520. mov es, bx
  521. call TrackIO
  522. ret
  523. VerifyTrack endp
  524. ;
  525. ; ReadTrack:
  526. ;
  527. ; Input: DS:DI points to BDS for drive
  528. ; ES:BX points to read packet
  529. ;
  530. PUBLIC READTRACK ;3.30
  531. ReadTrack:
  532. mov cs:RFLAG, ROMread
  533. jmp ReadWriteTrack
  534. ;
  535. ; WriteTrack:
  536. ;
  537. ; Input: DS:DI points to BDS for drive
  538. ; ES:BX points to write packet
  539. ;
  540. PUBLIC WRITETRACK ;3.30
  541. WriteTrack:
  542. mov cs:RFLAG, ROMwrite
  543. jmp ReadWriteTrack
  544. ;
  545. ; ReadWriteTrack:
  546. ;
  547. ; Input:
  548. ; DS:DI points to BDS for drive
  549. ; ES:BX points to write packet
  550. ; RFLAG - 2 for read, 3 for write
  551. ;
  552. PUBLIC READWRITETRACK ;3.30
  553. ReadWriteTrack proc near
  554. mov ax, word ptr es:[bx].TRWP_Cylinder
  555. mov cs:curtrk, ax
  556. mov ax, word ptr es:[bx].TRWP_Head
  557. ; ****** ASSUMPTION ******
  558. ; we assume that we have less than 256 heads, and that the Request
  559. ; Header Data Structure is unneccessarily big
  560. mov cs:curhd, al
  561. mov ax, word ptr es:[bx].TRWP_FirstSector
  562. mov cx, word ptr es:[bx].TRWP_SectorsToReadWrite
  563. les bx, es:[bx].TRWP_TransferAddress
  564. call TrackIO
  565. ret
  566. ReadWriteTrack endp
  567. ;
  568. ; TrackIO:
  569. ; Performs Track Read/Write/Verify
  570. ;
  571. ; Input:
  572. ; RFLAG - 2 = Read
  573. ; 3 = Write
  574. ; 4 = Verify
  575. ; ax - Index into track table of first sector to IO
  576. ; cx - number of sectors to IO
  577. ; es:bx - Transfer address
  578. ; ds:di - pointer to BDS
  579. ; curtrk - current cylinder
  580. ; curhd - current head
  581. ;
  582. public trackio
  583. TrackIO proc near
  584. ; procedure `disk' will pop stack to SPsav and return if error
  585. mov cs:SPsav, sp
  586. ; Ensure correct disk is in drive
  587. call CheckSingle
  588. ;
  589. ; Set up tables and variables for I/O
  590. ;
  591. cmp byte ptr cs:[Media_Set_For_Format],1
  592. jz DPTAlreadySet
  593. ; ;3.30
  594. ; SET UP TABLES AND VARIABLES FOR I/O ;3.30
  595. ; ;3.30
  596. SaveReg <AX,CX>
  597. call IOSetUp
  598. RestoreReg <CX,AX>
  599. ;
  600. ; point si at the table entry of the first sector to be IO'd
  601. ;
  602. DPTAlreadySet:
  603. mov si, offset trackTable
  604. shl ax, 1
  605. shl ax, 1
  606. add si, ax
  607. ;
  608. ; we want:
  609. ; cx to be the number of times we have to loop
  610. ; dx to be the number of sectors we read on each iteration
  611. mov dx, 1
  612. test word ptr ds:[di].Flags, GOOD_TRACKLAYOUT
  613. jz IOnextSector
  614. ; Hey! we can read all the sectors in one blow
  615. xchg dx, cx
  616. IOnextSector:
  617. push cx
  618. push dx
  619. ; skip over the cylinder and head in the track table
  620. inc si
  621. inc si
  622. ; Get sector id from track table
  623. mov AL, byte ptr cs:[si] ; get current sector value
  624. mov cs:[cursec], AL ; save cursec value
  625. ;*** For a Fixed disk multi-track disk I/O - 4/14/86 ;3.30
  626. ;Assumptions: 1). In the input CX (# of sectors to go) to TRACKIO, only CL;3.30 is
  627. ;valid. 2). Sector size should be set to 512 bytes. 3). GOODTRACKLAYOUT. ;3.30
  628. ; ;3.30
  629. test word ptr [di].Flags, fNon_Removable ;Fixed disk? - J.K;3.30 .
  630. jz IOREMOVABLE ;no - ;3.30
  631. mov cs:[seccnt], dx ;# of sectors to I;3.30 /O -
  632. mov ax, dx ; ;3.30
  633. call disk ; ;3.30
  634. pop dx ; ;3.30
  635. pop cx ; ;3.30
  636. clc ; ;3.30
  637. ret ; ;3.30
  638. IOREMOVABLE: ; ;3.30
  639. mov AL, byte ptr cs:[si]+1 ; get sector size index
  640. ; The next eight lines put sector size index in DPT
  641. push ES ; save value while getting pointer
  642. push SI ; to DPT
  643. push AX
  644. les SI, cs:DPT ; ES:SI points to DPT
  645. ; put size in DPT
  646. mov byte ptr ES:[si].Disk_Sector_Siz, AL
  647. mov AX, word ptr [di].seclim ; get number of sector/track
  648. mov byte ptr ES:[si].Disk_EOT,AL ; patch in DPT
  649. pop AX ; restore register values
  650. pop SI
  651. pop ES
  652. ; convert index to byte value
  653. call SectorSizeIndexToSectorSize
  654. push AX ; save number of bytes in sector
  655. mov AX, DX ; get number of sector for I/0
  656. DoTheIO:
  657. mov cs:[SECCNT],ax ; set up the count of sectors to I/O
  658. call disk
  659. ; advance buffer pointer by adding
  660. ; sector size
  661. pop ax
  662. add bx, ax
  663. pop dx
  664. pop cx
  665. loop IOnextSector
  666. call DONE ; Set time of last access, and reset
  667. clc ; entries in DPT.
  668. ret
  669. TrackIO endp
  670. ;
  671. ; The sector size in bytes needs to be converted to an index value for the IBM
  672. ; ROM. (0=>128, 1=>256,2=>512,3=>1024). It is assumed that only these values
  673. ; are permissible.
  674. ; On Input AX contains sector size in bytes
  675. ; On Output AL contains index
  676. ;
  677. public SectorSizeToSectorIndex
  678. SectorSizeToSectorIndex proc near
  679. and AH, 07h ; very simple error correction
  680. mov AL, AH ; shift left 8 bits
  681. cmp AL, 4 ; size 1024?
  682. jnz SecToIndexRet ; no, then we are done
  683. sub AL, 1 ; if 1024, adjust index to 3
  684. SecToIndexRet:
  685. ret
  686. SectorSizeToSectorIndex endp
  687. SectorSizeIndexToSectorSize proc near
  688. ; value in AH on entry is not important
  689. push CX ; save CX value
  690. mov CL, AL ; use index number as shift size
  691. mov AX, 0080h ; set AX to 128
  692. shl AX, CL ; shift by index to get proper value
  693. pop CX ; restore CX value
  694. ret
  695. SectorSizeIndexToSectorSize endp
  696. ;
  697. ; Set up the ROM for formatting.
  698. ; we have to tell the ROM BIOS what type of disk is in the drive.
  699. ; On Input - DS:DI - points to BDS
  700. ;
  701. SetDASD proc near
  702. ; See if we have new ROM and have issues Set Media Type For Format call
  703. test byte ptr cs:[Media_Set_For_Format],1
  704. jnz DasdHasBeenSet
  705. ; See if we have previously set DASD type
  706. cmp cs:[Had_Format_Error],1
  707. je DoSetDasd
  708. test word ptr ds:[di].Flags, SET_DASD_true
  709. jz DASDhasBeenSet
  710. and word ptr ds:[di].Flags, not SET_DASD_true
  711. ; the next nine lines determine and put the DASD type in AL
  712. DoSetDasd:
  713. mov cs:[Had_Format_Error],0
  714. mov cs:[GAP_PATCH], 50h ; assume 48tpi or 3.5" drive
  715. cmp [di].FormFactor, ffSmall; is 3.5" drive?
  716. jnz not35Drive ; no, skip down
  717. mov AL, 04h ; yes set proper DASD value
  718. jmp short Do_Set ; jump down
  719. Not35Drive:
  720. mov AL, 01h ;
  721. cmp [di].FormFactor, ff96tpi; 96tpi disk drive?
  722. jnz Do_Set ; no skip down to rom call
  723. inc AL ; reflect 96tpi drive in DASD type
  724. cmp [di].seclim, 15 ; 96tpi media in drive?
  725. jnz Do_Set ; no, skip down to rom call
  726. inc AL ; reflect 96tpi media in DASD type
  727. mov cs:[GAP_PATCH], 54h ; and in the GAP_PATCH
  728. Do_Set:
  729. mov AH, 17h ; set command to Set DASD type
  730. mov DL, [di].DriveNum ; set drive number
  731. int 13h ; call rom-bios
  732. DASDhasBeenSet:
  733. mov ah,byte ptr [di].seclim
  734. mov cs:[FORMT_EOT],ah
  735. ret
  736. SetDasd endp
  737. ;
  738. ; This routine is called if an error occurs while formatting or verifying.
  739. ; It resets the drive, and decrements the retry count.
  740. ; On Entry - DS:DI - points to BDS for the drive
  741. ; BP - contains retry count
  742. ; On Exit Flags indicate result of decrementing retry count
  743. ;
  744. ;
  745. ; There are some drives that "lose" the changeline indication if another
  746. ; floppy drive is accessed before the changeline is recorded by the device
  747. ; driver. In this situation, it is possible for the ROM to also not detect
  748. ; that the medium has changed. So, the end result is that we could have a
  749. ; diskette in the drive for which we can not even read the boot sector.
  750. ; We "fix" this by setting the byte at location DISK_STATE_MACHINE_DRV_0 (hex)
  751. ; for physical drive 0 (or DISK_STATE_MACHINE_DRV_1 for drive 1) to 0 (See
  752. ; IBM PC/AT "blessed" addresses Document for explanation) . This tells the ROM
  753. ; that the medium is 'unknown'. The ROM actually uses these locations for
  754. ; itself. Note that we do this only for internal drives; we do not do this for
  755. ; fixed disks or for physical drives > 1. We may end up corrupting some
  756. ; other bytes in memory that may be used for something else.
  757. ; NOTE: We do not stuff this byte if the last operation was a FORMAT because
  758. ; the ROM loses track of what it is trying to format!!
  759. ;
  760. ; This routine was changed to only stuff 61H when the drive indicated it
  761. ; supported changeline. The Phoenix ROM was taking a very long time
  762. ; to figure out what the media was which caused disk time outs to take
  763. ; forever
  764. ;
  765. ; We assume that DS:DI points to the current BDS for this drive.
  766. ; no registers should be touched
  767. ;
  768. AGAIN:
  769. call ResetDisk
  770. dec bp ; decrement retry count
  771. RET
  772. PUBLIC RESETDISK
  773. ResetDisk:
  774. push ax
  775. xor AH, AH ; set command to reset disk
  776. int 13h ; call the rom-bios
  777. pop ax
  778. mov cs:[STEP_DRV],-1 ; zap up the speed
  779. ret
  780. ;
  781. ; This routine sets up the Drive Parameter Table with the values needed for
  782. ; Format, does an Int 13. Values in DPT are restored after a VERIFY is done.
  783. ;
  784. ; On Entry - DS:DI - points to BDS for the drive
  785. ; ES:BX - points to TRKBUF
  786. ; AL - number of sectors
  787. ; AH - Int 13 function code
  788. ; CL - Sector number for verify
  789. ; On Exit - DS,DI,ES,BX remain unchanged.
  790. ; ax and flags are the results of the int 13
  791. ;
  792. Public To_ROM
  793. To_ROM:
  794. SAVEREG <DS,DI,ES,BX,SI> ;3.30
  795. ; The below line was replaced because saving the DPT is predicated upon
  796. ; whether the functionality of the new ROM was used, not if it exists.
  797. ; test byte ptr cs:[New_ROM],1
  798. test byte ptr cs:[Media_Set_For_Format],1
  799. jnz Got_Valid_DPT
  800. ; Set up values in the DPT
  801. ; Set up motor start correctly for 3.5" drives.
  802. push ax
  803. push ds
  804. xor ax,ax
  805. mov ds,ax
  806. lds si,dword ptr ds:[DskAdr] ; DS:SI := pDPT
  807. mov word ptr cs:[DPT],si
  808. mov word ptr cs:[DPT+2],ds ; Save pDPT
  809. pop ds
  810. push ES ; save value in ES
  811. LES SI, CS:DPT
  812. mov DX, [di].seclim ; set the sector per track in
  813. mov es:[si].DISK_EOT, DL ; the Disk Parameter Table
  814. cmp DX, 15 ; 96tip media?
  815. jz To_ROM1 ; yes, skip down
  816. ; no - set Format Gap to 320/360 media value
  817. mov CL, cs:[Gap_Patch]
  818. mov byte ptr ES:[si].DISK_FORMT_GAP, CL
  819. To_ROM1: ; 3.5" floppy drive?
  820. cmp byte ptr [di].FormFactor, ffSmall
  821. jnz To_ROM2 ; no, skip down
  822. ; yes - reset disk moter start value
  823. mov byte ptr ES:[si].DISK_MOTOR_STRT, 4
  824. To_ROM2:
  825. pop ES ; restore ES value
  826. pop ax
  827. Got_Valid_DPT:
  828. ; now set up the registers
  829. mov DL, [di].DriveNum ; set drive number
  830. mov DH, CS:[HDNUM] ; set head number
  831. mov CX, CS:[TRKNUM] ; set track number
  832. ror CH,1
  833. ror CH,1
  834. xchg CH, CL
  835. int 13h ; call the rom-bios disk routines
  836. RestoreReg <si,bx,es,di,ds>
  837. ret
  838. ;
  839. ; Get the owner of the physical drive represented by the logical drive in BL.
  840. ; The assumption is that we **ALWAYS** keep track of the owner of a drive!!
  841. ; If this is not the case, the system may hang, just following the linked list.
  842. ;
  843. PUBLIC IOCTL$GETOWN
  844. IOCTL$GETOWN:
  845. call SetDrive
  846. mov al,byte ptr [di].DriveNum ; Get physical drive number
  847. push cs
  848. pop ds
  849. mov di,word ptr Start_BDS
  850. Own_Loop:
  851. cmp byte ptr [di].DriveNum,al
  852. jne GetNextBDS
  853. test word ptr [di].flags,fI_Own_Physical
  854. jnz Done_GetOwn
  855. GetNextBDS:
  856. mov bx,word ptr [di].link+2
  857. mov di,word ptr [di].link
  858. mov ds,bx
  859. jmp short Own_Loop
  860. Done_GetOwn:
  861. JMP SHORT EXIT_OWN
  862. ;
  863. ; Set the ownership of the physical drive represented by the logical drive in
  864. ; BL.
  865. ;
  866. PUBLIC IOCTL$SETOWN
  867. IOCTL$SETOWN:
  868. call SetDrive
  869. mov byte ptr cs:[fSetOwner],1 ; set flag for CheckSingle to
  870. ; look at.
  871. call CheckSingle ; Set ownership of drive
  872. mov byte ptr cs:[fSetOwner],0 ; reset flag
  873. xor bx,bx
  874. mov es,bx
  875. mov cl,-1
  876. mov byte ptr es:[LSTDRV],cl ; Set up SDSB as well
  877. EXIT_OWN:
  878. ; If there is only one logical drive assigned to this physical drive, return
  879. ; 0 to user to indicate this.
  880. xor cl,cl
  881. test word ptr [di].flags,fI_Am_Mult
  882. jz EXIT_NO_MULT
  883. mov cl,byte ptr [di].DriveLet ; Get logical drive number
  884. inc cl ; get it 1-based
  885. EXIT_NO_MULT:
  886. LDS BX,CS:[PtrSav]
  887. mov byte ptr [BX].UNIT,CL
  888. jmp EXIT
  889. ;
  890. ; Moves the old DPT that had been saved in TempDPT back to DPT. This is done
  891. ; only if the first byte of TempDPT is not -1.
  892. ; All registers (including flags) are preserved.
  893. ;
  894. Public RestoreOldDPT
  895. RestoreOldDPT:
  896. ; If we have already restored the disk base table earlier, do not do it
  897. ; again.
  898. push ax
  899. xor al,al
  900. ; Reset flag and get current flag setting
  901. mov cs:[Had_Format_Error],al
  902. xchg byte ptr cs:[Media_Set_For_Format],al
  903. or al,al
  904. jz DontRestore
  905. SaveReg <si,ds,es>
  906. LDS SI,CS:[TempDPT]
  907. xor ax,ax
  908. mov es,ax ; have ES -> segment 0
  909. MOV WORD PTR ES:[DskAdr],SI
  910. MOV WORD PTR ES:[DskAdr+2],DS
  911. GotCurrentDPT:
  912. RestoreReg <es,ds,si>
  913. DontRestore:
  914. pop ax
  915. clc ; clear carry
  916. ret ; (7/31/86)
  917. ;end of file msioctl.asm