;****************************************************************************** ;****************************************************************************** ;****************************************************************************** ;****************************************************************************** ; ; ; DISK FORMATTING PROGRAM ; ; version 1.0 ; ; ;****************************************************************************** ;****************************************************************************** ;****************************************************************************** ;****************************************************************************** FORM ;****************************************************************************** ; ; ; SYSTEM CONSTANTS ; ; ;****************************************************************************** ; ; MRSOS: EQU 0005H ;CALL ADDRESS FOR MRS SYSRET: EQU 0000H ;SYSTEM RETURN ADDRESS CMDBUF: EQU 0007FH ;COMMAND BUFFER (INPUT) RDCE: EQU 1 ;READ CHARACTER OS REQUEST RDC: EQU 128 ;READ CHARACTER NO ECHO OS REQUEST WRTC: EQU 2 ;WRITE CHARACTER OS REQUEST WRBUF: EQU 9 ;WRITE BUFFER OS REQUEST NUMBER RDBUF: EQU 10 ;READ BUFFER OS REQUEST BELCHR: EQU 7 ;BELL CHARACTER LF: EQU 10 ;LINE FEED CHARACTER CRGRET: EQU 13 ;CARRIAGE RETURN CHARACTER TMDLAY: EQU 20H ;TIME DELAY CONSTANT RETURN: EQU 13 ;CARRIAGE RETURN CHARACTER DELETE: EQU 7FH ;DELETE CHARACTER ; ;****************************************************************************** ; ; D I S K C O N T R O L L E R C O N S T A N T S ; ; This program was originally written for a computer using a Western ; Digital 2793 disk controller located at address 50H (the 2793 is ; software compatible with the 1793 disk controller). In addition there ; is a drive select register located at address 60H. This register ; has bits that tell the disk controller whether a 5.25" drive or an ; 8" drive is being accessed, and the density of the target disk as ; well as the specific drive being selected. ; ;****************************************************************************** ; ; CMDREG: EQU 50H ;DISK CONTROLLER COMMAND REGISTER STATUS: EQU 50H ;DISK CONTROLLER STATUS REGISTER DATREG: EQU 53H ;DISK CONTROLLER DATA REGISTER DSKREG: EQU 60H ;DISK DRIVE SELECT REGISTER BSYMSK: EQU 01H ;CONTROLLER BUSY STATUS BIT MASK RDYMSK: EQU 80H ;CONTROLLER NOT READY STATUS BIT MASK WRPMSK: EQU 40H ;WRITE PROTECT MASK DRQMSK: EQU 02H ;DATA REQUEST BIT MASK LDTMSK: EQU 04H ;LOST DATA MASK MXWAIT: EQU 0FFH ;MAXIMUM DATA REQUEST WAIT INTERVAL ; ;****************************************************************************** ; ; A Z80 DMA controller is located at address 70H and is used exten- ; sively by this program. ; ;****************************************************************************** ; DMAREG: EQU 70H ;ADDRESS OF THE DMA CHIP DMALGT: EQU 14 ;LENGTH OF THE DMA INITIALIZATION TABLE DMACMD: EQU 87H ;ENABLE DMA COMMAND DMAHLT: EQU 83H ;DISABLE DMA COMMAND ; ;****************************************************************************** ; ; F O R M A T B U I L D T A B L E C O N S T A N T S ; ; The following constant values are all offsets into the main format ; build tables. ; ;****************************************************************************** ; DRVNBR: EQU 0 ;DISK DRIVE NUMBER DSKVAL: EQU 1 ;DISK REGISTER VALUE HDRADR: EQU 2 ;HEADER BUILD TABLE ADDRESS HDRAD2: EQU 3 ;HEADER BUILD TABLE ADDRESS MSB HDRLGT: EQU 4 ;LENGTH OF THE HEADER BUILD TABLE SCTADR: EQU 5 ;SECTOR BUILD TABLE ADDRESS SCTAD2: EQU 6 ;SECTOR BUILD TABLE ADDRESS MSB SCTLGT: EQU 7 ;LENGTH OF THE SECTOR BUILD TABLE SCTSIZ: EQU 8 ;# OF BYTES USED BY THE SECTOR AND GAP DATA SCTSZ2: EQU 9 ;# OF BYTES USED BY THE SECTOR AND GAP DATA MSB FSTSCT: EQU 10 ;FIRST SECTOR # USED ON A TRACK LSTSCT: EQU 11 ;LAST SECTOR # USED ON A TRACK TRLCHR: EQU 12 ;TRACK TRAILER CHARACTER USED OFFSET: EQU 13 ;OFFSET FROM START OF TABLE TO 1ST TRACK # FSTTRK: EQU 14 ;FIRST TRACK NUMBER USED LSTTRK: EQU 15 ;LAST TRACK NUMBER USED SIDES: EQU 16 ;NUMBER OF SIDES ON A DISK WRTCMD: EQU 17 ;WRITE TRACK COMMAND STPCMD: EQU 18 ;STEP HEAD COMMAND DELAY: EQU 19 ;TIME DELAY BEFORE CHECKING CONTROLLER STATUS SCTOFF: EQU 20 ;SECTOR NUMBER OFFSET IN BUILD TABLE TBLLGT: EQU 21 ;FORMAT TABLE LENGTH TBLLG2: EQU 22 ;FORMAT TABLE LENGTH MSB TLRLGT: EQU 23 ;# OF TRAILER CHARACTERS IN THE FORMAT TABLE TLRLG2: EQU 24 ;# OF TRAILER CHARACTERS MSB HOMCMD: EQU 25 ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; CONSOLE EXECUTIVE ; ;****************************************************************************** ; ORG 0100H ; CONSOL: LD SP,(6) ;INIT STACK POINTER CALL CLRSCN ;CLEAR THE CONSOLE SCREEN LD DE,MENU ;WRITE MENU TO CONSOLE LD C,WRBUF CALL MRSOS ; CONSLA: LD DE,INREQ ;OUTPUT COMMAND REQUEST MESSAGE TO CONSOLE LD C,WRBUF CALL MRSOS LD DE,CMDBUF ;GET COMMAND FROM CONSOLE LD C,RDBUF CALL MRSOS ; LD A,(CMDBUF+2) ;GET COMMAND CHARACTER CP A,'E' ;END FORMAT? JR NZ,CONSLB ;NO, CONTINUE CALL CLRSCN ;CLEAR THE CONSOLE SCREEN JP SYSRET CONSLB: CP A,'1' ;CHECK LOWER BOUNDS JR C,CONSLA ;REPEAT REQUEST IF OUT OF BOUNDS CP A,'9' ;CHECK UPPER BOUNDS JR NC,CONSLA ;REPEAT REQUEST IF OUT OF BOUNDS LD E,LF ;ECHO LINE FEED LD C,WRTC CALL MRSOS ; SUB A,'1' ;REMOVE ASCII CODING LD L,A ;SETUP COMMAND TABLE OFFSET LD H,0 ADD HL,HL ;FULL WORD/TABLE ENTRY LD DE,CMDTAB ;TABLE BASE ADDRESS ADD HL,DE ;POINTER TO TABLE ENTRY LD E,(HL) ;GET TABLE ENTRY INC HL LD D,(HL) PUSH DE ;MOVE TABLE ENTRY TO 'IX' POP IX ; LD DE,VERMSG ;WRITE VERIFY REQUEST LD C,WRBUF CALL MRSOS LD DE,CMDBUF ;GET VERIFICATION LD C,RDBUF CALL MRSOS LD E,LF ;ECHO LINE FEED LD C,WRTC CALL MRSOS LD A,(CMDBUF+2) ;GET VERIFY CHARACTER CP A,'Y' ;START FORMAT? JP NZ,CONSOL ;NO-RESTART EXEC ; CALL FORMAT ;FORMAT DISK JP CONSOL ;RESTART EXEC FORM ;****************************************************************************** ; ; C L R S C N ; ; THIS ROUTINE CLEARS THE SCREEN OF THE CONSOLE. THE MESSAGE "CLRMSG" ; USED BY THIS ROUTINE IS DESIGNED FOR AN ANSI STANDARD TERMINAL (VT100). ; ;****************************************************************************** ; ; CLRSCN: LD DE,CLRMSG ;OUTPUT THE CLEAR SCREEN COMMAND TO THE CONSOLE LD C,WRBUF CALL MRSOS RET FORM ;****************************************************************************** ; ; C O M M A N D T A B L E ; ; This table is used to translate the console command to a pointer ; to the specific set of tables used in formatting the desired disk. ; ;****************************************************************************** ; ; CMDTAB: DW SSSDA ;DRIVE A : 8" SINGLE SIDED,SINGLE DENSITY DW SSDDA ;DRIVE A : 8" SINGLE SIDED,DOUBLE DENSITY DW SSSDB ;DRIVE B : 8" SINGLE SIDED,SINGLE DENSITY DW SSDDB ;DRIVE B : 8" SINGLE SIDED,DOUBLE DENSITY DW SSSDC ;DRIVE C : 5.25" SINGLE SIDED,SINGLE DENSITY DW SSDDC ;DRIVE C : 5.25" SINGLE SIDED,DOUBLE DENSITY DW SSSDD ;DRIVE D : 5.25" SINGLE SIDED,SINGLE DENSITY DW SSDDD ;DRIVE D : 5.25" SINGLE SIDED,DOUBLE DENSITY FORM ;****************************************************************************** ; ; F O R M A T ; ; THIS IS THE ROUTINE THAT ACTUALLY FORMATS THE DISK ; ;****************************************************************************** ; ; FORMAT: CALL INIT ;INITIALIZE THE DRIVE AND TABLES JR NZ,FORMAE ;EXIT IF NO DISK IN SPECIFIED DRIVE LD A,(IX+FSTTRK) ;INITIALIZE THE TRACK COUNTER LD (TRKNBR),A LD IY,DMATBL ;SET A POINTER TO THE DMA TABLE LD B,(IX+TBLLGT) ;PUT THE TABLE LENGTH IN THE DMA TABLE LD (IY+10),B LD B,(IX+TBLLG2) LD (IY+11),B CALL DSPTRK ;DISPLAY THE TRACK NUMBER FORMA1: CALL WRTTRK ;WRITE THE TRACK SECOTRING INFO LD A,(TRKNBR) ;GET THE CURRENT TRACK NUMBER CP A,(IX+LSTTRK) ;COMPARE AGAINST THE HIGHEST TRACK NUMBER JR Z,FORMAE ;EXIT IF COMPLETE INC A ;INCREMENT THE TRACK NUMBER CALL DSPTRK ;DISPLAY THE TRACK NUMBER LD (TRKNBR),A CALL UPDATE ;UPDATE THE TRACK TABLE JR FORMA1 ;DO THE NEXT TRACK FORMAE: LD DE,ENDMSG ;SEND END MESSAGE TO CONSOLE LD C,WRBUF CALL MRSOS LD A,00H ;DESELECT DRIVES OUT (DSKREG),A RET FORM ;****************************************************************************** ; ; I N I T ; ; THIS ROUTINE INITIALIZES THE SYSTEM FOR DISK FORMATTING. ; FIRST IT HOMES THE HEAD ON THE DRIVE CONTAINING THE DISK TO FORMAT ; THEN IT BUILDS A TABLE IN MEMORY THAT REPRESENTS THE FORMATTING ; INFORMATION FOR THE ENTIRE FIRST TRACK ON THE DISK. ; ;****************************************************************************** ; ; INIT: CALL HOMEHD ;HOME THE HEAD ON THE SELECTED DRIVE JR NZ,INITE ;EXIT IF NO DISK IN THE DRIVE LD HL,TBLBGN ;SET A POINTER TO THE FORMAT TABLE CALL BLDHDR ;BUILD THE HEADER TABLE (1ST GAP) LD E,(IX+SCTADR) ;GET THE LSB OF THE SECTOR BUILD TABLE ADDR LD D,(IX+SCTAD2) ;GET THE MSB OF THE SECOTR BUILD TABLE ADDR LD A,(IX+SCTOFF) ;GET THE SECTOR # OFFSET IN THE BUILD TABLE ADD A,E ;ADD THE OFFSET TO THE START ADDRESS JR NC,INIT3 ;SKIP THE NEXT INSTRUCTION IF NO CARRY INC D ;ADD THE CARRY TO THE MSB OF THE ADDRESS INIT3: LD E,A ;PUT THE NEW LSB BACK IN E LD (SOFFST),DE ;STORE THE OFFSET ADDRESS LD A,(IX+FSTSCT) ;INITIALIZE THE SECTOR COUNTER LD (SCTNBR),A INIT1: CALL BLDSCT ;BUILD A SECTOR OF THE FORMAT TABLE LD A,(SCTNBR) ;GET THE SECTOR NUMBER CP A,(IX+LSTSCT) ;COMPARE AGAINST THE MAXIMUM SECTOR NUMBER JR Z,INIT2 ;BUILD THE TRAILER IF ALL DONE HERE INC A ;INCREMENT THE SECTOR NUMBER LD (SCTNBR),A JR INIT1 ;GO BUILD THE NEXT SECTOR INIT2: CALL BLDTLR ;BUILD THE TRAILER ONTO THE FORMAT TABLE INITE: RET FORM ;****************************************************************************** ; ; H O M E H D ; ; THIS ROUTINE HOMES THE HEAD ON THE DRIVE CONTAINING THE DISK TO ; BE FORMATTED. IF THE DRIVE DOES NOT CONTAIN A DISKETTE AN ERROR ; FLAG IS RETURNED. ; ;****************************************************************************** ; ; HOMEHD: CALL DSNBSY ;CHECK FOR DISK CONTROLLER NOT BUSY LD A,(IX+DSKVAL) ;GET THE DISK SELECT COMMAND OUT (DSKREG),A ;OUTPUT THE DISK SELECT COMMAND CALL WTSTAT ;WAIT FOR STATUS VALID CALL DSKRDY ;SEE IF A DISK IS IN THE SELECTED DRIVE JR NZ,HOMEHE ;EXIT IF NO DISK PRESENT LD A,(IX+HOMCMD) ;GET THE HOME HEAD COMMAND OUT (CMDREG),A CALL WTSTAT ;WAIT FOR THE STATUS TO BE VALID CALL TSTWRP ;SEE IF THE DISK IS WRITE PROTECTED HOMEHE: RET FORM ;****************************************************************************** ; ; D S N B S Y ; ; THIS ROUTINE EXAMINES THE DISK CONTROLLER STATUS AND WAITS FOR IT ; TO GIVE A NOT BUSY STATUS. ; ;****************************************************************************** ; ; DSNBSY: IN A,(STATUS) ;GET THE DISK CONTROLLER STATUS AND A,BSYMSK ;MASK OFF ALL BUT THE BUSY BIT JR NZ,DSNBSY ;LOOP IF THE BUSY BIT IS SET RET FORM ;****************************************************************************** ; ; W T S T A T ; ; THIS ROUTINE WAITS FOR THE DISK CONTROLLER STATUS REGISTER TO GO ; VALID AFTER A COMMAND IS RECEIVED ; ;****************************************************************************** ; ; WTSTAT: LD A,(IX+DELAY) ;GET THE TIME DELAY CONSTANT WTSTA1: DEC A ;DECREMENT THE TIMER JR NZ,WTSTA1 ;LOOP IF TIME NOT EXPIRED RET FORM ;****************************************************************************** ; ; D S K R D Y ; ; THIS ROUTINE CHECKS TO SEE IF THE READY BIT IS SET IN THE DISK ; CONTROLLER STATUS REGISTER, INDICATING THAT A DISKETTE IS IN THE ; SELECTED DRIVE. ; ;****************************************************************************** ; ; DSKRDY: IN A,(STATUS) ;GET THE DISK CONTROLLER STATUS AND A,RDYMSK ;MASK OFF ALL BUT THE NOT READY BIT RET FORM ;****************************************************************************** ; ; B L D H D R ; ; THIS ROUTINE BUILDS THE HEADER TABLE (1ST GAP) FOR THE DESIRED TRACK ; FORMAT. ; ;****************************************************************************** ; ; BLDHDR: LD C,(IX+HDRADR) ;GET THE HEADER BUILD TABLE ADDRESS LD B,(IX+HDRAD2) PUSH BC ;PUSH THE ADDRESS ONTO THE STACK POP IY ;POP THE ADDRESS INTO THE IY INDEX REGISTER LD A,(IX+HDRLGT) ;GET THE HEADER BUILD TABLE LENGTH BLDHD0: LD B,(IY+0) ;GET THE REPEAT COUNT AND CHARACTER INC IY ;INCREMENT THE TABLE POINTER LD C,(IY+0) ;GET THE CHARACTER BLDHD1: LD (HL),C ;STORE THE CHARACTER IN THE FORMAT TABLE INC HL ;INCREMENT THE FORMAT TABLE POINTER DEC B ;DECREMENT THE REPEAT COUNT JR NZ,BLDHD1 ;REPEAT CHARACTER IF NECESSARY INC IY ;INCREMENT THE HEADER BUILD TABLE POINTER DEC A ;DECREMENT THE BUILD TABLE COUNTER JR NZ,BLDHD0 ;CONTINUE IF ENTIRE HEADER ISN'T BUILT RET FORM ;****************************************************************************** ; ; B L D S C T ; ; THIS ROUTINE BUILDS THE NEXT SECTOR AND GAP INTO THE FORMAT TABLE. ; ;****************************************************************************** ; ; BLDSCT: LD C,(IX+SCTADR) ;GET THE SECTOR BUILD TABLE ADDRESS LD B,(IX+SCTAD2) PUSH BC ;PUT THE ADDRESS ONTO THE STACK POP IY ;POP THE ADDRESS INTO THE IY INDEX REGISTER PUSH HL ;SAVE THE FORMAT TABLE POINTER ON THE STACK LD HL,(SOFFST) ;GET THE SECTOR NUMBER OFFSET ADDRESS LD (HL),A ;STORE THE NEW SECTOR NUMBER IN THE TABLE POP HL ;RECOVER THE FORMAT TABLE POINTER LD A,(IX+SCTLGT) ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE BLDSC0: LD B,(IY+0) ;GET THE CHARACTER REPEAT COUNT INC IY ;INCREMENT THE BUILD TABLE POINTER LD C,(IY+0) ;GET THE CHARACTER BLDSC1: LD (HL),C ;PUT THE CHARACTER INTO THE FORMAT TABLE INC HL ;INCREMENT THE FORMAT TABLE POINTER DEC B ;DECREMENT THE CHARACTER REPEAT COUNT JR NZ,BLDSC1 ;REPEAT CHARACTER IF NECESSARY INC IY ;INCREMENT THE SECTOR BUILD TABLE POINTER DEC A ;DECREMENT THE BUILD TABLE LINE COUNTER JR NZ,BLDSC0 ;REPEAT IF THE ENTIRE SECOTR IS NOT BUILD RET FORM ;****************************************************************************** ; ; B L D T L R ; ; THIS ROUTINE BUILDS THE TRAILER AT THE END OF THE SECTOR TABLE ; ;****************************************************************************** ; ; BLDTLR: LD E,(IX+TLRLGT) ;GET THE # OF TRAILER CHARACTERS TO WRITE LD D,(IX+TLRLG2) BLDTL0: LD A,(IX+TRLCHR) ;GET THE TRAILER CHARACTER LD (HL),A ;PUT THE CHARACTER IN THE TABLE INC HL ;INCREMENT THE TABLE POINTER DEC DE ;DECREMENT THE CHARACTER COUNTER LD A,E ;TEST FOR ZERO CHARACTER COUNT OR A,D JR NZ,BLDTL0 ;LOOP IF WE AREN'T FINISHED RET FORM ;****************************************************************************** ; ; W R T T R K ; ; THIS ROUTINE WRITES A TRACK OF FORMAT INFORMATION TO THE DISK. ; ;****************************************************************************** ; ; WRTTRK: PUSH IY ;PUT THE CONTENTS OF THE IY REGISTER ON STACK POP HL ;MOVE IT INTO THE HL REGISTER LD C,DMAREG ;POINT TO THE DMA WRITE REGISTERS LD B,DMALGT ;LENGTH OF THE DMA TABLE OTIR ;PUT THE DMA TABLE INTO THE DMA CHIP CALL DSNBSY ;MAKE SURE THE DISK CONTROLLER ISN'T BUSY WRTTR1: LD A,DMACMD ;GET THE START DMA COMMAND OUT (DMAREG),A ;OUTPUT THE COMMAND TO THE DMA CHIP LD A,(IX+WRTCMD) ;GET THE WRITE TRACK COMMAND OUT (CMDREG),A ;AND OUTPUT IT TO THE DISK CONTROLLER CALL WTSTAT ;WAIT FOR VALID DISK CONTROLLER STATUS WRTTR0: IN A,(STATUS) ;GET THE DISK CONTROLLER STATUS LD B,A ;SAVE A COPY IN THE B REGISTER AND A,LDTMSK ;CHECK FOR LOST DATA JR NZ,WRTTRK ;GO TRY AGAIN IF WE BLEW IT THIS TIME LD A,B ;GET THE SAVED STATUS AND A,BSYMSK ;CHECK FOR DISK CONTROLLER BUSY JR NZ,WRTTR0 ;LOOP IF THE DISK CONTROLLER IS STILL BUSY LD A,DMAHLT ;DISABLE DMA COMMAND OUT (DMAREG),A RET FORM ;****************************************************************************** ; ; T S T W R P ; ; THIS ROUTINE EXAMINES THE DISK CONTROLLER STATUS REGISTER AFTER ; A WRITE COMMAND HAS BEEN ISSUED AND DETERMINES IF THE DISKETTE ; IS WRITE PROTECTED. IF THE DISK IS NOT WRITE PROTECTED A ZERO ; IS RETURNED IN THE ACCUMUALTOR, IF IT IS PROTECTED A 40H IF RETURNED ; ;****************************************************************************** ; ; TSTWRP: IN A,(STATUS) ;GET THE DISK CONTROLLER STATUS AND A,WRPMSK ;MASK OFF ALL BUT THE WRITE PROTECT BIT RET FORM ;****************************************************************************** ; ; D S P T R K ; ; THIS ROUTINE DISPLAYS THE CURRENT TRACK NUMBER ON THE CONSOLE. ; ;****************************************************************************** ; ; DSPTRK: LD C,WRBUF ;SET A POINTER TO THE WRITE BUFFER REQUEST LD (TRKDSP),A ;SAVE THE TRACK NUMBER IN THE MESSAGE LD DE,TRKMSG ;SET POINTER TO THE TRACK NUMBER MESSAGE CALL MRSOS ;CALL THE OPERATING SYSTEM RET FORM ;****************************************************************************** ; ; U P D A T E ; ; THIS ROUTINE UPDATES THE TRACK NUMBERS IN THE FORMAT TABLE AND STEPS ; THE HEAD ON THE DISK IN ONE TRACK. ; ;****************************************************************************** ; ; UPDATE: CALL STEPHD ;STEP-IN THE HEAD ONE TRACK LD B,(IX+FSTSCT) ;INITIALIZE THE SECTOR COUNTER LD HL,TBLBGN ;SET A POINTER TO THE START OF FORMAT TABLE LD A,L ;PUT THE LEAST SIGNIFICANT BYTE IN A ADD A,(IX+OFFSET) ;ADD THE TRACK # OFFSET TO A JR NC,UPDAT0 ;SKIP NEXT INSTRUCTION IF NO CARRY GENERATED INC H ;ADD THE CARRY TO H UPDAT0: LD L,A ;PUT THE NEW LSB BACK IN L UPDAT1: LD A,(TRKNBR) ;PUT THE NEW TRACK NUMBER IN A LD (HL),A ;DEPOSIT THE TRACK NUMBER IN THE FORMAT TABLE LD A,L ;PUT THE LSB OF THE TABLE ADDRESS IN A ADD A,(IX+SCTSIZ) ;ADD THE LSB OF THE SECTOR SIZE TO A JR NC,UPDAT2 ;SKIP THE NEXT INSTRUCTION IF NO CARRY INC H ;INCREMENT THE MSB OF THE ADDRESS UPDAT2: LD L,A ;SAVE THE LSB OF THE ADDRESSIN L LD A,H ;PUT THE MSB OF THE ADDRESS IN A ADD A,(IX+SCTSZ2) ;ADD THE MSB OF THE SECTOR SIZE TO A LD H,A ;SAVE THE MSB OF THE ADDRESS IN H LD A,B ;MOVE THE CURRENT SECTOR NUMBER INTO A INC B ;INCREMENT THE SECTOR COUNTER CP A,(IX+LSTSCT) ;COMPARE WITH THE MAXIMUM SECTOR NUMBER JR NZ,UPDAT1 ;LOOP IF WE AREN'T FINISHED RET FORM ;****************************************************************************** ; ; S T E P H D ; ; STEP THE HEAD ON THE DRIVE IN ONE TRACK. ; ;****************************************************************************** ; ; STEPHD: CALL DSNBSY ;MAKE SURE THE DISK CONTROLLER ISN'T BUSY LD A,(IX+STPCMD) ;LOAD THE ACCUMULATOR WITH THE STEP COMMAND OUT (CMDREG),A ;OUTPUT THE STEP COMMAND CALL WTSTAT ;WAIT FOR VALID DISK CONTROLLER STATUS RET FORM ;------------------------------------------------------------------------------ ; ; S Y S T E M D A T A T A B L E S ; ;------------------------------------------------------------------------------ ; ; ; TRKNBR: DB 0 SCTNBR: DB 0 SOFFST: DW 0 MENU: DB 13,10,10,'FORMAT PROGRAM-MAIN MENU',13,10,10 DB '1 : DRIVE A / SINGLE DENSITY',13,10 DB '2 : DRIVE A / DOUBLE DENSITY',13,10,10 DB '3 : DRIVE B / SINGLE DENSITY',13,10 DB '4 : DRIVE B / DOUBLE DENSITY',13,10,10 DB '5 : DRIVE C / SINGLE DENSITY',13,10 DB '6 : DRIVE C / DOUBLE DENSITY',13,10,10 DB '7 : DRIVE D / SINGLE DENSITY',13,10 DB '8 : DRIVE D / DOUBLE DENSITY',13,10,10 DB 'E : EXIT PROGRAM',13,10,10,10,10,'$' INREQ: DB 13,'Select the desired option number and press RETURN: $' CLRMSG: DB 1BH,'[2J$' VERMSG: DB 13,'Verify the command & enter the appropriate key (Y/N) $' TRKMSG: DB 13,'TRACK NUMBER ',130 TRKDSP: DB 0,0,'$' NODISK: DB 13,10,'THERE IS NO DISKETTE IN DRIVE $' WRTPRT: DB 13,10,'THE DISKETTE IS WRITE PROTECTED$' ENDMSG: DB 13,10,'FORMAT COMPLETE$' FORM ;****************************************************************************** ; ; DRIVE "A" : SINGLE DENSITY ; ;****************************************************************************** ; SSSDA: DB 0 ;DISK DRIVE NUMBER DB 0B1H ;DISK REGISTER VALUE DW HDRSS8 ;HEADER BUILD TABLE ADDRESS DB 4 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSS8 ;SECTOR BUILD TABLE ADDRESS DB 13 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 186 ;SECTOR AND GAP LENGTH IN TABLE DB 1 ;FIRST SECTOR NUMBER DB 26 ;LAST SECTOR NUMBER DB 0FFH ;TRACK TRAILER CHARACTER DB 80 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 76 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 9 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 5409 ;FORMAT TABLE LENGTH DW 500 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0CH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "B" : SINGLE DENSITY ; ;****************************************************************************** ; SSSDB: DB 1 ;DISK DRIVE NUMBER DB 0B2H ;DISK REGISTER VALUE DW HDRSS8 ;HEADER BUILD TABLE ADDRESS DB 4 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSS8 ;SECTOR BUILD TABLE ADDRESS DB 13 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 186 ;SECTOR AND GAP LENGTH IN TABLE DB 1 ;FIRST SECTOR NUMBER DB 26 ;LAST SECTOR NUMBER DB 0FFH ;TRACK TRAILER CHARACTER DB 80 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 76 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 9 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 5409 ;FORMAT TABLE LENGTH DW 500 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0CH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "C" : SINGLE DENSITY ; ;****************************************************************************** ; SSSDC: DB 2 ;DISK DRIVE NUMBER DB 054H ;DISK REGISTER VALUE DW HDRSDD ;HEADER BUILD TABLE ADDRESS DB 5 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSDD ;SECTOR BUILD TABLE ADDRESS DB 16 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 370 ;SECTOR AND GAP LENGTH IN TABLE DB 1 ;FIRST SECTOR NUMBER DB 16 ;LAST SECTOR NUMBER DB 4EH ;TRACK TRAILER CHARACTER DB 162 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 39 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 59H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 11 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 7066 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0DH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "D" : SINGLE DENSITY ; ;****************************************************************************** ; SSSDD: DB 3 ;DISK DRIVE NUMBER DB 058H ;DISK REGISTER VALUE DW HDRSDD ;HEADER BUILD TABLE ADDRESS DB 5 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSDD ;SECTOR BUILD TABLE ADDRESS DB 16 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 370 ;SECTOR AND GAP LENGTH IN TABLE DB 1 ;FIRST SECTOR NUMBER DB 16 ;LAST SECTOR NUMBER DB 4EH ;TRACK TRAILER CHARACTER DB 162 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 39 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 59H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 11 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 7066 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0DH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "A" : DOUBLE DENSITY ; ;****************************************************************************** ; SSDDA: DB 0 ;DISK DRIVE NUMBER DB 031H ;DISK REGISTER VALUE DW HDRSDD ;HEADER BUILD TABLE ADDRESS DB 5 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSDD ;SECTOR BUILD TABLE ADDRESS DB 16 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 370 ;SECTOR AND GAP LENGTH IN TABLE DB 1 ;FIRST SECTOR NUMBER DB 26 ;LAST SECTOR NUMBER DB 04EH ;TRACK TRAILER CHARACTER DB 162 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 76 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 11 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 10766 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0CH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "B" : DOUBLE DENSITY ; ;****************************************************************************** ; SSDDB: DB 1 ;DISK DRIVE NUMBER DB 032H ;DISK REGISTER VALUE DW HDRSDD ;HEADER BUILD TABLE ADDRESS DB 5 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSDD ;SECTOR BUILD TABLE ADDRESS DB 16 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 370 ;SECTOR AND GAP LENGTH IN TABLE DB 1 ;FIRST SECTOR NUMBER DB 26 ;LAST SECTOR NUMBER DB 04EH ;TRACK TRAILER CHARACTER DB 162 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 76 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 11 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 10766 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0CH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "C" : DOUBLE DENSITY ; ;****************************************************************************** ; SSDDC: DB 2 ;DISK DRIVE NUMBER DB 054H ;DISK REGISTER VALUE DW HDRSDK ;HEADER BUILD TABLE ADDRESS DB 5 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSDK ;SECTOR BUILD TABLE ADDRESS DB 18 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 594 ;SECTOR AND GAP LENGTH IN TABLE DB 0 ;FIRST SECTOR NUMBER DB 9 ;LAST SECTOR NUMBER DB 04EH ;TRACK TRAILER CHARACTER DB 116 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 39 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 11 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 7044 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0DH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; DRIVE "D" : DOUBLE DENSITY ; ;****************************************************************************** ; SSDDD: DB 3 ;DISK DRIVE NUMBER DB 058H ;DISK REGISTER VALUE DW HDRSDK ;HEADER BUILD TABLE ADDRESS DB 5 ;NUMBER OF ENTRIES IN HEADER BUILD TABLE DW SCTSDK ;SECTOR BUILD TABLE ADDRESS DB 18 ;NUMBER OF ENTRIES IN SECTOR BUILD TABLE DW 594 ;SECTOR AND GAP LENGTH IN TABLE DB 0 ;FIRST SECTOR NUMBER DB 9 ;LAST SECTOR NUMBER DB 04EH ;TRACK TRAILER CHARACTER DB 116 ;OFFSET FROM START OF TABLE TO 1ST TRACK NUMBER DB 0 ;FIRST TRACK NUMBER DB 39 ;LAST TRACK NUMBER DB 1 ;NUMBER OF SIDES ON THE DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY ON STATUS DB 11 ;SECTOR # OFFSET IN SECTOR BUILD TABLE DW 7044 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN FORMAT TABLE DB 0DH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; ; SINGLE SIDED DOUBLE DENSITY 5.25" FORMAT ; ; ;****************************************************************************** ; ; SSDD5: DB 4 ;DISK DRIVE NUMBER DB 051H ;DISK REGISTER VALUE DW HDRSDD ;HEADER BUILD TABLE ADDRESS DB 5 ;HEADER BUILD TABLE LENGTH DW SCTSDD ;SECTOR BUILD TABLE ADDRESS DB 16 ;SECTOR BUILD TABLE LENGTH DW 370 ;SECTOR AND GAP LENGTH DB 1 ;FIRST SECTOR NUMBER DB 16 ;LAST SECTOR NUMBER DB 4EH ;TRACK TRAILER CHARACTER DB 162 ;TRACK # OFFSET IN TABLE DB 0 ;FIRST TRACK NUMBER DB 39 ;LAST TRACK NUMBER DB 1 ;# OF SIDES ON DISK DB 0F4H ;WRITE TRACK COMMAND DB 59H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY CONSTANT DB 11 ;SECTOR NUMBER OFFSET IN SECTOR BUILD TABLE DW 7066 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN THE TABLE DB 0DH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; ; SINGLE SIDED DOUBLE DENSITY 5.25" KAYPRO FORMAT ; ; ;****************************************************************************** ; ; SSDDK: DB 2 ;DISK DRIVE NUMBER DB 054H ;DISK REGISTER VALUE DW HDRSDK ;HEADER BUILD TABLE ADDRESS DB 5 ;HEADER BUILD TABLE LENGTH DW SCTSDK ;SECTOR BUILD TABLE ADDRESS DB 18 ;SECTOR BUILD TABLE LENGTH DW 594 ;SECTOR AND GAP LENGTH DB 0 ;FIRST SECTOR NUMBER DB 9 ;LAST SECTOR NUMBER DB 4EH ;TRACK TRAILER CHARACTER DB 116 ;TRACK # OFFSET IN TABLE DB 0 ;FIRST TRACK NUMBER DB 39 ;LAST TRACK NUMBER DB 1 ;# OF SIDES ON DISK DB 0F4H ;WRITE TRACK COMMAND DB 58H ;STEP HEAD COMMAND DB 1AH ;TIME DELAY CONSTANT DB 11 ;SECTOR NUMBER OFFSET IN SECTOR BUILD TABLE DW 7044 ;FORMAT TABLE LENGTH DW 1000 ;NUMBER OF TRAILER CHARACTERS IN THE TABLE DB 0DH ;HOME HEAD COMMAND FORM ;****************************************************************************** ; ; ; SINGLE DENSITY TABLES ; ; ;****************************************************************************** ; ; HDRSS8: DW 0FF28H DW 0006H DW 0FC01H DW 0FF1AH ; ; SCTSS8: DW 0006H DW 0FE01H DW 0001H DW 0001H DW 0101H DW 0001H DW 0F701H DW 0FF0BH DW 0006H DW 0FB01H DW 0E580H DW 0F701H DW 0FF1BH FORM ;****************************************************************************** ; ; ; DOUBLE DENSITY TABLES ; ; ;****************************************************************************** ; ; HDRSDD: DW 4E50H DW 000CH DW 0F603H DW 0FC01H DW 4E32H ; ; SCTSDD: DW 000CH DW 0F503H DW 0FE01H DW 0001H ;TRACK NUMBER DW 0001H ;SIDE NUMBER DW 0101H ;SECTOR NUMBER DW 0101H ;SECTOR LENGTH DW 0F701H DW 4E16H DW 000CH DW 0F503H DW 0FB01H DW 0E580H ;1ST HALF OF DATA DW 0E580H ;2ND HALF OF DATA DW 0F701H DW 4E36H FORM ;****************************************************************************** ; ; ; KAYPRO FORMAT TABLES ; ; ;****************************************************************************** ; ; HDRSDK: DW 4E48H DW 000CH DW 0F603H DW 0FC01H DW 4E10H ; ; SCTSDK: DW 0008H DW 0F503H DW 0FE01H DW 0001H DW 0001H DW 0001H ;SECTOR NUMBER DW 0201H ;SECTOR SIZE DW 0F701H DW 04E16H DW 000CH DW 0F503H DW 0FB01H DW 0E580H DW 0E580H DW 0E580H DW 0E580H DW 0F701H DW 4E1AH FORM ;****************************************************************************** ; ; ; DMA COMMAND TABLE ; ; ;****************************************************************************** ; ; DMATBL: DB 0C3H ;WR6, RESET AND DISABLE INTERRUPTS DB 01H ;WR0, PORT B IS THE SOURCE (TEMPORARY) DB 28H ;WR2, PORT B IS I/O FIXED ADDRESS DB 085H ;WR4, BYTE MODE, ONE BYTE PORT B ADDRESS DB DATREG ;PORT B ADDRESS (DISK CONTROLLER DATA REGISTER) DB 8AH ;READY IS ACTIVE HIGH DB 0CFH ;LOAD PORT B ADDRESS DB 7DH ;2 BYTE A ADDRESS, BLOCK LENGTH, A IS SOURCE DW TBLBGN ;STARTING ADDRESS FOR PORT A DW 0000H ;INITIAL DUMMY BLOCK LENGTH DB 14H ;PORT A ADDRESS INCREMENTS AND IS MEMORY DB 0CFH ;LOAD PORT A ADDRESS ; TBLBGN: EQU $ ; ; END CONSOL