📄 format.asm
字号:
MOV AX,CX
XOR DX,DX
push bx
xor bx,bx
mov bl, deviceParameters.DP_BPB.BPB_SectorsPerCluster
DIV bx
pop bx
MOV CX,AX ; CX is rounded up and converted to a
; to a cluster #. Where cluster 0 =
; first cluster of data. Last bad
; Sector is in cluster CX.
SUB CX,BX
INC CX ; CX is number of clusters to mark bad
ADD BX,2 ; Bias start by correct amount since
; first cluster of data is really
; cluster 2.
xor ax,ax
MOV Al,deviceParameters.DP_BPB.BPB_SectorsPerCluster
MUL deviceParameters.DP_BPB.BPB_BytesPerSector
MOV BP,AX ; = Bytes/Cluster
; Mark CX clusters bad starting at cluster BX
PACKIT:
CALL BadClus ;Put it in the allocation map
JZ BAD150 ;If already marked bad, don't count it
ADD WORD PTR BADSIZ,BP ;Add in number of bad bytes
JNB BAD150
INC WORD PTR BADSIZ+2
BAD150:
INC BX ;Next cluster
LOOP PACKIT ;Continue for # of clusters
JMP GETTRK
; Inputs: BX = Cluster number
; Outputs: The given cluster is marked as invalid
; Zero flag is set if the cluster was already marked bad
; Registers modified: DX,SI
; No other registers affected
BadClus:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
CMP fBigFat,-1 ; if (!fBigFat) {
JZ DoBig
MOV DX,0FF7h ; badval = 0xFF7;
MOV AX,0FFFh ; mask = 0xFFF;
MOV SI,BX ; p = FAT+clus+clus/2;
SHR SI,1
ADD SI,BX
ADD SI, word ptr fatspace
TEST BX,1 ; if (clus&1) {
JZ DoSet
MOV CL,4 ; mask <<= 4;
SHL AX,CL
MOV CL,4 ; badval <<= 4;
SHL DX,CL ; }
JMP SHORT DoSet
DoBig: ; else {
MOV DX,0FFF7h ; badval = 0xFFF7;
MOV AX,0FFFFh ; mask = 0xFFFF;
MOV SI, word ptr fatSpace ; p = FAT + clus + clus;
ADD SI,BX
ADD SI,BX
DoSet: ; }
push es
mov es, word ptr fatSpace + 2
MOV CX,es:[SI] ; op = *p & mask;
AND CX,AX
NOT AX ; *p &= ~mask;
AND es:[SI],AX
OR es:[SI],DX ; *p |= badval;
CMP DX,CX ; return op == badval;
pop es
POP DX
POP CX
POP BX
POP AX
return
DRTFAT:
TEST SWITCHMAP,SWITCH_S ;If system requested, calculate size
JZ CLEARED
CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space?
JNZ CLEARED ;Yes
INC BYTE PTR DBLFLG ;No -- set the flag
CALL GETSIZE ;Calculate the system size
CLEARED:
CALL WriteFileSystem
JNC FATWRT
LOUSE:
lea dx, msgDiskUnusable
call PrintString
JMP FRMTPROB
LOUSEP:
POP DS
JMP LOUSE
FATWRT:
PUSH DS
MOV DL,DRIVE
INC DL
MOV AH,GET_DPB
INT 21H
CMP AL,-1
JZ LOUSEP ;Something BAD has happened
MOV [BX.dpb_next_free],0 ; Reset allocation to start of disk
MOV [BX.dpb_free_cnt],-1 ; Force free space to be computed
POP DS
TEST SWITCHMAP,SWITCH_S ;System desired
JZ STATUS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp
;reintroduce following section of code
;
CALL CHKSPACE ;Enough free space for system?
JNC SPACEOK ; Y: Go load system files
LEA DX, msgNoRoomDestDisk ; N: Print error message
CALL PrintString ;
MOV WORD PTR SYSSIZ+2,0 ;No system transfered
MOV WORD PTR SYSSIZ,0 ;No system transfered
JMP SHORT STATUS ;
SPACEOK: ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp
mov al, drive
call AccessDisk ; note what is current logical drive
CALL WRITEDOS ;Write the BIOS & DOS
JNC SYSOK
lea dx, msgNotSystemDisk
call PrintString
MOV WORD PTR SYSSIZ+2,0 ;No system transfered
MOV WORD PTR SYSSIZ,0 ;No system transfered
JMP SHORT STATUS
SYSOK:
lea dx, msgSystemTransfered
call PrintString
STATUS:
CALL CRLF
CALL VOLID
MOV AH,DISK_RESET
INT 21H
CALL DONE ;Final call to OEM module
JNC REPORTC
JMP FRMTPROB ;Report an error
REPORTC:
CALL REPORT
CALL MORE ;See if more disks to format
JMP SYSLOOP ;If we returned from MORE then continue
;******************************************
; Calculate the size in bytes of the system rounded up to sector and
; cluster boundries, Answer in SYSSIZ
GetSize proc near
call GetBioSize
call GetDosSize
call GetCmdSize
return
GetSize endp
GetBioSize proc near
MOV AX,WORD PTR bios.fileSizeInBytes
MOV DX,WORD PTR bios.fileSizeInBytes+2
CALL AddToSystemSize
return
GetBioSize endp
GetDosSize proc near
MOV AX,WORD PTR dos.fileSizeInBytes
MOV DX,WORD PTR dos.fileSizeInBytes+2
CALL AddToSystemSize
return
GetDosSize endp
GetCmdSize proc near
MOV AX,WORD PTR command.fileSizeInBytes
MOV DX,WORD PTR command.fileSizeInBytes+2
call AddToSystemSize
return
GetCmdSize endp
;Calculate the number of sectors used for the system
PUBLIC AddToSystemSize
AddToSystemSize proc near
push bx
DIV deviceParameters.DP_BPB.BPB_BytesPerSector
OR DX,DX
JZ FNDSIZ0
INC AX ; Round up to next sector
FNDSIZ0:
PUSH AX
XOR DX,DX
xor bx,bx
mov bl, deviceParameters.DP_BPB.BPB_SectorsPerCluster
div bx
POP AX
OR DX,DX
JZ ONCLUS
SUB DX, bx
NEG DX
ADD AX,DX ; Round up sector count to cluster
; boundry
ONCLUS:
MUL deviceParameters.DP_BPB.BPB_BytesPerSector
ADD WORD PTR SYSSIZ,AX
ADC WORD PTR SYSSIZ+2,DX
pop bx
return
AddToSystemSize endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp
; reintroduce following section of code
;; Check free space to see if there is enough room to load the system
;; On Entry: DL = drive
;; On Exit: carry flag set if not enough room
;; no other registers are affected
CHKSPACE PROC NEAR
PUSH AX ;Save resisters
PUSH BX
PUSH CX
PUSH DX
MOV AH,36H ;Get free space
INT 21h
;;16 bit math okay here, no danger of overflow
MUL CX ;Get bytes/cluster
MOV CX,AX ;
MOV AX,WORD PTR SYSSIZ ;Get # of bytes for system
MOV DX,WORD PTR SYSSIZ+2 ;
DIV CX ;Get # of clusters for system
CMP AX,BX ;Is there enough space?
JBE ENOUGHSPACE ; Y: Go clear carry
STC ; N: Set carry
JMP SHORT RESTOREREGS ;
;
ENOUGHSPACE:
CLC
;
RESTOREREGS:
POP DX ;Restore resisters
POP CX
POP BX
POP AX
RET
CHKSPACE ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp
MORE: CMP deviceParameters.DP_DeviceType, DEV_HARDDISK
je ExitProgram
CALL FormatAnother? ;Get yes or no response
JC ExitProgram
CALL CRLF
JMP CRLF
FEXIT:
mov ExitStatus,ExitFatal
ExitProgram:
test validSavedDeviceParameters, 0ffH
jz DoNotRestoreDeviceParameters
mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD
lea dx, savedDeviceParameters
call SetDeviceParameters
DoNotRestoreDeviceParameters:
mov al, ExitStatus
mov ah,exit
INT 21H
; Prompt the user for a system diskette in the default drive
SYSPRM:
MOV AH,GET_DEFAULT_DRIVE ;Will find out the default drive
INT 21H ;Default now in AL
MOV BL,AL
INC BL ; A = 1
ADD AL,41H ;Now in Ascii
MOV systemDriveLetter,AL ;Text now ok
CALL IsRemovable
JNC DoPrompt
;
; Media is non-removable. Switch sys disk to drive A. Check, though, to see
; if drive A is removable too.
;
MOV AL,"A"
MOV BYTE PTR [systemDriveLetter],AL
MOV [BiosFile],AL
MOV [DosFile],AL
MOV [CommandFile],AL
MOV BX,1
CALL IsRemovable
JNC DoPrompt
lea dx, msgNoSystemFiles
call PrintString
fexitJ:
JMP FEXIT
DoPrompt:
mov al, systemDriveLetter
sub al, 'A'
call AccessDisk
lea dx, ptr_msgInsertDosDisk
CALL std_printf ;Print first line
CALL USER_STRING ;Wait for a key
CALL CRLF
return
TARGPRM:
mov al, drive
call AccessDisk
lea DX, ptr_msgInsertDisk
CALL std_printf ;Print first line
CALL USER_STRING ;Wait for a key
CALL CRLF
return
;
; Determine if the drive indicated in BX is removable or not.
;
; Inputs: BX has drive (0=def, 1=A)
; Outputs: Carry clear
; Removable
; Carry set
; not removable
; Registers modified: none
IsRemovable:
SaveReg <AX>
MOV AX,(IOCTL SHL 8) OR 8 ; Rem media check
INT 21H
JNC CheckRemove
MOV AX,(IOCTL SHL 8) + 9 ; Is it a NET drive?
INT 21h
JC NotRemove ; Yipe, say non-removable
TEST DX,1000h
JNZ NotRemove ; Is NET drive, say non-removeable
JMP IsRemove ; Is local, say removable
CheckRemove:
TEST AX,1
JNZ NotRemove
IsRemove:
CLC
RestoreReg <AX>
return
NotRemove:
STC
RestoreReg <AX>
return
; DiSKPRoMpt:
;
; This routine prompts for the insertion of the correct diskette
; into the Target drive, UNLESS we are being re-entrantly invoked
; from LastChanceToSaveIt. If the target is a Hardisk we issue a
; warning message.
;
; INPUTS:
; deviceParameters.DP_DeviceType
; fLastChance
;
; OUTPUTS:
; Prompt string
; fLastChance := FALSE
;
; Registers affected:
; Flags
;
DSKPRM:
CMP fLastChance,TRUE
JE PrmptRet
CMP deviceParameters.DP_DeviceType, DEV_HARDDISK
jne goprnit
lea dx, ptr_msgHardDiskWarning
call std_printf
CALL Yes?
jnc OkToFormatHardDisk
mov ExitStatus, ExitNo
jmp ExitProgram
OkToFormatHardDisk:
CALL CRLF
CALL CRLF
return
GOPRNIT:
mov al, drive
call AccessDisk
lea dx,ptr_msgInsertDisk
CALL std_printf
CALL USER_STRING ;Wait for any key
CALL CRLF
CALL CRLF
PrmptRet:
mov fLastChance, FALSE
return
;-------------------------------------------------------------------------------
; ScanOff
; Scan Off separator characters
SCANOFF:
LODSB
CMP AL,' '
JZ SCANOFF
CMP AL,9
JZ SCANOFF
DEC SI
return
;-------------------------------------------------------------------------------
; MakeNum
; Makenum converts digits from ASCII AlphaNumeric format to
; numeric values
;
; Entry:
; AL == Character to be converted
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -