Source code of Windows XP (NT5)
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.

2029 lines
51 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. ;===========================================================================
  7. ;
  8. ; FILE: PHASE1.ASM
  9. ;
  10. ;===========================================================================
  11. ;===========================================================================
  12. ;Include file declarations
  13. ;===========================================================================
  14. debug equ 0
  15. .xlist
  16. INCLUDE DOSEQUS.INC
  17. INCLUDE DOSMAC.INC
  18. INCLUDE SYSCALL.INC
  19. INCLUDE ERROR.INC
  20. INCLUDE DIRENT.INC
  21. INCLUDE BPB.INC
  22. INCLUDE BOOTSEC.INC
  23. INCLUDE FOREQU.INC
  24. INCLUDE FORMACRO.INC
  25. INCLUDE IOCTL.INC
  26. INCLUDE FORSWTCH.INC
  27. .list
  28. ;
  29. ;---------------------------------------------------------------------------
  30. ;
  31. ; M020 : Looked for EXT_BOOT_SIG before assuming that the BPB in the boot
  32. ; sector is an extended one. Bug #4946
  33. ;
  34. ;---------------------------------------------------------------------------
  35. ;
  36. ;===========================================================================
  37. ; Data segment
  38. ;===========================================================================
  39. DATA SEGMENT PUBLIC PARA 'DATA'
  40. ;===========================================================================
  41. ; Declarations for all publics in other modules used by this module
  42. ;===========================================================================
  43. ;Constants
  44. EXTRN EXIT_NO :ABS
  45. EXTRN EXIT_FATAL :ABS
  46. ;Bytes
  47. EXTRN CMCDDFlag :BYTE
  48. EXTRN ValidSavedDeviceParameters:BYTE
  49. EXTRN DriveToFormat :BYTE
  50. EXTRN msgFormatNotSupported :BYTE
  51. EXTRN msgInsertDisk :BYTE
  52. EXTRN msgInvalidDeviceParameters:BYTE
  53. EXTRN ContinueMsg :BYTE
  54. EXTRN msgNotCompatablePart :BYTE
  55. EXTRN msgExistingFormatDiffers :BYTE
  56. EXTRN msgNoQuickFormat :BYTE
  57. EXTRN msgCrLf :BYTE
  58. EXTRN msgCheckExistingDiskFormat:BYTE
  59. EXTRN Extended_Error_Msg :BYTE
  60. EXTRN old_dir :BYTE
  61. EXTRN ExitStatus :BYTE
  62. ifdef NEC_98
  63. EXTRN SizeMap :BYTE
  64. EXTRN msgInsufficientMemory :BYTE
  65. endif
  66. ;Words
  67. EXTRN SectorsInRootDirectory :WORD
  68. EXTRN Paras_Per_Fat :WORD
  69. EXTRN SwitchMap :WORD
  70. EXTRN SwitchMap2 :WORD
  71. EXTRN SwitchCopy :WORD
  72. ifdef NEC_98
  73. EXTRN SASI1024Table :WORD
  74. EXTRN SCSI1024Table :WORD
  75. EXTRN Small2048Table :WORD
  76. EXTRN Large512Table :WORD
  77. EXTRN Large256Table :WORD
  78. else
  79. EXTRN DiskTable :WORD
  80. EXTRN DiskTable2 :WORD
  81. endif
  82. EXTRN RWErrorCode :WORD
  83. ;Pointers
  84. EXTRN FatSpace :DWORD
  85. ;Structures
  86. EXTRN SavedParams :BYTE
  87. EXTRN DeviceParameters :BYTE
  88. EXTRN IsExtRAWIODrv :BYTE
  89. EXTRN SwitchDevParams :BYTE
  90. EXTRN Read_Write_Relative :BYTE
  91. EXTRN SetDPBPacket :BYTE
  92. fBigFat DB FALSE
  93. fBig32Fat DB FALSE
  94. ThisSysInd DB 0 ; indicates size of FAT
  95. StartSector DD ? ; holds first data sector
  96. TotalClusters DD ? ; holds total #clusters on disk
  97. UnformattedHardDrive DB ?
  98. ifdef NEC_98
  99. SAV_INT24_OFF DW 0 ; original int 24 vector address
  100. SAV_INT24_SEG DW 0
  101. endif
  102. MediaSensePacket A_MEDIA_SENSE <> ; structure used in media
  103. ; sensing call
  104. ; the following table provides templates for
  105. ; BPBs used in CP/M disks.
  106. ; Order is very important (used by both MSFOR and PHASE1)
  107. CustomCPMBPBs LABEL BYTE
  108. BPB320 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffh, 1, 8, 2, 0, 0, 0, 0>
  109. BPB160 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feh, 1, 8, 1, 0, 0, 0, 0>
  110. BPB360 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdh, 2, 9, 2, 0, 0, 0, 0>
  111. BPB180 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fch, 2, 9, 1, 0, 0, 0, 0>
  112. EndCustomCPMBPBs LABEL BYTE
  113. ; This must folow CustomCPMBPBs
  114. BPB12 a_BPB <512, 1, 1, 2, 224, 2*15*80, 0F9h, 7, 15, 2, 0, 0, 0, 0>
  115. BPB720 a_BPB <512, 2, 1, 2, 112, 2* 9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
  116. BPB1440 a_BPB <512, 1, 1, 2, 224, 2*18*80, 0F0h, 9, 18, 2, 0, 0, 0, 0>
  117. BPB2880 a_BPB <512, 2, 1, 2, 240, 2*36*80, 0F0h, 9, 36, 2, 0, 0, 0, 0>
  118. ifdef NEC_98
  119. BPB640 a_BPB <512, 2, 1, 2, 112, 2* 8*80, 0FBh, 2, 8, 2, 0, 0, 0, 0>
  120. BPB1250 a_BPB <1024,1, 1, 2, 192, 2* 8*77, 0FEh, 2, 8, 2, 0, 0, 0, 0>
  121. BPB128 a_BPB <512,4,1, 2, 512, 0, 0F0h, 0F3h, 019h, 1, 0,0, 0CBE0h, 03h>
  122. BPB230 a_BPB <512,8,1, 2, 512, 0, 0F0h, 0DAh, 019h, 1, 0,0, 0CF75h, 06h>
  123. BPB650 a_BPB <512,020h,1, 2, 512, 0, 0F0h, 09Fh, 019h, 1, 0,0, 0D040h, 013h>
  124. endif
  125. EndStandardBPBs LABEL BYTE
  126. ; the following table indicates the switches
  127. ; which must be set for the given CP/M media
  128. CPMSwitchTable LABEL BYTE
  129. dw Switch_4 + Switch_8 ;320K
  130. dw Switch_1 + Switch_4 + Switch_8 ;160K
  131. dw Switch_4 ;360K
  132. dw Switch_1 + Switch_4 ;180K
  133. ; ========================================================================
  134. ; Tables added for media sense support in 5.00.
  135. ; ========================================================================
  136. MediaTable LABEL WORD
  137. ifdef NEC_98
  138. dw 0 ; 0
  139. dw OFFSET BPB12 ; 1 /5
  140. dw OFFSET BPB720 ; 2 /9
  141. dw 0 ; 3
  142. dw OFFSET BPB1250 ; 4 /M
  143. dw 0 ; 5
  144. dw 0 ; 6
  145. dw OFFSET BPB1440 ; 7 /4
  146. dw 0 ; 8
  147. dw OFFSET BPB2880 ; 9 not supported! but rest.
  148. else
  149. dw 0 ; 0
  150. dw 0 ; 1
  151. dw OFFSET BPB720 ; 2
  152. dw 0 ; 3
  153. dw 0 ; 4
  154. dw 0 ; 5
  155. dw 0 ; 6
  156. dw OFFSET BPB1440 ; 7
  157. dw 0 ; 8
  158. dw OFFSET BPB2880 ; 9
  159. endif
  160. EndMediaTable LABEL WORD
  161. DATA ENDS
  162. ;===========================================================================
  163. ; Executable code segment
  164. ;===========================================================================
  165. CODE SEGMENT PUBLIC PARA 'CODE'
  166. ASSUME CS:CODE, DS:DATA, ES:DATA
  167. ;===========================================================================
  168. ; Declarations for all externs
  169. ;===========================================================================
  170. ;Functions
  171. EXTRN AccessDisk :NEAR
  172. EXTRN USER_STRING :NEAR
  173. EXTRN CrLf :NEAR
  174. EXTRN CheckSwitches :NEAR
  175. EXTRN Read_Disk :NEAR
  176. EXTRN Yes? :NEAR
  177. ifdef NEC_98
  178. EXTRN GetDeviceParameters :NEAR
  179. EXTRN Alloc_Dir_Buf :NEAR
  180. EXTRN Alloc_Fat_Buf :NEAR
  181. EXTRN Alloc_Fat_Sec_Buf :NEAR
  182. EXTRN Alloc_DirBuf2 :NEAR
  183. EXTRN Alloc_Cluster_Buf :NEAR
  184. ifdef OPKBLD
  185. EXTRN Do_Switch_S :NEAR
  186. endif ;OPKBLD
  187. EXTRN ZeroAllBuffers :NEAR
  188. endif ;NEC_98
  189. ;Labels
  190. EXTRN FatalExit :NEAR
  191. EXTRN ExitProgram :NEAR
  192. ;===========================================================================
  193. ; Declarations for all publics in this module
  194. ;===========================================================================
  195. PUBLIC Phase1Initialisation
  196. PUBLIC MediaSense
  197. PUBLIC TargPrm
  198. PUBLIC CopyToSwitchDevParams
  199. PUBLIC CompareDevParams
  200. PUBLIC LoadSwitchDevParams
  201. PUBLIC DetermineExistingFormat
  202. PUBLIC DetermineExistingFormatNomsg
  203. PUBLIC IsValidBpb
  204. PUBLIC ResetDeviceParameters
  205. PUBLIC DetermineCPMFormat
  206. PUBLIC SetCPMParameters
  207. PUBLIC Set_BPB_Info
  208. PUBLIC Scan_Disk_Table
  209. PUBLIC Calc_Big16_Fat
  210. PUBLIC Calc_Big32_Fat
  211. PUBLIC Calc_Small_Fat
  212. PUBLIC SetStartSector
  213. PUBLIC SetfBigFat
  214. PUBLIC GetTotalClusters
  215. PUBLIC fBigFat
  216. PUBLIC fBig32Fat
  217. PUBLIC StartSector
  218. PUBLIC TotalClusters
  219. PUBLIC CustomCPMBPBs
  220. PUBLIC CPMSwitchTable
  221. PUBLIC EndStandardBPBs
  222. PUBLIC BPB720
  223. ifdef NEC_98
  224. PUBLIC BPB640
  225. PUBLIC BPB12
  226. PUBLIC BPB1250
  227. PUBLIC BPB128
  228. PUBLIC BPB230
  229. PUBLIC BPB650
  230. endif
  231. PUBLIC UnformattedHardDrive
  232. ; ==========================================================================
  233. ; Phase1Initialisation:
  234. ; This routine sets up fBigFat
  235. ; It also does most of the other initialisation
  236. ;
  237. ; Algorithm:
  238. ; Perform media sensing and if present adjust DeviceParameters
  239. ; Check switches against parameters
  240. ; Use switches to modify device parameters
  241. ; Save a copy of current DeviceParameters in SwitchDevParams
  242. ;
  243. ; IF (!SWITCH_U)
  244. ; {
  245. ; IF (!ValidBootRecord || !ValidBPB)
  246. ; set SWITCH_U
  247. ; ELSE
  248. ; {
  249. ; get device layout from BPB on disk
  250. ; IF (DeviceParameters = SwitchDevParams)
  251. ; do safe/quick format
  252. ; ELSE
  253. ; {
  254. ; IF (Switch_N || Switch_T || Switch_F)
  255. ; {
  256. ; Issue warning
  257. ; Format with BPB from SwitchDevParams if user continues
  258. ; }
  259. ; ELSE
  260. ; do safe/quick format
  261. ; }
  262. ; }
  263. ; }
  264. ;
  265. ; Calculate start sector (first sector not used by DOS)
  266. ; fBig32Fat = (((TotalSectors - StartSector)/SectorsPerCluster) >= 65526)
  267. ; fBigFat = (((TotalSectors - StartSector)/SectorsPerCluster) >= 4086)
  268. ; ==========================================================================
  269. Phase1Initialisation proc near
  270. ; use DevParms to check for removable
  271. test DeviceParameters.DP_DeviceAttributes,1
  272. .errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
  273. jnz @F ; Bit 0=1 --> not removable
  274. ; New media sensing call added for 5.00 will see if
  275. ; see if media sensing is avaliable and if it is will
  276. ; reset DeviceParameters to the real parameters for
  277. ; the type of disk being formatted.
  278. ifndef NEC_98
  279. call MediaSense
  280. else
  281. cmp DeviceParameters.DP_DeviceType, DEV_HARDDISK ; Hard disk?
  282. .errnz EDP_DEVICETYPE NE DP_DEVICETYPE
  283. jne @F ; No
  284. ; We ignore INT24 in order not to be stop formatting
  285. ; when "INT21 AH=32" is called.
  286. ; Set my INT24
  287. push es
  288. mov ah, 35h
  289. mov al, 24h
  290. int 21h ; get INT24's vector address
  291. mov SAV_INT24_OFF, bx ; save original INT24
  292. mov SAV_INT24_SEG, es ; save original INT24
  293. pop es
  294. push ds
  295. push cs
  296. pop ds
  297. mov ah, 25h
  298. mov al, 24h
  299. mov dx, OFFSET MY_INT24
  300. int 21h ; set my INT24
  301. pop ds
  302. ; Update Default BPB
  303. push ds
  304. push bx
  305. mov ah, 32h
  306. mov dl, DriveToFormat
  307. inc dl
  308. int 21h ; Get Drive Parameter Block
  309. pop bx
  310. pop ds
  311. ; Set original INT 24
  312. push ds
  313. push dx
  314. mov ah, 25h
  315. mov al, 24h
  316. mov ds, SAV_INT24_SEG
  317. mov dx, SAV_INT24_OFF
  318. int 21h ; set original INT24
  319. pop dx
  320. pop ds
  321. ; Get default BPB
  322. lea DX, DeviceParameters
  323. mov DeviceParameters.DP_SpecialFunctions, 0
  324. call GetDeviceParameters
  325. ; Allocate memory
  326. call Alloc_Dir_Buf ; Allocate root directory buffer
  327. jc gi_memerr
  328. call Alloc_Fat_Buf ; Allocate FAT buffer
  329. jc gi_memerr
  330. call Alloc_Fat_Sec_Buf ; Allocate fat sector buffer
  331. jc gi_memerr
  332. call Alloc_DirBuf2 ; Allocate 1-sector buffer DirBuf (general-
  333. ; purpose use)
  334. jc gi_memerr
  335. call Alloc_Cluster_Buf ; get room for retry buffer
  336. ifdef OPKBLD
  337. call Do_Switch_S ; Load system files if needed
  338. ; carry flag determined by Do_Switch_S
  339. else
  340. clc
  341. endif ;OPKBLD
  342. call ZeroAllBuffers ; initialize buffers
  343. jmp short @f
  344. gi_memerr:
  345. Message msgInsufficientMemory
  346. stc
  347. ret
  348. endif
  349. @@:
  350. ; Ensure that there is a valid #
  351. ; of Sectors in the track table
  352. mov ValidSavedDeviceParameters, 1
  353. cmp IsExtRAWIODrv,0
  354. je OldTabOff2
  355. mov SavedParams.EDP_TrackTableEntries, 0
  356. mov DeviceParameters.EDP_TrackTableEntries,0
  357. jmp short SetBPBnf
  358. OldTabOff2:
  359. mov SavedParams.DP_TrackTableEntries, 0
  360. ; Initialise to zero to see if
  361. ; CheckSwitches define track layout
  362. mov DeviceParameters.DP_TrackTableEntries,0
  363. SetBPBnf:
  364. call Set_BPB_Info ; Check to see if we are on
  365. ; Fat system.If not set BPB to proper
  366. ; values for format.
  367. SetMTsupp:
  368. ; Check switches against parameters
  369. ; and use switches to modify device
  370. ; parameters
  371. call CheckSwitches
  372. retc
  373. call CopyToSwitchDevParams ; Save a copy of deviceparameters as
  374. ; returned by CheckSwitches
  375. mov ax,SwitchMap ; No need to check existing format
  376. and ax,SWITCH_U+SWITCH_Q
  377. cmp ax,SWITCH_U ; if unconditional format specified
  378. jnz CheckExistingFormat
  379. jmp DevParamsOk
  380. CheckExistingFormat:
  381. ; New call added for 5.00 to see if the disk has been
  382. ; previously formatted, and if so this will reset
  383. ; DeviceParameters to those of the existing format.
  384. call DetermineExistingFormat
  385. jnc ValidExistingFormat ; carry clear if valid existing format
  386. InvalidExistingFormat:
  387. and RWErrorCode,0ffh ; check low byte for 'drive not ready' error
  388. cmp RWErrorCode,ERROR_I24_NOT_READY ;'not ready' error code = 2
  389. jne CheckForQ ; no error reading disk
  390. ; 'not ready' error occurred, give msg
  391. mov AX,21 ; load AX with extended error code for not ready
  392. SetFatalErr:
  393. Extended_Message ; deliver message "Not Ready"
  394. mov ExitStatus,EXIT_FATAL ; M006;
  395. stc
  396. jmp EndPhase1
  397. CheckForQ:
  398. test SwitchMap,SWITCH_Q ; Need to give message if /q was specified
  399. jz MakeUnconditional
  400. test SwitchCopy,(SWITCH_T or SWITCH_N or SWITCH_F) ; did user specify size?
  401. jnz TurnOffQ ; do an unconditional format at specified size
  402. ifdef OPKBLD
  403. ; Let OEM's quickformat a clean disk
  404. test DeviceParameters.DP_DeviceAttributes,1
  405. jnz DevParamsOk ; Bit 0=1 --> not removable
  406. endif ;OPKBLD
  407. Message msgNoQuickFormat ; Inform user quick format cannot be done
  408. call Yes? ; Continue with unconditional format?
  409. pushf
  410. Message msgCrLf
  411. popf
  412. jnc TurnOffQ
  413. mov ExitStatus,EXIT_NO ; load exit code 5 (response is 'no')
  414. jmp ExitProgram ; User wants to exit
  415. TurnOffQ:
  416. and SwitchMap,NOT SWITCH_Q ; Turn off /Q to continue
  417. MakeUnconditional:
  418. or SwitchMap,SWITCH_U ; Enable /U since invalid existing format
  419. or SwitchMap2, Switch2_C ; Enable /C since invalid existing format
  420. jmp SHORT DevParamsOk ; Device parameters will not have been
  421. ; modified since invalid existing format
  422. ValidExistingFormat:
  423. call CompareDevParams ; see if SwitchDevParams = DeviceParameters
  424. jnc DevParamsOk ; they are equal
  425. ; Check if user had specified a format
  426. ; size, since DeviceParameters on disk
  427. ; are different.
  428. test SwitchMap,SWITCH_Q ; special case where size was specified
  429. ; together with /Q :- use size specified
  430. ; only if invalid existing format
  431. jnz DevParamsOk ; use the parameters found on disk
  432. or SwitchMap,SWITCH_U ; Enable /U since new format specified
  433. or SwitchMap2, Switch2_C ; Enable /C since new format specified
  434. call LoadSwitchDevParams ; Set deviceparameters to SwitchDevParams
  435. ; i.e. follow user-specified size
  436. DevParamsOk:
  437. call SetDOS_Dpb ; m035 Setup default DOS DPB for this
  438. ; drive (for memory cards).
  439. jc SetFatalErr
  440. ; Store sector table info (layout of
  441. ; each track)
  442. mov CX, DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerTrack;CX = loop count
  443. .errnz EDP_BPB NE DP_BPB
  444. mov AX, 1 ;AX = sector #
  445. mov BX, DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector ;BX = sector size
  446. cmp IsExtRAWIODrv,0
  447. je OldTabOff
  448. cmp DeviceParameters.EDP_TrackTableEntries,0
  449. jne TrackLayoutSet ; There is a good track layout
  450. mov DeviceParameters.EDP_TrackTableEntries,CX
  451. lea DI, DeviceParameters.EDP_SectorTable
  452. jmp short GotTabOff
  453. OldTabOff:
  454. cmp DeviceParameters.DP_TrackTableEntries,0
  455. jne TrackLayoutSet ; There is a good track layout
  456. mov DeviceParameters.DP_TrackTableEntries,CX
  457. lea DI, DeviceParameters.DP_SectorTable
  458. GotTabOff:
  459. cld
  460. LoadSectorTable:
  461. stosw ; Write the sector number
  462. xchg AX, BX ; Get the sector size in bytes
  463. stosw ; Write the sector size
  464. xchg AX, BX
  465. inc AX ; Go to the next sector
  466. loop LoadSectorTable
  467. TrackLayoutSet:
  468. call SetStartSector
  469. call SetfBigFat
  470. call GetTotalClusters
  471. clc
  472. EndPhase1:
  473. return
  474. Phase1Initialisation endp
  475. ; =========================================================================
  476. ;
  477. ; MediaSense
  478. ; Checks for media sensing via IOCtl 440d subfuction 0868.
  479. ; If sensing is supported the user will be prompted to insert
  480. ; the disk if it's not detect and then the device parameters
  481. ; will be set according to the type of media being used.
  482. ;
  483. ; Before we can use the type returned we must be sure it's
  484. ; not a larger size disk than is formattable in the drive.
  485. ; We can do this by checking the media type byte in the
  486. ; saved device parameters.
  487. ;
  488. ; Input:
  489. ; DriveToFormat - Must have already been set
  490. ;
  491. ; =========================================================================
  492. MediaSense PROC NEAR
  493. mov BL, DriveToFormat
  494. inc BX
  495. mov CX, (RAWIO shl 8) or SENSE_MEDIA_TYPE
  496. cmp IsExtRAWIODrv,0
  497. je DoIOCTL1
  498. mov CX, (EXTRAWIO shl 8) or SENSE_MEDIA_TYPE
  499. DoIOCTL1:
  500. lea DX,MediaSensePacket
  501. ; First check if BIOS supports call
  502. mov AX, (IOCTL shl 8) or IOCTL_QUERY_BLOCK
  503. int 21h
  504. jc MediaSenseExit
  505. ; Now do actual call
  506. mov AX, (IOCTL shl 8) or GENERIC_IOCTL
  507. int 21h
  508. jnc GotMediaSense
  509. cmp AL,error_not_ready
  510. jne MediaSenseExit ; Machine does not support media sensing
  511. call TargPrm ; Insert disk prompt
  512. jmp SHORT MediaSense ; Retry the operation
  513. ; See if the type of media inserted is the same as the
  514. ; default for this type of drive and if not check to
  515. ; be sure it's
  516. GotMediaSense:
  517. mov AL,MediaSensePacket.MS_DEVICETYPE ; AL == media type
  518. cmp SavedParams.DP_DEVICETYPE,AL ; If the media in the
  519. .errnz EDP_DEVICETYPE NE DP_DEVICETYPE
  520. jl MediaSenseExit ; drv is > default size, use default
  521. ; Load BPB for sensed media
  522. xor AH,AH
  523. shl AX,1 ; AX == word offset in media table
  524. mov BX, offset MediaTable ; BX -> Start of media table
  525. add BX, AX ; BX -> Sensed type in media table
  526. cmp BX, offset EndMediaTable ; Make sure we're still in the table
  527. jge MediaSenseExit
  528. mov SI,[BX] ; DS:SI -> Sensed device parameters
  529. or SI,SI
  530. je MediaSenseExit ; Unknown Media?!
  531. lea DI, DeviceParameters.DP_BPB ; ES:DI -> Format parameters
  532. .errnz EDP_BPB NE DP_BPB
  533. mov CX, size A_BPB ; CX = bytes to move
  534. cmp IsExtRAWIODrv,0
  535. je DoIOCTL2
  536. mov CX, size A_BF_BPB ; CX = bytes to move
  537. DoIOCTL2:
  538. cld
  539. rep movsb
  540. ;
  541. ; Update the D_Cylinders. With 120mb floppies the cylinders field does change
  542. ; as opposed 720/1.44 drives
  543. ; We just back calculate the cylinders from sec/track, heads & total sectors
  544. ;
  545. .386
  546. push edx
  547. push ecx
  548. push eax
  549. movzx eax, DeviceParameters.DP_BPB.A_BPB_Heads
  550. movzx edx, DeviceParameters.DP_BPB.A_BPB_SectorsPerTrack
  551. mul edx
  552. mov ecx, eax ; save sectors per cylinder in ECX
  553. xor eax, eax
  554. mov ax, DeviceParameters.DP_BPB.A_BPB_TotalSectors
  555. or ax, ax
  556. jnz mse_sec_ok
  557. mov eax, dword ptr DeviceParameters.DP_BPB.A_BPB_BigTotalSectors
  558. mse_sec_ok:
  559. div ecx ; EAX = number of cylinders
  560. mov DeviceParameters.DP_Cylinders, ax
  561. pop eax
  562. pop ecx
  563. pop edx
  564. .8086
  565. MediaSenseExit:
  566. ret
  567. MediaSense ENDP
  568. ;========================================================================
  569. ;
  570. ; TargPrm : This procedure prompts the user to insert the target disk
  571. ; into the drive.
  572. ;
  573. ;========================================================================
  574. TargPrm PROC NEAR
  575. mov AL, DriveToFormat
  576. call AccessDisk
  577. Message MsgInsertDisk
  578. Message ContinueMsg
  579. call USER_STRING
  580. call CrLf
  581. ret
  582. TargPrm ENDP
  583. ;=========================================================================
  584. ;
  585. ; CopyToSwitchDevParams : This procedure copies the structure
  586. ; DeviceParameters into SwitchDevParams.
  587. ; Registers destroyed : CX,DI,SI
  588. ; Assumes : DS:DATA, ES:Nothing
  589. ;
  590. ;=========================================================================
  591. CopyToSwitchDevParams proc NEAR
  592. push DS
  593. pop ES
  594. mov DI,OFFSET SwitchDevParams ; ES:DI --> dest. parms
  595. mov SI,OFFSET DeviceParameters ; DS:SI --> src. parms
  596. mov CX,SIZE EA_DEVICEPARAMETERS ; byte transfer count
  597. cld
  598. rep movsb
  599. ret
  600. CopyToSwitchDevParams endp
  601. ;=========================================================================
  602. ;
  603. ; CompareDevParams : This procedure compares the structure
  604. ; DeviceParameters with SwitchDevParams.
  605. ; Registers destroyed : CX,DI,SI
  606. ; Assumes : DS:DATA, ES:Nothing
  607. ;
  608. ;=========================================================================
  609. CompareDevParams proc NEAR
  610. push DS
  611. pop ES
  612. mov DI,OFFSET SwitchDevParams ; ES:DI --> dest. parms
  613. mov SI,OFFSET DeviceParameters ; DS:SI --> src. parms
  614. mov CX,SIZE A_DEVICEPARAMETERS ; Set up count in bytes
  615. cmp IsExtRAWIODrv,0
  616. je DoCmp
  617. mov CX,SIZE EA_DEVICEPARAMETERS ; Set up count in bytes
  618. DoCmp:
  619. cld ; Set the direction
  620. repe cmpsb ; Compare the two BPBs
  621. jz EqualParams ; If ZR then BPBs matched
  622. NotEqualParams:
  623. stc ; Signal BPBs don't match
  624. jmp SHORT CompareParamsExit
  625. EqualParams:
  626. clc ; Signal BPB matches
  627. CompareParamsExit:
  628. ret
  629. CompareDevParams endp
  630. ;=========================================================================
  631. ;
  632. ; LoadSwitchDevParams : This procedure copies the structure
  633. ; SwitchDevParams into DeviceParameters.
  634. ; Registers destroyed : CX,DI,SI
  635. ; Assumes : DS:DATA,ES:Nothing
  636. ;
  637. ;=========================================================================
  638. LoadSwitchDevParams proc NEAR
  639. push DS
  640. pop ES
  641. mov DI,OFFSET DeviceParameters ; ES:DI --> dest. parms
  642. mov SI,OFFSET SwitchDevParams ; DS:SI --> src. parms
  643. mov CX,SIZE EA_DEVICEPARAMETERS ; byte transfer count
  644. cld
  645. rep movsb
  646. ret
  647. LoadSwitchDevParams endp
  648. ;=========================================================================
  649. ;
  650. ; DetermineExistingFormat : This procedure will check if there is a
  651. ; valid format existing on the disk, in
  652. ; which case DeviceParameters will be reset
  653. ; to that format.
  654. ;
  655. ; It is assumed the destination disk is
  656. ; already in the drive.
  657. ;
  658. ; DetermineExistingFormatNoMsg : alternate entry with no message
  659. ;
  660. ;
  661. ; Calls : IsValidBpb
  662. ; ResetDeviceParameters
  663. ; DetermineCPMFormat
  664. ;
  665. ; Called by : Phase1Initialisation
  666. ;
  667. ;=========================================================================
  668. DetermineExistingFormat proc near
  669. push DS
  670. push ES
  671. Set_Data_Segment ;ensure addressibility
  672. cmp UnformattedHardDrive,TRUE
  673. jne @F
  674. jmp InvalidBootRecord
  675. @@:
  676. Message msgCheckExistingDiskFormat
  677. jmp short DetermineExistCommon
  678. DetermineExistingFormatNoMsg:
  679. push ds
  680. push es
  681. set_data_segment
  682. cmp UnformattedHardDrive,TRUE
  683. je InvalidBootRecord
  684. DetermineExistCommon:
  685. xor DX,DX ; Starting sector to 0
  686. mov AL,DriveToFormat ; Set drive number
  687. mov AH,DH ; Signal this is a read AH=0
  688. lds BX,FatSpace ; Load transfer address
  689. assume DS:NOTHING,ES:DATA
  690. mov CX,2 ; # of sectors to read
  691. ; we are accessing < 32mb
  692. mov ES:Read_Write_Relative.Start_Sector_High,0
  693. call Read_Disk ; Disk sector read
  694. jnc BootCheck
  695. mov ES:RWErrorCode,AX ; Save error code (if any)
  696. jmp InvalidbootRecord
  697. BootCheck:
  698. cmp word ptr [bx+3], 'SM'
  699. jne @F
  700. cmp word ptr [bx+5], 'MD'
  701. jne @F
  702. cmp word ptr [bx+7], '3F'
  703. jne @F
  704. mov es:RWErrorCode, 0
  705. stc
  706. jmp short EndDetermine
  707. @@:
  708. cmp BYTE PTR [BX],0e9h ; Check for JMP opcode
  709. je TestBootSignature ; If Ok then check signature
  710. ; we can not know #reserved sectors)
  711. cmp BYTE PTR [BX],0ebh ; Else check for SHORT jmp
  712. jne TryCPM ; No match then not valid boot
  713. cmp BYTE PTR [BX+2],90h ; Now check for NOP opcode
  714. jne TryCPM ; No match then not valid boot
  715. TestBootSignature:
  716. ifndef NEC_98
  717. cmp WORD PTR [BX + 510],0aa55h ; Check for 55 AA sequence
  718. jne TryCPM ; Error if not equal
  719. endif
  720. CheckTheBpb:
  721. call IsValidBpb
  722. jc TryCPM ; CY --> Invalid format
  723. call ResetDeviceParameters ; set DeviceParameters to
  724. clc ; existing ones on the disk
  725. jmp SHORT EndDetermine
  726. TryCPM:
  727. ifdef NEC_98
  728. cmp ES:DeviceParameters.DP_DeviceType,DEV_HARDDISK
  729. je InvalidBootRecord
  730. endif
  731. ; check in case a CP/M disk is present
  732. test ES:DeviceParameters.DP_DeviceAttributes,1
  733. .errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
  734. jnz InvalidBootRecord ; Bit 0=1 --> not removable
  735. call DetermineCPMFormat
  736. jmp SHORT EndDetermine ; CP/M disk present, DeviceParameters
  737. ; will have been modified
  738. ; Carry propagated up to
  739. ; Note: DS can be anything
  740. InvalidBootRecord:
  741. stc ;flag invalid format
  742. EndDetermine:
  743. pop ES
  744. pop DS
  745. ret
  746. DetermineExistingFormat endp
  747. ;=========================================================================
  748. ;
  749. ; IsValidBpb : This procedure will inspect the BPB loaded into
  750. ; memory by the DetermineExistinFormat procedure.
  751. ;
  752. ; Input : DS:BX Buffer holding boot sector (FatSpace) ; M016
  753. ; Output : BPB is valid - NC
  754. ; BPB is invalid - CY
  755. ;
  756. ; Assumes: DS:BX: FatSpace (preserved); M016
  757. ;
  758. ;=========================================================================
  759. IsValidBpb proc near
  760. assume DS:NOTHING,ES:DATA
  761. push BX ; M016; preserve BX
  762. lea bx,[bx.bsBPB]
  763. ifdef NEC_98
  764. ;;; It is possible NEC_98's BPB is not 200h.
  765. cmp [BX.oldBPB.BPB_BytesPerSector],200h ; check BytesPerSector=512
  766. je @F
  767. cmp [BX.oldBPB.BPB_BytesPerSector],400h ; check BytesPerSector=1024
  768. je @F
  769. cmp [BX.oldBPB.BPB_BytesPerSector],800h ; check BytesPerSector=2048
  770. jne NotValidBpb
  771. @@:
  772. else
  773. cmp [BX.oldBPB.BPB_BytesPerSector],200h ; check BytesPerSector=512
  774. jne NotValidBpb
  775. endif
  776. and [BX.oldBPB.BPB_TotalSectors],0ffffh ; check that both TotalSectors
  777. jnz ResetBigTotalSectors ; and BigTotalSectors are not zero
  778. and [BX.oldBPB.BPB_BigTotalSectors],0ffffh ; low word
  779. jnz CheckMore
  780. and [BX.oldBPB.BPB_BigTotalSectorsHigh],0ffffh ; high word
  781. jz NotValidBpb
  782. jmp SHORT CheckMore
  783. ResetBigTotalSectors: ; if TotalSectors<>0 set
  784. and [BX.oldBPB.BPB_BigTotalSectors],0h ; BigTotalSectors to zero
  785. and [BX.oldBPB.BPB_BigTotalSectorsHigh],0h
  786. CheckMore:
  787. and [BX.oldBPB.BPB_SectorsPerFAT],0ffffh ; check SectorsPerFat <> 0
  788. jnz CheckMore2
  789. ;
  790. ; Is a FAT32 BPB
  791. ;
  792. and [BX.BGBPB_BigSectorsPerFat],0ffffh
  793. jnz CheckMore2
  794. and [BX.BGBPB_BigSectorsPerFatHi],0ffffh
  795. jz NotValidBpb
  796. CheckMore2:
  797. cmp [BX.oldBPB.BPB_SectorsPerTrack],1h ; check 0 < SectorsPerTrack < 64
  798. jb NotValidBpb
  799. cmp [BX.oldBPB.BPB_SectorsPerTrack],3fh
  800. ja NotValidBpb
  801. cmp [BX.oldBPB.BPB_Heads],1h ; check 0 < Heads < 256
  802. jb NotValidBpb
  803. cmp [BX.oldBPB.BPB_Heads],0ffh
  804. ja NotValidBpb
  805. BpbIsValid:
  806. clc
  807. jmp SHORT EndIsValidBpb
  808. NotValidBpb:
  809. stc
  810. EndIsValidBpb:
  811. pop BX ; M016; restore BX
  812. ret
  813. IsValidBpb endp
  814. ;=========================================================================
  815. ;
  816. ; ResetDeviceParameters : This procedure will copy the BPB of the
  817. ; disk into DeviceParameters. It will also
  818. ; set the fields DP_CYLINDERS and DP_MEDIATYPE,
  819. ; for removable media.
  820. ;
  821. ; Inputs : DS:BX Boot sector held in FatSpace ; M016
  822. ; Output : Modified DeviceParameters
  823. ; Modifies: ES,SI,DI,CX,DX,BX,AX
  824. ; Assumes: DS:BX Boot sector, ES:DATA
  825. ;
  826. ;=========================================================================
  827. ResetDeviceParameters proc near
  828. assume DS:NOTHING,ES:DATA
  829. lea si,[bx.bsBPB] ; Use SI instead of BX for copy
  830. ; DS:SI source BPB in buffer
  831. ;No need to modify DP_CYLINDERS,DP_MEDIATYPE
  832. ;(and DP_DEVICETYPE) for fixed disks.
  833. ifdef NEC_98
  834. cmp ES:DeviceParameters.DP_DeviceType,DEV_HARDDISK
  835. je CopyBpb
  836. endif
  837. ;use DevParms to check for removable
  838. test ES:DeviceParameters.DP_DeviceAttributes,1
  839. .errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
  840. jnz CopyBpb ; Bit 0=1 --> not removable
  841. ;first compute total cylinders as
  842. ;total sectors /(sectors per track)*#heads
  843. .386
  844. movzx EAX,[SI.oldBPB.BPB_TotalSectors] ;get total sectors
  845. .8086
  846. or AX,AX ;do we need to use Big total sectors?
  847. jnz GotTotalSectors ;don't need to if not zero
  848. UseBigTotalSectors:
  849. .386
  850. mov EAX,DWORD PTR [SI.oldBPB.BPB_BigTotalSectors]
  851. GotTotalSectors: ;now EAX has total #sectors
  852. movzx EBX,[SI.oldBPB.BPB_SectorsPerTrack] ;get sectors per track
  853. xor edx,edx
  854. div EBX
  855. .8086
  856. xor DX,DX ;clear the remainder
  857. mov CX,[SI.oldBPB.BPB_Heads] ;get number of heads
  858. div CX
  859. or DX,DX
  860. jz CylindersOk
  861. inc AX
  862. ;BUGBUG: Arithmetic may result in CYLINDERS being 1 less than actual value,
  863. ; for big disks (hence this calculation is skipped for fixed disks)
  864. ; PYS: fixed using same code as MSINIT.ASM
  865. CylindersOk:
  866. mov ES:DeviceParameters.DP_CYLINDERS,AX
  867. .errnz EDP_CYLINDERS NE DP_CYLINDERS
  868. ;now determine DP_MEDIATYPE & DP_DEVICETYPE
  869. mov ES:DeviceParameters.DP_MEDIATYPE,0 ; init. to zero
  870. .errnz EDP_MEDIATYPE NE DP_MEDIATYPE
  871. cmp AX,40 ; only 360K or less has 40 cylinders
  872. jne CopyBpb ; MEDIATYPE has been set
  873. cmp ES:DeviceParameters.DP_DEVICETYPE,DEV_5INCH96TPI
  874. .errnz EDP_DEVICETYPE NE DP_DEVICETYPE
  875. jne CopyBpb
  876. Is360K:
  877. mov ES:DeviceParameters.DP_MEDIATYPE,1 ; set to 1 only for 360K in 1.2M
  878. .errnz EDP_MEDIATYPE NE DP_MEDIATYPE
  879. ;BUGBUG: Changing the value of DEVICETYPE can result in SwitchDevParams !=
  880. ; DeviceParameters, and hence a just-formatted 360K disk may not be
  881. ; recognized! -is it really necessary to set DEVICETYPE?
  882. CopyBpb:
  883. mov DI,OFFSET ES:DeviceParameters.DP_BPB
  884. .errnz EDP_BPB NE DP_BPB
  885. ;ES:DI destination BPB in DeviceParameters
  886. mov CX,SIZE BIGFATBPB ;byte transfer count
  887. cmp [si.BPB_SectorsPerFAT],0 ;FAT32 BPB?
  888. je @f ;Yes
  889. mov CX,SIZE BPB ;byte transfer count
  890. cmp byte ptr [si.bsBootSignature-bsBPB], 29h ; extended BPB ?
  891. je @f ; Yes
  892. mov cx,((SIZE BPB)-6) ; no, ancient small BPB
  893. @@:
  894. cld ;set the direction
  895. rep movsb ;write the new BPB
  896. ret
  897. ResetDeviceParameters endp
  898. ;=========================================================================
  899. ;
  900. ; DetermineCPMFormat : This procedure will check the media
  901. ; descriptor in the FAT of the disk. The
  902. ; disk has a valid CP/M format if this is
  903. ; in the range FCh - FFh.
  904. ;
  905. ; Assumes : DS:BX points to boot sectors. ; M016
  906. ; Modifies : DS ; M016
  907. ; Returns : NC - Valid CP/M format detected
  908. ; DeviceParameters modified
  909. ; CY - Invalid format
  910. ;
  911. ;==========================================================================
  912. DetermineCPMFormat proc NEAR
  913. assume DS:NOTHING,ES:DATA
  914. cmp ES:DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,512
  915. .errnz EDP_BPB NE DP_BPB
  916. stc ; Checking default for drive
  917. ; (cannot check BPB since disk
  918. ; may not have one)
  919. jne ExitDetCPMFormat
  920. add BX,512 ; DS:BX points to first FAT
  921. mov CL,BYTE PTR [BX] ; load media descriptor byte into CL
  922. cmp CL,0fch
  923. jb ExitDetCPMFormat ; below = carry, how practical!
  924. Set_Data_Segment ; For the two following calls
  925. call SetCPMParameters ; modify DeviceParameters accordingly
  926. ExitDetCPMFormat:
  927. ret
  928. DetermineCPMFormat endp
  929. ;=========================================================================
  930. ;
  931. ; SetCPMParameters : This procedure copies the required BPB from the
  932. ; CP/M BPB table into DeviceParameters.BPB. Also,
  933. ; DeviceParameters.MediaType is set to 1, and
  934. ; DeviceParameters.Cylinders is set to 40.
  935. ;
  936. ; In case the disk has a 160K or 320K format, the /8
  937. ; switch is set, so that
  938. ; Returns : NC - DeviceParameters updated
  939. ; CY - Error (out of table boundaries)
  940. ;
  941. ; Modifies : AX,BX,CX,DX,SI,DI,ES
  942. ; DeviceParameters
  943. ;
  944. ; Assumes : CL contains media descriptor byte
  945. ;
  946. ;=========================================================================
  947. SetCPMParameters proc NEAR
  948. xor AX,AX ; find index into CP/M BPB table by
  949. mov AL,0ffh ; subtracting media descriptor from ffh
  950. sub AL,CL
  951. mov BX,SIZE A_BPB ; now find byte offset by multiplying
  952. mul BX ; by entry size
  953. lea SI,CustomCPMBPBs
  954. add SI,AX
  955. cmp SI,OFFSET EndCustomCPMBPBs ; check we are still in table
  956. ja NotInTable
  957. lea DI,DeviceParameters.DP_BPB
  958. .errnz EDP_BPB NE DP_BPB
  959. mov CX,SIZE A_BPB ; set up byte transfer count
  960. push DS ; set ES=DS
  961. pop ES
  962. cld ;set the direction
  963. rep movsb ; load the BPB
  964. mov BYTE PTR DeviceParameters.DP_MediaType,1
  965. .errnz EDP_MEDIATYPE NE DP_MEDIATYPE
  966. mov BYTE PTR DeviceParameters.DP_Cylinders,40
  967. .errnz EDP_CYLINDERS NE DP_CYLINDERS
  968. clc
  969. jmp SHORT ExitSetCPMParm
  970. NotInTable:
  971. stc
  972. ExitSetCPMParm:
  973. ret
  974. SetCPMParameters endp
  975. ;=========================================================================
  976. ; Set_BPB_Info : When we have a Fat count of 0, we must calculate
  977. ; certain parts of the BPB. The following code
  978. ; will do just that.
  979. ;
  980. ; Inputs : DeviceParameters
  981. ;
  982. ; Outputs : BPB information
  983. ;=========================================================================
  984. Procedure Set_BPB_Info ; Calc new BPB
  985. Set_Data_Segment ; Set up addressibility
  986. ifdef NEC_98
  987. cmp DeviceParameters.DP_BPB.BPB_NumberOfFats,00h
  988. je @F ; Yes, 0 FatS specified
  989. cmp DeviceParameters.DP_DeviceType,DEV_HARDDISK
  990. je $$IF101
  991. test DeviceParameters.DP_DeviceAttributes,1
  992. jnz $$IF101 ; Bit 0=1 --> not removable
  993. cmp CMCDDFlag,Yes ; Memory card?
  994. je $$IF101 ; We don't need current BPB
  995. lea DX, DeviceParameters
  996. mov DeviceParameters.DP_SpecialFunctions,INSTALL_FAKE_BPB
  997. call GetDeviceParameters
  998. jmp short $$IF101
  999. @@:
  1000. else
  1001. ; See if we have 0 Fats specified
  1002. cmp DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFats,00h
  1003. .errnz EDP_BPB NE DP_BPB
  1004. jne $$IF101 ; Yes, 0 FatS specified
  1005. endif
  1006. call Scan_Disk_Table ; Access disk table
  1007. mov BL,BYTE PTR DS:[SI+8] ; Get Fat type
  1008. mov CX,WORD PTR DS:[SI+4] ; Get Sectors/cluster
  1009. mov DX,WORD PTR DS:[SI+6] ; Number of entries for the root DIR
  1010. mov DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries,DX
  1011. mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster,CH
  1012. ifdef NEC_98
  1013. ;;
  1014. mov DeviceParameters.DP_BPB.oldBPB.BPB_MediaDescriptor,Fixed_Disk
  1015. ;;and ReservedSector not Fixed 1.(Large Partition)
  1016. ;; reserved sector >= 1024 bytes (NEC)
  1017. cmp word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,0200h
  1018. je $$reserved_2
  1019. cmp word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,0100h
  1020. ;Chicago is not supported 256 secters but for safely.
  1021. je $$reserved_4
  1022. mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0001h
  1023. jmp short @F
  1024. $$reserved_2:
  1025. mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0002h
  1026. jmp short @F
  1027. $$reserved_4:
  1028. mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0004h
  1029. @@:
  1030. else
  1031. mov DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,0200h
  1032. mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0001h
  1033. endif
  1034. mov DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFats,02h
  1035. .errnz EDP_BPB NE DP_BPB
  1036. cmp BL,fBig32 ; 32-bit Fat?
  1037. jne $$IF103 ; No
  1038. mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0020h
  1039. call Calc_Big32_Fat ; Calc Fat info
  1040. jmp SHORT $$EN102
  1041. $$IF103:
  1042. cmp BL,fBig ; 16-bit Fat?
  1043. jne $$IF102 ; no
  1044. call Calc_Big16_Fat ; Calc Fat info
  1045. jmp SHORT $$EN102
  1046. $$IF102:
  1047. call Calc_Small_Fat ; Calc small Fat info
  1048. $$EN102:
  1049. $$IF101:
  1050. ret
  1051. Set_BPB_Info ENDP
  1052. ;=========================================================================
  1053. ; Scan_Disk_Table : Scans the table containing information on
  1054. ; the disk's attributes. When it finds the
  1055. ; applicable data, it returns a pointer in
  1056. ; DS:SI for reference by the calling proc.
  1057. ;
  1058. ; Inputs : DiskTable - Contains data about disk types
  1059. ;
  1060. ; Outputs : DS:SI - Points to applicable disk data
  1061. ;=========================================================================
  1062. Procedure Scan_Disk_Table
  1063. cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ; small disk?
  1064. .errnz EDP_BPB NE DP_BPB
  1065. je $$IF106 ; Yes
  1066. mov DX,00h ; Set high to 0
  1067. mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1068. jmp SHORT $$EN106
  1069. $$IF106:
  1070. mov DX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+2]
  1071. mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+0]
  1072. $$EN106:
  1073. ifdef NEC_98
  1074. call SetDiskTableNEC_98
  1075. mov DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,BX
  1076. cmp dx,0
  1077. je @F
  1078. mov word ptr DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,0
  1079. mov DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors,AX
  1080. mov DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectorsHigh,DX
  1081. jmp short set_ok
  1082. @@:
  1083. mov DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,AX
  1084. mov word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors,0
  1085. mov word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectorsHigh,0
  1086. set_ok:
  1087. else
  1088. mov SI,offset DiskTable ; Point to disk data
  1089. endif
  1090. Scan:
  1091. cmp DX,WORD PTR DS:[SI] ; Below?
  1092. jb Scan_Disk_Table_Exit ; Yes, exit
  1093. ja Scan_Next ; No, continue
  1094. cmp AX,WORD PTR DS:[SI+2] ; Below or equal?
  1095. ifdef NEC_98
  1096. jb Scan_Disk_Table_Exit ; Yes, exit
  1097. else
  1098. jbe Scan_Disk_Table_Exit ; Yes, exit
  1099. endif
  1100. Scan_Next:
  1101. add SI,5*2 ; Adjust pointer
  1102. jmp Scan ; Continue scan
  1103. Scan_Disk_Table_Exit:
  1104. ret
  1105. Scan_Disk_Table ENDP
  1106. ;=========================================================================
  1107. ; Calc_Big32_Fat : Calculates the Sectors per Fat for a 32 bit Fat.
  1108. ;
  1109. ; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors or
  1110. ; DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1111. ;
  1112. ; Outputs : DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
  1113. ; DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
  1114. ; DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFatHi
  1115. ; DeviceParameters.DP_BPB.BGBPB_ExtFlags
  1116. ; DeviceParameters.DP_BPB.BGBPB_FS_Version
  1117. ; DeviceParameters.DP_BPB.BGBPB_RootDirStrtClus
  1118. ; DeviceParameters.DP_BPB.BGBPB_RootDirStrtClusHi
  1119. ;
  1120. ;=========================================================================
  1121. Procedure Calc_Big32_Fat
  1122. .386
  1123. ; Root dir is a cluster chain on FAT32 volumes
  1124. movzx edx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors ; EDX = Reserved
  1125. .errnz EDP_BPB NE DP_BPB
  1126. ; Get total sector count
  1127. cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ; Small disk?
  1128. je short $$IF109a ; Yes
  1129. movzx EAX,DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1130. jmp SHORT $$EN109a
  1131. $$IF109a:
  1132. mov EAX,DWORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors
  1133. $$EN109a:
  1134. sub EAX,EDX ; EAX = T - R
  1135. xor ebx,ebx
  1136. mov BL,DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFATs
  1137. mov BH,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
  1138. shr ebx,1 ; At 4 bytes per clus instead of 2,
  1139. ; halve divisor
  1140. GotDiv1:
  1141. add EAX,EBX ; EAX = T-R-D+(256*SPC)+nFAT
  1142. dec EAX ; EAX = T-R-D+(256*SPC)+nFAT-1
  1143. xor edx,edx
  1144. div EBX ; Sec/Fat = CEIL((TOTAL-DIR-RES)/
  1145. ; (((256*SECPERCLUS)+NUMFATS)/2)
  1146. mov DWORD PTR DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat,EAX
  1147. xor ax,ax
  1148. mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,ax
  1149. mov DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries,ax
  1150. mov DeviceParameters.DP_BPB.BGBPB_ExtFlags,ax
  1151. ;
  1152. ; For the moment we set the root dir start clus to 0. Later on, after
  1153. ; we determine which clusters are BAD, we will set this to something
  1154. ; proper.
  1155. ;
  1156. mov DeviceParameters.DP_BPB.BGBPB_RootDirStrtClus,ax
  1157. mov DeviceParameters.DP_BPB.BGBPB_RootDirStrtClusHi,ax
  1158. mov DeviceParameters.DP_BPB.BGBPB_FS_Version,FAT32_Curr_FS_Version
  1159. .8086
  1160. ret
  1161. Calc_Big32_Fat ENDP
  1162. ;=========================================================================
  1163. ; Calc_Big16_Fat : Calculates the Sectors per Fat for a 16 bit Fat.
  1164. ;
  1165. ; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors or
  1166. ; DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1167. ;
  1168. ; Outputs : DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
  1169. ;
  1170. ;=========================================================================
  1171. Procedure Calc_Big16_Fat
  1172. ; Get root size in sectors and add reserved to it
  1173. mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
  1174. .errnz EDP_BPB NE DP_BPB
  1175. mov bx,size dir_entry
  1176. mul bx ; DX:AX = bytes in root dir
  1177. mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector
  1178. dec bx ; Round up to sector multiple
  1179. add ax,bx
  1180. adc dx,0
  1181. inc bx ; get back sector size
  1182. div bx ; AX is sectors in root dir
  1183. mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
  1184. add ax,bx ; AX = R + D
  1185. mov bx,ax ; over to BX
  1186. ; Get Total sectors
  1187. cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ; Small disk?
  1188. je $$IF109 ; Yes
  1189. xor DX,DX ; Set high to 0
  1190. mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1191. jmp SHORT $$EN109
  1192. $$IF109:
  1193. mov DX,DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+2]
  1194. mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+0]
  1195. $$EN109:
  1196. sub AX,BX ; DX:AX = T - R - D
  1197. sbb DX,0
  1198. mov BL,DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFATs
  1199. mov BH,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
  1200. add AX,BX ; AX = T-R-D+(256*SPC)+nFAT
  1201. adc DX,0
  1202. sub AX,1 ; AX = T-R-D+(256*SPC)+nFAT-1
  1203. sbb DX,0
  1204. div BX ; Sec/Fat = CEIL((TOTAL-DIR-RES)/
  1205. ; ((256*SECPERCLUS)+NUMFATS)
  1206. mov WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,AX
  1207. ret
  1208. Calc_Big16_Fat ENDP
  1209. ;=========================================================================
  1210. ; Calc_Small_Fat: Calculates the Sectors per Fat for a 12 bit Fat.
  1211. ;
  1212. ; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors or
  1213. ; DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1214. ;
  1215. ; Outputs : DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
  1216. ;
  1217. ;=========================================================================
  1218. Procedure Calc_Small_Fat
  1219. ; Get root size in sectors and add reserved to it
  1220. mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
  1221. .errnz EDP_BPB NE DP_BPB
  1222. mov bx,size dir_entry
  1223. mul bx ; DX:AX = bytes in root dir
  1224. mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector
  1225. dec bx ; Round up to sector multiple
  1226. add ax,bx
  1227. adc dx,0
  1228. inc bx ; get back sector size
  1229. div bx ; AX is sectors in root dir
  1230. mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
  1231. add ax,bx ; AX = R + D
  1232. mov bx,ax ; over to BX
  1233. ; Get total sectors
  1234. cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ;small disk?
  1235. je $$IF112 ; Yes
  1236. xor DX,DX ; Set high to 0
  1237. mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1238. jmp SHORT $$EN112
  1239. $$IF112:
  1240. mov DX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+2]
  1241. mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+0]
  1242. $$EN112:
  1243. sub AX,BX ; DX:AX = T - R - D
  1244. sbb DX,0
  1245. xor BX,BX
  1246. mov BL,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
  1247. div BX
  1248. ; Now multiply by 3/2
  1249. mov BX,3
  1250. mul BX ; Div by log 2 of Sectors/clus
  1251. mov BX,2
  1252. div BX
  1253. xor DX,DX
  1254. ; Now divide by 512
  1255. mov BX,512
  1256. div BX
  1257. ifdef NEC_98
  1258. or dx,dx ; for remainder
  1259. jz @F
  1260. inc AX
  1261. @@:
  1262. test ax,01h ; for even
  1263. jz @F
  1264. inc ax
  1265. @@:
  1266. cmp DeviceParameters.DP_BPB.BPB_BytesPerSector,2048
  1267. jne @F
  1268. test ax,02h ; for 2048 bytes/sector
  1269. jz @F
  1270. add ax,2
  1271. @@:
  1272. else
  1273. inc AX
  1274. ; DX:AX contains number of Fat
  1275. ; sectors necessary
  1276. endif
  1277. mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,AX
  1278. ret
  1279. Calc_Small_Fat ENDP
  1280. ; ==========================================================================
  1281. ; StartSector = number of reserved Sectors
  1282. ; + number of Fat Sectors ( Number of FatS * Sectors Per Fat )
  1283. ; + number of directory Sectors ( 32* Root Entries / bytes Per Sector )
  1284. ; ( above is rounded up )
  1285. ;
  1286. ; Calculate the number of directory Sectors
  1287. ; ==========================================================================
  1288. SetStartSector proc near
  1289. xor ax,ax
  1290. cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFAT,ax
  1291. je NoRootDir
  1292. mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
  1293. .errnz EDP_BPB NE DP_BPB
  1294. mov BX, size dir_entry
  1295. mul BX ; DX:AX is bytes in root dir
  1296. mov bx, DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector
  1297. dec bx ; Round up to sector multiple
  1298. add ax,bx
  1299. adc dx,0
  1300. inc bx ; Get sector size back
  1301. div bx ; AX = Sectors in root dir
  1302. NoRootDir:
  1303. mov SectorsInRootDirectory,AX
  1304. .386
  1305. movzx eax,ax
  1306. mov StartSector, EAX ;not done yet!
  1307. ; Calculate the number of Fat Sectors
  1308. movzx EAX, DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
  1309. or ax,ax
  1310. jnz short NotFat32a
  1311. mov EAX, DWORD PTR DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
  1312. NotFat32a:
  1313. movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_numberOfFats
  1314. mul ebx
  1315. ; add in the number of boot Sectors
  1316. movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
  1317. add EAX,EBX
  1318. add StartSector, EAX
  1319. .8086
  1320. return
  1321. SetStartSector endp
  1322. ; ==========================================================================
  1323. ;
  1324. ; fBigFat = ( ( (TotalSectors - StartSector) / SectorsPerCluster) >= 4086 )
  1325. ;
  1326. ; ==========================================================================
  1327. SetfBigFat proc near
  1328. cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFAT,0
  1329. .errnz EDP_BPB NE DP_BPB
  1330. jne NotFat32b
  1331. mov fBig32Fat, TRUE ; Set flag
  1332. mov ThisSysInd,8
  1333. jmp SHORT $$EN21
  1334. NotFat32b:
  1335. cmp DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors+2,0
  1336. je $$IF21 ; no, 12-bit Fat
  1337. mov fBigFat, TRUE ; Set flag
  1338. mov ThisSysInd,6
  1339. jmp SHORT $$EN21 ; Nope, < 32,b
  1340. $$IF21: ; Assume this used
  1341. mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors
  1342. cmp AX,0 ; Was this field used?
  1343. jne $$IF23 ; Yes
  1344. ; No, use other sector field
  1345. mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1346. $$IF23: ; ** Fix for PTM PCDOS P51
  1347. mov ThisSysInd,1 ; Set small Fat for default
  1348. sub AX,word ptr StartSector ; Get Sectors in data area
  1349. xor DX,DX
  1350. xor BX,BX
  1351. mov bl,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
  1352. div BX ; Get total clusters
  1353. cmp AX,BIG_Fat_THRESHOLD ; Is clusters >= 4086?
  1354. jnae $$IF25
  1355. mov fBigFat,TRUE ; 16 bit Fat if >=4096
  1356. ; ** END fix for PTM PCDOS P51
  1357. mov ThisSysInd,4 ; set large Fat
  1358. $$IF25:
  1359. $$EN21:
  1360. return
  1361. SetfBigFat endp
  1362. ;==========================================================================
  1363. ;
  1364. ; GetTotalClusters : This procedure initializes the variable TotalClusters.
  1365. ; This is utilized by Quick Format to check for when all
  1366. ; the clusters have been processed.
  1367. ; Destroys : AX,BX,CX,DX
  1368. ; Strategy : TotalClusters = (TotalSectors-Fats-Root-Reserved)/SectorsPerCluster
  1369. ;
  1370. ;==========================================================================
  1371. GetTotalClusters proc NEAR
  1372. .386
  1373. movzx EAX,DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
  1374. .errnz EDP_BPB NE DP_BPB
  1375. or AX,AX ; Check if BigTotalSectors must be used
  1376. jnz short GoSubstract ; M015; Substrack Fats, Root and reserved
  1377. GetBigSectors:
  1378. mov EAX,dword ptr DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors
  1379. GoSubstract:
  1380. movzx edx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
  1381. sub EAX,EDX
  1382. movzx edx,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
  1383. or dx,dx
  1384. jnz short NotFat32c
  1385. mov DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries,dx ; No root dir on FAT32
  1386. mov edx,dword ptr DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
  1387. NotFat32c:
  1388. movzx cx,DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFats
  1389. jcxz GoDivide ; M017; if non fat, don't even do the root
  1390. SubstractAFat:
  1391. sub EAX,EDX
  1392. loop SubstractAFat
  1393. GoSubstractRoot:
  1394. ; Assumes that BytesPerSectors is a power of 2 and at least 32
  1395. ; Those are valid assumptions since BIOS requires the same.
  1396. mov BX,DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
  1397. shr BX,5 ; divide by 32, BX = root entries per sector (a power of 2)
  1398. or BX,BX ; Sanity check for infinite looping
  1399. jz short SayWhat
  1400. mov CX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
  1401. SubstractRootLoop:
  1402. test BX,1
  1403. jnz short SubstractRootReady
  1404. shr BX,1
  1405. shr CX,1
  1406. jmp short SubstractRootLoop
  1407. SubstractRootReady:
  1408. movzx ecx,cx
  1409. sub EAX,ECX
  1410. GoDivide:
  1411. movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
  1412. xor edx,edx
  1413. div EBX
  1414. inc EAX ; Bump by 1 since start with 2
  1415. cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,0
  1416. je short NoOvlChk
  1417. cmp EAX,0000FFEFh ; Sanity check
  1418. ja short SayWhat
  1419. NoOvlChk:
  1420. mov TotalClusters,EAX
  1421. .8086
  1422. ret
  1423. SayWhat:
  1424. Message msgInvalidDeviceParameters
  1425. jmp FatalExit
  1426. GetTotalClusters endp
  1427. ; SetDOS_Dpb - Need to set the DPB for a memory card because the
  1428. ; default will be for the last disk accessed in the
  1429. ; the drive and may not be correct for the current
  1430. ; disk.
  1431. SetDOS_Dpb PROC
  1432. cmp CMCDDFlag, Yes
  1433. je @f
  1434. clc
  1435. ret
  1436. @@:
  1437. push ds
  1438. pop es
  1439. mov di, offset SetDPBPacket
  1440. mov ax, OFFSET DeviceParameters.DP_BPB ; DS:AX --> BPB for disk
  1441. .errnz EDP_BPB NE DP_BPB
  1442. mov word ptr [di.SetDPB_Value1],ax
  1443. mov word ptr [di.SetDPB_Value1+2],ds
  1444. xor ax,ax
  1445. mov word ptr [di.SetDPB_Value2],ax
  1446. mov word ptr [di.SetDPB_Value2+2],ax
  1447. mov word ptr [di.SetDPB_Value3],ax
  1448. mov word ptr [di.SetDPB_Value3+2],ax
  1449. mov word ptr [di.SetDPB_Value4],ax
  1450. mov word ptr [di.SetDPB_Value4+2],ax
  1451. .386
  1452. mov [di.SetDPB_Function],SetDPB_SetDPBFrmBPB
  1453. movzx dx,DriveToFormat
  1454. .8086
  1455. inc dx ; 1 based drive number
  1456. mov ax,(Get_Set_DriveInfo SHL 8) OR Set_DPBForFormat
  1457. mov cx,size SDPDFormatStruc
  1458. int 21h
  1459. ;
  1460. ; NOTE: This call fails in protected mode under Win95. VFAT/VDEF do not
  1461. ; implement it. This call REALLY isn't necessary anyway. The
  1462. ; SetDeviceParameters we do as part of the format is supposed to
  1463. ; trigger the device driver to return "media changed" on the next
  1464. ; media check call.
  1465. ;
  1466. clc
  1467. ret
  1468. SetDOS_Dpb ENDP
  1469. ;==========================================================================
  1470. ifdef NEC_98
  1471. ; IN : DX:AX total_sectors
  1472. ; : DeviceParameters
  1473. ; OUT : SI = offset DiskTable
  1474. ; : BX = BytesPerSector
  1475. ; : DX:AX = total sectors
  1476. ;
  1477. ; USE : AX,BX,DX,SI
  1478. ;
  1479. SetDiskTableNEC_98 proc near
  1480. mov bx,DeviceParameters.DP_BPB.BPB_BytesPerSector
  1481. cmp bx,200h
  1482. je large?_512
  1483. cmp bx,100h
  1484. je large?_256
  1485. cmp bx,400h
  1486. jne not_large
  1487. large?_1024:
  1488. cmp dx,2
  1489. jb not_large
  1490. je @F
  1491. jmp set_large1024 ; 1024 and DX > 2 --> large partition.
  1492. ; > 129MB
  1493. @@:
  1494. cmp ax,200h
  1495. jb not_large
  1496. jmp set_large1024 ; 1024 and DX = 2 and AX >= 512 --> large partition.
  1497. ; > 128.5MB
  1498. large?_512:
  1499. cmp dx,4
  1500. jb not_large
  1501. je @F
  1502. jmp set_large512 ; 512 and DX > 4 --> large partition.
  1503. ; > 129MB
  1504. @@:
  1505. cmp ax,400h
  1506. jb not_large
  1507. jmp set_large512 ; 512 and DX = 4 and AX >= 1024 --> large partition.
  1508. ; > 128.5MB
  1509. large?_256:
  1510. cmp dx,8
  1511. jb not_large
  1512. je @F
  1513. jmp set_large256 ; 256 and DX > 8 --> large partition.
  1514. ; > 129MB
  1515. @@:
  1516. cmp ax,800h
  1517. jb not_large
  1518. jmp set_large256 ; 256 and DX = 8 and AX >= 2048 --> large partition.
  1519. ; > 128.5MB
  1520. not_large:
  1521. cmp bx,800h
  1522. jne @F
  1523. jmp set_2K
  1524. @@:
  1525. cmp bx,200h
  1526. je sec2K?_512
  1527. cmp bx,100h
  1528. je sec2K?_256
  1529. sec2K?_1024:
  1530. cmp dx,1
  1531. jb not_2K
  1532. je @F
  1533. shr dx,1 ;convert 1K->2K
  1534. rcr ax,1
  1535. jmp set_2K ; 1024 and DX > 1 --> 2KB partition.
  1536. ; > 65MB
  1537. @@:
  1538. cmp ax,200h
  1539. jb not_2K
  1540. shr dx,1 ;convert 1K->2K
  1541. rcr ax,1
  1542. jmp set_2K ; 1024 and DX = 1 and AX >= 1024 --> 2KB partition.
  1543. ; > 64.5MB
  1544. sec2K?_512:
  1545. cmp dx,2
  1546. jb not_2K
  1547. je @F
  1548. shr dx,1 ;convert 512->2K
  1549. rcr ax,1
  1550. shr dx,1
  1551. rcr ax,1
  1552. jmp set_2K ; 512 and DX > 2 --> 2KB partition.
  1553. ; > 65MB
  1554. @@:
  1555. cmp ax,400h
  1556. jb not_2K
  1557. shr dx,1 ;convert 512->2K
  1558. rcr ax,1
  1559. shr dx,1
  1560. rcr ax,1
  1561. jmp set_2K ; 512 and DX = 2 and AX >= 1024 --> 2KB partition.
  1562. ; > 64.5MB
  1563. sec2K?_256:
  1564. cmp dx,4
  1565. jb not_2K
  1566. je @F
  1567. shr dx,1 ;convert 256->2K
  1568. rcr ax,1
  1569. shr dx,1
  1570. rcr ax,1
  1571. shr dx,1
  1572. rcr ax,1
  1573. shr dx,1
  1574. rcr ax,1
  1575. jmp set_2K ; 256 and DX > 4 --> 2KB partition.
  1576. ; > 65MB
  1577. @@:
  1578. cmp ax,800h
  1579. jb not_2K
  1580. shr dx,1 ;convert 256->2K
  1581. rcr ax,1
  1582. shr dx,1
  1583. rcr ax,1
  1584. shr dx,1
  1585. rcr ax,1
  1586. shr dx,1
  1587. rcr ax,1
  1588. jmp set_2K ; 256 and DX = 4 and AX >= 1024 --> 2KB partition.
  1589. ; > 64.5MB
  1590. not_2K:
  1591. push cx
  1592. push dx
  1593. push ax
  1594. xor dx,dx
  1595. mov ax,1024
  1596. div bx
  1597. mov cx,ax
  1598. pop ax ;DX:AX total sectors
  1599. pop dx
  1600. @@:
  1601. shr cx,1
  1602. jc @F
  1603. shr dx,1
  1604. rcr ax,1
  1605. jmp short @B
  1606. pop cx ;DX:AX convert ->1KB
  1607. mov bx,1024
  1608. cmp dx,0
  1609. je @F
  1610. mov ax,0FFFFh
  1611. mov dx,0
  1612. @@:
  1613. ;;; follow function is NEC_98 only.
  1614. push ax
  1615. push ds
  1616. push dx
  1617. push cx
  1618. push cs
  1619. pop ds
  1620. mov dx,offset LPTABLE
  1621. mov cl,13h
  1622. int 220 ;GET LPTABLE
  1623. add dx,001Ah ;EXLPTABLE start offset
  1624. mov al,DriveToFormat
  1625. shl al,1 ;Drive * 2
  1626. xor ah,ah
  1627. add dx,ax
  1628. inc dx ;+1 (=DA/UA)
  1629. mov bx,dx
  1630. mov al,[bx] ;GET DA/UA at al
  1631. pop cx
  1632. pop dx
  1633. pop ds
  1634. mov ah,al ;al copy to ah
  1635. and al,0F0h
  1636. cmp al,80h
  1637. je @F
  1638. jmp set_SCSItable ;STACK AX ;Not 8xh
  1639. @@:
  1640. push es
  1641. push ax
  1642. mov ax,40h
  1643. mov es,ax ;es = 0040h
  1644. pop ax
  1645. mov al,es:[0057h]
  1646. pop es
  1647. cmp ah,80h
  1648. je IDE1_check ;STACK AX
  1649. and al,00000111b
  1650. cmp al,00000110b
  1651. je set_SASItable ;STACK AX 2nd IDE is 40MB
  1652. cmp al,00000100b
  1653. je set_SASItable ;STACK AX 2nd IDE is 20MB
  1654. jmp short set_SCSItable ;STACK AX
  1655. IDE1_check:
  1656. and al,00111000b
  1657. cmp al,00110000b
  1658. je set_SASItable ;STACK AX 1st IDE is 40MB
  1659. cmp al,00100000b
  1660. je set_SASItable ;STACK AX 1st IDE is 20MB
  1661. jmp short set_SCSItable ;STACK AX
  1662. LPTABLE DB 96 DUP (?)
  1663. set_SASItable:
  1664. pop ax
  1665. mov si, offset SASI1024Table
  1666. jmp short exit_disktable
  1667. set_large1024:
  1668. set_SCSItable:
  1669. pop ax
  1670. mov si, offset SCSI1024Table
  1671. jmp short exit_disktable
  1672. set_large256:
  1673. mov si, offset Large256Table
  1674. jmp short exit_disktable
  1675. set_large512:
  1676. mov si, offset Large512Table
  1677. jmp short exit_disktable
  1678. set_2K:
  1679. mov bx,2048
  1680. cmp dx,0
  1681. je @F
  1682. mov ax,0FFFFh
  1683. mov dx,0
  1684. @@:
  1685. mov si, offset Small2048Table
  1686. exit_disktable:
  1687. ret
  1688. SetDiskTableNEC_98 endp
  1689. MY_INT24 proc far
  1690. mov al, 0 ; don't display messages
  1691. iret
  1692. MY_INT24 endp
  1693. endif
  1694. CODE ENDS
  1695. END
  1696.