TITLE FORMAT UTILITY LIST NOCOND ;************************************************************* ; ; JADE DOUBLE D DISK FORMAT PROGRAM ; ;************************************************************* ; ; Format is a system utility which provides a means to ; write a single or double density format on any of drives A ; through D. ; ;************************************************************* ; ; REVISION STATUS: ; ; 1.0 - 8 FEB 81 GRH ; RELEASE ; ; 1.1 - 25 MAR 83 GRH ; Removed system track xfer. Superceeded by the new SYSGEN utility. ; Cleaned up for ASMB. ; Removed format system tracks only option. Never worked! ; Added capability to double the directory size for disks with many ; small programs (such as libraries). ; ; 1.2 - 31 AUG 83 GRH ; Added 256 byte (IBM system 34 compatibility) sector formatting. ; Added sector read verification after format. ; ; 1.3 - 09 JUN 84 GRH ; Removed format vector from BIOS to this program. ; VERSN EQU '13' ;CHANGE HERE FOR SIGN-ON CHANGE ; ;************************************************************* FALSE EQU 0 TRUE EQU NOT FALSE LSTINC EQU FALSE ; ; *INCLUDE JDDCONT.DEF ; *INCLUDE JDDLOC.DEF ; IF NOT LSTINC LIST OFF ENDIF *INCLUDE JDDCONT.DEF *INCLUDE JDDLOC.DEF LIST ON SUBTTL DECLARATIONS ; ; DRIVER MODULE DEFINITIONS ; CTRLC: EQU 3 ;REQUEST REBOOT CPM LF: EQU 0AH ;LINE FEED CR: EQU 0DH ;CARRIAGE RETURN BS EQU 08H ;BACKSPACE REBOOT: EQU 0 ;REBOOT ADDR TPA: EQU 100H ;TRANSIENT PROGRAM AREA DRV1 EQU 'C' ;1ST CP/M DRIVE TO FORMAT DRVN EQU 'D' ;LAST CP/M DRIVE TO FORMAT NDRVS EQU DRVN + 1 - DRV1 ;MAX NUMBER OF DRIVES TRK0: EQU 0 ;TRACK 0 TRK1: EQU 1 ;TRACK 1 TRK2: EQU 2 ;TRACK 2 TRK76: EQU 76 ;TRACK 76 SECSZ: EQU 128 ;128 BYTES PER SECTOR IDSEC: EQU 1 ;ID SECTOR # ; ; INJECTION MODULE DEFINITIONS ; ZEROS: EQU 00000000B ;ALL ZEROS BYTE ONES: EQU 11111111B ;ALL ONES BYTE FMTSZ EQU 256 ;FORMAT INJECTION MODULE LENGTH ; ; BDOS CALL VECTORS ; WBOOT EQU 0000H ;SYSTEM WARM BOOT BDOS: EQU 0005H ;SYSTEM CALL ADDR ; ; BIOS VECTOR DEFINITIONS ; SLDSKV: EQU 8 ;SELECT DISK OFFSET SETRKV: EQU 9 ;SET TRACK OFFSET SETSECV:EQU 10 ;SET SECTOR OFFSET SETMAV: EQU 11 ;SET ADDRESS OFFSET RDSECV: EQU 12 ;READ SECTOR OFFSET WRSECV: EQU 13 ;WRITE SECTOR OFFSET LOGVC: EQU 1 ;DRV SEL DON'T LOGON SUBTTL MACROS ;; ;; GENERATE THE TRANSLATE TABLE ;; GXLATE MACRO #SECTORS, #SKEW LIST NOGEN NXTSEC DL 1 ;;START WITH SECTOR 1 LOWEST DL 1 REPT #SECTORS ;;ONCE FOR EACH SECTOR LIST GEN DB NXTSEC LIST NOGEN NXTSEC DL NXTSEC + #SKEW ;;ADD IN SKEW FACTOR IF NXTSEC > #SECTORS ;;CHECK FOR OVERFLOW NXTSEC DL NXTSEC - #SECTORS IF NXTSEC <= LOWEST ;;CHECK FOR REPEAT NXTSEC DL LOWEST + 1 LOWEST DL NXTSEC ENDIF ENDIF ENDM ENDM SUBTTL MAIN PROGRAM ORG TPA ; ; PROGRAM ENTRY POINT ; JP INIT ;INITIALIZE $MEMRY DW CODEND ;PTR TO 1ST AVAILABLE BYTE OF MEMORY ; ; DRIVE LIMITS, USER CHANGABLE ; DRVLO DB DRV1 - 'A' ;1ST DRIVE DRVHI DB DRVN - 'A' + 1 ;LAST DRIVE + 1 ; ; COPYRIGHT NOTICE ; SIGNON: DB 'Floppy disk format Utility Ver ' DB HIGH VERSN,'.',LOW VERSN,CR,LF DB 'Copyright (c) 1983 GRH Enterprises' DB '$' ; ; MAIN PROGRAM CONTINUES ; INIT: LD SP,(BDOS + 1) DEC SP DEC SP LD DE,SIGNON ;OUTPUT MESSAGE CALL MSGOT FUNBG: LD DE,MSGFL ;OUTPUT FUNCTION LIST CALL MSGOT CALL CNSIN ;GET CONSOLE CHAR CP '1' ;IF 1 THEN FORMAT DDEN JR Z,FUN1 CP '2' ;ELSE IF 2 THEN FORMAT SDEN JP Z,FUN2 CP '3' ;ELSE IF 3 THEN FORMAT IBM 3740 JP Z,FUN3 CP '4' ;ELSE IF 4 THEN FORMAT 256 BYTE SECTORS JP Z,FUN4 LD DE,MSGSE ;ELSE OUTPUT ERROR MSG LD (LTRSE),A ;STORE BAD SYMBOL CALL MSGOT JR FUNBG ;REPEAT ;---------------------------------------------------------- ; ; FUNCTION 1 - DOUBLE DENSITY FORMAT ; TRK 0= SINGLE DENSITY ; TRK 1..76= DOUBLE DENSITY 128 BYTE SECTORS ; ;---------------------------------------------------------- FUN1: LD IX,IDSDD ;SET DEFAULT DIRECTORY SIZE LD A,(IX+DDFLG) ;SET FLAGS LD (FFLAG),A LD HL,DDSDIR CALL SELDR ;SELECT DRIVE JR C,FUNBG ;ERR- RESELECT LD A,TRK0 ;SET TRACK # LD (TRKNO),A CALL FMTSD ;FORMAT TRACK SDENS CALL NC,WRTID ;WHILE WE'RE HERE, WRITE ID SECTOR JR C,FUN1 ;ERR CALL TRKDONE ;OUTPUT '*' LD A,TRK1 ;SET NEXT TRACK # LD (TRKNO),A REPT1: CALL FMTDD ;FORMAT TRACK IN DDENS JR C,FUN1 ;ERR CALL TRKDONE LD A,(TRKNO) ;IF LAST TRACK THEN DONE CP TRK76 JR Z,DOCHK1 INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT1 DOCHK1: CALL CHECK ;CHECK FOR READ ERRORS JP FUN1 ;READY FOR ANOTHER DISK ;-------------------------------------------------- ; ; FUNCTION 2 - FORMAT IN JADE SINGLE DENSITY ; TRK 0= SINGLE DENSITY ; TRK 1= DOUBLE DENSITY ; TRK 2..76= SINGLE DENSITY ; ;-------------------------------------------------- FUN2: LD IX,IDSSD ;SELECT DRIVE LD A,(IX+DDFLG) LD (FFLAG),A LD HL,SDSDIR CALL SELDR JP C,FUNBG ;ERR LD A,TRK0 ;SET UP FOR TRACK 0 LD (TRKNO),A CALL FMTSD ;FORMAT IN SDENS CALL NC,WRTID ;WHILE WE'RE HERE, WRITE ID SECTOR JR C,FUN2 ;ERR CALL TRKDONE LD A,TRK1 ;SET UP FOR TRACK 1 LD (TRKNO),A CALL FMTDD ;FORMAT IN DDENS JR C,FUN2 ;ERR CALL TRKDONE LD A,TRK2 ;SET UP FOR TRACK 2 LD (TRKNO),A REPT2: CALL FMTSD ;FORMAT TRACK IN SDENS JR C,FUN2 ;ERR CALL TRKDONE LD A,(TRKNO) CP TRK76 JR Z,DOCHK2 INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT2 DOCHK2: CALL CHECK ;CHECK FOR READ ERRORS JR FUN2 ;READY FOR ANOTHER DISK ;-------------------------------------- ; ; FUNCTION 3 - FORMAT IBM 3740 ; TRK 0..76= SINGLE DENSITY ; ;-------------------------------------- FUN3: LD A,0 ;SET 3740 FLAGS LD (FFLAG),A CALL SELDR ;SELECT DRIVE JP C,FUNBG ;ERR LD A,TRK0 ;SET UP FOR TRACK 0 LD (TRKNO),A REPT3: CALL FMTSD ;FORMAT IN SDEN JR C,FUN3 ;ERR CALL TRKDONE ;OUTPUT '*' LD A,(TRKNO) ;IF TRACK 76 THEN DONE CP TRK76 JR Z,FUN3CK INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT3 FUN3CK: CALL CHECK ;READ EACH SECTOR JR FUN3 ;---------------------------------------------------------- ; ; FUNCTION 4 - DOUBLE DENSITY FORMAT ; TRK 0= SINGLE DENSITY ; TRK 1..76= DOUBLE DENSITY 256 BYTE SECTORS ; ;---------------------------------------------------------- FUN4: LD IX,IDSDD2 LD A,(IX+DDFLG) ;SET FORMAT FLAGS LD (FFLAG),A LD HL,DDSDIR CALL SELDR JP C,FUNBG ;ERR- RESELECT LD A,TRK0 ;SET TRACK # LD (TRKNO),A CALL FMTSD ;FORMAT TRACK SDENS CALL NC,WRTID ;WHILE WE'RE HERE, WRITE ID SECTOR JR C,FUN4 ;ERR CALL TRKDONE ;OUTPUT '*' LD A,TRK1 ;SET NEXT TRACK # LD (TRKNO),A REPT4: CALL FMTDD2 ;FORMAT TRACK IN DDENS JR C,FUN4 ;ERR CALL TRKDONE LD A,(TRKNO) ;IF LAST TRACK THEN DONE CP TRK76 JR Z,DOCHK4 INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT4 DOCHK4: CALL CHECK ;CHECK FOR READ ERRORS JR FUN4 ;READY FOR ANOTHER DISK SUBTTL SUBROUTINES ;**************************************************** ; ; MESSAGE OUTPUT SUBR ; ENTRY- DE= PTR TO '$' TERMINATED TEXT ; EXIT - ? ; ;**************************************************** MSGOT: LD C,9 ;PRINT STRING FUNCTION JP BDOS ;*********************************** ; ; CONSOLE INPUT SUBR ; EXIT - A= CHAR AND 7FH ; ;*********************************** CNSIN: LD C,1 ;CONSOLE READ FUNCTION # CALL BDOS AND 7FH CP CTRLC ;IF CTRL-C THEN REBOOT JP Z,REBOOT CP 'a' ;IF LOWER CASE THEN CONVERT TO UPPER CASE RET C CP 'z' + 1 RET NC AND 5FH RET ;******************************* ; ; OUTPUT '*' SUBR ; ;******************************* TRKDONE: LD E,'*' ;******************************* ; ; CONSOLE OUTPUT SUBR ; ENTRY- E= CHAR ; ;******************************* CNSOT: LD C,2 ;CONSOLE OUTPUT FUNCTION # JP BDOS ;*********************************************** ; ; WRITE ID SECTOR ; ENTRY- IX= PTR TO ID SECTOR IMAGE ; EXIT - CF= ERROR ; ;*********************************************** WRTID: PUSH IX ;HL -> BC POP BC CALL SETDMA ;SET XFER ADDR LD C,TRK0 ;SET TRACK 0 CALL SETTRK LD C,IDSEC ;SET ID SECTOR CALL SETSEC CALL WRSECT ;WRITE ID SECTOR OR A ;IF NO ERRORS THEN RETURN RET Z LD DE,MSGNC ;ELSE OUTPUT ERROR & RETURN CALL MSGOT SCF RET ;**************************************** ; ; FORMAT SINGLE DENSITY TRACK SUBR ; EXIT - CF: ERROR ; ;**************************************** FMTSD: LD HL,FT3740 ;SET INJECTION ADDR JR STDMA ;**************************************** ; ; FORMAT DOUBLE DENSITY TRACK SUBR ; EXIT - CF: ERROR ; ;**************************************** FMTDD: LD HL,FTJ48D ;SET INJECTION ADDR JR STDMA ;**************************************** ; ; FORMAT 256 BYTE DOUBLE DENSITY TRACK ; ;**************************************** FMTDD2: LD HL,FTJ26D ;USE 256 BYTE INJECTION MODULE STDMA: LD (BTDMA),HL ;SET PTR TO INJECTION MODULE LD A,(TRKNO) ;SET TRACK # SO BIOS IN SYNC WITH FORMAT LD C,A CALL SETTRK CALL FMTTRK ;FORMAT TRACK OR A ;IF NO ERR THEN RETURN RET Z LD DE,MSGNC ;ELSE OUTPUT ERROR MSG CALL MSGOT SCF ;RETURN ERROR FLAG RET ;************************************************ ; ; SELECT DRIVE SUBR ; ENTRY- HL= DEFAULT DIR VALUES PTR ; IX= DPB PTR ; EXIT - CF= ERROR ; ;************************************************ SELDR: LD A,(FFLAG) ;IF FORMAT FLAG NOT 0 THEN OR A JR Z,REPTD LD A,(HL) ;SET DPB TO DEFAULTS LD (IX+AL0),A INC HL LD A,(HL) LD (IX+DRM),A INC HL LD A,(HL) LD (IX+CKS),A REPTD: LD DE,MSGFD ;PRINT MESSAGE CALL MSGOT CALL CNSIN ;GET DRIVE INPUT CP CR ;IF RETURN THEN EXIT JR Z,EXITD LD (DRLTR),A ;ELSE SAVE DRIVE LETTER & TEST FOR LEGAL LD (LTRSE),A SUB 'A' LD HL,DRVLO CP (HL) JR C,ILLG LD HL,DRVHI CP (HL) JR C,NMBRD ;IF LEGAL THEN CONTINUE ILLG: LD DE,MSGSE ;PRINT SELECT ERROR MESSAGE CALL MSGOT JR REPTD EXITD: SCF ;SET FLAG TO CALLING RTN RET ; ; DRIVE SELECTED ; NMBRD: LD C,A ;SELECT DRIVE LD HL,DRVLO ;BIAS IT DOWN SUB (HL) LD (BTDRV),A LD E,LOGVC ;LOG ON VECTOR = NO LOG CALL BSELDK LD A,L ;IF SELECT ERROR THEN NO DRIVE OR H JR NZ,LOGOK LD DE,NODRVM CALL MSGOT SCF RET LOGOK: LD DE,MSGXX ;PRINT TYPE CR WHEN READY MSG CALL MSGOT CALL CNSIN ;IF NOT CR THEN REPEAT CP CR JR NZ,REPTD ; NOW ASK FOR DOUBLE DIRECTORY SIZE LD A,(FFLAG) ;IF SINGLE DENSITY 3740 THEN NO DPB OR A JR Z,IDOK LD DE,DIRQM CALL MSGOT CALL CNSIN CP 'Y' ;IF YES THEN CHANGE JR NZ,IDOK SCF ;DOUBLE DIRECTORY SPACE RL (IX+DRM) SLA (IX+CKS) ;DOUBLE CHECKSUMS LD A,(IX+AL0) ;SET UP TO DOUBLE ALLOCATION SIZE ADDBLK: SLA A JR NC,IDOK SRA (IX+AL0) ;ADD ANOTHER BLOCK JR ADDBLK IDOK: LD DE,FMTHDR ;OUTPUT HEADER OF TRACKS CALL MSGOT AND A ;ELSE CLEAR ERR FLAG & RETURN RET ;*************************************************************************** ; ; CHECK FUNCTION CHECKS ALL TRACKS BY READING BACKWARD FROM 76 ; ;*************************************************************************** CHECK: LD A,(DRLTR) ;DO LOG-ON SO CONTROLLER INFORMED SUB 'A' LD C,A LD E,LOGVC CALL BSELDK LD BC,SECBUF ;USE DUMMY SECTOR BUFFER CALL SETDMA LD A,76 ;START WITH LAST TRACK LD (TRKNO),A ; ; ALL SET TO DO TRACK ; VLP: LD C,A ;SEEK TRACK CALL SETTRK XOR A ;ASSUME NO ERRORS LD (RDERR),A LD E,BS ;START AT LAST '*' CALL CNSOT LD E,'V' ;OUTPUT VERIFY PROMPT CALL COUT LD A,-1 ;ASSUME TRANSLATE LD (TXFLG),A LD A,(FFLAG) ;COMPUTE NUMBER OF SECTORS IN TRACK OR A ;IF SINGLE DENSITY THEN DO 26 SECTORS JR Z,DO26 LD A,(TRKNO) ;ELSE IF FLAG BIT == 0 THEN DO 26 SECTORS CP 1 JR Z,VTRK1 JR C,VTRK0 BIT 2,(IX+DDFLG) JR Z,DO26 DOSECTS: XOR A ;NO XLATE LD (TXFLG),A LD A,(IX+SPT) ;USE DPB SECTORS JR SETNSEC VTRK1: BIT 1,(IX+DDFLG) JR Z,DO26 JR DOSECTS VTRK0: BIT 0,(IX+DDFLG) JR NZ,DOSECTS DO26: LD A,26 SETNSEC: INC A ;OFFSET FOR TEST LD (NSECTS),A LD A,1 ;START WITH 1ST SECTOR ; ; ALL SET TO DO SECTOR ; RDLP: LD (SECTOR),A ;SAVE CURRENT SECTOR LD HL,NSECTS CP (HL) JR Z,TDONE LD C,A CALL SECTRN CALL SETSEC CALL RDSEC OR A JR Z,VRDCNT LD (RDERR),A VRDCNT: LD A,(SECTOR) INC A JP RDLP ; ; TRACK IS DONE, CHECK IF ANY ERRORS ; TDONE: LD A,(RDERR) OR A JR NZ,VERR LD E,'-' JR OUTV VERR: LD E,'?' ;OUTPUT '?' OUTV: CALL COUT LD A,(TRKNO) ;NEXT TRACK DEC A LD (TRKNO),A RET M ;IF TRACK < 0 THEN DONE JP VLP ;************************************** ; ; SECTOR TRANSLATION SUBR ; ENTRY- C= SECTOR ; EXIT - C= SECTOR ; ;************************************** SECTRN: LD A,(TXFLG) ;IF NOT SINGLE DENSITY THEN RETURN OR A RET Z LD B,0 DEC C LD HL,TRNTBL ADD HL,BC LD C,(HL) RET ;********************************************************** ; ; CHAR OUT WITH CURSOR AT SAME POSITION SUBR ; ENTRY- E= CHAR TO OUTPUT ; ;********************************************************** COUT: CALL CNSOT LD E,BS JP CNSOT ;******************************* ; ; SET TRACK FUNCTION ; ENTRY- BC= TRACK # ; ;******************************* SETTRK: LD A,SETRKV BIOS: PUSH DE ;SAVE POSSIBLE LOGON VECTOR LD HL,(WBOOT +1) ;GET BIOS PTR LD E,A ;ADD IN OFFSET LD D,0 ADD HL,DE ADD HL,DE ADD HL,DE POP DE JP (HL) ;EXECUTE ;******************************** ; ; SET SECTOR FUNCTION ; ENTRY- BC= SECTOR # ; ;******************************** SETSEC: LD A,SETSECV JP BIOS ;********************************** ; ; SET DMA FUNCTION ; ENTRY- BC= MEMORY ADDR ; ;********************************** SETDMA: LD A,SETMAV JP BIOS ;********************************** ; ; WRITE SECTOR FUNCTION ; ;********************************** WRSECT: LD A,WRSECV JP BIOS ;********************************** ; ; READ SECTOR FUNCTION ; ;********************************** RDSEC: LD A,RDSECV JP BIOS ;********************************** ; ; FORMAT TRACK FUNCTION ; ;********************************** FMTTRK: LD A,DDMRQ ;SWITCH DD INTO SYSTEM OUT (DDPORT),A LD A,DDMB1 ;SELECT BANK 1 OUT (DDPORT),A LD BC,FMTSZ ;MOVE FORMAT CODE INTO FDC LD HL,(DADDR) LD DE,DDFBF ADD HL,DE EX DE,HL LD HL,(BTDMA) LDIR LD A,DDMRQ ;SELECT BANK 0 OUT (DDPORT),A LD BC,7 ;MOVE COMMAND BLOCK INTO FDC LD DE,DDCMD LD HL,(DADDR) ADD HL,DE EX DE,HL LD HL,BTCMD LDIR LD A,DDEXC ;EXECUTE COMMAND BLOCK OUT (DDPORT),A EX DE,HL ;SET UP TO MOVE DOWN STATUS BYTES LD BC,5 DSKWT: IN A,(DDPORT) ;WAIT UNTIL DONE AND DDSHLT JR NZ,DSKWT LD A,DDMRQ ;SWITCH DD INTO SYSTEM OUT (DDPORT),A LDIR ;FETCH STATUS BYTES LD A,DDOUT ;REMOVE FDC FROM MEMORY MAP OUT (DDPORT),A LD A,(BTSTS) ;RETURN STATUS OR A RET ;********************************************* ; ; SELECT DISK THROUGH BIOS FUNCTION ; ENTRY- E= DISK # ; ;********************************************* BSELDK: LD A,SLDSKV ;SELECT DISK FUNCTION # JP BIOS SUBTTL CONSTANT DECLARATIONS ;-------------------------------------- ; ; DEFAULT DIRECTORY SIZE VALUES ; ;-------------------------------------- DDSDIR: DB 80H,63,16 ;DOUBLE DENSITY SDSDIR: DB 0C0H,63,16 ;SINGLE DENSITY ;------------------------------------------------ ; ; SINGLE DENSITY TRANSLATION TABLE ; ;------------------------------------------------ TRNTBL: GXLATE 26,6 ;******************************************* ; ; JADE SINGLE DENSITY IDENTITY SECTOR ; TRACK 0= SD, 26 128 BYTE SECTORS ; TRACK 1= DD, 48 128 BYTE SECTORS EACH ; TRACK 2..76= SD ; ;******************************************* IDSSD: DB 'Jade DD Single density format ' ;CONFIRMATION TEXT ; ; DISK PARAMETER BLOCK IMAGE, TO BE TRANSFERRED TO BIOS AT LOGON TIME ; REPT IDSSD + 20H -$ ;POSITION DPB IN SECTOR LIST OFF DB 0E5H ;FILL WITH E5 LIST ON ENDM SPT EQU $ - IDSSD DW 26 ;SECTORS PER TRACK DB 3 ;BLOCK SHIFT FACTOR DB 7 ;BLOCK MASK DB 0 ;NULL MASK DW 242 ;DISK SIZE -1 DRM EQU $ - IDSSD ;OFFSET TO DRM BYTE DW 63 ;DIRECTORY MAXIMUM AL0 EQU $ - IDSSD ;OFFSET TO DIRECTORY ALLOCATION BYTE DB 11000000B ;ALLOC 0 DB 0 ;ALLOC 1 CKS EQU $ - IDSSD ;OFFSET TO CHECKSUMS BYTE DW 16 ;CHECK SIZE DW 2 ;TRACK OFFSET ; ; DISK CONTROLLER MODULE DISK PARAMETERS TO BE TRANSFERRED TO DCM AT ; LOGON TIME ; REPT IDSSD + 30H -$ ;LOCATE DCM BLK LIST OFF DB 0E5H LIST ON ENDM DB 6 ;SECTOR STAGGER (TRNS) DDFLG EQU $ - IDSSD DB 00000010B ;DISKETTE FLAGS REPT IDSSD+SECSZ-$ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;********************************************* ; ; JADE DOUBLE DENSITY IDENTITY SECTOR ; TRACK 0= SD, 26 128 BYTE SECTORS ; TRACKS 1..76= DD, 48 128 BYTE SECTORS EACH ; ;********************************************* IDSDD: DB 'Jade DD Double density format ' ;CONFIRMATION TEXT REPT IDSDD + 20H -$ LIST OFF DB 0E5H LIST ON ENDM DW 48 ;SECTORS PER TRK DB 4 ;BLOCK SHIFT FACTOR DB 00001111B ;BLOCK MASK DB 1 ;NULL MASK DW 224 ;DISK SIZE -1 DW 63 ;DIRECTORY MAXIMUM DB 10000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16 ;CHECK SIZE DW 2 ;TRACK OFFSET REPT IDSDD + 30H -$ ;LOCATE DCM BLOCK LIST OFF DB 0E5H LIST ON ENDM DB 6 ;SECTOR STAGGER (TRNS) DB 00000110B ;DISKETTE FLAGS ; REPT IDSDD + SECSZ -$ ;EXTEND TO FULL SECTOR LIST OFF DB 0E5H LIST ON ENDM ;********************************************* ; ; JADE DOUBLE DENSITY IDENTITY SECTOR ; TRACK 0= SD, 26 128 BYTE SECTORS ; TRACK 1..76= DD, 26 256 BYTE SECTORS EACH ; ;********************************************* IDSDD2: DB 'Jade DD Double density format ' ;CONFIRMATION TEXT REPT IDSDD2 + 20H -$ LIST OFF DB 0E5H LIST ON ENDM ; ; IN THIS CASE, CP/M IS FOOLED BY THE DEBLOCKING INTO THINKING ; THERE ARE 52 128 BYTE SECTORS PER TRACK ; DW 52 ;SECTORS PER TRK DB 4 ;BLOCK SHIFT FACTOR DB 00001111B ;BLOCK MASK DB 1 ;NULL MASK DW 242 ;DISK SIZE -1 DW 63 ;DIRECTORY MAXIMUM DB 10000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16 ;CHECK SIZE DW 2 ;TRACK OFFSET REPT IDSDD2 + 30H -$ ;LOCATE DCM BLOCK LIST OFF DB 0E5H LIST ON ENDM DB 6 ;SECTOR STAGGER (TRNS) DB 01000110B ;T0= SD, T1..76= 256 BYTE DD ; REPT IDSDD2 + SECSZ -$ ;EXTEND TO FULL SECTOR LIST OFF DB 0E5H LIST ON ENDM ;****************** ; ; MESSAGES ; ;****************** MSGFL: DB CR,LF,LF,'****** Functions List ******' DB CR,LF,'1. Jade 128 Byte Sector Double Density -n 8"' DB CR,LF,'2. Jade Single Density 8"' DB CR,LF,'3. Standard 3740 8"' DB CR,LF,'4. Jade 256 Byte Sector Double Density 8"' DB CR,LF,'USE CTRL-C TO RE-BOOT.' DB CR,LF,LF,'Enter function number: $' MSGSE: DB CR,LF,LF LTRSE: DB ' Is not a valid selection.$' MSGFD: DB CR,LF,LF,'Write format on drive (CR to reselect): $' MSGNC: DB CR,LF,LF,'Transfer incomplete$' MSGXX: DB CR,LF,LF,'TYPE CR WHEN DRIVE ' DRLTR: DB ' IS READY. $' NODRVM: DB CR,LF,'BIOS Select Error!$' DIRQM: DB CR,LF,'Double Directory Size? (Y/N) - $' FMTHDR DB CR,LF,'0---------1---------2---------3---------4---------5' DB '---------6---------7------',CR,LF,'$' SUBTTL INJECTION MODULES ;************************************************* ; ; SINGLE DENSITY FORMATTER INJECTION MODULE ; THIS CODE IS INTENDED TO EXECUTE WITHIN THE ; DOUBLE D MEMORY BANK 1. ALL ABSOLUTE MEMORY REFERENCES MUST BE OFFSET. ; THE OFFSET IS CALCULATED BY: ; ADDR = SYMBOL - START_OF_MODULE + DD_MODULE_LOCATION ; ;************************************************* FT3740: EQU $ SDOFF: EQU $ - FMTBG ;DETERMINE ADDR OF OFFSET DB 'FORMAT!S' ;CONFIRMATION TEXT ; ; START OF CODE, SHOULD BE FMTBG + 8 ; LD HL,SS3740 - SDOFF LD E,26 ;SET # SECTORS BG3740: LD B,40 ;# BYTES SRPT1: IN A,XPDSH ;WAIT FOR DATA REQ LD A,ONES XOR C OUT WDDTA,A ;WRITE DATA DJNZ SRPT1 LD B,6 ;WRITE 6 0s SRPT2: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT2 IN A,XPDSH ;WRITE INDEX MARK LD A,0FCH XOR C OUT WDDTA,A LD B,26 ;WRITE 26 ONES BYTES SRPT3: IN A,XPDSH LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT3 RP3740: LD B,6 ;WRITE 6 ZEROS BYTES SRPT4: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT4 IN A,XPDSH ;WRITE ID MARK LD A,0FEH XOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # LD A,0 XOR C OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZE LD A,0 ;(128) XOR C OUT WDDTA,A IN A,XPDSH ;WRITE CRC LD A,0F7H XOR C OUT WDDTA,A LD B,11 ;WRITE 11 ONES SRPT5: IN A,XPDSH LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT5 LD B,6 ;WRITE 6 ZEROS BYTES SRPT6: IN A,XPDSH LD A,ZEROS XOR C OUT WDDTA,A DJNZ SRPT6 IN A,XPDSH ;WRITE DATA MARK LD A,0FBH XOR C OUT WDDTA,A LD B,SECSZ ;WRITE SECTOR WITH E5 BYTES SRPT7: IN A,XPDSH LD A,0E5H XOR C OUT WDDTA,A DJNZ SRPT7 IN A,XPDSH ;WRITE CRC LD A,0F7H XOR C OUT WDDTA,A LD B,27 ;WRITE 27 ONES BYTES SRPT8: IN A,XPDSH LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT8 DEC E ;# SECTORS -1 JP NZ,RP3740 - SDOFF ;IF ANY LEFT THEN REPEAT LD HL,0 ;COUNT = 0 SRPT9: IN A,XPDSH LD A,ONES ;WRITE ONES UNTIL INTERRUPT XOR C OUT WDDTA,A INC HL ;RETURN ONES COUNT JP SRPT9 - SDOFF ; ; SECTOR TRANSLATION TABLE, NONE FOR SINGLE DENSITY ; SS3740: GXLATE 26, 1 ;*********************************************** ; ; DOUBLE D DOUBLE DENSITY INJECTION MODULE ; ;*********************************************** FTJ48D: EQU $ DDOFF: EQU $ - FMTBG ;DETERMINE ADDR OFFSET DB 'FORMAT!D' ;CONFIRMATION TEXT ; ; EXECUTION START POINT ; LD HL,SSJ48D - DDOFF ;SET PTR TO SECTOR TRANSLATION TABLE LD E,48 ;SECTOR COUNT BGJ48D: LD B,80 ;WRITE PREAMBLE - 80 4E BYTES DRPT1: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT1 LD B,12 ;WRITE 12 ZERO BYTES DRPT10: IN A,XPDSH XOR A,A XOR C OUT WDDTA,A DJNZ DRPT10 LD B,3 ;WRITE GAP C2 - 3 F6 BYTES DRPT11: IN A,XPDSH LD A,0F6H XOR C OUT WDDTA,A DJNZ DRPT11 IN A,XPDSH ;WRITE INDEX MARK LD A,0FCH XOR C OUT WDDTA,A LD B,32 ;WRITE GAP 1 - 32 4E BYTES DRPT12: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT12 RPJ48D: LD B,8 ;WRITE END OF GAP 3 - 8 ZERO BYTES DRPT2: IN A,XPDSH XOR A,A XOR C OUT WDDTA,A DJNZ DRPT2 LD B,3 ;WRITE GAP A1 - 3 F5 BYTES DRPT3: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJNZ DRPT3 IN A,XPDSH ;WRITE ID MARK LD A,0FEH XOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # XOR A,A XOR C OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZE LD A,0 ;128=0 XOR C OUT WDDTA,A IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,22 ;WRITE GAP 2 - 22 4E BYTES DRPT4: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT4 LD B,8 ;WRITE 8 ZERO BYTES DRPT5: IN A,XPDSH XOR A,A XOR C OUT WDDTA,A DJNZ DRPT5 LD B,3 ;WRITE GAP A1 - 3 F5 BYTES DRPT6: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJNZ DRPT6 IN A,XPDSH ;WRITE DATA MARK LD A,0FBH XOR C OUT WDDTA,A LD B,SECSZ ;WRITE SECTOR DATA WITH E5 BYTES DRPT7: IN A,XPDSH LD A,0E5H XOR C OUT WDDTA,A DJNZ DRPT7 IN A,XPDSH ;WRITE CRC LD A,0F7H XOR C OUT WDDTA,A LD B,24 ;WRITE GAP 3 - 24 4E BYTES DRPT8: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT8 DEC E ;IF SECTORS LEFT THEN REPEAT JP NZ,RPJ48D - DDOFF LD L,E LD H,L DRPT9: IN A,XPDSH LD A,4EH ;WRITE GAP 4 - 4EH BYTES UNTIL INTERRUPT XOR C OUT WDDTA,A INC HL ;COUNT NUMBER OF GAP 4 BYTES JR DRPT9 ; ; DOUBLE DENSITY SKEW TABLE, SKEW 8 SEEMS OPTIMUM ; SSJ48D: GXLATE 48, 8 ;*********************************************** ; ; DOUBLE D DOUBLE DENSITY INJECTION MODULE ; 256 BYTE SECTORS ; ;*********************************************** FTJ26D: EQU $ DD26OFF: EQU $ - FMTBG ;DETERMINE ADDR OFFSET DB 'FORMAT!D' ;CONFIRMATION TEXT ; ; EXECUTION START POINT ; LD HL,SSJ26D - DD26OFF ;SET PTR TO SECTOR TRANSLATION TABLE LD E,26 ;SECTOR COUNT BGJ26D: LD B,80 ;WRITE PREAMBLE - 80 4E BYTES DD261: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DD261 LD B,12 ;WRITE 12 ZERO BYTES DD2610: IN A,XPDSH XOR A,A XOR C OUT WDDTA,A DJNZ DD2610 LD B,3 ;WRITE GAP C2 - 3 F6 BYTES DD2611: IN A,XPDSH LD A,0F6H XOR C OUT WDDTA,A DJNZ DD2611 IN A,XPDSH ;WRITE INDEX MARK LD A,0FCH XOR C OUT WDDTA,A LD B,50 ;WRITE GAP 1 - 50 4E BYTES DD2612: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DD2612 RPJ26D: LD B,12 ;WRITE END OF GAP 3 - 12 ZERO BYTES DD262: IN A,XPDSH XOR A,A XOR C OUT WDDTA,A DJNZ DD262 LD B,3 ;WRITE GAP A1 - 3 F5 BYTES DD263: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJNZ DD263 IN A,XPDSH ;WRITE ID MARK LD A,0FEH XOR C OUT WDDTA,A IN A,XPDSH ;WRITE TRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # XOR A,A XOR C OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZE LD A,1 ;1= 256 XOR C OUT WDDTA,A IN A,XPDSH ;WRITE CRC WORD LD A,0F7H XOR C OUT WDDTA,A LD B,22 ;WRITE GAP 2 - 22 4E BYTES DD264: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DD264 LD B,12 ;WRITE 12 ZERO BYTES DD265: IN A,XPDSH XOR A,A XOR C OUT WDDTA,A DJNZ DD265 LD B,3 ;WRITE GAP A1 - 3 F5 BYTES DD266: IN A,XPDSH LD A,0F5H XOR C OUT WDDTA,A DJNZ DD266 IN A,XPDSH ;WRITE DATA MARK LD A,0FBH XOR C OUT WDDTA,A LD B,0 ;WRITE SECTOR DATA - 256 E5 BYTES DD267: IN A,XPDSH LD A,0E5H XOR C OUT WDDTA,A DJNZ DD267 IN A,XPDSH ;WRITE CRC LD A,0F7H XOR C OUT WDDTA,A LD B,54 ;WRITE GAP 3 - 54 4E BYTES DD268: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DD268 DEC E ;IF SECTORS LEFT THEN REPEAT JP NZ,RPJ26D - DD26OFF LD L,E LD H,L DD269: IN A,XPDSH LD A,4EH ;WRITE GAP 4 - 4EH BYTES UNTIL INTERRUPT XOR C OUT WDDTA,A INC HL ;COUNT NUMBER OF GAP 4 BYTES JR DD269 ; ; DOUBLE DENSITY SKEW TABLE, SKEW 9 SEEMS OPTIMUM ; SSJ26D: GXLATE 26, 9 SUBTTL VARIABLE DECLARATIONS ; ; FDC COMMAND BLOCK ; BTCMD DB DDFMT ;FORMAT COMMAND BTDRV DS 1 ;DRIVE # TRKNO: DS 1 ;TRACK NUMBER HOLD FFLAG: DS 1 ;FORMAT FLAG (DCM) DW 0 ;SPARES DB 0 ;MODE CONTROLS BTSTS DS 1 ;STATUS BYTE DS 4 ;LOAD WORDS BTDMA DS 2 ;ADDRESS OF INJECTION MODULE NSECTS DS 1 ;NUMBER OF SECTORS IN TRACK TXFLG DS 1 ;TRANSLATE SECTOR BOOLEAN FLAG RDERR DS 1 ;READ ERROR BOOLEAN FLAG SECTOR DS 1 ;CURRENT SECTOR SECBUF DS 256 ;SECTOR BUFFER CODEND EQU $ END