|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 18944 (0x4a00) Types: TextFile Names: »CR16MFD.ASM«
└─⟦b445f10af⟧ Bits:30004389 CP/M Plus Source files └─ ⟦this⟧ »CR16MFD.ASM«
TITLE 'CR16 MINI FLOPPY DISK I/O MODULE - DATE:840406' PAGE 43 ;************************************************************************ ;* THE MFDIO MODULE * ;* * ;* MINI FLOPPY FORMAT IS AS FOLLOWS: * ;* * ;* 77 TRACKS * ;* 8 RECORDS PER TRACK * ;* TWO HEADS/SIDES * ;* 512 BYTE RECORDS * ;* LOGICAL DRIVE G,H * ;* * ;************************************************************************ MACLIB PORTS ; MACLIB CPM3 ; MACLIB Z80 ; if ((hwconfig and cr16mfd) eq cr16mfd) PUBLIC CR160DPH,cr161dph EXTRN DSKTMR,MONCNT ;(BOOT) EXTRN ?XMOVE,?MOVE,MA3MIR ;(MOVE) EXTRN ?BNKSL EXTRN @ADRV ;ABSOLUTE DRIVE NUMBER (8 BITS) EXTRN @RDRV ;RELATIVE DRIVE NUMBER (8 BITS) EXTRN @DMA ;DISK TRANSFER ADDRESS (16 BITS) EXTRN @TRK ;DISK TRACK ADDRESS (16 BITS) EXTRN @SECT ;DISK SECTOR ADDRESS (16 BITS) ;; EXTRN @CNT ;RECORD COUNT FOR MULTI SECTOR TRANSFER EXTRN @DBNK ;DISK TRANSFER BANK (8 BITS) EXTRN @CBNK ;CURRENT CPU BANK EXTRN @ERMDE ;BDOS ERROR MODE EXTRN ?PDERR ;PRINT BIOS DISK ERRROR HEADER EXTRN ?PMSG ;PRINT MESSAGE UNTIL 0 EXTRN ?PDEC ; EXTRN ?CONIN ; EXTRN ?WBOOT ; ;EXTENDED DISK PARAMETER HEADERS (XDPH'S) DSEG ;BANKED MEMORY dw mfd$wr$trk dw mfd$rd$trk DW FORMAT ; DW MFD$WRITE ; DW MFD$READ ; DW MFD$LOGIN ; DW MFD$INIT0 ; DB 0,0 ; CR160DPH: DPH 0,MFDDPB dw mfd$wr$trk dw mfd$rd$trk DW FORMAT ; DW MFD$WRITE ; DW MFD$READ ; DW MFD$LOGIN ; DW MFD$INIT0 ; DB 1,0 ; CR161DPH: DPH 0,MFDDPB CSEG ;COMMON MEMORY MFDDPB: DPB 512,8,154,2048,64,1 PAGE DSEG ;REST IS BANKED MEMORY ;************************************************************************ ;* * ;************************************************************************ MFD$LOGIN: RET ;************************************************************************ ;* THE BOOT ENTRY CALLS EACH INIT ROUTINE DURING THE COLD START * ;* AND PRIOR TO ANY OTHER DISK ACCESS,THE INIT ROUTINE PERFORMS * ;* ANY NECESSARY HARDWARE INIT SUCH AS SETTING UP THE CONTROLLER * ; AND INTERRUPT VECTORS. * ;************************************************************************ MFD$INIT0: RET ; ;************************************************************************ ;* THE PARAMETERS FOR THE READ/WRITE ROUTINES ARE CONTAINED IN * ;* THE PUBLIC VARIABLES :@ADRV,@RDRV,@TRK,@SECT,@DMA,@CNT,@DBNK * ;* * ;* INPUT : <DE> = ADDRESS OF XDPH * ;* * ;* OUTPUT: <A> = 00H ,NO ERROR * ;* <A> = 01H ,PERMANENT ERROR * ;* * ;************************************************************************ MFD$READ: mvi a,1 sta @cnt LXI H,RD$MSG ;POINT AT 'READ' MVI A,C$MFD$RDMSEC ;1793 READ COMMAND MVI B,C$DMA$READ ;Z80-DMA COMMAND JMP RW$COMMON ; MFD$WRITE: mvi a,1 sta @cnt LXI H,WR$MSG ;POINT AT 'WRITE' MVI A,C$MFD$WRMSEC ;1793 WRITE COMMAND MVI B,C$DMA$WRITE ;Z80-DMA COMMAND JMP RW$COMMON ; mfd$rd$trk: MVI A,8 ;SET NUMBER OF SECTORS STA @CNT ; MVI A,0 ;SET START SECTOR STA @SECT ; LXI H,RD$MSG ;POINT AT 'READ' MVI A,C$MFD$RDMSEC ;1793 READ COMMAND MVI B,C$DMA$READ ;Z80-DMA COMMAND JMP RW$COMMON ; mfd$wr$trk: MVI A,8 ;SET NUMBER OF SECTORS STA @CNT ; MVI A,0 ;SET START SECTOR STA @SECT ; LXI H,WR$MSG ;POINT AT 'WRITE' MVI A,C$MFD$WRMSEC ;1793 WRITE COMMAND MVI B,C$DMA$WRITE ;Z80-DMA COMMAND JMP RW$COMMON ; MFD$FORMAT: LXI H,FM$MSG ;POINT AT 'FORMAT' MVI A,C$MFD$FWRTRK ;1793 WRITE TRACK COMMAND MVI B,C$DMA$WRITE ;Z80-DMA COMMAND JMP RW$COMMON ; RW$COMMON: SHLD RW$NAME ;SAVE MESSAGE FOR ERRORS STA DISK$COMMAND ;SAVE 1793 COMMAND (FDCMD) MOV A,B ; STA DMA$COMMAND ;SAVE DMA DIRECTION CODE (DMCMD) XRA A ; STA DISK$STATUS ;RESET DISK STATUS LDA @TRK ; CPI 77 JNC SIDE$ONE STA FTRK XRA A STA FSIDE ;select side 0 JMP END$SIDE SIDE$ONE: MOV B,A ; MVI A,153 ; SUB B ; STA FTRK ;physical track = 153 - logical track MVI A,1 ; STA FSIDE ;select side 1 END$SIDE: CALL SETV ;SETUP UNIT,TRACK AND SECTOR ORA A ; CZ TEST ;FDIO OR FWRTTRK;READ/WRITE "FCNT","FSIZE" BYTE SECTORS STA DISK$STATUS ; ORA A RZ ; RW$ERROR: LDA @ERMDE ;SUPPRESS ERROR MESSAGE, IF BDOS IS RETURNING CPI 0FFH ; ERRORS TO APPLICATION JZ HARD$ERROR ; CALL ?PDERR ;PRINT BIOS DISK ERROR HEADER LHLD RW$NAME ; CALL ?PMSG ; LDA DISK$STATUS ;GET STATUS BYTE FROM LAST ERROR CPI 0FFH ; JZ HARD$ERROR ; LXI H,ERROR$TABLE ; ERRM1: MOV E,M ;GET NEXT MESSAGE ADDRESS INX H ; MOV D,M ; INX H ; ADD A ;SHIFT LEFT AND PUSH RESIDUAL BITS WITH STATUS PUSH PSW ; XCHG ;PRINT MESSAGE ,SAVING TABLE POINTER CC ?PMSG ; XCHG ; POP PSW ;IF ANY MORE BITS LEFT CONTINUE JNZ ERRM1 ; CALL ?CONIN ;GET RESPONSE CPI 'C'-040H ;IF CTL-C WARM BOOT PUSH PSW CALL HARD$ERROR POP PSW JZ ?WBOOT ; HARD$ERROR: DI XRA A STA MONCNT ; EI ; MVI A,01H ;RETURN HARD ERROR TO BDOS RET ; TEST: LDA DISK$COMMAND ; CPI C$MFD$FWRTRK ; JZ FWRTTRK ; JMP FDIO ; ;------------------------------------------------------------------------- SETV: MVI A,0AH ;SET MINI FLOPPY RETRY COUNT STA MERCNT ; SETVLP: LDA MA3MIR ;SEE IF DRIVE MOTOR STILL ON ANI 080H ;MASK DRIVE BIT ON MVI A,XS$DELAY ;SET VERY SHORT SPINUP DELAY JNZ SETSP ;GO SETUP TIMER FOR SPINUP MVI A,M$DELAY ;USE LONG SPINUP TIME DELAY SETSP: STA DSKTMR ;START COUNTING LDA @RDRV ;GET DRIVE NUMBER MOV E,A ;INDEX DRIVE TABLE FOR PRESENT TRACK MVI D,00H ; LXI H,TRKTAB ; DAD D ; MOV A,M ;GET TRACK NUMBER FROM TABLE CPI 0FFH ;SEE IF JUST LOGGED OR JNZ SETNRST ;REQUIRES A RESTORE PUSH H ; CALL FRESTR ; POP H ; ORA A ;CHECK RESTORE STATUS RNZ ;RETURN IF ERROR SETNRST: PUSH H ;SAVE DRIVE TABLE INDEX LDA @RDRV ;GET DRIVE NUMBER AGAIN CALL GETUNMO ;SET UNIT AND GET TRACK NUMBER POP H ; PUSH PSW ;SAVE DESIRED TRACK NUMBER SPUPLP: LDA DSKTMR ; ANA A ;WAIT FOR SPINUP TIME TO ELAPSE JNZ SPUPLP ; MOV A,M ;GET CURRENT TRACK OUT P$MFD$TRK ;OUT TO CONTROLLER POP PSW ;RESTORE TRACK NUMBER CMP M ; JZ SETV1 ; OUT P$MFD$DATA ;DESIRED TRACK TO CONTROLLER MOV M,A ; PUSH H ; MVI A,C$MFD$SEEK ;MINI FLOPPY SEEK COMMAND ORI MFD$STEP$RATE ;PUT IN THE STEP RATE BITS CALL OCMD ;OUTPUT MINI FLOPPY COMMAND PUSH PSW ;SAVE STATUS MVI A,S$DELAY ;SET HEAD SETTLING DELAY TO 25 mSEK STA DSKTMR ; SETHSD: LDA DSKTMR ; ANA A ;WAIT FOR HEAD DELAY TO ELAPSE JNZ SETHSD ; POP PSW ;RESTORE STATUS POP H ;RESTORE TRACK TABLE POINTER STA FSTAT ;SAVE FULL STATUS FOR DIAGNOSTIC CPI 0FFH ;CHECK THE SEEK FOR TIMEOUT ERROR RZ ; ANI 01H ;MASK STATUS FOR CONTROLLER BUSY JZ SETV1 ;SEEK OK =>FINISH SETUP MOV C,A ;SAVE SEEK STATUS LDA MERCNT ;GET SEEK RETRY COUNT DCR A ; STA MERCNT ;SAVE FOR NEXT LOOP MOV A,C ;RESTORE STATUS RZ ; MVI M,0FFH ;SET TRACK TABLE ENTRY TO FORCE A RESTORE JMP SETVLP ; SETV1: LDA @SECT INR A OUT P$MFD$SECT ; XRA A ;CLEAR FOR NO ERRORS RET ;------------------------------------------------------------------------- SETUPDMA: if crtype eq CR8 LDA @DBNK ; MOV B,A MOV C,A CALL ?XMOVE LXI B,0 CALL ?MOVE ;RESET XMOVE FLAG else LDA @DBNK ;Get and save DMA-buffer bank STA DBNK LDA @CBNK ;Get and save current CPU bank STA CBNK endif XRA A ; OUT P$DMA$CLEAR ;MASTER CLEAR DMA CONTROLLER MVI A,040H ; OUT P$DMA$STAT ;SET HARDWARE ATTRIBUTES LDA DMA$COMMAND ;GET DMA MODE BYTE FOR THIS OPERATION OUT P$DMA$MODE ;TELL DMA WHAT TRANSFER WE WANT MVI A,041H ; OUT P$DMA$MODE ; INR A ; OUT P$DMA$MODE ; INR A ; OUT P$DMA$MODE ;SET UNUSED CHANNELS TO VERIFY MODE LHLD @DMA ;POINT TO THE DATA BUFFER OUT P$DMA$TOGGLE ;RESET HI/LO FLIP-FLOP MOV A,L ;LSB OF DMA BUFFER ADDRESS OUT P$DMA$ADR0 ; MOV A,H ;MSB OF DMA BUFFER ADDRESS OUT P$DMA$ADR0 ; RET ;------------------------------------------------------------------------ INIDMA: ;RESTORE DEFAULT DMA SETUP XRA A ; OUT P$DMA$CLEAR ;MASTER CLEAR DMA CONTROLLER MVI A,C$DMA$BYTE ; OUT P$DMA$STAT ; MVI A,88H ; OUT P$DMA$MODE ; MVI A,85H ; OUT P$DMA$MODE ; MVI A,82H ; OUT P$DMA$MODE ; MVI A,83H ; OUT P$DMA$MODE ; RET ; ;---------------------------------------------------------------------------- FDIO: MVI A,10 ; STA MRWCNT ; FPS1: CALL SETUPDMA ; LXI D,512 ;2*256 BYTES SECTOR LDA @CNT ;MULTI SECTOR COUNT IN 512 BYTES SECTORS LXI H,0 ; MORESH: DAD D ;MULTIPLY SECTOR COUNT BY SECTOR SIZE DCR A ; JNZ MORESH ; DCX H ; MOV A,L ;LSB OUT P$DMA$TOGGLE ; OUT P$DMA$CNT0 ; MOV A,H ;MSB OUT P$DMA$CNT0 ;SEND BYTE COUNT TO DMA LDA DISK$COMMAND ;GET COMMAND BYTE MOV D,A ; LDA FSIDE ;GET SIDE BYTE ANI 01H ; RLC ; RLC ; RLC ;SIDE BIT INTO POSITION ORA D ;PUT INTO COMMAND OUT P$MFD$STAT ;SEND COMMAND TO CONTROLLER MVI A,XL$DELAY ; STA DSKTMR ;MAX 2 SEC BEFORE THE CONTROLLER PBUSY: ;MUST BE BUSY LDA DSKTMR ;GET TIMER VALUE ANA A ; JZ IOTMOUT ;IF TIMEOUT THEN ABORT IN P$MFD$STAT ;GET STATUS RRC ; JNC PBUSY ;WAIT UNTIL CONTROLLER IS BUSY if crtype eq CR8 XRA A ; OUT P$DMA$MASK ;START DMA IOLP: IN P$MFD$STAT ;GET STATUS RRC ;SHIFT BUSY BIT INTO CARRY JNC FDIOTERM ;OUT IF NOT BUSY IN P$DMA$STAT ;GET DMA STATUS ANI 01H ;TEST IF TRANSFER COMPLETE JNZ FDIOTERM ; LDA DSKTMR ;GET TIMER VALUE ANA A ;TEST FOR TIMEOUT JNZ IOLP ; else JMP DSK$RW CSEG DSK$RW: LDA DBNK CALL ?BNKSL XRA A OUT P$DMA$MASK ;START DMA IOLP: IN P$MFD$STAT RRC JNC FDTERM IN P$DMA$STAT ANI 01H JNZ FDTERM LDA DSKTMR ANA A JNZ IOLP CALL EXIT$RW JMP IOTMOUT FDTERM: CALL EXIT$RW JMP FDIOTERM EXIT$RW: LDA CBNK CALL ?BNKSL LDA DBNK STA @DBNK RET DBNK DB 0 CBNK DB 0 DSEG endif IOTMOUT: CALL ENDCMD ;FORCE COMMAND TERMINATION MVI A,0FFH ;SET TIMEOUT ERROR FPS2: STA FSTAT ; SEEKERR: LDA MRWCNT ; DCR A ; STA MRWCNT ;DECREMENT RETRY COUNT JNZ FPS3 ; CALL INIDMA ;RESTORE DEFAULT DMA SETUP LDA FSTAT ; RET ; FPS3: CALL FRESTR ;RESTORE DISK ORA A ; JNZ SEEKERR ;RETRY IF RESTORE ERROR CALL SETV ; ORA A ; JNZ SEEKERR ; JMP FPS1 ;SEEK OK TRY AGAIN FDIOTERM: CALL ENDCMD ; STA FSTAT ; MVI B,0DCH ;ASSUME WRITE BIT MASK' LDA DISK$COMMAND ; CPI C$MFD$WRMSEC ; JZ WROP ; MVI B,09CH ; WROP: LDA FSTAT ;GET CONTROLLER STATUS ANA B ;MASK OF UNUSED BITS JNZ FPS2 ; MVI A,XL$DELAY ; STA DSKTMR ; CALL INIDMA ;RESTORE DEFAULT DMA SETUP XRA A ; STA MONCNT ;CLEAR MOTOR-ON COUNT RET ; ;************************************************************************ ; MINI FLOPPY FORMAT ROUTINE WILL FORMAT ALL TRACKS ON BOTH ; SIDES OF A MINI FLOPPY DISKETTE. THE TRACK NUMBERS ARE CYCLED ; TO TWICE THE NUMBER OF TRACKS PER SIDE SO THAT THE LEAST ; SIGNIFICANT BIT BECOMES THE SIDE SELECT BIT FOR THE DOUBLE ; HEADED TANDON TM100 96 TPI DRIVE. ; FORMAT: LDA @TRK ;IF TRACK ZERO RESTORE UNIT ORA A ; JNZ FMT2 FMT1: CALL FRESTR ;RESTORE SELECTED UNIT ORA A ;CHECK RESTORE STATUS JNZ RW$ERROR ;OUT IF ERROR MVI A,M$DELAY STA DSKTMR DELAY: LDA DSKTMR ; ANA A ; JNZ DELAY ; FMT2: CALL MFD$FORMAT ; ORA A ;CHECK ERROR STATUS RNZ ;IF WRITE ERROR THEN QUIT CALL mfd$rd$trk ; ORA A ;AND CHECK IT RNZ ;IF VERIFY ERROR THEN QUIT LXI H,TRKMSG ; CALL ?PMSG ;PRINT 'TRACK' MVI H,0 ; LDA @TRK ; MOV L,A ; CALL ?PDEC ;PRINT ACTUAL TRACK NUMBER XRA A ;RESET ERROR STATUS STA FSTAT ; STA DISK$STATUS ; RET ; ;************************************************************************* ; ROUTINE TO WRITE COMPLETE TRACK OF A SELECTED MINI FLOPPY ; DATA IS READ FROM THE DATA BUFFER AT "@DMA" PUT ONTO THE CURRENT ; MINI FLOPPY DISK POSITION. "@CNT" 128 BYTE GROUPS OF DATA ARE SENT ; TO THE MINI FLOPPY. ; FWRTTRK: MVI A,10 ;SET RETRY COUNT STA MRWCNT WTRET: CALL SETUPDMA ; LXI H,1900H ; MOV A,L ;LSB OUT P$DMA$TOGGLE ; OUT P$DMA$CNT0 ; MOV A,H ;MSB OUT P$DMA$CNT0 ;SEND BYTE COUNT TO DMA LDA DISK$COMMAND ; OUT P$MFD$STAT ; MVI E,01H ; MVI A,L$DELAY ; STA DSKTMR ; XTHL ; XTHL ;DELAY FOR 1793 TO SETUP WRTWLP: IN P$MFD$STAT ;GET CONTROLLER STATUS ANA E ;TEST IF READY FOR DATA JNZ STADMA ;WAIT IF NOT LDA DSKTMR ;GET PRESENT TIMER VALUE ANA A JNZ WRTWLP ;LOOP IF NOT TIMEOUT WTTMOUT: MVI A,0FFH STA FSTAT ;FLAG TIMEOUT RTRY: LDA MRWCNT ;GET AND DECREMENT RETRY COUNT DCR A STA MRWCNT JNZ WTRET ;GO TRY AGAIN UNTIL RETRY COUNT ZERO CALL ENDCMD ;FORCE TERMINATION CALL INIDMA ;RESTORE DEFAULT DMA SETUP LDA FSTAT ;GET ERROR STATUS RET if crtype eq CR8 STADMA: XRA A OUT P$DMA$MASK ;START DMA MVI A,XL$DELAY STA DSKTMR ;ALLOW 2-3 SEC. BEFORE ABORT FINLP: IN P$MFD$STAT ;GET CONTROLLER STATUS RRC JNC NOTBSY ;EXIT WHEN CONTROLLER NOT BUSY LDA DSKTMR ANA A JNZ FINLP ;LOOP UNTIL TIMEOUT JMP WTTMOUT ;GO RETRY else CSEG STADMA: LDA DBNK CALL ?BNKSL XRA A OUT P$DMA$MASK ;START DMA MVI A,XL$DELAY STA DSKTMR ;ALLOW 2-3 SEC. BEFORE ABORT FINLP: IN P$MFD$STAT ;GET CONTROLLER STATUS RRC JNC PRE$NOTBSY ;EXIT WHEN CONTROLLER NOT BUSY LDA DSKTMR ANA A JNZ FINLP ;LOOP UNTIL TIMEOUT CALL EXIT$RW JMP WTTMOUT ;GO RETRY PRE$NOTBSY: CALL EXIT$RW JMP NOTBSY DSEG endif NOTBSY: RLC ;SHIFT BITS INTO ORIGINAL POSITION STA FSTAT ;SAVE STATUS ANI 04H ;TEST IF CONTROLLER SATISFIED JNZ RTRY ;IF NOT - GO RETRY CALL ENDCMD ;GO FORCE TERMINATION STA FSTAT ANI 0DDH ;LEAVE ONLY ACTUAL BITS JNZ RTRY ;SOMETHING WRONG - TRY AGAIN CALL INIDMA ;RESTORE DEFAULT DMA SETUP LDA FSTAT ;GET STATUS ANI 0DDH RET ;****************************************************************************** ; ; ROUTINE TO CALCULATE MAP3 OUTPUT BYTE FOR MINI FLOPPY ADDRESSED BY ; PHYSICAL UNIT NUMBER IN (A), WITHOUT CHANGING MAP BITS. ; HEAD SELECT BIT BASED UPON THE PHYSICAL SIDE SELECT BYTE OF FSIDE. ; SUBROUTINE RETURNS WITH (A) EQUAL TO THE APPROPIATE PHYSICAL ; TRACK NUMBER FOR SUBSEQUENT SEEK ROUTINE CALL. ; GETUNMO: ANI 01H ;LIMIT SELECT TO ONLY TWO DISKS MOV B,A INR B ;ADJUST DRIVE NUMBER FOR 1 BASED LOOP MVI A,08H ;CONVERT BINARY TO LINEAR SELECT BINLIN: RLC ;ROTATE BIT INTO POSITION DCR B ;DONE SHIFTING? JNZ BINLIN ORI 080H ;TURN ON MINI FLOPPY MOTORS MOV B,A ;SAVE CODE SO'S WE CAN FIGURE OUT HEAD LDA FSIDE ;GET SINGLE BYTE FLOPPY SIDE NUMBER RRC ;MOVE INTO POSITION RRC ANI 040H ;STRIP OFF ALL BUT HEAD BIT ORA B ;GET FINAL COPY OF DRIVE CONFIG BYTE MOV B,A LDA MA3MIR ;GET MAP3 MIRROR ANI 0FH ;STRIP PREVIOUS DISK CONTROL BITS ORA B ;INSERT NEW DISK CONTROL BITS STA MA3MIR ;SAVE TILL NEXT TIME WE COME HERE OUT P$MAP3 ;UPDATE REGISTER LDA FTRK ;RETURN TRACK NUMBER FOR CALLER RET ****************************************************************************** ; ; ROUTINE TO OUTPUT MINI FLOPPY COMMAND IN (A). ROUTINE WAITS A ; MAXIMUM OF THREE SECONDS FOR A READY CONDITION BEFORE RETURNING ; A "0FFH" TIMEOUT CODE IN THE (A) REGISTER ; OCMD: OUT P$MFD$STAT ;SET COMMAND TO THE 1793 PUSH D LXI D,04FFFH ;MAXIMUM DELAY CALL WAIT1 POP D RET ; ****************************************************************************** ; ; WAIT FOR 1793 FLOPPY DISK CONTROLLER TO BECOME READY. THE ENTRY AT ; "WAIT1:"USES THE DELAY PARAMETER SET BY THE (DE) REGISTER PAIR. ; WAIT1: XTHL ;NOP TYPE DELAY XTHL XTHL XTHL IN P$MFD$STAT ;GET 1793 STATUS MOV C,A ;SAVE IN (C) ANI 01H ;SEE IF BUSY JZ WAIT2 ;RETURN IF NOT BUSY DCX D ;IF STILL BUSY THEN DEC LOOP DELAY COUNT MOV A,E ORA D ;DELAY COUNT DOWN TO ZERO YET? JNZ WAIT1 MVI C,0FFH ;SET TIMEOUT ERROR CODE WAIT2: PUSH B ;SAVE OPERATION STATUS CALL ENDCMD ;GO FORCE A TERMINATE POP B MOV A,C ;RESTORE STATUS TO (A) REGISTER RET ;****************************************************************************** ; ; ROUTINE TO FORCE RESET THE 1793 CHIP TO END A MULTIPLE COMMAND ; OR TO TERMINATE A HUNG COMMAND. INITIAL DELAY IS TO ALLOW THE ; 1793 CONTROLLER TO GET BY THE CRC BYTES ON READ/WRITE IF THIS ; SUBROUTINE HAD BEEN CALLED TO TERMINATE A MULTIPLE COMMAND. ; ENDCMD: MVI B,29 ;SHORT DELAY VALUE ENDWAT: NOP DCR B ;DEC LOOP DELAY COUNT JNZ ENDWAT IN P$MFD$STAT ;GET 1793 STATUS MOV B,A MVI A,C$MFD$FBD ;FORCE RESET COMMAND OUT P$MFD$STAT ; MOV A,B ; RET ;------------------------------------------------------------------------ FRESTR: MVI A,10 ;RETRY COUNT MOV B,A ; FREST1: PUSH B ; LDA @RDRV ;GET PHYSICAL DRIVE NUMBER MOV E,A ; MVI D,00H ;SET THIS DRIVE TRACK TABLE TO ZERO LXI H,TRKTAB ;TRACK TABLE BASE ADDRESS DAD D ; MVI M,00H ;MOVE A ZERO INTO THE TRACK TABLE CALL GETUNMO ;GET MINI FLOPPY UNIT MODE WORD MVI A,C$MFD$RESTORE ;GET RESTORE COMMAND ORI MFD$STEP$RATE ;PUT IN THE STEP RATE BITS CALL OCMD ;SEND RESTORE COMMAND TO 1793 POP B ; STA FSTAT ;SAVE STATUS FOR DIAGNOSTIC CPI 0FFH ; JZ RESTEX ; XRI 04H ;COMPLEMENT TRACK ZERO BIT ANI 05H ;SEE IF DRIVE BUSY OR NOT TRACK ZERO JZ RESTEX ; DCR B ; JNZ FREST1 ; RESTEX: PUSH PSW ; XRA A ; OUT P$MFD$TRK ; POP PSW ; RET ; PAGE ;------------------------------------------------------------------------- DISK$STATUS: DB 00H ;LAST ERROR STATUS CODE FOR MESSAGES TRKMSG: DB CR,'TRACK ',0 RD$MSG: DB ' CR16-READ ',CR,LF,0 WR$MSG: DB ' CR16-WRITE ',CR,LF,0 FM$MSG: DB ' CR16-FORMAT ',CR,LF,0 RW$NAME: DW RD$MSG ;TEXT FOR ERROR MESSAGE ERROR$TABLE: DW B7$MSG ;TABLE OF POINTERS TO ERROR DW B6$MSG ;MESSAGE STRINGS DW B5$MSG ;FIRST ENTRY IS FOR BIT 7 DW B4$MSG ;OF 1793 STATUS BYTE DW B3$MSG DW B2$MSG DW B1$MSG DW B0$MSG B7$MSG: DB 'NOT READY',CR,LF,0 B6$MSG: DB 'PROTECT',CR,LF,0 B5$MSG: DB 'FAULT',CR,LF,0 B4$MSG: DB 'RECORD NOT FOUND',CR,LF,0 B3$MSG: DB 'CRC',CR,LF,0 B2$MSG: DB 'LOST DATA',CR,LF,0 B1$MSG: DB 'DREQ',CR,LF,0 B0$MSG: DB 'BUSY',CR,LF,0 PAGE ;************************************************************************* @cnt db 1 ; FSTAT DB 0 ; FSIDE DB 0 ; FTRK DB 0 ; TRKTAB DB 0FFH,0FFH ; MRWCNT DB 0 ; MERCNT DB 0 ; DMA$COMMAND DB 0 ;(DMCMD) DISK$COMMAND DB 0 ;(FDCMD) endif END «eof»