AOH :: FMTDEMO.TXT

Assembly code for formatting disks

NAME	FMTDEMO
cr	equ	0ah
lf	equ	0dh

;*****************************************************************************
;*                                                                           *
;*  FORMAT DEMO WAS WRITTEN SO THAT YOU COULD SEE, LEARN AND USE ASMB PROG   *
;*  METHODS.  THE PROGRAM WILL FORMAT A FLOPPY IN DRIVE A TO 360K 9 SECTORS  *
;*  PER TRACK AND 40 TRACKS.  THE PROGRAM WILL WRITE THE BLANK FAT TABLE AND *
;*  THE EMPTY DIRRECTORY STRUCTOR.  NO ATTEMPT HAS BEEN MADE TO VERIFY THE   *
;*  DISKETTE FOR BAD SECTORS AFTER THE FORMAT. THE MAIN REASON IS THE ALGORY *
;*  USED TO WRITE A 12 BIT FAT IS A BITCH AND I DIDN'T FEEL THAT IT IS       *
;*  NESSARY IN DEMOING THE METHODS USED. ALSO THE CODE IS NOT OPTIMIZED FOR  *
;*  SIZE OR SPEED SO YOU CAN HAVE FUN DOING THAT IF YOU WANT.                *
;*  LINDA ASKED ME TO GIVE YOU SOME DEMOS, SO HAVE FUN AND HOPE THIS HELPS.  *
;*                                                                           *
;*  AUTHOR: BOB NOWECK                                                       *
;*          115 LYNTON RD.                                                   *
;*          JESUP,GA.              912-427-0756                              *
;*****************************************************************************





CODE		SEGMENT		BYTE PUBLIC 'CODE'
		PUBLIC	MAIN
		ASSUME  CS:CODE,DS:CODE,SS:STACK,ES:CODE
MAIN		PROC	FAR			;THIS IS AN EXE PROGRAM MAKE THE PROC A FAR
		MOV	AX,CS			;PREP THE SEGMENTS WITH THE CODE SEGMENT
		MOV	DS,AX			;SETUP THE DATA SEGMENT
		MOV	ES,AX			;SETUP THE EXTRA SEGMENT
		CALL	HELLO			;DISPLAY INITIAL SCREEN
		XOR	AX,AX			;NOW ZERO EVERYTHING OUT
		XOR	BX,BX			; '   '     '        '
		XOR	CX,CX			; '   '     '        '
		MOV	HD,0			;INITIALIZE THE HEAD AREA
TB1:		MOV	SI,0			;RESET SI TO 0
		MOV	CX,0			;AND THE CX
		MOV	DX,0			;AND THE DX
		MOV	TRK,0FFH		;AND REINITIALIZE TRACK COUNTER TO -1
LAB1:		INC	TRK			;INCRMT THE TRACK
		PUSH	DX			;SAVE THE REGS
		PUSH	CX			;IN PREP OF A CALL
		PUSH	BX			;THAT MIGHT CHANGE THEM
		PUSH	AX			;
		CALL	CON_DISP		;CALL THE INITAL SCREEN	
		POP	AX			;RESTORE THE REGS
		POP	BX			;
		POP	CX			;
		POP	DX			;	
		MOV	SEC,0			;RESET SECTOR INFO TO 0
LAB2:		MOV	DL,SEC			;DL HOLDS SECTOR NUMBER
		MOV	CL,2			;CL HOLDS MULTIPLIER
		SHL	DL,CL			;MULTIPLY DL,CL TO GET OFFSET OF 5
		XOR	DH,DH			;ZERO OUT THE DH REG
		MOV	CX,DX			;MOVE THE OFFSET TO THE CX
		INC	SEC			;INCRM SECTOR COUNT MUST NEVER BE 0
		MOV	BX,OFFSET TRACK_TABLE	;LOAD BX WITH ABS ADDR OF TABLE
        	ADD     BX,CX			;ADD OFFSET TO BX
		MOV	BP,BX			;FOR THE HELL OF IT THE BP NOW HAS THE ADDR
		MOV	AL,TRK			;MOVE THE TRACK INFO TO THE AL REG
		MOV	BYTE PTR ES:[BP],AL	;LOAD VALUE AT ES:BP WITH TRK INFO
		MOV	AL,HD			;MOVE THE HEAD INFO TO THE AL
		MOV	BYTE PTR ES:[BP+1],AL	;LOAD VALUE AT ES:BP+1 WITH HEAD INFO
		MOV 	AL,SEC			;MOVE SECTOR INFO TO AL
		MOV	BYTE PTR ES:[BP+2],AL	;LOAD VALUE AT ES:BP+2 WITH SECTOR INFO
		MOV	AL,SZ			;MOVE THE SECTOR SIZE CONST TO AL
		MOV	BYTE PTR ES:[BP+3],AL	;LOAD VALUE AT ES:BP+3 WITH SIZE INFO
		CMP	SEC,09H			;CHECK TO SEE IF WE ARE DONE
		JE	FMTTRK			;YEP FORMAT THE TRACK
		JMP	LAB2			;NOP CONT TO BUILD TABLE
FMTTRK:		CALL	FORMAT_TRACK		;FORMAT 1 TRACK
		JC	C_ERROR			;WAS THERE AN ERROR ,IF SO JUMP TO ERROR
CONT:   	CMP	TRK,028H		;SEE IF WE DID ALL TRACKS
		JE	DONE1			;YEP GOTO DONE1
		JMP	LAB1			;NOP INCM TRK
C_ERROR:	CALL	ECODE_DISP		;DISPLAY THE ERROR MSG'S	
		CALL	ERROR_RESET		;CLEAR THE NEC ERROR FLAGS
		CMP	ECODE,0			;SEE IF THIS IS A DOS BUG
		JA	DOS_BUG			;HANDLE IT, IF IT IS
		JMP	CONT			;ALL'S OK SO CONTINUE
DOS_BUG:	CALL	DOS_BUG_HANDLER		;FOUND DOS'S BUG SO HANDLE IT
		MOV	ECODE,0			;ZERO OUT OUR ERROR CODE AREA
		JMP	FMTTRK			;REFORMAT THE TRACK
DONE1:		CMP	HD,1			;SEE IF LAST HEAD ON FLPY = 1
		JNE	TB2			;NO SO JMP TO NEXT HEAD
		JMP	WRITE_FAT_CALL		;YES SO FINNISH UP
TB2:		INC	HD			;INCM HEAD
		JMP	TB1			;AND DO IT ALL OVER AGAIN
WRITE_FAT_CALL:	CALL	WRITE_FAT		;WRITE THE FAT TABLES
		MOV	DX,OFFSET CRLF		;ADDRESS OF CRLF
		CALL	WRITE_MSG		;PRINT IT	
		CALL	QUIT			;AND EXIT
MAIN 		ENDP				;END OF MAIN PROC


;*****************************************************************************
;*                                                                           *
;* THE VERSION OF DOS THAT I HAVE, HAS A BUG IN IT. THIS IS PC DOS 3.3       *
;* THE BUG IS: AFTER AN "REAL" ERROR HAS ACCURED, A FALSE ONE MIGHT BE       *
;* REPORTED. THE FALSE ERROR I'VE BEEN SEEING IS WRITE PROTECT ERROR         *
;* ON A NON-WRITE PROTECTED DISK.                                            *
;*                                                                           *
;*****************************************************************************




DOS_BUG_HANDLER	PROC	NEAR
		PUBLIC	DOS_BUG_HANDLER
		MOV	ROW,010H
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET DOS_BUG_MSG_6
		CALL	WRITE_MSG
		CALL	INKEY
		CALL	CLR_DOS_BUG
		RET
DOS_BUG_HANDLER	ENDP



;*****************************************************************************
;*                                                                           *
;*  CLEAR THE ERROR MSG OFF THE SCREEN.                                      *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*****************************************************************************



CLR_DOS_BUG	PROC	NEAR
		PUBLIC	CLR_DOS_BUG
		MOV	ROW,010H
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET CLR_DOS_BUG_MSG
		CALL	WRITE_MSG
		MOV	ROW,011H
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET CLR_DOS_BUG_MSG
		CALL	WRITE_MSG
		RET
CLR_DOS_BUG	ENDP


;*****************************************************************************
;*                                                                           *
;*  INKEY READS THE KEYBOARD AND WAITS FOR  <1> ONE KEY TO BE PRESSED        *
;*  THIS MAYBE A FUNCTION KEY, COMBINATION KEYS SUCH AS CNTRL AND SOMETHING  *
;*  OR JUST ANY OLD KEY.                                                     *
;*                                                                           *
;*  RETURNS: KEYBOARD_SCAN_CODE - FOR INDICATION OF FUNC OR COMBIN           *
;*  RETURNS: ASCII_CHAR_CODE - ASCII CODE FOR THE KEY                        *
;*****************************************************************************




INKEY		PROC	NEAR
		PUBLIC	INKEY
		MOV	AH,0			;SETUP FUNCTION CALL TO 
		INT	16H			;BIOS KEYBOARD ROUTINE
		MOV	KEYBOARD_SCAN_CODE,AH	;MOVE THE RESULTS
		MOV	ASCII_CHAR_CODE,AL	;
		RET				;AND EXIT
INKEY		ENDP


;*****************************************************************************
;*                                                                           *
;*  FORMAT 1 TRACK:                                                          *
;*  USES:                                                                    *
;*         TRK - THE TRACK TO FORMAT                                         *
;*         HD  - THE HEAD TO FORMAT                                          *
;*         DRV - THE DRIVE TO FORMAT <IN THIS PROGRAM ALWAYS 0 OR A DRIVE>   *
;* TRACK_TABLE - THE TABLE THAT POINTS TO THE TRACK/SECTOR INFO              *
;*                                                                           *
;* RETURNS: ECODE WHICH IS THE ERROR CODE IN THE AH.                         *
;*          ON ERROR CARRY FLAG IS SET.                                      *
;*                                                                           *
;*****************************************************************************




FORMAT_TRACK	PROC	NEAR
		PUBLIC	FORMAT_TRACK
		MOV	BX,offset TRACK_TABLE	;LOAD BX WITH ADDRESS OF TABLE
		MOV	AH,5			;SET FUNCTION CALL TO FORMAT
		MOV	AL,9			;WE ARE FORMATING 9 SECTORS PER TRACK
		MOV	CH,TRK			;LOAD THE TRACK INFO
		MOV	DH,HD			;AND THE HEAD INFO
		MOV	DL,DRV			;AND THE DRIVE WHICH IS 0 FOR A DRV
		INT	13H			;CALL ON BIOS TO FORMAT
		MOV	ECODE,AH
		RET
FORMAT_TRACK	ENDP



;*****************************************************************************
;*                                                                           *
;* ERROR_RESET ISSUES A RESET COMMAND TO THE NEC CONTROLLER, AND THUS CLEARS *
;* THE CARRY FLAG AND RESETS THE DRIVE FOR SUBSEQUENT COMMANDS.              *
;*                                                                           *
;* THIS ROUTINE MUST BE CALLED WHENEVER AN ERROR ACCURES IN FLOPPY ROUTINES  *
;*                                                                           *
;*****************************************************************************





ERROR_RESET	PROC	NEAR
		PUBLIC	ERROR_RESET
		mov	ah,00			;FUNCTION CODE TO CLEAR ERROR
		int	13h			;CALL ON DISK BIOS
		RET				
ERROR_RESET	ENDP




;*****************************************************************************
;*                                                                           *
;* ECODE_TABLE IS A TABLE OF ADDRESS WHICH CORRESPOND TO SUBROUTINES IN THE  *
;* PROCEDURE ECODE_DISP. I THOUGHT YOU MIGHT LIKE TO HAVE A LOOK AT HOW YOU  *
;* CAN SAVE CODING SPACE BY USING THIS METHOD.                               *
;*                                                                           *
;* ECODE_DISP IS THE DISPLAY ROUTINE FOR ERRORS.                             *
;* ON ENTRY THE ERROR CODE IS STORED IN ECODE, THIS IS TESTED TO SEE IF IT   *
;* IS GREATER THAN 9, IF NOT ECODE IS MOVED TO THE SI REGISTER, WHICH AT THIS*
;* POINT WILL HAVE A VALUE FROM 0 TO 9. THEN THE BP REGISTER IS LOADED WITH  *
;* THE ADDRESS OF THE TABLE. WE THEN LOAD THE CX REGISTER WITH THE VALUE     *
;* THAT IS POINTED TO BY THE BP+SI COMBINATION, THIS IS THE ADDRESS OF THE   *
;* ERROR ROUTINE CORRESPONDING TO THE ERROR NUMBER. THEN WE JUMP TO THAT     *
;* ADDRESS USING THE CX REGISTER.                                            *
;* THE UNKNOWN_ERROR HANDLER SHOWS AN ALTERNATE METHOD THAT I WOULD ADVISE   *
;* NOT USING, AS YOU WILL SPEND MUCH OF YOUR TIME TYPING IN CODE, AND AS A   *
;* RESULT YOUR FINALE PROGRAM WILL BE HUGH.                                  *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*****************************************************************************




ECODE_TABLE	LABEL	WORD	;TABLE OF ADDRESS FOR JMP INSTRUCTION
		DW	ERR0	;ERROR CODE 0 ADDRESS
		DW	ERR1	;ERROR CODE 1 ADDRESS
		DW	ERR2	;
		DW	ERR3	;AND SO FORTH
		DW	ERR4
		DW	ERR5
		DW	ERR6
		DW	ERR7
		DW	ERR8
		DW	ERR9


ECODE_DISP	PROC	NEAR
		PUBLIC	ECODE_DISP
		XOR	AX,AX			;ZERO OUT THE AX REG
						;NOTE: XOR'ING A REG IS QUICKER
						;THAN MOVING TO A REG, GOOD PROGRAMMING
						;PRACTICE
		MOV	AL,ECODE		;LOAD THE ERROR CODE INTO THE AL
		CMP	AL,0AH			;SEE IF IT IS ABOVE 10
		JA	UNKNOWN_ERROR		;YEP SO GOTO THE OTHER HANDLER
		MOV	SI,AX			;NOP LOAD THE SI REG FROM THE AX
		MOV	BP,OFFSET ECODE_TABLE	;NOW LOAD THE BP WITH THE ADDRESS OF THE TABLE
		MOV	CX,WORD PTR ES:[BP+SI]	;LOAD THE CX REG WITH THE ADDRESS POINTED TO BY 
						;THE BP SI COMBINATION
						;THIS IS THE ADDRESS OF THE SUBROUTINE
						;THAT WE WANT TO JUMP TO
		JMP	CX			;SO JUMP TO IT
ERR0:		MOV	DX,OFFSET ERR_0_MSG	;MOVE THE ADDRESS OF THE 0 ERR MESSAGE
		JMP	ERR_DISPLAY		;JMP TO THE HANDLER
ERR1:		MOV	DX,OFFSET ERR_1_MSG
		JMP	ERR_DISPLAY
ERR2:		MOV	DX,OFFSET ERR_2_MSG
		JMP	ERR_DISPLAY
ERR3:		MOV	DX,OFFSET ERR_3_MSG	
		JMP	ERR_DISPLAY
ERR4:		MOV	DX,OFFSET ERR_4_MSG
		JMP	ERR_DISPLAY
ERR5:		MOV	DX,OFFSET ERR_5_MSG
		JMP	ERR_DISPLAY
ERR6:		MOV	DX,OFFSET ERR_6_MSG
		JMP	ERR_DISPLAY
ERR7:		MOV	DX,OFFSET ERR_7_MSG
		JMP	ERR_DISPLAY
ERR8:		MOV	DX,OFFSET ERR_8_MSG
		JMP	ERR_DISPLAY
ERR9:		MOV	DX,OFFSET ERR_9_MSG
		JMP	ERR_DISPLAY

;*****************************************************************************
;*                                                                           *
;* UNKNOWN_ERROR IS A POOR WAY TO HANDLE DETERMINING VALUES                  *
;* I WOULD NOT USE THIS METHOD WITH MORE THAN 3 OR 4 TESTS                   *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*****************************************************************************


UNKNOWN_ERROR:
		MOV	AL,ECODE		;LOAD AL WITH ERROR CODE
		CMP	AL,010H			;SEE IF ITS = TO 10 HEX
		JE	BAD_CRC_HANDLER		;YES SO THIS MUST BE A BAD CRC
		CMP	AL,020H			;SEE IF ITS = TO 20 HEX
		JE	NEC_BAD_HANDLER		;YES SO THIS MUST BE NEC BAD
		CMP	AL,040H			;AND SO FORTH
		JE	SEEK_HANDLER		;
		CMP	AL,080H			;
		JE	TIME_OUT_HANDLER	;
		MOV	DX,OFFSET UNKNOWN_ERROR_MSG	;THIS SHOULD NEVER BE CALLED

		MOV	WORD PTR[EMSG],DX	;BUT IF IT IS WE MOVE THE MSG ADDRESS TO
 						;TO OUR PLACE HOLDER
		CALL	WRITE_ERROR_MSG		;THEN CALL THE ERROR MSG HANDLER
		MOV	AH,ECODE		;WE THEN LOAD THE AH WITH THE CODE
		MOV	CHAR,AH			;AND MOVE IT TO THE HOLDER CHAR
		CALL	ITOC			;WE CALL THE INTEGER TO CHAR CONVERT ROUTINE
		MOV	DX,OFFSET DECIMAL_STRING ;THEN MOVE THE ADDRESS OF THE CONVERTED NUMBER
		CALL	WRITE_MSG		;AND WRITE IT SO THAT WE MAY KNOW WHAT THE ERROR
						;NUMBER WAS.
		JMP	RETURN_F_ERR		;NOW WE EXIT THIS ROUTINE
BAD_CRC_HANDLER:
		MOV	DX,OFFSET ERR_10_MSG		
		JMP	ERR_DISPLAY
NEC_BAD_HANDLER:
		MOV	DX,OFFSET ERR_20_MSG
		JMP	ERR_DISPLAY
SEEK_HANDLER:	MOV	DX,OFFSET ERR_40_MSG
		JMP	ERR_DISPLAY
TIME_OUT_HANDLER:
		MOV	DX,OFFSET ERR_80_MSG
ERR_DISPLAY:	MOV	WORD PTR[EMSG],DX
		CALL	WRITE_ERROR_MSG
RETURN_F_ERR:	RET

ECODE_DISP	ENDP


;*****************************************************************************
;*                                                                           *
;* WRITE_ERROR_MSG MOVES THE CURSOR TO A CLEAR AREA OF SCREEN                *
;* THEN CLEARS THAT AREA. THEN LOADS THE CORRECT ERROR MSG AND CALLES THE    *
;* PRINT ROUTINE.                                                            *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*****************************************************************************

		




WRITE_ERROR_MSG	PROC	NEAR
		PUBLIC	WRITE_ERROR_MSG
		MOV	ROW,017H
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET CLR_MSG_AREA
		CALL	WRITE_MSG
		MOV	ROW,017H
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,EMSG		;THE VALUE IN EMSG IS THE ADDRESS OF
					;OUR ERROR MESSAGE, SO WE JUST LOAD IT
		CALL	WRITE_MSG
		RET
WRITE_ERROR_MSG	ENDP



;*****************************************************************************
;*                                                                           *
;* WRITE_MSG USES DOS TO WRITE A STRING ON THE SCREEN AT THE CURRENT CURSOR  *
;* LOCATION.  IT MUST BE TERMINATED WITH AN $                                *
;* THEN WE CLEAR OUT THE ITOC VALUE STRING.  JUST A GOOD PLACE TO DO IT.     *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*****************************************************************************




WRITE_MSG	PROC	NEAR
		PUBLIC	WRITE_MSG		;DX HAS STRING ADDRESS ON ENTRY
		MOV	AH,09			;SET DOS FUNCTION CALL
		INT	21H			;CALL THE UMBRELLA
		MOV	BX,OFFSET DECIMAL_STRING
		MOV	BYTE PTR [BX],020H	;MOVE SPACES TO 1 PLACE
		MOV	BYTE PTR [BX+1],020H	;MOVE SPACES TO 2 PLACE
		RET
WRITE_MSG	ENDP



HELLO		PROC	NEAR
		PUBLIC	HELLO
		CALL	CLS
		MOV	ROW,1
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET SIGN_ON_MSG
		CALL	WRITE_MSG
		MOV	ROW,9
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET FORMAT_MSG
		CALL	WRITE_MSG
		MOV	ROW,0BH
		MOV	COLUMN,0
		CALL	GOTOXY
		MOV	DX,OFFSET HEAD_MSG
		CALL	WRITE_MSG
		MOV	ROW,0BH
		MOV	COLUMN,0AH
		CALL	GOTOXY
		MOV	DX,OFFSET TRACK_MSG
		CALL	WRITE_MSG
		RET
HELLO		ENDP

;***************************************************************************
;*                                                                         *
;* THIS ROUTINE DISPLAYS THE WORDS TRACK AND HEAD, AS WELL AS DISPLAYS     *
;* THE CURRENT TRACK AND HEAD UPDATING EACH TIME CALLED.                   *
;*                                                                         *
;*                                                                         *
;***************************************************************************




CON_DISP	PROC	NEAR
		PUBLIC	CON_DISP
		MOV	ROW,0BH
		MOV	COLUMN,6
		CALL	GOTOXY
		MOV	AL,HD
		MOV	CHAR,AL
		CALL	ITOC
		MOV	DX,OFFSET DECIMAL_STRING
		CALL	WRITE_MSG
		MOV	ROW,0BH
		MOV	COLUMN,11H
		CALL	GOTOXY
		MOV	AL,TRK
		MOV	CHAR,AL
		CALL	ITOC
		MOV	DX,OFFSET DECIMAL_STRING
		CALL	WRITE_MSG
		RET
CON_DISP	ENDP

;*****************************************************************************
;*                                                                           *
;* CLEARS THE SCREEN.                                                        *
;*                                                                           *
;*****************************************************************************



CLS		PROC	NEAR
		PUBLIC	CLS
		MOV	AH,0
		MOV	AL,02
		INT	10H
		RET
CLS		ENDP


;*****************************************************************************
;*                                                                           *
;* GOTOXY ON THE SCREEN.                                                     *
;*                                                                           *
;*****************************************************************************



GOTOXY		PROC	NEAR
		PUBLIC	GOTOXY
		MOV	AH,2
		MOV	BH,0
		MOV	DH,ROW
		MOV	DL,COLUMN
		INT	10H
		RET
GOTOXY		ENDP



;*****************************************************************************
;*                                                                           *
;* WRITE A CHARECTER TO THE SCREEN.                                          *
;*                                                                           *
;*****************************************************************************


WRITE_CHAR	PROC	NEAR
		PUBLIC	WRITE_CHAR
		MOV	AH,0AH
		MOV	AL,CHAR
		MOV	BH,1
		MOV	BL,4
		MOV	CX,1
		INT	10H
		RET
WRITE_CHAR	ENDP

;*************************************
;*                                   *
;* ITOC WORKS BY TAKING A NUMBER     *
;* 0 THRU 255 AND CONVERTS IT TO     *
;* A PRINTABLE VALUE.                *
;* DECIMAL_STRING HOLDS THE VALUE    *
;* AND IS READY TO PRINT.            *
;*************************************




ITOC		PROC	NEAR
		PUBLIC	ITOC
		MOV	ITOC_ONES,0			;ZERO OUT PLACE HOLDERS
		MOV	ITOC_TENS,0			; "    "    "     "
		MOV	ITOC_HUNDREDS,0			; "    "    "     "
		MOV	AL,CHAR				;MOVE INTEGER 0-255 TO AL
T5:		CMP	AL,09H				;TEST TO SEE IF > 9
		JA	T6				;YES IT'S GREATER
		MOV	ITOC_ONES,AL			;NO MOVE AL TO ONES PLACE
		JMP	T7				;NOW STRIP TENS
T6:		SUB	AL,0AH				;SUBTRACT 10 FROM AL
		INC	ITOC_TENS			;ADD 1 TO TENS PLACE
		JMP	T5				;CONT UNTIL WE HAVE ZEROS PLACE AND TENS DONE
T7:		MOV	AL,ITOC_TENS			;NOW MOVE TENS TO AL
T8:		CMP	AL,09H				;SEE IF > 90
		JA	T9				;YEP
		MOV	ITOC_TENS,AL			;NOP MOV AL BACK TO TENS PLACE
		JMP	T11				;WE NOW HAVE THE INTEGER
							;DIVIDED INTO ONES,TENS,AND HUNDREDS
							;NOW WE SETUP THE STRING
T9:		SUB	AL,0AH				;SUB 10 FROM TENS PLACE
		INC	ITOC_HUNDREDS			;ADD 1 TO HUNDREDS
		JMP	T8				;AND CONT

T11:		MOV	BX,OFFSET DECIMAL_STRING	;MOVE THE ADDRESS TO BX
		MOV	AL,ITOC_HUNDREDS		;MOVE HUNDREDS TO AL
		ADD	AL,030H				;ADD 30 TO MAKE IT AN ASCII NUMBER
		MOV	BYTE PTR[BX],AL			;PUT IT IN PLACE
		MOV	AL,ITOC_TENS			;MOVE TENS TO AL
		ADD	AL,030H				;ADD 30
		MOV	BYTE PTR[BX+1],AL		;PUT IT IN PLACE
		MOV	AL,ITOC_ONES			;MOVE ONES TO AL
		ADD	AL,030H				;ADD 30
		MOV	BYTE PTR[BX+2],AL		;PUT IT IN PLACE
		RET					;AND WE ARE DONE
ITOC		ENDP		



;****************************************************************************
;*                                                                          *
;* QUIT DOES JUST THAT, IF WE WANTED TO WE COULD SET THE AL REG WITH SOME   *
;* VALUE, THAT COULD BE TESTED IN A BATCH FILE. FOR NOW WE WILL JUST LEAVE  *
;* IT WITH A RETURN CODE OF 0.                                              *
;*                                                                          *
;****************************************************************************



QUIT		PROC	NEAR
		PUBLIC	QUIT
		MOV	AX,04C00H		;EXIT WITH A 0 RET CODE
		INT 	21H			;AND MAKE DOS DO IT
QUIT		ENDP






WRITE_FAT	PROC	NEAR
		PUBLIC	WRITE_FAT
		MOV	DX,OFFSET FAT_MSG
		CALL	WRITE_MSG
		MOV	CLAREA,1  		;INITAILIZE SECTOR NUMBER TO 1
						;THIS IS THE AREA USED FOR BOOT
						;INFORMATION. WE WILL NOT USE IT
						;FOR WE WILL NOT WRITE ANYTHING
						;THERE,......BUT
wr1:		INC	CLAREA    		;NOW IS 2 AT START
		MOV	HD,0			;SET THE HEAD AREA TO 0
		MOV	AH,03			;SETUP FUNCTION CALL TO WRITE
		MOV	AL,4			;AND WE ARE WRITING ONLY 4 SECTOR
						;NOTE:!!!!!!
						;DOS ERROR EXISTS HERE
						;DOS REF. MAN. SAYS THAT YOU
						;DON'T NEED TO ENTER ANYTHING
						;IN THE AL REG. BUT YOU MUST
						;ENTER THE AMOUNT OF WRITE
		MOV	BX,OFFSET FAT_TABLE	;LOAD THE BX REG WITH THE ADDRESS OF THE TABLE
		MOV	CH,0			;AND CH WITH TRACK 0
		MOV	CL,CLAREA		;AND CL WITH SECTOR NUMBER 1 THRU 9
		MOV	DH,HD			;AND DH WITH THE HEAD NUMBER 0 OR 1
		MOV	DL,0			;AND DL HAS THE DRIVE 0 FOR A, 1 FOR B, ECT.
		INT	13H			;CALL ON BIOS TO EXICUTE FORMAT
		MOV	CLAREA,5 		;INCRM SECTOR NUMBER
		MOV	HD,0			;RESET HEAD TO 0
						;TRACK IS 0
						;HEAD IS 0

		MOV	DX,OFFSET DIR_MSG
		CALL	WRITE_MSG
		MOV	TOTSEC,3
NEXT_STEP:	INC	CLAREA			;SECTOR WAS 5 NOW IS 6
WRITE_DIR:	MOV	AH,03			;SETUP WRITE FUNCTION CALL
		MOV	AL,TOTSEC		;1 SECTOR TO WRITE
		MOV	BX,OFFSET DIR_TABLE	;ADDRESS OF BLANK DIRECTORY TABLE
		MOV	CH,0			;TRACK IS 0
		MOV	CL,CLAREA		;MOVE SECTOR INFO TO CL REG
		MOV	DH,HD			;AND HEAD INFO
		MOV	DL,0			;AND DRIVE IS A
		INT	13H			;WRITE THE DIRECTORY 
		CMP	HD,1			;CHECK TO SEE WHAT HEAD WE ARE ON
		JNE	INCHD			;IF NOT EQUAL TO 1
		RET				;IF EQUAL TO 1 QUIT
INCHD:		INC	HD			;INCRM HEAD SO THAT IT IS 1
		MOV	CLAREA,0		;AND CURRENT SECTOR
		JMP	NEXT_STEP		;AND REPEAT THE WHOLE THING OVER
						;AGAIN
WRITE_FAT	ENDP







TRACK_TABLE	DB	36 DUP(0)
FAT_TABLE	DB	0FDH,0FFH,0FFH,0	;FIRST FAT TABLE
		DB	127 DUP(4 DUP(0))
		DB	128 DUP(4 DUP(0))
		DB	0FDH,0FFH,0FFH,0	;SECOND FAT TABLE
		DB	127 DUP(4 DUP(0))
		DB	128 DUP(4 DUP(0))

DIR_TABLE	DB	64 DUP(0,31 DUP(0F6h))
ECODE		DB	?
TOTSEC		DB	?
SEC		DB	0
TRK		DB	0
HD		DB	0
DRV		DB	0
SZ		DB	2
CLAREA		DB	1
TOT		DB	?
CLUSTER		DW	?
CLUST_ADDR	DB	?
SIGN_ON_MSG	DB	"This is a floppy disk format program.",cr,lf
		DB	"It is useful only in that it will format",cr,lf
		DB	"a floppy in <A> drive. No attempt is made",cr,lf
		DB	"to verify the diskette.  The main purpose",cr,lf
		DB	"is to show YOU how to do it.",cr,lf
		DB	"Linda asked me to write this for you",cr,lf,"$"
TRACK_MSG	DB	"TRACK $"
HEAD_MSG	DB	"HEAD  $"
FORMAT_MSG	DB	"FORMATTING.... $"
CRLF		DB	CR,LF,"$"
ROW		DB	?
COLUMN		DB	?
CHAR		DB	?
INTEGER		DB	?
DECIMAL_STRING	DB	"   $"
DIR_MSG		DB	CR,LF,"WRITTING DIRECTORY STRUCTURE$"
FAT_MSG		DB	CR,LF,"WRITTING FAT TABLES$"
EMSG		DW	?
ERR_0_MSG	DB	"AN ERROR WAS GENERATED USING CODE 0 HUMMMMM.",CR,LF,"$"
ERR_1_MSG	DB	"BAD COMMAND ISSUED, THIS SHOULD NOT HAPPEN.",CR,LF,"$"
ERR_2_MSG	DB	"ADDRESS MARK NOT FOUND .",CR,LF,"$"
ERR_3_MSG	DB	"DISK IS WRITE PROTECTED.",CR,LF,"$"
ERR_4_MSG	DB	"SECTOR NOT FOUND.",CR,LF,"$"
ERR_5_MSG	DB	"AN ERROR WAS GENERATED USING CODE 5 HUMMMM.",CR,LF,"$"
ERR_6_MSG	DB	"DISK NOT IN DRIVE.",CR,LF,"$"
ERR_7_MSG	DB	"AN ERROR WAS GENERATED USING CODE 7 HUMMMM.",CR,LF,"$"
ERR_8_MSG	DB	"DMA OVERRUN, THIS SHOULD NOT HAPPEN.",CR,LF,"$"
ERR_9_MSG	DB	"DMA ACROSS 64K BOUNDARY. THIS SHOULD NOT HAPPEN!.",CR,LF,"$"
ERR_10_MSG	DB	"BAD CRC",CR,LF,"$"
ERR_20_MSG	DB	"NEC CONTROLER FAILED - HARDWARE ERROR!!!! -",CR,LF,"$"
ERR_40_MSG	DB	"SEEK FAILED  -HARDWARE ERROR!!!! -",CR,LF,"$"
ERR_80_MSG	DB	"TIME OUT ERROR. CLOSE DISK DOOR TO CORRECT",CR,LF,"$"


UNKNOWN_ERROR_MSG	DB	"AN UNKNOWN ERROR WAS ENCOUNTERED CODE-$"
ITOC_ONES	DB	?
ITOC_TENS	DB	?
ITOC_HUNDREDS	DB	?
CLR_MSG_AREA	DB	046H DUP(020H),"$"
DOS_BUG_MSG_6	DB	"BECAUSE OF A DOS BUG WE MIGHT GET AN ERROR MESSAGE",CR,LF
		DB	"IF THIS THE CASE, HIT RETURN ELSE CORRECT THE "
		DB	"PROBLEM AND HIT RETURN .$"
KEYBOARD_SCAN_CODE	DB	?
ASCII_CHAR_CODE		DB	?
CLR_DOS_BUG_MSG DB	04FH DUP(020H),"$"
PRESS_RETURN	DB	"PRESS RETURN TO CONTINUE -$"



CODE		ENDS		;END OF CODE SEGMENT

STACK	SEGMENT STACK  'STACK'
	DB	125 DUP('STACK AREA')
STACK	ENDS

	END	MAIN    	;NOTE ALWAYS END WITH THE RIGHT
				;PLACE TO START. IN THIS CASE THE MAIN
				;ROUTINE IS WHERE WE START THE PROGRAM




The entire AOH site is optimized to look best in Firefox® 3 on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986- AOH
We do not send spam. If you have received spam bearing an artofhacking.com email address, please forward it with full headers to abuse@artofhacking.com.