⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 format.asm

📁 msdos 3.30 source code
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        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 + -