TITLE DISK CONTROLLER MODULE (DCM) LIST NOCOND ;*************************************************************************** ; ; The Disk Controller Module contains the firmware for the Jade ; Double D Disk controller board. ; ;*************************************************************************** ; ; The disk controller module (DCM) resides internal to the Jade Double D ; Disk Controller board. This program provides a facility to read/write ; diskette sectors & format diskette tracks (in single & double density). ; This module sets the parameters for each drive during the "LOG-ON" ; operation. The FORMAT program (not in this module) writes an ident- ; ification sector (T0,S1) which provides the needed information. If this ; identity sector is not present on the diskette, it is assumed to be a ; standard 8" IBM 3740 format. ; ;*************************************************************************** ; ; REVISION STATUS: ; ; 1.0 - 1 AUG 82 GRH ; Initial release ; ; 1.1 - GRH ; Fix bug causing code to crash after predictable number of warm boots. ; A CALL was being made without a return in the login function. ; ; 1.2 - 1 AUG 82 GRH ; ADDED RECAL FEATURE TO RECOVER FROM THE INSTANCE WHERE THE ; HEAD IS OUTSIDE TRACK 0 BUT THE SENSOR IS STILL GIVING ; THE TRACK 0 SIGNAL. IF TRK 0 SENSE IS TRUE ON ENTRY, THE ; HEAD IS STEPPED IN SEVERAL TRACKS, THEN A TRK 0 SEEK IS ; PERFORMED. ; ; 1.3 - 31 AUG 83 GRH ; Add sector de-blocking algorithms for 256 byte sectors. Remove unused ; code & vars. Optimize code. ; ; 1.4 - 30 OCT 85 GRH ; Revise objects for improved include file. Add hooks for double sided ; drives. Change logon to return boolean reflecting a valid descriptor ; sector. ; ; 2.0 - 24 nov 85 grh ; Modify module to allow EPROM at low memory & RAM at high memory. ; Add diagnostics & better error reporting. ; Add EIA I/O. ; Change Command block structure to common IOPB structure. ; Add 5 1/4" disk hooks. ; ; 2.1 - 2 NOV 86 GRH ; Changed seek routines to allways set up new controls even if track ; is the same. This should allow the forcing of new controls to work. ; ; 2.2 - 31 DEC 86 GRH ; Added precomp thresholds to disk table. ; Added forced interrupt to reset because FDC is not software resetable. ; and may cause a 'hang' condition. ; Add double density logon read first and if fail then try single ; density read before giving up. ; VERSN EQU 0202H ; ;*************************************************************************** SUBTTL FIRMWARE DEFINITIONS FALSE EQU 0 TRUE EQU NOT FALSE ;============================================================================ ; ; ASSEMBLY TIME CONSTANTS ; ;============================================================================ DSIZE EQU 5 ;SIZE OF DISK DRIVES DFDFL EQU 0 ;DEFAULT DISK FLAGS ;============================================================================ ; ; INCLUDED DEFINITIONS ; ;*INCLUDE JDDLOC.DEF ;*INCLUDE COMIOPB.DEF ;*INCLUDE JDDDISK.DEF ;*INCLUDE JDDCONT.DEF ;*MACLIB ASMBTOOL.MLB ; ;============================================================================ LIST OFF *INCLUDE JDDLOC.DEF *INCLUDE COMIOPB.DEF *INCLUDE JDDDISK.DEF *INCLUDE JDDCONT.DEF *MACLIB ASMBTOOL.MLB LIST ON SUBTTL MAIN FIRMWARE ;*************************************************************************** ; ; REGISTER USAGE: ; A, B= SCRATCH ; C= 179X INVERSION CONSTANT ; DE= USED FOR R/W FLAG BY R/W SECTOR SUBR ; DE'= SECTOR DATA FOR READ/WRITE SECTOR FUNCTIONS ; HL= PTR TO DATA XFER BY R/W SECTOR SUBR ; IX= DISK PARAMETER BLOCK PTR ; IY= 179X NMI RETURN ADDRESS ; AF'= R/W FLAGS ; BC', HL'= NOT USED ; ;*************************************************************************** ;--------------------------------------------------------------------------- ; ; JUMP IS EXECUTED WHEN THE ONBOARD Z80 IS RESET. ; ;--------------------------------------------------------------------------- ORG 0 ; XOR A,A ;DISABLE NMI OUT (BLCTL),A JP CLEAR ;RESET & RE-INITIALIZE Z-80 REGS ;**************************************************************************** ; ; RESTART 8 FUNCTION - 100us TIMER ; THIS SUBROUTINE IS THE ENTRY POINT FOR THE DISK CONTROLLER TIMING MODULE. ; THIS MODULE PROVIDES DELAYS WHICH ARE MULTIPLES OF 100 us. THE CONTENTS OF ; DE DETERMINES THE TOTAL PERIOD. (DELAY= DE * 100 us). ; ENTRY- DE= 100 MICROSECOND MULTIPLIER (0= 65,536) ; EXIT - DE= A= B= 0 ; ;**************************************************************************** ; ; TIMING CONSTANTS FOR 100us ; IF DSIZE = 8 TMRFC EQU 19H ;1ST PASS TMRNC EQU 1CH ;NORMAL PASS ENDIF IF DSIZE = 5 TMRFC EQU 0CH ;1ST PASS TMRNC EQU 0EH ;NORMAL PASS ENDIF ORG 8 ;POSITION FOR RESTART 8 VECTOR ; ; USE SMALLER TIME TO OFFSET CALLING TIME ; LD B,TMRFC ;SET CONSTANT DJNZ $ JP TICKE ;GOTO TICK ENTRY ; ; DELAY FOR 100 us ; TICKR: LD B,TMRNC ;SET NORMAL CONSTANT DJNZ $ ; ; IF MULTIPLIER NOT EXHAUSTED THEN REPEAT TIME ; TICKE: DEC DE ;COUNT -1 LD A,D OR A,E ;IF COUNT NOT 0 THEN REPEAT NOP NOP JR NZ,TICKR ; ; DONE ; RET ;**************************************************************************** ; ; RESTART 32 FUNCTION - COMMAND FDC ; ENTRY - A= COMMAND ; EXIT - A= A XOR C ; ;**************************************************************************** ORG 32 XOR A,C OUT (WDCMD),A EX (SP),HL EX (SP),HL EX (SP),HL EX (SP),HL RET ;**************************************************************************** ; ; RESTART 40 FUNCTION - READ SECTOR ; ENTRY - HL= DATA PTR ; DE= PHYSICAL SECTOR ; EXIT - NZ= ERROR ; A, HL, B= ? ; ;**************************************************************************** ORG 40 ;POSITION CODE FOR RESTART 40D VECTOR EX AF,AF' ;SET UP READ XOR A,A DEC A EX AF,AF' JP RWSECT ;**************************************************************************** ; ; RESTART 48 - NOT USED ; ;**************************************************************************** ORG 48 ;**************************************************************************** ; ; RESTART 56 (MASKABLE INTERRUPT) FUNCTION - EXECUTE THE COMMAND BLOCK ; MASKABLE HOST INTERRUPT ROUTINE - EXECUTED WHEN RESTARTING THE LOCAL ; PROCESSOR FROM A HALT IN ORDER TO PROCESS A COMMAND. ; ;**************************************************************************** ORG 56 ;POSITION CODE FOR RESTART 56 VECTOR JP XCUTE ;---------------------------------------------------------------------------- ; ; SPARE COMMAND, RETURNS COMMAND ERROR ; ;---------------------------------------------------------------------------- SPAR: LD HL,CMDBLK + PBSTATO ;SET COMMAND ERROR LD (HL),CMDERR RET ;*************************************************************************** ; ; THIS IS THE NON-MASKABLE INTERRUPT ROUTINE USED BY THE FDC ; UPON COMMAND TERMINATION. THE STATUS PORT IS INTERROGATED & SAVED (SVSTS). ; ENTRY- IY= INTERRUPT RETURN ADDRESS ; EXIT - (COMMAND BLOCK STATUS)= A= FDC STATUS ; IY= INTERRUPTED ADDRESS ; ;*************************************************************************** IF $ > 66H ?OVRLAP NMI VECTOR,$-66H ENDIF ORG 66H ;POSITION CODE FOR NMI VECTOR LOCATION ; ; GET FDC STATUS & PUT INTO COMMAND BLOCK FOR HOST INTERPRETATION ; IN A,(WDSTS) ;CLEARS INTERRUPT TOO XOR A,C ; ; PUT RETURN ADDRESS ON STACK & RETURN TO IT. ; EX (SP),IY RETN ;*************************************************************************** ; ; COMMAND SELECTOR SUBR GETS CONTROL AFTER THE DISK CONTROLLER IS ; INTERRUPTED FROM THE HALT CONDITION. IT BRANCHES TO THE INDIVIDUAL ; COMMAND ROUTINES. ; ;*************************************************************************** XCUTE: ; ; CLEAR THE HOST INTERRUPT FLOP ; IN A,(XPIRR) ; ; ASSUME NO ERROR ; XOR A,A LD (CMDBLK + PBSTATO),A LD (CMDBLK + PBST1O),A ; ; GET FDC'S ATTENTION FOR COMMANDS ; CALL EXSTS ; ; FETCH COMMAND FROM COMMUNICATION BLOCK ; LD A,(CMDBLK + PBCMDO) ; ; IF ILLEGAL COMMAND THEN RETURN COMMAND ERROR ; CP NCMDS JR NC,SPAR ; ; COMPUTE COMMAND TABLE POINTER ; LD D,0 LD E,A ;SET UP OFFSET LD HL,CMDT ;SET TABLE PTR ADD HL,DE ADD HL,DE ;DO TWICE FOR WORD PTR ; ; FETCH COMMAND OFFSET FROM TABLE ; LD A,(HL) ;GET ADDRESS INC HL LD H,(HL) LD L,A ; ; EXECUTE COMMAND. ALL COMMANDS RETURN TO INTERRUPTED WAIT LOOP ; JP (HL) ;GOTO COMMAND ; ; COMMAND TABLE ; CMDT: DW LGON ;LOG-ON DRIVE DW READ ;READ SECTOR DW WRIT ;WRITE SECTOR DW FORM ;FORMAT TRACK DW ADDR ;READ ADDRESS DW EIAOUT ;EIA OUT DW EIAIN ;EIA IN DW IDLE ;BACKGROUND DW RETVER ;RETURN FIRMWARE VERSION DW SETFLGS ;SET DISK FLAGS DW LDHDI ;LOAD HEAD & WAIT DW SEEKTRK ;SEEK TRACK DW SETDP ;SET DISK DRIVE PARAMETERS DW RETDST ;RETURN DRIVE STATUS DW SETBAUD ;SET EIA BAUD RATES DW CLR ;CLEAR IDLE COMMANDS NCMDS EQU ($ - CMDT) / 2 ;COMMAND COUNT ;---------------------------------------------------------------------------- ; ; DRIVE LOG-ON COMMAND (0) ; READS THE IDENTITY SECTOR FROM THE DISKETTE AND MAKES THE NEEDED ENTRYS ; INTO THE DRIVE TABLE OR DEFAULTS. THE SECTOR DATA IS ALSO LEFT IN THE SECTOR ; BUFFER FOR BIOS TO ACCESS THE DESCRIPTOR DATA IN ORDER TO FINISH THE LOG-ON ; OPERATION. ; ;---------------------------------------------------------------------------- LGON: ; ; SELECT DRIVE 1ST ; CALL SELECT RET NZ ;IF DRIVE ERROR THEN RETURN ; ; SET UP TO READ DESCRIPTOR SECTOR ; XOR A,A ;SET TRACK=0 LD (CMDBLK + PBTRKO),A ; LD A,2 ;SET SECTOR LD (CMDBLK + PBSECO),A ; ; SEEK TRACK ; CALL SEEK ; ; TEST IF LOGON INHIBITED ; LD A,(IX + DVLGDO) OR A,A JR NZ,NODS ; ; READ DESCRIPTOR SECTOR INTO BUFFER ; SET 0,(IX + DVFLG) ;ASSUME DOUBLE DENSITY FIRST LD HL,SBUFR ;READ INTO SECTOR BUFFER LD DE,IDSECT RST 40 JR Z,LGCHK ;IF READ SUCCESSFUL THEN GO CHECK FOR ID ; RES 0,(IX + DVFLG) ;NOW TRY SINGLE DENSITY LD HL,SBUFR LD DE,IDSECT RST 40 ; ; CHECK FOR NEW DESCRIPTOR ID TEXT ; LGCHK: LD DE,DESCID ;SET STRING PTR LD HL,SBUFR + IDLABO ;SET SECTOR BUFFER PTR TO COMPARE LD B,DIDSIZ ;SET ID LENGTH ; CKNI: LD A,(DE) ;IF NOT ID THEN 3740 CP A,(HL) JR NZ,I3740 ; INC HL ;ELSE INC PTRS INC DE DJNZ CKNI ;IF NOT DONE THEN REPEAT ; ; FOUND DESCRIPTOR SECTOR - MOVE DISK FORMAT DATA TO DRIVE TABLE ; LD DE,DVFLG ;COMPUTE ADDRESS OF ELEMENT CALL GETDVEL EX DE,HL ; LD HL,SBUFR + IDFLGO ;SET SIDES & DENSITIES PUSH BC LD BC,DVDFSZ LDIR POP BC ; ; RETURN NEW DESCRIPTOR FLAG ; LD A,-2 ; ; RETURN DESCRIPTOR SECTOR FLAG TO HOST ; SETFFG: LD (CMDBLK + PBST2O),A RET ; ; ; ASSUME 3740 FORMAT ; I3740: ; ; SET DISK PARAMETERS TO SINGLE SIDED, SINGLE DENSITY ; LD DE,DVFLG ;GET DRIVE TABLE ADDRESS CALL GETDVEL LD DE,DVSSSD EX DE,HL PUSH BC LD BC,DVDFSZ LDIR POP BC ; ; RETURN INVALID DESCRIPTOR SECTOR TO HOST ; NODS: XOR A,A JR SETFFG ;*************************************************************************** ; ; RETURN ADDRESS OF DRIVE TABLE ELEMENT FUNCTION ; ENTRY- DE= OFFSET OF ELEMENT ; IX= PTR TO DRIVE TABLE ENTRY ; EXIT - HL= ADDRESS OF ELEMENT ; ;*************************************************************************** GETDVHLD: LD DE,DVHLDO GETDVEL: PUSH IX POP HL ADD HL,DE RET ;########################################################################### ; ; DEFAULT SINGLE SIDED - SINGLE DENSITY TABLE FOR NON ID SECTORED DISKS ; ;########################################################################### DVSSSD: DB DFDFL ;DEFAULT DRIVE FLAGS (SSSD) REPT 3 DB 26 ;;26 SECTORS DB 0 ;;128 BYTES PER SECTOR ENDM DB 14,27 ;;PRECOMP THRESHOLDS DVDFSZ EQU $ - DVSSSD ;---------------------------------------------------------------------------- ; ; READ SECTOR COMMAND (1) ; ;---------------------------------------------------------------------------- READ: LD A,-1 ;FLAG := READ OR A,A JR OPCONT ;---------------------------------------------------------------------------- ; ; WRITE SECTOR COMMAND (2) ; ;---------------------------------------------------------------------------- WRIT: XOR A,A ;FLAG := WRITE OPCONT: ; ; SAVE OPERATION FLAGS ; EX AF,AF' ;SAVE OP IN ALT REGS ; ; SELECT DRIVE 1ST ; CALL SELECT ;SELECT DRIVE ; ; IF NO ERRORS THEN SEEK TRACK ; CALL Z,SEEK ;SEEK TRACK ; ; IF SELECT OR SEEK ERROR THEN RETURN ; RET NZ ; ; SET READ PTR ; LD HL,SBUFR ; ; FETCH SECTOR DATA ; LD DE,(CMDBLK + PBSECO) JP RWSECT ;---------------------------------------------------------------------------- ; ; FORMAT TRACK COMMAND (3) ; ;---------------------------------------------------------------------------- FORM: ; ; CHECK FOR VALID DRIVER ; LD HL,(FMTBG) LD DE,0AA55H ;KEY BYTES OR A,A SBC HL,DE JR NZ,FMTINV ; ; 3RD & 4TH BYTES CONTAIN THE CHECKSUM COUNT ; LD HL,FMTBG + 2 LD E,(HL) INC HL LD D,(HL) DEC HL ;INCLUDING THE KEY BYTES DEC HL DEC HL LD B,0 ; ; COMPUTE CHECKSUM ; NXTCKS: LD A,(HL) ADD A,B LD B,A INC HL DEC DE LD A,E OR A,D JP NZ,NXTCKS ; ; IF CHECKSUM NOT 0 THEN ERROR ; OR A,B JR NZ,FMTINV ; ; SELECT DRIVE 1ST ; CALL SELECT RET NZ ;IF ERROR THEN RETURN ; ; SET DISK FLAGS TO DATA IN FLAGS BYTE OF COMMAND BLOCK ; LD A,(CMDBLK + PBFLGO) ;GET FORMAT FLAGS LD (IX + DVFLG),A ;RESET DRIVE FLAGS ; ; SEEK TRACK FROM COMMAND BLOCK ; CALL SEEK ; ; SET UP FOR COMMAND COMPLETION ; LD IY,NMIWT ;SET RETURN ADDR ; ; SET UP SIDE CONTROL AND PASS SIDE # IN D ; LD DE,(CMDBLK + PBSECO) LD A,D AND A,80H LD D,A ;SAVE SIDE IN D7 RRCA ;COMPUTE CONTROL BYTE RRCA LD (SIDE),A LD B,A LD A,(SVCTL) AND A,NOT BCDAS OR A,B CALL SETCTL ; RLC D ;PUT BIT 7 INTO BIT 0 ; ; EXECUTE CODE IN BUFFER ; JP FMTPS ;ENTER PAST THE VALIDATION BYTES ; ; COMMAND DONE, RETURN FORMAT STATUS ; NMIWT: ; ; RETURN LAST GAP BYTE COUNT ; LD (CMDBLK + PBST2O),HL ; ; MASK APPLICABLE ERRORS ; AND A,DMFER ;SET ANY ERRORS ; ; RETURN ERROR STATUS IN COMMUNICATION BLOCK ; RETERR: OR A,A ;IF NO ERROR THEN QUIT NOW RET Z ; LD (CMDBLK + PBST1O),A LD A,FDCERR RETFER: LD (CMDBLK + PBSTATO),A RET ; ; FORMAT DATA ERROR ; FMTINV: LD A,FMTERR JR RETFER ;---------------------------------------------------------------------------- ; ; READ ADDRESS COMMAND (4) ; ;---------------------------------------------------------------------------- ADDR: ; ; SELECT DRIVE 1ST ; CALL SELECT RET NZ ; ; RETRY COUNT = 0 ; XOR A,A LD (ERRCT),A ; ; SET UP FOR XFER ; RADRTY: LD IY,RADNMI ;SET COMMAND COMPLETION VECTOR LD HL,SBUFR ;USE SECTOR BUFFER ; ; ISSUE READ ADDRESS COMMAND ; LD A,DCRDA ;ISSUE COMMAND TO FDC RST 32 ; ; WAIT HERE FOR DATA ; RADNXT: IN A,(XPDSH) ;WAIT FOR DATA ; ; GET DATA & STORE IT ; IN A,(WDDTA) ;GET DATA XOR A,C LD (HL),A ;STORE IT INC HL ;NEXT JP RADNXT ; ; COMMAND DONE, CHECK FOR ERRORS ; RADNMI: ; ; PASS BACK THE XFER COUNT ; LD DE,SBUFR OR A,A SBC HL,DE LD (CMDBLK + PBST4O),HL ; ; NOW TEST ERRORS ; AND A,DMRER RET Z ; ; ERROR ENCOUNTERED, CHECK FOR RETRY ; LD B,A ;CHECK FOR RETRYS PUSH BC CALL CHKRT POP BC JR Z,RADRTY ; ; HARD ERROR, RETURN IT ; LD A,B JP RETERR ;---------------------------------------------------------------------------- ; ; EIA OUTPUT COMMAND (5) ; ;---------------------------------------------------------------------------- EIAOUT: ; ; TEST FOR BAUD RATE == 0 (BIT OUTPUT ONLY) ; LD A,(BAUDOUT) OR A,A JR NZ,EIAO3 ; ; STATIC OUTPUT OPTION - OUTPUT THE NEW BIT ; LD A,(CMDBLK + PBST5O) ;FETCH DATA BIT CPL ;COMPENSATE FOR DATA INVERSION AND A,1 ;MASK OUT UNUSED BITS REPT 3 RLCA ENDM LD (EIACTL),A ; ; USE EXISTING CONTROLS ; LD A,(SVCTL) ; FALL INTO SAVE CONTROL ;*************************************************************************** ; ; SET CONTROL PORT SUBROUTINE ; ENTRY- A= VALUE TO SET TO ; EXIT - A= VALUE WITH EIA BIT INCLUDED ; B= ? ; ;*************************************************************************** SETCTL: LD (SVCTL),A ;STORE VALUE ; ; ENTRY WITHOUT SAVE ; SETCTL1: LD B,A ;SAVE ORIGINAL VALUE LD A,(EIACTL) OR A,B OUT (BLCTL),A RET ; ; ; WAIT UNTIL READY TO ACCEPT CHARACTER ; EIAO3: IN A,(BLSTS) ;IF NOT READY THEN WAIT EI ;ALLOW BREAK AND A,BSEIA JR Z,EIAO3 ; DI ;NO MORE WHILE OUTPUTTING DATA ; ; FETCH CHARACTER FROM CMD BLOCK ; LD A,(CMDBLK + PBST5O) ;FETCH CHARACTER CPL ;OUTPUT PORT IS INVERTED LD E,A ; ; SET UP ; LD HL,BAUDOUT ;BAUD RATE DIVISOR PTR LD A,(SVCTL) ;LAST CONTROLS USED ; ; SEND THE START BIT ; SCF CALL BITOUT NOP NOP LD D,8 ;DATA BIT COUNT ; ; SEND EACH DATA BIT (39 CYCLE LOOP) ; EIAO1: RRC E CALL BITOUT DEC D JP NZ,EIAO1 ; ; SEND STOP BIT ; NOP AND A,A CALL BITOUT ; ; MAKE EIA BIT STATIC ; XOR A,A LD (EIACTL),A ; RET ;---------------------------------------------------------------------------- ; ; EIA INPUT COMMAND (6) ; ;---------------------------------------------------------------------------- EIAIN: ; ; TEST STATUS BIT ; IN A,(BLSTS) AND A,BSEIA ; ; IF BIT == 0 THEN RETURN 0 ; JR Z,EIAI1 ; ; ELSE RETURN -1 ; LD A,-1 EIAI1: LD (CMDBLK + PBST2O),A RET ;---------------------------------------------------------------------------- ; ; IDLE COMMAND (7) ; ;---------------------------------------------------------------------------- IDLE: IN A,(BLSTS) ;IF NO HOST INTERRUPT THEN WAIT AND A,BSINT JR Z,IDLE ; IN A,(XPIRR) ;ELSE RESET INTERRUPT REQUEST & EXIT RET ;---------------------------------------------------------------------------- ; ; RETURN FIRMWARE VERSION COMMAND (8) ; ;---------------------------------------------------------------------------- RETVER: LD HL,VERSN LD (CMDBLK + PBST2O),HL RET ;---------------------------------------------------------------------------- ; ; SET DISK PARAMETERS COMMAND (9) ; ENTRY- PBFLG= 0: SET PARAMETERS FROM SECTOR BUFR & DISABLE LOGON ; 1: RETURN PARAMETERS IN SECTOR BUFR & DISABLE LOGON ; 2: SET PARAMETERS FROM SECTOR BUFR & ENABLE LOGON ; 3: RETURN PARAMETERS IN SECTOR BUFR & ENABLE LOGON ;---------------------------------------------------------------------------- SETFLGS: ; ; SELECT DRIVE TABLE ; CALL SELECT RET NZ ; ; TEST FOR COMMAND ERROR ; LD A,(CMDBLK + PBFLGO) CP A,4 JP NC,SPAR ; ; SET UP FOR XFER ; LD DE,DVFLG ;FETCH PTR CALL GETDVEL LD DE,SBUFR ; ; DETERMINE DIRECTION ; BIT 0,A JR NZ,RETFLGS ; EX DE,HL ; RETFLGS: PUSH BC LD BC,DVDFSZ LDIR POP BC ; ; SELECT LOGON OPTION ; BIT 1,A LD A,0 JR NZ,SF1 ; INC A ; SF1: LD (IX + DVLGDO),A ; RET ;---------------------------------------------------------------------------- ; ; LOAD HEAD & IDLE COMMAND (10) ; ;---------------------------------------------------------------------------- LDHDI: CALL SELECT RET NZ ; ; LOAD HEAD ; LD E,DCHDL CALL EXHEAD ; ; WAIT FOR INTERRUPT ; LDHDI2: IN A,(XPMTX) ;KICK UNLOAD TIMEOUT IN PANTS IN A,(BLSTS) ;CHECK FOR INTERRUPT AND A,BSINT JR Z,LDHDI2 ; IN A,(XPIRR) ;CLEAR PENDING INTERRUPT RET ;---------------------------------------------------------------------------- ; ; SEEK TRACK COMMAND (11) ; ;---------------------------------------------------------------------------- SEEKTRK: CALL SELECT CALL Z,SEEK RET ;---------------------------------------------------------------------------- ; ; SET DRIVE PARAMETERS COMMAND (12) ; ENTRY- PBFLG= 0: SET PARAMETERS FROM SECTOR BUFFER ; 1: RETURN PARAMETERS IN SECTOR BUFFER ; ;---------------------------------------------------------------------------- SETDP: ; ; SELECT DRIVE TABLES ; CALL SELECT RET NZ ; ; TEST FOR COMMAND ERROR ; LD A,(CMDBLK + PBFLGO) CP A,2 JP NC,SPAR ; ; SET UP FOR XFER ; CALL GETDVHLD LD DE,SBUFR PUSH BC LD BC,TMSIZ ; ; DECIDE WHETHER SET OR RETURN DATA ; OR A,A JR NZ,RETDP ; EX DE,HL ; RETDP: LDIR ; ; IN ANY CASE, TRANSFER TO CURRENT VALUES ; CALL GETDVHLD LD DE,TMHLD LD BC,TMSIZ LDIR POP BC RET ;---------------------------------------------------------------------------- ; ; RETURN DRIVE STATUS COMMAND (13) ; ;---------------------------------------------------------------------------- RETDST: ; ; SELECT DRIVE ; CALL SELECT RET NZ ; ; RETURN DRIVE STATUS DATA ; IN A,(BLSTS) LD (CMDBLK + PBST2O),A RET ;---------------------------------------------------------------------------- ; ; SET EIA BAUD RATES COMMAND (14) ; ;---------------------------------------------------------------------------- SETBAUD: LD A,(CMDBLK + PBST5O) ;FETCH BAUD RATE DATA ; ; IF RATE == -1 THEN RETURN CURRENT RATE ; INC A JR NZ,SETBD3 ; LD A,(BAUDOUT) LD (CMDBLK + PBST5O),A RET ; ; ; IF OUT OF RANGE THEN RETURN ERROR ; SETBD3: DEC A CP A,MAXBAUD JR C,SETBD1 ; ; ARGUMENT ERROR, RETURN IT ; SETBD2: LD A,BRERR JP RETFER ; ; FETCH BAUD RATE ; SETBD1: LD HL,BAUDS ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) ; ; IF ILLEGAL BAUD RATE THEN RETURN ERROR ; INC A JR Z,SETBD2 ; ; ELSE STORE NEW BAUD RATE ; DEC A LD (BAUDOUT),A RET BAUDS: IF DSIZE = 8 DB 0,-1,248,121,57,25,9 ELSE DB 0,248,121,57,25,9,-1 ENDIF MAXBAUD EQU $ - BAUDS ;---------------------------------------------------------------------------- ; ; CLEAR COMMAND (15) ; ;---------------------------------------------------------------------------- CLR: JP SLEEP ;BREAK TO START SUBTTL SUBROUTINES ;************************************************ ; ; OUTPUT EIA BIT ; ENTRY- CF= BIT TO OUTPUT ; A= BLCTL IMAGE ; HL= BAUD RATE DIVISOR PTR ; EXIT - B= 0 ; A= LAST BLCTL DATA ; ;************************************************ BITOUT: JP C,BITO1 ; ; BIT IS 0, OUTPUT 0 ; RES 3,A JP BITO2 ; ; BIT IS 1, OUTPUT 1 ; BITO1: SET 3,A JP BITO2 ;EQUALIZE CLOCKS ; ; OUTPUT THE BIT ; BITO2: OUT (BLCTL),A ; ; DELAY FOR BAUD RATE ; LD B,(HL) DJNZ $ RET ;*************************************************************************** ; ; THIS SUBROUTINE IS RESPONSIBLE FOR SELECTING THE COMMAND REQUESTED DRIVE ; #. BEFORE DRIVE SELECTION, THE DRIVE MOTOR STATE IS TESTED AND IF NEEDED, ; THEY ARE TURNED ON. ; EXIT - IX= NEW DRIVE TABLE ; AF= 0: OK, /0: ERR ; B, DE, HL= ? ; ;*************************************************************************** SELECT: ; ; ENABLE DRIVE SELECT & FDC INTERRUPT ; LD A,(SVCTL) OR A,BCDSE CALL SETCTL ; ; IF REQUESTED DRIVE = CURRENT DRIVE THEN OK AS IS ; LD A,(CMDBLK + PBDRVO) SUB A,(IX + DVNBR) JR Z,SELEN ; ; UNLOAD HEAD ON CURRENT DRIVE ; LD E,DCHDU CALL EXHEAD ; ; DESELECT CURRENT DRIVE ; LD A,(SVCTL) ;DESELECT CURRENT DRIVE, AND A,[NOT BCDSE] CALL SETCTL ; ; IF REQUESTED DRIVE NOT LEGAL THEN RETURN ERROR ; LD A,(CMDBLK + PBDRVO) ;FETCH REQUESTED DRIVE CP A,4 JR C,SELCT1 ; LD A,SELERR OR A,A JP RETFER ; ; NOW SELECT REQUESTED DRIVE ; SELCT1: LD L,A ;SAVE NEW DRIVE LD A,(SVCTL) ;STRIP OLD DRIVE AND A,NOT (BCDSN + BCDSE) OR A,L ;ADD IN NEW DRIVE OUT (BLCTL),A OR A,BCDSE ;NOW ENABLE IT CALL SETCTL ; ; SELECT NEW DRIVE TABLE ; AND A,BCDSN LD IX,DVTBL LD DE,DVDES ;DRIVE TABLE ARRAY SIZE ; NEXT: DEC A ;IF DRIVE = 0 THEN EXIT WITH POINTER SET JP M,SLED ; ADD IX,DE ;ELSE POINT TO NEXT ARRAY & REPEAT JR NEXT ; ; IX NOW HAS DRIVE TABLE PTR, INITIALIZE DRIVE DATA ; SLED: CALL GETDVHLD LD DE,TMHLD PUSH BC LD BC,TMSIZ LDIR POP BC ; ; IF MOTOR OFF THEN START MOTOR ; SELEN: IN A,(BLSTS) ;GET BOARD LEVEL STATUS AND A,BSMOF ; IN A,(XPMTX) ;ISSUE MOTOR START OR CONTINUE IN EITHER CASE ; JR Z,CKDV ; ; IF MOTOR STARTED AFTER TIMEOUT THEN ASSUME MOTOR ON DELAY REQUIRED ; LD DE,(TMMTO) RST 8 ; ; FETCH DRIVE READY STATUS FROM FDC ; CKDV: CALL EXSTS ;SET FLAGS PER DRIVE READY AND A,DMDNR JP RETERR ;IF 0 THEN OK ;*************************************************************************** ; ; HOMED SUBROUTINE STEPS THE DISK DRIVE HEAD OUTWARD UNTIL TRACK 0 FLAG IS ; TRUE OR 255 STEPS HAVE BEEN ISSUED. ; EXIT - AF= 0: OK, /0: TRK 0 NOT FOUND ; B, DE, HL= ? ; ;*************************************************************************** HOMED: ; ; IF NOT ALREADY ON TRACK 0 THEN SKIP RECALIBRATE ; CALL EXSTS ;IF NOT TRK 0 THEN NO RECAL AND A,DMTK0 JR Z,HOME1 ; ; STEP IN 10 TRACKS TO INSURE INSIDE TRACK 0 ; LD L,10 ;ELSE STEP IN BEYOND TRK 0 LD A,(SVCTL) ;SELECT 'IN' OR A,BCDAS CALL SETCTL ; ; STEP ONCE ; RECAL1: IN A,(XPSTP) LD DE,(TMSTPC) RST 8 ; ; IF NOT 10 TRACKS THEN REPEAT ; DEC L JR NZ,RECAL1 ; ; NOW STEP OUT UNTIL TRACK 0 FOUND ; HOME1: LD A,(SVCTL) ;RESTORE DIRECTION AND A,NOT BCDAS CALL SETCTL ; ; SET MAX TRACKS TO STEP TO ; LD L,NBTRK ;SET MAX COUNT ; ; IF ON TRACK 0 THEN DONE ; STEP: CALL EXSTS ;IF ON TRACK 0 THEN EXIT AND A,DMTK0 JR NZ,EXIT ; ; IF > MAX TRACKS THEN RECAL ERROR ; DEC L ;IF STEPS = 255 THEN ERROR JR Z,EROR ; ; STEP ONCE ; IN A,(XPSTP) ;ISSUE STEP PULSE LD DE,(TMSTPC) ;SET DELAY RST 8 JR STEP ; ; DRIVE IS RESTORED, WAIT FOR SETTLING TIME ; EXIT: LD DE,(TMALS) ;WAIT A BIT AFTER LAST STEP RST 8 ; ; CURRENT TRACK = 0 ; XOR A,A ;SET COMPLETE FLAG & NO ERROR LD (IX+DVTRK),A ;SET TRACK VALUE ; ; RETURN NO ERROR ; RET ; ; TRACK 0 NOT FOUND ; EROR: LD A,SEEKERR ;SET FAILURE FLAG OR A,A ;SET NZ FLAG (ERROR) JP RETFER ;*************************************************************************** ; ; TRACK SEEK SUBROUTINE ; EXIT - DENSITY & PRE-COMP CONTROLS SET ; ZF= OK, NZ= ERROR ; B, DE, L= ? ; ;*************************************************************************** SEEK: ; ; IF HEAD NOT LOADED THEN LOAD HEAD ; CALL EXSTS AND A,DMHDL JR NZ,HLDD ; LD E,DCHDL CALL EXHEAD ; ; WAIT FOR HEAD SETTLING TIME ; LD DE,(TMHLD) RST 8 ; ; IF CURRENT TRACK = REQUESTED TRACK THEN NO SEEK REQUIRED ; HLDD: LD A,(CMDBLK + PBTRKO) SUB A,(IX + DVTRK) JR Z,SKDEN ;SET UP CONTROLS ANYWAY, IN CASE CHANGED ; ; SET DIRECTION & STEP COUNT ; DSET: ; ; SAVE TRACK DIFFERENCE ; PUSH AF ; ; DELAY FOR STEP AFTER WRITE REQUIREMENT ; LD DE,TMSAW ;DELAY FOR STEP AFTER WRITE RST 8 ; ; RESTORE TRACK DIFFERENCE ; POP AF ; ; IF REQUESTED < CURRENT TRACK THEN STEP OUT ; JR C,SOUT ;CARRY=STEP OUT ; ; ELSE STEP IN ; LD L,A ;COUNT LD A,(SVCTL) OR A,BCDAS CALL SETCTL JR STEPS ; ; STEP OUT REQUIRED ; SOUT: ; ; COMPUTE TRACK COUNT ; NEG ;COMPLEMENT OFFSET ; ; IF COUNT > 127 THEN HOME, MUST BE ERROR ; JP M,HOME ; ; SET UP TO STEP OUT ; LD L,A LD A,(SVCTL) AND A,NOT BCDAS ;CLEAR DIRECTION BIT CALL SETCTL ; ; STEP ONCE ; STEPS: IN A,(XPSTP) LD DE,(TMSTPC) RST 8 ; ; IF COUNT NOT EXHAUSTED THEN REPEAT ; DEC L ;IF STEPS-1 NOT 0 THEN STEP AGAIN JR NZ,STEPS ; ; WAIT FOR SETTLING TIME ; LD DE,(TMALS) ;ELSE EXTEND LAST PULSE RST 8 ; ; SET UP TRACK DENSITY & PRECOMPENSATION LEVEL ACCORDING TO TRACK NUMBER ; SKDEN: LD E,BCSDS + BCPCL ;USE SD, PRECOMP LOW AS DEFAULTS ; ; IF TRACK 0 THEN USE DEFAULTS ; LD A,(CMDBLK + PBTRKO) ;IF TRACK 0 THEN USE DEFAULTS CP A,1 JR C,TRK0 ; ; IF TRACK 1 THEN DO TRACK 1 ; JR Z,TRK1 ; ; IF DATA TRACKS ARE SINGLE DENSITY THEN USE DEFAULTS ; BIT DFDTDB,(IX + DVFLG) JR Z,CTLS ; ; *** MUST BE DOUBLE DENSITY IF MADE IT TO HERE *** ; ; IF TRACK < MEDIUM THRESHOLD THEN DO SAME AS TRACK 1 ; CP A,(IX + DVPCM) JR C,T1DD ; ; IF {TRACK < HIGH THRESHOLD} THEN DO MIDDLE VALUES ; CP A,(IX + DVPCH) LD E,BCDDE + BCPCM ;USE DOUBLE DENSITY, MEDIUM PRECOMP JR C,CTLS ; ; ELSE DO INNER VALUES ; LD E,BCDDE + BCPCH ;USE DOUBLE DENSITY, HIGH PRECOMP JR CTLS ; ; ; TRACK 0 ; TRK0: BIT DFT0DB,(IX + DVFLG) ;IF SD THEN USE DEFAULTS JR Z,CTLS JP T1DD ; ; ; TRACK 1 ; TRK1: BIT DFT1DB,(IX + DVFLG) ;IF SD THEN USE DEFAULTS JR Z,CTLS ; ; USE DOUBLE DENSITY, LOW PRECOMP ; T1DD: LD E,BCDDE + BCPCL ; ; SET CONTROLS ; CTLS: LD A,(SVCTL) ;ADD DENSITY, PRECOMP BITS TO CONTROL BITS AND A,NOT (BCDDE + BCPCA + BCPCB) ;CLEAR BITS 1ST OR A,E LD (IX + DVCTL),A ; ; SET CONTROLS ; EXITS: CALL SETCTL ; ; SET CURRENT TRACK ; LD A,(CMDBLK + PBTRKO) ;SET REQUESTED TRACK LD (IX + DVTRK),A XOR A,C OUT (WDTRK),A ;SET TRACK REGISTER ; ; RETURN NO ERRORS ; XOR A,A ;SET Z FLAG RET ; ; CALIBRATE TRACK # ; HOME: CALL HOMED ;HOME SELECTED DRIVE JP HLDD ;NOW SEEK TRACK ;*************************************************************************** ; ; HEAD LOAD/UNLOAD SUBROUTINES ; ENTRY - E= HEAD COMMAND ; EXIT - IY, A= ? ; ;*************************************************************************** EXHEAD: ; ; USE RETURN ADDRESS FOR INTERRUPT RETURN ; POP IY ;IY=RETURN ADDR ; ; PUT TRACK # INTO DATA REGISTER ; IN A,(WDTRK) ;PERFORM SEEK TO CURRENT TRACK WITH HEAD LOAD OUT (WDDTA),A ; ; OUTPUT PASSED COMMAND TO FDC ; LD A,E ;OUTPUT PASSED COMMAND XOR A,C OUT (WDCMD),A ; ; WAIT FOR FDC INTERRUPT ; JR $ ;WAIT FOR INTERRUPT ;*************************************************************************** ; ; GET STATUS SUBROUTINE ; EXIT - A= 1791 STATUS ; ;*************************************************************************** EXSTS: ; ; ISSUE TERMINATE FDC OPERATION & READ FDC STATUS COMMAND ; LD A,DCSTS ;OUTPUT SET STATUS COMMAND TO 1791 RST 32 ; ; RETURN FDC STATUS ; IN A,(WDSTS) XOR A,C RET ;**************************************************************************** ; ; READ/WRITE SECTOR SUBROUTINE INITIATES DISK XFER, SEVICES THE CONTROLLER ; CHIP DURING DATA XFER, & TERMINATES OPERATION WHEN FINISHED. ERROR ; DETECTION IS IMPLEMENTED & RETRIES ARE EXECUTED IF DATA ERRORS ARE DETECTED. ; ENTRY - D= 0: WRITE, /0: READ ; HL= XFER PTR ; DE'= PHYSICAL SECTOR # {1..N} (D15= SIDE BIT) ; EXIT - NZ= ERROR ; HL, A, B= ? ; ;**************************************************************************** RWSECT: ; ; SAVE THE XFER PTR ; LD (RWPTR),HL ; ; CLEAR ERROR COUNT ; XOR A,A LD (ERRCT),A ; ; SELECT SIDE ; LD A,D ;USE BIT 15 FOR SIDE SELECT AND A,80H RRCA ;SHIFT INTO CONTROLS BIT RRCA LD (SIDE),A IF DSIZE = 8 JP Z,SIDOK ; ; CHECK FOR ILLEGAL SIDE REQUEST ; IN A,(BLSTS) ;CHECK IF DRIVE CAPABLE AND A,BSTSD JP NZ,EROR ;IF NOT CAPABLE THEN SEEK ERROR ; SIDOK: ENDIF ; ; COMPUTE CONTROLS ; RWRTRY: LD HL,(RWPTR) ;RESTORE THE XFER PTR ; LD A,(SIDE) LD B,A LD A,(SVCTL) AND A,NOT BCDAS OR A,B CALL SETCTL ; ; SET FDC SECTOR REGISTER ; LD A,E XOR A,C OUT (WDSEC),A ; ; SET FDC INTERRUPT RETURN VECTOR ; LD IY,RWNMI ;SET NMI VECTOR FOR RETURN ; ; DEFAULT TO READ MODE ; LD B,DCRDS ; ; IF WRITE OPERATION THEN SET WRITE MODE ; EX AF,AF' OR A,A JR NZ,OPOK ; LD B,DCWRS ;WRITE OP ; ; OUTPUT COMMAND TO FDC ; OPOK: EX AF,AF' ;RE-SAVE MODE LD A,(SIDE) ;COMPUTE SIDE FLAG FOR FDC RRCA RRCA RRCA RRCA OR A,B ;OUTPUT READ SECTOR COMMAND RST 32 ; ; SELECT DIRECTION ; EX AF,AF' ;IF WRITE OP THEN GO DO IT JR Z,WROP ; EX AF,AF' ;RE-SAVE MODE ; ; READ DIRECTION ; RDREPT: ; ; OUTPUTTING TO THIS PORT GENERATES A CPU 'WAIT' UNTIL FDC READY ; IN A,(XPDSH) ; ; FDC READY, XFER DATA ; IN A,(WDDTA) XOR A,C LD (HL),A INC HL ;PTR +1 JR RDREPT ; ; OPERATION DONE, CHECK STATUS ; RWNMI: ; ; PASS BACK THE XFER COUNT ; PUSH DE LD DE,(RWPTR) OR A,A SBC HL,DE POP DE LD (CMDBLK + PBST4O),HL ; ; ASSUME READ ERROR MASK ; LD B,DMRER ;IF NO ERRORS THEN RETURN PUSH AF ;SAVE 179X STATUS ; ; IF WRITE MODE THEN USE WRITE ERROR MASK ; EX AF,AF' JR NZ,RWMSK ; LD B,DMWER ;WRITE ERR MASK ; ; RETURN OPERATION STATUS ; RWMSK: EX AF,AF' ;RE-SAVE MODE ; POP AF ;179X STATUS AND A,B RET Z ; ; SAVE THIS ERROR IN CASE RETRYS EXHAUSTED ; LD B,A PUSH BC ; ; SAVE SECTOR ; PUSH DE ; ; IF RETRYS NOT EXHAUSTED THEN RETRY ; CALL CHKRT POP DE POP BC ;FDC ERROR JR Z,RWRTRY ; ; RESTORE ERROR & RETURN IT ; LD A,B JP RETERR ; ; EXECUTION OF NEXT INSTRUCTION GENERATES A WAIT CONDITION UNTIL FDC READY ; WROP: EX AF,AF' ;RE-SAVE MODE ; REPTW: IN A,(XPDSH) ;HOLD FOR DATA REQ ; ; OUTPUT DATA TO FDC ; LD A,(HL) XOR A,C OUT (WDDTA),A ; ; POINT TO NEXT DATA ; INC HL JR REPTW ;**************************************************************************** ; ; CHECK FOR RETRYS SUBROUTINE ; EXIT - A= 0: OK, /0: HARD ERROR OR RETRYS EXHAUSTED ; ;**************************************************************************** CHKRT: ; ; IF ERROR IS DRIVE NOT READY THEN HARD ERROR ; AND A,DMDNR RET NZ ; ; IF NO RETRYS ALLOWED THEN RETURN HARD ERROR ; LD A,(CMDBLK + PBFLGO) AND A,1 SHL PBFNRB RET NZ ; ; KICK MOTOR ON IN THE PANTS AGAIN ; IN A,(XPMTX) ; ; BUMP ERROR COUNT ; LD A,(ERRCT) INC A LD (ERRCT),A ; ; IF HALF OF RETRYS EXHAUSTED THEN TRY RECALIBRATE ; CP A,RTYSK JR NZ,CKLS ; CALL HOMED ;HOME SELECTED DRIVE CALL Z,SEEK ;RE-SEEK DESIRED TRACK RET NZ ;IF ERROR THEN EXIT ; ; IF RETRYS EXHAUSTED THEN RETURN ERROR ; CKLS: CP A,RTYLS JR Z,STNZ ; ; DELAY A WHILE FOR PLL RECOVERY & RETURN WITH NO ERRORS ; LD DE,TMPLD ;ELSE WAIT & RETURN WITH NO ERRORS RST 8 ; XOR A,A RET ; ; RETURN RETRYS EXHAUSTED (NZ) ; STNZ: INC A RET ;---------------------------------------------------------------------------- ; ; INITIALIZATION FROM RESET VECTOR ; THIS ROUTINE CALLS THE COLD START SUBROUTINE & RUNS THE DIAGNOSTICS. ; ;---------------------------------------------------------------------------- CLEAR: ; ; SET UP HARDWARE ; LD SP,STACK ; ; SINGLE INTERRUPT MODE ; IM 1 ;SINGLE INTERRUPT MODE TO RST 56 ; ; TEST FOR INVERTED BUS FDC OPTION ; LD C,0 ;DEFAULT TO NON-INVERTED DATA IN A,(BLSTS) AND A,BSUS0 JR NZ,STOP ; ; IF INVERTED THEN SET REGISTER TO XOR DATA WITH 0FFH ; DEC C ; ; SET DRIVE TABLE POINTER TO DUMMY ; STOP: LD IX,DTDED ;SET DRIVE TABLE PTR ; ; INITIALIZE CONTROL PORT ; XOR A,A LD (EIACTL),A ;INIT EIA BIT CALL SETCTL ;BASE BLCTL BITS ; ; INITIALIZE DATA AREAS FROM ROM ; PUSH BC LD HL,IDATA LD DE,DATAA LD BC,DATASZ LDIR ; ; INIT OTHER VARIABLES ; LD A,(BAUDS + 2) ;BAUD RATE LD (BAUDOUT),A ; ; NOW DO DIAGNOSTICS ; ; TEST RAM 1ST ; LD HL,BANK0 ;TEST RAM LD BC,RAMSIZ ; NXTLOC: LD A,(HL) CPL LD (HL),A CP A,(HL) CPL LD (HL),A JR NZ,DRAMER ; INC HL DEC BC LD A,C OR A,B JR Z,RTSTDN JP NXTLOC ; ; RAM ERROR, RETURN ERROR TO HOST ; DRAMER: LD A,RAMERR POP BC ;RESTORE FDC POLARITY JR SETERR ; ; TEST INTERRUPT FLIP FLOP ; RTSTDN: POP BC ;RESTORE FDC DATA POLARITY IN A,(XPIRR) ;CLEAR INTERRUPT FF IN A,(BLSTS) ;FETCH INTERRUPT STATUS LD B,A ;SHOW IT TO HOST AND A,BSINT LD A,IFFER ;PASS BACK ERROR JR Z,SETERR ; ; TEST MOTOR ON ONE-SHOT ; IN A,(XPMTX) ;TURN ON MOTOR IN A,(BLSTS) ;FETCH STATUS LD B,A AND A,BSMOF LD A,MTONER ;ASSUME ERROR JR NZ,SETERR ; IN A,(XPMTO) ;TURN OFF MOTOR IN A,(BLSTS) LD B,A ;PASS BACK STATUS AND A,BSMOF JR Z,SETERR ; ; TEST FDC CHIP ; DFDCBSY: LD A,DCIFI ;GET FDC'S ATTENTION FIRST RST 32 ; DFDCB1: IN A,(WDSTS) ;WAIT FOR RESET SEQUENCE TO FINISH XOR A,C AND CSBSY JR NZ,DFDCB1 ; IN A,(WDTRK) ;CHECK FDC REGISTERS LD E,A CPL OUT (WDTRK),A LD B,A EX (SP),HL ;DELAY A WHILE FOR FDC TO CATCH UP EX (SP),HL EX (SP),HL EX (SP),HL IN A,(WDTRK) LD D,A XOR A,B LD B,1 JR NZ,WDBAD ; IN A,(WDSEC) LD E,A CPL OUT (WDSEC),A LD B,A EX (SP),HL EX (SP),HL EX (SP),HL EX (SP),HL IN A,(WDSEC) LD D,A XOR A,B LD B,2 JR Z,WDOK ; WDBAD: LD (CMDBLK + PBST3O),A ;PASS OUT DATA BIT ERROR (A 0= BAD) IN A,(WDSTS) ;PASS OUT FDC STATUS XOR A,C LD (CMDBLK + PBST1O),A LD A,E LD (CMDBLK + PBST4O),A LD A,D LD (CMDBLK + PBST5O),A LD A,FDCDER SETERR: LD (CMDBLK + PBSTATO),A LD A,B ;PASS OUT TEST # LD (CMDBLK + PBST2O),A WDOK: ; ; NOW DO RECAL COMMAND THAT MAY HAVE BEEN ABORTED FROM RESET ; LD A,00000000B RST 32 ; DFDCB2: IN A,(WDSTS) ;WAIT FOR COMMAND TO FINISH XOR A,C AND CSBSY JR NZ,DFDCB2 ; ; ALL DONE, SO GOING TO SLEEP ; SLEEP: LD SP,STACK EI ;DIAGNOSTICS OK, SET ALARM & GO TO SLEEP HALT ; ; WAKE-UP RETURNS HERE, SO RESTORE STACK & GO BACK TO SLEEP ; JR SLEEP SUBTTL CONSTANT DATA AREAS ;########################################################################### ; ; DISKETTE FORMAT LABEL ; ;########################################################################### DESCID DB 'Disk Descriptor ' ;NEW ID DIDSIZ EQU $ - DESCID ;########################################################################### ; ; DRIVE TABLE OFFSETS ; ;########################################################################### STRUCT 0 ; ; CONTROLLER DATA ; DVNBR DS 1 ;CURRENT PHYSICAL DRIVE # DVTRK DS 1 ;CURRENT PHYSICAL TRACK # DVSEC DS 1 ;CURRENT PHYSICAL SECTOR # DVCTL DS 1 ;LAST CONTROLS USED OFFSET DVLGDO DS 1 ;LOGON DISABLE FLAG ; ; DRIVE DATA ; DVHLDO DS 2 ;DRIVE HEAD LOAD DELAY VALUE DVSTPO DS 2 ;DRIVE STEP MOTOR RATE VALUE DVALSO DS 2 ;DRIVE DELAY AFTER LAST STEP VALUE DVMTOO DS 2 ;DRIVE MOTOR ON DELAY VALUE ; ; DISK FORMAT DATA ; DVFLG DS 1 ;DISK FORMAT FLAGS DVSPT0 DS 1 ;SECTORS PER TRACK 0 DVSSZ0 DS 1 ;SECTOR SIZE FOR TRACK 0 DVSPT1 DS 1 ;SECTORS PER TRACK 1 DVSSZ1 DS 1 ;SECTOR SIZE FOR TRACK 1 DVSPTD DS 1 ;SECTORS PER DATA TRACKS DVSSZD DS 1 ;SECTOR SIZE FOR DATA TRACKS DVPCM DS 1 ;MEDIUM PRECOMP START TRACK # DVPCH DS 1 ;HIGH PRECOMP START TRACK # ; DVSIZE DS 0 ENDM ;############################################################################ ; ; INITIAL DATA FOR RAM INITIALIZATION ; ;############################################################################ IDATA EQU $ ; ; DRIVE TABLES ; IRP #DRIVE,0,1,2,3 ; ; DRIVE TABLE FOR DRIVE #DRIVE ; DB #DRIVE ;;DRIVE # DB 255 ;;LAST TRACK # (-1 = UNUSED) DB 0 ;;LAST SECTOR # DB 0C4H + #DRIVE ;;LAST CONTROLS USED DB 0 ;;0: ENABLE, /0: DISABLE LOGON ; DW DFHLD ;;HEAD LOAD DELAY DW DFSTPC ;;STEP INTERVAL DELAY DW DFALS ;;DELAY AFTER LAST STEP DW DFMTO ;;MOTOR ON DELAY ; DB DFDFL ;;DEFAULT SSSD FORMAT FLAGS IF DSIZE = 8 REPT 3 DB 26 ;;26 SECTORS PER TRACK DB 0 ;;128 BYTES PER SECTOR ENDM DB 26 ;; MEDIUM PRECOMP START (1/3 TRACKS + 1) DB 52 ;; HIGH PRECOMP START (2/3 TRACKS + 1) ENDIF IF DSIZE = 5 REPT 3 DB 16 ;;16 SECTORS PER TRACK DB 0 ;;128 BYTES PER SECTOR ENDM DB 14 ;;MEDIUM PRECOMP START (1/3 TRACKS + 1) DB 27 ;;HIGH PRECOMP START (2/3 TRACKS + 1) ENDIF ENDM ; ; DUMMY DRIVE AS HANDLE ; DB 4,255,0,0,0 DW DFHLD,DFSTPC,DFALS,DFMTO DB 0 IF DSIZE = 5 REPT 3 DB 16,0 ENDM DB 14,27 ENDIF IF DSIZE = 8 REPT 3 DB 26,0 ENDM DB 26,52 ENDIF ;--------------------------------------------------------------------------- ; ; COMMAND BLOCK ; THIS IS THE HOST COMMUNICATION AREA ; ;--------------------------------------------------------------------------- REPT IOPBSZ DB 0 ENDM ; DATASZ EQU $ - IDATA ;SIZE OF INITIALIZATION SUBTTL DATA AREA ;############################################################################ ; ; BANK 0 ; ;############################################################################ ORG BANK0 ; ; FORMAT DRIVER BUFFER ; DS 512 ;FORMAT DRIVER BUFFER ; ; LOCAL DATA ; ORG BANK0 + 2F0H ; ; STACK GROWS TOWARD FORMAT BUFFER ; STACK EQU $ SIDE DS 1 ;SIDE SAVE {0,80H} ERRCT DS 1 ;RETRY COUNT {0..9} SVCTL DS 1 ;LAST BLCTL OUTPUT IMAGE EIACTL DS 1 ;EIA BIT TO OUTPUT TO CONTROL PORT BAUDOUT DS 1 ;EIA OUTPUT BAUD RATE RWPTR DS 2 ;R/W XFER POINTER ; ; *** THE FOLLOWING 8 BYTES MUST BE IN THIS ORDER FOR PROPER INITIALIZATION *** ; TMHLD DS 2 ;CURRENT DRIVE HEAD LOAD DELAY TMSTPC DS 2 ;CURRENT DRIVE STEP RATE TMALS DS 2 ;CURRENT DRIVE AFTER LAST STEP DELAY TMMTO DS 2 ;CURRENT DRIVE MOTOR ON DELAY TMSIZ EQU $ - TMHLD ;SIZE OF DRIVE PARAMETERS ; ; INITIALIZED DATA ; IF $ > (BANK0 + DDCBO - (DVSIZE * 5)) CONMSG **** UNINITIALIZED DATA OVERLAPS INITIALIZED DATA! **** ENDIF ORG BANK0 + DDCBO - (DVSIZE * 5) ;POSITION BLOCK DATAA EQU $ ; ; DRIVE TABLES ; DVTBL DS DVSIZE * 4 DTDED DS DVSIZE ;DUMMY DVDES EQU DVSIZE ;########################################################################### ; ; COMMAND BLOCK ; THIS IS THE HOST COMMUNICATION AREA ; ;########################################################################### CMDBLK: DS IOPBSZ ;RESERVE ENOUGH SPACE IF ($ - DATAA) <> DATASZ CONMSG **** DATA INITIALIZATION PHASE ERROR **** ENDIF ;########################################################################### ; ; PHYSICAL SECTOR BUFFER (UP TO 1K) ; ;########################################################################### ORG BANK1 SBUFR EQU $ ;PHYSICAL SECTOR BUFFER END