IMD 1.18: 19/12/2012 10:00:56  Disk Descriptor30à?€00M4åååååååååååå0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå0 ( ) *!+",#-$.%/ &0 'DCM8104 Z80c FMT8100 Z80€ !BLT104 Z80FMT8100 Z80"algorithms for 256 byte sectors. Remove unused ; code & vars. Optimize code. ; ; 1.4 - 30 OCT 85 GRH ; Revise objects for åE. ; THE 1ST JUMP IS EXECUTED WHEN THE ONBOARD Z80 IS RESET. ; THE SECOND JUMP IS THE DCM ENTRY FROM A BOOTSTRAP LOADER. ; in single & double density). ; This module sets the parameters for each drive during the "LOG-ON" ; operation. The FORMAT progJDDD102 DEF#$JDDL105 DEFR%&'()*JDDD100 DEF+,JDDC104 DEF2-./0improved include file. Add hooks for double sided ; drives. Change logon to return boolean reflecting a valid descriptor ; såTHIS ENTRY ASSUMES DCM HAS BEEN LOADED INTO DD BANK 1 BY THE ; LOADER ROUTINE. ; ;------------------------------------------ram (not in this module) writes an ident- ; ification sector (T0,S1) which provides the needed information. If this ; identityJDDL103 DEF;1234JDDL104 DEFQ56789:JDD100 C s;<=>?@ABJDDD100ADEFCDector. ; VERSN EQU '14' ; ;************************************************************* SUBTTL FIRMWARE DEFINITIONS FAå-------------------------- ORG 0 JP CLEAR ;RESET & RE-INITIALIZE Z-80 REGS JP INITB + BANKL ;INIT - BOOTSTRAPPED  sector is not present on the diskette, it is assumed to be a ; standard 8" IBM 3740 format. This program contains a 6 word timJDDC104ADEF2EFGHJDDD100BDEFIJJDDL103ADEF 66H ?OVRLAP NMI VECTOR,$-L INIT JR SLEEP ;-------------------------------------- ; ; ENTRY VECTOR TO READ SECTOR ; USES RST 40 VECTOR ; ;----D H,0 ; ; EXECUTE COMMAND. ALL COMMANDS RETURN TO INTERRUPTED WAIT LOOP ; JP (HL) ;GOTO COMMAND ; ; COMMAND TABLE ;OR ENABLES INTERRUPTS & HALTS. DURING THIS TIME, ; THE HOST SYSTEM CAN ACCESS THE CONTROLLER MEMORY AND GET THE COMMAND ; STAT; RETERR: OR A,A ;IF NO ERROR THEN QUIT NOW RET Z ; LD (CMDBLK + DDSTSO),A LD A,FDCERR RETFER: LD (CMDBLK + DDMODO),A 66H ENDIF ORG 66H ;POSITION CODE FOR NMI VECTOR LOCATION ; ; GET FDC STATUS & PUT INTO COMMAND BLOCK FOR HOST INTERPRET---------------------------------- ORG 40 ;POSITION CODE FOR RESTART 40D VECTOR JP RDSEC ;**************************** CMDT: DB LGON ;LOG-ON DRIVE DB READ ;READ SECTOR DB WRITV ;WRITE SECTOR DB FORM ;FORMAT TRACK DB ADDR ;READ ADDREUS AND SECTOR DATA. ; ;-------------------------------------------------------------------- SLEEP: EI ;SET ALARM HALT ;GO RET ;-------------------------------------------------------------------- ; ; DRIVE LOG-ON COMMAND READS THE IDENTITYATION ; IN A,(WDSTS) ;CLEARS INTERRUPT TOO XOR C LD (CMDBLK + DDSTSO),A ; ; PUT RETURN ADDRESS ON STACK & RETURN TO I********** ; ; TEMPORARY INIT USED ONLY ONCE ; ;************************************** IF $ > (56 - 8) ?OVRLAP RST 56,$-SS DB SPAR ;SPARES DB SPAR DB IDLE ;BACKGROUND NCMDS EQU $ - CMDT ;COMMAND COUNT WRITV: JP WRIT ;---------------- TO SLEEP ;-------------------------------------- ; ; IDLE COMMAND (NOT IMPLEMENTED) ; ;----------------------------- SECTOR FROM THE ; DISKETTE AND MAKES THE NEEDED ENTRYS INTO THE DRIVE TABLE. ; THE SECTOR DATA IS ALSO LEFT IN THE SECTOR BT. ; EX (SP),IY RETN ;******************************************************************** ; ; COMMAND SELECTOR SU56-8 ENDIF DS (56 - 8) - $ ;POSITION CODE RST38A: CALL INIT ; ; MODIFY CALL VECTOR TO NOT CALL THIS CODE ANY MORE ; ------------ ; ; FORMAT TRACK COMMAND ; ;---------------------------- FORM: ; ; SELECT DRIVE 1ST ; CALL SELECT R--------- IDLE: ; IN A,(BLSTS) ;IF NO HOST INTERRUPT THEN WAIT ; AND BSINT ; JR Z,IDLE ; ; IN A,(XPIRR) ;ELSE RESET INTERRUFFER FOR BIOS ; TO FINISH THE LOG-ON OPERATION. ; ;-------------------------------------------------------------------- LGBR GETS CONTROL AFTER THE DISK CONTROLLER IS ; INTERRUPTED FROM THE HALT CONDITION. IT BRANCHES TO THE INDIVIDUAL ; COMMAND R LD A,XCUTE ;MODIFY CALL VECTOR LD (HRVEC + 1),A ;-------------------------------------------------------------------- ;ET NZ ;IF ERROR THEN RETURN ; ; SET DISK FLAGS TO DATA IN SECTOR BYTE OF COMMAND BLOCK ; LD A,(CMDBLK + DDSECO) ;GET FORUPT REQUEST & EXIT ; RET ;------------------------------------------- ; ; READ ADDRESS COMMAND (NOT IMPLEMENTED) ; ;-ON: ; ; SELECT DRIVE 1ST ; CALL SELECT RET NZ ;IF DRIVE ERROR THEN RETURN ; ; SET UP TO READ DESCRIPTOR SECTOR ; OUTINES. ; ;******************************************************************** XCUTE: ; ; ASSUME NO ERROR ; XOR A,A  ; MASKABLE HOST INTERRUPT ROUTINE - EXECUTED WHEN RESTARTING THE ; LOCAL PROCESSOR FROM A HALT IN ORDER TO PROCESS A COMMANMAT FLAGS LD (IX + DVFLG),A ;RESET DRIVE FLAGS ; ; SEEK TRACK FROM COMMAND BLOCK ; CALL SEEK ; ; SET UP FOR COMMAND------------------------------------------ ADDR: ;------------------ ; ; SPARE COMMAND ; ;------------------ SPAR:  XOR A ;SET TRACK=0 LD (CMDBLK + DDTRKO),A ; INC A ;SET SECTOR =1 LD (CMDBLK + DDSECO),A ; ; SEEK TRACK ; CALL  LD (CMDBLK + DDMODO),A LD (CMDBLK + DDSTSO),A ; ; GET FDC'S ATTENTION FOR COMMANDS ; CALL EXSTS ;GET 179X'S ATTENTIOD. ; ;-------------------------------------------------------------------- ORG 56 ;POSITION CODE FOR RESTART 56 VECTOR ;  COMPLETION ; LD IY,NMIWT ;SET RETURN ADDR ; ; OUTPUT FORMAT TRACK COMMAND TO FDC ; LD A,DCWRT ;OUTPUT WRITE TRACK CO LD HL,CMDBLK + DDMODO ;SET COMMAND ERROR LD (HL),CMDERR RET ;********************************************************SEEK ; ; READ DESCRIPTOR SECTOR INTO BUFFER ; LD HL,XBUF LD E,1 CALL RDSEC ;READ ID SECTOR ; ; CHECK FOR DESCRIPN FOR CMDS ; ; FETCH COMMAND FROM COMMUNICATION BLOCK ; LD A,(CMDBLK + DDCMDO) ;GET HOST CMD ; ; IF ILLEGAL COMMAND T; CLEAR THE HOST INTERRUPT FLOP ; IN A,(XPIRR) ; ; RESTORE THE STACK ; LD SP,STACK ; ; FIRST TIME, CALL THE INITMMAND TO 1791 XOR C OUT (WDCMD),A EX (SP),HL ;WAIT FOR 1791 EX (SP),HL EX (SP),HL EX (SP),HL ; ; EXECUTE CODE I************ ; ; THIS IS THE NON-MASKABLE INTERRUPT ROUTINE USED BY THE FDC ; UPON COMMAND TERMINATION. THE STATUS PORT IS 0 ( ) *!+",#-$.%/ &0 'TOR ID TEXT ; LD DE,JADEID ;SET STRING PTR LD HL,XBUF + IDLBLO ;SET SECTOR BUFFER PTR TO COMPARE LD B,IDSZE ;SET ID LENG RETFER ; ; NOW SELECT REQUESTED DRIVE ; SELCT1: OUT (BLCTL),A OR BCDSE OUT (BLCTL),A LD (SVDRV),A ; ; SELECT  ; DEFAULT READ PTR IS UNBLOCKED ; LD HL,XBUF ;DEFAULT TO UNBLOCKED ; ; FETCH SECTOR DATA ; LD A,(CMDBLK + DDSECO)ORE DIRECTION OUT (BLCTL),A HOME1: ; ; SET MAX TRACKS TO 255 ; LD L,255D ;SET MAX COUNT ; ; IF ON TRACK 0 THEN DO******************************** ; ; THIS SUBROUTINE IS RESPONSIBLE FOR SELECTING THE COMMAND ; REQUESTED DRIVE #. BEFORE TH ; CKJI: LD A,(DE) ;IF ID NOT=JADE THEN 3740 CP (HL) JR NZ,I3740 ; INC HL ;ELSE INC PTRS INC DE DJNZ CKJI ;IF NEW DRIVE TABLE ; AND BCDSN LD IX,DVTBL LD DE,DVDES ;DRIVE TABLE ARRAY SIZE ; NEXT: DEC A ;IF DRIVE = 0 THEN EXIT WITH LD E,A ; ; CHECK FOR DEBLOCKING ; LD A,(IX + DVFLG) ;IF SECTOR SIZE == 128 THEN SKIP BLOCKING AND 11000000B JP Z,RNE ; STEP: CALL EXSTS ;IF ON TRACK 0 THEN EXIT AND DMTK0 JR NZ,EXIT ; ; IF > 255 TRACKS THEN RECAL ERROR ; DEC L DRIVE SELECTION, THE DRIVE MOTOR ; STATE IS TESTED AND IF NEEDED, THEY ARE TURNED ON. ; EXIT - IX= NEW DRIVE TABLE ; A= 0: NOT DONE THEN REPEAT ; ; VALID DESCRIPTOR SECTOR FOUND, FETCH DISK PARAMETERS ; LD A,(XBUF + IDFLGO) ;SET SIDES & DENSITI POINTER SET JP M,SLED ; ADD IX,DE ;ELSE POINT TO NEXT ARRAY & REPEAT JR NEXT ; ; IX NOW HAS DRIVE TABLE PTR ; SLEWSECA ; ; DEBLOCKING REQUIRED ; CALL DOBUFR ;SET UP PHYSICAL SECTOR BUFFER RET NZ ; ; IF READ THEN DOBUFR DID IT A;IF STEPS = 255 THEN ERROR JR Z,EROR ; ; STEP ONCE ; IN A,(XPSTP) ;ISSUE STEP PULSE LD DE,TMSTPC ;SET DELAY RST 8 OK, /0: ERR ; ;******************************************************************** SELECT: ; ; IF MOTOR OFF THEN START MES LD (IX + DVFLG),A ; ; RETURN VALID DESCRIPTOR SECTOR FLAG TO HOST ; LD A,-1 SETFFG: LD (CMDBLK + DDFFGO),A RET D: ; ; FETCH DRIVE READY STATUS FROM FDC ; CALL EXSTS ;SET FLAGS PER DRIVE READY AND DMDNR JP RETERR ;*********LL ; EX AF,AF' ;IF READ THEN ALREADY IN XBUF RET NZ ; ; ELSE WRITE IT OUT ; LD D,A EX AF,AF' LD HL,SBUFR ;USE P JR STEP ; ; DRIVE IS RESTORED, WAIT FOR SETTLING TIME ; EXIT: LD DE,TMALS ;WAIT A BIT AFTER LAST STEP RST 8 ; ; CUROTOR ; IN A,(BLSTS) ;GET BOARD LEVEL STATUS AND BSMOF ;IF MOTOR ON THEN CHECK DRIVE JR Z,CKDV ; IN A,(XPMTX) ;ELSE IS ; ; ASSUME 3740 FORMAT ; I3740: ; ; SET DISK PARAMETERS TO SINGLE SIDED, SINGLE DENSITY ; LD A,IDFLD ;SIDE & DE*********************************************************** ; ; HOMED SUBROUTINE STEPS THE DISK DRIVE HEAD OUTWARD UNTIL ;HYSICAL SECTOR BUFFER LD A,(BSECT) LD E,A JP RWSECT SUBTTL SUBROUTINES ;************************************** ; RENT TRACK = 0 ; LD A,0 ;SET COMPLETE FLAG LD (IX+DVTRK),A ;SET TRACK VALUE ; ; RETURN NO ERROR ; AND A ;SET RETURSUE MOTOR START LD DE,TMMTO ;WAIT FOR A WHILE RST 8 ; ; RETRIGGER MOTOR OFF DELAY ; CKDV: IN A,(XPMTX) ;EXTEND MOTOR TNSITIES FLAGS=0 LD (IX+DVFLG),A ; ; RETURN INVALID DESCRIPTOR SECTOR TO HOST ; XOR A,A JR SETFFG ;-------------- TRACK 0 FLAG IS TRUE OR 255 STEPS HAVE BEEN ISSUED ; EXIT - A= 0: OK, -1: TRK 0 NOT FOUND ; ;*******************************; INITIALIZE REGS & VARS SUBR ; ;************************************** INIT: ; ; SINGLE INTERRUPT MODE ; IM 1 ;SINN FLAGS RET ; ; TRACK 0 NOT FOUND ; EROR: LD A,SEEKERR ;SET FAILURE FLAG JP RETFER ;*****************************IME ; ; ENABLE DRIVE SELECT ; LD A,(SVDRV) OR BCDSE OUT (BLCTL),A ; ; IF REQUESTED DRIVE = CURRENT DRIVE THEN OK -------------- ; ; READ SECTOR COMMAND ; ;---------------------------- READ: LD A,-1 ;FLAG := READ OR A JR OPCONT ************************************* HOMED: ; ; IF NOT ALREADY ON TRACK 0 THEN SKIP RECALIBRATE ; CALL EXSTS ;IF NOT TGLE INTERRUPT MODE TO RST 56 ; ; TEST FOR INVERTED BUS FDC OPTION ; LD C,0 ;DEFAULT TO NON-INVERTED DATA IN A,(BLSTS) ******************* ; ; TRACK SEEK SUBROUTINE ; EXIT - DENSITY & PRE-COMP CONTROLS SET ; ZF= OK, NZ= ERROR ; ;*******AS IS ; LD A,(CMDBLK + DDDRVO) SUB (IX + DVNBR) RET Z ; ; UNLOAD HEAD ON CURRENT DRIVE ; LD E,DCHDU CALL EXHEAD  ;---------------------------- ; ; WRITE SECTOR COMMAND ; ;---------------------------- WRIT: XOR A ;FLAG := WRITE RK 0 THEN NO RECAL AND DMTK0 JR Z,HOME1 ; ; STEP IN 10 TRACKS TO INSURE INSIDE TRACK 0 ; LD L,10 ;ELSE STEP IN BEYON AND BSUS0 JR NZ,STOP ; ; IF INVERTED THEN SET REGISTER TO XOR DATA WITH 0FFH ; DEC C ; ; SET DRIVE TABLE POINTER ***************************************** SEEK: ; ; IF HEAD NOT LOADED THEN LOAD HEAD ; CALL EXSTS ;IF HEAD ALREADY LOA ; ; DESELECT CURRENT DRIVE ; LD A,(SVDRV) ;DESELECT CURRENT DRIVE, AND [NOT BCDSE] OUT (BLCTL),A ; ; IF REQUESTEDOPCONT: ; ; SAVE OPERATION FLAGS ; EX AF,AF' ;SAVE OP IN ALT REGS ; ; SELECT DRIVE 1ST ; CALL SELECT ;SELECT DRID TRK 0 LD A,(SVDRV) ;SELECT 'IN' OR BCDAS OUT (BLCTL),A ; ; STEP ONCE ; RECAL1: IN A,(XPSTP) LD DE,TMSTPC RST 8TO DUMMY ; STOP: LD IX,DTDED ;SET DRIVE TABLE PTR ; ; INITIALIZE DEBLOCKING BUFFER TO INSURE 1ST READ ; XOR A ;BLOCKEDDED THE BYPASS AND DMHDL JR NZ,HLDD ; LD E,DCHDL CALL EXHEAD ; ; WAIT FOR HEAD SETTLING TIME ; LD DE,TMHLD RST DRIVE NOT LEGAL THEN RETURN ERROR ; LD A,(CMDBLK + DDDRVO) ;FETCH REQUESTED DRIVE CP 4 JR C,SELCT1 ; LD A,SELERR JPVE ; ; IF NO ERRORS THEN SEEK TRACK ; CALL Z,SEEK ;SEEK TRACK ; ; IF SELECT OR SEEK ERROR THEN RETURN ; RET NZ ; ; ; IF NOT 10 TRACKS THEN REPEAT ; DEC L JR NZ,RECAL1 ; ; NOW STEP OUT UNTIL TRACK 0 FOUND ; LD A,(SVDRV) ;REST BUFFER := EMPTY LD (BSECT),A LD (SVDRV),A ;BASE BLCTL BITS ; ; DONE ; RET ;************************************0 ( ) *!+",#-$.%/ &0 ' 8 ; ; IF CURRENT TRACK = REQUESTED TRACK THEN NO SEEK REQUIRED ; HLDD: LD A,(CMDBLK + DDTRKO) SUB (IX + DVTRK) JR NZ,AD ; ;************************************************ RDSEC: LD D,-1 JR RWSECT ;*************************************) ;IF TRACK 0 THEN USE DEFAULTS CP 1 JR C,CTLS ; ; IF TRACK 1 THEN DO TRACK 1 ; JR Z,TRK1 ; ; IF TRACK < 26 THEN PUT READ SECTOR COMMAND XOR C OUT (WDCMD),A ; ; WAIT FOR FDC TO CATCH UP ; EX (SP),HL EX (SP),HL ;WAIT FOR 1791 RS ; XOR A ;SET Z FLAG RET ; ; CALIBRATE TRACK # ; HOME: CALL HOMED ;HOME SELECTED DRIVE JP HLDD ;NOW SEEK TRACKDSET ; ; RETURN PREVIOUS CONTROLS ; LD A,(IX + DVCTL) JR EXITS ; ; SET DIRECTION & STEP COUNT ; DSET: ; ; SAV* ; ; READ/WRITE SECTOR SUBR ; ENTRY- A'= 0: WRITE, /0: READ ; HL= XFER PTR ; E= SECTOR ; EXIT - NZ= ERROR ; A,HL,B= ?DO OUTER VALUES ; CP 26 JR C,OUTS ; ; IF {26 < TRACK < 52} THEN DO MIDDLE VALUES ; CP 52 JR C,MIDS ; ; ELSE DOEX (SP),HL EX (SP),HL ; ; SELECT DIRECTION ; LD A,D ;IF WRITE OP THEN GO DO IT OR A JR Z,WROP ; ; READ DIRECTI ;************************************** ; ; HEAD LOAD/UNLOAD SUBROUTINES ; ENTRY - E= HEAD COMMAND ; ;*************E TRACK DIFFERENCE ; PUSH AF ; ; DELAY FOR STEP AFTER WRITE REQUIREMENT ; LD DE,TMSAW ;DELAY FOR STEP AFTER WRITE RS ; ;************************************** RWSECA: EX AF,AF' LD D,A EX AF,AF' ;************************************* INNER VALUES ; JR INSD ; ; TRACK 1 ; TRK1: BIT DFT1DB,(IX + DVFLG) ;IF SD THEN USE DEFAULTS JR Z,CTLS ; ; USE DOON ; RDREPT: ; ; OUTPUTTING TO THIS PORT GENERATES A CPU 'WAIT' UNTIL FDC READY ; IN A,(XPDSH) ; ; FDC READY, XFER ************************* EXHEAD: ; ; USE RETURN ADDRESS FOR INTERRUPT RETURN ; POP IY ;IY=RETURN ADDR ; ; PUT TRACT 8 ; ; RESTORE TRACK DIFFERENCE ; POP AF ; ; IF REQUESTED < CURRENT TRACK THEN STEP OUT ; JR C,SOUT ;CARRY=STEP ******************************* ; ; READ/WRITE SECTOR SUBROUTINE INITIATES DISK XFER, SEVICES THE ; CONTROLLER CHIP DURINGUBLE DENSITY, LOW PRECOMP ; T1DD: LD E,BCDDS + BCPCL JR CTLS ; ; OUTSIDE TRACKS ; OUTS: BIT DFDTDB,(IX + DVFLG) ;IF SDDATA ; IN A,(WDDTA) XOR C LD (HL),A INC HL ;PTR +1 JR RDREPT ; ; OPERATION DONE, CHECK STATUS ; RWNMI: ; ; K # INTO DATA REGISTER ; IN A,(WDTRK) ;PERFORM SEEK TO CURRENT TRACK WITH HEAD LOAD OUT (WDDTA),A ; ; OUTPUT PASSED COMOUT ; ; ELSE STEP IN ; SIN: LD L,A LD A,(SVDRV) OR BCDAS OUT (BLCTL),A JR STEPS ; ; STEP OUT REQUIRED ; SOUT DATA XFER, & TERMINATES OPERATION ; WHEN FINISHED. ERROR DETECTION IS IMPLEMENTED & RETRIES ARE ; EXECUTED IF DATA ERRORS A THEN USE DEFAULTS JR Z,CTLS ; JR T1DD ;ELSE USE SAME AS TRACK 1 ; ; MIDDLE TRACKS ; MIDS: BIT DFDTDB,(IX + DVFLG) ; ASSUME READ ERROR MASK ; LD B,DMRER ;IF NO ERRORS THEN RETURN PUSH AF ;SAVE 179X STATUS ; ; IF WRITE OPERATION THEN MAND TO FDC ; LD A,E ;OUTPUT PASSED COMMAND XOR C OUT (WDCMD),A ; ; WAIT FOR FDC INTERRUPT ; JR $ ;WAIT FOR INTE: ; ; COMPUTE TRACK COUNT ; NEG ;COMPLEMENT OFFSET ; ; IF COUNT > 127 THEN HOME, MUST BE ERROR ; JP M,HOME ; ;RE DETECTED. ; ENTRY - D= 0: WRITE, /0: READ ; HL= XFER PTR ; E= PHYSICAL SECTOR # (1..26) ; EXIT - NZ= ERROR ; HL, A, IF SD THEN USE DEFAULTS JR Z,CTLS ; ; USE DOUBLE DENSITY, MEDIUM PRECOMP ; LD E,BCDDS + BCPCM ;USE DD, MEDIUM PRECOMP USE WRITE ERROR MASK ; LD A,D ;IF WRITE OP THEN OR A JR NZ,RWMSK ; LD B,DMWER ;USE WRITE ERR MASK ; ; RETURN OPERRUPT ;************************************** ; ; GET STATUS SUBROUTINE ; EXIT - A= 1791 STATUS ; ;***************** SET UP TO STEP OUT ; LD L,A LD A,(SVDRV) OUT (BLCTL),A ; ; STEP ONCE ; STEPS: IN A,(XPSTP) LD DE,TMSTPC RST B= ? ; ;******************************************************************** RWSECT: XOR A ;0 ERROR COUNT LD (ERRCT),A ;  JR CTLS ; ; INSIDE TRACKS ; INSD: BIT DFDTDB,(IX + DVFLG) ;IF SD THEN USE DEFAULTS JR Z,CTLS ; ; USE DOUBLE DENSITRATION STATUS ; RWMSK: POP AF ;179X STATUS AND B RET Z ; ; SAVE THIS ERROR IN CASE RETRYS EXHAUSTED ; LD B,A PUS********************* EXSTS: ; ; ISSUE TERMINATE FDC OPERATION & READ FDC STATUS COMMAND ; LD A,DCSTS ;OUTPUT SET STATU8 ; ; IF COUNT NOT EXHAUSTED THEN REPEAT ; DEC L ;IF STEPS-1 NOT 0 THEN STEP AGAIN JR NZ,STEPS ; ; WAIT FOR SETTLI ; SET FDC SECTOR REGISTER ; LD A,E XOR C OUT (WDSEC),A ; ; SET FDC INTERRUPT RETURN VECTOR ; RWRTRY: LD IY,RWNMIY, HIGH PRECOMP ; LD E,BCDDS + BCPCH ;SET DD, HIGH PRECOMP ; ; SET CONTROLS ; CTLS: LD A,(SVDRV) ;ADD DENSITY, PRECOMPH BC ; ; SAVE FLAG, SECTOR ; PUSH DE ;SAVE FLAG, SECTOR ; ; IF RETRYS NOT EXHAUSTED THEN RETRY ; CALL CHKRT POPS COMMAND TO 1791 XOR C OUT (WDCMD),A EX (SP),HL ;PAUSE EX (SP),HL EX (SP),HL EX (SP),HL ; ; RETURN FDC STATUS NG TIME ; LD DE,TMALS ;ELSE EXTEND LAST PULSE RST 8 ; ; SET UP TRACK DENSITY & PRECOMPENSATION LEVEL ACCORDING TO TRACK ;SET NMI VECTOR FOR RETURN ; ; DEFAULT TO READ COMMAND ; LD B,DCRDS ; ; IF WRITE OPERATION THEN SET WRITE COMMAND ; BITS TO CONTROL BITS OR E LD (IX + DVCTL),A ; ; SET CONTROLS ; EXITS: OUT (BLCTL),A ; ; SET CURRENT TRACK ; LD DE POP BC JR Z,RWRTRY ; ; RESTORE ERROR & RETURN IT ; LD A,B JP RETERR ; ; EXECUTION OF NEXT INSTRUCTION GENER ; IN A,(WDSTS) XOR C RET ;************************************************ ; ; READ SECTOR SUBR PRESETS RWOP TO RE NUMBER ; LD E,BCSDS + BCPCL ;USE SD, PRECOMP LOW AS DEFAULTS ; ; IF TRACK 0 THEN USE DEFAULTS ; LD A,(CMDBLK + DDTRKO LD A,D ;SELECT OPERATION OR A JR NZ,OPOK ; LD B,DCWRS ;WRITE OP ; ; OUTPUT COMMAND TO FDC ; OPOK: LD A,B ;OUT A,(CMDBLK + DDTRKO) ;SET REQUESTED TRACK LD (IX + DVTRK),A XOR C OUT (WDTRK),A ;SET TRACK REGISTER ; ; RETURN NO ERRO0 ( ) *!+",#-$.%/ &0 'ATES A WAIT CONDITION UNTIL FDC READY ; WROP: REPTW: IN A,(XPDSH) ;HOLD FOR DATA REQ ; ; OUTPUT DATA TO FDC ; LD A,(HLH + #DRIVE,26,48,48 ENDM ; DTDED: DB 4,255,0,0,0,0,0,0 ;DUMMY DVDES EQU DVSIZE ;-------------------------------------- ; ;************************************************ DOBUFR: ; ; SET UP SECTOR BUFFER ; CALL BUFOK RET NZ ; ; SETWHEN BOOTED IN, THIS CODE IS IN BANK 1 SO MOVE TO BANK 0 ; LD BC,BANKL ;SET BYTE COUNT TO MOVE LD DE,BANK0 LD HL,BANK1 ECTOR INTO BUFFER ; NOTSAME: LD HL,SBUFR ;SET PTR PUSH DE ;SAVE PHYSICAL SECTOR # CALL RDSEC POP DE JR Z,BRDOK ;IF) XOR C OUT (WDDTA),A ; ; POINT TO NEXT DATA ; INC HL JR REPTW ;************************************** ; ;  ; ; COMMAND BLOCK ; THIS IS THE HOST COMMUNICATION AREA ; ;-------------------------------------- IF $ > (BANK0 + DDCB UP FOR TRANSFER ; PUSH BC LD BC,SECSIZ ;SET UP XFER LD DE,XBUF LD HL,SBUFR ;DEFAULT TO LO HALF ; ; COMPUTE LOGICALLDIR ;XFER DCM TO BANK 0 FROM LOAD ; ; EXECUTING THIS JUMP STARTS EXECUTING THE SAME POINT IN THE BANK 0 IMAGE ; JP DOW ERROR THEN CLEAR BUFFER ; ; IF READ ERROR THEN SET BUFFER CORRUPTED (SECTOR = 0 (ILLEGAL)) ; LD E,0 ; ; SET BUFFER P CHECK FOR RETRYS SUBROUTINE ; EXIT - A= 0: OK, /0: ERROR ; ;************************************** CHKRT: ; ; IF ERROR O) ?OVRLAP COMMAND BLOCK,$-BANK0+DDCBO ENDIF ORG BANK0 + DDCBO ;POSITION BLOCK CMDBLK: DB 0 ;CONTROL COMMAND DB 0  SECTOR (0: LOW 128 BYTES, 1: HIGH 128 BYTES) ; LD A,(CMDBLK + DDSECO) DEC A ;MAKE 1..N INTO 0..N-1 SECTOR NUMBER BIT 0,N ;TRANSFER TO FOLLOWING CODE NOW IN BANK 0 ALSO ; ; NOW IN BANK 0 ; DOWN: ; ; SET UP HARDWARE ; LD SP,STACKOINTERS ; BRDOK: LD HL,BSECT LD (HL),E ;CURRENT SECTOR INC HL ;CURRENT TRACK LD A,(IX + DVTRK) LD (HL),A INC HL ;IS DRIVE NOT READY THEN HARD ERROR ; AND DMDNR RET NZ ; ; IF NO RETRYS ALLOWED THEN RETURN HARD ERROR ; LD A,(CMDBLK ;DRIVE # DB 0 ;TRACK # DB 0 ;SECTOR # DB 0 ;FORMAT FLAGS DB 0 ;UNASSIGNED DB 0 ;MODE SELECTS DB 0 ;CONTROLLERA JR Z,XOK ; LD HL,SBUFR + SECSIZ ;XFER HI HALF ; ; IF READ THEN BUFFER OK ; XOK: EX AF,AF' JR NZ,NOTWRT ; ; EL CALL INIT ; ; LOAD IN BIOS LOADER SECTOR, PUT BIOS LOADER ENTRY ON STACK SO READ WILL ;RETURN & EXECUTE IT INSTEAD OF THCURRENT DRIVE LD A,(IX + DVNBR) LD (HL),A RET SUBTTL DATA AREAS ;---------------------------- ; ; DISKETTE FORMAT + DDFFGO) AND DDNRT RET NZ ; ; KICK MOTOR ON IN THE PANTS AGAIN ; IN A,(XPMTX) ; ; BUMP ERROR COUNT ; LD A,(E STATUS DW 0 ;LOAD ADDR DW 0 ;LOAD LENGTH ; SVSTS DB 0 ;1791 RAW STATUS IF $ > (BANK0 + DDBUFO) ?OVRLAP XFER BUFFSE REVERSE DIRECTION ; EX DE,HL ; ; MOVE DATA TO/FROM BUFFER ; NOTWRT: EX AF,AF' ;RESTORE FLAG LDIR ; ; RETURN NIS CODE. ; LD E,2 ;LOAD IN BIOS LOADER SECTOR IN A,(XPMTX) LD HL,BANK0 + DDBUFO ;SET RETURN TO EXECUTE BLT PUSH HL J LABEL ; ;---------------------------- JADEID: DB 'Jade DD ' ;DISKETTE ID LABLE IDSZE: EQU $-JADEID ;LABEL LENGTH ;--RRCT) INC A LD (ERRCT),A ; ; IF HALF OF RETRYS EXHAUSTED THEN TRY RECALIBRATE ; CP RTYSK JR NZ,CKLS ; CALL HOMEDER,$-BANK0+DDBUFO ENDIF ORG (BANK0 + DDBUFO) XBUF EQU $ ;DATA XFER BUFFER START SUBTTL INITIALIZATION ROUTINE ;----O ERROR ; POP BC XOR A RET ;************************************** ; ; CHECK FOR BUFFER OK SUBR ; EXIT - NZ= ERROP RDSEC ; IF $ > BANK1 ?OVRLAP PAST BANK 0,$-BANK0+1024 ENDIF SUBTTL UNINITIALIZED VARIABLES ORG BANK1 ;##########------------------------------------ ; ; DRIVE TABLE OFFSETS ; ;-------------------------------------- STRUCT 0 DVNBR DS  ;HOME SELECTED DRIVE CALL Z,SEEK ;RE-SEEK DESIRED TRACK RET NZ ;IF ERROR THEN EXIT ; ; IF RETRYS EXHAUSTED THEN RETU----------------------------------------------------------------------- ; ; THIS CODE IS ENTERED BY THE BOOT INJECTION MODULR ; HL,DE,A= ? ;************************************** BUFOK: ; ; COMPUTE PHYSICAL SECTOR FROM LOGICAL SECTOR REQUESTED ###################################### ; ; PHYSICAL SECTOR LOCATIONS FOR DEBLOCKING ; ;#####################################1 ;CURRENT PHYSICAL DRIVE # DVTRK DS 1 ;CURRENT PHYSICAL TRACK # DVSEC DS 1 ;CURRENT PHYSICAL SECTOR # DVFLG DS 1 ;DISK FORMARN ERROR ; CKLS: CP RTYLS JR Z,STNZ ; ; DELAY A WHILE & RETURN WITH NO ERRORS ; LD DE,TMPLD ;ELSE WAIT & RETURN WITH E (BIM) FROM ENTRY ; VECTOR AT DCM ADDRESS 0003H (ACTUALLY AT 0403H WHEN EXECUTED). ; IT RELOCATES THE ENTIRE DCM CURRENTLY IN ; PS = ((LS - 1) / 2) + 1 ; LD A,(CMDBLK + DDSECO) DEC A SRA A INC A ; ; IF REQUESTED SECTOR IS CURRENT SECTOR TH########### SBUFR DS 256 ;PHYSICAL SECTOR BUFFER ; ; ;#####################################################################T FLAGS DVCTL DS 1 ;LAST CONTROLS USED OFFSET DVSPT0 DS 1 ;SECTORS PER TRACK 0 DVSPT1 DS 1 ;SECTORS PER TRACK 1 DVSPTD DS 1 NO ERRORS RST 8 ; XOR A RET ; ; RETURN RETRYS EXHAUSTED (NZ) ; STNZ: INC A RET ;**************************** BANK 1 TO BANK 0, THEN TRANSFERS ; CONTROL TO IT'S BANK 0 IMAGE WHICH THEN PROCEEDS TO INITIALIZE THE FIRMWARE ; AND LOAD THEEN RETURN ; LD E,A ;SAVE FOR LATER LD A,(BSECT) CP E JR NZ,NOTSAME ; LD A,(BDISK) ;IF BUFFER NOT SAME THEN READ BU#### ; ; NOTE: THE FOLLOWING 3 BYTES MUST APPEAR IN THIS ORDER, THEY ARE ; INDEXED BY A POINTER IN BUFOK SUBR. ; ;#########;SECTORS PER DATA TRACKS DVSIZE DS 0 ENDM ; ; ; DRIVE TABLES ; DVTBL: IRP #DRIVE,0,1,2,3 DB #DRIVE,255,0,DFDFL,0C4******************** ; ; DEBLOCKING BUFFER HANDLER ; ENTRY- AF'= ZF: WRITE OP, NZ: READ OP ; EXIT - NZ= ERROR ; HL, DE= ?  BIOS LOADER INTO THIS BUFFER. ; ;--------------------------------------------------------------------------- INITB: ; ; FR CP (IX + DVNBR) JR NZ,NOTSAME ; LD A,(BTRACK) CP (IX + DVTRK) RET Z ;SAME, JUST RETURN ; ; ELSE READ PROPER S0 ( ) *!+",#-$.%/ &0 '################################################################ BSECT DS 1 ;CURRENT SECTOR # BTRACK DS 1 ;CURRENT SECTOR TRACTOR DSIZE EQU 8 ;DISK SIZE {5, 8} IF DSIZE = 5 DDPORT DL DDPORT5 ;JADE CONTOLLER PORT SKEW EQU 6 ;SKEW FACTOR FOR DOUBåCLUDE JDDDISK.DEF *INCLUDE JDDCONT.DEF *INCLUDE COMIOPB.DEF LIST ON SUBTTL MACROS ;;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@* ; ; REVISION STATUS: ; ; X.1 - 30 DEC 86 GRH ; Fix bug causing display of side 1 sector number > 32768. ; Remove sectoK # BDISK DS 1 ;CURRENT SECTOR DISK # ; SVDRV DS 1 ;BLCTL DRIVE BITS ERRCT DS 1 ;RETRY COUNT ; DS 32 ;STACK SIZE STACK LE DENSITY DDSPTC EQU 29 ;DOUBLE DENSITY MAX SECTORS PER TRACK SDSPTC EQU 16 ;SINGLE DENSITY MAX SECTORS PER TRACK ENDIFå@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ;; ;; GENERATE THE TRANSLATE TABLE ;; ;;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@r skew for double density in order to get failure data. ; ; X.2 - 31 DEC 86 GRH ; Reinstall double density skew factor. ; EQU $ IF $ > (BANK1 + 1024) ?OVRLAP PAST BANK 1,$-BANK1+1024 ENDIF END  IF DSIZE = 8 DDPORT DL DDPORT8 ;JADE CONTOLLER PORT SKEW EQU 6 ;SKEW FACTOR FOR DOUBLE DENSITY DDSPTC EQU 48 ;DOUBLE å@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GXLATE MACRO #SECTORS, #SKEW LIST OFF NXTSEC DL 1 ;;START WITH SECTOR 1 LOWEST DL 1 ;; Add precomp thresholds to ID sector data & add logon to track 0 ; format after writing ID sector ; ; 1.0 - 8 FEB 81 GRH ;åDENSITY MAX SECTORS PER TRACK SDSPTC EQU 26 ;SINGLE DENSITY MAX SECTORS PER TRACK ENDIF ;============================åREPT #SECTORS ;;ONCE FOR EACH SECTOR LIST ON DB NXTSEC LIST OFF NXTSEC DL NXTSEC + #SKEW ;;ADD IN SKEW FACTOR ;; IF  RELEASE ; VERSN EQU '00' ;CHANGE HERE FOR SIGN-ON CHANGE ; ;***************************************************************å=============================================== ; ; LOCATIONS ; ;===========================================================åNXTSEC > #SECTORS ;;CHECK FOR OVERFLOW NXTSEC DL NXTSEC - #SECTORS ;; IF NXTSEC <= LOWEST ;;CHECK FOR REPEAT NXTSEC DL LOWE************ SUBTTL DECLARATIONS ;=========================================================================== ; ; ASSEMBLå================ REBOOT: EQU 0 ;REBOOT ADDR TPA: EQU 100H ;TRANSIENT PROGRAM AREA ;====================================åST + 1 LOWEST DL NXTSEC ENDIF ENDIF ;; ENDM LIST ON ENDM ;;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Y CONTROL ; ;=========================================================================== FALSE EQU 0 TRUE EQU NOT FALSE ; å======================================= ; ; BDOS CALL VECTORS ; ;========================================================= TITLE 8" FLOPPY DISK FORMAT UTILITY FOR JADE DD CONTROLLER LIST NOCOND ;****************************************************@@@@@@@@@@@@@@@@@@@@@@ ;; ;; GENERATE THE ID SECTOR DATA ;; ;; ARGS: ;; LS= LOGICAL SECTORS PER TRACK ;; BS= BLOCK SHIFT FDIAG EQU TRUE ;=========================================================================== ; ; CONSTANTS ; ;=========å================== WBOOT EQU 0000H ;SYSTEM WARM BOOT BDOS: EQU 0005H ;SYSTEM CALL ADDR ;===============================*********************** ; ; JADE DOUBLE D DISK FORMAT PROGRAM ; ;*********************************************************ACTOR ;; BL= BLOCK MASK ;; EM= EXTENT MASK ;; DS= DISK SIZE IN CP/M BLOCKS ;; DI= DIRECTORY SIZE ;; A0= ALLOCATION MASK 0 ================================================================== CTRLC: EQU 3 ;REQUEST REBOOT CPM LF: EQU 0AH ;LINE FEED å============================================ ; ;*INCLUDE JDDLOC.DEF ;*INCLUDE JDDDISK.DEF ;*INCLUDE JDDCONT.DEF ;*INCLUDE C****************** ; ; FORMATn is a system utility which provides a means to write a single or ; double density format on a;; A1= ALLOCATION MASK 1 ;; CK= CHECK SIZE ;; OF= OFFSET ;; PS= PHYSICAL SECTORS PER TRACK ;; FG= PHYSICAL DISK FLAGS ;; PTCR: EQU 0DH ;CARRIAGE RETURN BS EQU 08H ;BACKSPACE ; NDRVS EQU 4 ;MAX NUMBER OF DRIVES SECSZ: EQU 128 ;128 BYTES PER SECåOMIOPB.DEF ; ;=========================================================================== LIST OFF *INCLUDE JDDLOC.DEF *INny of the drives accessed by the DD controller. ; ;**************************************************************************0 ( ) *!+",#-$.%/ &0 ' TITLE BIOS LOADER TRANSIENT (BLT) LIST NOCOND ;*************************************************************************** åT 85 GRH ; Modify for updated include file. Remove communication block setup ; for boot continuation - allows boot from oth######################### SIGNON: DB 'Jade Double D 8" disk format Utility Ver ' DB HIGH VERSN,'.',LOW VERSN,CR,LF DB 'CoEN FINISHED CP SECEX JR Z,FINISH INC A ;ELSE BUMP SECTOR & REPEAT LD (SECTOR),A JR RDSEC ; ; READ ERROR HAS B ; ; Bios loader firmware ; ;*************************************************************************** ; ; The BIOS låer than drive 0. ; VERSN EQU '12' ; ;*************************************************************************** FALSE EQpyright (c) 1983,1986 GRH Enterprises' DB '$' ;------------------------------------------------------------------------EEN DETECTED ; ERRORS: LD (CMDBLK + CBSTS),A ;DISPLAY ERROR STATUS XOR A ;DESELECT DRIVE OUT BLCTL,A IN A,XPMTO ;Moader is read into the DCM sector buffer after the DCM program ; has initialized. This program then reads the BIOS module (1k) åU 0 TRUE EQU NOT FALSE ; ;*INCLUDE JDDLOC.DEF ; LIST OFF *INCLUDE JDDLOC.DEF LIST ON ; ; BIOS PROGRAM LINKAGE ; --- ; ; MAIN PROGRAM CONTINUES ; ;--------------------------------------------------------------------------- INIT: ; ; OTOR OFF HALT ;WAIT FOREVER ; ; BIOS SECTORS HAVE BEEN LOADED ; FINISH: LD HL,BANK1 LD A,(BANK1 + 1) ;GET PTR into DD bank ; 1. The command block in DCM is set to indicate the BIOS module size & it's ; load address. The BIOS loader prog= PHYSICAL DISK TRACKS ;; ;;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GENSPT MACRO #FLG,#FG, SECBG EQU 13 ;1ST SECTOR OF BIOS SECNM EQU 8 ;# SECTORS SECEX EQU SECBG+SECNM-1 ;LAST BIOS SECTOR CMDBLK EQU BANK0 + 0370H SET UP LOCAL STACK ; LD SP,(BDOS + 1) DEC SP DEC SP ; ; OUTPUT SIGNON MESSAGE ; LD DE,SIGNON ;OUTPUT MESSAGE CTO BIOS PARAMS (INIT -1) LD E,A LD D,0 ADD HL,DE DEC HL ;LOAD_ADDR = BIOS_START LD D,(HL) DEC HL LD E,(HL) LDram is generated by MOVCPM.COM as the ; cold start loader (900-97F Hex). ; ;*************************************************#PS IF #FLG AND 1 DB DDSPTC ELSE DB SDSPTC ENDIF DB #FG SHR 6 ENDM ; GENIDD MACRO #LS,#BS,#BL,#EM,#DS,#DI, ;START OF COMMUNICATION BLOCK SUBTTL MAIN PROGRAM ORG BUFBG ;PROGRAM START POINT ; ; INIT BIOS READ OPERATION ; BEALL MSGOT ; ; TEST IF CONTROLLER PRESENT ; IN A,(DDPORT) ;FETCH STATUS PORT DATA INC A ;IF 0FFH THEN NOT INSTALLED J (CMDBLK + CBLAD),DE DEC HL ;LENGTH = BIOS_SIZE LD D,(HL) DEC HL LD E,(HL) LD (CMDBLK + CBLNG),DE LD A,(SECTOR)************************** ; ; REVISIONS: ; 1.0 - ; Release ; 1.1 - ; Frees this routine from re-assembly due to chang#A0,#A1,#CK,#OF,#PS,#FG,#PT DW #LS DB #BS,#BL,#EM DW #DS,#DI DB #A0,#A1 DW #CK,#OF DB #FG GENSPT #FG, #FG, #PS GGIN: LD HL,BANK1 ;SET LOAD ADDR LD SP,RDSEC ;INIT STACK TO HARMLESS PLACE FOR NOW ; ; SET UP FOR EACH READ SECTOR COMMANR NZ,CINSTLD ; ; CONTROLLER NOT INSTALLED, ERROR ; LD DE,CNIM CALL MSGOT JP REBOOT ;QUIT ; ; ; SET UP CONTROLLE ;SET UP COMMAND BLOCK INC A ;NEXT SECTOR TO READ LD (CMDBLK + CBSEC),A EI ;SET ALARM & GO TO SLEEP HALT ; ; ing BIOS params. ; LOAD ADDR & SIZE are now words in BIOS at 'INIT' - 2 & 'INIT' - 4 ; respectivly. 'INIT' pointer happens to ENSPT #FG SHR 1, #FG, #PS GENSPT #FG SHR 2, #FG, #PS DB (#PT / 3) + 1 DB ((#PT / 3) * 2) + 1 ENDM SUBTTL MAIN PROGD ; RDSEC: LD IY,RDTST ;SET NMI VECTOR LD A,(SECTOR) ;SET 1ST SECTOR XOR C OUT WDSEC,A LD A,DCRDS ;READ SECTOR CMR ADDRESS ; CINSTLD: DEC A ;OFFSET BACK TO DATA AND A,DDSASW ;MASK ADDRESS SWITCH RLCA OR A,0E0H ;ASSUME 111xxx00B  SECTOR # STORAGE ; SECTOR: DB SECBG ;SECTOR COUNTER IF $ >= (BUFBG + 128) CONMSG MODULE TOO BIG FOR SECTOR ENDIF be at Cold Start (BIOS) + 1. ; DD Command Block is left initialized to next BIOS sector to read if ; BIOS exceeds 1K. The SystRAM ORG TPA ;--------------------------------------------------------------------------- ; ; PROGRAM ENTRY POINT ; ;---D XOR C OUT WDCMD,A EX (SP),HL EX (SP),HL EX (SP),HL EX (SP),HL ; ; READ SECTOR OPERATION ; RDBYT: IN A,XPDSH  LD H,A LD L,0 LD (DDADDR),HL ; ; CLEAR THE CONTROLLER ; LD A,DDBGN OUT (DDPORT),A ; IF DSIZE = 5 EX (SP),HL END em Boot Driver can then continue to read ; remaining sectors of BIOS until done. ; ; 1.2 - 20 FEB 83 GRH ; Include DDDEFIN------------------------------------------------------------------------ JP INIT ;INITIALIZE ;########################## ;WAIT FOR DATA IN A,WDDTA ;PUT DATA INTO MEMORY XOR C LD (HL),A INC HL JR RDBYT ; ; CHECK READ SECTOR STATUS ;WAIT FOR FDC TO CATCH UP EX (SP),HL EX (SP),HL EX (SP),HL ; ENDIF CLRWT: IN A,(DDPORT) ;WAIT FOR DONE AND A,DDSåE.INC into header, any changes for 62k system. ; ; 1.3 - 1 SEP 83 GRH ; Modify for sector deblocking DCM. ; ; 1.4 - 30 OC################################################# ; ; COPYRIGHT NOTICE ; ;##################################################, REPEAT UNTIL BIOS LOADED ; RDTST: AND DMRER AND 0FEH ;IF ERROR THEN EXIT JR NZ,ERRORS LD A,(SECTOR) ;IF LAST SECTOR TH 0 ( ) *!+",#-$.%/ &0 'HLT JR NZ,CLRWT ; ; OUTPUT MENU ; FUNBG: LD DE,MSGFL ;OUTPUT FUNCTION LIST CALL MSGOT ; ; GET FUNCTION SELECTION FSAGE OUTPUT SUBR ; ENTRY- DE= PTR TO '$' TERMINATED TEXT ; EXIT - ? ; ;*****************************************************--------------------------------------------------------------------------- ; ; 0 ; FUN0: LD HL,SSSDID ;JADE SSSD 26SPT ;X DE,HL ; ; INIT DIGITS TO 0 ; LD HL,UNIT LD B,5 SET0: LD (HL),0 INC HL DJNZ SET0 ; ; PROCESS TENTHOUSANDS DIGLOOP ; FMTDSKLP: ; ; SIDE 0 ; LD HL,0 LD (IOPB + PBSECO),HL ; ; FLAGS ; LD A,(IDSIMG + IDDFFO) LD (IOPB + PBROM USER ; CALL CNSIN ;GET CONSOLE CHAR LD (LTRSE),A ;SAVE CHAR FOR ERROR MESSAGE ; ; CHECK FOR RANGE ; SUB A,'0' ********************** PUTS: MSGOT: LD C,9 ;PRINT STRING FUNCTION JP BDOS ;***************************************** ; COMMON CODE ; DO48: LD A,77 - 1 ; ; COMMON INIT CODE ; DOCOMN: ; ; SET LAST TRACK OF DISK ; LD (LASTTRK),A IT ; DEC HL LD BC,-10000 CALL DECDIG ; ; PROCESS THOUSANDS DIGIT ; LD BC,-1000 CALL DECDIG ; ; PROCESS HUNDRFLGO),A ; ; FORMAT TRACK ; CALL FMTTRK RET NZ ;IF ERROR THEN RETURN ; ; WHILE ON TRACK 0, WRITE THE DESCRIPTOR SEC CP A,NFUNCS JR C,FUNOK ; ; UNKNOWN FUNCTION, ERROR ; FUNERR: LD DE,MSGSE ;ELSE OUTPUT ERROR MSG CALL MSGOT JR FUNBG********************************** ; ; CONSOLE INPUT SUBR ; EXIT - A= CHAR AND 7FH ; BC, DE, HL= ? ; ;***************** ; ; OVERLAY DPB DATA ; LD DE,IDSIMG + IDDPBO LD BC,IDDPBSZ LDIR ; ; OVERLAY DISK FORMAT DATA ; LD DE,IDSIMG + EDS DIGIT ; LD BC,-100 CALL DECDIG ; ; PROCESS TENS DIGIT ; LD BC,-10 CALL DECDIG ; ; REMAINDER IS UNITS DIGITTOR ; LD A,(IOPB + PBTRKO) OR A,A JR NZ,FMTDSK1 ; CALL WRTID ;WHILE WE'RE HERE, WRITE ID SECTOR RET NZ ;ERR ; FM ;REPEAT ; ; FUNCTION RANGE OK, COMPUTE EXECUTION ADDRESS ; FUNOK: LD HL,FUNTBL LD E,A LD D,0 ADD HL,DE ADD HL,DE********************************************************** CNSIN: ; ; GET CHARACTER ; LD C,1 ;CONSOLE READ FUNCTION # IDDFFO LD A,(HL) ;PULL OFF FLAGS FOR FORMAT IOPB LD BC,IDFSIZE LDIR ; ; PASS DISK FLAGS WITH FORMAT COMMAND ; LD  ; LD (HL),E ; ; OUTPUT DIGITS WITH LEADING SPACES ; LD HL,TTHOU ;SET PTR LD BC,500H ;5 DIGITS, NOCONVERT 0 TO SPACTDSK1: ; ; DO SECOND SIDE IF NEEDED ; LD A,(IDSIMG + IDDFFO) AND A,1 SHL DFTSDB JR Z,NO2ND ; LD HL,8000H ;BIT 15=  LD E,(HL) INC HL LD D,(HL) LD HL,FUNBG ;SET UP RETURN ADDRESS PUSH HL EX DE,HL JP (HL) ;EXECUTE COMMAND ; ;  CALL BDOS ; ; MASK BIT 7 ; AND A,7FH ; ; IF CTRL-C THEN ABORT ; CP A,CTRLC JP Z,REBOOT ; ; CONVERT LOWER CA(IOPB + PBFLGO),A ; ; DO FORMAT ; JP FMTDSK ; ; ; 1 ; FUN1: LD HL,DSSDID ;JADE DSSD 26SPT JR DO48 ; ; ; 2 E = FALSE ; NXTDEC: LD A,(HL) ;FETCH DIGIT DEC HL ;NEXT DIGIT ADD A,'0' ;CONVERT TO ASCII CP A,'0' ;IF NOT 0 THEN NOSIDE SELECT LD (IOPB + PBSECO),HL ; CALL FMTTRK RET NZ ; NO2ND: ; ; CHECK FOR DONE ; LD A,(IOPB + PBTRKO) INC FUNCTION ADDRESS TABLE ; FUNTBL: DW FUN0 ;SINGLE SIDED SINGLE DENSITY 26SPT (241K) DW FUN1 ;DOUBLE SIDED SINGLE DENSITY 26SE TO UPPER CASE ; CP A,'a' RET C CP A,'z' + 1 RET NC AND A,5FH RET ;*****************************************; FUN2: LD HL,SSSD40ID ;IBM 3740 SSSD 26SPT JR DO48 ; ; ; 3 ; FUN3: LD HL,DSSD40ID ;IBM 3740 DSSD 26SPT JR DO48 ; CONVERT TO SPACE = TRUE JR NZ,FIRST ; INC C ;ELSE IF FLAG != 0 THEN DIGIT OCCURRED DEC C JR NZ,OUTNUM ; LD A,B ;ATA LD (IOPB + PBTRKO),A LD C,A LD A,(LASTTRK) CP A,C JR NC,FMTDSKLP ; ; FORMAT DONE, GO TEST FOR READ ERRORS ; CSPT (480K) DW FUN2 ;SINGLE SIDED SINGLE DENSITY IBM 3740 (241K) DW FUN3 ;DOUBLE SIDED SINGLE DENSITY IBM 3740 (480K) DW ********************************** ; ; CONSOLE OUTPUT SUBR ; ENTRY- E= CHAR ; ;********************************************; ; 4 ; FUN4: LD HL,SSDD48ID ;JADE FORMAT SSDD 48SPT JR DO48 ; ; ; 5 ; FUN5: LD HL,DSDD48ID ;JADE FORMAT DSDD 48S LEAST ONE 0 DEC A LD A,'0' JR Z,OUTNUM ; LD A,' ' ;PAD WITH LEADING BLANKS UNTIL DIGIT JR OUTNUM ; ; NON-0 DIGIALL CHECK ;CHECK FOR READ ERRORS JP FMTDSK ;READY FOR ANOTHER DISK ;---------------------------------------------------FUN4 ;SINGLE SIDED DOUBLE DENSITY 48SPT (440K) DW FUN5 ;DOUBLE SIDED DOUBLE DENSITY 48SPT (880K) DW NOFUN DW NOFUN DW ******************************* CNSOT: LD C,2 ;CONSOLE OUTPUT FUNCTION # JP BDOS ;*************************************PT JR DO48 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; FORMAT DISK FUNCTION ; ;+T OCCURRED, FLAG = TRUE ; FIRST: INC C ; ; OUTPUT DIGIT ; OUTNUM: PUSH HL PUSH BC PUSH AF LD E,A LD C,2 CALL B------------------------ ; ; CUSTOM FORMATTER ; ;---------------------------------------------------------------------------NOFUN DW CUSTOM NFUNCS EQU ($ - FUNTBL) / 2 ; ; NO SUPPORTED FUNCTION STUB ; NOFUN: POP HL ;RESTORE STACK JR FUNERR ************************************** ; ; PUT DECIMAL SUBROUTINE ; ENTRY- HL= VALUE TO OUTPUT ; EXIT - HL, DE, BC, A= ? ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FMTDSK: ; ; SELECT DRIVE ; CALL SELDR ;SELECDOS POP AF POP BC POP HL DJNZ NXTDEC ; ; DONE ALL 5 DIGITS ; RET ;****************************************** CUSTOM: RET SUBTTL SUBROUTINES ;*************************************************************************** ; ; MES ;TELL ERROR ;--------------------------------------------------------------------------- ; ; SELECT PARAMETERS ; ; ;*************************************************************************** PUTD: ; ; PUT DATA IN PROPER REGISTERS ; ET DRIVE RET C ;ERR- RESELECT ; ; SET UP IOPB FOR 1ST TRACK ; LD A,0 ;SET TRACK # LD (IOPB + PBTRKO),A ; ; MAIN  0 ( ) *!+",#-$.%/ &0 '********************************* ; ; OUTPUT CRLF SUBROUTINE ; EXIT - HL, DE, BC, AF= ? ; ;********************************LD DE,ENDEQM CALL MSGOT ; LD HL,IOPB CALL EXECIOPB ;FORMAT TRACK ; ; TELL LAST PADDING ; PUSH AF LD HL,(IOPB + IOPB CALL EXECIOPB JR NZ,WIDERR ;IF ERROR THEN RETURN ; ; OK SO FAR, PERFORM LOGON TO SET CONTROLLER FLAGS ; LD HL,LOALL MSGOT CALL CNSIN ;IF NOT CR THEN REPEAT CP A,CR JR NZ,SELDR ; ; RETURN NO ERROR ; AND A,A RET ;********(DDSPT),A ; LD A,(IOPB + PBSECO + 1) ;SIDE RLCA AND A,1 LD (DDSID),A ; LD A,(IOPB + PBTRKO) ;SECTOR SIZE INDEX CAL******************************************* CRLF: LD DE,CRLFM JP PUTS ;*************************************************PBST2O) CALL PUTD ; POP AF RET Z ;IF NO ERROR THEN RETURN ; ; ERROR- TELL SO ; LD DE,MSGNC ;ELSE OUTPUT ERROR MSGGIOPB CALL EXECIOPB RET Z ;IF LOGON OK THEN RETURN ; ; ERROR ENCOUNTERED, TELL IT ; WIDERR: LD DE,MSGNC ;ELSE OUTPUT ******************************************************************* ; ; CHECK FUNCTION CHECKS ALL TRACKS BY READING BACKWARDL GETSSZ AND A,3 LD (DDSSZ),A ; LD HL,128 ;SECTOR BYTE COUNT FMTD1: OR A,A JR Z,FMTD0 ; ADD HL,HL DEC A JR FM************************** ; ; CREATE DECIMAL DIGIT SUBROUTINE ; ENTRY- HL= PTR TO PLACE TO STORE DIGIT ; DE= VALUE TO CONV CP A,SEEKERR ;IF SEEK ERROR THEN DIFFERENT MESSAGE JR NZ,FTE1 ; LD DE,SKERM ; FTE1: CALL MSGOT XOR A,A ;RETURN ERROERROR & RETURN CALL MSGOT XOR A,A DEC A RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FROM LAST TRACK ; ;*************************************************************************** CHECK: ; ; SET UP ; LDTD1 ; FMTD0: LD (DDSECSZ),HL ; LD HL,FMTDD ;SET INJECTION ADDR ; ; COMMON FORMATTER CODE ; STDMA: ; ; SET UP PTR ERT ; BC= DIVISOR FOR DIGIT ; EXIT - HL= PTR TO NEXT DIGIT ; DE= REMAINDER ; BC= -BC ; ;*******************************R FLAG DEC A RET ;*************************************************************************** ; ; SELECT DRIVE SUBR+++++ ; ; FORMAT TRACK FUNCTION ; EXIT - AF= /0: ERROR ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HL,(IOPB + PBTRKO) ;START WITH LAST TRACK FORMATTED DEC HL LD (RDIOPB + PBTRKO),HL ; LD A,(IOPB + PBDRVO) ;SAME DRIVE TO DRIVER ; LD (IOPB + PBDMAO),HL ; ; CALCULATE CHECKSUM ; INC HL ;POINT TO BYTE COUNT INC HL LD E,(HL) ;FETCH B******************************************** DECDIG: PUSH HL EX DE,HL ADD HL,BC JR NC,ADDIT ; EX DE,HL POP HL INC  ; EXIT - CF= ERROR ; ;*************************************************************************** SELDR: ; ; OUTPUT PRO++++++++++ FMTTRK: LD A,(IOPB + PBFLGO) LD L,A LD A,(IOPB + PBTRKO) CP A,1 JR C,FMT0 JR Z,FMT1 ; SRL L FMT1: SRL LD (RDIOPB + PBDRVO),A ; ; NEW LINE ; LD DE,CRLFM CALL MSGOT ; ; ALL SET TO DO TRACK ; VLP: ; ; SET TRACK SIZYTE COUNT INC HL LD D,(HL) ; ; MAKE LAST BYTE = 0 TO CALCULATE CHECKSUM PROPERLY ; LD HL,(IOPB + PBDMAO) ADD HL,DE (HL) JR DECDIG ; ; ADDIT: LD A,C CPL LD E,A LD A,B CPL LD D,A INC DE ADD HL,DE EX DE,HL POP HL DEC HL MPT ; LD DE,MSGFD CALL MSGOT ; ; GET RESPONSE ; CALL CNSIN ; ; IF RETURN THEN EXIT ; CP A,CR ;IF RETURN THENL FMT0: BIT 0,L JR NZ,FMTDDTRK ; ; FORMAT SINGLE DENSITY TRACK SUBR ; ; SET UP DRIVER ; LD A,(IOPB + PBTRKO) ;SECTE ; RDTRKL: LD A,(RDIOPB + PBTRKO) CALL GETSPT ; SETNSEC: INC A ;OFFSET FOR TEST LD (NSECTS),A ; ; START WITH 1 DEC HL ;COMPENSATE, WE'RE 1 PAST LD (HL),0 ; LD HL,(IOPB + PBDMAO) ;REFETCH PTR TO START OF MODULE LD C,0 ;CHECKSUM S RET UNIT: DS 4 TTHOU: DS 1 ;*************************************************************************** ; ; WRITE  EXIT SCF RET Z ; ; SAVE DRIVE LETTER IN MESSAGES ; LD (DRLTR),A ;ELSE SAVE DRIVE LETTER & TEST FOR LEGAL LD (LTRSEORS PER TRACK CALL GETSPT LD (SDSPT),A ; LD A,(IOPB + PBSECO + 1) ;SIDE RLCA AND A,1 LD (SDSID),A ; LD A,(IOPB +ST SECTOR ; LD A,1 ;START WITH 1ST SECTOR ; ; READ LOOP ; RDLP: ; ; CHECK FOR SECTOR TRANSLATION ; LD (CURSEC),TARTS AT 0 ; FMTCKS: LD A,(HL) ;FETCH BYTE INC HL ;POINT TO NEXT BYTE ADD A,C ;ADD TO CHECKSUM LD C,A ; DEC DE ;IID SECTOR ; EXIT - AF= /0: ERROR ; ;*************************************************************************** WRTID: ; ;),A ; ; TEST FOR LEGAL DRIVE {0..3} ; SUB A,'0' CP A,4 JR C,NMBRD ;IF LEGAL THEN CONTINUE ; ; ILLEGAL DRIVE, REP PBTRKO) ;SECTOR SIZE INDEX CALL GETSSZ AND A,3 LD (SDSSZ),A ; LD HL,128 ;SECTOR BYTE COUNT FMTS1: OR A,A JR Z,FMTA ;SAVE THE CURRENT SECTOR ; LD A,(IDSIMG + IDFLGO) ;FETCH FLAGS LD L,A LD A,(RDIOPB + PBTRKO) ;FETCH TRACK CP A,1 ;F --COUNT != 0 THEN REPEAT LD A,E OR A,D JR NZ,FMTCKS ; LD A,C ;STORE -CHECKSUM IN LAST BYTE NEG DEC HL LD (HL), SET UP IOPBs ; LD A,(IOPB + PBDRVO) LD (WIDIOPB + PBDRVO),A LD (LOGIOPB + PBDRVO),A ; LD HL,IDSIMG LD (WIDIOPB + EAT ; LD DE,MSGSE ;PRINT SELECT ERROR MESSAGE CALL MSGOT JR SELDR ; ; ; DRIVE SELECTED ; NMBRD: LD (IOPB + PBDRVO)S0 ; ADD HL,HL DEC A JR FMTS1 ; FMTS0: LD (SDSECSZ),HL ; LD HL,FMTSD ;SET INJECTION ADDR JR STDMA ; ; ; FORMAIF TRACK 0 THEN TEST BIT 0 JR C,RDTST JR Z,RDTST1 ;IF TRACK 1 THEN TEST BIT 1 ; SRL L ;ELSE TEST BIT 2 RDTST1: SRL L A ; ; FORMAT THE TRACK ; LD DE,FMTGM ;OUTPUT FORMATTING MESSAGE CALL MSGOT ; LD HL,(IOPB + PBTRKO) CALL PUTD ; PBDMAO),HL ; LD HL,IDSECT ;SET ID SECTOR LD (WIDIOPB + PBSECO),HL ; ; EXECUTE THE IOPB ; LD HL,WIDIOPB ;PASS PTR TO ,A LD (WIDIOPB + PBDRVO),A LD (RDIOPB + PBDRVO),A ; ; PAUSE FOR READY ; LD DE,MSGXX ;PRINT TYPE CR WHEN READY MSG CT DOUBLE DENSITY TRACK SUBR ; FMTDDTRK: ; ; SET UP DRIVER ; LD A,(IOPB + PBTRKO) ;SECTORS PER TRACK CALL GETSPT LD  0 ( ) *!+",#-$.%/ &0 ' RDTST: BIT 0,L ;IF DOUBLE DENSITY THEN NO XLATE LD A,(CURSEC) JR NZ,RDSOK ; ; XLATE SECTOR ; LD HL,TRNTBL ;POINT CK NO. JR C,GFT0 ;IF TRK 0 THEN OK ; INC HL ;ELSE POINT TO TRK 1 INC HL JR Z,GFT0 ;IF TRK 1 THEN OK ; INC HL ;EL ; ; IF DOUBLE SIDED THEN DO SIDE 2 ; LD A,(IDSIMG + IDFLGO) BIT DFTSDB,A JR Z,TD1 ; ; IS DOUBLE SIDED, TOGGLE SI ' ; ; DISK PARAMETER BLOCK IMAGE, TO BE TRANSFERRED TO BIOS AT LOGON TIME ; DW SDSPTC ;SECTORS PER TRACK DB 3 ;BLOCK S),HL EX (SP),HL EX (SP),HL ; ENDIF DDWAIT: IN A,(DDPORT) ;NOW TEST FOR DONE AND A,DDSHLT JR NZ,DDWAIT ; ; GET TO TABLE DEC A ;{1..N} -> {0..N-1} ADD A,L ;CALCULATE OFFSET TO SECTOR LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) SE POINT TO DATA TRACKS INC HL ; GFT0: LD A,(HL) POP HL RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++DE ; LD A,(RDIOPB + PBSECO + 1) XOR A,80H LD (RDIOPB + PBSECO + 1),A JP NZ,RDTRKL ; TD1: ; ; NEXT TRACK ; RDNXTHIFT FACTOR DB 7 ;BLOCK MASK DB 0 ;NULL MASK DW 242 ;DISK SIZE -1 DW 63 ;DIRECTORY MAXIMUM DB 11000000B ;ALLOC 0 IOPB DATA ; LD A,DDMB0 OUT (DDPORT),A ; LD HL,(DDADDR) ;CACULATE OFFSET TO FDC COMMAND BLOCK LD DE,DDCBO ADD HL,DE  ;FETCH TRANSLATED SECTOR ; ; SET SECTOR ; RDSOK: LD (RDIOPB + PBSECO),A ;SAVE CURRENT SECTOR ; ; CHECK CONSOLE FOR A+++++++++++++++++++++ ; ; RETURN DISK FORMAT PHYSICAL SECTOR SIZE INDEX FUNCTION ; ENTRY- A= TRACK {0,1,..} ; EXIT - A= SECTT: LD A,(RDIOPB + PBTRKO) ;NEXT TRACK DEC A LD (RDIOPB + PBTRKO),A ; ; IF NEXT TRACK < 0 THEN RETURN ; JP P,VLP ;  DB 0 ;ALLOC 1 DW 16 ;CHECK SIZE DW 2 ;TRACK OFFSET ; ; PAD TO FORMAT DATA WITH E5H ; REPT IDSIMG + 40H - $ LIST; PUSH IY POP DE LD BC,IOPBSZ LDIR ; ; REMOVE FDC WINDOW BEFORE RETURN ; LD A,DDFREE OUT (DDPORT),A ; ; TESBORT ; LD C,11 ;GET CONSOLE STATUS CALL BDOS ; OR A,A JP Z,NOABRT ; LD C,1 ;FLUSH CONSOLE CHAR BEFORE ABORT CALOR SIZE INDEX {0:128, 1:256, 2:512, 3:1024} ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GELD DE,OKM JP MSGOT ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; EXECUTE IOPB FUNCTI OFF DB 0E5H LIST ON ENDM ; ; DISKETTE FORMAT DATA ; DB 00000000B ;DISKETTE FLAGS ; REPT 3 DB SDSPTC ;;SECTORT FOR ERROR ; LD A,(IY + PBSTATO) OR A,A IF DIAG = TRUE ; ; RETURN IF OK ; RET Z ; ; OUTPUT ERROR DATA ; L BDOS ; LD DE,ABRTDM ;OUTPUT ABORTED MESSAGE JP MSGOT ; ; NOABRT: ; ; IF LAST SECTOR OF TRACK THEN DONE ; LD HL,TSSZ: PUSH HL LD HL,IDSIMG + IDSSZ0O JP GETIDD ;%%% ; *INCLUDE DPBDEF.Z80 SUBTTL CONSTANT DECLARATIONS ;--------ON ; ENTRY- HL= IOPB PTR ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ EXECIOPB: ; ; OPS PER TRACK DB 0 ;;BYTES PER SECTOR {0:128, 1:256, 2:512, 3:1024} ENDM ; ; FILL REMAINING SECTOR DATA WITH E5H ; REPTPUSH AF LD L,A LD H,0 PUSH IY PUSH HL LD DE,IOPBERM CALL MSGOT ; POP HL CALL PUTD ; POP IY PUSH IY LD L,NSECTS LD A,(CURSEC) CP A,(HL) JR NC,TDONE ; ; OUTPUT TESTING TRACK MESSAGE ; LD DE,TSTGM CALL MSGOT ; LD HL,(---------------------------------------- ; ; SINGLE DENSITY TRANSLATION TABLE ; ;-------------------------------------------EN WINDOW TO CONTROLLER ; LD A,DDMB0 OUT (DDPORT),A ; ; MOVE FORMAT BUFFER TO DD ; PUSH HL POP IY LD L,(IY+PBDMA IDSIMG + 128 - $ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;#################################################(IY + PBST1O) LD H,0 CALL PUTD POP IY POP AF ; ENDIF RET ;++++++++++++++++++++++++++++++++++++++++++++++++++RDIOPB + PBTRKO) CALL PUTD ; ; OUTPUT SIDE NO. ; LD DE,SIDEM CALL MSGOT ; LD A,(RDIOPB + PBSECO + 1) RLCA AND ----- SPT DL SDSPTC TRNTBL: GXLATE SPT,6 SUBTTL DISK DESCRIPTOR SECTOR DATA ;########################################O) LD H,(IY+PBDMAO + 1) PUSH HL ;SAVE FOR SECTOR DATA MOVE LD DE,(DDADDR) LD BC,512 LDIR ; ; MOVE IOPB TO DD ; ########################## ; ; DISK DESCRIPTOR SECTOR OVERLAYS ; ;##########################################################+++++++++++++++++++++++++ ; ; RETURN TRACK PHYSICAL SECTORS PER TRACK FUNCTION ; ENTRY- A= TRACK ; EXIT - A= PHYSICAL SECTORA,1 LD L,A LD H,0 CALL PUTD ; ; OUTPUT SECTOR ; LD DE,SECM CALL MSGOT ; LD HL,(RDIOPB + PBSECO) RES 7,H ;M################################### ; ; SINGLE DENSITY DESCRIPTOR SECTOR (128 BYTES) ; TRACK 0..40= SD, (SDSPTC) 128 BYTE SEC LD DE,(DDADDR) ;CALCULATE OFFSET TO COMMAND BLOCK IN FDC LD HL,DDCBO ADD HL,DE EX DE,HL ; PUSH IY POP HL LD BC,IO################# SSSDID: GENIDD 26,3,7,0,242,63,0C0H,0,16,2,26,2,77 DSSDID: GENIDD 52,4,0FH,1,242,63,80H,0,16,2,26,0AH,77S PER TRACK {1,2,..255} ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GETSPT: ; ; POINT ASK OFF SIDE BIT CALL PUTD ; ; EXECUTE THE READ ; LD HL,RDIOPB CALL EXECIOPB ; LD DE,ERM ;IF READ ERROR THEN OUTTORS ; ;########################################################################### IDSIMG: ; ; RESERVE FIRST 16 BYTES FOPBSZ LDIR ; ; MOVE SECTOR DATA TO DD ; LD A,DDMB1 OUT (DDPORT),A POP HL LD DE,(DDADDR) LD BC,1024 LDIR ; ;  SSSD40ID: GENIDD 26,3,7,0,242,63,0C0H,0,16,2,26,0,77 DSSD40ID: GENIDD 52,4,0FH,1,242,63,80H,0,16,2,26,8,77 SSDD48ID: GTO BASE OF DATA ; PUSH HL LD HL,IDSIMG + IDSPT0O ;ASSUME TRACK 0 ; ; COMMON GET DATA CODE ; GETIDD: CP A,1 ;TEST TRAPUT ERROR CALL NZ,MSGOT ; ; NEXT SECTOR & REPEAT ; LD A,(CURSEC) INC A JP RDLP ; ; ; TRACK IS DONE ; TDONE:R BOOT, IF NEEDED ; REPT 16 LIST OFF DB 0E5H LIST ON ENDM ; ; DISK DESCRIPTOR SECTOR KEY ; DB 'Disk Descriptor EXECUTE ; LD A,DDEXC OUT (DDPORT),A ; ; WAIT FOR DONE ; IF DSIZE = 5 EX (SP),HL ;DELAY FOR FDC ACTION EX (SP 0 ( ) *!+",#-$.%/ &0 'ENIDD 48,4,0FH,1,224,63,80H,0,16,2,48,6,77 DSDD48ID: GENIDD 96,4,0FH,0,449,127,0C0H,0,16,2,48,0EH,77 ;##################1 BYTES FFH ; LD B,11 ;WRITE 11 ONES SRPT5: IN A,(XPDSH) LD A,0FFH XOR C OUT (WDDTA),A DJNZ SRPT5 ; ; WRITE 6 BKM DB ' Ok',CR,LF,'$' ERM DB ' Error!',CR,LF,'$' ABRTDM DB ' ** ABORTED **',CR,LF,'$' CNIM DB CR,LF,'Controller not instal########## ; ; SECTOR TRANSLATION TABLE, NONE FOR SINGLE DENSITY ; ;########################################################PT2 ; ; WRITE INDEX MARK ; IN A,(XPDSH) LD A,0FCH ;0FCH COMMANDS FDC CHIP TO WRITE INDEX MARK XOR C OUT (WDDTA),A ######################################################### ; ; MESSAGES ; ;###############################################YTES 0 ; LD B,6 ;WRITE 6 ZEROS BYTES SRPT6: IN A,(XPDSH) LD A,0 XOR C OUT (WDDTA),A DJNZ SRPT6 ; ; WRITE DATA Mled at port 4' DB (DDPORT AND 0FH) + '0' DB 'H$' IF DIAG IOPBERM DB CR,LF,'IOPB error = (status fdc status) $' EN################### SDXT: GXLATE SDSPTC, 1 ; ; CHECKSUM COMPENSATION BYTE. MODIFY TO MAKE TOTAL CHECKSUM = 0 ; DB 0  ; ; WRITE 26 BYTES FFH ; LD B,26 SRPT3: IN A,(XPDSH) LD A,0FFH XOR C OUT (WDDTA),A DJNZ SRPT3 ; ; COMMON SEC############################ MSGFL: DB CR,LF,LF,'****** Functions List ******' DB CR,LF,'0. Single sided, single density, 2ARK ; IN A,(XPDSH) LD A,0FBH ;0FBH COMMANDS FDC CHIP TO WRITE DATA ID MARK XOR C OUT (WDDTA),A ; ; WRITE SECSIZ BYDIF SUBTTL SINGLE DENSITY TRACK FORMATTER INJECTION MODULE ;############################################################### ;STARTING WITH 0 ALLOWS RUNTIME COMPUTATION ; SDOVSIZE EQU $ - FMTSD IF SDOVSIZE > 512 ; ; USER WARNING MESSAGE ; TOR CODE ; RPTSEC: ; ; WRITE 6 BYTES 0 ; LD B,6 SRPT4: IN A,(XPDSH) LD A,0 XOR C OUT (WDDTA),A DJNZ SRPT4 ; 6 SPT (241k)' DB CR,LF,'1. Double sided, single density, 26 SPT (484k)' DB CR,LF,'2. Single sided, single density, IBM 3TES E5H ; PUSH DE ;SAVE DE (SECTOR COUNT) SDSECSZ EQU $ + 1 ;PTR TO SECTOR BYTE COUNT LD DE,SECSZ SRPT7: IN A,(XPDSH) ############ ; ; SINGLE DENSITY FORMATTER INJECTION MODULE ; THIS CODE IS INTENDED TO EXECUTE WITHIN THE DOUBLE D MEMORY. CONMSG **** WARNING! SDRIVER EXCEEDS 512 BYTES ALLOCATED SPACE!! **** ENDIF SUBTTL DOUBLE DENSITY TRACK FORMATTER INJECTI; WRITE SECTOR ID MARK ; IN A,(XPDSH) LD A,0FEH ;0FEH COMMANDS FDC CHIP TO WRITE ID MARK XOR C OUT (WDDTA),A ; ; 740 (148K)' DB CR,LF,'3. Double sided, single density, IBM 3740 (296K)' DB CR DB LF,LF,'4. Single sided, double density, 4 LD A,0E5H XOR C OUT (WDDTA),A DEC DE LD A,E OR A,D JP NZ,SRPT7 - FMTSD + FMTBG ; ; WRITE DATA CRC ; IN A,(XP; ENTRY- DRIVE IS SELECTED, FLAGS ARE SET & TRACK IS SEEK'D ; IY= RETURN ADDRESS FOR FDC INTERRUPT ; D= SIDE # ; ;########ON MODULE ;########################################################################### ; ; DOUBLE D DOUBLE DENSITY INJECTIO WRITE TRACK NUMBER ; IN A,(XPDSH) IN A,(WDTRK) ;USE FDC'S OWN DATA OUT (WDDTA),A ; ; WRITE SIDE NUMBER ; IN A,(XP8 SPT (446k)' DB CR,LF,'5. Double sided, double density, 48 SPT (894k)' DB CR,LF,LF,'9. Custom configuration' DB CR,LFDSH) LD A,0F7H ;0F7H COMMANDS FDC CHIP TO WRITE CRC XOR C OUT (WDDTA),A ; POP DE ;ENOUGH TIME TO RESTORE SECTOR COUNT################################################################### FMTSD: ; ; FORMAT DRIVER HEADER ; DB 55H,0AAH ;KEYS N MODULE ; ;########################################################################### FMTDD: ; ; FORMAT DRIVER HEADER DSH) SDSID EQU $ + 1 ;PTR TO SIDE BYTE LD A,0 XOR C OUT (WDDTA),A ; ; WRITE SECTOR NUMBER ; IN A,(XPDSH) LD A,(,'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. NOW ; ; WRITE 27 BYTES FFH ; LD B,27 SRPT8: IN A,(XPDSH) LD A,0FFH XOR C OUT (WDDTA),A DJNZ SRPT8 ; ; IF -- DW SDOVSIZE ;CHECKSUM SIZE ; ; MAIN DRIVER ENTRY ; ; INIT PTR TO SECTOR TABLE ; SR0: LD HL,SDXT - FMTSD + FMTBG ; ; DB 55H,0AAH ;KEYS DW DDOVSIZE ;CHECKSUM SIZE ; ; MAIN DRIVER ENTRY ; ; INIT PTR TO SECTOR TABLE ; DR0: LD HL,DDXHL) ;FETCH FROM TRANSLATION TABLE XOR C OUT (WDDTA),A ; INC HL ; ; WRITE SECTOR SIZE INDEX ; IN A,(XPDSH) SDSSZ $' MSGFD: DB CR,LF,LF,'Write format on drive (CR to reselect): $' MSGNC: DB CR,LF,LF,'Execution Error!$' SKERM: DB CR,LF,'SeeSECTOR_COUNT != 0 THEN DO NEXT SECTOR ; DEC E ;# SECTORS -1 JP NZ,RPTSEC - FMTSD + FMTBG ; ; COUNT THE NUMBER OF FILL ; INIT SECTOR COUNT ; SDSPT EQU $ + 1 ;POINTER TO SPT LD E,SDSPTC ; ; COMMAND FDC TO WRITE TRACK ; LD A,DCWRT RST - FMTDD + FMTBG ; ; INIT SECTOR COUNT ; DDSPT EQU $ + 1 ;PTR TO SECTOR COUNT BYTE LD E,DDSPTC ; ; INIT COMPLEMENTEQU $ + 1 ;PTR TO SECTOR SIZE INDEX BYTE LD A,0 ;{0:128, 1:256, 2:512, 3:1024} XOR C OUT (WDDTA),A ; ; WRITE HEADER k Error. Is Drive Double Sided?$' MSGXX: DB CR,LF,LF,'Type CR when drive ' DRLTR: DB ' is ready. $' FMTGM DB CR,'Formatting BYTES TO INDEX ; LD HL,0 ;COUNT = 0 ; SRPT9: IN A,(XPDSH) LD A,0FFH ;WRITE ONES UNTIL INTERRUPT XOR C OUT (WDDTA),AT 32 ; ; WRITE 40 BYTES FFH ; LD B,40 ;# BYTES SRPT1: IN A,(XPDSH) ;WAIT FOR DATA REQ LD A,0FFH XOR C OUT (WDDTA)ING REGISTER' ; LD A,C EXX LD C,A LD DE,-1 ;BYTE COUNT SUBTRACTOR USING ADD INSTRUCTION EXX ; ; PRE-INVERT SECTOCRC ; IN A,(XPDSH) LD A,0F7H ;0F7H COMMANDS FDC CHIP TO WRITE ACCUMULATED CRC XOR C OUT (WDDTA),A ; ; WRITE 1track $' ENDEQM DB ' End = $' TSTGM DB CR,'Testing track $' SIDEM DB ' Side $' SECM DB ' Sector $' CRLFM DB CR,LF,'$' O INC HL ;RETURN ONES COUNT JP SRPT9 - FMTSD + FMTBG ;#################################################################,A ;WRITE DATA DJNZ SRPT1 ; ; WRITE 6 BYTES 00 ; LD B,6 SRPT2: IN A,(XPDSH) LD A,0 XOR C OUT (WDDTA),A DJNZ SR 0 ( ) *!+",#-$.%/ &0 'R DATA ; LD A,(DDSECD - FMTDD + FMTBG) XOR A,C LD (DDSECD - FMTDD + FMTBG),A ; ; COMMAND FDC TO WRITE TRACK ; LD A 1 LIST OFF DB 0 LIST ON ENDM ; ; LOGON IOPB ; LOGIOPB: DB 0 REPT IOPBSZ - 1 LIST OFF DB 0 LIST ON ENDM A,(XPDSH) LD A,(HL) XOR C OUT (WDDTA),A INC HL ; ; WRITE SECTOR SIZE ; IN A,(XPDSH) DDSSZ EQU $ + 1 ;PTR TO SECREQUIRE ; ; ;=========================================================================== ; ; DISK DESCRIPTOR SECTOR TEXT TORS LEFT THEN REPEAT ; DEC E JP NZ,RPJ48D - FMTDD + FMTBG ; ; COUNT REMAINING BYTES TO INDEX AND RETURN THEM TO HOST ,DCWRT RST 32 ; ; WRITE PREAMBLE - 80 X 4EH BYTES ; LD B,80 DRPT1: IN A,(XPDSH) LD A,4EH XOR C OUT (WDDTA),A D ; ; READ SECTOR BUFFER ; SECBUF DS 1024 ;SECTOR BUFFER END TOR SIZE INDEX BYTE LD A,0 ;128=0 XOR C OUT (WDDTA),A ; ; WRITE HEADER CRC ; IN A,(XPDSH) LD A,0F7H XOR C OUKEY ; ;=========================================================================== STRUCT 16 IDLABO DS 20H - 16 ;'Disk Desc; LD L,E ;START WITH 0 LD H,L ; ; WRITE GAP 4 - 4EH BYTES UNTIL INTERRUPT (INDEX) ; DRPT9: IN A,(XPDSH) LD A,4EH JNZ DRPT1 ; ; WRITE 12 X 0 BYTES ; LD B,12 DRPT10: IN A,(XPDSH) XOR A,A XOR C OUT (WDDTA),A DJNZ DRPT10 ; ; åT (WDDTA),A ; ; WRITE GAP 2 - 22 X 4EH BYTES ; LD B,22 DRPT4: IN A,(XPDSH) LD A,4EH XOR C OUT (WDDTA),A DJNZ DRPriptor '(Sector) ENDM ; ; ;=========================================================================== ; ; CP/M DISK PARXOR C OUT (WDDTA),A INC HL ;COUNT++ JR DRPT9 ; ; DOUBLE DENSITY SKEW TABLE, SKEW 8 SEEMS OPTIMUM ; DDXT: GXLATE DDSPTWRITE GAP C2 - 3 X F6H BYTES ; LD B,3 DRPT11: IN A,(XPDSH) LD A,0F6H XOR C OUT (WDDTA),A DJNZ DRPT11 ; ; WRITE I;**************************************************************************** ; ; M5b FORMAT DISK DESCRIPTOR SECTOR DEFINITIONT4 ; ; WRITE 8 X 0 BYTES ; LD B,8 DRPT5: IN A,(XPDSH) XOR A,A XOR C OUT (WDDTA),A DJNZ DRPT5 ; ; WRITE GAP AAMETER BLOCK (DPB) DATA (MOVED TO CP/M BIOS AT LOG-ON) ; (LOGICAL DISK DATA) ; ;=============================================C, SKEW ; ; CHECKSUM COMPENSATION BYTE. MODIFY TO MAKE TOTAL CHECKSUM = 0 ; DB 0 ;STARTING WITH 0 ALLOWS RUNTIME COMPUNDEX MARK ; IN A,(XPDSH) ;WRITE INDEX MARK LD A,0FCH XOR C OUT (WDDTA),A ; ; WRITE GAP 1 - 32 X 4EH BYTES ; LD BS ; ;**************************************************************************** ; ; REVISIONS: ; ; 1.0 - 31 OCT 85 GRH1 - 3 X F5H BYTES ; LD B,3 DRPT6: IN A,(XPDSH) LD A,0F5H XOR C OUT (WDDTA),A DJNZ DRPT6 ; ; WRITE DATA MARK ; ============================== IDDPBO EQU 20H ;DD ID SECTOR DPB DATA OFFSET STRUCT IDDPBO IDSPTO DS 2 ;SECTORS PER TRACK IDTATION ; DDOVSIZE EQU $ - FMTDD IF DDOVSIZE > 512 ; ; USER WARNING MESSAGE ; CONMSG **** WARNING! DDRIVER EXCEEDS ,32 DRPT12: IN A,(XPDSH) LD A,4EH XOR C OUT (WDDTA),A DJNZ DRPT12 ; ; COMMON SECTOR CODE ; RPJ48D: ; ; WRITE  ; RELEASE ; ; 1.1 - 24 SEP 86 GRH ; Totally change data format to allow greater versatility. ; ; 1.2 - 31 DEC 86 GRH  IN A,(XPDSH) LD A,0FBH XOR C OUT (WDDTA),A ; ; WRITE SECTOR DATA WITH E5H BYTES ; EXX ;SAVE REGS ; DDSECSZ EQUBSHO DS 1 ;BLOCK SHIFT FACTOR IDBLMO DS 1 ;BLOCK MASK IDEXMO DS 1 ;EXTENT MASK IDDSMO DS 2 ;DISK STORAGE SIZE -1 IDDRMO DS 2512 BYTES ALLOCATED SPACE!! **** ENDIF SUBTTL VARIABLE DECLARATIONS NSECTS DS 1 ;NUMBER OF SECTORS IN TRACK CURSEC DS 1END OF GAP 3 - 8 X 0 BYTES ; LD B,8 DRPT2: IN A,(XPDSH) XOR A,A XOR C OUT (WDDTA),A DJNZ DRPT2 ; ; WRITE GAP A1  ; Added precomp track bytes to disk format data block. ; ;******************************************************************* $ + 1 ;PTR TO SECTOR BYTE COUNT BYTE LD HL,SECSZ DEC HL ;OFFSET TO GENERATE CARRY ; DRPT7: IN A,(XPDSH) DDSECD EQU $ + ;DIRECTORY MAXIMUM IDAL0O DS 1 ;DIRECTORY CLUSTER ALLOCATION 0 IDAL1O DS 1 ;DIRECTORY CLUSTER ALLOCATION 1 (0 CONTINUED) IDC ;CURRENT SECTOR DDADDR DS 2 ;JADE CONTROLLER WINDOW ADDRESS LASTTRK DS 2 ;LAST TRACK ; ; FORMAT TRACK IOPB ; IOPB DB- 3 X F5H BYTES ; LD B,3 DRPT3: IN A,(XPDSH) LD A,0F5H XOR C OUT (WDDTA),A DJNZ DRPT3 ; ; WRITE ID MARK ; IN ********* IDSECT EQU 2 ;SECTOR NUMBER FOR ID SECTOR ;=================================================================== 1 LD A,0E5H ; XOR C ;CONVERSION COMMENTED OUT. ALREADY DONE OUT (WDDTA),A ADD HL,DE JP C,DRPT7 - FMTDD + FMTBG ; ; KSO DS 2 ;DIRECTORY CHECKSUMS SIZE IDOFFO DS 2 ;DIRECTORY TRACK OFFSET (RESERVED TRACKS CNT) IDEND DS 0 ENDM IDDPBSZ EQU ID 3 ;FORMAT TRACK REPT IOPBSZ - 1 LIST OFF DB 0 LIST ON ENDM ; ; WRITE ID SECTOR IOPB ; WIDIOPB: DB 2 ;WRITE SEA,(XPDSH) LD A,0FEH XOR C OUT (WDDTA),A ; ; WRITE TRACK # ; IN A,(XPDSH) IN A,(WDTRK) OUT (WDDTA),A ; ; WRI======== ; ; DISK DESCRIPTOR SECTOR ; THIS SECTOR IS ON TRACK 0 OF FLOPPY AND HARD DISKS ; ;=============================== WRITE DATA CRC ; IN A,(XPDSH) LD A,0F7H XOR C OUT (WDDTA),A ; EXX ;ENOUGH TIME TO RESTORE SECTOR COUNT NOW ; ;END - IDDPBO ;SIZE OF THIS STRUCTURE ; ; ;=========================================================================== ; ; CTOR REPT IOPBSZ - 1 LIST OFF DB 0 LIST ON ENDM ; ; READ SECTOR IOPB ; RDIOPB: DB 1 ;READ SECTOR REPT IOPBSZ -TE SIDE # ; IN A,(XPDSH) DDSID EQU $ + 1 ;PTR TO SIDE BYTE LD A,0 XOR C OUT (WDDTA),A ; ; WRITE SECTOR # ; IN ============================================ ; ; RESERVE 16 BYTES SPACE TO ALLOW A BOOTSTRAP VECTOR, WHICH SOME MACHINES ;  WRITE GAP 3 - 24 X 4EH BYTES ; LD B,24 DRPT8: IN A,(XPDSH) LD A,4EH XOR C OUT (WDDTA),A DJNZ DRPT8 ; ; IF SEC0 ( ) *!+",#-$.%/ &0 ' PHYSICAL DISK FORMAT FLAGS ; ;=========================================================================== IDDFFO EQU 40H SASE LOCK RECOVERY (100US) (DCM) TMSAW EQU 10 ;STEP AFTER WRITING (100US) (DCM) DFHLD EQU 350 ;HEAD ENGAGE TIME (100US) (DCM)åT ; ; D7 D0 ; |DCN|2SD|MOF|EIA|INT|TST|US1|US0| ; ^ ^ ^ ^ ^ ^ ^ ^_____ 1: 179X DATA INVERT ; | : ; CHANGED DEFINITIONS TO ALLOW FOR 1795/7 CHIP ; ; 1.2 - 23 OCT 83 GRH ; CLEANED UP, ADDED HEADER GRAPHICS ; ; 1.3 -TRUCT IDDFFO ;OFFSET TO DISK FORMAT PARAMETERS IDFLGO DS 1 ;DRIVE FLAGS BYTE IDSPT0O DS 1 ;TRACK 0 SECTORS PER TRACK IDSSZ0O DFSTPC EQU 80 ;STEPPER INTERVAL (100US) (DCM) DFALS EQU 80 ;DELAY AFTER LAST STEP (100US) (DCM) DFMTO EQU 4000 ;MOTOR STAå | | | | | |_________ 1: USER SWITCH 1 (SPARE) ; | | | | | |_____________ 0: TEST MODE ; | | | | 30 OCT 85 GRH ; Rearranged definitions. Added double sided hooks. ; ; 1.4 - 24 NOV 85 GRH ; Change code to reflect prom DS 1 ;TRACK 0 SECTOR SIZE {0:128, 1:256, 2:512, 3:1024} IDSPT1O DS 1 ;TRACK 1 SECTORS PER TRACK IDSSZ1O DS 1 ;TRACK 1 SECTOR RT UP DELAY (100US) (DCM) ENDIF ;============================================================================ ; ; Rå |_________________ 0: HOST INTERRUPT REQUEST ; | | | |_____________________ 1: EIA PORT INPUT ; | | |________ version of hardware. ; ; 1.5 - 22 SEP 86 GRH ; Add automatic 5"/8" timing constant selection based on value of ; assembleSIZE IDSPTDO DS 1 ;DATA TRACKS SECTORS PER TRACK IDSSZDO DS 1 ;DATA TRACKS SECTOR SIZE IDPCMO DS 1 ;MEDIUM PRECOMP START TRACETRY VALUES: ; ;============================================================================ RTYSK EQU 5 ;REPOSITION HEAD ONå_________________ 1: MOTOR OFF ; | |_____________________________ 0: 2 SIDED DRIVE ; |_________________________________ r variable 'DSIZE' {5,8}. DSIZE MUST be defined in main ; file. ; ;**********************************************************K # IDPCHO DS 1 ;HIGH PRECOMP START TRACK # IDFEND DS 0 ENDM IDFSIZE EQU IDFEND - IDDFFO ;SIZE OF FORMAT DATA ; ; DISK  RETRY RTYLS EQU 9 ;LAST REPEATED RETRY ;============================================================================ ; å0: DISK CHANGE FLAG ; ; THE FOLLOWING DEFINES EACH BIT & FUNCTION OF THE BOARD ; STATUS PORT (BLSTS) BSUS0 EQU 00000001B ;U****************** ;============================================================================ ; ; DISK DRIVE PARAMETERFORMAT FLAGS DEFINITION ; ; 7 0 ; | | | |0| | | | | ; \___/^ ^ ^ ^ ^__ TRACK 0 DENSITY= 0:SINGLE, 1:DOUBLE ; | | |  ; INTERNAL MEMORY ASSIGNMENTS ; ROM= 0000..0FFFH ; RAM BANK 0= 8000H..83FFH ; RAM BANK 1= 8400H..87FFH ; ;==============åSER SWITCH 0 - 179X INVERT BSUS1 EQU 00000010B ;USER SWITCH 1 - SPARE BSTST EQU 00000100B ;TEST MODE BSINT EQU 00001000B ;HOSS ; ;============================================================================ IF DSIZE = 8 NBTRK EQU 80 ;MAXIMUM # S| |____ TRACK 1 DENSITY= 0:SINGLE, 1:DOUBLE ; | | | |______ DATA TRACKS DENSITY= 0:SINGLE, 1:DOUBLE ; | | |________ ============================================================== BANKL EQU 1024 ;1K BANK LENGTH BANK0 EQU 8000H ;LOWER BANK BA SUBTTL INTERNAL DISK CONTROLLER DEFINITIONS ;**************************************************************************** ; T INT REQ BSEIA EQU 00010000B ;EIA SIGNAL INPUT BSMOF EQU 00100000B ;MOTOR OFF INDICATOR BSTSD EQU 01000000B ;2 SIDED DRIVE FTEPS TMPLD EQU 1200 ;PHASE LOCK RECOVERY (100US) (DCM) TMSAW EQU 10 ;STEP AFTER WRITING (100US) (DCM) DFHLD EQU 350 ;HEAD SIDES= 0:SINGLE SIDED, 1:DOUBLE SIDED ; | |____________ DISK TYPE= 0:FLOPPY DISK, 1:HARD DISK ; |_______________ SECTOR SSE ADDR BANK1 EQU BANK0 + BANKL ;UPPER BANK BASE ADDR RAMSIZ EQU BANKL * 2 ;EXTENT OF RAM ; FMTBG EQU BANK0 ;FORMAT BUFFER ; INTERNAL BOARD LEVEL PARAMETERS INCLUDE MODULE FOR THE JADE ; DOUBLE D DISK CONTROLLER BOARD. INCLUDE THIS MODULE TO DEFINE LAG BSDCN EQU 10000000B ;DISK CHANGE ;============================================================================ BLCTL: EENGAGE TIME (100US) (DCM) DFSTPC EQU 80 ;STEPPER INTERVAL (100US) (DCM) DFALS EQU 80 ;DELAY AFTER LAST STEP (100US) (DCM) DIZE BITS= 00:128, 01:256, 10:512, 11:1024 ; ; DRIVE FLAGS BIT #S DFT0DB EQU 0 DFT1DB EQU 1 DFDTDB EQU 2 DFTSDB EQU 3 DF FMTPS EQU FMTBG + 4 ;FORMAT START ADDR ;============================================================================ ; ;ANY ; PARAMETERS WITH SOFTWARE TO EXECUTE ON THE BOARD'S Z-80 PROCESSOR. ; ;************************************************QU 0 ;BOARD LEVEL CONTROL PORT ; ; |PCB|PCA|DAS|DDE|EIA|DSE|DSB|DSA| ; \_____/ ^ ^ ^ ^ \_____/ ; | | | FMTO EQU 1 ;MOTOR START UP DELAY (100US) (DCM) ENDIF IF DSIZE = 5 NBTRK EQU 80 ;MAXIMUM # STEPS TMPLD EQU 1200 ;PHHARDB EQU 5 DFDBLB EQU 6 DFDBL1B EQU 7  PORTS ; ;============================================================================ BLSTS: EQU 0 ;BOARD LEVEL STATUS POR**************************** ; ; REVISIONS: ; ; 1.0 - 19 JUL 82 ; RELEASE ; ; 1.1 - 14 FEB 83 ; MODIFIED FOR REV C BOARD0 ( ) *!+",#-$.%/ &0 '| | |______ DRIVE SELECT ADDRESS (0..3) ; | | | | |____________ DRIVE SELECT & FDC NMI ENABLE ; | D ; | |_____________________ 1: DISK WRITE PROTECTED, 0: UNPROTECTED ; |________________________ 1: DRIVE NOT READY, 0: DRI | | |U |H |V |R1|R2| ; \___/ ^ ^ ^ \___/ ; | | | | |___ STEP RATE (SEE DATA SHEET) ; | | | |TEST MASK DMWER EQU CSDNR+CSWRP+CSWFLT+CSRNF+CSCRC+CSLDE+CSBSY ;WRITE ERROR TEST DMFER EQU CSDNR+CSWRP+CSWFLT+CSLDE ;FORMAT ER________________ COMMAND: ; 00: READ ADDRESS 01: NOT USED ; 10: READ TRACK 11: WRITE TRACK ; DCRDA EQU 11000000B| | |________________ EIA OUTPUT PORT ; | | |____________________ DOUBLE DENSITY ENABLE ; | |___________VE READY ; CSDNR EQU 10000000B ;DRIVE NOT READY CSWRP EQU 01000000B ;WRITE PROTECTED CSHLD EQU 00100000B ;HEAD LOADED CSSKE________ 1: VERIFY TRACK AFTER SEEK, 0: NO VERIFY ; | | |___________ 1: LOAD HEAD, 0: UNLOAD HEAD ; | |______ROR TEST DMTK0 EQU CSTK0 ;TRACK 0 TEST DMHDL EQU CSHLD ;HEAD LOAD TEST DMDNR EQU CSDNR ;DRIVE NOT READY DMLDE EQU CSLDE  ;READ TRACK ADDR DCWRT EQU 11110000B ;WRITE TRACK FORMAT ; ; ; TYPE IV COMMANDS: ; 7 0 ; |1 |1 |0 |1 |I3|I2|I1|I0| ; _____________ DIRECTION & SIDE SELECT ; | 1: IN/SIDE 1, 0: OUT/SIDE 0 ; |______________________________ PRECOMP S EQU 00010000B ;SEEK ERROR CSCRC EQU 00001000B ;CRC ERROR CSTK0 EQU 00000100B ;TRACK 0 CSINDX EQU 00000010B ;INDEX CSBSY EQU________ 1: UPDATE TRACK REGISTER, 0: NO UPDATE ; |__________________ COMMAND: ; 00: RESTORE & SEEK 01: STEP AS LAS;LOST DATA ERR ;============================================================================ WDTRK EQU WDCMD + 1 ;179X TRACK ^ ^ ^ ^___ 1: INTERRUPT ON LOW-TO-HIGH READY ; | | |______ 1: INTERRUPT ON HIGH-TO-LOW READY ; | |____ELECT (0..3) ; ; THE FOLLOWING ASSIGNS EACH BIT POSITION & FUNCTION OF THE ; BOARD CONTROL PORT (BLCTL). ; BCDSA EQU 00 00000001B ;BUSY ; ; ; TYPE II & III COMMAND RESULTS ; 7 0 ; |NR|WP|WF|NF|CE|LD|RQ|BY| ; ^ ^ ^ ^ ^ ^ ^ ^___ 1: T ; 10: STEP IN 11: STEP OUT ; DCHDL: EQU 00011000B ;LOAD HEAD DCHDU EQU 00010000B ;HEAD UNLOAD ; ; ; TYPE II COM REGISTER ;============================================================================ WDSEC EQU WDCMD + 2 ;179X SECTOR REG_____ 1: INTERRUPT ON NEXT INDEX PULSE ; |____________ 1: INTERRUPT IMMEDIATELY ; DCSTS: EQU 11010000B ;TERMINATE OPERA000001B ;DRIVE SELECT A (2^0) BCDSB EQU 00000010B ;DRIVE SELECT B (2^1) BCDSE EQU 00000100B ;DRIVE SELECT ENABLE BCEIA EQU 00BUSY, 0: DONE ; | | | | | | |______ 1: XFER DATA, 0: NOT READY TO XFER DATA ; | | | | | |_________ 1: LOST DATA XMANDS: ; 7 0 ; |1 |0 |WT|M |F2|E |F1|A0| ; ^ ^ ^ ^ ^ ^___ WRITE 1: DELETED, 0: NORMAL DATA MARK ; | |ISTER ;============================================================================ WDDTA EQU WDCMD + 3 ;179X DATA REGISTER TION & READ TYPE 1 STATUS DCIFI EQU 11011000B ;FORCED INTERRUPT - NOT USED ;================================================001000B ;EIA SIGNAL OUT BCDDE EQU 00010000B ;DOUBLE DENSITY ENABLE BCDAS EQU 00100000B ;DIRECTION & SIDE BCPCA EQU 01000000B FER, 0: XFER OK ; | | | | |____________ 1: CRC ERROR IN ID FIELD ; | | | |_______________ 1: RECORD NOT FOUND, 0: XFE | | | (0 FOR READ COMMAND) ; | | | | |______ 1: SIDE 1, 0: SIDE 0 ; | | | |_________ 1: HEAD LOAD DE ;============================================================================ XPSTP: EQU 8H ;STEP PULSE GENERATOR ; (DATA ============================ WDSTS: EQU WDCMD ;179X STATUS REGISTER ; ; STATUS BIT DEFINITIONS ; TYPE I COMMAND RESULTS: ;PRECOMP SELECT A BCPCB EQU 10000000B ;PRECOMP SELECT B BCDR0: EQU 0 ;DRIVE 0 SELECT ; ; FUNCTION ASSIGNMENTS: ; BCDSN EQR OK ; | | |__________________ 1: READ- DELETED DATA, WRITE- WRITE FAULT ; | |_____________________ 1: DISK WRITE PROTECTLAY, 0: NO HEAD LOAD DELAY ; | | |____________ SECTOR LENGTH FIELD SELECT (SEE MANUAL) ; | | (SHOULD BE 1 F= DON'T CARE) ;============================================================================ XPMTO: EQU 10H ;MOTOR OFF GENER; 7 0 ; |NR|WP|HL|SE|CE|T0|IX|BY| ; ^ ^ ^ ^ ^ ^ ^ ^___ 1: BUSY, 0: DONE ; | | | | | | |______ 1: INDEX, 0: U BCDSA + BCDSB ;DRIVE MASK BCSDS EQU 0 ;SINGLE DENSITY BCDDS EQU BCDDE ;DOUBLE DENSITY BCPCH EQU BCPCA ;PRECOMP HEAVY BCED, 0: UNPROTECTED ; |________________________ 1: DRIVE NOT READY, 0: DRIVE READY ; ; SAME AS TYPE I COMMANDS EXCEPT: CSTYPOR IBM STANDARD) ; | |_______________ 1: READ MULTIPLE SECTORS, 0: NOT ; |__________________ 1: WRITE, 0: READ ATOR ; (DATA = DON'T CARE) ;============================================================================ XPIRR EQU 20H ;RENOT INDEX ; | | | | | |_________ 1: TRACK 00, 0: NOT TRACK 00 ; | | | | |____________ 1: CRC ERROR IN ID FIELD ; PCM EQU BCPCB ;PRECOMP MEDIUM BCPCL EQU BCPCA + BCPCB ;PRECOMP LIGHT BCPCZ EQU 0 ;PRECOMP OFF ;==========================E EQU 00100000B ;RECORD TYPE CSWFLT EQU 00100000B ;WRITE FAULT CSRNF EQU 00010000B ;RECORD NOT FOUND CSLDE EQU 00000100B ;LOSCOMMAND ; DCRDS EQU 10001000B ;READ SECTOR DCRMSº EQÕ 10011000Â ;REAÄ MULIPLÅ RECORDS DCWRS EQU 10101000B ;WRITE SECTOR ; SET HOST INTERRUPT REQUEST FF ; (DATA = DON'T CARE) ;=======================================================================| | | |_______________ 1: TRACK SEEK VERIFY ERROR, 0: VERIFY OK ; | | |__________________ 1: HEAD LOADED, 0: HEAD UNLOADE================================================== WDCMD: EQU 4 ;179X COMMAND REGISTER ; ; TYPE I COMMANDS: ; 7 0 ; |0T DATA ERR CSDRQ EQU 00000010B ;DATA REQUEST ; ; DISK STATUS MASKS ; DMRER EQU CSDNR+CSRNF+CSCRC+CSLDE+CSBSY ;READ ERROR ; ; TYPE III COMMANDS: ; 7 0 ; |1 |1 | | |0 |E |0 |0 | ; \___/ ^_________ 1: HEAD LOAD DELAY, 0: NO DELAY ; |0 ( ) *!+",#-$.%/ &0 '===== XPMTX: EQU 40H ;MOTOR ON GENERATOR ; (DATA = DON'T CARE) ;==========================================================K FORMAT FLAGS DEFINITION ; ; 7 0 ; | | | |0| | | | | ; \___/^ ^ ^ ^ ^__ TRACK 0 DENSITY= 0:SINGLE, 1:DOUBLE ; | | ååISKS ; ;=========================================================================== ; ; DS 3 ;ALLOW A JUMP VECTOR FOR THOSE ================== XPDSH: EQU 80H ;DATA SYNC HOLD ; (DATA = DON'T CARE) | | |____ TRACK 1 DENSITY= 0:SINGLE, 1:DOUBLE ; | | | |______ DATA TRACKS DENSITY= 0:SINGLE, 1:DOUBLE ; | | |_______ååMACHINES THAT NEED IT ; ; DISK DESCRIPTOR SECTOR TEXT KEY ; STRUCT 0 IDLBLO DS 20H - 3 ENDM ; ; CP/M DISK PARAMETERå_ SIDES= 0:SINGLE SIDED, 1:DOUBLE SIDED ; | |____________ DISK TYPE= 0:FLOPPY DISK, 1:HARD DISK ; |_______________ SECTORåå BLOCK (DPB) DATA (MOVED TO CP/M BIOS AT LOG-ON) ; IDDPBO EQU 20H ;DD ID SECTOR DPB DATA OFFSET STRUCT IDDPBO IDSPTO DS 2 ;å SIZE BITS= 00:128, 01:256, 10:512, 11:1024 ; ; DRIVE FLAGS BIT #S DFT0DB EQU 0 DFT1DB EQU 1 DFDTDB EQU 2 DFTSDB EQU 3 ååSECTORS PER TRACK IDBSHO DS 1 ;BLOCK SHIFT FACTOR IDBLMO DS 1 ;BLOCK MASK IDEXMO DS 1 ;EXTENT MASK IDDSMO DS 2 ;DISK STORAGEåDFHARDB EQU 5 DFDBLB EQU 6 DFDBL1B EQU 7 åå SIZE -1 IDDRMO DS 2 ;DIRECTORY MAXIMUM IDAL0O DS 1 ;DIRECTORY CLUSTER ALLOCATION 0 IDAL1O DS 1 ;DIRECTORY CLUSTER ALLOCATIONåååå 1 (0 CONTINUED) IDCKSO DS 2 ;DIRECTORY CHECKSUMS SIZE IDOFFO DS 2 ;DIRECTORY TRACK OFFSET (RESERVED TRACKS CNT) IDDPBSZ DS 0åå;**************************************************************************** ; ; JADE FORMAT DISK DEFINITIONS ; ;**********å ;SIZE OF THIS STRUCTURE ENDM ; ; DISK FORMAT FLAGS ; IDDFFO EQU 30H STRUCT IDDFFO ;OFFSET TO DISK FORMAT PARAMETERS åå****************************************************************** ; ; REVISIONS: ; ; 1.0 - 31 OCT 85 GRH ; RELEASE ; ;å IDSTGO DS 1 ;SECTOR STAGGER BYTE (NOT USED) IDFLGO DS 1 ;DRIVE FLAGS BYTE IDSPT0O DS 1 ;TRACK 0 SECTORS PER TRACK IDSPT1O DSåå**************************************************************************** ;=============================================å 1 ;TRACK 1 SECTORS PER TRACK IDSPTDO DS 1 ;DATA TRACKS SECTORS PER TRACK IDFSIZE DS 0 ;SIZE OF FORMAT DATA ENDM ; ; DISåå============================== ; ; JADE FORMAT DISK DESCRIPTOR SECTOR ; THIS SECTOR IS SECTOR 1, TRACK 0 OF FLOPPY AND HARD D0 ( ) *!+",#-$.%/ &0 ' SUBTTL DOUBLE D SYSTEM CONFIGURATION DEFINITIONS ;****************************************************************************; DDFMT EQU 3 ;FORMAT TRACK (EXECUTE DDMB1 + 8) ;DDCMD BYTE 3 ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE TRACK NUMBER {0..=================================== ; ; PAGE 0 LOCATIONS COMPATIBLE WITH CP/M ; DADDR: EQU 0040H ;DISK WINDOW PTR IN PAGED SECTOR BUFFER OFFSET ;============================ ; ; DOUBLE D COMMAND PORT ; ;============================ DDPORPARAMETERS ; DDLOG EQU 0 ;LOG ON DISK ;DDCMD BYTE 0 ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE WILL BE SET TO 0 BY COMMAN ; ; THIS INCLUDE MODULE DEFINES THE SYSTEM TO BOARD LEVEL ; PARAMETERS FOR THE JADE DOUBLE D DISK CONTROLLER. IT SHOULD BE 76} ;DDSEC BYTE DISK FLAGS TO STORE INTO (DRIVE_TABLE[DVFLG]) ;DDFFG BYTE X ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0 0 DMASK EQU DADDR + 2 ;STATUS HALT BIT MASK FOR BIOS DTEMP EQU DMASK + 1 ;NOT IMPLEMENTED, BUT RESERVED ; DDBASE: EQU 0E000T: EQU 43H ;DOUBLE D PORT ADDR ; ; D7 D0 ; |BGN| X | X | X | X | X |MB1|MB0| ; ^ ^ ^_____ 0: REMOVE MEMORYD ;DDSEC BYTE WILL BE SET TO 1 BY COMMAND ;DDFFG BYTE RETURNED DISK DESCRIPTOR SECTOR STATUS ; 0: NOT FOUND ; !0: BUFFER  ; INCLUDED AS DEFINITIONS WHENEVER THE BOARD IS DIRECTLY INTERFACED ; TO BY A SOFTWARE MODULE. ; ;************************: NONE) ;DDSTS: BYTE FDC STATUS IF DDMOD <> 0 ;DDADR: WORD X ;DDBSZ: WORD RETURNED NUMBER OF BYTES FROM LAST SECTOR TO INDEX H ;DD WINDOW BASE ADDR (ADDED TO STATUS BITS) ;======================================================= ; ; SYSTEM TO C BANK FROM HOST ; | | 1: ENABLE MEMORY BANK TO HOST & ; | | GENERATE PROCESSOR INTERRUPT ; | |_______CONTAINS VALID DISK DESCRIPTOR SECTOR DATA ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUS IF**************************************************** ; ; REVISIONS: ; ; 1.0 19 JUL 82 ; RELEASE ; ; 1.1 14 FEB 83 ; CH DDFBFO EQU 300H ;DD FORMAT BUFFER OFFSET (BANK 1) ; ; READ ADDRESS COMMAND (NOT IMPLEMENTED) ; DDRDA EQU 4 ;READ ADDRESONTROLLER COMMUNICATION BLOCK (IOPB) ; ;======================================================= DDCBO EQU 370H ;DCM COMMAND __ 0: SELECT 1K MEMORY BANK 0 ; | 1: SELECT 1K MEMORY BANK 1 ; |_________________________________ RESET BOARD PROC DDMOD <> 0 ;DDADR: WORD X ;DDBSZ: WORD X ; ; READ SECTOR COMMAND ; DDRDS EQU 1 ;READ SECTOR INTO DDBUF ;DDCMD BYTE 1 ANGED TO REFLECT REV C BOARD HARDWARE CHANGES: ; MA10 IN STATUS PORT BIT 1 & DELETION OF MEMORY ACKNOWLEDGE BIT 0 ; IN STAS ; ; EIA OUTPUT COMMAND (NOT IMPLEMENTED) ; DDSP1 EQU 5 ;SPARE ; ; EIA STATUS COMMAND (NOT IMPLEMENTED) ; DDSP2 EQBLOCK OFFSET STRUCT 0 DDCMDO DS 1 ;COMMAND BYTE (SEE BELOW) DDDRVO DS 1 ;DRIVE DDTRKO DS 1 ;TRACK DDSECO DS 1 ;SECTOR (FORESSOR (1) ; ; ; COMMANDS (OUTPUT TO DDPORT) ; DDOUT: EQU 0 ;REMOVE DD WINDOW FROM SYSTEM DDBGN: EQU 10000000B ;RESET DD ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE TRACK NUMBER {0..76} ;DDSEC BYTE SECTOR NUMBER {1..26} ;DDFFG BYTE 80H FOR NO RETUS PORT & MOVE OF HALT FLAG FROM BIT 1 TO BIT 0 OF STATUS ; PORT. ; 1.2 - 23 OCT 83 GRH ; CLEANED UP, ADDED HEADER GRAPHU 6 ;SPARE ; ; IDLE COMMAND (NOT IMPLEMENTED) ; DDIDL EQU 7 ;IDLE- WAIT FOR HOST INT., THEN HALT ;DDCMD BYTE 4..255 ;DMAT FLAGS) DDFFGO DS 1 ;FLAGS DDSPRO DS 1 ;SPARE DDMODO DS 1 ;ERROR CODE: ; 0: NONE ; -1= COMMAND ERROR ; -2= FDC Z80A DDMRQ: EQU 00000001B ;REQUEST MEMORY BANK 0 WINDOW DDMRT: EQU 00000000B ;RELEASE MEMORY WINDOW DDMB0: EQU 00000001B ;SETRYS ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUS IF DDMOD <> 0 ;DDADR: WORD X ;DDBSZ: WICS ; ; 1.3 - 7 JUN 85 GRH ; Added Jade format disk descriptor sector definitions. ; ; 1.4 - 29 OCT 85 GRH ; Changed dDDRV BYTE X ;DDTRK BYTE X ;DDSEC BYTE X ;DDFFG BYTE X ;DDSPR BYTE X ;DDMOD BYTE CMDERR ;NOT IMPLEMENTED, COMMAND ERROR ;DD ERROR (DDSTS= FDC STATUS) ; THE FOLLOWING ERRORS ON BOOT ONLY: ; 1= HOME ERR ; 2= READ ERR A ; 4= READ ERR BLECT MEMORY BANK 0 DDMB1: EQU 00000011B ;SELECT MEMORY BANK 1 DDEXC: EQU 00000010B ;ISSUE DD INTERRUPT (START) ;=========ORD X ; ; WRITE SECTOR COMMAND ; DDWRS EQU 2 ;WRITE SECTOR FROM DDBUF ;DDCMD BYTE 2 ;DDDRV BYTE DRIVE NUMBER {0..3} ;Disk descriptor sector format to new format. ; Clarified communication block commands. ; Added hook for log-on return of valid STS BYTE X ;DDADR WORD X ;DDBSZ WORD X ; ; COMMAND ERROR CODES (DDMODO OF COMMAND BLOCK ON RETURN) ; NOERR EQU 0 ;NO ERR ; 80H= DRIVE NOT READY DDSTSO DS 1 ;DISK CONTROLLER STATUS (SEE 179X MAN'L) DDADRO DS 2 ;LOAD & JUMP ADDR ; FORMAT= ================================== ; ; STATUS PORT (SAME ADDRESS AS DDPORT) ; ;===========================================DTRK BYTE TRACK NUMBER {0..76} ;DDSEC BYTE SECTOR NUMBER {1..26} ;DDFFG BYTE 80H FOR NO RETRYS ;DDSPR BYTE X ;DDMOD BYTE RETdisk descriptor boolean. ; Removed disk format data & command block data definitions to JDDDISK ; ;**************************OR AFTER FUNCTION CMDERR EQU 20H ;INVALID COMMAND FROM HOST FDCERR EQU 1FH ;CONTROLLER ERROR (DDSTSO= FDC ERROR CODE) SELERR # OF PADDING BYTES UNTIL INDEX ; BOOT= START OF BOOT MODULE IN MAIN MEMORY DDBSZO DS 2 ;DCM BLOCK LOAD SIZE (SIZE OF BOOT M ; ; D7 D0 ; | X | X | X | X |S12|S11|S10|HLT| ; \_________/ ^_____ PROCESSOR HALT FLAG (0) ; |_______URNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUS IF DDMOD <> 0 ;DDADR: WORD X ;DDBSZ: WORD X ; ; FORMAT TRACK COMMAND ************************************************** ;====================================== ; ; HOST MEMORY AREAS ; ;===EQU 21H ;ILLEGAL DRIVE REQUESTED SEEKERR EQU 15H ;SEEK ERROR ; ; TRANSFER BUFFER OFFSET TO DDBASE ; DDBUFO EQU 380H ;DODULE) ENDM ; ; COMMANDS (DDCMD OF COMMUNICATION BLOCK) ; ; LOGON COMMAND, READS DESCRIPTOR SECTOR & SETS DISK FORMAT 0 ( ) *!+",#-$.%/ &0 '______ BOARD MEMORY ADDR SWITCH POS. ; DDSHLT: EQU 00000001B ;STATUS PORT HALT FLAG, 0= HALT, 1= BUSY DDSASW: EQU 00001110B ;====== ; ; INTERNAL MEMORY ASSIGNMENTS ; ;============================================================================ BAå FLAG (1) ; |_________________________________ DISK CHANGE FLAG (1) ; ; THE FOLLOWING DEFINES EACH BIT & FUNCTION OF THE BO: ; CHANGED DEFINITIONS TO ALLOW FOR 1795/7 CHIP ; ; 1.2 - 23 OCT 83 GRH ; CLEANED UP, ADDED HEADER GRAPHICS ; ; 1.3 -STATUS PORT ADDR SW MASK NKL: EQU 1024 ;1K BANK LENGTH BANK0: EQU 0 ;LOWER BANK BASE ADDR BANK1: EQU BANK0 + BANKL ;UPPER BANK BASE ADDR ; FMTBG EQåARD ; STATUS PORT (BLSTS) BSUS0 EQU 00000001B ;USER SWITCH 0 - 179X INVERT BSUS1 EQU 00000010B ;USER SWITCH 1 - SPARE BSTST 30 OCT 85 GRH ; Rearranged definitions. Added double sided hooks. ; ;*****************************************************åU BANK1 + 300H ;FORMAT BUFFER FMTPS EQU FMTBG + 8 ;FORMAT START ADDR ; ; BOOTSTRAP COMMUNICATION ; BEHOM: EQU 1 ;HOME ERå EQU 00000100B ;TEST MODE BSINT EQU 00001000B ;HOST INT REQ BSEIA EQU 00010000B ;EIA SIGNAL INPUT BSMOF EQU 00100000B ;MOTOR *********************** ;============================================================================ ; ; DISK DRIVE PARAåROR BERDA: EQU 2 ;READ ERROR A BERDB: EQU 4 ;READ ERROR B ; ; DISK CONTROLLER MODULE (DCM) LINKAGE ; DCMSS: EQU 4 ;1SåOFF INDICATOR BSTSD EQU 01000000B ;2 SIDED DRIVE FLAG BSDCN EQU 10000000B ;DISK CHANGE ;===================================METERS ; ;============================================================================ TMSTP: EQU 8 ;STEPPER INTERVAL (ms) (åT DCM SECTOR DCMBG: EQU BANK1+3 ;DCM COLD START ENTRY DCMLN: EQU 1024 ;DCM LENGTH ;====================================å========================================= BLCTL: EQU 0 ;BOARD LEVEL CONTROL PORT ; ; |PCB|PCA|DAS|DDE|EIA|DSE|DSB|DSA| ; \_BIM) TMSTPC EQU 80 ; " " (100US) (DCM) TMDBR: EQU 1 ;DELAY BEFORE READ (ms) (BIM) NBTRK: EQU 80 ;MAXIMUM # STEPSå======================================== ; ; PORTS ; ;====================================================================å____/ ^ ^ ^ ^ \_____/ ; | | | | | |______ DRIVE SELECT ADDRESS (0..3) ; | | | | |_____ TMHLD EQU 350 ;HEAD ENGAGE TIME (100US) (DCM) TMALS EQU 80 ;DELAY AFTER LAST STEP (100US) (DCM) TMMTO EQU 1 ;MOTOR START å======== BLSTS: EQU 0 ;BOARD LEVEL STATUS PORT ; ; D7 D0 ; |DCN|2SD|MOF|EIA|INT|TST|US1|US0| ; ^ ^ ^ ^ ^ SUBTTL INTERNAL DISK CONTROLLER DEFINITIONS ;**************************************************************************** ; _______ DRIVE SELECT ENABLE ; | | | |________________ EIA OUTPUT PORT ; | | |____________________ DOUBLEUP DELAY (100US) (DCM) TMPLD EQU 1200 ;PHASE LOCK RECOVERY (100US) (DCM) TMSAW EQU 10 ;STEP AFTER WRITING (100US) (DCM) ; å ^ ^ ^_____ 179X DATA INVERT (1) ; | | | | | | |_________ USER SWITCH 1 (SPARE) ; | | | | | |_; INTERNAL BOARD LEVEL PARAMETERS INCLUDE MODULE FOR THE JADE ; DOUBLE D DISK CONTROLLER BOARD. INCLUDE THIS MODULE TO DEFINE  DENSITY ENABLE ; | |________________________ DIRECTION & SIDE SELECT ; |______________________________ PRECOMP SE; TIMING CONSTANTS: ; TMRFC EQU 19H ;1ST PASS TMRNC EQU 1CH ;NORMAL PASS ; ; RETRY VALUES: ; RTYSK EQU 5 ;REPOSITIå____________ TEST MODE (1) ; | | | | |_________________ HOST INTERRUPT REQUEST (1) ; | | | |________________ANY ; PARAMETERS WITH SOFTWARE TO EXECUTE ON THE BOARD'S Z-80 PROCESSOR. ; ;************************************************LECT (0..3) ; ; THE FOLLOWING ASSIGNS EACH BIT POSITION & FUNCTION OF THE ; BOARD CONTROL PORT (BLCTL). ; BCDSA EQU 000ON HEAD ON RETRY RTYLS EQU 9 ;LAST REPEATED RETRY ;======================================================================å_____ EIA PORT INPUT ; | | |_________________________ MOTOR OFF (1) ; | |_____________________________ 2 SIDED DRIVE**************************** ; ; REVISIONS: ; ; 1.0 - 19 JUL 82 ; RELEASE ; ; 1.1 - 14 FEB 83 ; MODIFIED FOR REV C BOARD0 ( ) *!+",#-$.%/ &0 '00001B ;DRIVE SELECT A (2^0) BCDSB EQU 00000010B ;DRIVE SELECT B (2^1) BCDSE EQU 00000100B ;DRIVE SELECT ENABLE BCEIA EQU 000å;READ TRACK ADDR DCSTS: EQU 11010000B ;TERMINATE OPERATION & READ TYPE 1 STATUS DCIFI EQU 11011000B ;FORCED INTERRUPT - NOT US======================================================== ; ; DISK DRIVE PARAMETERS ; ;================================================ WDSEC: EQU 6 ;179X SECTOR REGISTER ;==========================================================================01000B ;EIA SIGNAL OUT BCDDE EQU 00010000B ;DOUBLE DENSITY ENABLE BCDAS EQU 00100000B ;DIRECTION & SIDE BCPCA EQU 01000000B ;åED DCWRT EQU 11110000B ;WRITE TRACK FORMAT ;============================================================================ WD======================================== TMSTP: EQU 8 ;STEPPER INTERVAL (ms) (BIM) TMDBR: EQU 1 ;DELAY BEFORE READ (ms) (BIM== WDDTA: EQU 7 ;179X DATA REGISTER ;============================================================================ XPSTP: EPRECOMP SELECT A BCPCB EQU 10000000B ;PRECOMP SELECT B BCDR0: EQU 0 ;DRIVE 0 SELECT ; ; FUNCTION ASSIGNMENTS: ; BCDSN EQUåSTS: EQU 4 ;179X STATUS REGISTER ; ; STATUS BIT DEFINITIONS ; TYPE I: ; CSDNR EQU 10000000B ;DRIVE NOT READY CSWRP EQU 010) ; NBTRK: EQU 80 ;MAXIMUM # STEPS ; ; DELAYS ; TMPLD EQU 1200 ;PHASE LOCK RECOVERY (100US) (DCM) TMSAW EQU 10 ;STEPQU 8H ;STEP PULSE GENERATOR ; (DATA = DON'T CARE) ;======================================================================== BCDSA + BCDSB ;DRIVE MASK BCSDS EQU 0 ;SINGLE DENSITY BCDDS EQU BCDDE ;DOUBLE DENSITY BCPCH EQU BCPCA ;PRECOMP HEAVY BCP SUBTTL INTERNAL DISK CONTROLLER DEFINITIONS ;**************************************************************************** ; 00000B ;WRITE PROTECTED CSHLD EQU 00100000B ;HEAD LOADED CSSKE EQU 00010000B ;SEEK ERROR CSCRC EQU 00001000B ;CRC ERROR CSTK AFTER WRITING (100US) (DCM) ; ; DEFAULT DRIVE PARAMETERS ; DFHLD EQU 350 ;HEAD ENGAGE TIME (100US) (DCM) DFSTPC EQU 80 ==== XPMTO: EQU 10H ;MOTOR OFF GENERATOR ; (DATA = DON'T CARE) ;==========================================================CM EQU BCPCB ;PRECOMP MEDIUM BCPCL EQU BCPCA + BCPCB ;PRECOMP LIGHT BCPCZ EQU 0 ;PRECOMP OFF ;===========================; INTERNAL BOARD LEVEL PARAMETERS INCLUDE MODULE FOR THE JADE ; DOUBLE D DISK CONTROLLER BOARD. INCLUDE THIS MODULE TO DEFINE 0 EQU 00000100B ;TRACK 0 CSINDX EQU 00000010B ;INDEX CSBSY EQU 00000001B ;BUSY ; ; TYPE II & III ; CSTYPE EQU 00100000B ;R ;STEPPER INTERVAL (100US) (DCM) DFALS EQU 80 ;DELAY AFTER LAST STEP (100US) (DCM) DFMTO EQU 1 ;MOTOR START UP DELAY (100US)================== XPIRR EQU 20H ;RESET HOST INTERRUPT REQUEST FF ; (DATA = DON'T CARE) ;================================================================================== WDCMD: EQU 4 ;179X COMMAND REGISTER ; DCHDL: EQU 00011000B ;LOAD HEAD DCHDANY ; PARAMETERS WITH SOFTWARE TO EXECUTE ON THE BOARD'S Z-80 PROCESSOR. ; ;************************************************ECORD TYPE CSWFLT EQU 00100000B ;WRITE FAULT CSRNF EQU 00010000B ;RECORD NOT FOUND CSLDE EQU 00000100B ;LOST DATA ERR CSDRQ  (DCM) ; ; TIMING CONSTANTS FOR 100us (8"), 200us (5 1/4") ; TMRFC EQU 19H ;1ST PASS TMRNC EQU 1CH ;NORMAL PASS ; ; =========================================== XPMTX: EQU 40H ;MOTOR ON GENERATOR ; (DATA = DON'T CARE) ;====================U EQU 00010000B ;HEAD UNLOAD ; ; THE READ & WRITE SECTOR CMDS NOW HAVE SIDE 1 SELECT BIT SET FOR ; 1791..4 CHIPS, HOWEVER TH**************************** ; ; REVISIONS: ; ; 1.0 - 19 JUL 82 ; RELEASE ; ; 1.1 - 14 FEB 83 ; MODIFIED FOR REV C BOARDEQU 00000010B ;DATA REQUEST ; ; DISK STATUS MASKS ; DMRER: EQU 10011101B ;READ ERROR TEST MASK DMWER EQU 11111101B ;WRITE RETRY VALUES: ; RTYSK EQU 5 ;REPOSITION HEAD ON RETRY RTYLS EQU 9 ;LAST REPEATED RETRY ;===================================================================================== XPDSH: EQU 80H ;DATA SYNC HOLD ; (DATA = DON'T CARE) E SIDE CHECK ENABLE BIT IS FALSE, SO IT ; BECOMES A DON'T CARE. THIS IS NEEDED FOR COMPATABILITY WITH THE 1795..7 ; CHIP, WH: ; CHANGED DEFINITIONS TO ALLOW FOR 1795/7 CHIP ; ; 1.2 - 23 OCT 83 GRH ; CLEANED UP, ADDED HEADER GRAPHICS ; ; 1.3 - ERROR TEST DMFER EQU 11100100B ;FORMAT ERROR TEST DMTK0: EQU 00000100B ;TRACK 0 TEST DMHDL EQU 00100000B ;HEAD LOAD TEST DM=============================================== ; ; INTERNAL MEMORY ASSIGNMENTS ; ROM= 0000..0FFFH ; RAM BANK 0= 8000H..83åICH USES THE SIDE SELECT BIT FOR DETERMINING SECTOR SIZE & MUST ; BE A 1 FOR 128 BYTES PER SECTOR. (0= 256 BYTES) ; DCRDS EQ 30 OCT 85 GRH ; Rearranged definitions. Added double sided hooks. ; ; 1.4 - 24 NOV 85 GRH ; Change code to reflect promDNR EQU 10000000B ;DRIVE NOT READY DMLDE EQU 00000100B ;LOST DATA ERR ;=====================================================FFH ; RAM BANK 1= 8400H..87FFH ; ;============================================================================ BANKL EQU 102åU 10001000B ;READ SECTOR DCRMSº EQÕ 10011000Â ;REAÄ MULIPLÅ RECORDS DCWRS EQU 10101000B ;WRITE SECTOR ; DCRDA EQU 11000000B  version of hardware. ; ;**************************************************************************** ;=========================================== WDTRK: EQU 5 ;179X TRACK REGISTER ;================================================================0 ( ) *!+",#-$.%/ &0 '4 ;1K BANK LENGTH BANK0 EQU 8000H ;LOWER BANK BASE ADDR BANK1 EQU BANK0 + BANKL ;UPPER BANK BASE ADDR RAMSIZ EQU BANKL * 2  ^ ^ ^ ^___ WRITE 1: DELETED, 0: NORMAL DATA MARK ; | | | | | (0 FOR READ COMMAND) ; | | | | |______NCTION OF THE BOARD ; STATUS PORT (BLSTS) BSUS0 EQU 00000001B ;USER SWITCH 0 - 179X INVERT BSUS1 EQU 00000010B ;USER SWITCH UPT - NOT USED ;============================================================================ WDSTS: EQU WDCMD ;179X STATUS RENABLE BCDAS EQU 00100000B ;DIRECTION & SIDE BCPCA EQU 01000000B ;PRECOMP SELECT A BCPCB EQU 10000000B ;PRECOMP SELECT B BCD;EXTENT OF RAM ; FMTBG EQU BANK0 ;FORMAT BUFFER FMTPS EQU FMTBG + 4 ;FORMAT START ADDR ; ; BOOTSTRAP COMMUNICATION ; B 1: SIDE 1, 0: SIDE 0 ; | | | |_________ 1: HEAD LOAD DELAY, 0: NO HEAD LOAD DELAY ; | | |____________ SECT1 - SPARE BSTST EQU 00000100B ;TEST MODE BSINT EQU 00001000B ;HOST INT REQ BSEIA EQU 00010000B ;EIA SIGNAL INPUT BSMOF EQU 0EGISTER ; ; STATUS BIT DEFINITIONS ; TYPE I COMMAND RESULTS: ; 7 0 ; |NR|WP|HL|SE|CE|T0|IX|BY| ; ^ ^ ^ ^ ^ ^ ^R0: EQU 0 ;DRIVE 0 SELECT ; ; FUNCTION ASSIGNMENTS: ; BCDSN EQU BCDSA + BCDSB ;DRIVE MASK BCSDS EQU 0 ;SINGLE DENSITY BCEHOM: EQU 1 ;HOME ERROR BERDA: EQU 2 ;READ ERROR A BERDB: EQU 4 ;READ ERROR B ; ; DISK CONTROLLER MODULE (DCM) LINKAGE OR LENGTH FIELD SELECT (SEE MANUAL) ; | | (SHOULD BE 1 FOR IBM STANDARD) ; | |_______________ 1: READ MULTIP0100000B ;MOTOR OFF INDICATOR BSTSD EQU 01000000B ;2 SIDED DRIVE FLAG BSDCN EQU 10000000B ;DISK CHANGE ;=================== ^___ 1: BUSY, 0: DONE ; | | | | | | |______ 1: INDEX, 0: NOT INDEX ; | | | | | |_________ 1: TRACK 00, 0: NOT TDDS EQU BCDDE ;DOUBLE DENSITY BCPCH EQU BCPCA ;PRECOMP HEAVY BCPCM EQU BCPCB ;PRECOMP MEDIUM BCPCL EQU BCPCA + BCPCB ;PREC ; DCMSS: EQU 4 ;1ST DCM SECTOR DCMBG: EQU BANK1+3 ;DCM COLD START ENTRY DCMLN: EQU 1024 ;DCM LENGTH ;===============LE SECTORS, 0: NOT ; |__________________ 1: WRITE, 0: READ COMMAND ; DCRDS EQU 10001000B ;READ SECTOR DCRMSº EQÕ 1001========================================================= BLCTL: EQU 0 ;BOARD LEVEL CONTROL PORT ; ; |PCB|PCA|DAS|DDE|EIA|DSERACK 00 ; | | | | |____________ 1: CRC ERROR IN ID FIELD ; | | | |_______________ 1: TRACK SEEK VERIFY ERROR, 0: VERIOMP LIGHT BCPCZ EQU 0 ;PRECOMP OFF ;============================================================================ WDCMD: EQ============================================================= ; ; PORTS ; ;===============================================1000Â ;REAÄ MULIPLÅ RECORDS DCWRS EQU 10101000B ;WRITE SECTOR ; ; ; TYPE III COMMANDS: ; 7 0 ; |1 |1 | | |0 |E |0 |0 |DSB|DSA| ; \_____/ ^ ^ ^ ^ \_____/ ; | | | | | |______ DRIVE SELECT ADDRESS (0..3) ; | | FY OK ; | | |__________________ 1: HEAD LOADED, 0: HEAD UNLOADED ; | |_____________________ 1: DISK WRITE PROTECTED, 0: UU 4 ;179X COMMAND REGISTER ; ; TYPE I COMMANDS: ; 7 0 ; |0 | | |U |H |V |R1|R2| ; \___/ ^ ^ ^ \___/ ; ============================= BLSTS: EQU 0 ;BOARD LEVEL STATUS PORT ; ; D7 D0 ; |DCN|2SD|MOF|EIA|INT|TST|US1|US0| | ; \___/ ^_________ 1: HEAD LOAD DELAY, 0: NO DELAY ; |________________ COMMAND: ; 00: READ ADDRESS 01: NOT U | | |____________ DRIVE SELECT & FDC NMI ENABLE ; | | | |________________ EIA OUTPUT PORT ; | | |_NPROTECTED ; |________________________ 1: DRIVE NOT READY, 0: DRIVE READY ; CSDNR EQU 10000000B ;DRIVE NOT READY CSWRP EQU | | | | |___ STEP RATE (SEE DATA SHEET) ; | | | |________ 1: VERIFY TRACK AFTER SEEK, 0: NO VERIFY ; | ; ^ ^ ^ ^ ^ ^ ^ ^_____ 1: 179X DATA INVERT ; | | | | | | |_________ 1: USER SWITCH 1 (SPARE) ; SED ; 10: READ TRACK 11: WRITE TRACK ; DCRDA EQU 11000000B ;READ TRACK ADDR DCWRT EQU 11110000B ;WRITE TRACK FORMAT ;___________________ DOUBLE DENSITY ENABLE ; | |________________________ DIRECTION & SIDE SELECT ; | 1: IN/SID01000000B ;WRITE PROTECTED CSHLD EQU 00100000B ;HEAD LOADED CSSKE EQU 00010000B ;SEEK ERROR CSCRC EQU 00001000B ;CRC ERROR C | |___________ 1: LOAD HEAD, 0: UNLOAD HEAD ; | |______________ 1: UPDATE TRACK REGISTER, 0: NO UPDATE ; |___ | | | | | |_____________ 0: TEST MODE ; | | | | |_________________ 0: HOST INTERRUPT REQUEST ; | |  ; ; TYPE IV COMMANDS: ; 7 0 ; |1 |1 |0 |1 |I3|I2|I1|I0| ; ^ ^ ^ ^___ 1: INTERRUPT ON LOW-TO-HIGH READY ; E 1, 0: OUT/SIDE 0 ; |______________________________ PRECOMP SELECT (0..3) ; ; THE FOLLOWING ASSIGNS EACH BIT POSITION STK0 EQU 00000100B ;TRACK 0 CSINDX EQU 00000010B ;INDEX CSBSY EQU 00000001B ;BUSY ; ; ; TYPE II & III COMMAND RESULTS ; 7_______________ COMMAND: ; 00: RESTORE & SEEK 01: STEP AS LAST ; 10: STEP IN 11: STEP OUT ; DCHDL: EQU 00011000B | |_____________________ 1: EIA PORT INPUT ; | | |_________________________ 1: MOTOR OFF ; | |____________________ | | |______ 1: INTERRUPT ON HIGH-TO-LOW READY ; | |_________ 1: INTERRUPT ON NEXT INDEX PULSE ; |____________ & FUNCTION OF THE ; BOARD CONTROL PORT (BLCTL). ; BCDSA EQU 00000001B ;DRIVE SELECT A (2^0) BCDSB EQU 00000010B ;DRIVE SEL 0 ; |NR|WP|WF|NF|CE|LD|RQ|BY| ; ^ ^ ^ ^ ^ ^ ^ ^___ 1: BUSY, 0: DONE ; | | | | | | |______ 1: XFER DATA, 0: ;LOAD HEAD DCHDU EQU 00010000B ;HEAD UNLOAD ; ; ; TYPE II COMMANDS: ; 7 0 ; |1 |0 |WT|M |F2|E |F1|A0| ; ^ ^ _________ 0: 2 SIDED DRIVE ; |_________________________________ 0: DISK CHANGE FLAG ; ; THE FOLLOWING DEFINES EACH BIT & FU 1: INTERRUPT IMMEDIATELY ; DCSTS: EQU 11010000B ;TERMINATE OPERATION & READ TYPE 1 STATUS DCIFI EQU 11011000B ;FORCED INTERRECT B (2^1) BCDSE EQU 00000100B ;DRIVE SELECT ENABLE BCEIA EQU 00001000B ;EIA SIGNAL OUT BCDDE EQU 00010000B ;DOUBLE DENSITY 0 ( ) *!+",#-$.%/ &0 'NOT READY TO XFER DATA ; | | | | | |_________ 1: LOST DATA XFER, 0: XFER OK ; | | | | |____________ 1: CRC ERROR INå========================= WDDTA EQU WDCMD + 3 ;179X DATA REGISTER ;=========================================================ber of selected DD card */ int i, d, j, c; struct cb { unsigned char dd_cmd; /* command */ unsigned char dd_drv;å ID FIELD ; | | | |_______________ 1: RECORD NOT FOUND, 0: XFER OK ; | | |__________________ 1: READ- DELETED DATA, WRIå=================== XPSTP: EQU 8H ;STEP PULSE GENERATOR ; (DATA = DON'T CARE) ;=========================================== /* drive */ unsigned dd_trk; /* track */ unsigned dd_sec; /* sector */ unsigned char dd_ffg; /* flags */ unsigned dd_åTE- WRITE FAULT ; | |_____________________ 1: DISK WRITE PROTECTED, 0: UNPROTECTED ; |________________________ 1: DRIVE NOTå================================= XPMTO: EQU 10H ;MOTOR OFF GENERATOR ; (DATA = DON'T CARE) ;=============================dma; /* Unused dma address */ unsigned char dd_dmax;/* Unused dma extended address */ unsigned char dd_sts; /* Controller stå READY, 0: DRIVE READY ; ; SAME AS TYPE I COMMANDS EXCEPT: CSTYPE EQU 00100000B ;RECORD TYPE CSWFLT EQU 00100000B ;WRITE FAU/**************************************************************************** Jade Double D floppy controller test/exercisor=============================================== XPIRR EQU 20H ;RESET HOST INTERRUPT REQUEST FF ; (DATA = DON'T CARE) ;====atus */ unsigned char dd_st1; /* fdc status if dd_mod == 0x1f */ unsigned char dd_st2; /* returned value #1 */ unsigned chåLT CSRNF EQU 00010000B ;RECORD NOT FOUND CSLDE EQU 00000100B ;LOST DATA ERR CSDRQ EQU 00000010B ;DATA REQUEST ; ; DISK ST program ***************************************************************************** Revisions: 1.0 - 26 Nov 85 gr======================================================================== XPMTX: EQU 40H ;MOTOR ON GENERATOR ; (DATA = DON'T Car dd_st3; /* returned value #2 */ unsigned char dd_st4; /* returned value #3 */ unsigned char dd_st5; /* returned value #4 åATUS MASKS ; DMRER EQU CSDNR+CSRNF+CSCRC+CSLDE+CSBSY ;READ ERROR TEST MASK DMWER EQU CSDNR+CSWRP+CSWFLT+CSRNF+CSCRC+CSLDE+CSBh Release ****************************************************************************/ #include stdio.h #include ctypeARE) ;============================================================================ XPDSH: EQU 80H ;DATA SYNC HOLD ; (DATA */ } cmd_blk; /**************************************************************************** main program ***åSY ;WRITE ERROR TEST DMFER EQU CSDNR+CSWRP+CSWFLT+CSLDE ;FORMAT ERROR TEST DMTK0 EQU CSTK0 ;TRACK 0 TEST DMHDL EQU CSHLD ;H.h #define TRUE -1 #define FALSE 0 unsigned char in(); char sec_buf[2048], /* Sector buffer */ fmt_buf[] = {0x55,0xa= DON'T CARE) *************************************************************************/ main () { puts("\nJade Double D Controller ExeåEAD LOAD TEST DMDNR EQU CSDNR ;DRIVE NOT READY DMLDE EQU CSLDE ;LOST DATA ERR ;==========================================a,0x24,0,0x21,0x10,0x80,0x11, 0x80,0x83,1,0x14,0,0xed,0xb0,0xc9, 'H','e','l','l','o',' ','W','o','r','l','d','!'årcisor Vers. 1.0\n"); help(); /* Display the command list */ dd_port = 0x40; /* Initialize port & data area */ å================================== WDTRK EQU WDCMD + 1 ;179X TRACK REGISTER ;===============================================,0,0,0}, *cptr, /* Ptr to command block array elements */ *gets(), /* Tell cc that this is a char ptr */ tbuf[80]; /*å dd_addr = sec_buf; /* One = the other */ while (TRUE) { crlf(); printf("-"); gets(tbuf); switå============================= WDSEC EQU WDCMD + 2 ;179X SECTOR REGISTER ;=================================================== Input buffer */ unsigned atob(), atoh(), a, dd_addr, /* Location of selected DD window */ dd_port; /* I/O port numå0 ( ) *!+",#-$.%/ &0 'ch (c = toupper(tbuf[0])) { case 'X': /* Exit to DOS */ exit(0); break; case 'H': /* Display  gets(tbuf); if (tbuf[0] != '\0') *cptr = atoi(tbuf); cptr++; printf("Enter data tracks sectors per track {1..48}: "rocessor */ wait_dd(); get_cdb(); dmp_cdb(); dd_dump(); break; case '0': /* Log on drive */ cmd_bl (tbuf[0] != '\0') { i = -1; a = atoi(tbuf); cmd_blk.dd_st2 = a & 0xff; cmd_blk.dd_st3 = a >> 8; } pr cmd_blk.dd_cmd = 6; dd_exec(); printf("\nEIA bit = %s", (cmd_blk.dd_st2 & 1) ? "TRUE" : "FALSE"); break; case '7help message */ help(); break; case 'Q': /* Dump the DD ram */ printf("\nEnter start address (Hex) - "); gets(t); gets(tbuf); if (tbuf[0] != '\0') *cptr = atoi(tbuf); cmd_blk.dd_ffg = 0; /* Set parameters */ dd_exec(); break;k.dd_cmd = 0; if (get_drive()) break; dd_exec(); break; case '1': /* Read sector */ cmd_blk.dd_intf("Enter motor start delay: "); gets(tbuf); if (tbuf[0] != '\0') { i = -1; a = atoi(tbuf); cmd_blk.dd_st': /* Idle */ cmd_blk.dd_cmd = 7; dd_exec(); break; case '8': /* Return firmware version */ cmd_blk.dd_cmd = 8;buf); i = atoh(tbuf); if (i < 0) break; while (i < 2048) { dump_16(i); i += 16; if ((i % 256) == 0) case 'A': /* Load head & idle */ cmd_blk.dd_cmd = 10; if (get_drive()) break; dd_exec(); break; case 'Bcmd = 1; if (get_drive()) break; if (get_sec_trk()) break; dd_exec(); break; case '2': /* Write sect4 = a & 0xff; cmd_blk.dd_st5 = a >> 8; } cmd_blk.dd_ffg = 0; /* Set parameters */ if (i) dd_exec(); break;  dd_exec(); printf("\nFirmware version = %c.%c", (cmd_blk.dd_st3 & 0xff) + '0', (cmd_blk.dd_st2 & 0xff) + '0'); b if (*gets(tbuf) != '\0') { printf("\n%c\n", *tbuf); break; } } break; case 'Z': /* Dump the s': /* Seek track */ cmd_blk.dd_cmd = 11; if (get_drive()) break; if (get_trk()) break; dd_exec(); break; or */ cmd_blk.dd_cmd = 2; if (get_drive()) break; if (get_sec_trk()) break; dd_exec(); break; case '3':  case 'D': /* Return drive status */ cmd_blk.dd_cmd = 13; if (get_drive()) break; dd_exec(); printf("\nBoard lereak; case '9': /* Set disk flags/sectors per track */ cmd_blk.dd_cmd = 9; if (get_drive()) break; cmd_blk.dd_ffector buffer */ for (i=0x400; i < 2048;) { dump_16(i); i += 16; if ((i % 256) == 0) if (*gets(tbuf) != '\0' case 'C': /* Set drive parameters */ cmd_blk.dd_cmd = 12; if (get_drive()) break; cmd_blk.dd_ffg = -1; /* Display cu/* Format track */ cmd_blk.dd_cmd = 3; if (get_drive()) break; fmt_buf[2] = sizeof (fmt_buf); for (a=0, i=0; i < (vel status= "); for (i=0, j=cmd_blk.dd_st2; i<8; i++, j = j << 1) { printf("%c", (j & 0x80) ? '1' : '0'); } brg = 0xff; /* Display current data */ dd_exec(); printf("\nFlags T0 T1 DT\n"); for (i=0, j=cmd_blk.dd_st2; i<8; i+) break; } break; case 'P': /* Display ports from 0x40..0x43 */ for (i=0; i < 4; i++) { c = in(0x40 + irrent parameters */ dd_exec(); printf("\n\ Head engage time= %5d Step interval= %5d\n\ Time after last step= %5d (sizeof (fmt_buf)) - 1); i++) a += fmt_buf[i]; fmt_buf[sizeof (fmt_buf) - 1] = (-a); out(dd_port, 1); movmem(fmt_buf,eak; case 'E': /* Set/return baud rate */ cmd_blk.dd_cmd = 14; cmd_blk.dd_st5 = 0xff; dd_exec(); printf("\n\ +, j = j << 1) { printf("%c", (j & 0x80) ? '1' : '0'); } printf(" %2d %2d %2d", cmd_blk.dd_st3, cmd_blk.dd_st4,); if (c != 0xff) printf("\nA Controller responds to port: %02xH", 0x40+i); } case 'S': /* Set controMotor start delay= %5d", cmd_blk.dd_trk, cmd_blk.dd_sec, cmd_blk.dd_st2 + cmd_blk.dd_st3 * 256, cmd_blk.dd_st4 + cmd_blk.dd_st dd_addr, sizeof (fmt_buf)); out(dd_port,0); for (i=0, a=0; i 0x43 || dd_port < 0x40) printf("Illegal port!"); c = in(dd_port); dd_addr = (((c & 0x0e) << 1) | 0xe0) <) { i = -1; cmd_blk.dd_trk = atoi(tbuf); } printf("Enter Step interval: "); gets(tbuf); if (tbuf[0] !=break; dd_exec(); break; case '5': /* EIA output */ cmd_blk.dd_cmd = 5; printf("\nEnter character to outdd_st5 = atoi(tbuf); dd_exec(); } break; default: /* Command error */ printf("\nCommand Error!\n"); br gets(tbuf); if (tbuf[0] != '\0') *cptr = atoi(tbuf); cptr++; printf("Enter track 1 sectors per track {1..48}: "); < 8; printf("DD Window at %04xH",dd_addr); break; case 'T': /* Run diagnostics */ out(dd_port,0x80); /* reset dd p '\0') { i = -1; cmd_blk.dd_sec = atoi(tbuf); } printf("Enter time after last step: "); gets(tbuf); ifput to EIA port: "); gets(tbuf); cmd_blk.dd_st5 = tbuf[0]; dd_exec(); break; case '6': /* EIA input/status */ 0 ( ) *!+",#-$.%/ &0 'eak; } } } /**************************************************************************** Displayf("\nSector error!"); return TRUE;} cmd_blk.dd_sec = d; printf("Enter Side {0,1}: "); gets(tbuf); d = atoi(tbuf) out(dd_port,1); /* Fetch DD window */ movmem(dd_addr,sec_buf,1024); /* Move the window */ out(dd_port,3); /* Fe************************************************************* Convert ASCII to binary returns value ***************f("\n\ Cmd Drv Trk Sec Flg Sts St1 St2 St3 St4 St5\n\ %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",\ cmd help message ****************************************************************************/ help() { printf("\nCommand; if (d < 0 || d > 1) {printf("\nSide Error!"); return TRUE;} cmd_blk.dd_sec += (d == 0) ? 0 : 0x80; get_trk(); tch 2nd window */ movmem(dd_addr,&sec_buf[1024],1024); out(dd_port,1); /* Restore DD */ out(dd_port,0); } *************************************************************/ unsigned atob(p) char *p;{ unsigned a; for (a=0; (*p_blk.dd_cmd, cmd_blk.dd_drv, cmd_blk.dd_trk, cmd_blk.dd_sec, cmd_blk.dd_ffg, cmd_blk.dd_sts, cmd_blk.dd_st1, cmd_blk.dd_ss:\n\ H- Help X- Exit to DOS\n\ Q- Dump the entire RAM Z- Dump the sector buffer\n\ P- Find the po } /**************************************************************************** Get track info from user return /**************************************************************************** Execute the command ******************** == '0' || *p == '1');) a = (a << 1) + (*p++ - '0'); return a; } /***********************************************t2, cmd_blk.dd_st3, cmd_blk.dd_st4, cmd_blk.dd_st5); } /************************************************************rts S- Set the port\n\ T- Run diagnostics\n\ 0- Log on drive 8- Return firmware version\n\ 1- Read ses TRUE if error, FALSE if ok ****************************************************************************/ int get_trk() { ********************************************************/ dd_exec() { int i; out(dd_port,1); movmem(&cmd_blk,dd_a***************************** Convert ASCII to hex number returns value *********************************************************** Get drive from user returns TRUE if error, FALSE if ok *******************************************ctor 9- Set disk flags/sectors per track\n\ 2- Write sector A- Load head & idle\n\ 3- Format track  int d; printf("\nEnter track number {0..76}: "); gets(tbuf); d = atoi(tbuf); if (d > 76) {printf("\nTrackddr + 0x370, sizeof (cmd_blk)); out(dd_port,2); wait_dd(); get_cdb(); dmp_cdb(); dd_dump(); } /*************************************/ unsigned atoh(p) char *p; { unsigned a; for (a = 0; (isdigit(*p) || (*p >= 'A' &*********************************/ int get_drive() { int d; printf("\nEnter drive number {0..3}: "); gets(tbuf);  B- Seek track\n\ 4- Read address C- Set/return drive params\n\ 5- EIA output D- Retur error!"); return TRUE;} cmd_blk.dd_trk = d; return FALSE; } /********************************************************************************************************************** Get command block from controller *************& *p <= 'F'));) { a = a << 4; if (*p > '9') a += (*p++ - '7'); else a += (*p++ - '0'); } ret d = atoi(tbuf); if (d > 3) {printf("\nDrive error!"); return TRUE;} cmd_blk.dd_drv = d; return FALSE; n drive status\n\ 6- EIA input E- Set EIA baud rate\n\ 7- Idle\n"); } /************************************************************ Wait a specific time for controller completion returns TRUE if timeout, FALSE if no time***************************************************************/ get_cdb() { out(dd_port,1); movmem(dd_addr + 0x370, &curn a; } /**************************************************************************** Dump a line of buffer data } /**************************************************************************** Get sector & track info from user r********************************************** new line ***************************************************************out (normal) ****************************************************************************/ int wait_dd() { unsigned i; md_blk, sizeof (cmd_blk)); out(dd_port,0); if (cmd_blk.dd_sts != 0) printf("\n**** ERROR! **** -> %2x - %2x\n",to console in Hex - ASCII output format is argument = offset address of sector buffereturns TRUE if error, FALSE if ok ****************************************************************************/ int get_sec_*************/ crlf() { printf("\n"); } /************************************************************************* for (i=0; i < 40000; i++) if ((in(dd_port) & 1) == 0) break; if (i == 40000) { printf("\nController timeout! cmd_blk.dd_sts, cmd_blk.dd_st1); } /****************************************************************************  {0..size} ("address" of format) ****************************************************************************/ dump_16(addr)trk() { int d; printf("\nEnter sector number {1..48}: "); gets(tbuf); d = atoi(tbuf); if (d > 48) {print*** Dump Jade controller ram ****************************************************************************/ dd_dump() {"); return TRUE; } printf("\nExecution time = %4u of 40000", i); return FALSE; } /*************** Dump command block ****************************************************************************/ dmp_cdb() { print0 ( ) *!+",#-$.%/ &0 ' char *addr; { int j; for (j=0; j < 16; j++) { if (j == 0) printf("\n%04x: ",addr); printf("%02x ", CK IDSPTDO DS 1 ;DATA TRACKS SECTORS PER TRACK IDFEND DS 0 ENDM IDFSIZE EQU IDFEND - IDDFFO ;SIZE OF FORMAT DATA ; ; DIååISKS ; ;=========================================================================== ; IDLBLO EQU 0 ;JADE ID LABEL OFFSET 'Jasec_buf[addr + j]); } for (j=0; j < 16; j++) { c = sec_buf[addr + j] & 0x7f; if (c >= ' ' && c < 0x7f) SK FORMAT FLAGS DEFINITION ; ; 7 0 ; | | | |0| | | | | ; \___/^ ^ ^ ^ ^__ TRACK 0 DENSITY= 0:SINGLE, 1:DOUBLE ; | | ååde DD ' ; DS 3 ;ALLOW A JUMP VECTOR FOR THOSE MACHINES THAT NEED IT ; ; DISK DESCRIPTOR SECTOR TEXT KEY ; STRUCT 3 ID printf("%c", c); else printf("."); } }  | | |____ TRACK 1 DENSITY= 0:SINGLE, 1:DOUBLE ; | | | |______ DATA TRACKS DENSITY= 0:SINGLE, 1:DOUBLE ; | | |______ååLABO DS 20H - 3 ;'Disk Descriptor Sector' ENDM ; ; CP/M DISK PARAMETER BLOCK (DPB) DATA (MOVED TO CP/M BIOS AT LOG-ON) ; å__ SIDES= 0:SINGLE SIDED, 1:DOUBLE SIDED ; | |____________ DISK TYPE= 0:FLOPPY DISK, 1:HARD DISK ; |_______________ SECTOååIDDPBO EQU 20H ;DD ID SECTOR DPB DATA OFFSET STRUCT IDDPBO IDSPTO DS 2 ;SECTORS PER TRACK IDBSHO DS 1 ;BLOCK SHIFT FACTOR IåR SIZE BITS= 00:128, 01:256, 10:512, 11:1024 ; ; DRIVE FLAGS BIT #S DFT0DB EQU 0 DFT1DB EQU 1 DFDTDB EQU 2 DFTSDB EQU 3 ååDBLMO DS 1 ;BLOCK MASK IDEXMO DS 1 ;EXTENT MASK IDDSMO DS 2 ;DISK STORAGE SIZE -1 IDDRMO DS 2 ;DIRECTORY MAXIMUM IDAL0O DS 1å DFHARDB EQU 5 DFDBLB EQU 6 DFDBL1B EQU 7 åå ;DIRECTORY CLUSTER ALLOCATION 0 IDAL1O DS 1 ;DIRECTORY CLUSTER ALLOCATION 1 (0 CONTINUED) IDCKSO DS 2 ;DIRECTORY CHECKSUMS SIåå;**************************************************************************** ; ; JADE FORMAT DISK DEFINITIONS ; ;**********åZE IDOFFO DS 2 ;DIRECTORY TRACK OFFSET (RESERVED TRACKS CNT) IDEND DS 0 ENDM IDDPBSZ EQU IDEND - IDDPBO ;SIZE OF THIS STRUCåå****************************************************************** ; ; REVISIONS: ; ; 1.0 - 31 OCT 85 GRH ; RELEASE ; ;åTURE ; ; DISK FORMAT FLAGS ; IDDFFO EQU 30H STRUCT IDDFFO ;OFFSET TO DISK FORMAT PARAMETERS IDSTGO DS 1 ;SECTOR STAGGEåå**************************************************************************** ;=============================================åR BYTE (NOT USED) IDFLGO DS 1 ;DRIVE FLAGS BYTE IDSPT0O DS 1 ;TRACK 0 SECTORS PER TRACK IDSPT1O DS 1 ;TRACK 1 SECTORS PER TRAåå============================== ; ; JADE FORMAT DISK DESCRIPTOR SECTOR ; THIS SECTOR IS SECTOR 1, TRACK 0 OF FLOPPY AND HARD D0 ( ) *!+",#-$.%/ &0 ' SUBTTL DOUBLE D SYSTEM CONFIGURATION DEFINITIONS ;****************************************************************************0 ;DDADR: WORD X ;DDBSZ: WORD X ; ; FORMAT TRACK COMMAND ; DDFMT EQU 3 ;FORMAT TRACK (EXECUTE DDMB1 + 8) ;DDCMD BYTE 3=================================== ; ; PAGE 0 LOCATIONS COMPATIBLE WITH CP/M ; DADDR: EQU 0040H ;DISK WINDOW PTR IN PAGE ; ; TRANSFER BUFFER OFFSET TO DDBASE ; DDBUFO EQU 380H ;DD SECTOR BUFFER OFFSET ;============================ ; ; PARAMETERS ; DDLOG EQU 0 ;LOG ON DISK ;DDCMD BYTE 0 ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE WILL BE SET TO 0 BY COMMAN ; ; THIS INCLUDE MODULE DEFINES THE SYSTEM TO BOARD LEVEL ; PARAMETERS FOR THE JADE DOUBLE D DISK CONTROLLER. IT SHOULD BE  ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE TRACK NUMBER {0..76} ;DDSEC BYTE DISK FLAGS TO STORE INTO (DRIVE_TABLE[DVFLG])  0 DMASK EQU DADDR + 2 ;STATUS HALT BIT MASK FOR BIOS DTEMP EQU DMASK + 1 ;NOT IMPLEMENTED, BUT RESERVED ; DDBASE: EQU 0E000 DOUBLE D COMMAND PORT ; ;============================ DDPORT: EQU 43H ;DOUBLE D PORT ADDR ; ; D7 D0 ; |BGN| X D ;DDSEC BYTE WILL BE SET TO 1 BY COMMAND ;DDFFG BYTE RETURNED DISK DESCRIPTOR SECTOR STATUS ; 0: NOT FOUND ; !0: BUFFER  ; INCLUDED AS DEFINITIONS WHENEVER THE BOARD IS DIRECTLY INTERFACED ; TO BY A SOFTWARE MODULE. ; ;************************;DDFFG BYTE X ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUS IF DDMOD <> 0 ;DDADR: WORD X H ;DD WINDOW BASE ADDR (ADDED TO STATUS BITS) ;======================================================= ; ; SYSTEM TO C| X | X | X | X |MB1|MB0| ; ^ ^ ^_____ 0: REMOVE MEMORY BANK FROM HOST ; | | 1: ENABLE MEMORY BANK TO HOST CONTAINS VALID DISK DESCRIPTOR SECTOR DATA ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUS IF**************************************************** ; ; REVISIONS: ; ; 1.0 19 JUL 82 ; RELEASE ; ; 1.1 14 FEB 83 ; CH;DDBSZ: WORD RETURNED NUMBER OF BYTES FROM LAST SECTOR TO INDEX DDFBFO EQU 300H ;DD FORMAT BUFFER OFFSET (BANK 1) ; ; READONTROLLER COMMUNICATION BLOCK (IOPB) ; ;======================================================= DDCBO EQU 370H ;DCM COMMAND & ; | | GENERATE PROCESSOR INTERRUPT ; | |_________ 0: SELECT 1K MEMORY BANK 0 ; | 1: SELECT 1K MEMORY DDMOD <> 0 ;DDADR: WORD X ;DDBSZ: WORD X ; ; READ SECTOR COMMAND ; DDRDS EQU 1 ;READ SECTOR INTO DDBUF ;DDCMD BYTE 1 ANGED TO REFLECT REV C BOARD HARDWARE CHANGES: ; MA10 IN STATUS PORT BIT 1 & DELETION OF MEMORY ACKNOWLEDGE BIT 0 ; IN STA ADDRESS COMMAND (NOT IMPLEMENTED) ; DDRDA EQU 4 ;READ ADDRESS ; ; EIA OUTPUT COMMAND (NOT IMPLEMENTED) ; DDSP1 EQU 5 BLOCK OFFSET STRUCT 0 DDCMDO DS 1 ;COMMAND BYTE (SEE BELOW) DDDRVO DS 1 ;DRIVE DDTRKO DS 1 ;TRACK DDSECO DS 1 ;SECTOR (FOR BANK 1 ; |_________________________________ RESET BOARD PROCESSOR (1) ; ; ; COMMANDS (OUTPUT TO DDPORT) ; DDOUT: EQU  ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE TRACK NUMBER {0..76} ;DDSEC BYTE SECTOR NUMBER {1..26} ;DDFFG BYTE 80H FOR NO RETUS PORT & MOVE OF HALT FLAG FROM BIT 1 TO BIT 0 OF STATUS ; PORT. ; 1.2 - 23 OCT 83 GRH ; CLEANED UP, ADDED HEADER GRAPH;SPARE ; ; EIA STATUS COMMAND (NOT IMPLEMENTED) ; DDSP2 EQU 6 ;SPARE ; ; IDLE COMMAND (NOT IMPLEMENTED) ; DDIDL EQUMAT FLAGS) DDFFGO DS 1 ;FLAGS DDSPRO DS 1 ;SPARE DDMODO DS 1 ;ERROR CODE: ; 0: NONE ; -1= COMMAND ERROR ; -2= FDC0 ;REMOVE DD WINDOW FROM SYSTEM DDBGN: EQU 10000000B ;RESET DD Z80A DDMRQ: EQU 00000001B ;REQUEST MEMORY BANK 0 WINDOW DDMRTTRYS DDNRT EQU 10000000B ;INHIBIT RETRYS FLAG ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUICS ; ; 1.3 - 7 JUN 85 GRH ; Added Jade format disk descriptor sector definitions. ; ; 1.4 - 29 OCT 85 GRH ; Changed d 7 ;IDLE- WAIT FOR HOST INT., THEN HALT ;DDCMD BYTE 4..255 ;DDDRV BYTE X ;DDTRK BYTE X ;DDSEC BYTE X ;DDFFG BYTE X ;DDSPR ERROR (DDSTS= FDC STATUS) ; THE FOLLOWING ERRORS ON BOOT ONLY: ; 1= HOME ERR ; 2= READ ERR A ; 4= READ ERR B: EQU 00000000B ;RELEASE MEMORY WINDOW DDMB0: EQU 00000001B ;SELECT MEMORY BANK 0 DDMB1: EQU 00000011B ;SELECT MEMORY BANK 1 S IF DDMOD <> 0 ;DDADR: WORD X ;DDBSZ: WORD X ; ; WRITE SECTOR COMMAND ; DDWRS EQU 2 ;WRITE SECTOR FROM DDBUF ;DDCMD Bisk descriptor sector format to new format. ; Clarified communication block commands. ; Added hook for log-on return of valid  BYTE X ;DDMOD BYTE CMDERR ;NOT IMPLEMENTED, COMMAND ERROR ;DDSTS BYTE X ;DDADR WORD X ;DDBSZ WORD X ; ; COMMAND ERROR C ; 80H= DRIVE NOT READY DDSTSO DS 1 ;DISK CONTROLLER STATUS (SEE 179X MAN'L) DDADRO DS 2 ;LOAD & JUMP ADDR ; FORMAT= DDEXC: EQU 00000010B ;ISSUE DD INTERRUPT (START) ;=========================================== ; ; STATUS PORT (SAME ADDYTE 2 ;DDDRV BYTE DRIVE NUMBER {0..3} ;DDTRK BYTE TRACK NUMBER {0..76} ;DDSEC BYTE SECTOR NUMBER {1..26} ;DDFFG BYTE 80H TO disk descriptor boolean. ; Removed disk format data & command block data definitions to JDDDISK ; ;**************************ODES (DDMODO OF COMMAND BLOCK ON RETURN) ; NOERR EQU 0 ;NO ERROR AFTER FUNCTION CMDERR EQU 20H ;INVALID COMMAND FROM HOST FD# OF PADDING BYTES UNTIL INDEX ; BOOT= START OF BOOT MODULE IN MAIN MEMORY DDBSZO DS 2 ;DCM BLOCK LOAD SIZE (SIZE OF BOOT MRESS AS DDPORT) ; ;=========================================== ; ; D7 D0 ; | X | X | X | X |S12|S11|S10|HLT| ; INHIBIT RETRYS (SEE READ SECTOR) ;DDSPR BYTE X ;DDMOD BYTE RETURNED ERROR CODE (0: NONE) ;DDSTS: BYTE FDC STATUS IF DDMOD <> ************************************************** ;====================================== ; ; HOST MEMORY AREAS ; ;===CERR EQU 1FH ;CONTROLLER ERROR (DDSTSO= FDC ERROR CODE) SELERR EQU 21H ;ILLEGAL DRIVE REQUESTED SEEKERR EQU 15H ;SEEK ERROR ODULE) ENDM ; ; COMMANDS (DDCMD OF COMMUNICATION BLOCK) ; ; LOGON COMMAND, READS DESCRIPTOR SECTOR & SETS DISK FORMAT 0 ( ) *!+",#-$.%/ &0 ' \_________/ ^_____ PROCESSOR HALT FLAG (0) ; |_____________ BOARD MEMORY ADDR SWITCH POS. ; DDSHLT: EQU 00000001B ;E EQU IDFEND - IDDFFO ;SIZE OF FORMAT DATA ; ; DISK FORMAT FLAGS DEFINITION ; ; 7 0 ; | | | |0| | | | | ; \___/^ ^ ^ ååISKS ; ;=========================================================================== ; ; DS 3 ;ALLOW A JUMP VECTOR FOR THOSE STATUS PORT HALT FLAG, 0= HALT, 1= BUSY DDSASW: EQU 00001110B ;STATUS PORT ADDR SW MASK ^ ^__ TRACK 0 DENSITY= 0:SINGLE, 1:DOUBLE ; | | | | |____ TRACK 1 DENSITY= 0:SINGLE, 1:DOUBLE ; | | | |______ DATA TååMACHINES THAT NEED IT ; ; DISK DESCRIPTOR SECTOR TEXT KEY ; STRUCT 0 IDLBLO DS 20H - 3 ENDM ; ; CP/M DISK PARAMETERåRACKS DENSITY= 0:SINGLE, 1:DOUBLE ; | | |________ SIDES= 0:SINGLE SIDED, 1:DOUBLE SIDED ; | |____________ DISK TYPE= 0åå BLOCK (DPB) DATA (MOVED TO CP/M BIOS AT LOG-ON) ; IDDPBO EQU 20H ;DD ID SECTOR DPB DATA OFFSET STRUCT IDDPBO IDSPTO DS 2 ;å:FLOPPY DISK, 1:HARD DISK ; |_______________ SECTOR SIZE BITS= 00:128, 01:256, 10:512, 11:1024 ; ; DRIVE FLAGS BIT #S DFååSECTORS PER TRACK IDBSHO DS 1 ;BLOCK SHIFT FACTOR IDBLMO DS 1 ;BLOCK MASK IDEXMO DS 1 ;EXTENT MASK IDDSMO DS 2 ;DISK STORAGEåT0DB EQU 0 DFT1DB EQU 1 DFDTDB EQU 2 DFTSDB EQU 3 DFHARDB EQU 5 DFDBLB EQU 6 DFDBL1B EQU 7 åå SIZE -1 IDDRMO DS 2 ;DIRECTORY MAXIMUM IDAL0O DS 1 ;DIRECTORY CLUSTER ALLOCATION 0 IDAL1O DS 1 ;DIRECTORY CLUSTER ALLOCATIONåååå 1 (0 CONTINUED) IDCKSO DS 2 ;DIRECTORY CHECKSUMS SIZE IDOFFO DS 2 ;DIRECTORY TRACK OFFSET (RESERVED TRACKS CNT) IDEND DS 0 åå;**************************************************************************** ; ; JADE FORMAT DISK DEFINITIONS ; ;**********å ENDM IDDPBSZ EQU IDEND - IDDPBO ;SIZE OF THIS STRUCTURE ; ; DISK FORMAT FLAGS ; IDDFFO EQU 30H STRUCT IDDFFO ;OFFSET åå****************************************************************** ; ; REVISIONS: ; ; 1.0 - 31 OCT 85 GRH ; RELEASE ; ;åTO DISK FORMAT PARAMETERS IDSTGO DS 1 ;SECTOR STAGGER BYTE (NOT USED) IDFLGO DS 1 ;DRIVE FLAGS BYTE IDSPT0O DS 1 ;TRACK 0 SECåå**************************************************************************** ;=============================================åTORS PER TRACK IDSPT1O DS 1 ;TRACK 1 SECTORS PER TRACK IDSPTDO DS 1 ;DATA TRACKS SECTORS PER TRACK IDFEND DS 0 ENDM IDFSIZåå============================== ; ; JADE FORMAT DISK DESCRIPTOR SECTOR ; THIS SECTOR IS SECTOR 1, TRACK 0 OF FLOPPY AND HARD D0 ( ) *!+",#-$.%/ &0 ' SUBTTL INTERNAL DISK CONTROLLER DEFINITIONS ;**************************************************************************** ; _______ DRIVE SELECT ENABLE ; | | | |________________ EIA OUTPUT PORT ; | | |____________________ DOUBLEUP DELAY (100US) (DCM) TMPLD EQU 1200 ;PHASE LOCK RECOVERY (100US) (DCM) TMSAW EQU 10 ;STEP AFTER WRITING (100US) (DCM) ;  BIT SET FOR ; 1791..4 CHIPS, HOWEVER THE SIDE CHECK ENABLE BIT IS FALSE, SO IT ; BECOMES A DON'T CARE. THIS IS NEEDED FOR C ^ ^ ^_____ 179X DATA INVERT (1) ; | | | | | | |_________ USER SWITCH 1 (SPARE) ; | | | | | |_; INTERNAL BOARD LEVEL PARAMETERS INCLUDE MODULE FOR THE JADE ; DOUBLE D DISK CONTROLLER BOARD. INCLUDE THIS MODULE TO DEFINE  DENSITY ENABLE ; | |________________________ DIRECTION & SIDE SELECT ; | 1: IN/SIDE 1, 0: OUT/SIDE 0 ; ; TIMING CONSTANTS: ; TMRFC EQU 19H ;1ST PASS TMRNC EQU 1CH ;NORMAL PASS ; ; RETRY VALUES: ; RTYSK EQU 5 ;REPOSITIOMPATABILITY WITH THE 1795..7 ; CHIP, WHICH USES THE SIDE SELECT BIT FOR DETERMINING SECTOR SIZE & MUST ; BE A 1 FOR 128 BYT____________ TEST MODE (1) ; | | | | |_________________ HOST INTERRUPT REQUEST (1) ; | | | |________________ANY ; PARAMETERS WITH SOFTWARE TO EXECUTE ON THE BOARD'S Z-80 PROCESSOR. ; ;************************************************|______________________________ PRECOMP SELECT (0..3) ; ; THE FOLLOWING ASSIGNS EACH BIT POSITION & FUNCTION OF THE ; BOAON HEAD ON RETRY RTYLS EQU 9 ;LAST REPEATED RETRY ;======================================================================ES PER SECTOR. (0= 256 BYTES) ; DCRDS EQU 10001000B ;READ SECTOR DCRMSº EQÕ 10011000Â ;REAÄ MULIPLÅ RECORDS DCWRS EQU 101010_____ EIA PORT INPUT ; | | |_________________________ MOTOR OFF (1) ; | |_____________________________ 2 SIDED DRIVE**************************** ; ; REVISIONS: ; ; 1.0 - 19 JUL 82 ; RELEASE ; ; 1.1 - 14 FEB 83 ; MODIFIED FOR REV C BOARDRD CONTROL PORT (BLCTL). ; BCDSA EQU 00000001B ;DRIVE SELECT A (2^0) BCDSB EQU 00000010B ;DRIVE SELECT B (2^1) BCDSE EQU 000====== ; ; INTERNAL MEMORY ASSIGNMENTS ; ;============================================================================ BA00B ;WRITE SECTOR ; DCRDA EQU 11000000B ;READ TRACK ADDR DCSTS: EQU 11010000B ;TERMINATE OPERATION & READ TYPE 1 STATUS DCIF FLAG (1) ; |_________________________________ DISK CHANGE FLAG (1) ; ; THE FOLLOWING DEFINES EACH BIT & FUNCTION OF THE BO: ; CHANGED DEFINITIONS TO ALLOW FOR 1795/7 CHIP ; ; 1.2 - 23 OCT 83 GRH ; CLEANED UP, ADDED HEADER GRAPHICS ; ; 1.3 -00100B ;DRIVE SELECT ENABLE BCEIA EQU 00001000B ;EIA SIGNAL OUT BCDDE EQU 00010000B ;DOUBLE DENSITY ENABLE BCDAS EQU 00100000NKL: EQU 1024 ;1K BANK LENGTH BANK0: EQU 0 ;LOWER BANK BASE ADDR BANK1: EQU BANK0 + BANKL ;UPPER BANK BASE ADDR ; FMTBG EQI EQU 11011000B ;FORCED INTERRUPT - NOT USED DCWRT EQU 11110000B ;WRITE TRACK FORMAT ;======================================ARD ; STATUS PORT (BLSTS) BSUS0 EQU 00000001B ;USER SWITCH 0 - 179X INVERT BSUS1 EQU 00000010B ;USER SWITCH 1 - SPARE BSTST 30 OCT 85 GRH ; Rearranged definitions. Added double sided hooks. ; ;*****************************************************B ;DIRECTION & SIDE BCPCA EQU 01000000B ;PRECOMP SELECT A BCPCB EQU 10000000B ;PRECOMP SELECT B BCDR0: EQU 0 ;DRIVE 0 SELECTU BANK1 + 300H ;FORMAT BUFFER FMTPS EQU FMTBG + 8 ;FORMAT START ADDR ; ; BOOTSTRAP COMMUNICATION ; BEHOM: EQU 1 ;HOME ER====================================== WDSTS: EQU 4 ;179X STATUS REGISTER ; ; STATUS BIT DEFINITIONS ; TYPE I: ; CSDNR EQU EQU 00000100B ;TEST MODE BSINT EQU 00001000B ;HOST INT REQ BSEIA EQU 00010000B ;EIA SIGNAL INPUT BSMOF EQU 00100000B ;MOTOR *********************** ;============================================================================ ; ; DISK DRIVE PARA ; ; FUNCTION ASSIGNMENTS: ; BCDSN EQU BCDSA + BCDSB ;DRIVE MASK BCSDS EQU 0 ;SINGLE DENSITY BCDDS EQU BCDDE ;DOUBLE DENROR BERDA: EQU 2 ;READ ERROR A BERDB: EQU 4 ;READ ERROR B ; ; DISK CONTROLLER MODULE (DCM) LINKAGE ; DCMSS: EQU 4 ;1S 10000000B ;DRIVE NOT READY CSWRP EQU 01000000B ;WRITE PROTECTED CSHLD EQU 00100000B ;HEAD LOADED CSSKE EQU 00010000B ;SEEK EOFF INDICATOR BSTSD EQU 01000000B ;2 SIDED DRIVE FLAG BSDCN EQU 10000000B ;DISK CHANGE ;===================================METERS ; ;============================================================================ TMSTP: EQU 8 ;STEPPER INTERVAL (ms) (SITY BCPCH EQU BCPCA ;PRECOMP HEAVY BCPCM EQU BCPCB ;PRECOMP MEDIUM BCPCL EQU BCPCA + BCPCB ;PRECOMP LIGHT BCPCZ EQU 0 ;PT DCM SECTOR DCMBG: EQU BANK1+3 ;DCM COLD START ENTRY DCMLN: EQU 1024 ;DCM LENGTH ;====================================RROR CSCRC EQU 00001000B ;CRC ERROR CSTK0 EQU 00000100B ;TRACK 0 CSINDX EQU 00000010B ;INDEX CSBSY EQU 00000001B ;BUSY ; ;========================================= BLCTL: EQU 0 ;BOARD LEVEL CONTROL PORT ; ; |PCB|PCA|DAS|DDE|EIA|DSE|DSB|DSA| ; \_BIM) TMSTPC EQU 80 ; " " (100US) (DCM) TMDBR: EQU 1 ;DELAY BEFORE READ (ms) (BIM) NBTRK: EQU 80 ;MAXIMUM # STEPSRECOMP OFF ;============================================================================ WDCMD: EQU 4 ;179X COMMAND REGISTER======================================== ; ; PORTS ; ;==================================================================== TYPE II & III ; CSTYPE EQU 00100000B ;RECORD TYPE CSWFLT EQU 00100000B ;WRITE FAULT CSRNF EQU 00010000B ;RECORD NOT FOUND ____/ ^ ^ ^ ^ \_____/ ; | | | | | |______ DRIVE SELECT ADDRESS (0..3) ; | | | | |_____ TMHLD EQU 350 ;HEAD ENGAGE TIME (100US) (DCM) TMALS EQU 80 ;DELAY AFTER LAST STEP (100US) (DCM) TMMTO EQU 1 ;MOTOR START  ; DCHDL: EQU 00011000B ;LOAD HEAD DCHDU EQU 00010000B ;HEAD UNLOAD ; ; THE READ & WRITE SECTOR CMDS NOW HAVE SIDE 1 SELECT======== BLSTS: EQU 0 ;BOARD LEVEL STATUS PORT ; ; D7 D0 ; |DCN|2SD|MOF|EIA|INT|TST|US1|US0| ; ^ ^ ^ ^ ^0 ( ) *!+",#-$.%/ &0 'CSLDE EQU 00000100B ;LOST DATA ERR CSDRQ EQU 00000010B ;DATA REQUEST ; ; DISK STATUS MASKS ; DMRER: EQU 10011101B ;READ EUMBER 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 ATA = DON'T CARE) ;============================================================================ XPDSH: EQU 80H ;DATA SYNC H JP INIT ;INITIALIZE $MEMRY DW CODEND ;PTR TO 1ST AVAILABLE BYTE OF MEMORY ; ; DRIVE LIMITS, USER CHANGABLE ; DRVLOved system track xfer. Superceeded by the new SYSGEN utility. ; Cleaned up for ASMB. ; Removed format system tracks only optioRROR TEST MASK DMWER EQU 11111101B ;WRITE ERROR TEST DMFER EQU 11100100B ;FORMAT ERROR TEST DMTK0: EQU 00000100B ;TRACK 0 TES;128 BYTES PER SECTOR IDSEC: EQU 1 ;ID SECTOR # ; ; INJECTION MODULE DEFINITIONS ; ZEROS: EQU 00000000B ;ALL ZEROS BOLD ; (DATA = DON'T CARE)  DB DRV1 - 'A' ;1ST DRIVE DRVHI DB DRVN - 'A' + 1 ;LAST DRIVE + 1 ; ; COPYRIGHT NOTICE ; SIGNON: DB 'Floppy disk format Un. Never worked! ; Added capability to double the directory size for disks with many ; small programs (such as libraries). ;T DMHDL EQU 00100000B ;HEAD LOAD TEST DMDNR EQU 10000000B ;DRIVE NOT READY DMLDE EQU 00000100B ;LOST DATA ERR ;===========YTE ONES: EQU 11111111B ;ALL ONES BYTE FMTSZ EQU 256 ;FORMAT INJECTION MODULE LENGTH ; ; BDOS CALL VECTORS ; WBOOT åtility Ver ' DB HIGH VERSN,'.',LOW VERSN,CR,LF DB 'Copyright (c) 1983 GRH Enterprises' DB '$' ; ; MAIN PROGRAM C ; 1.2 - 31 AUG 83 GRH ; Added 256 byte (IBM system 34 compatibility) sector formatting. ; Added sector read verification a================================================================= WDTRK: EQU 5 ;179X TRACK REGISTER ;======================EQU 0000H ;SYSTEM WARM BOOT BDOS: EQU 0005H ;SYSTEM CALL ADDR ; ; BIOS VECTOR DEFINITIONS ; SLDSKV: EQU 8 ;SELECT åONTINUES ; INIT: LD SP,(BDOS + 1) DEC SP DEC SP LD DE,SIGNON ;OUTPUT MESSAGE CALL MSGOT FUNBG: LD DE,MSGFL ;OUTPUfter format. ; ; 1.3 - 09 JUN 84 GRH ; Removed format vector from BIOS to this program. ; VERSN EQU '13' ;CHANGE HERE FOR====================================================== WDSEC: EQU 6 ;179X SECTOR REGISTER ;================================DISK OFFSET SETRKV: EQU 9 ;SET TRACK OFFSET SETSECV:EQU 10 ;SET SECTOR OFFSET SETMAV: EQU 11 ;SET ADDRESS OFFSET RDSECV: åT FUNCTION LIST CALL MSGOT CALL CNSIN ;GET CONSOLE CHAR CP '1' ;IF 1 THEN FORMAT DDEN JR Z,FUN1 CP '2' ;ELSE IF SIGN-ON CHANGE ; ;************************************************************* FALSE EQU 0 TRUE EQU NOT FALSE LSTINC EQU ============================================ WDDTA: EQU 7 ;179X DATA REGISTER ;============================================EQU 12 ;READ SECTOR OFFSET WRSECV: EQU 13 ;WRITE SECTOR OFFSET LOGVC: EQU 1 ;DRV SEL DON'T LOGON SUBTTL MACROS ;; ;å 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 2FALSE ; ; *INCLUDE JDDCONT.DEF ; *INCLUDE JDDLOC.DEF ; IF NOT LSTINC LIST OFF ENDIF *INCLUDE JDDCONT.DEF *INCLUDE JD================================ XPSTP: EQU 8H ;STEP PULSE GENERATOR ; (DATA = DON'T CARE) ;==============================; GENERATE THE TRANSLATE TABLE ;; GXLATE MACRO #SECTORS, #SKEW LIST NOGEN NXTSEC DL 1 ;;START WITH SECTOR 1 LOWEST DL 1  TITLE FORMAT UTILITY LIST NOCOND ;************************************************************* ; ; JADE DOUBLE D DISK F56 BYTE SECTORS JP Z,FUN4 LD DE,MSGSE ;ELSE OUTPUT ERROR MSG LD (LTRSE),A ;STORE BAD SYMBOL CALL MSGOT JR FUNBG ;DLOC.DEF LIST ON SUBTTL DECLARATIONS ; ; DRIVER MODULE DEFINITIONS ; CTRLC: EQU 3 ;REQUEST REBOOT CPM LF: EQU 0AH ============================================== XPMTO: EQU 10H ;MOTOR OFF GENERATOR ; (DATA = DON'T CARE) ;================ REPT #SECTORS ;;ONCE FOR EACH SECTOR LIST GEN DB NXTSEC LIST NOGEN NXTSEC DL NXTSEC + #SKEW ;;ADD IN SKEW FACTOR ORMAT PROGRAM ; ;************************************************************* ; ; Format is a system utility which providREPEAT ;---------------------------------------------------------- ; ; FUNCTION 1 - DOUBLE DENSITY FORMAT ; TRK 0= SIN ;LINE FEED CR: EQU 0DH ;CARRIAGE RETURN BS EQU 08H ;BACKSPACE REBOOT: EQU 0 ;REBOOT ADDR TPA: EQU 100H ;TRANSIENT PRO============================================================ XPIRR EQU 20H ;RESET HOST INTERRUPT REQUEST FF ; (DATA = DON'T C IF NXTSEC > #SECTORS ;;CHECK FOR OVERFLOW NXTSEC DL NXTSEC - #SECTORS IF NXTSEC <= LOWEST ;;CHECK FOR REPEAT NXTSEC DL Les a means to ; write a single or double density format on any of drives A ; through D. ; ;******************************GLE DENSITY ; TRK 1..76= DOUBLE DENSITY 128 BYTE SECTORS ; ;---------------------------------------------------------- FUN1:GRAM 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 NARE) ;============================================================================ XPMTX: EQU 40H ;MOTOR ON GENERATOR ; (DOWEST + 1 LOWEST DL NXTSEC ENDIF ENDIF ENDM ENDM SUBTTL MAIN PROGRAM ORG TPA ; ; PROGRAM ENTRY POINT ;******************************* ; ; REVISION STATUS: ; ; 1.0 - 8 FEB 81 GRH ; RELEASE ; ; 1.1 - 25 MAR 83 GRH ; Remo0 ( ) *!+",#-$.%/ &0 ' LD IX,IDSDD ;SET DEFAULT DIRECTORY SIZE LD A,(IX+DDFLG) ;SET FLAGS LD (FFLAG),A LD HL,DDSDIR CALL SELDR ;SELECT DR******** ; ; OUTPUT '*' SUBR ; ;******************************* TRKDONE: LD E,'*' ;******************************* S JR C,FUN2 ;ERR CALL TRKDONE LD A,TRK2 ;SET UP FOR TRACK 2 LD (TRKNO),A REPT2: CALL FMTSD ;FORMAT TRACK IN SDENS **************** FMTDD2: LD HL,FTJ26D ;USE 256 BYTE INJECTION MODULE STDMA: LD (BTDMA),HL ;SET PTR TO INJECTION MODULE LA,TRK0 ;SET TRACK # LD (TRKNO),A CALL FMTSD ;FORMAT TRACK SDENS CALL NC,WRTID ;WHILE WE'RE HERE, WRITE ID SECTOR JR IVE JR C,FUNBG ;ERR- RESELECT LD A,TRK0 ;SET TRACK # LD (TRKNO),A CALL FMTSD ;FORMAT TRACK SDENS CALL NC,WRTID ; ; CONSOLE OUTPUT SUBR ; ENTRY- E= CHAR ; ;******************************* CNSOT: LD C,2 ;CONSOLE OUTPUT FUNCTION # JP  JR C,FUN2 ;ERR CALL TRKDONE LD A,(TRKNO) CP TRK76 JR Z,DOCHK2 INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR RED A,(TRKNO) ;SET TRACK # SO BIOS IN SYNC WITH FORMAT LD C,A CALL SETTRK CALL FMTTRK ;FORMAT TRACK OR A ;IF NO ERR THC,FUN4 ;ERR CALL TRKDONE ;OUTPUT '*' LD A,TRK1 ;SET NEXT TRACK # LD (TRKNO),A REPT4: CALL FMTDD2 ;FORMAT TRACK IN;WHILE WE'RE HERE, WRITE ID SECTOR JR C,FUN1 ;ERR CALL TRKDONE ;OUTPUT '*' LD A,TRK1 ;SET NEXT TRACK # LD (TRKNO)BDOS ;*********************************************** ; ; WRITE ID SECTOR ; ENTRY- IX= PTR TO ID SECTOR IMAGE ; EXIT PT2 DOCHK2: CALL CHECK ;CHECK FOR READ ERRORS JR FUN2 ;READY FOR ANOTHER DISK ;-------------------------------------EN RETURN RET Z LD DE,MSGNC ;ELSE OUTPUT ERROR MSG CALL MSGOT SCF ;RETURN ERROR FLAG RET ;******************* DDENS JR C,FUN4 ;ERR CALL TRKDONE LD A,(TRKNO) ;IF LAST TRACK THEN DONE CP TRK76 JR Z,DOCHK4 INC A ;ELSE DO N,A REPT1: CALL FMTDD ;FORMAT TRACK IN DDENS JR C,FUN1 ;ERR CALL TRKDONE LD A,(TRKNO) ;IF LAST TRACK THEN DONE C- CF= ERROR ; ;*********************************************** WRTID: PUSH IX ;HL -> BC POP BC CALL SETDMA ;SET XFER - ; ; FUNCTION 3 - FORMAT IBM 3740 ; TRK 0..76= SINGLE DENSITY ; ;-------------------------------------- FUN3: LD A,0 ;***************************** ; ; SELECT DRIVE SUBR ; ENTRY- HL= DEFAULT DIR VALUES PTR ; IX= DPB PTR ; EXIT - CF= ERROREXT TRACK LD (TRKNO),A JR REPT4 DOCHK4: CALL CHECK ;CHECK FOR READ ERRORS JR FUN4 ;READY FOR ANOTHER DISK SUBP TRK76 JR Z,DOCHK1 INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT1 DOCHK1: CALL CHECK ;CHECK FOR READ ERRORS JADDR LD C,TRK0 ;SET TRACK 0 CALL SETTRK LD C,IDSEC ;SET ID SECTOR CALL SETSEC CALL WRSECT ;WRITE ID SECTOR 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 ; ;************************************************ SELDR: LD A,(FFLAG) ;IF FORMAT FLAG NOT 0 THEN OR A JR Z,REPTD TTL SUBROUTINES ;**************************************************** ; ; MESSAGE OUTPUT SUBR ; ENTRY- DE= PTR TO '$' TERMP FUN1 ;READY FOR ANOTHER DISK ;-------------------------------------------------- ; ; FUNCTION 2 - FORMAT IN JADE SINOR A ;IF NO ERRORS THEN RETURN RET Z LD DE,MSGNC ;ELSE OUTPUT ERROR & RETURN CALL MSGOT SCF RET ;************* REPT3: CALL FMTSD ;FORMAT IN SDEN JR C,FUN3 ;ERR CALL TRKDONE ;OUTPUT '*' LD A,(TRKNO) ;IF TRACK 76 THEN DONE  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 REINATED TEXT ; EXIT - ? ; ;**************************************************** MSGOT: LD C,9 ;PRINT STRING FUNCTION JP GLE DENSITY ; TRK 0= SINGLE DENSITY ; TRK 1= DOUBLE DENSITY ; TRK 2..76= SINGLE DENSITY ; ;--------------------------------*************************** ; ; FORMAT SINGLE DENSITY TRACK SUBR ; EXIT - CF: ERROR ; ;********************************** CP TRK76 JR Z,FUN3CK INC A ;ELSE DO NEXT TRACK LD (TRKNO),A JR REPT3 FUN3CK: CALL CHECK ;READ EACH SECTOR JR FPTD: LD DE,MSGFD ;PRINT MESSAGE CALL MSGOT CALL CNSIN ;GET DRIVE INPUT CP CR ;IF RETURN THEN EXIT JR Z,EXITD LD (DBDOS ;*********************************** ; ; CONSOLE INPUT SUBR ; EXIT - A= CHAR AND 7FH ; ;***********************------------------ FUN2: LD IX,IDSSD ;SELECT DRIVE LD A,(IX+DDFLG) LD (FFLAG),A LD HL,SDSDIR CALL SELDR JP C,FUNB****** FMTSD: LD HL,FT3740 ;SET INJECTION ADDR JR STDMA ;**************************************** ; ; FORMAT DOUBLE UN3 ;---------------------------------------------------------- ; ; FUNCTION 4 - DOUBLE DENSITY FORMAT ; TRK 0= SINGLERLTR),A ;ELSE SAVE DRIVE LETTER & TEST FOR LEGAL LD (LTRSE),A SUB 'A' LD HL,DRVLO CP (HL) JR C,ILLG LD HL,DRVHI ************ CNSIN: LD C,1 ;CONSOLE READ FUNCTION # CALL BDOS AND 7FH CP CTRLC ;IF CTRL-C THEN REBOOT JP Z,REBOOT G ;ERR LD A,TRK0 ;SET UP FOR TRACK 0 LD (TRKNO),A CALL FMTSD ;FORMAT IN SDENS CALL NC,WRTID ;WHILE WE'RE HERE, WRDENSITY TRACK SUBR ; EXIT - CF: ERROR ; ;**************************************** FMTDD: LD HL,FTJ48D ;SET INJECTION ADDR  DENSITY ; TRK 1..76= DOUBLE DENSITY 256 BYTE SECTORS ; ;---------------------------------------------------------- FUN4: LD CP (HL) JR C,NMBRD ;IF LEGAL THEN CONTINUE ILLG: LD DE,MSGSE ;PRINT SELECT ERROR MESSAGE CALL MSGOT JR REPTD EXIT CP 'a' ;IF LOWER CASE THEN CONVERT TO UPPER CASE RET C CP 'z' + 1 RET NC AND 5FH RET ;***********************ITE ID SECTOR JR C,FUN2 ;ERR CALL TRKDONE LD A,TRK1 ;SET UP FOR TRACK 1 LD (TRKNO),A CALL FMTDD ;FORMAT IN DDENJR STDMA ;**************************************** ; ; FORMAT 256 BYTE DOUBLE DENSITY TRACK ; ;************************ IX,IDSDD2 LD A,(IX+DDFLG) ;SET FORMAT FLAGS LD (FFLAG),A LD HL,DDSDIR CALL SELDR JP C,FUNBG ;ERR- RESELECT LD 0 ( ) *!+",#-$.%/ &0 'D: SCF ;SET FLAG TO CALLING RTN RET ; ; DRIVE SELECTED ; NMBRD: LD C,A ;SELECT DRIVE LD HL,DRVLO ;BIAS IT DOWN SUB ************** ; ; SET DMA FUNCTION ; ENTRY- BC= MEMORY ADDR ; ;********************************** SETDMA: LD A,SETMAV J LD BC,SECBUF ;USE DUMMY SECTOR BUFFER CALL SETDMA LD A,76 ;START WITH LAST TRACK LD (TRKNO),A ; ; ALL SET TO DOT ;********************************************* ; ; SELECT DISK THROUGH BIOS FUNCTION ; ENTRY- E= DISK # ; ;*********UTV: CALL COUT LD A,(TRKNO) ;NEXT TRACK DEC A LD (TRKNO),A RET M ;IF TRACK < 0 THEN DONE JP VLP ;***********(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 NP BIOS ;********************************** ; ; WRITE SECTOR FUNCTION ; ;********************************** WRSECT: LD A, TRACK ; VLP: LD C,A ;SEEK TRACK CALL SETTRK XOR A ;ASSUME NO ERRORS LD (RDERR),A LD E,BS ;START AT LAST '*' ************************************ BSELDK: LD A,SLDSKV ;SELECT DISK FUNCTION # JP BIOS SUBTTL CONSTANT DECLARATIONS *************************** ; ; SECTOR TRANSLATION SUBR ; ENTRY- C= SECTOR ; EXIT - C= SECTOR ; ;*************************Z,LOGOK LD DE,NODRVM CALL MSGOT SCF RET LOGOK: LD DE,MSGXX ;PRINT TYPE CR WHEN READY MSG CALL MSGOT CALL CNSIN WRSECV JP BIOS ;********************************** ; ; READ SECTOR FUNCTION ; ;********************************** RDSE CALL CNSOT LD E,'V' ;OUTPUT VERIFY PROMPT CALL COUT LD A,-1 ;ASSUME TRANSLATE LD (TXFLG),A LD A,(FFLAG) ;COM;-------------------------------------- ; ; DEFAULT DIRECTORY SIZE VALUES ; ;-------------------------------------- DDSDIR:************* SECTRN: LD A,(TXFLG) ;IF NOT SINGLE DENSITY THEN RETURN OR A RET Z LD B,0 DEC C LD HL,TRNTBL ADD HL ;IF NOT CR THEN REPEAT CP CR JR NZ,REPTD ; NOW ASK FOR DOUBLE DIRECTORY SIZE LD A,(FFLAG) ;IF SINGLE DENSITY 3740 THC: LD A,RDSECV JP BIOS ;********************************** ; ; FORMAT TRACK FUNCTION ; ;*****************************PUTE NUMBER OF SECTORS IN TRACK OR A ;IF SINGLE DENSITY THEN DO 26 SECTORS JR Z,DO26 LD A,(TRKNO) ;ELSE IF FLAG BIT ==  DB 80H,63,16 ;DOUBLE DENSITY SDSDIR: DB 0C0H,63,16 ;SINGLE DENSITY ;------------------------------------------------ ; ,BC LD C,(HL) RET ;********************************************************** ; ; CHAR OUT WITH CURSOR AT SAME POSITIEN NO DPB OR A JR Z,IDOK LD DE,DIRQM CALL MSGOT CALL CNSIN CP 'Y' ;IF YES THEN CHANGE JR NZ,IDOK SCF ;DOU***** FMTTRK: LD A,DDMRQ ;SWITCH DD INTO SYSTEM OUT (DDPORT),A LD A,DDMB1 ;SELECT BANK 1 OUT (DDPORT),A LD BC,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 (TXFL; SINGLE DENSITY TRANSLATION TABLE ; ;------------------------------------------------ TRNTBL: GXLATE 26,6 ;************ON SUBR ; ENTRY- E= CHAR TO OUTPUT ; ;********************************************************** COUT: CALL CNSOT LD E,BS BLE DIRECTORY SPACE RL (IX+DRM) SLA (IX+CKS) ;DOUBLE CHECKSUMS LD A,(IX+AL0) ;SET UP TO DOUBLE ALLOCATION SIZE ADDBLKFMTSZ ;MOVE FORMAT CODE INTO FDC LD HL,(DADDR) LD DE,DDFBF ADD HL,DE EX DE,HL LD HL,(BTDMA) LDIR LD A,DDMRQ ;SEG),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******************************* ; ; JADE SINGLE DENSITY IDENTITY SECTOR ; TRACK 0= SD, 26 128 BYTE SECTORS ; TRACK 1= DD,  JP CNSOT ;******************************* ; ; SET TRACK FUNCTION ; ENTRY- BC= TRACK # ; ;***************************: SLA A JR NC,IDOK SRA (IX+AL0) ;ADD ANOTHER BLOCK JR ADDBLK IDOK: LD DE,FMTHDR ;OUTPUT HEADER OF TRACKS CALL MSGOLECT 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) JR NZ,DOSECTS DO26: LD A,26 SETNSEC: INC A ;OFFSET FOR TEST LD (NSECTS),A LD A,1 ;START WITH 1ST SECTOR ; 48 128 BYTE SECTORS EACH ; TRACK 2..76= SD ; ;******************************************* IDSSD: DB 'Jade DD Single density **** SETTRK: LD A,SETRKV BIOS: PUSH DE ;SAVE POSSIBLE LOGON VECTOR LD HL,(WBOOT +1) ;GET BIOS PTR LD E,A ;ADD IN OFFSET AND A ;ELSE CLEAR ERR FLAG & RETURN RET ;************************************************************************* HL,BTCMD LDIR LD A,DDEXC ;EXECUTE COMMAND BLOCK OUT (DDPORT),A EX DE,HL ;SET UP TO MOVE DOWN STATUS BYTES LD BC; ALL SET TO DO SECTOR ; RDLP: LD (SECTOR),A ;SAVE CURRENT SECTOR LD HL,NSECTS CP (HL) JR Z,TDONE LD C,A CALL SEformat ' ;CONFIRMATION TEXT ; ; DISK PARAMETER BLOCK IMAGE, TO BE TRANSFERRED TO BIOS AT LOGON TIME ; REPT IDSSD + 20H -$ T LD D,0 ADD HL,DE ADD HL,DE ADD HL,DE POP DE JP (HL) ;EXECUTE ;******************************** ; ; SET SECTO** ; ; CHECK FUNCTION CHECKS ALL TRACKS BY READING BACKWARD FROM 76 ; ;*****************************************************,5 DSKWT: IN A,(DDPORT) ;WAIT UNTIL DONE AND DDSHLT JR NZ,DSKWT LD A,DDMRQ ;SWITCH DD INTO SYSTEM OUT (DDPORT),A LCTRN CALL SETSEC CALL RDSEC OR A JR Z,VRDCNT LD (RDERR),A VRDCNT: LD A,(SECTOR) INC A JP RDLP ; ; TRACK I;POSITION DPB IN SECTOR LIST OFF DB 0E5H ;FILL WITH E5 LIST ON ENDM SPT EQU $ - IDSSD DW 26 ;SECTORS PER TRACK R FUNCTION ; ENTRY- BC= SECTOR # ; ;******************************** SETSEC: LD A,SETSECV JP BIOS ;****************************************** CHECK: LD A,(DRLTR) ;DO LOG-ON SO CONTROLLER INFORMED SUB 'A' LD C,A LD E,LOGVC CALL BSELDK DIR ;FETCH STATUS BYTES LD A,DDOUT ;REMOVE FDC FROM MEMORY MAP OUT (DDPORT),A LD A,(BTSTS) ;RETURN STATUS OR A RES DONE, CHECK IF ANY ERRORS ; TDONE: LD A,(RDERR) OR A JR NZ,VERR LD E,'-' JR OUTV VERR: LD E,'?' ;OUTPUT '?' O0 ( ) *!+",#-$.%/ &0 '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 FMTBG ;DETERMINE ADDR OF OFFSET DB 'FORMAT!S' ;CONFIRMATION TEXT ; ; START OF CODE, SHOULD BE FMTBG + 8 ; LD HL,SS3740 - SDD + 30H -$ ;LOCATE DCM BLOCK LIST OFF DB 0E5H LIST ON ENDM DB 6 ;SECTOR STAGGER (TRNS) DB 00000110B ;DISKETTE FD 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 ist ******' DB CR,LF,'1. Jade 128 Byte Sector Double Density -n 8"' DB CR,LF,'2. Jade Single Density 8"' DB CR,LF,'3. Sta DW 63 ;DIRECTORY MAXIMUM AL0 EQU $ - IDSSD ;OFFSET TO DIRECTORY ALLOCATION BYTE DB 11000000B ;ALLOC 0 DB 0 ;ALLOC 1 CKSDOFF LD E,26 ;SET # SECTORS BG3740: LD B,40 ;# BYTES SRPT1: IN A,XPDSH ;WAIT FOR DATA REQ LD A,ONES XOR C OUT LAGS ; REPT IDSDD + SECSZ -$ ;EXTEND TO FULL SECTOR LIST OFF DB 0E5H LIST ON ENDM ;***************************** 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 ndard 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 fS EQU $ - IDSSD ;OFFSET TO CHECKSUMS BYTE DW 16 ;CHECK SIZE DW 2 ;TRACK OFFSET ; ; DISK CONTROLLER MODULE DISK PARAMETERWDDTA,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 **************** ; ; JADE DOUBLE DENSITY IDENTITY SECTOR ; TRACK 0= SD, 26 128 BYTE SECTORS ; TRACK 1..76= DD, 26 256 BYTE LD A,ONES XOR C OUT WDDTA,A DJNZ SRPT8 DEC E ;# SECTORS -1 JP NZ,RP3740 - SDOFF ;IF ANY LEFT THEN REPEAT LD HLunction number: $' MSGSE: DB CR,LF,LF LTRSE: DB ' Is not a valid selection.$' MSGFD: DB CR,LF,LF,'Write format on drive (CS TO BE TRANSFERRED TO DCM AT ; LOGON TIME ; REPT IDSSD + 30H -$ ;LOCATE DCM BLK LIST OFF DB 0E5H LIST ON ENDM  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,ONE SECTORS EACH ; ;********************************************* IDSDD2: DB 'Jade DD Double density format ' ;CONFIRMATION TEXT,0 ;COUNT = 0 SRPT9: IN A,XPDSH LD A,ONES ;WRITE ONES UNTIL INTERRUPT XOR C OUT WDDTA,A INC HL ;RETURN ONES COUNT R to reselect): $' MSGNC: DB CR,LF,LF,'Transfer incomplete$' MSGXX: DB CR,LF,LF,'TYPE CR WHEN DRIVE ' DRLTR: DB ' IS READY. DB 6 ;SECTOR STAGGER (TRNS) DDFLG EQU $ - IDSSD DB 00000010B ;DISKETTE FLAGS REPT IDSSD+SECSZ-$ ;FILL OUT SECTOR LISS 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 REPT IDSDD2 + 20H -$ LIST OFF DB 0E5H LIST ON ENDM ; ; IN THIS CASE, CP/M IS FOOLED BY THE DEBLOCKING INTO THINKIJP SRPT9 - SDOFF ; ; SECTOR TRANSLATION TABLE, NONE FOR SINGLE DENSITY ; SS3740: GXLATE 26, 1 ;**********************$' NODRVM: DB CR,LF,'BIOS Select Error!$' DIRQM: DB CR,LF,'Double Directory Size? (Y/N) - $' FMTHDR DB CR,LF,'0---------1----T OFF DB 0E5H LIST ON ENDM ;********************************************* ; ; JADE DOUBLE DENSITY IDENTITY SECTOR,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 ONG ; THERE ARE 52 128 BYTE SECTORS PER TRACK ; DW 52 ;SECTORS PER TRK DB 4 ;BLOCK SHIFT FACTOR DB 00001111B ;BLOCK MAS************************* ; ; DOUBLE D DOUBLE DENSITY INJECTION MODULE ; ;*********************************************** -----2---------3---------4---------5' DB '---------6---------7------',CR,LF,'$' SUBTTL INJECTION MODULES ;*************** ; TRACK 0= SD, 26 128 BYTE SECTORS ; TRACKS 1..76= DD, 48 128 BYTE SECTORS EACH ; ;************************************UT 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 OUK DB 1 ;NULL MASK DW 242 ;DISK SIZE -1 DW 63 ;DIRECTORY MAXIMUM DB 10000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16 ;CHEC FTJ48D: EQU $ DDOFF: EQU $ - FMTBG ;DETERMINE ADDR OFFSET DB 'FORMAT!D' ;CONFIRMATION TEXT ; ; EXECUTION START POINT ; ********************************** ; ; SINGLE DENSITY FORMATTER INJECTION MODULE ; THIS CODE IS INTENDED TO EXECUTE WITHIN ********* IDSDD: DB 'Jade DD Double density format ' ;CONFIRMATION TEXT REPT IDSDD + 20H -$ LIST OFF DB 0E5H LIST ON T 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,0K SIZE DW 2 ;TRACK OFFSET REPT IDSDD2 + 30H -$ ;LOCATE DCM BLOCK LIST OFF DB 0E5H LIST ON ENDM DB 6 ;SECTOR  LD HL,SSJ48D - DDOFF ;SET PTR TO SECTOR TRANSLATION TABLE LD E,48 ;SECTOR COUNT BGJ48D: LD B,80 ;WRITE PREAMBLE - 80 THE ; DOUBLE D MEMORY BANK 1. ALL ABSOLUTE MEMORY REFERENCES MUST BE OFFSET. ; THE OFFSET IS CALCULATED BY: ; ADDR = SYMBOL ENDM DW 48 ;SECTORS PER TRK DB 4 ;BLOCK SHIFT FACTOR DB 00001111B ;BLOCK MASK DB 1 ;NULL MASK DW 224 ;DISK SIZF7H 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 BSTAGGER (TRNS) DB 01000110B ;T0= SD, T1..76= 256 BYTE DD ; REPT IDSDD2 + SECSZ -$ ;EXTEND TO FULL SECTOR LIST OFF DB 0E4E 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  - START_OF_MODULE + DD_MODULE_LOCATION ; ;************************************************* FT3740: EQU $ SDOFF: EQU $ - E -1 DW 63 ;DIRECTORY MAXIMUM DB 10000000B ;ALLOC 0 DB 0 ;ALLOC 1 DW 16 ;CHECK SIZE DW 2 ;TRACK OFFSET REPT ID,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 L5H LIST ON ENDM ;****************** ; ; MESSAGES ; ;****************** MSGFL: DB CR,LF,LF,'****** Functions L 0 ( ) *!+",#-$.%/ &0 ' 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 O 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 - 2DATA 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 XOåS 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 OUUT 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 B56 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 OR 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 BYåT 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: YTES 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 DUT 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 ;TES DRPT8: IN A,XPDSH LD A,4EH XOR C OUT WDDTA,A DJNZ DRPT8 DEC E ;IF SECTORS LEFT THEN REPEAT JP NZ,RPJ48D - DDå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 RPT2: 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,0IF 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 BYTESOFF 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 å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,0FEHF5H 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 T UNTIL INTERRUPT XOR C OUT WDDTA,A INC HL ;COUNT NUMBER OF GAP 4 BYTES JR DD269 ; ; DOUBLE DENSITY SKEW TABLE, SKEW 9;COUNT NUMBER OF GAP 4 BYTES JR DRPT9 ; ; DOUBLE DENSITY SKEW TABLE, SKEW 8 SEEMS OPTIMUM ; SSJ48D: GXLATE 48, 8 ;***å 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 CRACK # IN A,WDTRK OUT WDDTA,A IN A,XPDSH ;WRITE SIDE # XOR A,A XOR C OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR #  SEEMS OPTIMUM ; SSJ26D: GXLATE 26, 9 SUBTTL VARIABLE DECLARATIONS ; ; FDC COMMAND BLOCK ; BTCMD DB DDFMT ;FORMAT COM******************************************** ; ; DOUBLE D DOUBLE DENSITY INJECTION MODULE ; 256 BYTE SECTORS ; ;*********å OUT WDDTA,A IN A,XPDSH ;WRITE SECTOR # LD A,(HL) XOR C OUT WDDTA,A INC HL IN A,XPDSH ;WRITE SECTOR SIZE L 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,XPMAND BTDRV DS 1 ;DRIVE # TRKNO: DS 1 ;TRACK NUMBER HOLD FFLAG: DS 1 ;FORMAT FLAG (DCM) DW 0 ;SPARES DB 0 ;MODE CONTR************************************** FTJ26D: EQU $ DD26OFF: EQU $ - FMTBG ;DETERMINE ADDR OFFSET DB 'FORMAT!D' ;CONFIRMAåD 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 2DSH ;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 XOLS BTSTS DS 1 ;STATUS BYTE DS 4 ;LOAD WORDS BTDMA DS 2 ;ADDRESS OF INJECTION MODULE NSECTS DS 1 ;NUMBER OF SECTORSTION TEXT ; ; EXECUTION START POINT ; LD HL,SSJ26D - DD26OFF ;SET PTR TO SECTOR TRANSLATION TABLE LD E,26 ;SECTOR COUNå - 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,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  IN TRACK TXFLG DS 1 ;TRANSLATE SECTOR BOOLEAN FLAG RDERR DS 1 ;READ ERROR BOOLEAN FLAG SECTOR DS 1 ;CURRENT SECTOR SECT 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,åPDSH 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  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 BUF DS 256 ;SECTOR BUFFER CODEND EQU $ END 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 BYTE!0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå"0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå#0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå$0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå%0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå&0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå'0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå(0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå)0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå*0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå+0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå,0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå-0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå.0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå/0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå00 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå10 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå20 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå30 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå40 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå50 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå60 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå70 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå80 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå90 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå:0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå;0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå<0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå=0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå>0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå?0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå@0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååA0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååB0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååC0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååD0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååE0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååF0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååG0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååH0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååI0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååJ0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååK0 ( ) *!+",#-$.%/ &0 'ååååååååååååååååååååååååååååååååååååååååååååååååL0 ( ) *!+",#-$.%/ &0 'åååååååååååååååååååååååååååååååååååååååååååååååå