Category : Utilities for DOS and Windows Machines
Archive   : FORMAX.ZIP
Filename : 800KFMAT.ASM

 
Output of file : 800KFMAT.ASM contained in archive : FORMAX.ZIP

CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 100H

START: JMP GO

;-------------------------------------------

EVEN
DW 128 DUP (0)
STKTOP DW 0

CYLPERDSK EQU 80

BYTESPERSEC EQU 512
SECPERCLUS EQU 2
RESERVEDSEC EQU 1
NMBROFFATS EQU 2
ROOTENTRIES EQU 112
SECPERDISK EQU 1600
DESCRIPTOR EQU 0F0H
SECPERFAT EQU 3
SECPERTRK EQU 10
NMBROFHEADS EQU 2
HIDDENSEC EQU 0

DSM EQU 57H

OLD_DISKBASE DD 0

OLD23 DD 0

CYL DB 0
HEAD DB 0
SECT DB 0

RETRY_COUNT DW 0

DRIVE DB 0
BREAK DB 0

DISKBASE DB 0DFH
DB 02H
DB 25H
DB 02H
DB SECPERTRK
DB 1BH
DB 0FFH
DB 28H ;format gap
DB 00H ;fill byte
DB 0FH
DB 08H

; C H R N
SA DB 0,0,1,2
DB 0,0,2,2
DB 0,0,3,2
DB 0,0,4,2
DB 0,0,5,2
DB 0,0,6,2
DB 0,0,7,2
DB 0,0,8,2
DB 0,0,9,2
DB 0,0,10,2

MSG1 DB 0DH,0AH,'Format successful.',0DH,0AH,24H
MSG2 DB 0DH,0AH,'Format failed - track 0 unusable.',0DH,0AH,24H
MSG3 DB 0DH,'Cylinder '
MSG3A DB ' ',' '
DB 'Head '
MSG3B DB ' ',24H
MSG4 DB ' - error on this track.',0Dh,0Ah,24h
MSG5 DB 0DH,0AH,'Format failed - error reading boot sector'
DB ' from default drive.',0Dh,0Ah,24h
MSG6 DB 'Drive letter (A: or B:) must be specified.',0Dh,0Ah,24h
MSG7 DB 'Insert diskette and press a key when ready '
DB '(or to abort).',0Dh,0Ah,24h
MSG8 DB 0DH,0AH,'Terminated by control-break.',0DH,0AH,24H
LOGO DB '800 k byte formatter for low-density diskettes'
DB ' in PC/AT high-density drive',0Dh,0Ah
DB 'Version 1.0 - Copyright (C) 1987, Alan D. Jones',0Dh,0Ah,0Ah
DB 'Use memory-resident program "800K" to write & read '
DB 'these diskettes.',0Dh,0Ah,0Ah,24h
CRLF DB 0DH,0AH,24H

EVEN
BOOTIMG DB 512 DUP (0)
FAT DB DESCRIPTOR,0FFH,0FFH
DB 509 DUP (0)
DB 512 DUP (0)
DB 512 DUP (0)

;-------------------------------------------

;ctrl-break routine

INT23 PROC FAR

MOV CS:BREAK,1
IRET

INT23 ENDP

;-------------------------------------------

;routine to assure proper setting of
; "diskette state machine" byte

DSMS PROC

PUSH ES
PUSH BX
PUSH AX
MOV AX,40H
MOV ES,AX
MOV BX,90H
ADD BL,DRIVE
MOV AL,ES:[BX]
AND AL,0DFH
OR AL,07H
MOV ES:[BX],AL
POP AX
POP BX
POP ES
RET

DSMS ENDP

;-------------------------------------------

;convert byte in AL to ASCII at DS:[DI]

BTA PROC

PUSH AX
SUB AH,AH
AAM
ADD AX,3030H
MOV [DI],AH
MOV [DI+1],AL
POP AX
RET

BTA ENDP

;-------------------------------------------

;write and verify a sector with retries

WRITSEC PROC

PUSH BX
MOV RETRY_COUNT,5
WRSEC1:
MOV DL,DRIVE
MOV DH,HEAD
MOV CL,SECT
MOV CH,CYL
POP BX
PUSH BX
MOV AL,1
MOV AH,3
CLD
CALL DSMS
INT 13H
JNC WRSEC3
WRSEC2:
DEC RETRY_COUNT
CMP RETRY_COUNT,0
JNE WRSEC1

POP BX
STC
RET

;verify sector

WRSEC3:
MOV DL,DRIVE
MOV DH,HEAD
MOV CL,SECT
MOV CH,CYL
POP BX
PUSH BX
MOV AL,1
MOV AH,4
CLD
CALL DSMS
INT 13H
JC WRSEC2

POP BX
CLC
RET

WRITSEC ENDP

;-------------------------------------------

GO:
PUSH DS
CLI
POP SS
MOV SP,OFFSET STKTOP
STI

;display logo

MOV DX,OFFSET LOGO
MOV AH,9
INT 21H

;scan command line for drive letter

MOV SI,80H
SUB CH,CH
MOV CL,[SI]
INC SI
INC SI
CMP CX,3
JB CLERR
SUB CX,2
CLSCL:
CMP WORD PTR [SI],3A41H
JE DRV0
CMP WORD PTR [SI],3A61H
JE DRV0
CMP WORD PTR [SI],3A42H
JE DRV1
CMP WORD PTR [SI],3A62H
JE DRV1
LOOP CLSCL

;command line error

CLERR:
MOV DX,OFFSET MSG6
MOV AH,9
INT 21H
MOV AX,4C00H
INT 21H

;drive 0 (A:)

DRV0:
MOV DRIVE,0
JMP RDBOOTIMG

;drive 1 (B:)

DRV1:
MOV DRIVE,1

;read boot sector from current drive

RDBOOTIMG:
MOV AH,19H
INT 21H
MOV BX,OFFSET BOOTIMG
MOV CX,1
MOV DX,0
INT 25H
ADD SP,2
JNC DRIVINIT

MOV DX,OFFSET MSG5
MOV AH,9
INT 21H
MOV AX,4C01H
INT 21H

;initialize the floppy drive (clear change line)

DRIVINIT:
MOV DX,OFFSET MSG7
MOV AH,9
INT 21H
MOV AH,0
INT 16H
CMP AL,1BH
JNE DRVINIT1
MOV AX,4C00H
INT 21H

DRVINIT1:
MOV AH,0
MOV DL,DRIVE
INT 13H

MOV DL,DRIVE
MOV DH,0
MOV CH,1
MOV CL,1
MOV BX,OFFSET THEEND
CLD
MOV AX,0201H
INT 13H

MOV DL,DRIVE
MOV DH,0
MOV CH,0
MOV CL,1
MOV BX,OFFSET THEEND
CLD
MOV AX,0201H
INT 13H

;grab ctrl-break interrupt

MOV AX,3523H
INT 21H
MOV WORD PTR OLD23,BX
MOV WORD PTR OLD23+2,ES
MOV DX,OFFSET INT23
MOV AX,2523H
INT 21H

;set up new disk_base

SUB AX,AX
MOV ES,AX
MOV BX,78H
LES BX,ES:[BX]
MOV WORD PTR OLD_DISKBASE,BX
MOV WORD PTR OLD_DISKBASE+2,ES
SUB AX,AX
MOV ES,AX
MOV BX,78H
MOV ES:[BX+2],DS
MOV ES:[BX],OFFSET DISKBASE

MOV AX,40H
MOV ES,AX
MOV BX,90H
MOV BYTE PTR ES:[BX],DSM
MOV BX,8BH
MOV BYTE PTR ES:[BX],DSM
MOV BX,41H
MOV BYTE PTR ES:[BX],00H

MOV DX,03F7H
MOV AL,DSM
ROL AL,1
ROL AL,1
AND AL,03H
OUT DX,AL

MOV CYL,0
MOV HEAD,0

;set up sector addresses

FMLOOP:
MOV SI,OFFSET SA
MOV CX,SECPERTRK
SASET: MOV AL,CYL
MOV BYTE PTR [SI],AL
MOV AL,HEAD
MOV BYTE PTR [SI+1],AL
ADD SI,4
LOOP SASET

;display status message

MOV AL,CYL
MOV DI,OFFSET MSG3A
CALL BTA
MOV AL,HEAD
MOV DI,OFFSET MSG3B
CALL BTA
MOV DX,OFFSET MSG3
MOV AH,9
INT 21H

;format a track

MOV RETRY_COUNT,5
BIOSCL1:
MOV DL,DRIVE
MOV DH,HEAD
MOV CL,1
MOV CH,CYL
MOV BX,OFFSET SA
PUSH DS
POP ES
MOV AL,SECPERTRK
MOV AH,5
CLD
CALL DSMS
INT 13H
JNC VFYTRK
DEC_RETRY:
MOV DL,DRIVE
MOV AH,0
CALL DSMS
INT 13H
DEC RETRY_COUNT
CMP RETRY_COUNT,0
JNE BIOSCL1
JMP FMTERR

;verify the track

VFYTRK:
MOV DL,DRIVE
MOV DH,HEAD
MOV CL,1
MOV CH,CYL
MOV BX,OFFSET THEEND
MOV AL,SECPERTRK
MOV AH,2
CLD
CALL DSMS
INT 13H
JC DEC_RETRY
JMP INCTRK

;bad track - flag clusters in FAT image

FMTERR:

;display message

MOV DX,OFFSET MSG4
MOV AH,9
INT 21H

;read sectors one at a time to find bad ones

MOV SECT,1
READSINGLE:
MOV DL,DRIVE
MOV DH,HEAD
MOV CL,SECT
MOV CH,CYL
MOV BX,OFFSET THEEND
MOV AL,1
MOV AH,2
CLD
CALL DSMS
INT 13H
JNC NSSECT

;compute sector number

MOV AL,CYL
MOV CL,SECPERTRK*2
MUL CL
MOV CL,SECT
DEC CL
SUB CH,CH
ADD AX,CX
CMP HEAD,0
JE CCN
ADD AX,SECPERTRK

;compute cluster number

CCN:
SUB AX,RESERVEDSEC
SUB AX,NMBROFFATS*SECPERFAT
SUB AX,(ROOTENTRIES*32)/BYTESPERSEC
SUB DX,DX
MOV CX,SECPERCLUS
DIV CX
ADD AX,2

;compute offset into table

MOV CL,1
AND CL,AL
SHL CL,1
SHL CL,1
MOV DX,AX
SHR AX,1
ADD AX,DX

;write FF7's

MOV BX,OFFSET FAT
ADD BX,AX
MOV AX,0FF7H
SHL AX,CL
OR [BX],AX

;next sector on track

NSSECT:
INC SECT
CMP SECT,SECPERTRK
JBE READSINGLE

;increment to next track

INCTRK:
CMP BREAK,1
JNE INCHEAD
JMP BREAKEXIT
INCHEAD:
INC HEAD
CMP HEAD,1
JA INCTRK2
JMP FMLOOP
INCTRK2:
MOV HEAD,0
INC CYL
CMP CYL,CYLPERDSK
JNB SENDLF
JMP FMLOOP

;display CRLF

SENDLF:
MOV DX,OFFSET CRLF
MOV AH,9
INT 21H

;plug in correct media parameters

MOV BX,OFFSET BOOTIMG
MOV WORD PTR [BX+11],BYTESPERSEC
MOV BYTE PTR [BX+13],SECPERCLUS
MOV WORD PTR [BX+14],RESERVEDSEC
MOV BYTE PTR [BX+16],NMBROFFATS
MOV WORD PTR [BX+17],ROOTENTRIES
MOV WORD PTR [BX+19],SECPERDISK
MOV BYTE PTR [BX+21],DESCRIPTOR
MOV WORD PTR [BX+22],SECPERFAT
MOV WORD PTR [BX+24],SECPERTRK
MOV WORD PTR [BX+26],NMBROFHEADS
MOV WORD PTR [BX+28],HIDDENSEC

;write diskette boot sector

PUSH DS
POP ES
MOV CYL,0
MOV HEAD,0
MOV SECT,1
MOV BX,OFFSET BOOTIMG
CALL WRITSEC
JC FATALERR
CMP BREAK,1
JE BREAKEXIT

;write first copy of FAT

MOV SECT,2
MOV BX,OFFSET FAT
CALL WRITSEC
JC FATALERR
ADD BX,512
MOV SECT,3
CALL WRITSEC
JC FATALERR
ADD BX,512
MOV SECT,4
CALL WRITSEC
JC FATALERR
CMP BREAK,1
JE BREAKEXIT

;write second copy of FAT

MOV SECT,5
MOV BX,OFFSET FAT
CALL WRITSEC
JC FATALERR
ADD BX,512
MOV SECT,6
CALL WRITSEC
JC FATALERR
ADD BX,512
MOV SECT,7
CALL WRITSEC
JC FATALERR
CMP BREAK,1
JE BREAKEXIT

;display "ok" msg

MOV DX,OFFSET MSG1
MOV AH,9
INT 21H
JMP RESTORE

;error

FATALERR: MOV DX,OFFSET MSG2
MOV AH,9
INT 21H
JMP RESTORE

;control-break exit

BREAKEXIT:
MOV DX,OFFSET MSG8
MOV AH,9
INT 21H

;restore BIOS parameters + INT 23H
; and exit

RESTORE:
SUB AX,AX
MOV ES,AX
MOV BX,78H
MOV AX,WORD PTR OLD_DISKBASE
MOV ES:[BX],AX
MOV AX,WORD PTR OLD_DISKBASE+2
MOV ES:[BX+2],AX

LDS DX,OLD23
MOV AX,2523H
INT 21H

MOV AX,4C00H
INT 21H

THEEND LABEL BYTE

CODE ENDS
END START