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.

1204 lines
34 KiB

5 years ago
  1. ; SCCSID = @(#)oemfor.asm 1.28 85/10/15
  2. name OemFormatRoutines
  3. debug equ 0
  4. ;-------------------------------------------------------------------------------
  5. ; Public for debugging only
  6. public CheckSwitches
  7. public LastChanceToSaveIt
  8. public WriteBootSector
  9. public OemDone
  10. public WriteBogusDos
  11. public ConvertToOldDirectoryFormat
  12. public SetPartitionTable
  13. public ReadSector
  14. public WriteSector
  15. public SectorIO
  16. public GetVolumeId
  17. public CheckVolumeId
  18. public customBPBs
  19. public BootSectorIsFine
  20. public NotSlashB
  21. public NotSingleSided
  22. public EndSwitchCheck
  23. public WeCanNotIgnoreThisError
  24. public CanNotWriteBoot
  25. public HardDisk?
  26. public BogusDos
  27. public sys_mess_loop
  28. public end_sys_loop
  29. public DirectoryRead
  30. public wrtdir
  31. public DirectoryWritten
  32. public PartitionTableRead
  33. public partitionscan
  34. public dochange
  35. public partitionset
  36. public BadPartitionTable
  37. public FCBforVolumeIdSearch
  38. public CopyVolumeId
  39. public CompareVolumeIds
  40. public VolumeToUpper
  41. public NextLetter
  42. public BadVolumeId
  43. public switchlist
  44. public boot2
  45. public boot
  46. public scratchBuffer
  47. public bootDrive
  48. public biosFilename
  49. public dosFilename
  50. public oldDrive
  51. public oldVolumeId
  52. public bootSignature
  53. public ptr_msgWhatIsVolumeId?
  54. public trackReadWritePacket
  55. public BPB81
  56. public BPB82
  57. public BPB91
  58. public BPB92
  59. ;-------------------------------------------------------------------------------
  60. data segment public 'DATA'
  61. data ends
  62. code segment public 'CODE'
  63. assume cs:code,ds:data
  64. Public AccessDisk
  65. public CheckSwitches
  66. public LastChanceToSaveIt
  67. public WriteBootSector
  68. public OemDone
  69. public BiosFile
  70. public DosFile
  71. data segment
  72. extrn AddToSystemSize:near
  73. extrn currentCylinder:word
  74. extrn currentHead:word
  75. extrn deviceParameters:byte
  76. extrn drive:byte
  77. extrn driveLetter:byte
  78. extrn fBigFAT:byte
  79. extrn inbuff:byte
  80. extrn switchmap:word
  81. extrn Old_Dir:byte
  82. extrn fLastChance:byte
  83. extrn msgBadVolumeId:byte
  84. extrn msgBadPartitionTable:byte
  85. extrn msgBootWriteError:byte
  86. extrn msgDirectoryReadError:byte
  87. extrn msgDirectoryWriteError:byte
  88. extrn msgInvalidParameter:byte
  89. extrn msgIncompatibleParameters:byte
  90. extrn msgIncompatibleParametersForHardDisk:byte
  91. extrn msgParametersNotSupportedByDrive:byte
  92. extrn msgPartitionTableReadError:byte
  93. extrn msgPartitionTableWriteError:byte
  94. extrn msgWhatIsVolumeId?:byte
  95. extrn NumSectors:word, TrackCnt:word
  96. IF DEBUG
  97. extrn msgFormatBroken:byte
  98. ENDIF
  99. data ends
  100. extrn PrintString:near
  101. extrn std_printf:near
  102. extrn crlf:near
  103. extrn user_string:near
  104. ;-------------------------------------------------------------------------------
  105. ; Support Routines
  106. Switches macro s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16
  107. ;;
  108. switchCount = 0
  109. switchmask = 1
  110. irp x,<&s1,&s2,&s3,&s4,&s5,&s6,&s7,&s8,&s9,&s10,&s11,&s12,&s13,&s14,&s15,&s16>
  111. ifnb <x>
  112. switchCount = switchCount + 1
  113. SWITCH_&&x = switchmask
  114. switchmask = 2 * switchmask
  115. endif
  116. endm
  117. public switchlist
  118. switchlist db switchCount
  119. db "&s16&&s15&&s14&&s13&&s12&&s11&&s10&&s9&&s8&&s7&&s6&&s5&&s4&&s3&&s2&&s1&"
  120. endm
  121. ;-------------------------------------------------------------------------------
  122. ; Constants
  123. ; Standard dos macros
  124. INCLUDE DOSMAC.INC
  125. ; This defines all the int 21H system calls
  126. INCLUDE SYSCALL.INC
  127. ; Limits
  128. ; following were removed into FILESIZE.INC by kwc on 10/04/86
  129. ;BIOS_SIZE equ 5400h ; Used to set size of
  130. ;DOS_SIZE equ 7600h ; Bogus DOS for /B switch
  131. include filesize.inc
  132. ; end of FILESIZE.INC change by kwc on 10/04/86
  133. LOGBOOTSECT equ 1
  134. ;MAX_SECTORS_IN_TRACK equ 20 Already defined in ioctl.INC
  135. Set_Drv_Owner equ 0Fh ; IOCTL subfunction
  136. ;-------------------------------------------------------------------------------
  137. ; These are the data structures which we will need
  138. INCLUDE DIRENT.INC
  139. include ioctl.INC
  140. ;-------------------------------------------------------------------------------
  141. ; And this is the actual data
  142. data segment
  143. BiosFile db "x:\IO.SYS", 0
  144. DosFile db "x:\MSDOS.SYS", 0
  145. trackReadWritePacket a_TrackReadWritePacket <>
  146. Switches S,V,H,C,T,N,1,4,8,B
  147. ; BIOS parameter blocks for various media
  148. customBPBs label byte
  149. BPB92 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdH, 2, 9, 2, 0, 0, 0, 0>
  150. BPB91 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fcH, 2, 9, 1, 0, 0, 0, 0>
  151. BPB82 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffH, 1, 8, 2, 0, 0, 0, 0>
  152. BPB81 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feH, 1, 8, 1, 0, 0, 0, 0>
  153. BPB720 a_BPB <512, 2, 1, 2, 112, 2*9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
  154. Custom_Media equ 0F0H ; Media byte for custom format
  155. Dual_8_Media equ 0FFh ; Dual sided 8 sectored
  156. Single_8_Media equ 0FEh ; Single sided 8 sectored
  157. Dual_9_Media equ 0FDh ; Dual sided 9 sectored
  158. Single_9_Media equ 0FCh ; Single sided 9 sectored
  159. Dual_15_Media equ 0F9h ; Dual sided 15 sectored
  160. Fixed_Disk equ 0F8h ; Fixed Disk
  161. boot2 db 0,0,0, "Boot 1.x"
  162. db 512 - 11 dup(?)
  163. REORG2 LABEL BYTE
  164. ORG BOOT2
  165. INCLUDE ..\BOOT\BOOT11.INC
  166. ORG REORG2
  167. boot db 0,0,0,"Boot 2.x"
  168. bootBPB a_BPB <>
  169. db 512 - (size a_BPB + 11 + 3) dup(0)
  170. bootDrive db 0
  171. bootSignature dw 0
  172. REORG LABEL BYTE
  173. ORG BOOT
  174. INCLUDE ..\BOOT\BOOT.INC
  175. ORG REORG
  176. scratchBuffer db 512 dup(?)
  177. ptr_msgWhatIsVolumeId? dw offset msgWhatIsVolumeId?
  178. dw offset driveLetter
  179. data ends
  180. ;-------------------------------------------------------------------------------
  181. ; AccessDisk:
  182. ; Called whenever a different disk is about to be accessed
  183. ;
  184. ; Input:
  185. ; al - drive letter (0=A, 1=B, ...)
  186. ;
  187. ; Output:
  188. ; none
  189. AccessDisk proc near
  190. push ax ; save drive letter
  191. mov bl,al ; Set up GENERIC IOCTL REQUEST preamble
  192. inc bl
  193. mov ax,(IOCTL SHL 8) + Set_Drv_Owner ; IOCTL function
  194. int 21h
  195. pop ax
  196. return
  197. AccessDisk endp
  198. ;-------------------------------------------------------------------------------
  199. ; CheckSwitches:
  200. ; Check switches against device parameters
  201. ; Use switches to modify device parameters
  202. ;
  203. ; Input:
  204. ; deviceParameters
  205. ;
  206. ; Output:
  207. ; deviceParameters may be modified
  208. ; Carry set if error
  209. ;
  210. ; Algorithm:
  211. ; if hard disk
  212. ; Check Boot Sector for valid Signature
  213. ; IF (valid)
  214. ; Check the volume id
  215. ; Make sure no switches other than /V, /S are specifed
  216. ; else if 96 tpi without /4 or not 5.25" disk
  217. ; Make sure no switches other than /V, /S are specifed
  218. ; else
  219. ; if 48 tpi drive and switch /4
  220. ; turn off switch /4
  221. ; if single sided drive and switch /1 but not switch /8
  222. ; turn off switch /1
  223. ; if any of interesting switches are on (/C, /O, /V, /S are not)
  224. ; set number of cylinders to 40
  225. ; choose new BPB depending on switches /1 and /8
  226. ;
  227. CheckSwitches proc near
  228. IF DEBUG
  229. ; See if the boot sector was initialised correctly
  230. cmp bootSignature, 0aa55H
  231. je BootSectorIsFine
  232. lea dx, msgFormatBroken
  233. jmp short SwitchError
  234. ENDIF ; DEBUG
  235. BootSectorIsFine:
  236. ; Disallow /C
  237. lea dx, msgInvalidParameter
  238. test switchmap, SWITCH_C
  239. jz CheckExcl
  240. SwitchError:
  241. call PrintString
  242. stc
  243. ret
  244. ; Only certain permutations of the switches /N /T /V /B /S and /V are legal.
  245. ; For specific cases see the file Switchmap.legal.
  246. CheckExcl:
  247. lea dx, msgIncompatibleParameters ; Error message
  248. test SwitchMap, SWITCH_B ; IF ( SWITCH_B)
  249. jz SVpermitted
  250. test SwitchMap, SWITCH_S or SWITCH_V ; THEN exclude SWITCH_S and
  251. jnz SwitchError ; SWITCH_V
  252. SVpermitted:
  253. test SwitchMap, SWITCH_8 ; IF ( SWITCH_8 )
  254. jz Check_N
  255. ; THEN
  256. test SwitchMap, SWITCH_N or SWITCH_T ; exclude SWITCH_N and
  257. jnz SwitchError
  258. test SwitchMap, SWITCH_V ; SWITCH_V if unaccompanied
  259. jz Check_N ; by SWITCH_S
  260. test SwitchMap, SWITCH_S
  261. jz SwitchError ; ENDIF ( SWITCH_8 )
  262. Check_N: ; IF ( SWITCH_N or SWITCH_T )
  263. test SwitchMap, SWITCH_N or SWITCH_T
  264. jz ExclChkDone
  265. test SwitchMap, SWITCH_1 or SWITCH_4 ; THEN exclude SWITCH_1 and
  266. jnz SwitchError ; SWITCH_4
  267. ExclChkDone:
  268. ; Patch the boot sector so that the boot strap loader knows what disk to
  269. ; boot from
  270. mov bootDrive, 00H
  271. cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
  272. jne CheckFor5InchDrives
  273. ; Formatting a hard disk so we must repatch the boot sector
  274. mov bootDrive, 80H
  275. test switchmap, not (SWITCH_S or SWITCH_V)
  276. jz SwitchesOkForHardDisk
  277. lea dx, msgIncompatibleParametersForHardDisk
  278. call PrintString
  279. stc
  280. ret
  281. ; Before checking the Volume Id we need to verify that a valid one exists
  282. ; We assume that unless a valid boot sector exists on the target disk, no
  283. ; valid Volume Id can exist.
  284. SwitchesOkForHardDisk:
  285. SaveReg <ax,bx,cx,dx,ds>
  286. mov al,drive
  287. mov cx,LogBootSect
  288. xor dx,dx
  289. lea bx,scratchBuffer ; ScratchBuffer := Absolute_Disk_Read(
  290. INT 25h ; Logical_sec_1 )
  291. pop ax ; Stupid Int 25! leaves flags
  292. ; on the stack. We throw them away
  293. jnc CheckSignature
  294. stc
  295. RestoreReg <ds,dx,cx,bx,ax>
  296. ret
  297. CheckSignature: ; IF (BootSector.BootSignature != aa55)
  298. mov ax, Word Ptr (ScratchBuffer + (BootSignature - boot))
  299. cmp ax, 0aa55h
  300. RestoreReg <ds,dx,cx,bx,ax>
  301. clc ; not an error, just not vol.
  302. retnz ; THEN RETURN
  303. call CheckVolumeId ; ELSE CheckVolumeID
  304. return
  305. OnlyVSpermitted:
  306. test switchmap, not (SWITCH_S or SWITCH_V)
  307. retz
  308. lea dx, msgIncompatibleParameters
  309. Print_And_Return:
  310. call PrintString
  311. stc
  312. return
  313. CheckFor5InchDrives:
  314. ;If drive type is anything other than 48 or 96, then only /V/S/H/N/T allowed
  315. cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
  316. je Got96
  317. cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
  318. je Got48
  319. test switchmap, not (SWITCH_V or SWITCH_S or SWITCH_N or SWITCH_T or SWITCH_H)
  320. jz Goto_Got_BPB
  321. lea dx,msgParametersNotSupportedByDrive
  322. jmp short Print_And_Return
  323. ; We have a 96tpi floppy drive
  324. ; /4 allows just about all switches however, /1 requires /4
  325. Got96:
  326. test switchmap, SWITCH_4
  327. jnz CheckForInterestingSwitches ;If /4 check /N/T/V/S
  328. test switchmap, SWITCH_1 ;If /1 and /4 check others
  329. jz Got48
  330. ;If only /1 with no /4, see if /N/T
  331. test SwitchMap,(Switch_N or Switch_T)
  332. jnz CheckForInterestingSwitches
  333. lea dx, msgIncompatibleParameters ;If no /4 but /1 die
  334. jmp short Print_And_Return
  335. Got48:
  336. ;Ignore /4 for non-96tpi 5 1/4" drives
  337. and switchmap, not SWITCH_4
  338. ;Ignore /1 if drive has only one head and not /8
  339. cmp word ptr deviceParameters.DP_BPB.BPB_Heads, 1
  340. ja CheckForInterestingSwitches
  341. test switchmap, SWITCH_8
  342. jz CheckForInterestingSwitches
  343. and switchmap, not SWITCH_1
  344. ;Are any interesting switches set?
  345. CheckForInterestingSwitches:
  346. test switchmap, not (SWITCH_V or SWITCH_S or SWITCH_H) ;Anything but /V/S/H?
  347. jz Goto_EndSwitchCheck ;No, everything ok
  348. ;At this point there are switches other than /v/s/h
  349. test SwitchMap,(SWITCH_N or SWITCH_T)
  350. jz Use_48tpi ;Not /n/t, so must be /b/1/8/4
  351. ;We've got /N/T, see if there are others
  352. test SwitchMap, not (SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or SWITCH_H)
  353. jz NT_Compatible ;Nope, all is well
  354. ;If 96tpi drive and /1 exists with /N/T, then okay, otherwise error
  355. cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
  356. jne Bad_NT_Combo
  357. test SwitchMap, not (SWITCH_1 or SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or SWITCH_H)
  358. jz Goto_Got_BPB
  359. Bad_NT_Combo:
  360. lea dx, msgIncompatibleParameters
  361. jmp Print_And_Return
  362. Goto_Got_BPB:
  363. jmp Got_BPB_Ok ;Sleazy, but je won't reach it
  364. Goto_EndSwitchCheck:
  365. jmp EndSwitchCheck
  366. ;There is a problem with /N/T in that IO.SYS will default to a BPB with the
  367. ;media byte set to F0 (other) if the /N/T combo is used for the format. This
  368. ;will cause problems if we are creating a media that has an assigned media
  369. ;byte, i.e. 160,180,320,360, or 720k media using /N/T. To avoid this problem,
  370. ;if we detect a /N/T combo that would correspond to one of these medias, then
  371. ; we will set things up using the /4/1/8 switches instead of the /N/T
  372. ; MT - 7/17/86 PTR 33D0110
  373. ; Combo's that we look for - 96tpi drive @ /T:40, /N:9
  374. ; 96tpi drive @ /T:40, /N:8
  375. ;
  376. ; Look for this combo after we set everything up with the /T/N routine
  377. ; 1.44 drive @ /T:80, /N:9
  378. NT_Compatible:
  379. cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
  380. jne Goto_Got_BPB
  381. cmp TrackCnt,40 ;Look for 40 tracks
  382. jne Got_BPB_Ok
  383. cmp NumSectors,9 ;9 sectors?
  384. je Found_48tpi_Type
  385. cmp NumSectors,8 ;8 sectors?
  386. jne Goto_Got_BPB ;Nope, different type, let it go thru
  387. or SwitchMap,SWITCH_8 ;Yes, turn on /8 switch
  388. Found_48tpi_Type:
  389. and SwitchMap,not (SWITCH_N or SWITCH_T) ;Turn off /T/N
  390. ;******End PTR fix
  391. ; if we have a 96 tpi drive then we will be using it in 48 tpi mode
  392. Use_48tpi:
  393. cmp byte ptr deviceParameters.DP_DeviceType, DEV_5INCH96TPI
  394. jne Not96tpi
  395. mov byte ptr deviceParameters.DP_MediaType, 1
  396. mov word ptr deviceParameters.DP_Cylinders, 40
  397. Not96tpi:
  398. ; Since we know we are formatting in 48 tpi mode turn on /4 switch
  399. ; (We use this info in LastChanceToSaveIt)
  400. or switchmap, SWITCH_4
  401. ; At this point we know that we will require a special BPB
  402. ; It will be one of:
  403. ; 0) 9 track 2 sides - if no switches
  404. ; 1) 9 track 1 side - if only /1 specified
  405. ; 2) 8 track 2 sides - if only /8 specified
  406. ; 3) 8 track 1 side - if /8 and /1 specified
  407. ;
  408. Get_BPBs:
  409. ; ax is used to keep track of which of the above BPB's we want
  410. xor ax, ax
  411. ; /B implies /8
  412. test switchmap, SWITCH_B
  413. jz NotSlashB
  414. or switchmap, SWITCH_8
  415. NotSlashB:
  416. test switchmap, SWITCH_1
  417. jz NotSingleSided
  418. add ax, 1
  419. NotSingleSided:
  420. test switchmap, SWITCH_8
  421. jz Not8SectorsPerTrack
  422. add ax, 2
  423. ; /8 implies Old_Dir = TRUE
  424. mov Old_Dir,TRUE
  425. Not8SectorsPerTrack:
  426. ; Ok now we know which BPB to use so lets move it to the device parameters
  427. mov bx, size a_BPB
  428. mul bx
  429. lea si, CustomBPBs
  430. add si, ax
  431. lea di, deviceParameters.DP_BPB
  432. mov cx, size a_BPB
  433. push ds
  434. pop es
  435. repnz movsb
  436. ;*****************************************************************
  437. ;* /N/T DCR stuff. Possible flaw exists if we are dealing with a
  438. ;* HardDisk. If they support the "custom format" features for
  439. ;* Harddisks too, then CheckForInterestingSwitches should
  440. ;* consider /n/t UNinteresting, and instead of returning
  441. ;* after setting up the custom BPB we fall through and do our
  442. ;* Harddisk Check.
  443. Got_BPB_OK:
  444. test switchmap,SWITCH_N+SWITCH_T
  445. jnz Setup_Stuff
  446. jmp EndSwitchCheck
  447. Setup_Stuff:
  448. ; Set up NumSectors and SectorsPerTrack entries correctly
  449. test switchmap,SWITCH_N
  450. jz No_Custom_Seclim
  451. mov ax,word ptr NumSectors
  452. mov DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax
  453. jmp short Handle_Cyln
  454. No_Custom_Seclim:
  455. mov ax,deviceParameters.DP_BPB.BPB_SectorsPerTrack
  456. mov NumSectors,ax
  457. Handle_Cyln:
  458. test switchmap,SWITCH_T
  459. jz No_Custom_Cyln
  460. ; Set up TrackCnt and Cylinders entries correctly
  461. mov ax,TrackCnt
  462. mov DeviceParameters.DP_Cylinders,ax
  463. jmp short Check_720
  464. No_Custom_Cyln:
  465. mov ax,DeviceParameters.DP_Cylinders
  466. mov TrackCnt,ax
  467. ;****PTM P868 - Always making 3 1/2 media byte 0F0h. If 720, then set to
  468. ; 0F9h and use the DOS 3.20 BPB. Should check all drives
  469. ; at this point (Make sure not 5 inch just for future
  470. ; protection)
  471. ; We will use the known BPB info for 720 3 1/2 diskettes for
  472. ; this special case. All other new diskette media will use the
  473. ; calculations that follow Calc_Total for BPB info.
  474. ; Fix MT 11/12/86
  475. Check_720:
  476. cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
  477. je Calc_Total
  478. cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
  479. je Calc_Total
  480. cmp TrackCnt,80
  481. jne Calc_Total
  482. cmp NumSectors,9
  483. jne Calc_Total
  484. ; At this point we know we have a 3 1/2 720kb diskette to format. Use the
  485. ; built in BPB rather than the one handed to us by DOS, because the DOS one
  486. ; will be based on the default for that drive, and it can be different from
  487. ; what we used in DOS 3.20 for the 720's. Short sighted on our part to use
  488. ; 0F9h as the media byte, should have use 0F0h (OTHER) and then we wouldn't
  489. ; have this problem.
  490. SaveReg <ds,es,si,di,cx>
  491. mov cx,seg data ;Setup seg regs, just in case they ain't!
  492. mov ds,cx
  493. mov es,cx
  494. mov si,offset BPB720 ;Copy the BPB!
  495. mov di,offset deviceParameters.DP_BPB
  496. mov cx,size a_BPB
  497. rep movsb
  498. RestoreReg <cx,di,si,es,ds>
  499. jmp EndSwitchCheck
  500. ;End PTM P868 fix ****************************************
  501. Calc_Total:
  502. mov ax,NumSectors
  503. mov bx,DeviceParameters.DP_BPB.BPB_Heads
  504. mul bl ; AX = # of sectors * # of heads
  505. mul TrackCnt ; DX:AX = Total Sectors
  506. or dx,dx
  507. jnz Got_BigTotalSectors
  508. mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax
  509. jmp short Set_BPB
  510. Got_BigTotalSectors:
  511. mov DeviceParameters.DP_BPB.BPB_BigTotalSectors,ax
  512. mov DeviceParameters.DP_BPB.BPB_BigTotalSectors+2,dx
  513. push dx ; preserve dx for further use
  514. xor dx,dx
  515. mov DeviceParameters.DP_BPB.BPB_TotalSectors,dx
  516. pop dx
  517. Set_BPB:
  518. ; We calculate the number of sectors required in a FAT. This is done as:
  519. ; # of FAT Sectors = TotalSectors / SectorsPerCluster * # of bytes in FAT to
  520. ; represent one cluster (i.e. 3/2) / BytesPerSector (i.e. 512)
  521. xor bx,bx
  522. mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster
  523. div bx ; DX:AX contains # of clusters
  524. ; now multiply by 3/2
  525. mov bx,3
  526. mul bx
  527. mov bx,2
  528. div bx
  529. xor dx,dx ; throw away modulo
  530. ; now divide by 512
  531. mov bx,512
  532. div bx
  533. ; dx:ax contains number of FAT sectors necessary
  534. inc ax ; Go one higher
  535. mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax
  536. mov DeviceParameters.DP_MediaType,0
  537. mov DeviceParameters.DP_BPB.BPB_MediaDescriptor,Custom_Media
  538. EndSwitchCheck:
  539. clc
  540. return
  541. CheckSwitches endp
  542. ;-------------------------------------------------------------------------------
  543. ; LastChanceToSaveIt:
  544. ; This routine is called when an error is detected in DiskFormat.
  545. ; If it returns with carry not set then DiskFormat is restarted.
  546. ; It gives the oem one last chance to try formatting differently.
  547. ; fLastChance gets set Then to prevent multiple prompts from being
  548. ; issued for the same diskette.
  549. ;
  550. ; Algorithm:
  551. ; IF (error_loc == Track_0_Head_1) &
  552. ; ( Device_type < 96TPI )
  553. ; THEN
  554. ; fLastChance := TRUE
  555. ; try formatting 48TPI_Single_Sided
  556. ; ELSE return ERROR
  557. ;
  558. LastChanceToSaveIt proc near
  559. cmp currentCylinder, 0
  560. jne WeCanNotIgnoreThisError
  561. cmp currentHead, 1
  562. jne WeCanNotIgnoreThisError
  563. cmp deviceParameters.DP_DeviceType, DEV_5INCH
  564. ja WeCanNotIgnoreThisError
  565. mov fLastChance, TRUE
  566. or switchmap, SWITCH_1
  567. call CheckSwitches
  568. clc
  569. ret
  570. WeCanNotIgnoreThisError:
  571. stc
  572. ret
  573. LastChanceToSaveIt endp
  574. ;-------------------------------------------------------------------------------
  575. WriteBootSector proc near
  576. ; Copy BPB to boot sector
  577. lea si, deviceParameters.DP_BPB
  578. lea di, bootBPB
  579. mov cx, size a_BPB
  580. push ds
  581. pop es
  582. repnz movsb
  583. ; Write out the boot sector
  584. mov al, drive
  585. mov cx, 1
  586. xor dx, dx
  587. lea bx, boot
  588. int 26H
  589. pop ax
  590. jc CanNotWriteBoot
  591. return
  592. CanNotWriteBoot:
  593. lea dx, msgBootWriteError
  594. call PrintString
  595. stc
  596. ret
  597. WriteBootSector endp
  598. ;-------------------------------------------------------------------------------
  599. ; OemDone:
  600. ;
  601. OemDone proc near
  602. ; if /b write out a fake dos & bios
  603. test switchmap, SWITCH_B
  604. jz Switch8?
  605. call WriteBogusDos
  606. retc
  607. Switch8?:
  608. test switchmap, SWITCH_8
  609. jz HardDisk?
  610. call ConvertToOldDirectoryFormat
  611. retc
  612. HardDisk?:
  613. cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
  614. clc
  615. retnz
  616. call SetPartitionTable
  617. return
  618. OemDone endp
  619. ;------------------------------------------------------------------------------
  620. data segment
  621. biosFilename db "x:\io.sys",0
  622. dosFilename db "x:\msdos.sys",0
  623. data ends
  624. ; simple code to stuff bogus dos in old-style diskette.
  625. BogusDos:
  626. push cs
  627. pop ds
  628. mov al,20h
  629. out 20h,al ; turn on the timer so the disk motor
  630. mov si,mesofs ; shuts off
  631. sys_mess_loop:
  632. lodsb
  633. end_sys_loop:
  634. or al,al
  635. jz end_sys_loop
  636. mov ah,14
  637. mov bx,7
  638. int 16
  639. jmp sys_mess_loop
  640. include bootmes.inc
  641. mesofs equ no_sys_mess - BogusDos
  642. WriteBogusDos proc near
  643. mov al,driveLetter
  644. mov biosFilename,al
  645. mov dosFilename,al
  646. mov cx, ATTR_HIDDEN or ATTR_SYSTEM
  647. lea dx, biosFilename
  648. mov ah,CREAT
  649. int 21h
  650. mov bx,ax
  651. mov cx, BIOS_SIZE
  652. push ds
  653. push cs
  654. pop ds
  655. assume ds:code
  656. lea dx, BogusDos
  657. mov ah,WRITE
  658. int 21h
  659. pop ds
  660. assume ds:data
  661. mov ah,CLOSE
  662. int 21h
  663. mov cx, ATTR_HIDDEN or ATTR_SYSTEM
  664. lea dx, dosFilename
  665. mov ah,CREAT
  666. int 21h
  667. mov bx,ax
  668. mov cx, DOS_SIZE
  669. lea dx, BogusDos
  670. mov ah,WRITE
  671. int 21h
  672. mov ah,CLOSE
  673. int 21h
  674. ; Comunicate system size to the main format program
  675. xor dx,dx
  676. mov ax,DOS_SIZE
  677. call AddToSystemSize
  678. xor dx,dx
  679. mov ax,BIOS_SIZE
  680. call AddToSystemSize
  681. clc
  682. return
  683. WriteBogusDos endp
  684. ;-------------------------------------------------------------------------------
  685. ConvertToOldDirectoryFormat proc near
  686. ;
  687. ; convert to 1.1 directory
  688. ;
  689. mov al,drive ; Get 1st sector of directory
  690. mov cx,1 ; 1.1 directory always starts on
  691. mov dx,3 ; sector 3
  692. lea bx,scratchBuffer
  693. int 25h
  694. pop ax ; clean up stack
  695. jnc DirectoryRead
  696. lea dx, msgDirectoryReadError
  697. call PrintString
  698. stc
  699. ret
  700. DirectoryRead:
  701. ; fix attribute of io.sys and msdos.sys
  702. lea bx,scratchBuffer
  703. mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
  704. add bx, size dir_entry
  705. mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
  706. wrtdir:
  707. mov al,[drive] ; write out the directory
  708. cbw
  709. mov cx,1
  710. mov dx,3
  711. lea bx,scratchBuffer
  712. int 26h
  713. pop ax ; clean up stack
  714. jnc DirectoryWritten
  715. lea dx, msgDirectoryWriteError
  716. call PrintString
  717. stc
  718. ret
  719. DirectoryWritten:
  720. test switchmap, SWITCH_S ; Was system requested?
  721. retnz ; yes, don't write old boot sector
  722. mov al,drive
  723. cbw
  724. mov bx,offset boot2 ; no, write old boot sector
  725. cmp deviceParameters.DP_BPB.BPB_Heads, 1
  726. je bootset8
  727. mov word ptr [bx+3],0103h ; start address for double sided drives
  728. bootset8:
  729. mov cx,1
  730. xor dx,dx
  731. int 26h ; write out that boot sector
  732. pop ax
  733. retnc
  734. lea dx, msgBootWriteError
  735. call PrintString
  736. stc
  737. ret
  738. ConvertToOldDirectoryFormat endp
  739. ;-------------------------------------------------------------------------------
  740. a_PartitionTableEntry struc
  741. BootInd db ?
  742. BegHead db ?
  743. BegSector db ?
  744. BegCylinder db ?
  745. SysInd db ?
  746. EndHead db ?
  747. EndSector db ?
  748. EndCylinder db ?
  749. RelSec dd ?
  750. CSec dd ?
  751. a_PartitionTableEntry ends
  752. ; structure of the IBM hard disk boot sector:
  753. IBMBoot STRUC
  754. db 512 - (4*size a_PartitionTableEntry + 2) dup(?)
  755. PartitionTable db 4*size a_PartitionTableEntry dup(?)
  756. Signature dw ?
  757. IBMBoot ENDS
  758. SetPartitionTable proc near
  759. mov ax, 0 ; Head
  760. mov bx, 0 ; Cylinder
  761. mov cx, 0 ; Sector
  762. lea dx, boot2
  763. call ReadSector
  764. jnc PartitionTableRead
  765. lea dx, msgPartitionTableReadError
  766. call PrintString
  767. stc
  768. ret
  769. PartitionTableRead:
  770. ; Check to see if there is a partition table (by looking for its signature)
  771. cmp boot2.signature, 0aa55H
  772. jne BadPartitionTable
  773. ; Scan all the partitions search for the FIRST DOS partition. We then set the
  774. ; appropriate FAT size in the FIRST DOS partition and return.
  775. lea bx, boot2.PartitionTable
  776. partitionscan:
  777. ; have we scanned all partitions?
  778. cmp bx,(offset Boot2.PartitionTable)+4*size a_PartitionTableEntry
  779. jae BadPartitionTable
  780. cmp [bx].sysind,1
  781. jz dochange
  782. cmp [bx].sysind,4
  783. jz dochange
  784. add bx,size a_PartitionTableEntry
  785. jmp partitionscan
  786. dochange:
  787. mov [bx].sysind,4 ; assume 16 bit fat
  788. cmp fbigfat,0 ; test assumption
  789. jnz partitionset ; is 16 bit fat, assumption correct
  790. mov [bx].sysind,1 ; 12 bit fat, pre 3.0 dos can read it
  791. partitionset:
  792. mov ax, 0 ; Head
  793. mov bx, 0 ; Cylinder
  794. mov cx, 0 ; Sector
  795. lea dx, boot2
  796. call WriteSector
  797. retnc
  798. lea dx, msgPartitionTableWriteError
  799. call PrintString
  800. stc
  801. ret
  802. BadPartitionTable:
  803. lea dx, msgBadPartitionTable
  804. call PrintString
  805. stc
  806. ret
  807. SetPartitionTable endp
  808. ;-------------------------------------------------------------------------------
  809. ; ReadSector:
  810. ; Read one sector
  811. ;
  812. ; Input:
  813. ; ax - head
  814. ; bx - cylinder
  815. ; cx - sector
  816. ; dx - transfer address
  817. ReadSector proc near
  818. mov TrackReadWritePacket.TRWP_FirstSector, cx
  819. mov cx,(RAWIO shl 8) or READ_TRACK
  820. call SectorIO
  821. return
  822. ReadSector endp
  823. ;-------------------------------------------------------------------------------
  824. ; WriteSector:
  825. ; Write one sector
  826. ;
  827. ; Input:
  828. ; ax - head
  829. ; bx - cylinder
  830. ; cx - sector
  831. ; dx - transfer address
  832. WriteSector proc near
  833. mov TrackReadWritePacket.TRWP_FirstSector, cx
  834. mov cx,(RAWIO shl 8) or WRITE_TRACK
  835. call SectorIO
  836. return
  837. WriteSector endp
  838. ;-------------------------------------------------------------------------------
  839. ; SectorIO:
  840. ; Read/Write one sector
  841. ;
  842. ; Input:
  843. ; ax - head
  844. ; bx - cylinder
  845. ; cx - (RAWIO shl 8) or READ_TRACK
  846. ; - (RAWIO shl 8) or WRITE_TRACK
  847. ; dx - transfer address
  848. SectorIO proc near
  849. mov TrackReadWritePacket.TRWP_Head, ax
  850. mov TrackReadWritePacket.TRWP_Cylinder, bx
  851. mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress, dx
  852. mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress + 2, ds
  853. mov TrackReadWritePacket.TRWP_SectorsToReadWrite, 1
  854. mov bl, drive
  855. inc bl
  856. mov ax, (IOCTL shl 8) or GENERIC_IOCTL
  857. lea dx, trackReadWritePacket
  858. int 21H
  859. return
  860. SectorIO endp
  861. ;-------------------------------------------------------------------------------
  862. data segment
  863. oldDrive db ?
  864. FCBforVolumeIdSearch db 0ffH
  865. db 5 dup(0)
  866. db 08H
  867. db 0
  868. db "???????????"
  869. db 40 DUP(0)
  870. data ends
  871. GetVolumeId proc near
  872. ; Input:
  873. ; dl = drive
  874. ; di = name buffer
  875. ; Save current drive
  876. mov ah,19H
  877. int 21H
  878. mov oldDrive, al
  879. ; Change current drive to the drive that has the volume id we want
  880. mov ah, 0eH
  881. int 21H
  882. ; Search for the volume id
  883. mov ah, 11H
  884. lea dx, FCBforVolumeIdSearch
  885. int 21H
  886. push ax
  887. ; Restore current drive
  888. mov ah, 0eH
  889. mov dl,oldDrive
  890. int 21H
  891. ; Did the search succeed?
  892. pop ax
  893. or al,al
  894. jz CopyVolumeId
  895. stc
  896. ret
  897. CopyVolumeId:
  898. ; Find out where the FCB for the located volume id was put
  899. mov ah,2fH
  900. int 21H
  901. ; Copy the Volume Id
  902. mov si, bx
  903. add si, 8
  904. push es
  905. push ds
  906. pop es
  907. pop ds
  908. mov cx, 11
  909. rep movsb
  910. push es
  911. pop ds
  912. clc
  913. ret
  914. GetVolumeId endp
  915. data segment
  916. oldVolumeId db 11 dup(0)
  917. data ends
  918. CheckVolumeId proc near
  919. ; Get the volume id that's on the disk
  920. lea di, oldVolumeId
  921. mov dl, drive
  922. call GetVolumeId
  923. jnc Ask_User ;Did we find one?
  924. clc ;No, return with no error
  925. ret
  926. ; Ask the user to enter the volume id that he/she thinks is on the disk
  927. ; (first blank out the input buffer)
  928. Ask_User:
  929. lea dx, ptr_msgWhatIsVolumeId?
  930. call std_printf
  931. call user_string
  932. call crlf
  933. ; If the user just pressed ENTER, then there must be no label
  934. cmp inbuff+1, 0
  935. jne CompareVolumeIds
  936. cmp oldVolumeId, 0
  937. jne BadVolumeId
  938. ret
  939. CompareVolumeIds:
  940. ; pad the reponse with blanks
  941. ; The buffer is big enough so just add 11 blanks to what the user typed in
  942. push ds
  943. pop es
  944. mov cx, 11
  945. xor bx,bx
  946. mov bl, inbuff + 1
  947. lea di, inbuff + 2
  948. add di, bx
  949. mov al, ' '
  950. rep stosb
  951. ; Make the reply all uppercase
  952. mov cl, inbuff + 1
  953. xor ch,ch
  954. lea si, inbuff + 2
  955. VolumeToUpper:
  956. mov al, [si]
  957. cmp al, 'a'
  958. jb NextLetter
  959. cmp al, 'z'
  960. ja NextLetter
  961. sub al, 'a' - 'A'
  962. mov [si],al
  963. NextLetter:
  964. inc si
  965. loop VolumeToUpper
  966. ; Now compare what the user specified with what is really out there
  967. mov cx, 11
  968. lea si, inbuff + 2
  969. lea di, oldVolumeId
  970. repe cmpsb
  971. jne BadVolumeId
  972. ret
  973. BadVolumeId:
  974. lea dx, msgBadVolumeId
  975. call PrintString
  976. stc
  977. ret
  978. CheckVolumeId endp
  979. code ends
  980. end