diff options
Diffstat (limited to 'v4.0/src/CMD/FORMAT/FORMAT.ASM')
| -rw-r--r-- | v4.0/src/CMD/FORMAT/FORMAT.ASM | 4509 |
1 files changed, 4509 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FORMAT/FORMAT.ASM b/v4.0/src/CMD/FORMAT/FORMAT.ASM new file mode 100644 index 0000000..c9034d7 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORMAT.ASM | |||
| @@ -0,0 +1,4509 @@ | |||
| 1 | page 84,132 | ||
| 2 | ; | ||
| 3 | ; SCCSID = @(#)format.asm 1.26 85/10/20 | ||
| 4 | ; SCCSID = @(#)format.asm 1.26 85/10/20 | ||
| 5 | ;*************************************************************** | ||
| 6 | ; | ||
| 7 | ; 86-DOS FORMAT DISK UTILITY | ||
| 8 | ; | ||
| 9 | ; This routine formats a new disk,clears the FAT and DIRECTORY then | ||
| 10 | ; optionally copies the SYSTEM and COMMAND.COM to this new disk | ||
| 11 | ; | ||
| 12 | ; SYNTAX: FORMAT [drive][/switch1][/switch2]...[/switch16] | ||
| 13 | ; | ||
| 14 | ; Regardless of the drive designator , the user will be prompted to | ||
| 15 | ; insert the diskette to be formatted. | ||
| 16 | ; | ||
| 17 | ;*************************************************************** | ||
| 18 | |||
| 19 | ; 5/12/82 ARR Mod to ask for volume ID | ||
| 20 | ; 5/19/82 ARR Fixed rounding bug in CLUSCAL: | ||
| 21 | ; REV 1.5 | ||
| 22 | ; Added rev number message | ||
| 23 | ; Added dir attribute to DELALL FCB | ||
| 24 | ; REV 2.00 | ||
| 25 | ; Redone for 2.0 | ||
| 26 | ; REV 2.10 | ||
| 27 | ; 5/1/83 ARR Re-do to transfer system on small memory systems | ||
| 28 | ; REV 2.20 | ||
| 29 | ; 6/17/83 system size re-initialization bug -- mjb001 | ||
| 30 | ; Rev 2.25 | ||
| 31 | ; 8/31/83 16-bit fat insertion | ||
| 32 | ; Rev 2.26 | ||
| 33 | ; 11/2/83 MZ fix signed compare problems for bad sectors | ||
| 34 | ; Rev 2.27 | ||
| 35 | ; 11/8/83 EE current directories are always saved and restored | ||
| 36 | ; Rev 2.28 | ||
| 37 | ; 11/9/83 NP Printf and changed to an .EXE file | ||
| 38 | ; Rev 2.29 | ||
| 39 | ; 11/11/83 ARR Fixed ASSIGN detection to use NameTrans call to see | ||
| 40 | ; if drive letter remapped. No longer IBM only | ||
| 41 | ; Rev 2.30 | ||
| 42 | ; 11/13/83 ARR SS does NOT = CS, so all use of BP needs CS override | ||
| 43 | ; Rev 2.31 | ||
| 44 | ; 12/27/83 ARR REP STOSB instruction at Clean: changed to be | ||
| 45 | ; sure ES = CS. | ||
| 46 | |||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | code segment public para 'CODE' | ||
| 51 | code ends | ||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | data segment public para 'DATA' | ||
| 56 | data ends | ||
| 57 | |||
| 58 | End_Of_Memory segment public para 'BUFFERS' | ||
| 59 | End_Of_Memory ends | ||
| 60 | |||
| 61 | |||
| 62 | code segment public para 'CODE' | ||
| 63 | |||
| 64 | assume cs:code,ds:nothing,es:nothing | ||
| 65 | |||
| 66 | ;------------------------------------------------------------------------------- | ||
| 67 | ; Define as public for debugging | ||
| 68 | |||
| 69 | ; procedures | ||
| 70 | public GetSize | ||
| 71 | public AddToSystemSize | ||
| 72 | public Phase1Initialisation | ||
| 73 | public SetStartSector | ||
| 74 | public SetfBigFat | ||
| 75 | public Phase2Initialisation | ||
| 76 | public DiskFormat | ||
| 77 | public BadSector | ||
| 78 | public DisplayCurrentTrack | ||
| 79 | public WriteFileSystem | ||
| 80 | public Done | ||
| 81 | public CurrentLogicalSector | ||
| 82 | public PrintErrorAbort | ||
| 83 | public GetDeviceParameters | ||
| 84 | public SetDeviceParameters | ||
| 85 | public Multiply_32_Bits | ||
| 86 | |||
| 87 | public START | ||
| 88 | public FatAllocated | ||
| 89 | public MEMERRJ | ||
| 90 | public MEM_OK | ||
| 91 | public RDFRST | ||
| 92 | public NEEDSYS | ||
| 93 | public INITCALL | ||
| 94 | public SWITCHCHK | ||
| 95 | public SYSLOOP | ||
| 96 | public FRMTPROB | ||
| 97 | public GETTRK | ||
| 98 | public TRKFND | ||
| 99 | public CLRTEST | ||
| 100 | public CMPTRKS | ||
| 101 | public BadClus | ||
| 102 | ; public DoBig | ||
| 103 | ; public DoSet | ||
| 104 | public DRTFAT | ||
| 105 | public CLEARED | ||
| 106 | public LOUSE | ||
| 107 | public LOUSEP | ||
| 108 | public FATWRT | ||
| 109 | public SYSOK | ||
| 110 | public STATUS | ||
| 111 | public REPORTC | ||
| 112 | public ONCLUS | ||
| 113 | public MORE | ||
| 114 | public FEXIT | ||
| 115 | public SYSPRM | ||
| 116 | public fexitJ | ||
| 117 | public DoPrompt | ||
| 118 | public TARGPRM | ||
| 119 | public IsRemovable | ||
| 120 | public CheckRemove | ||
| 121 | public IsRemove | ||
| 122 | public NotRemove | ||
| 123 | public DSKPRM | ||
| 124 | public GOPRNIT | ||
| 125 | public crlf | ||
| 126 | public PrintString | ||
| 127 | public std_printf | ||
| 128 | public READDOS | ||
| 129 | public RDFILS | ||
| 130 | public FILESDONE | ||
| 131 | public CLSALL | ||
| 132 | public GOTBIOS | ||
| 133 | public GOTDOS | ||
| 134 | public CLSALLJ | ||
| 135 | public GOTCOM | ||
| 136 | public WRITEDOS | ||
| 137 | public GOTALLBIO | ||
| 138 | public BIOSDONE | ||
| 139 | public GOTNDOS | ||
| 140 | public PARTDOS | ||
| 141 | public GOTALLDOS | ||
| 142 | public DOSDONE | ||
| 143 | public PARTCOM | ||
| 144 | public GOTALLCOM | ||
| 145 | public COMDONE | ||
| 146 | public MAKEFIL | ||
| 147 | public CheckMany | ||
| 148 | public CLOSETARG | ||
| 149 | public IOLOOP | ||
| 150 | public GOTTARG | ||
| 151 | public GSYS | ||
| 152 | public TESTSYS | ||
| 153 | public GETOFFS | ||
| 154 | ; public TESTSYSDISK ; dcl 8/23/86 | ||
| 155 | public SETBIOS | ||
| 156 | public BIOSCLS | ||
| 157 | public SETBIOSSIZ | ||
| 158 | public DOSOPNOK | ||
| 159 | public DOSCLS | ||
| 160 | public SETDOSSIZ | ||
| 161 | public GotComHand | ||
| 162 | public COMCLS | ||
| 163 | public SETCOMSIZ | ||
| 164 | public GETFSIZ | ||
| 165 | public READFILE | ||
| 166 | public WRITEFILE | ||
| 167 | public FILIO | ||
| 168 | public NORMIO | ||
| 169 | public IORETP | ||
| 170 | public IORET | ||
| 171 | public NORMALIZE | ||
| 172 | public GotDeviceParameters | ||
| 173 | public LoadSectorTable | ||
| 174 | public NotBigTotalSectors | ||
| 175 | public NotBig | ||
| 176 | public FormatLoop | ||
| 177 | public FormatDone | ||
| 178 | public ContinueFormat | ||
| 179 | public ReportBadTrack | ||
| 180 | public NoMoreTracks | ||
| 181 | public WriteDIRloop | ||
| 182 | public Main_Routine | ||
| 183 | public ControlC_Handler | ||
| 184 | |||
| 185 | ; bytes | ||
| 186 | public fBigFat | ||
| 187 | public formatError | ||
| 188 | public ROOTSTR | ||
| 189 | public DBLFLG | ||
| 190 | public DRIVE | ||
| 191 | public FILSTAT | ||
| 192 | public USERDIRS | ||
| 193 | public VOLFCB | ||
| 194 | public VOLNAM | ||
| 195 | public TRANSRC | ||
| 196 | public TRANDST | ||
| 197 | public INBUFF | ||
| 198 | public driveLetter | ||
| 199 | public systemDriveLetter | ||
| 200 | public CommandFile | ||
| 201 | public ExitStatus | ||
| 202 | public VolDrive | ||
| 203 | public DelFCB | ||
| 204 | public DelDrive | ||
| 205 | |||
| 206 | ; words | ||
| 207 | public startSector | ||
| 208 | public fatSpace | ||
| 209 | public firstHead | ||
| 210 | public firstCylinder | ||
| 211 | public tracksLeft | ||
| 212 | public tracksPerDisk | ||
| 213 | public sectorsInRootDirectory | ||
| 214 | public directorySector | ||
| 215 | public printStringPointer | ||
| 216 | public MSTART | ||
| 217 | public MSIZE | ||
| 218 | public TempHandle | ||
| 219 | public BEGSEG | ||
| 220 | public SWITCHMAP | ||
| 221 | public SWITCHCOPY | ||
| 222 | public FAT | ||
| 223 | public CLUSSIZ | ||
| 224 | public SECSIZ | ||
| 225 | public SYSTRKS | ||
| 226 | public SECTORS | ||
| 227 | public currentHead | ||
| 228 | public currentCylinder | ||
| 229 | public PercentComplete | ||
| 230 | public Formatted_Tracks_High | ||
| 231 | public Formatted_Tracks_Low | ||
| 232 | |||
| 233 | ; other | ||
| 234 | public deviceParameters | ||
| 235 | public Disk_Access | ||
| 236 | public formatPacket | ||
| 237 | ;------------------------------------------------------------------------------- | ||
| 238 | |||
| 239 | data segment public para 'DATA' | ||
| 240 | extrn msgAssignedDrive:byte | ||
| 241 | extrn msgBadDosVersion:byte | ||
| 242 | extrn msgDirectoryWriteError:byte | ||
| 243 | extrn msgFormatComplete:byte | ||
| 244 | extrn msgFormatNotSupported:byte | ||
| 245 | extrn msgFATwriteError:byte | ||
| 246 | extrn msgInvalidDeviceParameters:byte | ||
| 247 | extrn msgLabelPrompt:byte | ||
| 248 | extrn msgNeedDrive:byte | ||
| 249 | extrn msgNoSystemFiles:byte | ||
| 250 | extrn msgNetDrive:byte | ||
| 251 | extrn msgInsertDisk:byte | ||
| 252 | extrn msgHardDiskWarning:byte | ||
| 253 | extrn msgSystemTransfered:byte | ||
| 254 | extrn msgFormatAnother?:byte | ||
| 255 | extrn msgBadCharacters:byte | ||
| 256 | extrn msgBadDrive:byte | ||
| 257 | extrn msgInvalidParameter:byte | ||
| 258 | extrn msgParametersNotSupported:byte | ||
| 259 | extrn msgReInsertDisk:byte | ||
| 260 | extrn msgInsertDosDisk:byte | ||
| 261 | extrn msgFormatFailure:byte | ||
| 262 | extrn ContinueMsg:Byte | ||
| 263 | extrn msgNotSystemDisk:byte | ||
| 264 | extrn msgDiskUnusable:byte | ||
| 265 | extrn msgOutOfMemory:byte | ||
| 266 | extrn msgCurrentTrack:byte | ||
| 267 | extrn msgWriteProtected:byte | ||
| 268 | extrn msgInterrupt:byte | ||
| 269 | extrn msgCRLF:byte | ||
| 270 | extrn Fatal_Error:Byte | ||
| 271 | extrn Read_Write_Relative:Byte | ||
| 272 | extrn PSP_Segment:Word | ||
| 273 | extrn Parse_Error_Msg:Byte | ||
| 274 | extrn Extended_Error_Msg:Byte | ||
| 275 | extrn MsgVerify:Byte | ||
| 276 | |||
| 277 | data ends | ||
| 278 | |||
| 279 | |||
| 280 | debug equ 0 | ||
| 281 | .xlist | ||
| 282 | INCLUDE VERSIONA.INC | ||
| 283 | INCLUDE DOSMAC.INC | ||
| 284 | INCLUDE SYSCALL.INC | ||
| 285 | INCLUDE ERROR.INC | ||
| 286 | INCLUDE DPB.INC | ||
| 287 | INCLUDE CPMFCB.INC | ||
| 288 | INCLUDE DIRENT.INC | ||
| 289 | INCLUDE CURDIR.INC | ||
| 290 | INCLUDE PDB.INC | ||
| 291 | INCLUDE BPB.INC | ||
| 292 | INCLUDE FOREQU.INC | ||
| 293 | INCLUDE FORMACRO.INC | ||
| 294 | INCLUDE IOCTL.INC | ||
| 295 | INCLUDE FORSWTCH.INC | ||
| 296 | INCLUDE SYSVAR.INC | ||
| 297 | .list | ||
| 298 | |||
| 299 | |||
| 300 | ;------------------------------------------------------------------------------- | ||
| 301 | ; And this is the actual data | ||
| 302 | |||
| 303 | data segment public para 'DATA' | ||
| 304 | public deviceParameters | ||
| 305 | public bios | ||
| 306 | public dos | ||
| 307 | public command | ||
| 308 | public FAT_Flag | ||
| 309 | |||
| 310 | validSavedDeviceParameters db 0 | ||
| 311 | savedDeviceParameters a_DeviceParameters <> | ||
| 312 | deviceParameters a_DeviceParameters <> | ||
| 313 | |||
| 314 | Disk_Access A_DiskAccess_Control <> ;an000; dms; | ||
| 315 | |||
| 316 | formatPacket a_FormatPacket <> | ||
| 317 | RWPacket a_TrackReadWritePacket <> | ||
| 318 | RW_TRF_Area db 512 dup(0) | ||
| 319 | |||
| 320 | startSector dw ? | ||
| 321 | fatSpace dd ? | ||
| 322 | fBigFat db FALSE | ||
| 323 | |||
| 324 | firstHead dw ? | ||
| 325 | firstCylinder dw ? | ||
| 326 | tracksLeft dw ? | ||
| 327 | tracksPerDisk dw ? | ||
| 328 | |||
| 329 | Formatted_Tracks_Low dw 0 | ||
| 330 | Formatted_Tracks_High dw 0 | ||
| 331 | |||
| 332 | |||
| 333 | public NumSectors ,TrackCnt | ||
| 334 | NumSectors dw 0FFFFh | ||
| 335 | TrackCnt dw 0FFFFh | ||
| 336 | PercentComplete dw 0FFFFh ;Init non-zero so msg will display first time | ||
| 337 | |||
| 338 | public Old_Dir | ||
| 339 | Old_Dir db FALSE | ||
| 340 | |||
| 341 | public fLastChance | ||
| 342 | fLastChance db FALSE ; Flags reinvocation from | ||
| 343 | ; LastChanceToSaveIt. Used by DSKPRM | ||
| 344 | |||
| 345 | sectorsInRootDirectory dw ? | ||
| 346 | |||
| 347 | directorySector dd 0 | ||
| 348 | |||
| 349 | formatError db 0 | ||
| 350 | |||
| 351 | printStringPointer dw 0 | ||
| 352 | |||
| 353 | ; Exit status defines | ||
| 354 | ExitStatus db 0 | ||
| 355 | ExitOK equ 0 | ||
| 356 | ExitCtrlC equ 3 | ||
| 357 | ExitFatal equ 4 | ||
| 358 | ExitNo equ 5 | ||
| 359 | ExitDriveNotReady equ 6 ;an017; dms;drive not ready error | ||
| 360 | ExitWriteProtect equ 7 ;an017; dms;write protect error | ||
| 361 | |||
| 362 | ROOTSTR DB ? | ||
| 363 | DB ":\",0 | ||
| 364 | DBLFLG DB 0 ;Initialize flags to zero | ||
| 365 | IOCNT DD ? | ||
| 366 | MSTART DW ? ; Start of sys file buffer (para#) | ||
| 367 | MSIZE DW ? ; Size of above in paragraphs | ||
| 368 | TempHandle DW ? | ||
| 369 | FILSTAT DB ? ; In memory status of files | ||
| 370 | ; XXXXXX00B BIOS not in | ||
| 371 | ; XXXXXX01B BIOS partly in | ||
| 372 | ; XXXXXX10B BIOS all in | ||
| 373 | ; XXXX00XXB DOS not in | ||
| 374 | ; XXXX01XXB DOS partly in | ||
| 375 | ; XXXX10XXB DOS all in | ||
| 376 | ; XX00XXXXB COMMAND not in | ||
| 377 | ; XX01XXXXB COMMAND partly in | ||
| 378 | ; XX10XXXXB COMMAND all in | ||
| 379 | |||
| 380 | USERDIRS DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory | ||
| 381 | |||
| 382 | Paras_Per_Fat dw 0000h ;an000;holds fat para count | ||
| 383 | Fat_Init_Value dw 0000h ;an000;initializes the FAT | ||
| 384 | |||
| 385 | bios a_FileStructure <> | ||
| 386 | BiosAttributes EQU attr_hidden + attr_system + attr_read_only | ||
| 387 | |||
| 388 | dos a_FileStructure <> | ||
| 389 | DosAttributes EQU attr_hidden + attr_system + attr_read_only | ||
| 390 | |||
| 391 | command a_FileStructure <> | ||
| 392 | CommandAttributes EQU 0 | ||
| 393 | CommandFile DB "X:\COMMAND.COM",0 | ||
| 394 | CommandFile_Buffer DB 127 dup(0) ;an000;allow room for copy | ||
| 395 | |||
| 396 | Command_Com DB "COMMAND.COM",0 | ||
| 397 | |||
| 398 | VOLFCB DB -1,0,0,0,0,0,8 | ||
| 399 | VOLDRIVE DB 0 | ||
| 400 | VOLNAM DB " " | ||
| 401 | DB 8 | ||
| 402 | DB 26 DUP(?) | ||
| 403 | |||
| 404 | DelFCB DB -1,0,0,0,0,0,8 | ||
| 405 | DelDRIVE DB 0 | ||
| 406 | DelNAM DB "???????????" | ||
| 407 | DB 8 | ||
| 408 | DB 26 DUP(?) | ||
| 409 | |||
| 410 | TRANSRC DB "A:CON",0,0 ; Device so we don't hit the drive | ||
| 411 | TRANDST DB "A:\",0,0,0,0,0,0,0,0,0,0 | ||
| 412 | |||
| 413 | BEGSEG DW ? | ||
| 414 | SWITCHMAP DW ? | ||
| 415 | SWITCHCOPY DW ? | ||
| 416 | FAT DW ? | ||
| 417 | DW ? | ||
| 418 | CLUSSIZ DW ? | ||
| 419 | SECSIZ DW ? | ||
| 420 | SYSTRKS DW ? | ||
| 421 | SECTORS DW ? | ||
| 422 | INBUFF DB 80,0 | ||
| 423 | DB 80 DUP(?) | ||
| 424 | |||
| 425 | |||
| 426 | drive db 0 | ||
| 427 | driveLetter db "x" | ||
| 428 | systemDriveLetter db "x" | ||
| 429 | |||
| 430 | CTRL_BREAK_VECTOR dd ? ;ac010; dms;Holds CTRL-Break | ||
| 431 | ; vector | ||
| 432 | |||
| 433 | Command_Path dd ? ;an011; dms;hold pointer to | ||
| 434 | ; COMMAND's path | ||
| 435 | |||
| 436 | Comspec_ID db "COMSPEC=",00 ;an011; dms;Comspec target | ||
| 437 | |||
| 438 | |||
| 439 | Environ_Segment dw ? ;an011; dms;hold segment of | ||
| 440 | ; environ. vector | ||
| 441 | ;======== Disk Table ========== ;an012; dms; | ||
| 442 | ;Used if NumberOfFATs in BPB | ||
| 443 | ;is 0. | ||
| 444 | |||
| 445 | DiskTable dw 0, 32680, 0803h, 512, 0 | ||
| 446 | dw 4h, 0000h, 0402h, 512, Fbig | ||
| 447 | dw 8h, 0000h, 0803h, 512, Fbig | ||
| 448 | dw 10h, 0000h, 1004h, 512, Fbig | ||
| 449 | dw 20h, 0000h, 2005h, 512, Fbig | ||
| 450 | |||
| 451 | public Org_AX ;an000; dms;make it known | ||
| 452 | Org_AX dw ? ;an000; dms;AX on entry | ||
| 453 | |||
| 454 | Cluster_Boundary_Adj_Factor dw ? ;an000; dms; | ||
| 455 | Cluster_Boundary_SPT_Count dw ? ;an000; dms; | ||
| 456 | Cluster_Boundary_Flag db False ;an000; dms; | ||
| 457 | Cluster_Boundary_Buffer_Seg dw ? ;an000; dms; | ||
| 458 | |||
| 459 | Relative_Sector_Low dw ? ;an000; dms; | ||
| 460 | Relative_Sector_High dw ? ;an000; dms; | ||
| 461 | |||
| 462 | FAT_Flag db ? ;an000; dms; | ||
| 463 | Tracks_To_Format dw ? ;an015; dms; | ||
| 464 | Track_Count dw ? ;an015; dms; | ||
| 465 | Format_End db FALSE ;an015; dms; | ||
| 466 | |||
| 467 | public Msg_Allocation_Unit_Val | ||
| 468 | |||
| 469 | Msg_Allocation_Unit_Val dd ? ;an019; dms; | ||
| 470 | |||
| 471 | |||
| 472 | data ends | ||
| 473 | |||
| 474 | ;For FORPROC and FORMES modules | ||
| 475 | |||
| 476 | public secsiz,clussiz,inbuff | ||
| 477 | |||
| 478 | PUBLIC crlf,std_printf | ||
| 479 | |||
| 480 | public switchmap,drive,driveLetter,fatSpace | ||
| 481 | public fBigFat, PrintString,currentHead,currentCylinder | ||
| 482 | extrn CheckSwitches:near,LastChanceToSaveIt:near | ||
| 483 | extrn Volid:near | ||
| 484 | extrn WriteBootSector:near,OemDone:near | ||
| 485 | extrn AccessDisk:near | ||
| 486 | extrn Main_Init:near | ||
| 487 | extrn Read_Disk:near | ||
| 488 | extrn Write_Disk:near | ||
| 489 | |||
| 490 | data segment public para 'DATA' | ||
| 491 | extrn BiosFile:byte,DosFile:byte | ||
| 492 | data ends | ||
| 493 | |||
| 494 | ;For FORPROC module | ||
| 495 | |||
| 496 | EXTRN FormatAnother?:near,Yes?:near,REPORT:NEAR,USER_STRING:NEAR | ||
| 497 | data segment public para 'DATA' | ||
| 498 | extrn syssiz:dword,biosiz:dword | ||
| 499 | data ends | ||
| 500 | |||
| 501 | DOSVER_LOW EQU 0300H+20 | ||
| 502 | DOSVER_HIGH EQU 0300H+20 | ||
| 503 | |||
| 504 | RECLEN EQU fcb_RECSIZ+7 | ||
| 505 | RR EQU fcb_RR+7 | ||
| 506 | |||
| 507 | PSP_Environ equ 2ch ;an011; dms;location of | ||
| 508 | ; environ. segment | ||
| 509 | ; in PSP | ||
| 510 | |||
| 511 | Fbig equ 0ffh ;an000; dms;flag for big FAT | ||
| 512 | |||
| 513 | START: | ||
| 514 | xor bx,bx ; ;AN000; | ||
| 515 | push bx ; ;AN000; | ||
| 516 | Set_Data_Segment ; ;AC000; | ||
| 517 | mov Org_AX,ax ;an000; dms;save ax on entry | ||
| 518 | jmp Main_Init ; ;AC000; | ||
| 519 | |||
| 520 | |||
| 521 | Main_Routine: ; ;AN000; | ||
| 522 | ; Set memory requirements | ||
| 523 | mov bx,PSP_Segment ;Shrink to free space for FAT ;AC000; | ||
| 524 | mov es,bx ; ;AC000; | ||
| 525 | mov bx,End_Of_Memory ; ;AC000; | ||
| 526 | sub bx,PSP_Segment ; ;AC000; | ||
| 527 | DOS_Call Setblock ; ;AC000; | ||
| 528 | |||
| 529 | call Get_Disk_Access ;an014; dms; | ||
| 530 | cmp Disk_Access.DAC_Access_Flag,0ffh ;an014; dms;is access already allowed? | ||
| 531 | ; $if ne ;an014; dms;no, don't change status | ||
| 532 | JE $$IF1 | ||
| 533 | lea dx,Disk_Access ;an014; dms;point to parm block | ||
| 534 | mov Disk_Access.DAC_Access_Flag,01h ;an014; dms;signal disk access | ||
| 535 | call Set_Disk_Access_On_Off ;an014;dms;allow disk access | ||
| 536 | ; $endif ;an014; dms; | ||
| 537 | $$IF1: | ||
| 538 | |||
| 539 | CALL Phase1Initialisation | ||
| 540 | jnc FatAllocated | ||
| 541 | |||
| 542 | Message msgFormatFailure ; ;AC000; | ||
| 543 | jmp Fexit | ||
| 544 | |||
| 545 | MEMERR: | ||
| 546 | mov ax, seg data | ||
| 547 | mov ds, ax | ||
| 548 | Message msgOutOfMemory ; ;AC000; | ||
| 549 | ;call PrintString | ||
| 550 | JMP FEXIT | ||
| 551 | |||
| 552 | FatAllocated: | ||
| 553 | |||
| 554 | TEST SWITCHMAP,SWITCH_S | ||
| 555 | JZ INITCALL | ||
| 556 | MOV BX,0FFFFH | ||
| 557 | MOV AH,ALLOC | ||
| 558 | INT 21H | ||
| 559 | OR BX,BX | ||
| 560 | JZ MEMERRJ ;No memory | ||
| 561 | MOV [MSIZE],BX | ||
| 562 | MOV AH,ALLOC | ||
| 563 | INT 21H | ||
| 564 | JNC MEM_OK | ||
| 565 | MEMERRJ: | ||
| 566 | JMP MEMERR ;No memory | ||
| 567 | |||
| 568 | MEM_OK: | ||
| 569 | MOV [MSTART],AX | ||
| 570 | |||
| 571 | RDFRST: | ||
| 572 | mov bios.fileSizeInParagraphs,0 ;mjb001 initialize file size | ||
| 573 | mov dos.fileSizeInParagraphs,0 ;mjb001 ... | ||
| 574 | mov command.fileSizeInParagraphs,0 ;mjb001 ... | ||
| 575 | CALL READDOS ;Read BIOS and DOS | ||
| 576 | JNC INITCALL ;OK -- read next file | ||
| 577 | NEEDSYS: | ||
| 578 | CALL SYSPRM ;Prompt for system disk | ||
| 579 | JMP RDFRST ;Try again | ||
| 580 | |||
| 581 | INITCALL: | ||
| 582 | CALL Phase2Initialisation | ||
| 583 | |||
| 584 | SWITCHCHK: | ||
| 585 | MOV DX,SWITCHMAP | ||
| 586 | MOV SWITCHCOPY,DX | ||
| 587 | |||
| 588 | SYSLOOP: | ||
| 589 | ;Must intialize for each iteration | ||
| 590 | |||
| 591 | MOV WORD PTR SYSSIZ,0 | ||
| 592 | MOV WORD PTR SYSSIZ+2,0 | ||
| 593 | MOV BYTE PTR DBLFLG,0 | ||
| 594 | mov ExitStatus, ExitOK | ||
| 595 | MOV DX,SWITCHCOPY | ||
| 596 | MOV SWITCHMAP,DX ;Restore original Switches | ||
| 597 | ; DiskFormat will handle call for new disk | ||
| 598 | CALL DISKFORMAT ;Format the disk | ||
| 599 | JNC GETTRK | ||
| 600 | FRMTPROB: | ||
| 601 | |||
| 602 | test SwitchMap,Switch_Select ;an017; dms;SELECT option? | ||
| 603 | ; $if z ;an017; dms;no - display message | ||
| 604 | JNZ $$IF3 | ||
| 605 | Message msgFormatFailure ; ;AC000; | ||
| 606 | mov ExitStatus, ExitFatal ;an017; dms; | ||
| 607 | ; $endif ;an017; dms; | ||
| 608 | $$IF3: | ||
| 609 | CALL MORE ;See if more disks to format | ||
| 610 | JMP SHORT SYSLOOP | ||
| 611 | |||
| 612 | ;Mark any bad sectors in the FATs | ||
| 613 | ;And keep track of how many bytes there are in bad sectors | ||
| 614 | |||
| 615 | GETTRK: | ||
| 616 | CALL BADSECTOR ;Do bad track fix-up | ||
| 617 | JC FRMTPROB ;Had an error in Formatting - can't recover | ||
| 618 | CMP AX,0 ;Are we finished? | ||
| 619 | JNZ TRKFND ;No - check error conditions | ||
| 620 | JMP DRTFAT ;Yes | ||
| 621 | TRKFND: | ||
| 622 | mov bx,word ptr Relative_Sector_Low ;get the low word of the sector ;an000; dms; | ||
| 623 | CMP BX,STARTSECTOR ;Are any sectors in the system area bad? | ||
| 624 | JAE CLRTEST ; MZ 2.26 unsigned compare | ||
| 625 | Message msgDiskUnusable ; ;AC000; | ||
| 626 | JMP FRMTPROB ;Bad disk -- try again | ||
| 627 | CLRTEST: | ||
| 628 | MOV SECTORS,AX ;Save the number of sectors on the track | ||
| 629 | TEST SWITCHMAP,SWITCH_S ;If system requested calculate size | ||
| 630 | JZ BAD100 | ||
| 631 | CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space? | ||
| 632 | JNZ CMPTRKS ;Yes -- all ready for the compare | ||
| 633 | INC BYTE PTR DBLFLG ;No -- set the flag | ||
| 634 | CALL GETBIOSIZE ; Get the size of the BIOS | ||
| 635 | MOV DX,WORD PTR SYSSIZ+2 | ||
| 636 | MOV AX,WORD PTR SYSSIZ | ||
| 637 | MOV WORD PTR BIOSIZ+2,DX | ||
| 638 | MOV WORD PTR BIOSIZ,AX | ||
| 639 | CALL GETDOSSIZE | ||
| 640 | CALL GETCMDSIZE | ||
| 641 | MOV DX,WORD PTR BIOSIZ+2 | ||
| 642 | MOV AX,WORD PTR BIOSIZ | ||
| 643 | DIV deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 644 | ADD AX,STARTSECTOR | ||
| 645 | MOV SYSTRKS,AX ;Space FAT,Dir,and system files require | ||
| 646 | CMPTRKS: | ||
| 647 | mov bx,word ptr Relative_Sector_Low ;get the low word of the sector ;an000; dms; | ||
| 648 | CMP BX,SYSTRKS | ||
| 649 | JA BAD100 ; MZ 2.26 unsigned compare | ||
| 650 | mov ExitStatus, ExitFatal | ||
| 651 | Message msgNotSystemDisk ; ;AC000; | ||
| 652 | AND SWITCHMAP,NOT SWITCH_S ;Turn off system transfer switch | ||
| 653 | MOV WORD PTR SYSSIZ+2,0 ;No system to transfer | ||
| 654 | MOV WORD PTR SYSSIZ,0 ;No system to transfer | ||
| 655 | BAD100: | ||
| 656 | |||
| 657 | CMP deviceParameters.DP_DeviceType, DEV_HARDDISK ;an000; dms;hard disk? | ||
| 658 | ; $if e ;an000; dms; yes | ||
| 659 | JNE $$IF5 | ||
| 660 | call Get_Bad_Sector_Hard ;an000; dms;see if a sector is bad | ||
| 661 | ; $else ;an000; dms;floppy disk | ||
| 662 | JMP SHORT $$EN5 | ||
| 663 | $$IF5: | ||
| 664 | call Get_Bad_Sector_Floppy ;an000; dms;mark entire track bad | ||
| 665 | ; $endif ;an000; dms; | ||
| 666 | $$EN5: | ||
| 667 | |||
| 668 | JMP GETTRK | ||
| 669 | |||
| 670 | ; Inputs: BX = Cluster number | ||
| 671 | ; Outputs: The given cluster is marked as invalid | ||
| 672 | ; Zero flag is set if the cluster was already marked bad | ||
| 673 | ; Registers modified: DX,SI | ||
| 674 | ; No other registers affected | ||
| 675 | |||
| 676 | ;========================================================================= | ||
| 677 | ; BADCLUS : Marks off a bad cluster in the FAT | ||
| 678 | ; If a cluster has already been marked bad it | ||
| 679 | ; will return with ZR. | ||
| 680 | ; | ||
| 681 | ; Inputs : DX:AX - Cluster Number | ||
| 682 | ; | ||
| 683 | ; Outputs : Cluster is marked invalid | ||
| 684 | ; ZR set if cluster already marked bad | ||
| 685 | ;========================================================================= | ||
| 686 | |||
| 687 | BadClus proc near ;an000; mark bad clusters | ||
| 688 | |||
| 689 | push di ;an000; save affected regs | ||
| 690 | push ax | ||
| 691 | push bx | ||
| 692 | push cx | ||
| 693 | push dx | ||
| 694 | push es | ||
| 695 | |||
| 696 | mov es, word ptr fatSpace + 2 ;an005; obtain seg of FAT | ||
| 697 | CMP fBigFat,TRUE ;an005; 16 bit fat? | ||
| 698 | ; $if ne ;an005; no - 12-bit fat | ||
| 699 | JE $$IF8 | ||
| 700 | push ax ;an000; save ax - contains low cluster number | ||
| 701 | mov si,dx ;an000; pick up high word of cluster | ||
| 702 | mov di,ax ;an000; pick up low word of cluster | ||
| 703 | mov cx,2 ;an000; divide by 2 | ||
| 704 | call Divide_32_Bits ;an000; 32 bit divide | ||
| 705 | |||
| 706 | add ax,di ;an000; add in low word of result | ||
| 707 | adc dx,si ;an000; pick up low word carry | ||
| 708 | ;cluster = cluster * 1.5 | ||
| 709 | add ax,word ptr fatspace ;an005; add 0 | ||
| 710 | adc dx,0 ;an000; pick up carry | ||
| 711 | |||
| 712 | mov bx,dx ;an000; get high word for adjust | ||
| 713 | mov cx,es ;an005; place seg in ax | ||
| 714 | call BadClus_Address_Adjust ;an000; adjust segment offset | ||
| 715 | mov es,cx ;an000; new segment | ||
| 716 | mov si,ax ;an000; new offset | ||
| 717 | |||
| 718 | MOV DX,0FF7h ;an005; bad cluster flag | ||
| 719 | MOV AX,0FFFh ;an005; mask value | ||
| 720 | |||
| 721 | pop cx ;an000; restore ax in cx - low cluster number | ||
| 722 | test cx,1 ;an000; is old clus num odd? | ||
| 723 | ; $if nz ;an005; yes | ||
| 724 | JZ $$IF9 | ||
| 725 | mov cl,4 ;an005; set shift count | ||
| 726 | SHL AX,cl ;an005; get only 12 bits - fff0 | ||
| 727 | mov cl,4 ;an005; set shift count | ||
| 728 | SHL DX,cl ;an005; get 12 bits - ff70 | ||
| 729 | ; $endif ;an005; | ||
| 730 | $$IF9: | ||
| 731 | ; $else ;an005; 16-bit fats here | ||
| 732 | JMP SHORT $$EN8 | ||
| 733 | $$IF8: | ||
| 734 | xor si,si ;an005; clear si | ||
| 735 | mov bx,dx ;an000; get high word for multiply | ||
| 736 | mov cx,2 ;an000; multiply by 2 | ||
| 737 | call Multiply_32_Bits ;an000; 32 bit multiply | ||
| 738 | ; due to 2 bytes per | ||
| 739 | ; FAT cell. This gives | ||
| 740 | ; us an offset into the | ||
| 741 | ; FAT. | ||
| 742 | |||
| 743 | mov cx,es ;an005; place seg in cx | ||
| 744 | call BadClus_Address_Adjust ;an000; adjust segment:offset | ||
| 745 | mov es,cx ;an000; new segment | ||
| 746 | mov si,ax ;an000; new offset | ||
| 747 | |||
| 748 | MOV DX,0FFF7h ;an005; bad cluster value | ||
| 749 | MOV AX,0FFFFh ;an005; mask value | ||
| 750 | ; $endif | ||
| 751 | $$EN8: | ||
| 752 | |||
| 753 | MOV CX,es:[SI] ;an005; get contents of fat cell | ||
| 754 | AND CX,AX ;an005; make it 12 or 16 bit | ||
| 755 | ; depending on value in AX | ||
| 756 | NOT AX ;an005; set AX to 0 | ||
| 757 | AND es:[SI],AX ;an005; clear FAT entry | ||
| 758 | OR es:[SI],DX ;an005; flag it a bad cluster | ||
| 759 | CMP DX,CX ; return op == badval; | ||
| 760 | |||
| 761 | pop es | ||
| 762 | pop dx | ||
| 763 | pop cx | ||
| 764 | pop bx | ||
| 765 | pop ax | ||
| 766 | pop di | ||
| 767 | return | ||
| 768 | |||
| 769 | badclus endp | ||
| 770 | |||
| 771 | DRTFAT: | ||
| 772 | TEST SWITCHMAP,SWITCH_S ;If system requested, calculate size | ||
| 773 | JZ CLEARED | ||
| 774 | CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space? | ||
| 775 | JNZ CLEARED ;Yes | ||
| 776 | INC BYTE PTR DBLFLG ;No -- set the flag | ||
| 777 | CALL GETSIZE ;Calculate the system size | ||
| 778 | CLEARED: | ||
| 779 | call Ctrl_Break_Save ;ac010; dms;save CTRL-Break | ||
| 780 | call Set_Ctrl_Break | ||
| 781 | CALL WriteFileSystem | ||
| 782 | |||
| 783 | JNC FATWRT | ||
| 784 | |||
| 785 | |||
| 786 | LOUSE: | ||
| 787 | |||
| 788 | call Reset_Ctrl_Break ;ac010; dms;restore CTRL-Break | ||
| 789 | Message msgDiskUnusable ; ;AC000; | ||
| 790 | JMP FRMTPROB | ||
| 791 | |||
| 792 | LOUSEP: | ||
| 793 | POP DS | ||
| 794 | JMP LOUSE | ||
| 795 | |||
| 796 | FATWRT: | ||
| 797 | |||
| 798 | PUSH DS | ||
| 799 | MOV DL,DRIVE | ||
| 800 | INC DL | ||
| 801 | MOV AH,GET_DPB | ||
| 802 | INT 21H | ||
| 803 | CMP AL,-1 | ||
| 804 | JZ LOUSEP ;Something BAD has happened | ||
| 805 | MOV [BX.dpb_next_free],0 ; Reset allocation to start of disk | ||
| 806 | MOV [BX.dpb_free_cnt],-1 ; Force free space to be computed | ||
| 807 | POP DS | ||
| 808 | TEST SWITCHMAP,SWITCH_S ;System desired | ||
| 809 | JZ STATUS | ||
| 810 | mov al, drive | ||
| 811 | call AccessDisk ; note what is current logical drive | ||
| 812 | CALL WRITEDOS ;Write the BIOS & DOS | ||
| 813 | JNC SYSOK | ||
| 814 | Message msgNotSystemDisk ; ;AC000; | ||
| 815 | MOV WORD PTR SYSSIZ+2,0 ;No system transfered | ||
| 816 | MOV WORD PTR SYSSIZ,0 ;No system transfered | ||
| 817 | JMP SHORT STATUS | ||
| 818 | |||
| 819 | SYSOK: | ||
| 820 | |||
| 821 | |||
| 822 | test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display if EXEC'd by ;AN000; | ||
| 823 | ; $IF Z ; Select ;AN000; | ||
| 824 | JNZ $$IF13 | ||
| 825 | Message msgSystemTransfered ; ;AC000; | ||
| 826 | ; $ENDIF ;AN000; | ||
| 827 | $$IF13: | ||
| 828 | STATUS: | ||
| 829 | |||
| 830 | call Reset_Ctrl_Break ;ac010; dms;restore CTRL-Break | ||
| 831 | |||
| 832 | CALL CRLF | ||
| 833 | |||
| 834 | |||
| 835 | |||
| 836 | |||
| 837 | MOV AH,DISK_RESET | ||
| 838 | INT 21H | ||
| 839 | CALL DONE ;Final call to OEM module | ||
| 840 | JNC REPORTC | ||
| 841 | JMP FRMTPROB ;Report an error | ||
| 842 | |||
| 843 | REPORTC: | ||
| 844 | |||
| 845 | ; | ||
| 846 | ;TEMP FIX for /AUTOTEST | ||
| 847 | ; | ||
| 848 | test SwitchMap,(Switch_Autotest or Switch_8) ;TEMP | ||
| 849 | ; $IF Z | ||
| 850 | JNZ $$IF15 | ||
| 851 | CALL VOLID | ||
| 852 | ; $ENDIF | ||
| 853 | $$IF15: | ||
| 854 | test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Need to shut down the report? ;AN000; | ||
| 855 | ; $IF Z ;If exec'd by Select, we do ;AN000; | ||
| 856 | JNZ $$IF17 | ||
| 857 | CALL REPORT ;Print report | ||
| 858 | ; $ENDIF ; ;AN000; | ||
| 859 | $$IF17: | ||
| 860 | CALL MORE ;See if more disks to format | ||
| 861 | JMP SYSLOOP ;If we returned from MORE then continue | ||
| 862 | |||
| 863 | ;****************************************** | ||
| 864 | ; Calculate the size in bytes of the system rounded up to sector and | ||
| 865 | ; cluster boundries, Answer in SYSSIZ | ||
| 866 | |||
| 867 | GetSize proc near | ||
| 868 | call GetBioSize | ||
| 869 | call GetDosSize | ||
| 870 | call GetCmdSize | ||
| 871 | return | ||
| 872 | GetSize endp | ||
| 873 | |||
| 874 | GetBioSize proc near | ||
| 875 | MOV AX,WORD PTR bios.fileSizeInBytes | ||
| 876 | MOV DX,WORD PTR bios.fileSizeInBytes+2 | ||
| 877 | CALL AddToSystemSize | ||
| 878 | return | ||
| 879 | GetBioSize endp | ||
| 880 | |||
| 881 | GetDosSize proc near | ||
| 882 | MOV AX,WORD PTR dos.fileSizeInBytes | ||
| 883 | MOV DX,WORD PTR dos.fileSizeInBytes+2 | ||
| 884 | CALL AddToSystemSize | ||
| 885 | return | ||
| 886 | GetDosSize endp | ||
| 887 | |||
| 888 | GetCmdSize proc near | ||
| 889 | MOV AX,WORD PTR command.fileSizeInBytes | ||
| 890 | MOV DX,WORD PTR command.fileSizeInBytes+2 | ||
| 891 | call AddToSystemSize | ||
| 892 | return | ||
| 893 | GetCmdSize endp | ||
| 894 | |||
| 895 | ;Calculate the number of sectors used for the system | ||
| 896 | PUBLIC AddToSystemSize | ||
| 897 | AddToSystemSize proc near | ||
| 898 | push bx | ||
| 899 | DIV deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 900 | OR DX,DX | ||
| 901 | JZ FNDSIZ0 | ||
| 902 | INC AX ; Round up to next sector | ||
| 903 | FNDSIZ0: | ||
| 904 | PUSH AX | ||
| 905 | XOR DX,DX | ||
| 906 | xor bx,bx | ||
| 907 | mov bl, deviceParameters.DP_BPB.BPB_SectorsPerCluster | ||
| 908 | div bx | ||
| 909 | POP AX | ||
| 910 | OR DX,DX | ||
| 911 | JZ ONCLUS | ||
| 912 | SUB DX, bx | ||
| 913 | NEG DX | ||
| 914 | ADD AX,DX ; Round up sector count to cluster | ||
| 915 | ; boundry | ||
| 916 | ONCLUS: | ||
| 917 | MUL deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 918 | ADD WORD PTR SYSSIZ,AX | ||
| 919 | ADC WORD PTR SYSSIZ+2,DX | ||
| 920 | pop bx | ||
| 921 | return | ||
| 922 | AddToSystemSize endp | ||
| 923 | |||
| 924 | MORE: | ||
| 925 | |||
| 926 | mov Formatted_Tracks_Low,0 ;Reinit the track counter ;AN000; | ||
| 927 | mov Formatted_Tracks_High,0 ; in case of another format ;AN000; | ||
| 928 | test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display if EXEC'd by ;AN000; | ||
| 929 | jnz ExitProgram ; Select ;AN000; | ||
| 930 | |||
| 931 | CMP deviceParameters.DP_DeviceType, DEV_HARDDISK | ||
| 932 | je ExitProgram | ||
| 933 | test SwitchMap,(SWITCH_Select or SWITCH_AUTOTEST) ;If exec'd from select, then;AN000; | ||
| 934 | jnz ExitProgram ; don't give user choice ;AN000; | ||
| 935 | CALL FormatAnother? ;Get yes or no response | ||
| 936 | JC ExitProgram | ||
| 937 | CALL CRLF | ||
| 938 | JMP CRLF | ||
| 939 | |||
| 940 | |||
| 941 | FEXIT: | ||
| 942 | Set_Data_Segment ;Make sure have addressability ;AN000; | ||
| 943 | mov ExitStatus,ExitFatal | ||
| 944 | |||
| 945 | ExitProgram: | ||
| 946 | test validSavedDeviceParameters, 0ffH | ||
| 947 | jz DoNotRestoreDeviceParameters | ||
| 948 | mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD | ||
| 949 | lea dx, savedDeviceParameters | ||
| 950 | call SetDeviceParameters | ||
| 951 | DoNotRestoreDeviceParameters: | ||
| 952 | |||
| 953 | call Format_Access_Wrap_Up ;determine access status ;an000; dms;determine access status | ||
| 954 | mov al,ExitStatus ;Get Errorlevel ;AN000; | ||
| 955 | DOS_Call Exit ;Exit program ;AN000; | ||
| 956 | int 20h ;If other exit fails ;AN000; | ||
| 957 | |||
| 958 | ; Prompt the user for a system diskette in the default drive | ||
| 959 | SYSPRM: | ||
| 960 | MOV AH,GET_DEFAULT_DRIVE ;Will find out the default drive | ||
| 961 | INT 21H ;Default now in AL | ||
| 962 | MOV BL,AL | ||
| 963 | INC BL ; A = 1 | ||
| 964 | ADD AL,41H ;Now in Ascii | ||
| 965 | MOV systemDriveLetter,AL ;Text now ok | ||
| 966 | CALL IsRemovable | ||
| 967 | JNC DoPrompt | ||
| 968 | ; | ||
| 969 | ; Media is non-removable. Switch sys disk to drive A. Check, though, to see | ||
| 970 | ; if drive A is removable too. | ||
| 971 | ; | ||
| 972 | MOV AL,"A" | ||
| 973 | MOV BYTE PTR [systemDriveLetter],AL | ||
| 974 | MOV [BiosFile],AL | ||
| 975 | MOV [DosFile],AL | ||
| 976 | MOV [CommandFile],AL | ||
| 977 | MOV BX,1 | ||
| 978 | CALL IsRemovable | ||
| 979 | JNC DoPrompt | ||
| 980 | Message msgNoSystemFiles ; ;AC000; | ||
| 981 | fexitJ: | ||
| 982 | JMP FEXIT | ||
| 983 | |||
| 984 | DoPrompt: | ||
| 985 | mov al, systemDriveLetter | ||
| 986 | sub al, 'A' | ||
| 987 | call AccessDisk | ||
| 988 | Message msgInsertDOSDisk ; ;AC000; | ||
| 989 | Message ContinueMsg | ||
| 990 | ;lea dx, ptr_msgInsertDosDisk | ||
| 991 | ;CALL std_printf ;Print first line | ||
| 992 | CALL USER_STRING ;Wait for a key | ||
| 993 | CALL CRLF | ||
| 994 | call crlf | ||
| 995 | return | ||
| 996 | |||
| 997 | TARGPRM: | ||
| 998 | mov al, drive | ||
| 999 | call AccessDisk | ||
| 1000 | Message MsgInsertDisk ; ;AC000; | ||
| 1001 | Message ContinueMsg ; | ||
| 1002 | ;lea DX, ptr_msgInsertDisk | ||
| 1003 | ;CALL std_printf ;Print first line | ||
| 1004 | CALL USER_STRING ;Wait for a key | ||
| 1005 | CALL CRLF | ||
| 1006 | return | ||
| 1007 | |||
| 1008 | ; | ||
| 1009 | ; Determine if the drive indicated in BX is removable or not. | ||
| 1010 | ; | ||
| 1011 | ; Inputs: BX has drive (0=def, 1=A) | ||
| 1012 | ; Outputs: Carry clear | ||
| 1013 | ; Removable | ||
| 1014 | ; Carry set | ||
| 1015 | ; not removable | ||
| 1016 | ; Registers modified: none | ||
| 1017 | |||
| 1018 | IsRemovable: | ||
| 1019 | SaveReg <AX> | ||
| 1020 | MOV AX,(IOCTL SHL 8) OR 8 ; Rem media check | ||
| 1021 | INT 21H | ||
| 1022 | JNC CheckRemove | ||
| 1023 | MOV AX,(IOCTL SHL 8) + 9 ; Is it a NET drive? | ||
| 1024 | INT 21h | ||
| 1025 | JC NotRemove ; Yipe, say non-removable | ||
| 1026 | TEST DX,1000h | ||
| 1027 | JNZ NotRemove ; Is NET drive, say non-removeable | ||
| 1028 | JMP IsRemove ; Is local, say removable | ||
| 1029 | CheckRemove: | ||
| 1030 | TEST AX,1 | ||
| 1031 | JNZ NotRemove | ||
| 1032 | IsRemove: | ||
| 1033 | CLC | ||
| 1034 | RestoreReg <AX> | ||
| 1035 | return | ||
| 1036 | NotRemove: | ||
| 1037 | STC | ||
| 1038 | RestoreReg <AX> | ||
| 1039 | return | ||
| 1040 | |||
| 1041 | |||
| 1042 | ; DiSKPRoMpt: | ||
| 1043 | ; | ||
| 1044 | ; This routine prompts for the insertion of the correct diskette | ||
| 1045 | ; into the Target drive, UNLESS we are being re-entrantly invoked | ||
| 1046 | ; from LastChanceToSaveIt. If the target is a Hardisk we issue a | ||
| 1047 | ; warning message. | ||
| 1048 | ; | ||
| 1049 | ; INPUTS: | ||
| 1050 | ; deviceParameters.DP_DeviceType | ||
| 1051 | ; fLastChance | ||
| 1052 | ; | ||
| 1053 | ; OUTPUTS: | ||
| 1054 | ; Prompt string | ||
| 1055 | ; fLastChance := FALSE | ||
| 1056 | ; | ||
| 1057 | ; Registers affected: | ||
| 1058 | ; Flags | ||
| 1059 | ; | ||
| 1060 | DSKPRM: | ||
| 1061 | CMP fLastChance,TRUE | ||
| 1062 | JE PrmptRet | ||
| 1063 | |||
| 1064 | CMP deviceParameters.DP_DeviceType, DEV_HARDDISK | ||
| 1065 | jne goprnit | ||
| 1066 | Message msgHardDiskWarning ; ;AC000; | ||
| 1067 | ;lea dx, ptr_msgHardDiskWarning | ||
| 1068 | ;call std_printf | ||
| 1069 | CALL Yes? | ||
| 1070 | jnc OkToFormatHardDisk | ||
| 1071 | mov ExitStatus, ExitNo | ||
| 1072 | jmp ExitProgram | ||
| 1073 | |||
| 1074 | OkToFormatHardDisk: | ||
| 1075 | CALL CRLF | ||
| 1076 | CALL CRLF | ||
| 1077 | return | ||
| 1078 | |||
| 1079 | GOPRNIT: | ||
| 1080 | mov al, drive | ||
| 1081 | call AccessDisk | ||
| 1082 | Message msgInsertDisk ; ;AC000; | ||
| 1083 | Message ContinueMsg ; | ||
| 1084 | ;lea dx,ptr_msgInsertDisk | ||
| 1085 | ;CALL std_printf | ||
| 1086 | CALL USER_STRING ;Wait for any key | ||
| 1087 | CALL CRLF | ||
| 1088 | CALL CRLF | ||
| 1089 | |||
| 1090 | PrmptRet: | ||
| 1091 | mov fLastChance, FALSE | ||
| 1092 | return | ||
| 1093 | |||
| 1094 | |||
| 1095 | ;------------------------------------------------------------------------------- | ||
| 1096 | |||
| 1097 | ControlC_Handler: | ||
| 1098 | mov ax, seg data | ||
| 1099 | mov ds, ax | ||
| 1100 | Message msgInterrupt ; ;AC000; | ||
| 1101 | mov ExitStatus, ExitCtrlC | ||
| 1102 | jmp ExitProgram | ||
| 1103 | |||
| 1104 | |||
| 1105 | crlf: | ||
| 1106 | ;lea dx, msgCRLF | ||
| 1107 | mov dx,offset msgCRLF ;CR,LF added to message ;AC000; | ||
| 1108 | PrintString: | ||
| 1109 | ;mov printStringPointer, dx | ||
| 1110 | ;lea dx, PrintStringPointer | ||
| 1111 | |||
| 1112 | std_printf: | ||
| 1113 | ;push dx | ||
| 1114 | ;call printf | ||
| 1115 | call Display_Interface ; ;AC000; | ||
| 1116 | return | ||
| 1117 | |||
| 1118 | ;------------------------------------------------------------------------------- | ||
| 1119 | |||
| 1120 | |||
| 1121 | ;**************************************** | ||
| 1122 | ;Copy IO.SYS, MSDOS.SYS and COMMAND.COM into data area. | ||
| 1123 | ; Carry set if problems | ||
| 1124 | |||
| 1125 | READDOS: | ||
| 1126 | push ax ;save regs ;an025; dms; | ||
| 1127 | push bx ; ;an025; dms; | ||
| 1128 | push es ; ;an025; dms; | ||
| 1129 | |||
| 1130 | mov ah,Get_In_Vars ;Find out boot drive ;an025; dms; | ||
| 1131 | int 21h ; ;an025; dms; | ||
| 1132 | mov al,byte ptr es:[bx].SysI_Boot_Drive ;get 1 based drive ID ;an025; dms; | ||
| 1133 | add al,40h ;Make it ASCII ;an025; dms; | ||
| 1134 | mov [BiosFile],al ;Stuff it in file specs. ;an025; dms; | ||
| 1135 | mov [DosFile],al ; ;an025; dms; | ||
| 1136 | mov [CommandFile],al ; ;an025; dms; | ||
| 1137 | |||
| 1138 | pop es ;restore regs ;an025; dms; | ||
| 1139 | pop bx ; ;an025; dms; | ||
| 1140 | pop ax ; ;an025; dms; | ||
| 1141 | |||
| 1142 | call Get_BIOS ; dcl 8/23/86 | ||
| 1143 | JNC RDFILS | ||
| 1144 | return | ||
| 1145 | |||
| 1146 | RDFILS: | ||
| 1147 | MOV BYTE PTR [FILSTAT],0 | ||
| 1148 | MOV BX,[bios.fileHandle] | ||
| 1149 | MOV AX,[MSTART] | ||
| 1150 | MOV DX,AX | ||
| 1151 | ADD DX,[MSIZE] ; CX first bad para | ||
| 1152 | MOV [bios.fileStartSegment],AX | ||
| 1153 | MOV CX,[bios.fileSizeInParagraphs] | ||
| 1154 | ADD AX,CX | ||
| 1155 | CMP AX,DX | ||
| 1156 | JBE GOTBIOS | ||
| 1157 | MOV BYTE PTR [FILSTAT],00000001B ; Got part of BIOS | ||
| 1158 | MOV SI,[MSIZE] | ||
| 1159 | XOR DI,DI | ||
| 1160 | CALL DISIX4 | ||
| 1161 | push ds | ||
| 1162 | MOV DS,[bios.fileStartSegment] | ||
| 1163 | assume ds:nothing | ||
| 1164 | CALL READFILE | ||
| 1165 | pop ds | ||
| 1166 | assume ds:data | ||
| 1167 | JC CLSALL | ||
| 1168 | XOR DX,DX | ||
| 1169 | MOV CX,DX | ||
| 1170 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 1171 | INT 21H | ||
| 1172 | MOV WORD PTR [bios.fileOffset],AX | ||
| 1173 | MOV WORD PTR [bios.fileOffset+2],DX | ||
| 1174 | FILESDONE: | ||
| 1175 | CLC | ||
| 1176 | CLSALL: | ||
| 1177 | PUSHF | ||
| 1178 | ; CALL COMCLS ; dcl 8/23/86 | ||
| 1179 | call FILE_CLS ; dcl 8/23/86 | ||
| 1180 | POPF | ||
| 1181 | return | ||
| 1182 | |||
| 1183 | GOTBIOS: | ||
| 1184 | MOV BYTE PTR [FILSTAT],00000010B ; Got all of BIOS | ||
| 1185 | push es | ||
| 1186 | LES SI,[bios.fileSizeInBytes] | ||
| 1187 | MOV DI,ES | ||
| 1188 | pop es | ||
| 1189 | push ds | ||
| 1190 | MOV DS,[bios.fileStartSegment] | ||
| 1191 | assume ds:nothing | ||
| 1192 | CALL READFILE | ||
| 1193 | pop ds | ||
| 1194 | assume ds:data | ||
| 1195 | JC CLSALL | ||
| 1196 | |||
| 1197 | push ax ; dcl 8/23/86 | ||
| 1198 | push dx ; dcl 8/23/86 | ||
| 1199 | call File_Cls ; dcl 8/23/86 | ||
| 1200 | call Get_DOS ; dcl 8/23/86 | ||
| 1201 | pop dx ; dcl 8/23/86 | ||
| 1202 | pop ax ; dcl 8/23/86 | ||
| 1203 | |||
| 1204 | JNC Found_IBMDOS ;mt 12/8/86 P894 | ||
| 1205 | return ;mt 12/8/86 | ||
| 1206 | |||
| 1207 | Found_IBMDOS: ;mt 12/8/86 | ||
| 1208 | |||
| 1209 | MOV BX,[dos.fileHandle] | ||
| 1210 | MOV [dos.fileStartSegment],AX | ||
| 1211 | CMP AX,DX ; No room left? | ||
| 1212 | JZ CLSALL ; Yes | ||
| 1213 | MOV CX,[dos.fileSizeInParagraphs] | ||
| 1214 | ADD AX,CX | ||
| 1215 | CMP AX,DX | ||
| 1216 | JBE GOTDOS | ||
| 1217 | OR BYTE PTR [FILSTAT],00000100B ; Got part of DOS | ||
| 1218 | SUB DX,[dos.fileStartSegment] | ||
| 1219 | MOV SI,DX | ||
| 1220 | XOR DI,DI | ||
| 1221 | CALL DISIX4 | ||
| 1222 | push ds | ||
| 1223 | MOV DS,[dos.fileStartSegment] | ||
| 1224 | assume ds:nothing | ||
| 1225 | CALL READFILE | ||
| 1226 | pop ds | ||
| 1227 | assume ds:data | ||
| 1228 | JC CLSALL | ||
| 1229 | XOR DX,DX | ||
| 1230 | MOV CX,DX | ||
| 1231 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 1232 | INT 21H | ||
| 1233 | MOV WORD PTR [dos.fileOffset],AX | ||
| 1234 | MOV WORD PTR [dos.fileOffset+2],DX | ||
| 1235 | JMP FILESDONE | ||
| 1236 | |||
| 1237 | GOTDOS: | ||
| 1238 | OR BYTE PTR [FILSTAT],00001000B ; Got all of DOS | ||
| 1239 | push es | ||
| 1240 | LES SI,[dos.fileSizeInBytes] | ||
| 1241 | MOV DI,ES | ||
| 1242 | pop es | ||
| 1243 | push ds | ||
| 1244 | MOV DS,[dos.fileStartSegment] | ||
| 1245 | assume ds:nothing | ||
| 1246 | CALL READFILE | ||
| 1247 | pop ds | ||
| 1248 | assume ds:data | ||
| 1249 | |||
| 1250 | CLSALLJ: JNC NOTCLSALL ;PTM P894 mt 12/8/86 | ||
| 1251 | jmp clsall ; | ||
| 1252 | |||
| 1253 | NotCLSALL: | ||
| 1254 | push ax ; dcl 8/23/86 | ||
| 1255 | |||
| 1256 | push dx ; dcl 8/23/86 | ||
| 1257 | call File_cls ; dcl 8/23/86 | ||
| 1258 | call Get_Command_Path ;ac011; dms; get path of | ||
| 1259 | ; COMMAND.COM | ||
| 1260 | call Get_COMMAND ;ac011; dms; Point to COMMAND | ||
| 1261 | ; and read it | ||
| 1262 | pop dx ; dcl 8/23/86 | ||
| 1263 | pop ax ; dcl 8/23/86 | ||
| 1264 | |||
| 1265 | JNC Found_COMMAND ;mt 12/8/86 P894 | ||
| 1266 | return ;mt 12/8/86 | ||
| 1267 | |||
| 1268 | Found_COMMAND: ;mt 12/8/86 | ||
| 1269 | MOV BX,[command.fileHandle] | ||
| 1270 | MOV [command.fileStartSegment],AX | ||
| 1271 | CMP AX,DX ; No room left? | ||
| 1272 | JZ CLSALLJ ; Yes | ||
| 1273 | MOV CX,[command.fileSizeInParagraphs] | ||
| 1274 | ADD AX,CX | ||
| 1275 | CMP AX,DX | ||
| 1276 | JBE GOTCOM | ||
| 1277 | OR BYTE PTR [FILSTAT],00010000B ; Got part of COMMAND | ||
| 1278 | SUB DX,[command.fileStartSegment] | ||
| 1279 | MOV SI,DX | ||
| 1280 | XOR DI,DI | ||
| 1281 | CALL DISIX4 | ||
| 1282 | push ds | ||
| 1283 | MOV DS,[command.fileStartSegment] | ||
| 1284 | assume ds:nothing | ||
| 1285 | CALL READFILE | ||
| 1286 | pop ds | ||
| 1287 | assume ds:data | ||
| 1288 | JC CLSALLJ | ||
| 1289 | XOR DX,DX | ||
| 1290 | MOV CX,DX | ||
| 1291 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 1292 | INT 21H | ||
| 1293 | MOV WORD PTR [command.fileOffset],AX | ||
| 1294 | MOV WORD PTR [command.fileOffset+2],DX | ||
| 1295 | JMP FILESDONE | ||
| 1296 | |||
| 1297 | GOTCOM: | ||
| 1298 | OR BYTE PTR [FILSTAT],00100000B ; Got all of COMMAND | ||
| 1299 | push es | ||
| 1300 | LES SI,[command.fileSizeInBytes] | ||
| 1301 | MOV DI,ES | ||
| 1302 | pop es | ||
| 1303 | push ds | ||
| 1304 | MOV DS,[command.fileStartSegment] | ||
| 1305 | assume ds:nothing | ||
| 1306 | CALL READFILE | ||
| 1307 | pop ds | ||
| 1308 | assume ds:data | ||
| 1309 | JMP CLSALL | ||
| 1310 | |||
| 1311 | ;************************************************** | ||
| 1312 | ;Write BIOS DOS COMMAND to the newly formatted disk. | ||
| 1313 | |||
| 1314 | ASSUME DS:DATA | ||
| 1315 | WRITEDOS: | ||
| 1316 | MOV CX,BiosAttributes | ||
| 1317 | MOV DX,OFFSET BiosFile | ||
| 1318 | push es | ||
| 1319 | LES SI,[bios.fileSizeInBytes] | ||
| 1320 | MOV DI,ES | ||
| 1321 | pop es | ||
| 1322 | CALL MAKEFIL | ||
| 1323 | retc | ||
| 1324 | |||
| 1325 | MOV [TempHandle],BX | ||
| 1326 | TEST BYTE PTR FILSTAT,00000010B | ||
| 1327 | JNZ GOTALLBIO | ||
| 1328 | call Get_BIOS ; dcl 8/23/86 | ||
| 1329 | jnc Got_WBIOS ;mt 12/8/86 P894 | ||
| 1330 | ret | ||
| 1331 | |||
| 1332 | Got_WBIOS: | ||
| 1333 | |||
| 1334 | push es | ||
| 1335 | LES SI,[bios.fileOffset] | ||
| 1336 | MOV DI,ES | ||
| 1337 | pop es | ||
| 1338 | MOV WORD PTR [IOCNT],SI | ||
| 1339 | MOV WORD PTR [IOCNT+2],DI | ||
| 1340 | MOV BP,OFFSET bios | ||
| 1341 | CALL GOTTARG | ||
| 1342 | retc | ||
| 1343 | JMP SHORT BIOSDONE | ||
| 1344 | |||
| 1345 | GOTALLBIO: | ||
| 1346 | push es | ||
| 1347 | LES SI,[bios.fileSizeInBytes] | ||
| 1348 | MOV DI,ES | ||
| 1349 | pop es | ||
| 1350 | push ds | ||
| 1351 | MOV DS,[bios.fileStartSegment] | ||
| 1352 | assume ds:nothing | ||
| 1353 | CALL WRITEFILE | ||
| 1354 | pop ds | ||
| 1355 | assume ds:data | ||
| 1356 | BIOSDONE: | ||
| 1357 | MOV BX,[TempHandle] | ||
| 1358 | MOV CX,bios.fileTime | ||
| 1359 | MOV DX,bios.fileDate | ||
| 1360 | CALL CLOSETARG | ||
| 1361 | MOV CX,DosAttributes | ||
| 1362 | MOV DX,OFFSET DosFile | ||
| 1363 | push es | ||
| 1364 | LES SI,[dos.fileSizeInBytes] | ||
| 1365 | MOV DI,ES | ||
| 1366 | pop es | ||
| 1367 | CALL MAKEFIL | ||
| 1368 | retc | ||
| 1369 | |||
| 1370 | GOTNDOS: | ||
| 1371 | MOV [TempHandle],BX | ||
| 1372 | TEST BYTE PTR FILSTAT,00001000B | ||
| 1373 | JNZ GOTALLDOS | ||
| 1374 | call Get_DOS ; dcl 8/23/86 | ||
| 1375 | jnc Got_WDOS ;mt 12/8/86 P894 | ||
| 1376 | ret | ||
| 1377 | |||
| 1378 | Got_WDOS: | ||
| 1379 | MOV BP,OFFSET dos | ||
| 1380 | TEST BYTE PTR FILSTAT,00000100B | ||
| 1381 | JNZ PARTDOS | ||
| 1382 | MOV WORD PTR [dos.fileOffset],0 | ||
| 1383 | MOV WORD PTR [dos.fileOffset+2],0 | ||
| 1384 | CALL GETSYS3 | ||
| 1385 | retc | ||
| 1386 | JMP SHORT DOSDONE | ||
| 1387 | |||
| 1388 | PARTDOS: | ||
| 1389 | push es | ||
| 1390 | LES SI,[dos.fileOffset] | ||
| 1391 | MOV DI,ES | ||
| 1392 | pop es | ||
| 1393 | MOV WORD PTR [IOCNT],SI | ||
| 1394 | MOV WORD PTR [IOCNT+2],DI | ||
| 1395 | CALL GOTTARG | ||
| 1396 | retc | ||
| 1397 | JMP SHORT DOSDONE | ||
| 1398 | |||
| 1399 | GOTALLDOS: | ||
| 1400 | push es | ||
| 1401 | LES SI,[dos.fileSizeInBytes] | ||
| 1402 | MOV DI,ES | ||
| 1403 | pop es | ||
| 1404 | push ds | ||
| 1405 | MOV DS,[dos.fileStartSegment] | ||
| 1406 | assume ds:nothing | ||
| 1407 | CALL WRITEFILE | ||
| 1408 | pop ds | ||
| 1409 | assume ds:data | ||
| 1410 | DOSDONE: | ||
| 1411 | MOV BX,[TempHandle] | ||
| 1412 | MOV CX,dos.fileTime | ||
| 1413 | MOV DX,dos.fileDate | ||
| 1414 | CALL CLOSETARG | ||
| 1415 | MOV CX,CommandAttributes | ||
| 1416 | call Command_Root ;an011; dms;adjust path for | ||
| 1417 | ;COMMAND.COM creation | ||
| 1418 | MOV DX,OFFSET CommandFile | ||
| 1419 | push es | ||
| 1420 | LES SI,[command.fileSizeInBytes] | ||
| 1421 | MOV DI,ES | ||
| 1422 | pop es | ||
| 1423 | CALL MAKEFIL | ||
| 1424 | retc | ||
| 1425 | |||
| 1426 | MOV [TempHandle],BX | ||
| 1427 | TEST BYTE PTR FILSTAT,00100000B | ||
| 1428 | JNZ GOTALLCOM | ||
| 1429 | call Get_COMMAND ; dcl 8/23/86 | ||
| 1430 | jnc Got_WCOM ;mt 12/8/86 P894 | ||
| 1431 | ret | ||
| 1432 | |||
| 1433 | Got_WCOM: | ||
| 1434 | MOV BP,OFFSET command | ||
| 1435 | TEST BYTE PTR FILSTAT,00010000B | ||
| 1436 | JNZ PARTCOM | ||
| 1437 | MOV WORD PTR [command.fileOffset],0 | ||
| 1438 | MOV WORD PTR [command.fileOffset+2],0 | ||
| 1439 | CALL GETSYS3 | ||
| 1440 | retc | ||
| 1441 | JMP SHORT COMDONE | ||
| 1442 | |||
| 1443 | PARTCOM: | ||
| 1444 | push es | ||
| 1445 | LES SI,[command.fileOffset] | ||
| 1446 | MOV DI,ES | ||
| 1447 | pop es | ||
| 1448 | MOV WORD PTR [IOCNT],SI | ||
| 1449 | MOV WORD PTR [IOCNT+2],DI | ||
| 1450 | CALL GOTTARG | ||
| 1451 | retc | ||
| 1452 | JMP SHORT COMDONE | ||
| 1453 | |||
| 1454 | GOTALLCOM: | ||
| 1455 | push es | ||
| 1456 | LES SI,[command.fileSizeInBytes] | ||
| 1457 | MOV DI,ES | ||
| 1458 | pop es | ||
| 1459 | push ds | ||
| 1460 | MOV DS,[command.fileStartSegment] | ||
| 1461 | assume ds:nothing | ||
| 1462 | CALL WRITEFILE | ||
| 1463 | pop ds | ||
| 1464 | assume ds:data | ||
| 1465 | COMDONE: | ||
| 1466 | MOV BX,[TempHandle] | ||
| 1467 | MOV CX,command.fileTime | ||
| 1468 | MOV DX,command.fileDate | ||
| 1469 | CALL CLOSETARG | ||
| 1470 | ;**************************************************************** | ||
| 1471 | ; I don't see the need for the following code!! - RS 3.20 | ||
| 1472 | ; CMP BYTE PTR [FILSTAT],00101010B | ||
| 1473 | ; JZ NOREDOS | ||
| 1474 | ;RDFRST2: | ||
| 1475 | ; CALL READDOS ; Start back with BIOS | ||
| 1476 | ; JNC NOREDOS | ||
| 1477 | ; CALL SYSPRM ;Prompt for system disk | ||
| 1478 | ; JMP RDFRST2 ;Try again | ||
| 1479 | ;NOREDOS: | ||
| 1480 | ;**************************************************************** | ||
| 1481 | CLC | ||
| 1482 | return | ||
| 1483 | |||
| 1484 | ;********************************************* | ||
| 1485 | ; Create a file on target disk | ||
| 1486 | ; CX = attributes, DX points to name | ||
| 1487 | ; DI:SI is size file is to have | ||
| 1488 | ; | ||
| 1489 | ; There is a bug in DOS 2.00 and 2.01 having to do with writes | ||
| 1490 | ; from the end of memory. In order to circumvent it this routine | ||
| 1491 | ; must create files with the length in DI:SI | ||
| 1492 | ; | ||
| 1493 | ; On return BX is handle, carry set if problem | ||
| 1494 | |||
| 1495 | MAKEFIL: | ||
| 1496 | MOV BX,DX | ||
| 1497 | PUSH WORD PTR [BX] | ||
| 1498 | MOV AL,DriveLetter | ||
| 1499 | MOV [BX],AL | ||
| 1500 | MOV AH,CREAT | ||
| 1501 | INT 21H | ||
| 1502 | POP WORD PTR [BX] | ||
| 1503 | MOV BX,AX | ||
| 1504 | JC CheckMany | ||
| 1505 | MOV CX,DI | ||
| 1506 | MOV DX,SI | ||
| 1507 | MOV AX,LSEEK SHL 8 | ||
| 1508 | INT 21H ; Seek to eventual EOF | ||
| 1509 | XOR CX,CX | ||
| 1510 | MOV AH,WRITE | ||
| 1511 | INT 21H ; Set size of file to position | ||
| 1512 | XOR CX,CX | ||
| 1513 | MOV DX,CX | ||
| 1514 | MOV AX,LSEEK SHL 8 | ||
| 1515 | INT 21H ; Seek back to start | ||
| 1516 | return | ||
| 1517 | |||
| 1518 | ; | ||
| 1519 | ; Examine error code in AX to see if it is too-many-open-files. | ||
| 1520 | ; If it is, we abort right here. Otherwise we return. | ||
| 1521 | ; | ||
| 1522 | CheckMany: | ||
| 1523 | CMP AX,error_too_many_open_files | ||
| 1524 | retnz | ||
| 1525 | Extended_Message ; ;AC006; | ||
| 1526 | JMP FEXIT | ||
| 1527 | |||
| 1528 | ;********************************************* | ||
| 1529 | ; Close a file on the target disk | ||
| 1530 | ; CX/DX is time/date, BX is handle | ||
| 1531 | |||
| 1532 | CLOSETARG: | ||
| 1533 | MOV AX,(FILE_TIMES SHL 8) OR 1 | ||
| 1534 | INT 21H | ||
| 1535 | MOV AH,CLOSE | ||
| 1536 | INT 21H | ||
| 1537 | return | ||
| 1538 | |||
| 1539 | ;**************************************** | ||
| 1540 | ; Transfer system files | ||
| 1541 | ; BP points to data structure for file involved | ||
| 1542 | ; offset is set to current amount read in | ||
| 1543 | ; Start set to start of file in buffer | ||
| 1544 | ; TempHandle is handle to write to on target | ||
| 1545 | |||
| 1546 | IOLOOP: | ||
| 1547 | MOV AL,[systemDriveLetter] | ||
| 1548 | CMP AL,[DriveLetter] | ||
| 1549 | JNZ GOTTARG | ||
| 1550 | MOV AH,DISK_RESET | ||
| 1551 | INT 21H | ||
| 1552 | CALL TARGPRM ;Get target disk | ||
| 1553 | |||
| 1554 | GOTTARG: | ||
| 1555 | ASSUME DS:DATA | ||
| 1556 | ;Enter here if some of file is already in buffer, IOCNT must be set | ||
| 1557 | ; to size already in buffer. | ||
| 1558 | MOV BX,[TempHandle] | ||
| 1559 | MOV SI,WORD PTR [IOCNT] | ||
| 1560 | MOV DI,WORD PTR [IOCNT+2] | ||
| 1561 | push ds | ||
| 1562 | MOV DS,ds:[BP.fileStartSegment] | ||
| 1563 | assume ds:nothing | ||
| 1564 | CALL WRITEFILE ; Write next part | ||
| 1565 | pop ds | ||
| 1566 | assume ds:data | ||
| 1567 | retc | ||
| 1568 | |||
| 1569 | push es | ||
| 1570 | LES AX,ds:[BP.fileOffset] | ||
| 1571 | CMP AX,WORD PTR ds:[BP.fileSizeInBytes] | ||
| 1572 | JNZ GETSYS3 | ||
| 1573 | MOV AX,ES | ||
| 1574 | CMP AX,WORD PTR ds:[BP.fileSizeInBytes+2] | ||
| 1575 | JNZ GETSYS3 | ||
| 1576 | pop es | ||
| 1577 | return ; Carry clear from CMP | ||
| 1578 | |||
| 1579 | GETSYS3: | ||
| 1580 | ;Enter here if none of file is in buffer | ||
| 1581 | pop es | ||
| 1582 | MOV AH,DISK_RESET | ||
| 1583 | INT 21H | ||
| 1584 | MOV AX,[MSTART] ;Furthur IO done starting here | ||
| 1585 | MOV ds:[BP.fileStartSegment],AX ;point to start of buffer | ||
| 1586 | MOV AL,[systemDriveLetter] ;see if we have system disk | ||
| 1587 | CMP AL,[DriveLetter] | ||
| 1588 | JNZ TESTSYS | ||
| 1589 | GSYS: | ||
| 1590 | MOV AH,DISK_RESET | ||
| 1591 | INT 21H | ||
| 1592 | CALL SYSPRM ;Prompt for system disk | ||
| 1593 | TESTSYS: | ||
| 1594 | ; CALL TESTSYSDISK ; dcl 8/23/86 | ||
| 1595 | JC GSYS | ||
| 1596 | MOV BX,word ptr DS:[BP.fileHandle] ; CS over ARR 2.30 | ||
| 1597 | push es | ||
| 1598 | LES DX,dword ptr DS:[BP.fileOffset] ; CS over ARR 2.30 | ||
| 1599 | MOV CX,ES | ||
| 1600 | pop es | ||
| 1601 | PUSH DX | ||
| 1602 | MOV AX,LSEEK SHL 8 | ||
| 1603 | INT 21H | ||
| 1604 | POP DX | ||
| 1605 | push es | ||
| 1606 | LES SI,dword ptr DS:[BP.fileSizeInBytes] ; CS over ARR 2.30 | ||
| 1607 | MOV DI,ES ;put high word in di | ||
| 1608 | pop es | ||
| 1609 | SUB SI,DX ;get low word value | ||
| 1610 | SBB DI,CX ; DI:SI is #bytes to go | ||
| 1611 | PUSH DI | ||
| 1612 | PUSH SI | ||
| 1613 | ADD SI,15 ;round up 1 para | ||
| 1614 | ADC DI,0 ;pick up carry | ||
| 1615 | CALL DISID4 ;div 16 to get para count | ||
| 1616 | MOV AX,SI ;put para count in ax | ||
| 1617 | POP SI ;restore bytes remaining | ||
| 1618 | POP DI ;restore bytes remaining | ||
| 1619 | CMP AX,[MSIZE] ;enough memory to read remainder? | ||
| 1620 | JBE GOTSIZ2 ;yes | ||
| 1621 | MOV SI,[MSIZE] | ||
| 1622 | XOR DI,DI | ||
| 1623 | CALL DISIX4 | ||
| 1624 | GOTSIZ2: | ||
| 1625 | MOV WORD PTR [IOCNT],SI ;save byte count for read | ||
| 1626 | MOV WORD PTR [IOCNT+2],DI | ||
| 1627 | push ds | ||
| 1628 | MOV DS,[MSTART] | ||
| 1629 | assume ds:nothing | ||
| 1630 | CALL READFILE | ||
| 1631 | pop ds | ||
| 1632 | assume ds:data | ||
| 1633 | JNC GETOFFS | ||
| 1634 | CALL CLSALL | ||
| 1635 | JMP GSYS | ||
| 1636 | GETOFFS: | ||
| 1637 | XOR DX,DX ;clear dx | ||
| 1638 | MOV CX,DX ;clear cx | ||
| 1639 | MOV AX,(LSEEK SHL 8) OR 1 | ||
| 1640 | INT 21H | ||
| 1641 | MOV WORD PTR DS:[BP.fileOffset],AX ; CS over ARR 2.30 | ||
| 1642 | MOV WORD PTR DS:[BP.fileOffset+2],DX ; CS over ARR 2.30 | ||
| 1643 | ;;;;;; CALL CLSALL | ||
| 1644 | JMP IOLOOP | ||
| 1645 | |||
| 1646 | ;************************************************* | ||
| 1647 | ; Test to see if correct system disk. Open handles | ||
| 1648 | |||
| 1649 | CRET12: | ||
| 1650 | STC | ||
| 1651 | return | ||
| 1652 | |||
| 1653 | ;TESTSYSDISK: ; dcl 8/23/86 | ||
| 1654 | Get_BIOS: ; dcl 8/23/86 | ||
| 1655 | MOV AX,OPEN SHL 8 | ||
| 1656 | MOV DX,OFFSET BiosFile | ||
| 1657 | INT 21H | ||
| 1658 | JNC SETBIOS | ||
| 1659 | ; call CheckMany ; dcl 8/23/86 | ||
| 1660 | jmp CheckMany ; dcl 8/23/86 | ||
| 1661 | |||
| 1662 | SETBIOS: | ||
| 1663 | MOV [Bios.fileHandle],AX | ||
| 1664 | MOV BX,AX | ||
| 1665 | CALL GETFSIZ | ||
| 1666 | CMP [bios.fileSizeInParagraphs],0 | ||
| 1667 | JZ SETBIOSSIZ | ||
| 1668 | CMP [bios.fileSizeInParagraphs],AX | ||
| 1669 | JZ SETBIOSSIZ | ||
| 1670 | BIOSCLS: | ||
| 1671 | MOV AH,CLOSE | ||
| 1672 | MOV BX,[Bios.fileHandle] | ||
| 1673 | INT 21H | ||
| 1674 | ; JMP CRET12 ; dcl 8/23/86 | ||
| 1675 | ret | ||
| 1676 | |||
| 1677 | SETBIOSSIZ: | ||
| 1678 | MOV [bios.fileSizeInParagraphs],AX | ||
| 1679 | MOV WORD PTR [bios.fileSizeInBytes],SI | ||
| 1680 | MOV WORD PTR [bios.fileSizeInBytes+2],DI | ||
| 1681 | MOV [bios.fileDate],DX | ||
| 1682 | MOV [bios.fileTime],CX | ||
| 1683 | clc | ||
| 1684 | ret ; dcl 8/23/86 | ||
| 1685 | |||
| 1686 | Get_DOS: ; dcl 8/23/86 | ||
| 1687 | MOV AX,OPEN SHL 8 | ||
| 1688 | MOV DX,OFFSET DosFile | ||
| 1689 | INT 21H | ||
| 1690 | JNC DOSOPNOK | ||
| 1691 | ; call CheckMany ; dcl 8/23/86 | ||
| 1692 | ; JMP BIOSCLS ; dcl 8/23/86 Checkmany no ret. | ||
| 1693 | jmp CheckMany ; dcl 8/23/86 | ||
| 1694 | |||
| 1695 | DOSOPNOK: | ||
| 1696 | MOV [dos.fileHandle],AX | ||
| 1697 | MOV BX,AX | ||
| 1698 | CALL GETFSIZ | ||
| 1699 | CMP [dos.fileSizeInParagraphs],0 | ||
| 1700 | JZ SETDOSSIZ | ||
| 1701 | CMP [dos.fileSizeInParagraphs],AX | ||
| 1702 | JZ SETDOSSIZ | ||
| 1703 | |||
| 1704 | DOSCLS: | ||
| 1705 | MOV AH,CLOSE | ||
| 1706 | MOV BX,[dos.fileHandle] | ||
| 1707 | INT 21H | ||
| 1708 | ; JMP BIOSCLS ; dcl 8/23/86 | ||
| 1709 | ret ; dcl 8/23/86 | ||
| 1710 | |||
| 1711 | SETDOSSIZ: | ||
| 1712 | MOV [dos.fileSizeInParagraphs],AX | ||
| 1713 | MOV WORD PTR [dos.fileSizeInBytes],SI | ||
| 1714 | MOV WORD PTR [dos.fileSizeInBytes+2],DI | ||
| 1715 | MOV [dos.fileDate],DX | ||
| 1716 | MOV [dos.fileTime],CX | ||
| 1717 | clc | ||
| 1718 | ret ; dcl 8/23/86 | ||
| 1719 | |||
| 1720 | |||
| 1721 | |||
| 1722 | Get_COMMAND: | ||
| 1723 | MOV AX,OPEN SHL 8 | ||
| 1724 | MOV DX,OFFSET CommandFile | ||
| 1725 | INT 21H | ||
| 1726 | JNC GotComHand | ||
| 1727 | ; call CheckMany ; dcl 8/23/86 | ||
| 1728 | ; JMP DosCls ; dcl 8/23/86 | ||
| 1729 | jmp Checkmany ; dcl 8/23/86 | ||
| 1730 | |||
| 1731 | GotComHand: | ||
| 1732 | MOV [command.fileHandle],AX | ||
| 1733 | MOV BX,AX | ||
| 1734 | CALL GETFSIZ | ||
| 1735 | CMP [command.fileSizeInParagraphs],0 | ||
| 1736 | JZ SETCOMSIZ | ||
| 1737 | CMP [command.fileSizeInParagraphs],AX | ||
| 1738 | JZ SETCOMSIZ | ||
| 1739 | COMCLS: | ||
| 1740 | MOV AH,CLOSE | ||
| 1741 | MOV BX,[command.fileHandle] | ||
| 1742 | INT 21H | ||
| 1743 | ; JMP DOSCLS ; dcl 8/23/86 | ||
| 1744 | ret ; dcl 8/23/86 | ||
| 1745 | |||
| 1746 | SETCOMSIZ: | ||
| 1747 | MOV [command.fileSizeInParagraphs],AX | ||
| 1748 | MOV WORD PTR [command.fileSizeInBytes],SI | ||
| 1749 | MOV WORD PTR [command.fileSizeInBytes+2],DI | ||
| 1750 | MOV [command.fileDate],DX | ||
| 1751 | MOV [command.fileTime],CX | ||
| 1752 | CLC | ||
| 1753 | return | ||
| 1754 | |||
| 1755 | FILE_CLS: ; dcl 8/23/86 | ||
| 1756 | MOV AH,CLOSE ; dcl 8/23/86 | ||
| 1757 | INT 21H ; dcl 8/23/86 | ||
| 1758 | ret ; dcl 8/23/86 | ||
| 1759 | |||
| 1760 | ;******************************************* | ||
| 1761 | ; Handle in BX, return file size in para in AX | ||
| 1762 | ; File size in bytes DI:SI, file date in DX, file | ||
| 1763 | ; time in CX. | ||
| 1764 | |||
| 1765 | GETFSIZ: | ||
| 1766 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 1767 | XOR CX,CX | ||
| 1768 | MOV DX,CX | ||
| 1769 | INT 21H | ||
| 1770 | MOV SI,AX | ||
| 1771 | MOV DI,DX | ||
| 1772 | ADD AX,15 ; Para round up | ||
| 1773 | ADC DX,0 | ||
| 1774 | AND DX,0FH ; If the file is larger than this it | ||
| 1775 | ; is bigger than the 8086 address | ||
| 1776 | ; space! | ||
| 1777 | MOV CL,12 | ||
| 1778 | SHL DX,CL | ||
| 1779 | MOV CL,4 | ||
| 1780 | SHR AX,CL | ||
| 1781 | OR AX,DX | ||
| 1782 | PUSH AX | ||
| 1783 | MOV AX,LSEEK SHL 8 | ||
| 1784 | XOR CX,CX | ||
| 1785 | MOV DX,CX | ||
| 1786 | INT 21H | ||
| 1787 | MOV AX,FILE_TIMES SHL 8 | ||
| 1788 | INT 21H | ||
| 1789 | POP AX | ||
| 1790 | return | ||
| 1791 | |||
| 1792 | ;******************************************** | ||
| 1793 | ; Read/Write file | ||
| 1794 | ; DS:0 is Xaddr | ||
| 1795 | ; DI:SI is byte count to I/O | ||
| 1796 | ; BX is handle | ||
| 1797 | ; Carry set if screw up | ||
| 1798 | ; | ||
| 1799 | ; I/O SI bytes | ||
| 1800 | ; I/O 64K - 1 bytes DI times | ||
| 1801 | ; I/O DI bytes | ||
| 1802 | |||
| 1803 | |||
| 1804 | READFILE: | ||
| 1805 | ; Must preserve AX,DX | ||
| 1806 | PUSH AX | ||
| 1807 | PUSH DX | ||
| 1808 | PUSH BP | ||
| 1809 | MOV BP,READ SHL 8 | ||
| 1810 | CALL FILIO | ||
| 1811 | POP BP | ||
| 1812 | POP DX | ||
| 1813 | POP AX | ||
| 1814 | return | ||
| 1815 | |||
| 1816 | WRITEFILE: | ||
| 1817 | PUSH BP | ||
| 1818 | MOV BP,WRITE SHL 8 | ||
| 1819 | CALL FILIO | ||
| 1820 | POP BP | ||
| 1821 | return | ||
| 1822 | |||
| 1823 | FILIO: | ||
| 1824 | XOR DX,DX | ||
| 1825 | MOV CX,SI | ||
| 1826 | JCXZ K64IO | ||
| 1827 | MOV AX,BP | ||
| 1828 | INT 21H | ||
| 1829 | retc | ||
| 1830 | ADD DX,AX | ||
| 1831 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1832 | retnz | ||
| 1833 | CALL NORMALIZE | ||
| 1834 | K64IO: | ||
| 1835 | CLC | ||
| 1836 | MOV CX,DI | ||
| 1837 | JCXZ IORET | ||
| 1838 | MOV AX,BP | ||
| 1839 | INT 21H | ||
| 1840 | retc | ||
| 1841 | ADD DX,AX | ||
| 1842 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1843 | retnz | ||
| 1844 | CALL NORMALIZE | ||
| 1845 | MOV CX,DI | ||
| 1846 | K64M1: | ||
| 1847 | PUSH CX | ||
| 1848 | XOR AX,AX | ||
| 1849 | OR DX,DX | ||
| 1850 | JZ NORMIO | ||
| 1851 | MOV CX,10H | ||
| 1852 | SUB CX,DX | ||
| 1853 | MOV AX,BP | ||
| 1854 | INT 21H | ||
| 1855 | JC IORETP | ||
| 1856 | ADD DX,AX | ||
| 1857 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1858 | JNZ IORETP | ||
| 1859 | CALL NORMALIZE | ||
| 1860 | NORMIO: | ||
| 1861 | MOV CX,0FFFFH | ||
| 1862 | SUB CX,AX | ||
| 1863 | MOV AX,BP | ||
| 1864 | INT 21H | ||
| 1865 | JC IORETP | ||
| 1866 | ADD DX,AX | ||
| 1867 | CMP AX,CX ; If not =, AX<CX, carry set. | ||
| 1868 | JNZ IORETP | ||
| 1869 | CALL NORMALIZE ; Clears carry | ||
| 1870 | POP CX | ||
| 1871 | LOOP K64M1 | ||
| 1872 | PUSH CX | ||
| 1873 | IORETP: | ||
| 1874 | POP CX | ||
| 1875 | IORET: | ||
| 1876 | return | ||
| 1877 | |||
| 1878 | |||
| 1879 | ;********************************* | ||
| 1880 | ; Shift DI:SI left 4 bits | ||
| 1881 | DISIX4: | ||
| 1882 | MOV CX,4 | ||
| 1883 | SH32: | ||
| 1884 | SHL SI,1 | ||
| 1885 | RCL DI,1 | ||
| 1886 | LOOP SH32 | ||
| 1887 | return | ||
| 1888 | |||
| 1889 | ;********************************* | ||
| 1890 | ; Shift DI:SI right 4 bits | ||
| 1891 | DISID4: | ||
| 1892 | MOV CX,4 | ||
| 1893 | SH32B: | ||
| 1894 | SHR DI,1 | ||
| 1895 | RCR SI,1 | ||
| 1896 | LOOP SH32B | ||
| 1897 | return | ||
| 1898 | |||
| 1899 | ;******************************** | ||
| 1900 | ; Normalize DS:DX | ||
| 1901 | |||
| 1902 | NORMALIZE: | ||
| 1903 | PUSH DX | ||
| 1904 | PUSH AX | ||
| 1905 | SHR DX,1 | ||
| 1906 | SHR DX,1 | ||
| 1907 | SHR DX,1 | ||
| 1908 | SHR DX,1 | ||
| 1909 | MOV AX,DS | ||
| 1910 | ADD AX,DX | ||
| 1911 | MOV DS,AX | ||
| 1912 | POP AX | ||
| 1913 | POP DX | ||
| 1914 | AND DX,0FH ; Clears carry | ||
| 1915 | return | ||
| 1916 | |||
| 1917 | ;------------------------------------------------------------------------------- | ||
| 1918 | ; Phase1Initialisation: | ||
| 1919 | ; This routine MUST set up fatSpace, and fBigFat | ||
| 1920 | ; It also does most of the other initialisation | ||
| 1921 | ; | ||
| 1922 | ; Algorithm: | ||
| 1923 | ; Open a handle for accessing the drive | ||
| 1924 | ; Get device parameters | ||
| 1925 | ; save device parameters for exit | ||
| 1926 | ; Check switches against parameters | ||
| 1927 | ; Use switches to modify device parameters | ||
| 1928 | ; directorySector = malloc( Bytes Per Sector ) | ||
| 1929 | ; fatSpace = malloc( Bytes Per Sector * Sectors Per Fat ) | ||
| 1930 | ; Calculate start sector (first sector not used by DOS) | ||
| 1931 | ; fBigFat = (((Total Sectors - StartSector)/Sectors Per Cluster) >= 4086) | ||
| 1932 | ; | ||
| 1933 | Phase1Initialisation proc near | ||
| 1934 | |||
| 1935 | ; Get device parameters | ||
| 1936 | lea dx, deviceParameters | ||
| 1937 | mov deviceParameters.DP_SpecialFunctions, 0 | ||
| 1938 | call GetDeviceParameters | ||
| 1939 | jnc GotDeviceParameters | ||
| 1940 | Message msgFormatNotSupported ; ;AC000; | ||
| 1941 | ;lea dx, ptr_msgFormatNotSupported | ||
| 1942 | ;call std_printf | ||
| 1943 | jmp fexit | ||
| 1944 | GotDeviceParameters: | ||
| 1945 | |||
| 1946 | ; Save the device parameters for when we exit | ||
| 1947 | lea si, deviceParameters | ||
| 1948 | lea di, savedDeviceParameters | ||
| 1949 | mov cx, size a_DeviceParameters | ||
| 1950 | push ds | ||
| 1951 | pop es | ||
| 1952 | rep movsb | ||
| 1953 | |||
| 1954 | ; Ensure that there is a valid number of sectors in the track table | ||
| 1955 | mov savedDeviceParameters.DP_TrackTableEntries, 0 | ||
| 1956 | mov validSavedDeviceParameters, 1 | ||
| 1957 | |||
| 1958 | ; Initialise this to zero to know if CheckSwitches defined the track layout | ||
| 1959 | mov deviceParameters.DP_TrackTableEntries, 0 | ||
| 1960 | |||
| 1961 | call Set_BPB_Info ;an000; dms; Check to see if we are on | ||
| 1962 | ; FAT system. If not set BPB to proper | ||
| 1963 | ; values for format. | ||
| 1964 | SetMTsupp: | ||
| 1965 | |||
| 1966 | ; Check switches against parameters and use switches to modify device parameters | ||
| 1967 | call CheckSwitches | ||
| 1968 | retc | ||
| 1969 | |||
| 1970 | IF ShipDisk | ||
| 1971 | |||
| 1972 | test SwitchMap,Switch_Z ;an000; dms;1 sector/cluster disk? | ||
| 1973 | ; $if nz ;an000; dms;yes | ||
| 1974 | JZ $$IF19 | ||
| 1975 | mov DeviceParameters.DP_BPB.BPB_SectorsPerCluster,01h ;an000; dms;set BPB accordingly | ||
| 1976 | call Calc_Small_Fat ;an000; dms;calc FAT size | ||
| 1977 | ; $endif ;an000; dms; | ||
| 1978 | $$IF19: | ||
| 1979 | |||
| 1980 | ENDIF | ||
| 1981 | |||
| 1982 | |||
| 1983 | cmp deviceParameters.DP_TrackTableEntries, 0 | ||
| 1984 | jne TrackLayoutSet ; There is a good track layout | ||
| 1985 | |||
| 1986 | ; Store sector table info | ||
| 1987 | mov cx, deviceParameters.DP_BPB.BPB_SectorsPerTrack | ||
| 1988 | mov deviceParameters.DP_TrackTableEntries, cx | ||
| 1989 | mov ax, 1 | ||
| 1990 | mov bx, deviceParameters.DP_BPB.BPB_bytesPerSector | ||
| 1991 | lea di, deviceParameters.DP_SectorTable | ||
| 1992 | LoadSectorTable: | ||
| 1993 | stosw | ||
| 1994 | xchg ax, bx | ||
| 1995 | stosw | ||
| 1996 | xchg ax, bx | ||
| 1997 | inc ax | ||
| 1998 | loop LoadSectorTable | ||
| 1999 | TrackLayoutSet: | ||
| 2000 | |||
| 2001 | ; | ||
| 2002 | ; directorySector = malloc( Bytes Per Sector ) | ||
| 2003 | ; | ||
| 2004 | mov bx, deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 2005 | add bx, 0fH | ||
| 2006 | shr bx, 1 | ||
| 2007 | shr bx, 1 | ||
| 2008 | shr bx, 1 | ||
| 2009 | shr bx, 1 | ||
| 2010 | mov ah, Alloc | ||
| 2011 | int 21H | ||
| 2012 | retc | ||
| 2013 | mov word ptr directorySector+2, ax | ||
| 2014 | xor ax,ax | ||
| 2015 | mov word ptr directorySector, ax | ||
| 2016 | |||
| 2017 | ; | ||
| 2018 | ; fatSpace = malloc( Bytes Per Sector * Sectors Per FAT ) | ||
| 2019 | ; | ||
| 2020 | mov ax, deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 2021 | add ax, 0fH | ||
| 2022 | shr ax, 1 | ||
| 2023 | shr ax, 1 | ||
| 2024 | shr ax, 1 | ||
| 2025 | shr ax, 1 | ||
| 2026 | mul deviceParameters.DP_BPB.BPB_SectorsPerFAT | ||
| 2027 | mov Paras_Per_Fat,ax ;AN005;128k FAT | ||
| 2028 | mov bx,ax | ||
| 2029 | mov ah,Alloc | ||
| 2030 | int 21H | ||
| 2031 | retc | ||
| 2032 | mov word ptr fatSpace+2,ax | ||
| 2033 | xor ax,ax | ||
| 2034 | mov word ptr fatSpace,ax | ||
| 2035 | |||
| 2036 | call SetStartSector | ||
| 2037 | call SetfBigFat | ||
| 2038 | |||
| 2039 | clc | ||
| 2040 | return | ||
| 2041 | |||
| 2042 | Phase1Initialisation endp | ||
| 2043 | |||
| 2044 | ;------------------------------------------------------------------------------- | ||
| 2045 | |||
| 2046 | SetStartSector proc near | ||
| 2047 | |||
| 2048 | ; startSector = number of reserved sectors | ||
| 2049 | ; + number of FAT Sectors ( Number of FATS * Sectors Per FAT ) | ||
| 2050 | ; + number of directory sectors ( 32* Root Entries / bytes Per Sector ) | ||
| 2051 | ; ( above is rounded up ) | ||
| 2052 | |||
| 2053 | ; Calculate the number of directory sectors | ||
| 2054 | mov ax, deviceParameters.DP_BPB.BPB_RootEntries | ||
| 2055 | mov bx, size dir_entry | ||
| 2056 | mul bx | ||
| 2057 | add ax, deviceParameters.DP_BPB.BPB_bytesPerSector | ||
| 2058 | dec ax | ||
| 2059 | xor dx,dx | ||
| 2060 | div deviceParameters.DP_BPB.BPB_bytesPerSector | ||
| 2061 | mov sectorsInRootDirectory,ax | ||
| 2062 | mov startSector, ax | ||
| 2063 | |||
| 2064 | ; Calculate the number of FAT sectors | ||
| 2065 | mov ax, deviceParameters.DP_BPB.BPB_SectorsPerFAT | ||
| 2066 | mul deviceParameters.DP_BPB.BPB_numberOfFATs | ||
| 2067 | ; Add in the number of boot sectors | ||
| 2068 | add ax, deviceParameters.DP_BPB.BPB_ReservedSectors | ||
| 2069 | add startSector, ax | ||
| 2070 | |||
| 2071 | return | ||
| 2072 | |||
| 2073 | SetStartSector endp | ||
| 2074 | |||
| 2075 | ;------------------------------------------------------------------------------- | ||
| 2076 | |||
| 2077 | SetfBigFat proc near | ||
| 2078 | ; | ||
| 2079 | ; fBigFat = ( ( (Total Sectors - Start Sector) / Sectors Per Cluster) >= 4086 ) | ||
| 2080 | ; | ||
| 2081 | cmp deviceParameters.DP_BPB.BPB_BigTotalSectors+2,0 ; > 32mb part? ;AN000; | ||
| 2082 | ; $IF NE ;Yes, big FAT ;AC000; | ||
| 2083 | JE $$IF21 | ||
| 2084 | mov fBigFat, TRUE ;Set flag ;AN000; | ||
| 2085 | ; $ELSE ;Nope, < 32,b ;AC000; | ||
| 2086 | JMP SHORT $$EN21 | ||
| 2087 | $$IF21: | ||
| 2088 | mov ax,deviceParameters.DP_BPB.BPB_BigTotalSectors ;Assume this used ;AN000; | ||
| 2089 | cmp ax,0 ;Was this field used? ;AN000; | ||
| 2090 | ; $IF E ;Nope, use the other sector field;AN000; | ||
| 2091 | JNE $$IF23 | ||
| 2092 | mov ax, deviceParameters.DP_BPB.BPB_TotalSectors ; ;AC000; | ||
| 2093 | ;** Fix for PTM PCDOS P51 | ||
| 2094 | ; $ENDIF ; ;AN000; | ||
| 2095 | $$IF23: | ||
| 2096 | sub ax,startSector ;Get sectors in data area | ||
| 2097 | xor dx,dx | ||
| 2098 | xor bx,bx | ||
| 2099 | mov bl,deviceParameters.DP_BPB.BPB_sectorsPerCluster | ||
| 2100 | div bx ;Get total clusters | ||
| 2101 | cmp ax,BIG_FAT_THRESHOLD ;Is clusters >= 4086? | ||
| 2102 | ; $IF AE | ||
| 2103 | JNAE $$IF25 | ||
| 2104 | mov fBigFAT,TRUE ;16 bit FAT if >=4096 | ||
| 2105 | ;** END fix for PTM PCDOS P51 | ||
| 2106 | ; $ENDIF | ||
| 2107 | $$IF25: | ||
| 2108 | ; $ENDIF | ||
| 2109 | $$EN21: | ||
| 2110 | return | ||
| 2111 | |||
| 2112 | SetfBigFat endp | ||
| 2113 | |||
| 2114 | ;------------------------------------------------------------------------------- | ||
| 2115 | ; | ||
| 2116 | ; Phase2Initialisation: | ||
| 2117 | ; Use device parameters to build information that will be | ||
| 2118 | ; required for each format | ||
| 2119 | ; | ||
| 2120 | ; Algorithm: | ||
| 2121 | ; Calculate first head/cylinder to format | ||
| 2122 | ; Calculate number of tracks to format | ||
| 2123 | ; Calculate the total bytes on the disk and save for later printout | ||
| 2124 | ; First initialise the directory buffer | ||
| 2125 | ; | ||
| 2126 | Phase2Initialisation proc near | ||
| 2127 | |||
| 2128 | ; Calculate first track/head to format (round up - kludge) | ||
| 2129 | mov ax, deviceParameters.DP_BPB.BPB_HiddenSectors | ||
| 2130 | mov dx, deviceParameters.DP_BPB.BPB_HiddenSectors + 2 | ||
| 2131 | add ax, deviceParameters.DP_BPB.BPB_SectorsPerTrack | ||
| 2132 | adc dx, 0 | ||
| 2133 | dec ax | ||
| 2134 | sbb dx, 0 | ||
| 2135 | div deviceParameters.DP_BPB.BPB_SectorsPerTrack | ||
| 2136 | xor dx,dx | ||
| 2137 | div deviceParameters.DP_BPB.BPB_Heads | ||
| 2138 | mov firstCylinder, ax | ||
| 2139 | mov firstHead, dx | ||
| 2140 | |||
| 2141 | ; Calculate the total number of tracks to be formatted (round down - kludge) | ||
| 2142 | mov ax, deviceParameters.DP_BPB.BPB_TotalSectors | ||
| 2143 | xor dx,dx | ||
| 2144 | ; if (TotalSectors == 0) then use BigTotalSectors | ||
| 2145 | or ax,ax | ||
| 2146 | jnz NotBigTotalSectors | ||
| 2147 | mov ax, deviceParameters.DP_BPB.BPB_BigTotalSectors | ||
| 2148 | mov dx, deviceParameters.DP_BPB.BPB_BigTotalSectors + 2 | ||
| 2149 | |||
| 2150 | NotBigTotalSectors: | ||
| 2151 | div deviceParameters.DP_BPB.BPB_SectorsPerTrack | ||
| 2152 | mov tracksPerDisk, ax | ||
| 2153 | |||
| 2154 | ; Initialise the directory buffer | ||
| 2155 | ; Clear out the Directory Sector before any information is inserted. | ||
| 2156 | mov cx, deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 2157 | les di, directorySector | ||
| 2158 | xor ax,ax | ||
| 2159 | rep stosb | ||
| 2160 | |||
| 2161 | mov ax, deviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 2162 | xor dx, dx | ||
| 2163 | mov bx, size dir_entry | ||
| 2164 | div bx | ||
| 2165 | mov cx, ax | ||
| 2166 | |||
| 2167 | les bx, directorySector | ||
| 2168 | ; If Old_Dir = TRUE then put the first letter of each directory entry must be 0E5H | ||
| 2169 | xor al, al | ||
| 2170 | cmp old_Dir, TRUE | ||
| 2171 | jne StickE5 | ||
| 2172 | mov al, 0e5H | ||
| 2173 | StickE5: | ||
| 2174 | mov es:[bx], al | ||
| 2175 | add bx, size dir_entry | ||
| 2176 | loop stickE5 | ||
| 2177 | |||
| 2178 | ret | ||
| 2179 | |||
| 2180 | Phase2Initialisation endp | ||
| 2181 | |||
| 2182 | ;------------------------------------------------------------------------------- | ||
| 2183 | ; | ||
| 2184 | ; SetDeviceParameters: | ||
| 2185 | ; Set the device parameters | ||
| 2186 | ; | ||
| 2187 | ; Input: | ||
| 2188 | ; drive | ||
| 2189 | ; dx - pointer to device parameters | ||
| 2190 | ; | ||
| 2191 | SetDeviceParameters proc near | ||
| 2192 | |||
| 2193 | mov ax, (IOCTL shl 8) or GENERIC_IOCTL | ||
| 2194 | mov bl, drive | ||
| 2195 | inc bl | ||
| 2196 | mov cx, (RAWIO shl 8) or SET_DEVICE_PARAMETERS | ||
| 2197 | int 21H | ||
| 2198 | return | ||
| 2199 | |||
| 2200 | SetDeviceParameters endp | ||
| 2201 | |||
| 2202 | ;------------------------------------------------------------------------------- | ||
| 2203 | ; | ||
| 2204 | ; GetDeviceParameters: | ||
| 2205 | ; Get the device parameters | ||
| 2206 | ; | ||
| 2207 | ; Input: | ||
| 2208 | ; drive | ||
| 2209 | ; dx - pointer to device parameters | ||
| 2210 | ; | ||
| 2211 | GetDeviceParameters proc near | ||
| 2212 | |||
| 2213 | mov ax, (IOCTL shl 8) or GENERIC_IOCTL | ||
| 2214 | mov bl, drive | ||
| 2215 | inc bl | ||
| 2216 | mov cx, (RAWIO shl 8) or GET_DEVICE_PARAMETERS | ||
| 2217 | int 21H | ||
| 2218 | return | ||
| 2219 | |||
| 2220 | GetDeviceParameters endp | ||
| 2221 | |||
| 2222 | ;------------------------------------------------------------------------------- | ||
| 2223 | ; | ||
| 2224 | ; DiskFormat: | ||
| 2225 | ; Format the tracks on the disk | ||
| 2226 | ; Since we do our SetDeviceParameters here, we also need to | ||
| 2227 | ; detect the legality of /N /T if present and abort with errors | ||
| 2228 | ; if not. | ||
| 2229 | ; This routine stops as soon as it encounters a bad track | ||
| 2230 | ; Then BadSector is called to report the bad track, and it continues | ||
| 2231 | ; the format | ||
| 2232 | ; | ||
| 2233 | ; Algorithm: | ||
| 2234 | ; Initialise in memory FAT | ||
| 2235 | ; current track = first | ||
| 2236 | ; while not done | ||
| 2237 | ; if format track fails | ||
| 2238 | ; DiskFormatErrors = true | ||
| 2239 | ; return | ||
| 2240 | ; next track | ||
| 2241 | |||
| 2242 | DiskFormat proc near | ||
| 2243 | |||
| 2244 | |||
| 2245 | ; | ||
| 2246 | ; Initialise fatSpace | ||
| 2247 | ; | ||
| 2248 | |||
| 2249 | |||
| 2250 | push es | ||
| 2251 | |||
| 2252 | call Fat_Init ;an000; initialize the FAT | ||
| 2253 | |||
| 2254 | mov di, word ptr fatspace+2 ;an000; get segment of FAT | ||
| 2255 | mov es, di ;an000; place it in es | ||
| 2256 | mov di, word ptr fatSpace ;Should be 0 | ||
| 2257 | mov al, deviceParameters.DP_BPB.BPB_MediaDescriptor | ||
| 2258 | mov ah, 0ffH | ||
| 2259 | stosw | ||
| 2260 | mov ax, 00ffH | ||
| 2261 | test fBigFat, TRUE | ||
| 2262 | jz NotBig | ||
| 2263 | mov ax, 0ffffH | ||
| 2264 | NotBig: stosw | ||
| 2265 | pop es | ||
| 2266 | |||
| 2267 | ; don't bother to do the formatting if /c was given | ||
| 2268 | test switchmap, SWITCH_C | ||
| 2269 | jz Keep_Going | ||
| 2270 | jmp FormatDone ;FormatDone is to far away | ||
| 2271 | |||
| 2272 | Keep_Going: | ||
| 2273 | foofoo = INSTALL_FAKE_BPB or TRACKLAYOUT_IS_GOOD | ||
| 2274 | mov deviceParameters.DP_SpecialFunctions, foofoo | ||
| 2275 | lea dx, deviceParameters | ||
| 2276 | |||
| 2277 | call SetDeviceParameters | ||
| 2278 | |||
| 2279 | call Cluster_Buffer_Allocate ;an000; dms;get room for retry buffer | ||
| 2280 | |||
| 2281 | call Prompt_User_For_Disk ;an016; dms; | ||
| 2282 | |||
| 2283 | test switchmap,switch_8 ; DCL 5/12/86 avoid Naples AH=18h | ||
| 2284 | jnz stdBpB ; lackof support for 8 sectors/track | ||
| 2285 | |||
| 2286 | ; DCL 5/12/86 | ||
| 2287 | ; Always do the STATUS_FOR_FORMAT test, as we don't know if the machine | ||
| 2288 | ; has this support. For 3.2 /N: & /T: were not documented & therefore | ||
| 2289 | ; not fully supported thru the ROM of Aquarius & Naples & Royal Palm | ||
| 2290 | |||
| 2291 | ;test SwitchMap, SWITCH_N or SWITCH_T ; IF ( /N or /T ) ;; DCL 5/12/86 | ||
| 2292 | ;jz StdBPB | ||
| 2293 | ; THEN check if | ||
| 2294 | ; supported | ||
| 2295 | mov formatPacket.FP_SpecialFunctions, STATUS_FOR_FORMAT | ||
| 2296 | mov ax, (IOCTL shl 8) or GENERIC_IOCTL | ||
| 2297 | mov bl, drive | ||
| 2298 | inc bl | ||
| 2299 | mov cx, (RAWIO shl 8) or FORMAT_TRACK | ||
| 2300 | lea dx, formatPacket | ||
| 2301 | int 21H | ||
| 2302 | ; switch ( FormatStatusCall) | ||
| 2303 | |||
| 2304 | ;cmp FormatPacket.FP_SpecialFunctions, Format_No_ROM_Support | ||
| 2305 | ;jb NTSupported ; 0 returned from IBMBIO | ||
| 2306 | ;ja IllegalComb ; 2 returned - ROM Support | ||
| 2307 | ; Illegal Combination! | ||
| 2308 | cmp FormatPacket.FP_SpecialFunctions,0 | ||
| 2309 | je NTSupported | ||
| 2310 | cmp FormatPacket.FP_SpecialFunctions,2 | ||
| 2311 | ; $IF E ; ;AC000; | ||
| 2312 | JNE $$IF28 | ||
| 2313 | Message msgInvalidParameter ; ;AC000; | ||
| 2314 | mov Fatal_Error,Yes ;Indicate quittin'type err! ;AN000; | ||
| 2315 | ; $ELSE ; ; ; | ||
| 2316 | JMP SHORT $$EN28 | ||
| 2317 | $$IF28: | ||
| 2318 | cmp FormatPacket.FP_SpecialFunctions,3 ; ; ; | ||
| 2319 | ; $IF E ; ;AC000; | ||
| 2320 | JNE $$IF30 | ||
| 2321 | mov ax,Error_Not_Ready ;flag not ready ;an000;dms; | ||
| 2322 | call CheckError ; set error level ;an017; dms; | ||
| 2323 | jmp FrmtProb ; exit program ;an017; dms; | ||
| 2324 | ; $ELSE ; DCL No ROM support is okay ; ; | ||
| 2325 | JMP SHORT $$EN30 | ||
| 2326 | $$IF30: | ||
| 2327 | ; except for /N: & /T: ; ; | ||
| 2328 | test SwitchMap, SWITCH_N or SWITCH_T ; DCL 5/12/86 ; ; | ||
| 2329 | ; $IF NZ ; ;AC000; | ||
| 2330 | JZ $$IF32 | ||
| 2331 | Message msgParametersNotSupported ; ;AC000; | ||
| 2332 | mov Fatal_Error,Yes ;Indicate quittin'type err! ;AN000; | ||
| 2333 | ; $ENDIF ; ;AN000; | ||
| 2334 | $$IF32: | ||
| 2335 | ; $ENDIF ; ;AN000; | ||
| 2336 | $$EN30: | ||
| 2337 | ; $ENDIF ; ;AN000; | ||
| 2338 | $$EN28: | ||
| 2339 | cmp Fatal_Error,Yes ; ;AN000; | ||
| 2340 | jne StdBPB ; ;AN000; | ||
| 2341 | jmp Fexit | ||
| 2342 | ; | ||
| 2343 | ; We have the support to carry out the FORMAT | ||
| 2344 | ; | ||
| 2345 | NTSupported: | ||
| 2346 | StdBPB: | ||
| 2347 | ;call DSKPRM ; prompt user for disk ;; DCL 5/12/86 | ||
| 2348 | mov FormatPacket.FP_SpecialFunctions, 0 | ||
| 2349 | mov ax, firstHead | ||
| 2350 | mov formatPacket.FP_Head, ax | ||
| 2351 | mov ax, firstCylinder | ||
| 2352 | mov formatPacket.FP_Cylinder, ax | ||
| 2353 | mov cx, tracksPerDisk | ||
| 2354 | mov tracksLeft, cx | ||
| 2355 | mov Format_End,False ;an015; dms;flag not at end of format | ||
| 2356 | call Calc_Max_Tracks_To_Format ;an015; dms;max track count for FormatTrack call | ||
| 2357 | FormatLoop: | ||
| 2358 | call Format_Loop ;an015; dms;Format until CY occurs | ||
| 2359 | |||
| 2360 | cmp Format_End,True ;an015; dms;End of Format? | ||
| 2361 | ; $if e ;an015; dms;yes | ||
| 2362 | JNE $$IF36 | ||
| 2363 | mov FormatError,0 ;an015; dms;signal good format | ||
| 2364 | clc ;an015; dms;clear CY | ||
| 2365 | ; $else ;an015; dms;bad format | ||
| 2366 | JMP SHORT $$EN36 | ||
| 2367 | $$IF36: | ||
| 2368 | call CheckError ;an015; dms;determine type of error | ||
| 2369 | ; $if nc ;an015; dms; | ||
| 2370 | JC $$IF38 | ||
| 2371 | call LastChanceToSaveIt ;an015; dms;acceptable error? | ||
| 2372 | ; $if c ;an015; dms;yes | ||
| 2373 | JNC $$IF39 | ||
| 2374 | mov FormatError,1 ;an015; dms;signal error type | ||
| 2375 | clc ;an015; dms;clear CY | ||
| 2376 | ; $else ;an015; dms;not acceptable error | ||
| 2377 | JMP SHORT $$EN39 | ||
| 2378 | $$IF39: | ||
| 2379 | call SetStartSector ;an015; dms;start from scratch | ||
| 2380 | call SetFBigFat ;an015; dms; | ||
| 2381 | push ax ;an015; dms; | ||
| 2382 | call Phase2Initialisation ;an015; dms; | ||
| 2383 | clc ;an015; dms; | ||
| 2384 | pop ax ;an015; dms; | ||
| 2385 | jmp DiskFormat ;an015; dms;try again | ||
| 2386 | ; $endif ;an015; dms; | ||
| 2387 | $$EN39: | ||
| 2388 | ; $endif ;an015; dms; | ||
| 2389 | $$IF38: | ||
| 2390 | ; $endif ;an015; dms; | ||
| 2391 | $$EN36: | ||
| 2392 | return | ||
| 2393 | |||
| 2394 | FormatDone: | ||
| 2395 | mov FormatError,0 | ||
| 2396 | clc | ||
| 2397 | return | ||
| 2398 | |||
| 2399 | DiskFormat endp | ||
| 2400 | |||
| 2401 | |||
| 2402 | ;------------------------------------------------------------------------------- | ||
| 2403 | ; | ||
| 2404 | ; BadSector: | ||
| 2405 | ; Reports the bad sectors. | ||
| 2406 | ; Reports the track where DiskFormat stopped. | ||
| 2407 | ; From then on it formats until it reaches a bad track, or end, | ||
| 2408 | ; and reports that. | ||
| 2409 | ; | ||
| 2410 | ; Output: | ||
| 2411 | ; Carry: set --> fatal error | ||
| 2412 | ; if Carry not set | ||
| 2413 | ; ax - The number of consecutive bad sectors encountered | ||
| 2414 | ; ax == 0 --> no more bad sectors | ||
| 2415 | ; bx - The logical sector number of the first bad sector | ||
| 2416 | ; | ||
| 2417 | ; Algorithm: | ||
| 2418 | ; if DiskFormatErrors | ||
| 2419 | ; DiskFormatErrors = false | ||
| 2420 | ; return current track | ||
| 2421 | ; else | ||
| 2422 | ; next track | ||
| 2423 | ; while not done | ||
| 2424 | ; if format track fails | ||
| 2425 | ; return current track | ||
| 2426 | ; next track | ||
| 2427 | ; return 0 | ||
| 2428 | |||
| 2429 | BadSector proc near | ||
| 2430 | |||
| 2431 | |||
| 2432 | ; don't bother to do the formatting if /c was given | ||
| 2433 | test switchmap, SWITCH_C | ||
| 2434 | jnz NoMoreTracks | ||
| 2435 | |||
| 2436 | test formatError, 0ffH | ||
| 2437 | jz ContinueFormat | ||
| 2438 | mov formatError, 0 | ||
| 2439 | jmp ReportBadTrack | ||
| 2440 | |||
| 2441 | ContinueFormat: | ||
| 2442 | call Adj_Track_Count ;an015; dms;decrease track counter | ||
| 2443 | call NextTrack ;an015; dms;adjust head and cylinder | ||
| 2444 | cmp Format_End,True ;an015; dms;end of format? | ||
| 2445 | ; $if ne ;an015; dms;no | ||
| 2446 | JE $$IF44 | ||
| 2447 | call Format_Loop ;an015; dms;format until CY | ||
| 2448 | cmp Format_End,True ;an015; dms;end of format? | ||
| 2449 | ; $if ne ;an015; dms;no | ||
| 2450 | JE $$IF45 | ||
| 2451 | call CheckError ;an015; dms;must be error - which error? | ||
| 2452 | ; $if nc ;an015; dms;non-fatal error? | ||
| 2453 | JC $$IF46 | ||
| 2454 | call CurrentLogicalSector ;an015; dms;yes - get position | ||
| 2455 | mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an015; dms; set track size | ||
| 2456 | clc ;an015; dms;signal O.K. to continue | ||
| 2457 | ; $endif ;an015; dms; | ||
| 2458 | $$IF46: | ||
| 2459 | ; $else ;an015; dms; | ||
| 2460 | JMP SHORT $$EN45 | ||
| 2461 | $$IF45: | ||
| 2462 | jmp NoMoreTracks ;an015; dms;end of format | ||
| 2463 | ; $endif ;an015; dms; | ||
| 2464 | $$EN45: | ||
| 2465 | ; $else ;an015; dms; | ||
| 2466 | JMP SHORT $$EN44 | ||
| 2467 | $$IF44: | ||
| 2468 | jmp NoMoreTracks ;an015; dms;end of format | ||
| 2469 | ; $endif ;an015; dms; | ||
| 2470 | $$EN44: | ||
| 2471 | return ;an015; dms; | ||
| 2472 | |||
| 2473 | ReportBadTrack: | ||
| 2474 | call CurrentLogicalSector | ||
| 2475 | mov ax, deviceParameters.DP_BPB.BPB_SectorsPerTrack | ||
| 2476 | clc | ||
| 2477 | return | ||
| 2478 | |||
| 2479 | NoMoreTracks: | ||
| 2480 | test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display done msg;AN000; | ||
| 2481 | ; $IF Z ; if EXEC'd by SELECT ;AN000; | ||
| 2482 | JNZ $$IF52 | ||
| 2483 | Message msgFormatComplete ; ;AC000; | ||
| 2484 | ; $ENDIF ; ;AN000; | ||
| 2485 | $$IF52: | ||
| 2486 | mov ax, 0 | ||
| 2487 | clc | ||
| 2488 | return | ||
| 2489 | |||
| 2490 | BadSector endp | ||
| 2491 | |||
| 2492 | |||
| 2493 | |||
| 2494 | ;------------------------------------------------------------------------------- | ||
| 2495 | |||
| 2496 | data segment public para 'DATA' | ||
| 2497 | |||
| 2498 | ;ptr_msgCurrentTrack dw offset msgCurrentTrack | ||
| 2499 | currentHead dw 0 | ||
| 2500 | currentCylinder dw 0 | ||
| 2501 | |||
| 2502 | data ends | ||
| 2503 | |||
| 2504 | ;========================================================================= | ||
| 2505 | ; Calc_Current_Head_Cyl : Obtain the current head and cylinder of the | ||
| 2506 | ; track being formatted. | ||
| 2507 | ; | ||
| 2508 | ; Inputs: FP_Cylinder - Cylinder of track being formatted | ||
| 2509 | ; FP_Head - Head of track being formatted | ||
| 2510 | ;========================================================================= | ||
| 2511 | |||
| 2512 | Procedure Calc_Current_Head_Cyl ;an000; dms; | ||
| 2513 | |||
| 2514 | push cx ;an000; dms;save cx | ||
| 2515 | mov cx,FormatPacket.FP_Cylinder ;an000; dms;get current cylinder | ||
| 2516 | mov CurrentCylinder,cx ;an000; dms;put into variable | ||
| 2517 | mov cx,FormatPacket.FP_Head ;an000; dms;get current head | ||
| 2518 | mov CurrentHead,cx ;an000; dms;put into variable | ||
| 2519 | pop cx ;an000; dms;restore cx | ||
| 2520 | ret ;an000; dms; | ||
| 2521 | |||
| 2522 | Calc_Current_Head_Cyl endp ;an000; dms; | ||
| 2523 | |||
| 2524 | |||
| 2525 | DisplayCurrentTrack proc near | ||
| 2526 | |||
| 2527 | push dx ; ;AN000; | ||
| 2528 | push cx ; ;AN000; | ||
| 2529 | push ax ;an015; dms; | ||
| 2530 | |||
| 2531 | mov ax,Tracks_To_Format ;an015; dms;get track count | ||
| 2532 | |||
| 2533 | add Formatted_Tracks_Low,ax ;Indicate formatted a track ;AN000; | ||
| 2534 | adc Formatted_Tracks_High,0 ; ;AN000; | ||
| 2535 | mov ax,Formatted_Tracks_Low ; ;AN000; | ||
| 2536 | mov bx,Formatted_Tracks_High ; ;AN000; | ||
| 2537 | mov cx,100 ;Make integer calc for div ;AN000; | ||
| 2538 | call Multiply_32_Bits ; BX:AX = (Cyl * Head *100) ;AN000; | ||
| 2539 | mov dx,bx ;Set up divide ;AN000; | ||
| 2540 | div TracksPerDisk ;% = (Cyl * Head *100)/ # tracks;AN000; | ||
| 2541 | cmp ax,PercentComplete ;Only print message when change ;AN000; | ||
| 2542 | ; $IF NE ;To avoid excess cursor splat ;AN000; | ||
| 2543 | JE $$IF54 | ||
| 2544 | mov PercentComplete,ax ;Save it if changed ;AN000; | ||
| 2545 | Message msgCurrentTrack ; ;AC000; | ||
| 2546 | ; $ENDIF ; | ||
| 2547 | $$IF54: | ||
| 2548 | pop ax ;an015; dms; | ||
| 2549 | pop cx ;Restore register ;AN000; | ||
| 2550 | pop dx ; ;AN000; | ||
| 2551 | return | ||
| 2552 | |||
| 2553 | DisplayCurrentTrack endp | ||
| 2554 | |||
| 2555 | |||
| 2556 | ;------------------------------------------------------------------------------- | ||
| 2557 | ; CheckError: | ||
| 2558 | ; Input: | ||
| 2559 | ; ax - extended error code | ||
| 2560 | ; Ouput: | ||
| 2561 | ; carry set if error is fatal | ||
| 2562 | ; Message printed if Not Ready or Write Protect | ||
| 2563 | ; | ||
| 2564 | CheckError proc near | ||
| 2565 | cmp ax, error_write_protect | ||
| 2566 | je WriteProtectError | ||
| 2567 | cmp ax, error_not_ready | ||
| 2568 | je NotReadyError | ||
| 2569 | cmp currentCylinder, 0 | ||
| 2570 | jne CheckRealErrors | ||
| 2571 | cmp currentHead, 0 | ||
| 2572 | je BadTrackZero | ||
| 2573 | |||
| 2574 | CheckRealErrors: | ||
| 2575 | cmp ax, error_CRC | ||
| 2576 | je JustABadTrack | ||
| 2577 | cmp ax, error_sector_not_found | ||
| 2578 | je JustABadTrack | ||
| 2579 | cmp ax, error_write_fault | ||
| 2580 | je JustABadTrack | ||
| 2581 | cmp ax, error_read_fault | ||
| 2582 | je JustABadTrack | ||
| 2583 | cmp ax, error_gen_failure | ||
| 2584 | je JustABadTrack | ||
| 2585 | |||
| 2586 | stc | ||
| 2587 | ret | ||
| 2588 | |||
| 2589 | JustABadTrack: | ||
| 2590 | clc | ||
| 2591 | ret | ||
| 2592 | |||
| 2593 | WriteProtectError: | ||
| 2594 | |||
| 2595 | test SwitchMap,Switch_SELECT ;an017; dms;SELECT option? | ||
| 2596 | ; $if z ;an017; dms;no - display messages | ||
| 2597 | JNZ $$IF56 | ||
| 2598 | Message msgCRLF ; ;AC006; | ||
| 2599 | Message msgCRLF ; ;AC006; | ||
| 2600 | Extended_Message ; ;AC006; | ||
| 2601 | ; $else ;an017; dms;yes - set error level | ||
| 2602 | JMP SHORT $$EN56 | ||
| 2603 | $$IF56: | ||
| 2604 | mov ExitStatus,ExitWriteProtect ;an017; dms;signal write protect error | ||
| 2605 | ; $endif ;an017; dms; | ||
| 2606 | $$EN56: | ||
| 2607 | |||
| 2608 | stc ;an017; dms;signal fatal error | ||
| 2609 | ret ;an017; dms;return to caller | ||
| 2610 | |||
| 2611 | NotReadyError: | ||
| 2612 | test SwitchMap,Switch_SELECT ;an017; dms; SELECT option? | ||
| 2613 | ; $if z ;an017; dms; no - display messages | ||
| 2614 | JNZ $$IF59 | ||
| 2615 | Message msgCRLF ; ;AC006; | ||
| 2616 | Message msgCRLF ; ;AC006; | ||
| 2617 | Extended_Message ; ;AC006; | ||
| 2618 | ; $else ;an017; dms;yes - set error level | ||
| 2619 | JMP SHORT $$EN59 | ||
| 2620 | $$IF59: | ||
| 2621 | mov ExitStatus,ExitDriveNotReady ;an017; dms;signal drive not ready | ||
| 2622 | ; $endif ;an017; dms; | ||
| 2623 | $$EN59: | ||
| 2624 | stc | ||
| 2625 | ret | ||
| 2626 | |||
| 2627 | |||
| 2628 | BadTrackZero: | ||
| 2629 | Message msgDiskUnusable ; ;AC000; | ||
| 2630 | stc | ||
| 2631 | ret | ||
| 2632 | |||
| 2633 | CheckError endp | ||
| 2634 | |||
| 2635 | ;------------------------------------------------------------------------------- | ||
| 2636 | ; WriteFileSystem: | ||
| 2637 | ; Write the boot sector and FATs out to disk | ||
| 2638 | ; Clear the directory sectors to zero | ||
| 2639 | ; | ||
| 2640 | |||
| 2641 | WriteFileSystem proc near | ||
| 2642 | |||
| 2643 | |||
| 2644 | call WriteBootSector | ||
| 2645 | retc | ||
| 2646 | |||
| 2647 | Set_Data_Segment ;Set DS,ES = DATA ;AN000; | ||
| 2648 | ; Write out each of the FATs | ||
| 2649 | push ds ;ac005; dms;save ds | ||
| 2650 | xor cx, cx | ||
| 2651 | mov cl, es:deviceParameters.DP_BPB.BPB_numberOfFATs ; ;AC000; | ||
| 2652 | mov dx, es:deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AC000; | ||
| 2653 | mov al, es:drive ; ;AC000; | ||
| 2654 | mov bx,word ptr es:FatSpace+2 ;Get segment of memory Fat ;AC000; | ||
| 2655 | mov ds,bx ; ;AN000; | ||
| 2656 | mov bx,word ptr es:FatSpace ; ;AN000; | ||
| 2657 | |||
| 2658 | mov si,bx ;ac005; dms;set up for add. calc | ||
| 2659 | call SEG_ADJ ;ac005; dms;get adjusted seg:off | ||
| 2660 | mov bx,si ;ac005; dms;get new off | ||
| 2661 | assume ds:nothing,es:data ; ;AN000; | ||
| 2662 | |||
| 2663 | ; $do ;ac005; dms;while FATS > 0 | ||
| 2664 | $$DO62: | ||
| 2665 | cmp cx,00 ;ac005; dms;FATS remaining? | ||
| 2666 | ; $leave e ;ac005; dms;no | ||
| 2667 | JE $$EN62 | ||
| 2668 | push bx ;ac005; dms;save FAT offset | ||
| 2669 | push ds ;ac005; dms;save FAT segment | ||
| 2670 | push cx ;ac005; dms;save FAT count | ||
| 2671 | push dx ;ac005; dms;reserved FAT sector | ||
| 2672 | call WRITE_FAT ;ac005; dms;write the FAT | ||
| 2673 | pop dx ;ac005; dms;get 1st. FAT sector | ||
| 2674 | pop cx ;ac005; dms;get FAT count | ||
| 2675 | pop ds ;ac005; dms;restore FAT segment | ||
| 2676 | pop bx ;ac005; dms;restore FAT offset | ||
| 2677 | ; $if c ;ac005; dms;an error occurred | ||
| 2678 | JNC $$IF64 | ||
| 2679 | Message msgFATwriteError;ac005; dms;say why failed | ||
| 2680 | jmp FEXIT ;ac005; dms;exit format | ||
| 2681 | ; $endif ;ac005; dms; | ||
| 2682 | $$IF64: | ||
| 2683 | add dx, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000; | ||
| 2684 | dec cx ;ac005; dms;decrease FAT count | ||
| 2685 | ; $enddo ;ac005; dms; | ||
| 2686 | JMP SHORT $$DO62 | ||
| 2687 | $$EN62: | ||
| 2688 | |||
| 2689 | pop ds ;ac005; dms;restore ds | ||
| 2690 | assume ds:data ;ac005; dms; | ||
| 2691 | |||
| 2692 | |||
| 2693 | ; Clear the directory | ||
| 2694 | |||
| 2695 | ; Now write the initialised directory sectors out to disk | ||
| 2696 | mov ax, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000; | ||
| 2697 | xor dx,dx | ||
| 2698 | push bx ;an000; dms;save bx | ||
| 2699 | xor bx,bx ;an000; dms;clear bx | ||
| 2700 | mov bl,es:DeviceParameters.DP_BPB.BPB_NumberOfFATs ;an000; dms;get FAT count | ||
| 2701 | mul bx ;an000; dms;get total FAT sectors | ||
| 2702 | pop bx ;an000; dms;restore bx | ||
| 2703 | |||
| 2704 | mov dx, es:deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AC000; | ||
| 2705 | add dx, ax | ||
| 2706 | mov cx, es:sectorsInRootDirectory ; ;AC000; | ||
| 2707 | WriteDIRloop: | ||
| 2708 | push cx | ||
| 2709 | push dx | ||
| 2710 | mov al, es:drive ; ;AC000; | ||
| 2711 | mov cx, 1 | ||
| 2712 | lds bx, es:directorySector ; ;AC000; | ||
| 2713 | |||
| 2714 | assume ds:nothing,es:data ; ;AN000; | ||
| 2715 | |||
| 2716 | ;Assume dir is alway contined in first 32mb of partition | ||
| 2717 | |||
| 2718 | mov es:Read_Write_Relative.Start_Sector_High,0 ; ;AC000; | ||
| 2719 | Call Write_Disk ; ;AN000; | ||
| 2720 | jnc Dir_OK ; ;AC000; | ||
| 2721 | Message msgDirectoryWriteError ; ;AC000; | ||
| 2722 | jmp FExit ; ;AN000; | ||
| 2723 | Dir_OK: ; ;AN000; | ||
| 2724 | pop dx | ||
| 2725 | add dx, 1 | ||
| 2726 | pop cx | ||
| 2727 | loop WriteDIRLoop | ||
| 2728 | |||
| 2729 | Set_Data_Segment ;Set DS to DATA segment ;AN000; | ||
| 2730 | ; Ok, we can tell the device driver that we are finished formatting | ||
| 2731 | mov savedDeviceParameters.DP_TrackTableEntries, 0 | ||
| 2732 | mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD | ||
| 2733 | lea dx, savedDeviceParameters | ||
| 2734 | call SetDeviceParameters | ||
| 2735 | |||
| 2736 | MOV AH,DISK_RESET ; Flush any directories in | ||
| 2737 | INT 21H ; buffers | ||
| 2738 | |||
| 2739 | return | ||
| 2740 | |||
| 2741 | |||
| 2742 | WriteFileSystem endp | ||
| 2743 | |||
| 2744 | ;========================================================================= | ||
| 2745 | ; WRITE_FAT : This routine writes the logical sector count requested. | ||
| 2746 | ; It will write a maximum of 40h sectors. If more | ||
| 2747 | ; than 40h exists it will continue looping until | ||
| 2748 | ; all sectors have been written. | ||
| 2749 | ; | ||
| 2750 | ; Inputs : AL - Drive letter | ||
| 2751 | ; DS:BX - Segment:offset of transfer address | ||
| 2752 | ; CX - Sector count | ||
| 2753 | ; DX - 1st. sector | ||
| 2754 | ; | ||
| 2755 | ; Outputs : Logical sectors written | ||
| 2756 | ;========================================================================= | ||
| 2757 | |||
| 2758 | procedure write_fat | ||
| 2759 | |||
| 2760 | mov cx, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000; | ||
| 2761 | |||
| 2762 | ; $do ;an000;while sectors left | ||
| 2763 | $$DO67: | ||
| 2764 | cmp cx,00h ;an000;any sectors? | ||
| 2765 | ; $leave e ;an000;no | ||
| 2766 | JE $$EN67 | ||
| 2767 | |||
| 2768 | cmp cx,40h | ||
| 2769 | ; $if a ;an000;yes | ||
| 2770 | JNA $$IF69 | ||
| 2771 | push cx ;an000;save cx | ||
| 2772 | mov cx,40h | ||
| 2773 | push ax ;an000;save ax | ||
| 2774 | call write_disk ;an000;write it | ||
| 2775 | pop ax ;an000;restore ax | ||
| 2776 | pop cx ;an000;restore cx | ||
| 2777 | jc Write_Exit ;an000;exit if fail | ||
| 2778 | mov si,8000h | ||
| 2779 | call seg_adj ;an000;adjust segment | ||
| 2780 | mov bx,si ;an000;new offset | ||
| 2781 | add dx,40h | ||
| 2782 | sub cx,40h | ||
| 2783 | ; $else ;an000;< 64k | ||
| 2784 | JMP SHORT $$EN69 | ||
| 2785 | $$IF69: | ||
| 2786 | push ax ;an000;save ax | ||
| 2787 | call write_disk ;an000;write it | ||
| 2788 | pop ax ;an000;restore ax | ||
| 2789 | xor cx,cx ;an000;set cx to 0 - last read | ||
| 2790 | ; $endif | ||
| 2791 | $$EN69: | ||
| 2792 | ; $enddo | ||
| 2793 | JMP SHORT $$DO67 | ||
| 2794 | $$EN67: | ||
| 2795 | |||
| 2796 | Write_Exit: | ||
| 2797 | |||
| 2798 | ret | ||
| 2799 | |||
| 2800 | write_fat endp | ||
| 2801 | |||
| 2802 | ;========================================================================= | ||
| 2803 | ; SEG_ADJ : This routine adjusts the segment:offset to prevent | ||
| 2804 | ; address wrap. | ||
| 2805 | ; | ||
| 2806 | ; Inputs : SI - Offset to adjust segment with | ||
| 2807 | ; DS - Segment to be adjusted | ||
| 2808 | ; | ||
| 2809 | ; Outputs : SI - New offset | ||
| 2810 | ; DS - Adjusted segment | ||
| 2811 | ;========================================================================= | ||
| 2812 | |||
| 2813 | procedure seg_adj | ||
| 2814 | |||
| 2815 | push ax | ||
| 2816 | push cx | ||
| 2817 | push dx | ||
| 2818 | mov ax,si ;an000;get offset | ||
| 2819 | mov bx,0010h ;an000;16 | ||
| 2820 | xor dx,dx ;an000;clear dx | ||
| 2821 | div bx ;an000;get para count | ||
| 2822 | ; $if c ;an000;overflow? | ||
| 2823 | JNC $$IF73 | ||
| 2824 | adc bx,0 ;an000;pick it up | ||
| 2825 | ; $endif ;an000; | ||
| 2826 | $$IF73: | ||
| 2827 | mov bx,ds ;an000;get seg | ||
| 2828 | add bx,ax ;an000;adjust for paras | ||
| 2829 | mov ds,bx ;an000;save new seg | ||
| 2830 | mov si,dx ;an000;new offset | ||
| 2831 | pop dx | ||
| 2832 | pop cx | ||
| 2833 | pop ax | ||
| 2834 | ret | ||
| 2835 | |||
| 2836 | seg_adj endp | ||
| 2837 | |||
| 2838 | ;------------------------------------------------------------------------------- | ||
| 2839 | ; format is done... so clean up the disk! | ||
| 2840 | ; | ||
| 2841 | Done proc near | ||
| 2842 | |||
| 2843 | |||
| 2844 | call OemDone | ||
| 2845 | return | ||
| 2846 | |||
| 2847 | Done endp | ||
| 2848 | |||
| 2849 | ;------------------------------------------------------------------------------- | ||
| 2850 | ; CurrentLogicalSector: | ||
| 2851 | ; Get the current logical sector number | ||
| 2852 | ; | ||
| 2853 | ; Input: | ||
| 2854 | ; current track = tracksPerDisk - tracksLeft | ||
| 2855 | ; SectorsPerTrack | ||
| 2856 | ; | ||
| 2857 | ; Output: | ||
| 2858 | ; BX = logical sector number of the first sector in the track we | ||
| 2859 | ; just tried to format | ||
| 2860 | ; | ||
| 2861 | CurrentLogicalSector proc near | ||
| 2862 | |||
| 2863 | push ax ;an000; dms;save regs | ||
| 2864 | push bx ;an000; dms; | ||
| 2865 | push dx ;an000; dms; | ||
| 2866 | |||
| 2867 | mov ax, tracksPerDisk | ||
| 2868 | sub ax, tracksLeft | ||
| 2869 | xor dx,dx ;an000; dms;clear dx | ||
| 2870 | mul deviceParameters.DP_BPB.BPB_SectorsPerTrack | ||
| 2871 | mov word ptr Relative_Sector_High,dx ;an000; dms;save high word of sector # | ||
| 2872 | mov word ptr Relative_Sector_Low,ax ;an000; dms;save low word of sector # | ||
| 2873 | |||
| 2874 | pop dx ;an000; dms;restore regs | ||
| 2875 | pop bx ;an000; dms; | ||
| 2876 | pop ax ;an000; dms; | ||
| 2877 | |||
| 2878 | return | ||
| 2879 | |||
| 2880 | CurrentLogicalSector endp | ||
| 2881 | |||
| 2882 | ;------------------------------------------------------------------------------- | ||
| 2883 | ; PrintErrorAbort: | ||
| 2884 | ; Print an error message and abort | ||
| 2885 | ; | ||
| 2886 | ; Input: | ||
| 2887 | ; dx - Pointer to error message string | ||
| 2888 | ; | ||
| 2889 | PrintErrorAbort proc near | ||
| 2890 | |||
| 2891 | push dx | ||
| 2892 | call crlf | ||
| 2893 | pop dx | ||
| 2894 | call PrintString | ||
| 2895 | |||
| 2896 | jmp fexit | ||
| 2897 | |||
| 2898 | PrintErrorAbort endp | ||
| 2899 | |||
| 2900 | |||
| 2901 | |||
| 2902 | |||
| 2903 | ;***************************************************************************** | ||
| 2904 | ;Routine name: Multiply_32_Bits | ||
| 2905 | ;***************************************************************************** | ||
| 2906 | ; | ||
| 2907 | ;Description: A real sleazy 32 bit x 16 bit multiply routine. Works by adding | ||
| 2908 | ; the 32 bit number to itself for each power of 2 contained in the | ||
| 2909 | ; 16 bit number. Whenever a bit that is set in the multiplier (CX) | ||
| 2910 | ; gets shifted to the bit 0 spot, it means that that amount has | ||
| 2911 | ; been multiplied so far, and it should be added into the total | ||
| 2912 | ; value. Take the example CX = 12 (1100). Using the associative | ||
| 2913 | ; rule, this is the same as CX = 8+4 (1000 + 0100). The | ||
| 2914 | ; multiply is done on this principle - whenever a bit that is set | ||
| 2915 | ; is shifted down to the bit 0 location, the value in BX:AX is | ||
| 2916 | ; added to the running total in DI:SI. The multiply is continued | ||
| 2917 | ; until CX = 0. The routine will exit with CY set if overflow | ||
| 2918 | ; occurs. | ||
| 2919 | ; | ||
| 2920 | ; | ||
| 2921 | ;Called Procedures: None | ||
| 2922 | ; | ||
| 2923 | ;Change History: Created 7/23/87 MT | ||
| 2924 | ; | ||
| 2925 | ;Input: BX:AX = 32 bit number to be multiplied | ||
| 2926 | ; CX = 16 bit number to be multiplied. (Must be even number) | ||
| 2927 | ; | ||
| 2928 | ;Output: BX:AX = output. | ||
| 2929 | ; CY set if overflow | ||
| 2930 | ; | ||
| 2931 | ;Psuedocode | ||
| 2932 | ;---------- | ||
| 2933 | ; | ||
| 2934 | ; Point at ControlC_Handler routine | ||
| 2935 | ; Set interrupt handler (INT 21h, AX=2523h) | ||
| 2936 | ; ret | ||
| 2937 | ;***************************************************************************** | ||
| 2938 | |||
| 2939 | Public Multiply_32_Bits | ||
| 2940 | Multiply_32_Bits proc ; ;AN000; | ||
| 2941 | |||
| 2942 | push di ; ;AN000; | ||
| 2943 | push si ; ;AN000; | ||
| 2944 | xor di,di ;Init result to zero | ||
| 2945 | xor si,si ; | ||
| 2946 | cmp cx,0 ;Multiply by 0? ;AN000; | ||
| 2947 | ; $IF NE ;Keep going if not ;AN000; | ||
| 2948 | JE $$IF75 | ||
| 2949 | ; $DO ;This works by adding the result;AN000; | ||
| 2950 | $$DO76: | ||
| 2951 | test cx,1 ;Need to add in sum of this bit?;AN000; | ||
| 2952 | ; $IF NZ ;Yes ;AN000; | ||
| 2953 | JZ $$IF77 | ||
| 2954 | add si,ax ;Add in the total so far for ;AN000; | ||
| 2955 | adc di,bx ; this bit multiplier (CY oflow);AN000; | ||
| 2956 | ; $ELSE ;Don't split multiplier ;AN000; | ||
| 2957 | JMP SHORT $$EN77 | ||
| 2958 | $$IF77: | ||
| 2959 | clc ;Force non exit ;AN000; | ||
| 2960 | ; $ENDIF ; ;AN000; | ||
| 2961 | $$EN77: | ||
| 2962 | ; $LEAVE C ;Leave on overflow ;AN000; | ||
| 2963 | JC $$EN76 | ||
| 2964 | shr cx,1 ;See if need to multiply value ;AN000; | ||
| 2965 | cmp cx,0 ;by 2 ;AN000; | ||
| 2966 | ; $LEAVE E ;Done if cx shifted down to zero;AN000; | ||
| 2967 | JE $$EN76 | ||
| 2968 | add ax,ax ;Each time cx is shifted, add ;AN000; | ||
| 2969 | adc bx,bx ;value to itself (Multiply * 2) ;AN000; | ||
| 2970 | ; $ENDDO C ;CY set on overflow ;AN000; | ||
| 2971 | JNC $$DO76 | ||
| 2972 | $$EN76: | ||
| 2973 | ; $IF NC ;If no overflow, add in DI:SI ;AN000; | ||
| 2974 | JC $$IF83 | ||
| 2975 | mov ax,si ; which contains the original ;AN000; | ||
| 2976 | mov bx,di ; value if odd, 0 if even. This ;AN000; | ||
| 2977 | clc ;Set no overflow flag ;AN000; | ||
| 2978 | ; $ENDIF ; ;AN000; | ||
| 2979 | $$IF83: | ||
| 2980 | ; $ELSE ; | ||
| 2981 | JMP SHORT $$EN75 | ||
| 2982 | $$IF75: | ||
| 2983 | xor ax,ax ; | ||
| 2984 | xor bx,bx ; | ||
| 2985 | ; $ENDIF ;Multiply by 0 ;AN000; | ||
| 2986 | $$EN75: | ||
| 2987 | pop si ; ;AN000; | ||
| 2988 | pop di ; ;AN000; | ||
| 2989 | ret ; ;AN000; | ||
| 2990 | |||
| 2991 | Multiply_32_Bits endp | ||
| 2992 | |||
| 2993 | |||
| 2994 | ;========================================================================= | ||
| 2995 | ; Divide_32_Bits - This routine will perform 32bit division | ||
| 2996 | ; | ||
| 2997 | ; Inputs : SI:DI - value to be divided | ||
| 2998 | ; CX - divisor | ||
| 2999 | ; | ||
| 3000 | ; Outputs : SI:DI - result | ||
| 3001 | ; CX - remainder | ||
| 3002 | ;========================================================================= | ||
| 3003 | |||
| 3004 | Procedure Divide_32_Bits ;an000; dms; | ||
| 3005 | |||
| 3006 | push ax ;an000; dms;save regs | ||
| 3007 | push bx ;an000; dms; | ||
| 3008 | push dx ;an000; dms; | ||
| 3009 | |||
| 3010 | xor dx,dx ;an000; dms;clear dx | ||
| 3011 | mov ax,si ;an000; dms;get high word | ||
| 3012 | div cx ;an000; dms;get high word result | ||
| 3013 | mov si,ax ;an000; dms;save high word result | ||
| 3014 | |||
| 3015 | mov ax,di ;an000; dms;get low word | ||
| 3016 | div cx ;an000; dms;get low word result | ||
| 3017 | mov di,ax ;an000; dms;save low word result | ||
| 3018 | mov cx,dx ;an000; dms;pick up remainder | ||
| 3019 | |||
| 3020 | pop dx ;an000; dms;restore regs | ||
| 3021 | pop bx ;an000; dms; | ||
| 3022 | pop ax ;an000; dms; | ||
| 3023 | |||
| 3024 | ret ;an000; dms; | ||
| 3025 | |||
| 3026 | Divide_32_Bits endp ;an000; dms; | ||
| 3027 | |||
| 3028 | |||
| 3029 | |||
| 3030 | |||
| 3031 | ;========================================================================= | ||
| 3032 | ; FAT_INIT: This routine initializes the FAT based on the | ||
| 3033 | ; number of paragraphs. | ||
| 3034 | ; | ||
| 3035 | ; | ||
| 3036 | ; input - fatspace | ||
| 3037 | ; fatspace+2 | ||
| 3038 | ; paras_per_fat | ||
| 3039 | ; fat_init_value | ||
| 3040 | ; output - fat space is initialized | ||
| 3041 | ; | ||
| 3042 | ;========================================================================= | ||
| 3043 | Public Fat_Init | ||
| 3044 | Fat_Init proc near | ||
| 3045 | |||
| 3046 | push es | ||
| 3047 | push di | ||
| 3048 | push ax | ||
| 3049 | push bx | ||
| 3050 | push cx | ||
| 3051 | mov di, word ptr FatSpace+2 ;Get segment of Fat space ;AC000; | ||
| 3052 | mov es,di ; ;AN000; | ||
| 3053 | mov di, word ptr FatSpace ; ;AN000; | ||
| 3054 | mov bx,Paras_Per_Fat ;an000;get number of paras | ||
| 3055 | mov ax,fat_init_value ;an000; | ||
| 3056 | push dx ;an000;save bx | ||
| 3057 | mov dx,es ;an000;grab es into dx | ||
| 3058 | ; $do | ||
| 3059 | $$DO87: | ||
| 3060 | cmp bx,0 ;an000;do while bx not = 0 | ||
| 3061 | ; $leave e ;an000;exit if 0 | ||
| 3062 | JE $$EN87 | ||
| 3063 | mov cx,10h ;an000;word move of paragraph | ||
| 3064 | rep stosb ;an000;move the data to FAT | ||
| 3065 | xor di,di ;an000;offset always init to 0 | ||
| 3066 | inc dx ;an000;next paragraph | ||
| 3067 | mov es,dx ;an000;put next para in es | ||
| 3068 | dec bx ;an000;loop iteration counter | ||
| 3069 | ; $enddo ;an000; | ||
| 3070 | JMP SHORT $$DO87 | ||
| 3071 | $$EN87: | ||
| 3072 | pop dx ;an000; | ||
| 3073 | pop cx ;an000; | ||
| 3074 | pop bx ;an000; | ||
| 3075 | pop ax ;an000; | ||
| 3076 | pop di ;an000; | ||
| 3077 | pop es ;an000; | ||
| 3078 | |||
| 3079 | ret ;an000; | ||
| 3080 | |||
| 3081 | Fat_Init endp ;an000; | ||
| 3082 | |||
| 3083 | |||
| 3084 | ;========================================================================= | ||
| 3085 | ; Ctrl_Break_Write : This routine takes the control break request | ||
| 3086 | ; an returns. In essence, it disables the CTRL-BREAK. | ||
| 3087 | ; This routine is used during the writing of the | ||
| 3088 | ; FAT, DIR, and SYSTEM. | ||
| 3089 | ;========================================================================= | ||
| 3090 | |||
| 3091 | Ctrl_Break_Write: ;ac010; dms; | ||
| 3092 | |||
| 3093 | iret ;ac010; dms;return to caller | ||
| 3094 | |||
| 3095 | |||
| 3096 | ;========================================================================= | ||
| 3097 | ; Ctrl_Break_Save : This routine gets the current vector of | ||
| 3098 | ; INT 23h and saves it in CTRL_BREAK_VECTOR. | ||
| 3099 | ; | ||
| 3100 | ; Inputs : none | ||
| 3101 | ; | ||
| 3102 | ; Outputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine | ||
| 3103 | ;========================================================================= | ||
| 3104 | |||
| 3105 | Ctrl_Break_Save proc near ;ac010; dms; | ||
| 3106 | |||
| 3107 | push es ;ac010; dms;save es | ||
| 3108 | push bx ;ac010; dms;save bx | ||
| 3109 | push ax ;ac010; dms;save ax | ||
| 3110 | |||
| 3111 | mov ax,3523h ;ac010; dms;get CTRL-BREAK | ||
| 3112 | ; interrupt vector | ||
| 3113 | int 21h ;ac010; dms; | ||
| 3114 | |||
| 3115 | mov word ptr Ctrl_Break_Vector,bx ;ac010; dms;get vector offset | ||
| 3116 | mov word ptr Ctrl_Break_Vector+2,es ;ac010; dms;get vector segment | ||
| 3117 | |||
| 3118 | pop ax ;ac010; dms;restore ax | ||
| 3119 | pop bx ;ac010; dms;restore bx | ||
| 3120 | pop es ;ac010; dms;restore es | ||
| 3121 | |||
| 3122 | ret ;ac010; dms; | ||
| 3123 | |||
| 3124 | |||
| 3125 | Ctrl_Break_Save endp ;ac010; dms; | ||
| 3126 | |||
| 3127 | |||
| 3128 | ;========================================================================= | ||
| 3129 | ; Set_Ctrl_Break : This routine sets the CTRL-Break vector to one | ||
| 3130 | ; defined by the user. | ||
| 3131 | ; | ||
| 3132 | ; Inputs : none | ||
| 3133 | ; | ||
| 3134 | ; Outputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine | ||
| 3135 | ;========================================================================= | ||
| 3136 | |||
| 3137 | Set_Ctrl_Break proc near ;ac010; dms; | ||
| 3138 | |||
| 3139 | push ds ;ac010; dms;save ds | ||
| 3140 | push ax ;ac010; dms;save ax | ||
| 3141 | push bx ;ac010; dms;save bx | ||
| 3142 | push dx ;ac010; dms;save dx | ||
| 3143 | |||
| 3144 | push cs ;ac010; dms;swap cs with ds | ||
| 3145 | pop ds ;an000; dms;point to code seg | ||
| 3146 | |||
| 3147 | mov dx,offset Ctrl_Break_Write ;ac010; dms;get interrupt vec. | ||
| 3148 | mov ax,2523h ;ac010; dms;set CTRL-BREAK | ||
| 3149 | ; interrupt vector | ||
| 3150 | int 21h ;ac010; dms; | ||
| 3151 | |||
| 3152 | pop dx ;ac010; dms;restore dx | ||
| 3153 | pop bx ;ac010; dms;restore bx | ||
| 3154 | pop ax ;ac010; dms;restore ax | ||
| 3155 | pop ds ;ac010; dms;restore ds | ||
| 3156 | |||
| 3157 | ret ;ac010; dms; | ||
| 3158 | |||
| 3159 | |||
| 3160 | Set_Ctrl_Break endp ;ac010; dms; | ||
| 3161 | |||
| 3162 | |||
| 3163 | ;========================================================================= | ||
| 3164 | ; Reset_Ctrl_Break : This routine resets the CTRL-Break vector to that | ||
| 3165 | ; originally defined. | ||
| 3166 | ; | ||
| 3167 | ; Inputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine | ||
| 3168 | ; | ||
| 3169 | ; Outputs : none | ||
| 3170 | ;========================================================================= | ||
| 3171 | |||
| 3172 | Reset_Ctrl_Break proc near ;ac010; dms; | ||
| 3173 | |||
| 3174 | push ds ;ac010; dms;save ds | ||
| 3175 | push ax ;ac010; dms;save ax | ||
| 3176 | push bx ;ac010; dms;save bx | ||
| 3177 | push dx ;ac010; dms;save ds | ||
| 3178 | |||
| 3179 | mov ax,word ptr Ctrl_Break_Vector+2 ;ac010; dms;get seg. of vector | ||
| 3180 | mov bx,word ptr Ctrl_Break_Vector ;ac010; dms;get off. of vector | ||
| 3181 | mov ds,ax ;ac010; dms;get seg. | ||
| 3182 | mov dx,bx ;ac010; dms;get off. | ||
| 3183 | mov ax,2523h ;ac010; dms;set CTRL-BREAK | ||
| 3184 | ; interrupt vector | ||
| 3185 | int 21h ;ac010; dms; | ||
| 3186 | |||
| 3187 | pop dx ;ac010; dms;restore dx | ||
| 3188 | pop bx ;ac010; dms;restore bx | ||
| 3189 | pop ax ;ac010; dms;restore ax | ||
| 3190 | pop ds ;ac010; dms;restore ds | ||
| 3191 | |||
| 3192 | ret ;ac010; dms; | ||
| 3193 | |||
| 3194 | |||
| 3195 | Reset_Ctrl_Break endp ;ac010; dms; | ||
| 3196 | |||
| 3197 | ;========================================================================= | ||
| 3198 | ; Get_Command_Path : This routine finds the path where | ||
| 3199 | ; COMMAND.COM resides based on the | ||
| 3200 | ; environmental vector. Once the | ||
| 3201 | ; path is found it is copied to | ||
| 3202 | ; CommandFile. | ||
| 3203 | ; | ||
| 3204 | ; Inputs : Exec_Block.Segment_Env - Segment of environmental vector | ||
| 3205 | ; Comspec_ID - "COMSPEC=" | ||
| 3206 | ; | ||
| 3207 | ; Outputs : CommandFile - Holds path to COMMAND.COM | ||
| 3208 | ;========================================================================= | ||
| 3209 | |||
| 3210 | Procedure Get_Command_Path ;an011; dms; | ||
| 3211 | |||
| 3212 | push ds ;an011; dms;save ds | ||
| 3213 | push es ;an011; dms;save es | ||
| 3214 | |||
| 3215 | Set_Data_Segment ;an011; dms; DS,ES = Data | ||
| 3216 | call Get_PSP_Parms ;an011; dms; gets PSP info. | ||
| 3217 | cld ;an011; dms; clear direction | ||
| 3218 | mov ax,es:Environ_Segment ;an011; dms; get seg. of | ||
| 3219 | ; environ. vector | ||
| 3220 | mov ds,ax ;an011; dms; put it in DS | ||
| 3221 | assume ds:nothing ;an011; dms; | ||
| 3222 | xor si,si ;an011; dms; clear si | ||
| 3223 | mov bx,si ;an011; dms; save si | ||
| 3224 | mov di,offset Comspec_ID ;an011; dms; point to target | ||
| 3225 | mov cx,127 ;an011; dms; loop 127 times | ||
| 3226 | ; $do ;an011; dms; while cx not 0 | ||
| 3227 | $$DO90: | ||
| 3228 | ; and target not found | ||
| 3229 | cmp cx,00h ;an011; dms; end of env.? | ||
| 3230 | ; $leave e ;an011; dms; yes | ||
| 3231 | JE $$EN90 | ||
| 3232 | |||
| 3233 | push cx ;an011; dms; save cx | ||
| 3234 | mov cx,0008h ;an011; dms; loop 8 times | ||
| 3235 | repe cmpsb ;an011; dms; "COMSPEC=" ? | ||
| 3236 | pop cx ;an011; dms; restore cx | ||
| 3237 | ; $if z ;an011; dms; yes | ||
| 3238 | JNZ $$IF92 | ||
| 3239 | push di ;an011; dms; save di | ||
| 3240 | mov di,offset es:CommandFile ;an011; dms | ||
| 3241 | lodsb ;an011; dms; priming read | ||
| 3242 | mov dl,al ;an011; dms; prepare for capitalization | ||
| 3243 | call Cap_Char ;an011; dms; capitalize character in DL | ||
| 3244 | cmp dl,es:CommandFile ;an011; dms;COMSPEC same as default drive? | ||
| 3245 | ; $if e ;an000; dms; yes | ||
| 3246 | JNE $$IF93 | ||
| 3247 | ; $do ;an011; dms; while AL not = 0 | ||
| 3248 | $$DO94: | ||
| 3249 | cmp al,00h ;an011; dms; at end? | ||
| 3250 | ; $leave e ;an011; dms; yes | ||
| 3251 | JE $$EN94 | ||
| 3252 | stosb ;an011; dms; save it | ||
| 3253 | lodsb ;an011; dms; get character | ||
| 3254 | ; $enddo | ||
| 3255 | JMP SHORT $$DO94 | ||
| 3256 | $$EN94: | ||
| 3257 | ; $endif ;an011; dms; | ||
| 3258 | $$IF93: | ||
| 3259 | pop di ;an011; dms; restore di | ||
| 3260 | mov cx,0ffffh ;an011; dms; flag target found | ||
| 3261 | ; $endif ;an011; dms; | ||
| 3262 | $$IF92: | ||
| 3263 | |||
| 3264 | cmp cx,0ffffh ;an011; dms; target found? | ||
| 3265 | ; $leave e ;an011; dms; yes | ||
| 3266 | JE $$EN90 | ||
| 3267 | |||
| 3268 | mov di,offset Comspec_ID ;an011; dms; point to target | ||
| 3269 | mov si,bx ;an011; dms; restore si | ||
| 3270 | inc si ;an011; dms; point to next byte | ||
| 3271 | mov bx,si ;an011; dms; save si | ||
| 3272 | |||
| 3273 | dec cx ;an011; dms; decrease counter | ||
| 3274 | ; $enddo ;an011; dms; | ||
| 3275 | JMP SHORT $$DO90 | ||
| 3276 | $$EN90: | ||
| 3277 | |||
| 3278 | pop es ;an011; dms; restore es | ||
| 3279 | pop ds ;an011; dms; restore ds | ||
| 3280 | |||
| 3281 | ret ;an011; dms; | ||
| 3282 | |||
| 3283 | Get_Command_Path endp ;an011; dms; | ||
| 3284 | |||
| 3285 | |||
| 3286 | ; | ||
| 3287 | ;**************************************************************************** | ||
| 3288 | ; Get_PSP_Parms | ||
| 3289 | ;**************************************************************************** | ||
| 3290 | ; | ||
| 3291 | ; | ||
| 3292 | ; | ||
| 3293 | ; | ||
| 3294 | |||
| 3295 | Procedure Get_PSP_Parms ; ;AC000; | ||
| 3296 | |||
| 3297 | Set_Data_Segment | ||
| 3298 | mov ax,PSP_Segment ;Get segment of PSP ;AN000; | ||
| 3299 | mov ds,ax ; " " " " ;AN000; | ||
| 3300 | ; ; | ||
| 3301 | assume ds:nothing | ||
| 3302 | ;Setup segment of Environment string, get from PSP ; ; | ||
| 3303 | |||
| 3304 | mov ax,ds:PSP_Environ ; ; ; | ||
| 3305 | mov es:Environ_Segment,ax ; ; ; | ||
| 3306 | Set_Data_Segment | ||
| 3307 | ret ; ; ; | ||
| 3308 | |||
| 3309 | |||
| 3310 | Get_PSP_Parms endp ; ;AN000; | ||
| 3311 | |||
| 3312 | |||
| 3313 | ;========================================================================= | ||
| 3314 | ; Command_Root : This routine sets up CommandFile so that the | ||
| 3315 | ; COMMAND.COM will be written to the root. | ||
| 3316 | ; It does this by copying at offset 3 of CommandFile | ||
| 3317 | ; the literal COMMAND.COM. This effectively | ||
| 3318 | ; overrides the original path, but maintains the | ||
| 3319 | ; drive letter that is to be written to. | ||
| 3320 | ; | ||
| 3321 | ; Inputs : CommandFile - Holds full path to default COMMAND.COM | ||
| 3322 | ; Outputs : CommandFile - Holds modified path to new COMMAND.COM | ||
| 3323 | ; on target drive. | ||
| 3324 | ;========================================================================= | ||
| 3325 | |||
| 3326 | Procedure Command_Root ;an011; dms; | ||
| 3327 | |||
| 3328 | push ds ;an011; dms; save ds | ||
| 3329 | push es ;an011; dms; save es | ||
| 3330 | push di ;an011; dms; save di | ||
| 3331 | push si ;an011; dms; save si | ||
| 3332 | push cx ;an011; dms; save cx | ||
| 3333 | Set_Data_Segment ;an011; | ||
| 3334 | |||
| 3335 | mov di,offset CommandFile+3 ;an011; dms; point to path | ||
| 3336 | ; past drive spec | ||
| 3337 | mov si,offset Command_Com ;an011; dms; holds the literal | ||
| 3338 | ; COMMAND.COM | ||
| 3339 | mov cx,000ch ;an011; dms; len. of literal | ||
| 3340 | rep movsb ;an011; dms; move it | ||
| 3341 | |||
| 3342 | pop cx ;an011; dms; restore cx | ||
| 3343 | pop si ;an011; dms; restore si | ||
| 3344 | pop di ;an011; dms; restore di | ||
| 3345 | pop es ;an011; dms; restore es | ||
| 3346 | pop ds ;an011; dms; restore ds | ||
| 3347 | |||
| 3348 | ret ;an011; dms; | ||
| 3349 | |||
| 3350 | Command_Root endp ;an011; dms; | ||
| 3351 | |||
| 3352 | |||
| 3353 | ;========================================================================= | ||
| 3354 | ; Set_BPB_Info : When we have a FAT count of 0, we must calculate | ||
| 3355 | ; certain parts of the BPB. The following code | ||
| 3356 | ; will do just that. | ||
| 3357 | ; | ||
| 3358 | ; Inputs : DeviceParameters | ||
| 3359 | ; | ||
| 3360 | ; Outputs : BPB information | ||
| 3361 | ;========================================================================= | ||
| 3362 | |||
| 3363 | Procedure Set_BPB_Info ;an012; dms;calc new BPB | ||
| 3364 | |||
| 3365 | Set_Data_Segment ;an012; dms;set up addressibility | ||
| 3366 | cmp DeviceParameters.DP_BPB.BPB_NumberOfFats,00h ;an012; dms;see if we have 0 FATS specified | ||
| 3367 | ; $if e ;an012; dms;yes, 0 FATS specified | ||
| 3368 | JNE $$IF101 | ||
| 3369 | call Scan_Disk_Table ;an012; dms;access disk table | ||
| 3370 | mov bl,byte ptr ds:[si+8] ;an012; dms;get FAT type | ||
| 3371 | mov cx,word ptr ds:[si+4] ;an012; dms;get sectors/cluster | ||
| 3372 | mov dx,word ptr ds:[si+6] ;an012; dms;number of entries for the root DIR | ||
| 3373 | |||
| 3374 | mov DeviceParameters.DP_BPB.BPB_RootEntries,dx ;an012; dms;save root entries | ||
| 3375 | mov DeviceParameters.DP_BPB.BPB_SectorsPerCluster,ch ;an012; dms;save sectors/cluster | ||
| 3376 | mov DeviceParameters.DP_BPB.BPB_BytesPerSector,0200h ;an012; dms;save bytes/sector | ||
| 3377 | mov DeviceParameters.DP_BPB.BPB_ReservedSectors,0001h ;an012; dms;save reserved sectors | ||
| 3378 | mov DeviceParameters.DP_BPB.BPB_NumberOfFats,02h ;an012; dms;FAT count | ||
| 3379 | |||
| 3380 | cmp bl,FBIG ;an012; dms;Big FAT? | ||
| 3381 | ; $if e ;an012; dms;yes | ||
| 3382 | JNE $$IF102 | ||
| 3383 | call Calc_Big_FAT ;an012; dms;calc big FAT info | ||
| 3384 | ; $else ;an012; dms; | ||
| 3385 | JMP SHORT $$EN102 | ||
| 3386 | $$IF102: | ||
| 3387 | call Calc_Small_FAT ;an012; dms;calc small FAT info | ||
| 3388 | ; $endif ;an012; dms; | ||
| 3389 | $$EN102: | ||
| 3390 | ; $endif ;an012; dms; | ||
| 3391 | $$IF101: | ||
| 3392 | |||
| 3393 | ret ;an012; dms; | ||
| 3394 | |||
| 3395 | Set_BPB_Info endp ;an012; dms; | ||
| 3396 | |||
| 3397 | |||
| 3398 | |||
| 3399 | ;========================================================================= | ||
| 3400 | ; Scan_Disk_Table : Scans the table containing information on | ||
| 3401 | ; the disk's attributes. When it finds the | ||
| 3402 | ; applicable data, it returns a pointer in | ||
| 3403 | ; DS:SI for reference by the calling proc. | ||
| 3404 | ; | ||
| 3405 | ; Inputs : DiskTable - Contains data about disk types | ||
| 3406 | ; | ||
| 3407 | ; Outputs : DS:SI - Points to applicable disk data | ||
| 3408 | ;========================================================================= | ||
| 3409 | |||
| 3410 | Procedure Scan_Disk_Table ;an012; dms; | ||
| 3411 | |||
| 3412 | cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk? | ||
| 3413 | ; $if ne ;an012; dms;yes | ||
| 3414 | JE $$IF106 | ||
| 3415 | mov dx,00h ;an012; dms;set high to 0 | ||
| 3416 | mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count | ||
| 3417 | ; $else ;an012; dms; | ||
| 3418 | JMP SHORT $$EN106 | ||
| 3419 | $$IF106: | ||
| 3420 | mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count | ||
| 3421 | mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count | ||
| 3422 | ; $endif ;an012; dms; | ||
| 3423 | $$EN106: | ||
| 3424 | |||
| 3425 | mov si,offset DiskTable ;an012; dms;point to disk data | ||
| 3426 | Scan: | ||
| 3427 | |||
| 3428 | cmp dx,word ptr ds:[si] ;an012; dms;below? | ||
| 3429 | jb Scan_Disk_Table_Exit ;an012; dms;yes, exit | ||
| 3430 | ja Scan_Next ;an012; dms;no, continue | ||
| 3431 | cmp ax,word ptr ds:[si+2] ;an012; dms;below or equal? | ||
| 3432 | jbe Scan_Disk_Table_Exit ;an012; dms;yes, exit | ||
| 3433 | |||
| 3434 | Scan_Next: | ||
| 3435 | |||
| 3436 | add si,5*2 ;an012; dms;adjust pointer | ||
| 3437 | jmp Scan ;an012; dms;continue scan | ||
| 3438 | |||
| 3439 | Scan_Disk_Table_Exit: | ||
| 3440 | |||
| 3441 | ret ;an012; dms; | ||
| 3442 | |||
| 3443 | Scan_Disk_Table endp ;an012; dms; | ||
| 3444 | |||
| 3445 | |||
| 3446 | |||
| 3447 | ;========================================================================= | ||
| 3448 | ; Calc_Big_FAT : Calculates the sectors per FAT for a 16 bit FAT. | ||
| 3449 | ; | ||
| 3450 | ; Inputs : DeviceParameters.DP_BPB.BPB_BigTotalSectors or | ||
| 3451 | ; DeviceParameters.DP_BPB.BPB_TotalSectors | ||
| 3452 | ; | ||
| 3453 | ; Outputs : DeviceParameters.DP_BPB.BPB_SectorsPerFat | ||
| 3454 | ;========================================================================= | ||
| 3455 | |||
| 3456 | Procedure Calc_Big_FAT ;an012; dms; | ||
| 3457 | |||
| 3458 | cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk? | ||
| 3459 | ; $if ne ;an012; dms;yes | ||
| 3460 | JE $$IF109 | ||
| 3461 | mov dx,00h ;an012; dms;set high to 0 | ||
| 3462 | mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count | ||
| 3463 | ; $else ;an012; dms; | ||
| 3464 | JMP SHORT $$EN109 | ||
| 3465 | $$IF109: | ||
| 3466 | mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count | ||
| 3467 | mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count | ||
| 3468 | ; $endif ;an012; dms; | ||
| 3469 | $$EN109: | ||
| 3470 | |||
| 3471 | mov cl,04h ;an012; dms;16 DIR entries per sector | ||
| 3472 | push dx ;an012; dms;save total sectors (high) | ||
| 3473 | mov dx,DeviceParameters.DP_BPB.BPB_RootEntries ;an012; dms;get root entry count | ||
| 3474 | shr dx,cl ;an012; dms;divide by 16 | ||
| 3475 | sub ax,dx ;an012; dms; | ||
| 3476 | pop dx ;an012; dms;restore dx | ||
| 3477 | sbb dx,0 ;an012; dms; | ||
| 3478 | sub ax,1 ;an012; dms;AX = T - R - D | ||
| 3479 | sbb dx,0 ;an012; dms; | ||
| 3480 | mov bl,02h ;an012; dms; | ||
| 3481 | mov bh,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an012; dms;get sectors per cluster | ||
| 3482 | add ax,bx ;an012; dms;AX = T-R-D+256*SPC+2 | ||
| 3483 | adc dx,0 ;an012; dms; | ||
| 3484 | sub ax,1 ;an012; dms;AX = T-R-D+256*SPC+1 | ||
| 3485 | sbb dx,0 ;an012; dms; | ||
| 3486 | div bx ;an012; dms; sec/FAT = CEIL((TOTAL-DIR-RES)/ | ||
| 3487 | ; (256*SECPERCLUS+2) | ||
| 3488 | mov word ptr DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax ;an012; dms;Sectors/cluster | ||
| 3489 | ret ;an012; dms; | ||
| 3490 | |||
| 3491 | Calc_Big_FAT endp ;an012; dms; | ||
| 3492 | |||
| 3493 | |||
| 3494 | ;========================================================================= | ||
| 3495 | ; Calc_Small_FAT: Calculates the sectors per FAT for a 12 bit FAT. | ||
| 3496 | ; | ||
| 3497 | ; Inputs : DeviceParameters.DP_BPB.BPB_BigTotalSectors or | ||
| 3498 | ; DeviceParameters.DP_BPB.BPB_TotalSectors | ||
| 3499 | ; | ||
| 3500 | ; Outputs : DeviceParameters.DP_BPB.BPB_SectorsPerFat | ||
| 3501 | ;========================================================================= | ||
| 3502 | |||
| 3503 | Procedure Calc_Small_FAT ;an012; dms; | ||
| 3504 | |||
| 3505 | cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk? | ||
| 3506 | ; $if ne ;an012; dms;yes | ||
| 3507 | JE $$IF112 | ||
| 3508 | mov dx,00h ;an012; dms;set high to 0 | ||
| 3509 | mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count | ||
| 3510 | ; $else ;an012; dms; | ||
| 3511 | JMP SHORT $$EN112 | ||
| 3512 | $$IF112: | ||
| 3513 | mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count | ||
| 3514 | mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count | ||
| 3515 | ; $endif ;an012; dms; | ||
| 3516 | $$EN112: | ||
| 3517 | |||
| 3518 | xor bx,bx ;an012; dms;clear bx | ||
| 3519 | mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an012; dms;get sectors/cluster | ||
| 3520 | div bx ;an012; dms; | ||
| 3521 | ; now multiply by 3/2 | ||
| 3522 | mov bx,3 ;an012; dms; | ||
| 3523 | mul bx ;an012; dms;div by log 2 of sectors/cluster | ||
| 3524 | mov bx,2 ;an012; dms; | ||
| 3525 | div bx ;an012; dms; | ||
| 3526 | xor dx,dx ;an012; dms; | ||
| 3527 | ; now divide by 512 | ||
| 3528 | mov bx,512 ;an012; dms; | ||
| 3529 | div bx ;an012; dms; | ||
| 3530 | inc ax ;an012; dms; | ||
| 3531 | ; dx:ax contains number of FAT sectors necessary | ||
| 3532 | mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax ;an012; dms;save sectors/FAT | ||
| 3533 | ret ;an012; dms; | ||
| 3534 | |||
| 3535 | Calc_Small_FAT endp ;an012; dms; | ||
| 3536 | |||
| 3537 | ;========================================================================= | ||
| 3538 | ; Get_Bad_Sector_Hard : Determine the bad sector. | ||
| 3539 | ; | ||
| 3540 | ; Inputs : Head of failing track | ||
| 3541 | ; Cylinder of failing track | ||
| 3542 | ; Relative_Sector_Low - 1st. sector in track | ||
| 3543 | ; Relative_Sector_High | ||
| 3544 | ; | ||
| 3545 | ; Cluster_Boundary_Adj_Factor - The number of sectors | ||
| 3546 | ; that are to be read | ||
| 3547 | ; at one time. | ||
| 3548 | ; Cluster_Boundary_SPT_Count - Used by Calc_Cluster_Boundary | ||
| 3549 | ; to track how many sectors | ||
| 3550 | ; have been read. | ||
| 3551 | ; Cluster_Boundary_Flag - True (Use cluster buffer) | ||
| 3552 | ; - False (Use internal buffer) | ||
| 3553 | ; Cluster_Boundary_Buffer_Seg - Segment of buffer | ||
| 3554 | ; | ||
| 3555 | ; Outputs : Marked cluster as bad | ||
| 3556 | ;========================================================================= | ||
| 3557 | |||
| 3558 | Procedure Get_Bad_Sector_Hard ;an000; dms; | ||
| 3559 | |||
| 3560 | push cx ;an000; dms;save cx | ||
| 3561 | mov cx,0001h ;an000; dms;set counter to start at 1 | ||
| 3562 | mov Cluster_Boundary_SPT_Count,00h ;an000; dms;clear sector counter | ||
| 3563 | mov Cluster_Boundary_Adj_Factor,01h ;an000; dms;default value | ||
| 3564 | ; $do ;an000; dms;while sectors left | ||
| 3565 | $$DO115: | ||
| 3566 | cmp cx,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;at end? | ||
| 3567 | ; $leave a ;an000; dms;yes,exit | ||
| 3568 | JA $$EN115 | ||
| 3569 | push cx ;an000; dms;save cx | ||
| 3570 | |||
| 3571 | cmp Cluster_Boundary_Flag,True ;an000; dms;full buffer there? | ||
| 3572 | ; $if e ;an000; dms;yes | ||
| 3573 | JNE $$IF117 | ||
| 3574 | call Calc_Cluster_Boundary ;an000; dms;see if on boundary | ||
| 3575 | mov ax,Cluster_Boundary_Buffer_Seg | ||
| 3576 | mov word ptr RWPacket.TRWP_TransferAddress[0],0 ;an000; dms;point to transfer area | ||
| 3577 | mov word ptr RWPacket.TRWP_TransferAddress[2],ax ;an000; dms; | ||
| 3578 | ; $else ;an000; dms;default to internal buffer | ||
| 3579 | JMP SHORT $$EN117 | ||
| 3580 | $$IF117: | ||
| 3581 | mov word ptr RWPacket.TRWP_TransferAddress[0],offset RW_TRF_Area ;an000; dms;point to transfer area | ||
| 3582 | mov word ptr RWPacket.TRWP_TransferAddress[2],DS ;an000; dms; | ||
| 3583 | ; $endif ;an000; dms; | ||
| 3584 | $$EN117: | ||
| 3585 | |||
| 3586 | call Verify_Structure_Set_Up ;an019; dms; set up verify vars | ||
| 3587 | |||
| 3588 | mov ax,(IOCTL shl 8) or GENERIC_IOCTL ;an000; dms; | ||
| 3589 | xor bx,bx ;an000; dms;clear bx | ||
| 3590 | mov bl,drive ;an000; dms;get drive | ||
| 3591 | inc bl ;an000; dms;adjust it | ||
| 3592 | mov cx,(IOC_DC shl 8) or READ_TRACK ;an000; dms;read track | ||
| 3593 | lea dx,RWPacket ;an000; dms;point to parms | ||
| 3594 | int 21h ;an000; dms; | ||
| 3595 | |||
| 3596 | pop cx ;an000; dms;restore cx | ||
| 3597 | |||
| 3598 | push cx ;an000; dms;save cx | ||
| 3599 | |||
| 3600 | ; $if c ;an000; dms;an error occurred | ||
| 3601 | JNC $$IF120 | ||
| 3602 | call Calc_Cluster_Position ;an000; dms;determine which cluster | ||
| 3603 | call BadClus ;an000; dms;mark the cluster as bad | ||
| 3604 | ; $endif ;an000; dms; | ||
| 3605 | $$IF120: | ||
| 3606 | |||
| 3607 | pop cx ;an000; dms;restore cx | ||
| 3608 | |||
| 3609 | add cx,Cluster_Boundary_Adj_Factor ;an000; dms;adjust loop counter | ||
| 3610 | mov ax,Cluster_Boundary_Adj_Factor ;an000; dms;get adjustment factor | ||
| 3611 | xor dx,dx ;an000; dms;clear dx | ||
| 3612 | add ax,Relative_Sector_Low ;an000; dms;add in low word | ||
| 3613 | adc dx,Relative_Sector_High ;an000; dms;pick up carry in high word | ||
| 3614 | mov Relative_Sector_Low,ax ;an000; dms;save low word | ||
| 3615 | mov Relative_Sector_High,dx ;an000; dms;save high word | ||
| 3616 | |||
| 3617 | |||
| 3618 | ; $enddo ;an000; dms; | ||
| 3619 | JMP SHORT $$DO115 | ||
| 3620 | $$EN115: | ||
| 3621 | |||
| 3622 | pop cx ;an000; dms;restore cx | ||
| 3623 | |||
| 3624 | ret ;an000; dms; | ||
| 3625 | |||
| 3626 | Get_Bad_Sector_Hard endp ;an000; dms; | ||
| 3627 | |||
| 3628 | |||
| 3629 | ;========================================================================= | ||
| 3630 | ; Verify_Structure_Set_Up : Set up the fields for the Read IOCTL | ||
| 3631 | ; to verify the sectors in a failing | ||
| 3632 | ; track. Also, it displays the | ||
| 3633 | ; message notifying the user of the | ||
| 3634 | ; sectors it is verifying. | ||
| 3635 | ;========================================================================= | ||
| 3636 | |||
| 3637 | Procedure Verify_Structure_Set_Up ;an019; dms;set up verify structure | ||
| 3638 | |||
| 3639 | mov RWPacket.TRWP_SpecialFunctions,00h ;an000; dms;reset special functions | ||
| 3640 | |||
| 3641 | mov ax,FormatPacket.FP_Head ;an000; dms;get current head | ||
| 3642 | mov RWPacket.TRWP_Head,ax ;an000; dms;get current head | ||
| 3643 | |||
| 3644 | mov ax,FormatPacket.FP_Cylinder ;an000; dms;get current cylinder | ||
| 3645 | mov RWPacket.TRWP_Cylinder,ax ;an000; dms;get current cylinder | ||
| 3646 | |||
| 3647 | dec cx ;an000; dms;make sector 0 based | ||
| 3648 | mov RWPacket.TRWP_FirstSector,cx ;an000; dms;get sector to read | ||
| 3649 | |||
| 3650 | mov ax,Cluster_Boundary_Adj_Factor ;an000; dms;get # of sectors to read | ||
| 3651 | mov RWPacket.TRWP_SectorsToReadWrite,ax ;an000; dms;read only # sector(s) | ||
| 3652 | |||
| 3653 | call Calc_Cluster_Position ;an019; dms;determine cluster number | ||
| 3654 | mov word ptr Msg_Allocation_Unit_Val[+2],dx ;an019; dms;save high word of cluster | ||
| 3655 | mov word ptr Msg_Allocation_Unit_Val[+0],ax ;an019; dms;save low word of cluster | ||
| 3656 | message MsgVerify | ||
| 3657 | |||
| 3658 | ret | ||
| 3659 | |||
| 3660 | Verify_Structure_Set_Up endp ;an019; dms; | ||
| 3661 | |||
| 3662 | |||
| 3663 | ;========================================================================= | ||
| 3664 | ; Get_Bad_Sector_Floppy : This routine marks an entire track as bad | ||
| 3665 | ; since it is a floppy disk. | ||
| 3666 | ; | ||
| 3667 | ; Inputs : Relative_Sector_Low - first sector | ||
| 3668 | ; | ||
| 3669 | ; Outputs : FAT marked with bad sectors | ||
| 3670 | ;========================================================================= | ||
| 3671 | |||
| 3672 | Procedure Get_Bad_Sector_Floppy ;an000; dms; | ||
| 3673 | |||
| 3674 | push bx ;an000; dms;save regs | ||
| 3675 | push cx ;an000; dms; | ||
| 3676 | |||
| 3677 | mov cx,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;get sectors/track | ||
| 3678 | ; $do ;an000; dms;while sectors left | ||
| 3679 | $$DO123: | ||
| 3680 | cmp cx,00 ;an000; dms;at end | ||
| 3681 | ; $leave e ;an000; dms;yes | ||
| 3682 | JE $$EN123 | ||
| 3683 | push bx ;an000; dms;save bx we destroy it | ||
| 3684 | push cx ;an000; dms;save cx we destroy it | ||
| 3685 | call Calc_Cluster_Position ;an000; dms;get cluster position | ||
| 3686 | call BadClus ;an000; dms;mark it as bad | ||
| 3687 | pop cx ;an000; dms;restore regs | ||
| 3688 | pop bx ;an000; dms; | ||
| 3689 | dec cx ;an000; dms;decrease loop counter | ||
| 3690 | inc Relative_Sector_Low ;an000; dms;next sector | ||
| 3691 | ; $enddo ;an000; dms; | ||
| 3692 | JMP SHORT $$DO123 | ||
| 3693 | $$EN123: | ||
| 3694 | |||
| 3695 | pop cx ;an000; dms;restore regs | ||
| 3696 | pop bx ;an000; dms; | ||
| 3697 | |||
| 3698 | ret ;an000; dms; | ||
| 3699 | |||
| 3700 | Get_Bad_Sector_Floppy endp ;an000; dms; | ||
| 3701 | |||
| 3702 | |||
| 3703 | ;========================================================================= | ||
| 3704 | ; Calc_Cluster_Position : This routine calculates which cluster the | ||
| 3705 | ; failing sector falls in. | ||
| 3706 | ; | ||
| 3707 | ; Inputs : Relative_Sector_High - high word of sector position | ||
| 3708 | ; Relative_Sector_Low - low word of sector position | ||
| 3709 | ; | ||
| 3710 | ; Outputs : DX:AX - Cluster position | ||
| 3711 | ;========================================================================= | ||
| 3712 | Procedure Calc_Cluster_Position ;an000; dms; | ||
| 3713 | |||
| 3714 | push cx ;an000; dms;save regs | ||
| 3715 | push di ;an000; dms; | ||
| 3716 | push si ;an000; dms; | ||
| 3717 | |||
| 3718 | xor dx,dx ;an000; dms;clear high word | ||
| 3719 | mov dx,word ptr Relative_Sector_High ;an000; dms;get the high sector word | ||
| 3720 | mov ax,word ptr Relative_Sector_Low ;an000; dms;get the low sector word | ||
| 3721 | sub ax,StartSector ;an000; dms;get relative sector # | ||
| 3722 | sbb dx,0 ;an000; dms;pick up borrow | ||
| 3723 | |||
| 3724 | mov si,dx ;an000; dms;get high word | ||
| 3725 | mov di,ax ;an000; dms;get low word | ||
| 3726 | xor cx,cx ;an000; dms;clear cx | ||
| 3727 | mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster | ||
| 3728 | call Divide_32_Bits ;an000; dms;32 bit division | ||
| 3729 | |||
| 3730 | mov dx,si ;an000; dms;get high word of result | ||
| 3731 | mov ax,di ;an000; dms;get low word of result | ||
| 3732 | add ax,2 ;an000; dms;adjust for cluster bias | ||
| 3733 | adc dx,0 ;an000; dms;pick up carry | ||
| 3734 | |||
| 3735 | pop si ;an000; dms;restore regs | ||
| 3736 | pop di ;an000; dms; | ||
| 3737 | pop cx ;an000; dms; | ||
| 3738 | |||
| 3739 | ret ;an000 ;dms; | ||
| 3740 | |||
| 3741 | Calc_Cluster_Position endp ;an000; dms; | ||
| 3742 | |||
| 3743 | |||
| 3744 | ;========================================================================= | ||
| 3745 | ; Cap_Char : This routine will capitalize the character passed in | ||
| 3746 | ; DL. | ||
| 3747 | ; | ||
| 3748 | ; Inputs : DL - Character to be capitalized | ||
| 3749 | ; | ||
| 3750 | ; Outputs : DL - Capitalized character | ||
| 3751 | ;========================================================================= | ||
| 3752 | |||
| 3753 | Procedure Cap_Char ;an011; dms; | ||
| 3754 | |||
| 3755 | push ax ;an011; dms;save ax | ||
| 3756 | mov ax,6520h ;an011; dms;capitalize character | ||
| 3757 | int 21h ;an011; dms; | ||
| 3758 | pop ax ;an011; dms;restore ax | ||
| 3759 | ret ;an011; dms; | ||
| 3760 | |||
| 3761 | Cap_Char endp ;an011; dms; | ||
| 3762 | |||
| 3763 | ;========================================================================= | ||
| 3764 | ; Set_Disk_Access_On_Off: This routine will either turn access on or off | ||
| 3765 | ; to a disk depending on the contents of the | ||
| 3766 | ; buffer passed in DX. | ||
| 3767 | ; | ||
| 3768 | ; Inputs : DX - pointer to buffer | ||
| 3769 | ; | ||
| 3770 | ;========================================================================= | ||
| 3771 | |||
| 3772 | Procedure Set_Disk_Access_On_Off ;an014; dms; | ||
| 3773 | |||
| 3774 | push ax ;an014; dms;save regs | ||
| 3775 | push bx ;an014; dms; | ||
| 3776 | push cx ;an014; dms; | ||
| 3777 | push dx ;an014; dms; | ||
| 3778 | |||
| 3779 | xor bx,bx ;an014; dms;clear bx | ||
| 3780 | mov bl,Drive ;an014; dms;get driver number | ||
| 3781 | inc bl ;an014; dms;make it 1 based | ||
| 3782 | call IsRemovable ;an014; dms;see if removable media | ||
| 3783 | ; $if c ;an014; dms;not removable | ||
| 3784 | JNC $$IF126 | ||
| 3785 | mov ax,(IOCTL shl 8) or Generic_IOCTL ;an014; dms;generic ioctl | ||
| 3786 | xor bx,bx ;an014; dms;clear bx | ||
| 3787 | mov bl,Drive ;an014; dms;get drive letter | ||
| 3788 | inc bl ;an014; dms;make it 1 based | ||
| 3789 | mov cx,(RAWIO shl 8) or Set_Access_Flag ;an014; dms;allow access to disk | ||
| 3790 | int 21h ;an014; dms; | ||
| 3791 | ; $endif ;an014; dms; | ||
| 3792 | $$IF126: | ||
| 3793 | |||
| 3794 | pop dx ;an014; dms;restore regs | ||
| 3795 | pop cx ;an014; dms; | ||
| 3796 | pop bx ;an014; dms; | ||
| 3797 | pop ax ;an014; dms; | ||
| 3798 | |||
| 3799 | ret ;an014; dms; | ||
| 3800 | |||
| 3801 | Set_Disk_Access_On_Off endp ;an014; dms; | ||
| 3802 | |||
| 3803 | |||
| 3804 | ;========================================================================= | ||
| 3805 | ; Get_Disk_Access : This routine will determine the access state of | ||
| 3806 | ; the disk. | ||
| 3807 | ; | ||
| 3808 | ; Inputs : DX - pointer to buffer | ||
| 3809 | ; Outputs : Disk_Access.DAC_Access_Flag - 0ffh signals access allowed | ||
| 3810 | ; to the disk previously. | ||
| 3811 | ; | ||
| 3812 | ;========================================================================= | ||
| 3813 | |||
| 3814 | Procedure Get_Disk_Access ;an014; dms; | ||
| 3815 | |||
| 3816 | push ax ;an014; dms;save regs | ||
| 3817 | push bx ;an014; dms; | ||
| 3818 | push cx ;an014; dms; | ||
| 3819 | push dx ;an014; dms; | ||
| 3820 | |||
| 3821 | xor bx,bx ;an014; dms;clear bx | ||
| 3822 | mov bl,Drive ;an014; dms;get driver number | ||
| 3823 | inc bl ;an014; dms;make it 1 based | ||
| 3824 | call IsRemovable ;an014; dms;see if removable media | ||
| 3825 | ; $if c ;an014; dms;not removable | ||
| 3826 | JNC $$IF128 | ||
| 3827 | mov ax,(IOCTL shl 8) or Generic_IOCTL ;an014; dms;generic ioctl | ||
| 3828 | xor bx,bx ;an014; dms;clear bx | ||
| 3829 | mov bl,Drive ;an014; dms;get drive letter | ||
| 3830 | inc bl ;an014; dms;make it 1 based | ||
| 3831 | mov cx,(RAWIO shl 8) or Get_Access_Flag ;an014; dms;determine disk access | ||
| 3832 | lea dx,Disk_Access ;an014; dms;point to parm list | ||
| 3833 | int 21h ;an014; dms; | ||
| 3834 | cmp Disk_Access.DAC_Access_Flag,01h ;an014; dms;access is currently allowed? | ||
| 3835 | ; $if e ;an014; dms;yes | ||
| 3836 | JNE $$IF129 | ||
| 3837 | mov Disk_Access.DAC_Access_Flag,0ffh ;an014; dms;signal access is currently allowed | ||
| 3838 | ; $endif ;an014; dms; | ||
| 3839 | $$IF129: | ||
| 3840 | ; $endif ;an014; dms; | ||
| 3841 | $$IF128: | ||
| 3842 | |||
| 3843 | pop dx ;an014; dms;restore regs | ||
| 3844 | pop cx ;an014; dms; | ||
| 3845 | pop bx ;an014; dms; | ||
| 3846 | pop ax ;an014; dms; | ||
| 3847 | |||
| 3848 | ret ;an014; dms; | ||
| 3849 | |||
| 3850 | Get_Disk_Access endp ;an014; dms; | ||
| 3851 | |||
| 3852 | ;========================================================================= | ||
| 3853 | ; Calc_Cluster_Boundary : This routine will determine where, within a | ||
| 3854 | ; cluster, a sector resides. | ||
| 3855 | ; | ||
| 3856 | ; Inputs : Relative_Sector_Low - Sector | ||
| 3857 | ; Relative_Sector_High | ||
| 3858 | ; | ||
| 3859 | ; Outputs : Cluster_Boundary_Adj_Factor - The number of sectors | ||
| 3860 | ; remaining in the cluster. | ||
| 3861 | ; Cluster_Boundary_SPT_Count - The count of sectors | ||
| 3862 | ; having been accessed for | ||
| 3863 | ; a track. | ||
| 3864 | ;========================================================================= | ||
| 3865 | |||
| 3866 | Procedure Calc_Cluster_Boundary ;an000; dms; | ||
| 3867 | |||
| 3868 | push ax ;an000; dms;save regs | ||
| 3869 | push bx ;an000; dms; | ||
| 3870 | push cx ;an000; dms; | ||
| 3871 | push dx ;an000; dms; | ||
| 3872 | push si ;an000; dms; | ||
| 3873 | push di ;an000; dms; | ||
| 3874 | |||
| 3875 | xor dx,dx ;an000; dms;clear high word | ||
| 3876 | mov dx,word ptr Relative_Sector_High ;an000; dms;get the high sector word | ||
| 3877 | mov ax,word ptr Relative_Sector_Low ;an000; dms;get the low sector word | ||
| 3878 | sub ax,StartSector ;an000; dms;get relative sector # | ||
| 3879 | sbb dx,0 ;an000; dms;pick up borrow | ||
| 3880 | |||
| 3881 | mov si,dx ;an000; dms;get high word | ||
| 3882 | mov di,ax ;an000; dms;get low word | ||
| 3883 | xor cx,cx ;an000; dms;clear cx | ||
| 3884 | mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster | ||
| 3885 | call Divide_32_Bits ;an000; dms;32 bit division | ||
| 3886 | |||
| 3887 | or cx,cx ;an000; dms;see if remainder exists | ||
| 3888 | ; $if nz ;an000; dms;remainder exists | ||
| 3889 | JZ $$IF132 | ||
| 3890 | xor bx,bx ;an021; dms; | ||
| 3891 | mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an021; dms;get sectors/cluster | ||
| 3892 | sub bx,cx ;an021; dms;get number of sectors to read | ||
| 3893 | mov Cluster_Boundary_Adj_Factor,bx ;ac021; dms;remainder = sector count | ||
| 3894 | ; $else ;an000; dms;no remainder | ||
| 3895 | JMP SHORT $$EN132 | ||
| 3896 | $$IF132: | ||
| 3897 | xor bx,bx ;an000; dms;clear bx | ||
| 3898 | mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster | ||
| 3899 | mov Cluster_Boundary_Adj_Factor,bx ;an000; dms;get sectors/cluster | ||
| 3900 | ; $endif ;an000; dms; | ||
| 3901 | $$EN132: | ||
| 3902 | |||
| 3903 | mov ax,Cluster_Boundary_SPT_Count ;an000; dms;get current sector count | ||
| 3904 | xor dx,dx ;an000; dms;clear high word | ||
| 3905 | add ax,Cluster_Boundary_Adj_Factor ;an000; dms;get next sector count | ||
| 3906 | cmp ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;exceeded sectors/track? | ||
| 3907 | ; $if a ;an000; dms;yes | ||
| 3908 | JNA $$IF135 | ||
| 3909 | mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;only use difference | ||
| 3910 | sub ax,Cluster_Boundary_SPT_Count ;an000; dms;get next sector count | ||
| 3911 | mov Cluster_Boundary_Adj_Factor,ax ;an000; dms; | ||
| 3912 | ; $endif ;an000; dms; | ||
| 3913 | $$IF135: | ||
| 3914 | |||
| 3915 | mov ax,Cluster_Boundary_SPT_Count ;an000; dms;get sector count | ||
| 3916 | xor dx,dx ;an000; dms;clear high word | ||
| 3917 | add ax,Cluster_Boundary_Adj_Factor ;an000; dms;get new sector count | ||
| 3918 | mov Cluster_Boundary_SPT_Count,ax ;an000; dms;save it | ||
| 3919 | |||
| 3920 | pop di ;an000; dms;restore regs | ||
| 3921 | pop si ;an000; dms; | ||
| 3922 | pop dx ;an000; dms;restore regs | ||
| 3923 | pop cx ;an000; dms; | ||
| 3924 | pop bx ;an000; dms; | ||
| 3925 | pop ax ;an000; dms; | ||
| 3926 | |||
| 3927 | ret ;an000; dms; | ||
| 3928 | |||
| 3929 | Calc_Cluster_Boundary endp ;an000; dms; | ||
| 3930 | |||
| 3931 | ;========================================================================= | ||
| 3932 | ; Cluster_Buffer_Allocate : This routine will allocate a buffer | ||
| 3933 | ; based on a cluster's size. If enough | ||
| 3934 | ; space does not exist, a cluster will | ||
| 3935 | ; be redefined to a smaller size for | ||
| 3936 | ; purposes of sector retries. | ||
| 3937 | ; | ||
| 3938 | ; Inputs : DeviceParameters.DP_BPB.BPB_BytesPerSector | ||
| 3939 | ; DeviceParameters.DP_BPB.BPB_SectorsPerCluster | ||
| 3940 | ; | ||
| 3941 | ; Outputs : Cluster_Boundary_Flag - True (space available) | ||
| 3942 | ; False(not enough space) | ||
| 3943 | ; Cluster_Boundary_Buffer_Seg - Pointer to buffer | ||
| 3944 | ;========================================================================= | ||
| 3945 | |||
| 3946 | Procedure Cluster_Buffer_Allocate ;an000; dms; | ||
| 3947 | |||
| 3948 | push ax ;an000; dms;save regs | ||
| 3949 | push bx ;an000; dms; | ||
| 3950 | push cx ;an000; dms; | ||
| 3951 | push dx ;an000; dms; | ||
| 3952 | |||
| 3953 | mov ax,(Alloc shl 8) ;an000; dms;allocate memory | ||
| 3954 | mov bx,0ffffh ;an000; dms;get available memory | ||
| 3955 | int 21h ;an000; dms; | ||
| 3956 | |||
| 3957 | mov ax,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an000; dms;get bytes/sector | ||
| 3958 | xor dx,dx ;an000; dms;clear high word | ||
| 3959 | xor cx,cx ;an000; dms;clear cx | ||
| 3960 | mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sector count | ||
| 3961 | mul cx ;an000; dms;get total byte count | ||
| 3962 | mov cl,4 ;an000; dms;set up shift count | ||
| 3963 | shr ax,cl ;an000; dms;divide by 16 | ||
| 3964 | inc ax ;an000; dms;round up | ||
| 3965 | |||
| 3966 | cmp bx,ax ;an000; dms;enough room | ||
| 3967 | ; $if a ;an000; dms;yes | ||
| 3968 | JNA $$IF137 | ||
| 3969 | mov bx,ax ;an000; dms;allocate needed memory | ||
| 3970 | mov ax,(Alloc shl 8) ;an000; dms; | ||
| 3971 | int 21h ;an000; dms; | ||
| 3972 | mov Cluster_Boundary_Buffer_Seg,ax ;an000; dms;save pointer to buffer | ||
| 3973 | mov Cluster_Boundary_Flag,True ;an000; dms;signal space available | ||
| 3974 | ; $else ;an000; dms;not enough room | ||
| 3975 | JMP SHORT $$EN137 | ||
| 3976 | $$IF137: | ||
| 3977 | mov Cluster_Boundary_Flag,False ;an000; dms;signal not enough space | ||
| 3978 | ; $endif ;an000; dms; | ||
| 3979 | $$EN137: | ||
| 3980 | |||
| 3981 | pop dx ;an000; dms;restore regs | ||
| 3982 | pop cx ;an000; dms; | ||
| 3983 | pop bx ;an000; dms; | ||
| 3984 | pop ax ;an000; dms; | ||
| 3985 | |||
| 3986 | ret ;an000; dms; | ||
| 3987 | |||
| 3988 | Cluster_Buffer_Allocate endp ;an000; dms; | ||
| 3989 | |||
| 3990 | |||
| 3991 | ;========================================================================= | ||
| 3992 | ; Set_CDS_Off - This routine disallows access to a | ||
| 3993 | ; disk if a format fails on a non-FAT | ||
| 3994 | ; formatted disk. | ||
| 3995 | ; | ||
| 3996 | ;========================================================================= | ||
| 3997 | |||
| 3998 | Procedure Set_CDS_Off ;an000; dms; | ||
| 3999 | |||
| 4000 | push ax ;an000; dms;save regs | ||
| 4001 | push dx ;an000; dms; | ||
| 4002 | |||
| 4003 | mov ax,5f08h ;an000; dms;reset CDS | ||
| 4004 | mov dl,Drive ;an000; dms;drive to reset | ||
| 4005 | int 21h ;an000; dms; | ||
| 4006 | |||
| 4007 | pop dx ;an000; dms;restore regs | ||
| 4008 | pop ax ;an000; dms; | ||
| 4009 | |||
| 4010 | ret ;an000; dms; | ||
| 4011 | |||
| 4012 | Set_CDS_Off endp ;an000; dms; | ||
| 4013 | |||
| 4014 | |||
| 4015 | ;========================================================================= | ||
| 4016 | ; Format_Access_Wrap_Up - This routine determines whether or | ||
| 4017 | ; not access should be allowed to the | ||
| 4018 | ; disk based on the exit status of | ||
| 4019 | ; format. | ||
| 4020 | ; | ||
| 4021 | ;========================================================================= | ||
| 4022 | |||
| 4023 | Procedure Format_Access_Wrap_Up ;an000; dms; | ||
| 4024 | |||
| 4025 | cmp Disk_Access.DAC_Access_Flag,0ffh ;an015; dms;access prev. allowed? | ||
| 4026 | ; $if ne ;an015; dms;no | ||
| 4027 | JE $$IF140 | ||
| 4028 | cmp ExitStatus,ExitOK ;an015; dms;good exit? | ||
| 4029 | ; $if ne ;an015; dms;no | ||
| 4030 | JE $$IF141 | ||
| 4031 | lea dx,Disk_Access ;an015; dms;point to parm block | ||
| 4032 | mov Disk_Access.DAC_Access_Flag,00h ;an015; dms;signal no disk access | ||
| 4033 | call Set_Disk_Access_On_Off ;an015; dms;don't allow disk access | ||
| 4034 | ; $else ;an015; dms;bad exit | ||
| 4035 | JMP SHORT $$EN141 | ||
| 4036 | $$IF141: | ||
| 4037 | lea dx,Disk_Access ;an015; dms;point to parm block | ||
| 4038 | mov Disk_Access.DAC_Access_Flag,01h ;an015; dms;signal disk access | ||
| 4039 | call Set_Disk_Access_On_Off ;an015; dms;allow disk access | ||
| 4040 | ; $endif ;an015; dms; | ||
| 4041 | $$EN141: | ||
| 4042 | ; $endif ;an015; dms; | ||
| 4043 | $$IF140: | ||
| 4044 | |||
| 4045 | cmp FAT_Flag,No ;an012; dms;non-FAT format? | ||
| 4046 | ; $if e ;an012; dms;yes | ||
| 4047 | JNE $$IF145 | ||
| 4048 | cmp ExitStatus,ExitOK ;an012; dms;good exit? | ||
| 4049 | ; $if ne ;an012; dms;no | ||
| 4050 | JE $$IF146 | ||
| 4051 | call Set_CDS_Off ;an012; dms;disallow FAT access | ||
| 4052 | ; $endif ;an012; dms; | ||
| 4053 | $$IF146: | ||
| 4054 | ; $endif ;an012; dms; | ||
| 4055 | $$IF145: | ||
| 4056 | |||
| 4057 | ret ;an000; dms; | ||
| 4058 | |||
| 4059 | Format_Access_Wrap_Up endp ;an000; dms; | ||
| 4060 | |||
| 4061 | ;========================================================================= | ||
| 4062 | ; BadClus_Address_Adjust - This routine adjusts the segment and | ||
| 4063 | ; offset to provide addressibility into | ||
| 4064 | ; the FAT table. | ||
| 4065 | ; | ||
| 4066 | ; Inputs : bx - high word to adjust segment for | ||
| 4067 | ; ax - low word to adjust segment for | ||
| 4068 | ; cx - segment to be adjusted | ||
| 4069 | ; | ||
| 4070 | ; Outputs : cx - new segment value | ||
| 4071 | ; ax - new offset value | ||
| 4072 | ;========================================================================= | ||
| 4073 | |||
| 4074 | Procedure BadClus_Address_Adjust ;an000; dms; | ||
| 4075 | |||
| 4076 | push bx ;an000; save regs | ||
| 4077 | push dx ;an000; | ||
| 4078 | push di ;an000; | ||
| 4079 | push si ;an000; | ||
| 4080 | |||
| 4081 | mov dx,cx ;an000; save segment value | ||
| 4082 | mov si,bx ;an000; get high word for divide | ||
| 4083 | mov di,ax ;an000; get low word for divide | ||
| 4084 | xor cx,cx ;an000; clear cx | ||
| 4085 | mov cl,Paragraph_Size ;an000; divide by 16 | ||
| 4086 | call Divide_32_Bits ;an000; perform division | ||
| 4087 | |||
| 4088 | add dx,di ;an000; adjust segment for result | ||
| 4089 | mov ax,cx ;an000; pick up the remainder | ||
| 4090 | mov cx,dx ;an000; pass back new segment | ||
| 4091 | |||
| 4092 | pop si ;an000; restore regs | ||
| 4093 | pop di ;an000; | ||
| 4094 | pop dx ;an000; | ||
| 4095 | pop bx ;an000; | ||
| 4096 | |||
| 4097 | ret ;an000; dms; | ||
| 4098 | |||
| 4099 | BadClus_Address_Adjust endp ;an000; dms; | ||
| 4100 | |||
| 4101 | |||
| 4102 | |||
| 4103 | ;========================================================================= | ||
| 4104 | ; NextTrack : This routine determines the next track to be | ||
| 4105 | ; formatted. | ||
| 4106 | ; | ||
| 4107 | ; Inputs : TracksLeft - # of tracks remaining | ||
| 4108 | ; Tracks_To_Format - # of tracks to format in 1 call | ||
| 4109 | ; FP_Head - disk head | ||
| 4110 | ; FP_Cylinder - disk cylinder | ||
| 4111 | ; | ||
| 4112 | ; Outputs : TracksLeft - # of tracks remaining | ||
| 4113 | ; FP_Head - disk head | ||
| 4114 | ; FP_Cylinder - disk cylinder | ||
| 4115 | ; CY - no tracks left to format | ||
| 4116 | ; NC - tracks left to format | ||
| 4117 | ;========================================================================= | ||
| 4118 | |||
| 4119 | Procedure NextTrack ;an015; dms; | ||
| 4120 | |||
| 4121 | |||
| 4122 | cmp TracksLeft,00 ;an015; dms;end of format? | ||
| 4123 | ; $if e ;an015; dms;yes | ||
| 4124 | JNE $$IF149 | ||
| 4125 | stc ;an015; dms;signal end of format | ||
| 4126 | mov Format_End,True | ||
| 4127 | ; $else | ||
| 4128 | JMP SHORT $$EN149 | ||
| 4129 | $$IF149: | ||
| 4130 | mov cx,Tracks_To_Format ;an015; dms;get max track count for call | ||
| 4131 | ; $do ;an015; dms;while tracks remain | ||
| 4132 | $$DO151: | ||
| 4133 | cmp TracksLeft,00 ;an015; dms;end of format? | ||
| 4134 | ; $leave e ;an015; dms;yes | ||
| 4135 | JE $$EN151 | ||
| 4136 | cmp cx,00 ;an015; dms;end of head/cyl. adjustment? | ||
| 4137 | ; $leave e ;an015; dms;yes | ||
| 4138 | JE $$EN151 | ||
| 4139 | inc FormatPacket.FP_Head ;an015; dms;next head | ||
| 4140 | mov ax,FormatPacket.FP_Head ;an015; dms;get head for comp | ||
| 4141 | cmp ax,DeviceParameters.DP_BPB.BPB_Heads ;an015; dms;exceeded head count? | ||
| 4142 | ; $if e ;an015; dms;yes | ||
| 4143 | JNE $$IF154 | ||
| 4144 | mov FormatPacket.FP_Head,00 ;an015; dms;reinit. head | ||
| 4145 | inc FormatPacket.FP_Cylinder ;an015; dms;next cylinder | ||
| 4146 | ; $endif ;an015; dms; | ||
| 4147 | $$IF154: | ||
| 4148 | |||
| 4149 | dec cx ;an015; dms;decrease counter | ||
| 4150 | ; $enddo ;an015; dms; | ||
| 4151 | JMP SHORT $$DO151 | ||
| 4152 | $$EN151: | ||
| 4153 | |||
| 4154 | clc ;an015; dms;clear CY | ||
| 4155 | ; $endif ;an015; dms; | ||
| 4156 | $$EN149: | ||
| 4157 | |||
| 4158 | ret ;an015; dms; | ||
| 4159 | |||
| 4160 | NextTrack endp ;an015; dms; | ||
| 4161 | |||
| 4162 | ;========================================================================= | ||
| 4163 | ; Determine_Format_Type : This routine determines the type of format | ||
| 4164 | ; that is to occur based on the media type. | ||
| 4165 | ; | ||
| 4166 | ; Inputs : Dev_HardDisk - Media type (harddisk) | ||
| 4167 | ; Multi_Track_Format - EQU 02h | ||
| 4168 | ; Single_Track_Format - EQU 00h | ||
| 4169 | ; | ||
| 4170 | ; Outputs : FP_SpecialFunctions - Set appropriately for single | ||
| 4171 | ; or multi track format | ||
| 4172 | ;========================================================================= | ||
| 4173 | |||
| 4174 | Procedure Determine_Format_Type ;an015; dms; | ||
| 4175 | |||
| 4176 | cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk? | ||
| 4177 | ; $if e ;an015; dms;yes | ||
| 4178 | JNE $$IF158 | ||
| 4179 | mov FormatPacket.FP_SpecialFunctions,Multi_Track_Format ;an015; dms;set for multi track format | ||
| 4180 | ; $else ;an015; dms; | ||
| 4181 | JMP SHORT $$EN158 | ||
| 4182 | $$IF158: | ||
| 4183 | mov FormatPacket.FP_SpecialFunctions,Single_Track_Format ;an015; dms;set for single track format | ||
| 4184 | ; $endif ;an015; dms; | ||
| 4185 | $$EN158: | ||
| 4186 | ret ;an015; dms; | ||
| 4187 | |||
| 4188 | Determine_Format_Type endp ;an015; dms; | ||
| 4189 | |||
| 4190 | |||
| 4191 | ;========================================================================= | ||
| 4192 | ; FormatTrack : This routine performs multi track or single | ||
| 4193 | ; track formatting based on the state of the | ||
| 4194 | ; SpecialFunctions byte. | ||
| 4195 | ; | ||
| 4196 | ; Inputs : Tracks_To_Format - # of tracks to format in 1 call | ||
| 4197 | ; FormatPacket - Parms for IOCTL call | ||
| 4198 | ; | ||
| 4199 | ; Outputs : NC - formatted track(s) | ||
| 4200 | ; CY - error in format | ||
| 4201 | ; AX - extended error on CY | ||
| 4202 | ;========================================================================= | ||
| 4203 | |||
| 4204 | Procedure FormatTrack ;an015; dms; | ||
| 4205 | |||
| 4206 | mov ax,(IOCTL shl 8) or Generic_IOCTL ;an015; dms;Generic IOCTL | ||
| 4207 | mov bl,drive ;an015; dms;get drive number | ||
| 4208 | inc bl ;an015; dms;make it 1 based | ||
| 4209 | mov cx,(RawIO shl 8) or Format_Track ;an015; dms;Format track(s) | ||
| 4210 | mov dx,Tracks_To_Format ;an015; dms;get track count | ||
| 4211 | mov FormatPacket.FP_TrackCount,dx ;an015; dms;put count in parms list | ||
| 4212 | lea dx,FormatPacket ;an015; dms;ptr to parms | ||
| 4213 | int 21h ;an015; dms; | ||
| 4214 | |||
| 4215 | ; $if c ;an015; dms;error? | ||
| 4216 | JNC $$IF161 | ||
| 4217 | mov ah,59h ;an015; dms;get extended error | ||
| 4218 | xor bx,bx ;an015; dms;clear bx | ||
| 4219 | int 21h ;an015; dms; | ||
| 4220 | stc ;an015; dms;flag an error | ||
| 4221 | ; $endif ;an015; dms; | ||
| 4222 | $$IF161: | ||
| 4223 | |||
| 4224 | ret ;an015; dms; | ||
| 4225 | |||
| 4226 | FormatTrack endp ;an015; dms; | ||
| 4227 | |||
| 4228 | |||
| 4229 | ;========================================================================= | ||
| 4230 | ; Determine_Track_Count : This routine determines the number of | ||
| 4231 | ; tracks to be formatted, based on whether | ||
| 4232 | ; or not we have a hard disk. If we have | ||
| 4233 | ; a hard disk we can use multi-track | ||
| 4234 | ; format/verify, otherwise we use the | ||
| 4235 | ; single track format/verify. | ||
| 4236 | ; | ||
| 4237 | ; Inputs : Device_Type - Media type | ||
| 4238 | ; | ||
| 4239 | ; Outputs : Tracks_To_Format - Max. number of tracks | ||
| 4240 | ; to be formatted in one | ||
| 4241 | ; call | ||
| 4242 | ;========================================================================= | ||
| 4243 | |||
| 4244 | Procedure Determine_Track_Count ;an015; dms; | ||
| 4245 | |||
| 4246 | cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk? | ||
| 4247 | ; $if e ;an015; dms;yes | ||
| 4248 | JNE $$IF163 | ||
| 4249 | call Calc_Track_Count ;an015; dms;calc Tracks_To_Format | ||
| 4250 | ; $else ;an015; dms;removable media | ||
| 4251 | JMP SHORT $$EN163 | ||
| 4252 | $$IF163: | ||
| 4253 | mov Tracks_To_Format,0001h ;an015; dms;default to 1 track | ||
| 4254 | ; $endif ;an015; dms; | ||
| 4255 | $$EN163: | ||
| 4256 | |||
| 4257 | ret ;an015; dms; | ||
| 4258 | |||
| 4259 | Determine_Track_Count endp ;an015;dms; | ||
| 4260 | |||
| 4261 | |||
| 4262 | ;========================================================================= | ||
| 4263 | ; Calc_Track_Count : This routine determines if we have enough tracks | ||
| 4264 | ; remaining to use the max. number of tracks | ||
| 4265 | ; in the FormatTrack call. If the tracks remaining | ||
| 4266 | ; to be formatted is less that the max. number of | ||
| 4267 | ; allowable tracks for the call, the max. number | ||
| 4268 | ; of allowable tracks is set to the remaining track | ||
| 4269 | ; count. | ||
| 4270 | ; | ||
| 4271 | ; Inputs : Track_Count - Max. number of allowable tracks to be | ||
| 4272 | ; formatted in 1 FormatTrack call. | ||
| 4273 | ; TracksLeft - Track count of remaining tracks to be | ||
| 4274 | ; formatted. | ||
| 4275 | ; | ||
| 4276 | ; Outputs : Tracks_To_Format - Count of the tracks to be formatted | ||
| 4277 | ; in the next FormatTrack call. | ||
| 4278 | ; | ||
| 4279 | ; | ||
| 4280 | ;========================================================================= | ||
| 4281 | |||
| 4282 | Procedure Calc_Track_Count ;an015; dms; | ||
| 4283 | |||
| 4284 | push ax ;an015; dms;save regs | ||
| 4285 | mov ax,Track_Count ;an015; dms;max bytes to format | ||
| 4286 | cmp ax,TracksLeft ;an015; dms;too many tracks? | ||
| 4287 | ; $if a ;an015; dms;yes | ||
| 4288 | JNA $$IF166 | ||
| 4289 | mov ax,TracksLeft ;an015; dms;format remaining tracks | ||
| 4290 | ; $endif ;an015; dms; | ||
| 4291 | $$IF166: | ||
| 4292 | mov Tracks_To_Format,ax ;an015; dms;save track count | ||
| 4293 | |||
| 4294 | pop ax ;an015; dms; | ||
| 4295 | |||
| 4296 | ret ;an015; dms; | ||
| 4297 | |||
| 4298 | Calc_Track_Count endp ;an015; dms; | ||
| 4299 | |||
| 4300 | ;========================================================================= | ||
| 4301 | ; Calc_Max_Tracks_To_Format : This routine determines the maximum | ||
| 4302 | ; number of tracks to format at 1 time. | ||
| 4303 | ; | ||
| 4304 | ; Inputs : DeviceParameters - SectorsPerTrack | ||
| 4305 | ; BytesPerSector | ||
| 4306 | ; | ||
| 4307 | ; Outputs : Track_Count - Max. # of tracks to format in 1 call | ||
| 4308 | ; to FormatTrack | ||
| 4309 | ;========================================================================= | ||
| 4310 | |||
| 4311 | Procedure Calc_Max_Tracks_To_Format | ||
| 4312 | |||
| 4313 | push ax ;an015; dms;save regs | ||
| 4314 | push bx ;an015; dms; | ||
| 4315 | push dx ;an015; dms; | ||
| 4316 | |||
| 4317 | mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an015; dms;get sectors per track | ||
| 4318 | mov bx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an015; dms;get byte count | ||
| 4319 | xor dx,dx ;an015; dms;clear dx | ||
| 4320 | mul bx ;an015; dms;get total byte count | ||
| 4321 | mov bx,ax ;an015; dms;put count in bx | ||
| 4322 | mov ax,Max_Format_Size ;an015; dms;max bytes to format | ||
| 4323 | div bx ;an015; dms;get track count | ||
| 4324 | mov Track_Count,ax | ||
| 4325 | |||
| 4326 | pop dx ;an015; dms; | ||
| 4327 | pop bx ;an015; dms; | ||
| 4328 | pop ax ;an015; dms; | ||
| 4329 | |||
| 4330 | ret | ||
| 4331 | |||
| 4332 | Calc_Max_Tracks_To_Format endp | ||
| 4333 | |||
| 4334 | |||
| 4335 | |||
| 4336 | |||
| 4337 | |||
| 4338 | ;========================================================================= | ||
| 4339 | ; Format_Track_Retry : This routine performs the retry logic for | ||
| 4340 | ; the format multi-track. It will retry each track | ||
| 4341 | ; until the failing track is encountered through | ||
| 4342 | ; a CY condition. | ||
| 4343 | ; | ||
| 4344 | ; Inputs : none | ||
| 4345 | ; | ||
| 4346 | ; Outputs : CY - indicates either a failing track or end of format | ||
| 4347 | ; | ||
| 4348 | ; | ||
| 4349 | ;========================================================================= | ||
| 4350 | |||
| 4351 | Procedure Format_Track_Retry | ||
| 4352 | |||
| 4353 | clc ;an022; dms; clear existing CY | ||
| 4354 | mov Tracks_To_Format,1 ;an015; dms; only format 1 track | ||
| 4355 | ; $do ;an015; dms; while we have good tracks | ||
| 4356 | $$DO168: | ||
| 4357 | ; $leave c ;an015; dms; exit on bad track | ||
| 4358 | JC $$EN168 | ||
| 4359 | call FormatTrack ;an015; dms; format the track | ||
| 4360 | ; $if nc ;an015; dms;error? | ||
| 4361 | JC $$IF170 | ||
| 4362 | call DisplayCurrentTrack ;an022; dms;adjust percent counter | ||
| 4363 | call Adj_Track_Count | ||
| 4364 | call NextTrack ;an015; dms;calc next track | ||
| 4365 | ; $endif ;an015; dms; | ||
| 4366 | $$IF170: | ||
| 4367 | ; $enddo ;an015; dms; | ||
| 4368 | JMP SHORT $$DO168 | ||
| 4369 | $$EN168: | ||
| 4370 | |||
| 4371 | ret ;an015; dms; | ||
| 4372 | |||
| 4373 | Format_Track_Retry endp ;an015; dms; | ||
| 4374 | |||
| 4375 | ;========================================================================= | ||
| 4376 | ; Format_Loop : This routine provides the main template | ||
| 4377 | ; for the formatting of a disk. A disk | ||
| 4378 | ; will be formatted as long as there are | ||
| 4379 | ; tracks remaining to be formatted. | ||
| 4380 | ; This routine can be exited on a carry | ||
| 4381 | ; condition; i.e., bad track, last track, etc. | ||
| 4382 | ; | ||
| 4383 | ; Inputs : none | ||
| 4384 | ; | ||
| 4385 | ; Outputs : CY - Set on exit from this routine | ||
| 4386 | ; AX - Possible error condition code | ||
| 4387 | ;========================================================================= | ||
| 4388 | |||
| 4389 | Procedure Format_Loop ;an015; dms; | ||
| 4390 | |||
| 4391 | clc ;an015; dms;initialize to NC | ||
| 4392 | ; $do ;an015; dms;while NC | ||
| 4393 | $$DO173: | ||
| 4394 | ; $leave c ;an015; dms;exit on CY | ||
| 4395 | JC $$EN173 | ||
| 4396 | call Calc_Current_Head_Cyl ;an015; dms;head and cylinder calc. | ||
| 4397 | call Determine_Format_Type ;an015; dms;floppy/hard media? | ||
| 4398 | call Determine_Track_Count ;an015; dms;how many tracks? | ||
| 4399 | call FormatTrack ;an015; dms;format track(s) | ||
| 4400 | ; $if c ;an015; dms;formattrack failed | ||
| 4401 | JNC $$IF175 | ||
| 4402 | pushf ;an015; dms;save flags | ||
| 4403 | cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk? | ||
| 4404 | ; $if e ;an015; dms;yes | ||
| 4405 | JNE $$IF176 | ||
| 4406 | popf ;an015; dms;restore flags | ||
| 4407 | call Format_Track_Retry ;an015; dms;find failing track | ||
| 4408 | ; $else ;an015; dms; | ||
| 4409 | JMP SHORT $$EN176 | ||
| 4410 | $$IF176: | ||
| 4411 | popf ;an015; dms;restore flags | ||
| 4412 | ; $endif ;an015; dms; | ||
| 4413 | $$EN176: | ||
| 4414 | ; $endif ;an015; dms; | ||
| 4415 | $$IF175: | ||
| 4416 | |||
| 4417 | ; $if c ;an015; dms;format error? | ||
| 4418 | JNC $$IF180 | ||
| 4419 | pushf ;an015; dms;yes - save flags | ||
| 4420 | push ax ;an015; dms;save return code | ||
| 4421 | call CheckRealErrors ;an015; dms;check error type | ||
| 4422 | ; $if nc ;an015; dms;if non-fatal | ||
| 4423 | JC $$IF181 | ||
| 4424 | call DisplayCurrentTrack ;an015; dms;display % formatted | ||
| 4425 | ; $endif ;an015; dms; | ||
| 4426 | $$IF181: | ||
| 4427 | pop ax ;an015; dms;restore regs | ||
| 4428 | popf ;an015; dms; | ||
| 4429 | ; $endif ;an015; dms; | ||
| 4430 | $$IF180: | ||
| 4431 | |||
| 4432 | ; $leave c ;an015; dms;exit on CY | ||
| 4433 | JC $$EN173 | ||
| 4434 | |||
| 4435 | call DisplayCurrentTrack ;an015; dms;tell how much formatted | ||
| 4436 | call Adj_Track_Count ;an015; dms;decrease track counter | ||
| 4437 | call NextTrack ;an015; dms;adjust head and cylinder | ||
| 4438 | ; $enddo ;an015; dms; | ||
| 4439 | JMP SHORT $$DO173 | ||
| 4440 | $$EN173: | ||
| 4441 | ret ;an015; dms; | ||
| 4442 | |||
| 4443 | Format_Loop endp ;an015; dms; | ||
| 4444 | |||
| 4445 | ;========================================================================= | ||
| 4446 | ; Adj_Track_Count : This routine adjusts the track count by the | ||
| 4447 | ; number of tracks that have been formatted | ||
| 4448 | ; in one FormatTrack call. | ||
| 4449 | ; | ||
| 4450 | ; Inputs : TracksLeft - # of tracks remaining to be formatted | ||
| 4451 | ; Tracks_To_Format - Tracks formatted in 1 call | ||
| 4452 | ; | ||
| 4453 | ; Outputs : TracksLeft - # of tracks remaining to be formatted | ||
| 4454 | ;========================================================================= | ||
| 4455 | |||
| 4456 | Procedure Adj_Track_Count ;an015; dms; | ||
| 4457 | |||
| 4458 | push ax ;an015; dms; save regs | ||
| 4459 | mov ax,TracksLeft ;an015; dms; get tracks remaining | ||
| 4460 | sub ax,Tracks_To_Format ;an015; dms; subtract amount formatted | ||
| 4461 | mov TracksLeft,ax ;an015; dms; save new tracks remaining value | ||
| 4462 | pop ax ;an015; dms; restore regs | ||
| 4463 | ret ;an015; dms; | ||
| 4464 | |||
| 4465 | Adj_Track_Count endp ;an015; dms; | ||
| 4466 | |||
| 4467 | ;========================================================================= | ||
| 4468 | ; Prompt_User_For_Disk : This routine prompts the user for the | ||
| 4469 | ; disk to be formatted. An appropriate | ||
| 4470 | ; message is chosen based on the type | ||
| 4471 | ; of switch entered. If the /SELECT | ||
| 4472 | ; switch is entered, the disk prompt is | ||
| 4473 | ; issued through the INT 2fh services | ||
| 4474 | ; provided by SELECT. | ||
| 4475 | ; | ||
| 4476 | ; Inputs : Switchmap - Switches chosen for format | ||
| 4477 | ; | ||
| 4478 | ; Outputs : Message printed as appropriate. | ||
| 4479 | ;========================================================================= | ||
| 4480 | |||
| 4481 | Procedure Prompt_User_For_Disk ;an016;dms; | ||
| 4482 | |||
| 4483 | push ax ;an016;dms;save ax | ||
| 4484 | test switchmap, (SWITCH_Backup or SWITCH_Select or SWITCH_AUTOTEST) ;Suppress prompt? ;AC000; | ||
| 4485 | ; $IF Z ; ;AC000; | ||
| 4486 | JNZ $$IF186 | ||
| 4487 | call DSKPRM ; prompt user for disk | ||
| 4488 | ; $ENDIF ; ;AC000; | ||
| 4489 | $$IF186: | ||
| 4490 | |||
| 4491 | test switchmap, (Switch_Select) ;an016;dms;/SELECT requested? | ||
| 4492 | ; $if nz ;an016;dms;yes | ||
| 4493 | JZ $$IF188 | ||
| 4494 | mov al, drive ;an016;dms;get drive to access for format | ||
| 4495 | call AccessDisk ;an016;dms;access the disk | ||
| 4496 | mov ax,Select_Disk_Message ;an016;dms;display disk prompt | ||
| 4497 | int 2fh ;an016;dms; through INT 2fh services | ||
| 4498 | ; $endif ;an016;dms; | ||
| 4499 | $$IF188: | ||
| 4500 | pop ax ;an016;dms;restore ax | ||
| 4501 | |||
| 4502 | ret ;an016;dms; | ||
| 4503 | |||
| 4504 | Prompt_User_For_Disk endp ;an016;dms; | ||
| 4505 | |||
| 4506 | |||
| 4507 | code ends | ||
| 4508 | END START | ||
| 4509 | \ No newline at end of file | ||