home *** CD-ROM | disk | FTP | other *** search
- TITLE 'CPM+ DISK IO MODULE FOR XCOMP HARD DISK CONTROLLER'
- ;
- ;This is a self contained module to link in a Xcomp controler to CPM+. It
- ;is setup for a 10 Mg byte miniscribe at the moment
- ;
-
- ; John Monahan (201) 783 1548
- ;
- ; DEFINE LOGICAL VALUES:
- TRUE EQU -1
- FALSE EQU NOT TRUE
- ;
- ; DETERMINE IF BANK SELECTING:
- BANKED EQU TRUE ;FULL BLOWN VERSION
- ;
- ;
- BELL EQU 07H
- CR EQU 0DH
- LF EQU 0AH
- MAXCYL EQU 500 ;<---WILL ALLOW A MAX OF ONLY 8 MBYTES
- LZONE EQU 656
- ;
- ; DRIVE COMMANDS
- ;
- SKCMD EQU 3 ;SEEK
- SKOUT EQU 1 ;SEEK OUTWARD
- NOPC EQU 40H ;NO PRE-COMPENSATION
- LOWRT EQU 80H ;LOW WRITE CURRENT
- VSA EQU 8 ;SEEK VERIFY START ADDRESS
- VCA EQU 1BH ;SEEK VERIFY COMMAND ADDRESS
- ;
- ; DRIVE STATUS
- ;
- READY EQU 1 ;DRIVE READY
- WRTFLT EQU 2 ;WRITE FAULT
- TK00 EQU 4 ;TRACK ZERO
- RAWINDX EQU 20H ;RAW INDEX
- ;
- ; CONTROLLER COMMANDS
- ;
- BANK0 EQU 0 ;BANK 0 SELECT
- BANK1 EQU 1 ;BANK 1 SELECT
- DBENB EQU 2 ;DATA BUFFER ENABLE
- CBENB EQU 4 ;COMPARE BUFFER ENABLE
- START EQU 8 ;START COMMAND
- ;
- ; DRIVE/CONTROLLER I/O
- ;
- CBASE EQU 70H ;BASE ADR OF THE CONTROLLER
- DRCSR EQU CBASE ;DRIVE COMMAND/STATUS
- EXTCMD EQU CBASE+1 ;EXTENDED COMMNAND REGISTER
- LOSC EQU CBASE+2 ;SEEK COUNT, LSB
- HISC EQU CBASE+3 ; * MSB
- CTCSR EQU CBASE+4 ;CONTROLLER COMMAND/STATUS
- CTBFR EQU CBASE+5 ;CONTROLLER BUFFER ADDRESS
- CTDP EQU CBASE+6 ;CONTROLLER DATA PORT
-
-
- ; DEFINE PUBLIC LABELS:
- PUBLIC DPH0 ;DISK PARAMETER HEADERS
-
- ; DEFINE EXTERNAL LABELS:
- EXTRN @ADRV,@RDRV
- EXTRN @DMA,@TRK,@SECT
- EXTRN @CBNK
- EXTRN @DBNK ;BANK FOR DMA OPERATION
- EXTRN @ERMDE ;BDOS ERROR MODE
- EXTRN ?WBOOT ;WARM BOOT VECTOR
- EXTRN ?PMSG ;PRINT MESSAGE @<HL> UP TO 00, SAVES
- ; [BC] AND [DE]
- EXTRN ?PDERR ;PRINT BIOS DISK ERROR HEADER
- EXTRN ?CONIN,?CONO ;CONSOLE IN AND OUT
- EXTRN ?CONST ;CONSOLE STATUS
- EXTRN ?BNKSL ;SELECT PROCESSOR MEMORY BANK
-
- EXTRN ?SMSG ;MY ROUTINE TO SPEAK A MESSAGE
- ;YOU CAN REMOVE REFERENCES TO THIS
-
- ; INCLUDE CP/M 3.0 DISK DEFINITION MACROS:
- MACLIB CPM3
-
- ; INCLUDE Z-80 MACRO LIBRARY:
- MACLIB Z80
-
-
- IF BANKED
- DSEG ;PUT IN OP SYS BANK IF BANKING
- ELSE
- CSEG ;ELSE KEEP IN COMMON MEMORY
- ENDIF
-
- ; EXTENDED DISK PARAMETER HEADER FOR DRIVE 0:
- DW HDWRT ;HARD DISK WRITE ROUTINE
- DW HDRD ;HARD DISK READ ROUTINE
- DW HDLOGIN ;HARD DISK LOGIN PROCEDURE
- DW HDINIT ;HARD DISK DRIVE INITIALIZATION ROUTINE
- DB 0 ;RELATIVE DRIVE 0 ON THIS CONTROLLER
- DB 0 ;MEDIA TYPE:
- ; HI BIT SET : DRIVE NEEDS RECALIBRATING
- DPH0: DPH 0,HD$DPB,0,
-
- ; MAKE SURE DPB'S ARE IN COMMON MEMORY:
- CSEG
-
- ; 256 BYTE SECTORS ON HARD DISK
- HD$DPB: DPB 256,32,1000,2048,1024,2,8000H
-
- IF BANKED
- DSEG ;CAN SET BACK TO BANKED SEGMENT IF BANKING
- ENDIF
-
- ;;;;; HDINIT:
- HDINIT RET ;DO NOT INITILIZE HARD DISK YET
- ;
- ;;;;; HDLOGIN
- ;------ INITILIZE THE XCOMP HARD DISK CONTROLLER (MUST DOWNLOAD MICROCODE) ---
- HDLOGIN:
- CALL XTKZ ;RESTORE
- JNZ RESERR
- LXI H,SAYSIGNON
- CALL ?SMSG ;SPEAK MESSAGE
- XRA A ;RETURN WITH NO ERROR
- RET
-
- RESERR: LXI H,MSGH2 ;RESTORE FAILED
- CALL ?PMSG
- ORI 1
- RET
- ;
- ;;;;; HDWRT
- ; ROUTINE WRITES 1 SECTOR TO THE DISK:
- ;
- HDWRT: XRA A
- STA ERFLG
- CALL GETDMA ;GET DMA ADR, SET POINTERS
-
- IF BANKED
- JMP ADJBNNN
-
- CSEG
-
- ADJBNNN:LDA @CBNK
- PUSH PSW
- LDA @DBNK
- CALL ?BNKSL
- OUTIR
- POP PSW
- CALL ?BNKSL
- JMP ADJDDD
-
- DSEG
-
- ELSE
- OUTIR
- ENDIF
-
- ADJDDD: CALL XWRT
- LDA ERFLG
- RET
-
- XWRT: LXI H,WTBL ;GET COMMAND TABLE
- CALL DORW ;EXICUTE WR/RD COMMANDS
- JMP XR1
-
- ;;;;; HDRD
- ; ROUTINE READS 1 PHYSICAL SECTOR FROM THE DRIVE:
- ;
- HDRD: XRA A
- STA ERFLG ;CLEAR THE ERROR FLAG
- CALL XREAD ;READ A BLOCK
- CALL GETDMA ;GET DMA ADR, SET POINTERS
-
- IF BANKED
- JMP ADJBNKS
-
- CSEG ;MUST HAVE THE FOLLOWING CODE IN COMMON
-
- ADJBNKS:LDA @CBNK
- PUSH PSW
- LDA @DBNK ;MUST HAVE THIS CODE IN COMMON
- CALL ?BNKSL ;NOW DMA ADDRESS IS AT THE CORRECT BANK
- IN CTDP ;PRIME DATA INPUT
- NOP
- INIR ;BLOCK INPUT
- POP PSW
- CALL ?BNKSL
- JMP ADJDON
-
- DSEG
-
- ELSE
- IN CTDP ;PRIME DATA INPUT
- NOP
- INIR ;BLOCK INPUT
- ENDIF
-
- ADJDON: LDA ERFLG ;ERROR FLAG
- RET
- ;
- XREAD: LXI H,RTBL ;SEEK SECTOR COMMAND TABLE IS SENT TO CONTROLLER
- CALL DORW ;SEND IT
- XR1: MVI A,0
- RZ ;RIF READ/WRITE OK
- INR A
- STA ERFLG ;SET ERROR FLAG
- RET
- ;
- DORW: SHLD CTA ;SAVE CMD TBL ADR
- CALL XSEK ;SEEK TO NEW TRACK (IF REQUIRED)
- RNZ ;RIF SEEK FAILED
- CALL XSEL ;HEAD SELECT
- LHLD CTA
- ;
- DO0: MOV A,M
- STA RETRY ;SET RETRY COUNT
- INX H
- MOV A,M
- OUT CTCSR ;ENB CMP BFR
- INX H
- MOV A,M
- OUT CTBFR ;SET CMP BFR ADR
- INX H
- SHLD CTA ;SAVE CMD TBL ADR
- ;
- LXI H,RCA ;REAL TK ADR
- MVI B,3
- DO1: MOV A,M
- OUT CTDP ;PUT HDR INFO INTO CMP BFR
- INX H
- DCR B
- JNZ DO1
- LDA @SECT
- OUT CTDP ;SET SECT ADR FOR COMPARE
- ;
- DO2: CALL XRDY ;DRIVE READY ?
- RNZ ; RIF NO
- LHLD CTA ;CMD TBL ADR
- MOV A,M ;A = CNTL BANK
- INX H
- MOV B,A
- OUT CTCSR ;SLCT CNTL BANK
- MOV A,M
- OUT CTBFR ;SET START ADR
- INX H
- MOV A,B
- ORI START
- OUT CTCSR ;START R/W CMD
- ;
- DO3: CALL WFD ;WAIT FOR READ/WRITE TO FINISH
- RC ;ABORT IF TIMEOUT
- ANA M ;TEST CTLR STATUS (0=OK)
- MOV B,A
- IN DRCSR ;DRIVE STATUS
- ANI WRTFLT
- CNZ CLRDF ;CIF CLEAR DRIVE FAULT
- ORA B ;SET/CLEAR ERROR FLAG (0=OK)
- RZ ;RIF READ/WRITE OK
- LXI H,RETRY
- DCR M ;DECR RETRY COUNT
- JNZ DO2 ;JIF RETRY READ/WRITE
- ;
- ; SET ERROR FLAG
- ;
- SEF: MVI A,1 ;A = ERROR FLAG
- ORA A ;SET 8080 FLAGS
- RET ;TAKE ERROR EXIT
- ;
- ; ---WAIT FOR DONE---
- ;
- WFD: PUSH H
- LXI H,0 ;TIMEOUT DELAY COUNT
- ;
- WFD1: IN CTCSR ;CTLR STATUS
- RRC
- JC WFD2 ;WAIT FOR DONE
- DCX H
- MOV A,H
- ORA L
- JNZ WFD1
- ;
- OUT CTCSR
- POP H
- MVI A,1
- ORA A
- STC
- RET
- ;
- WFD2: POP H
- IN CTCSR ;GET NON-CHANGING STATUS
- MOV B,A
- XRA A
- OUT CTCSR ;STOP CTLR
- MOV A,B
- RET
- ;
- ; SETS THE CONTROLLER BUFFER ADDRESS TO THE CORRECT
- ; STARTING POINT. ALSO SETS B=256 & H/L=@DMA
- ;
- GETDMA: LHLD @DMA
- MVI C,CTDP ;FOR BLOCK I/O
- MVI B,0 ;B = COUNT (256 BYTES)
- MVI A,DBENB
- OUT CTCSR ;ENB DATA BFR
- MVI A,0
- GET1: OUT CTBFR ;SET CTLR DATA BFR ADR
- RET
- ;
- ; ---REZERO---
- ;
- XTKZ: LXI H,0
- SHLD RCA
- CALL TZT ;TEST IF TRK 0
- RZ
- ;
- LXI H,511 ;#OF CYLINDERS WE CAN COUNT ON CONTROLLER
- CALL RTZ ;SEEK OUT
- RC ;ABORT DRIVE NOT READY
- RZ ;IS AT 0
- LXI H,LZONE+10-511
- CALL RTZ ;TRY SECOND PUMP
- RC
- RZ
- JMP SEF ;ABORT RESTORE FAILED
- ;
- ; SEEK OUTWARD
- ;
- RTZ: CALL XRDY
- STC
- RNZ
- MOV A,L
- OUT LOSC ;SET LSB OF SEEK COUNT
- MOV A,H
- OUT HISC ;SET MSB
- MVI A,SKOUT
- OUT EXTCMD ;SET SEEK DIRECTION OUTWARD
- MVI A,SKCMD
- OUT DRCSR ;ISSUE SEEK
- CALL WSC
- RC
- ;
- TZT: IN DRCSR ;GET DRIVE STATUS
- ANI TK00
- XRI TK00
- RET
- ;
- ;
- ; ---SEEK---
- ;
- XSEK: MVI A,3
- STA SKRTC ;SET SEEK RETRY COUNT
- ;
- XSEK1: LHLD @TRK ;REQUESTED TRACK
- MVI B,1
- CALL DRS ;SHIFT H/L RIGHT ONCE
- LXI D,MAXCYL
- CALL TSUB
- RAL
- JNC SEF ;ABORT IF INVALID ADDRESS
- XSEK2: XCHG ;[DE] = NEW CYLINDER ADDRESS
- LHLD RCA ;LOAD UP CURRENT REAL ADR
- XCHG
- SHLD RCA ;SAVE NEW ADDRESS
- XCHG
- CALL SUBT ;GET DIFFERENCE
- RZ ;RETURN IF SAME
- MVI B,1 ;DIR = OUT
- RAL
- JNC XSEK3 ;OK SEEK OUTWARD
- ;
- MVI B,3 ;SEEK INWARD
- MOV A,L
- CMA ;MAKE SEEK POSITIVE
- MOV L,A
- MOV A,H
- CMA
- MOV H,A
- INX H
- ;
- XSEK3: MOV A,B ;GO TO SEEKING INWARD
- STA SKDIR
- LXI D,512
- CALL TSUB
- RAL
- JNC XSEK4 ;JIF DOUBLE PUMP IS REQ
- CALL PSK ;DO PARTIAL SEEK
- RNZ
- JMP XSEK5
- ;
- XSEK4: DCX D ;[DE] =511
- CALL SUBT ;[HL]-[DE]
- SHLD RSKNT ;SAVE RESIDUAL COUNT
- XCHG
- CALL PSK
- RNZ ;ABORT IF SEEK FAILED
- LHLD RSKNT
- CALL PSK ;SEND THE REST
- RNZ
- ;
- ; ;SEEK VERIFY
- XSEK5: MVI A,3
- STA VSRTC ;SET RETRY COUNT
- MVI A,CBENB
- OUT CTCSR ;ENABLE BANK ZERO CMP BFR
- MVI A,VCA
- OUT CTBFR ;SET CMP BFR ADR
- LHLD RCA ;REAL (CURR) CYL ADR
- MOV A,L
- OUT CTDP ;SET CYL ADR, LSB
- MOV A,H
- OUT CTDP ;SET CYL ADR, MSB
- XSEK6: MVI A,VSA
- OUT CTBFR ;SET M/CODE START ADR
- MVI A,START
- OUT CTCSR ;START VERIFY
- CALL WFD ;WAIT FOR DONE
- ANI 0CH ;TEST CTLR STATUS
- RZ ;RIF VERIFY OK
- LXI H,VSRTC
- DCR M ;DECR RETRY COUNT
- JNZ XSEK6 ;JIF RETRY SEEK VERIFY
- ; VERIFY FAILED
- CALL XTKZ ;RESTORE
- LXI H,SKRTC
- DCR M ;DECR RETRY COUNT
- JNZ XSEK1 ;JIF RETRY SEEK
- ; UNRECOVERABLE SEEK ERROR
- ORI 1 ;SET ERROR FLAG
- RET ;ABORT
- ;
- ; PARTIAL SEEK
- ;
- PSK: CALL XRDY ;DRIVE READY ?
- RNZ ;ABORT, DRIVE NOT RDY
- MOV A,L
- OUT LOSC ;SET SEEK COUNT, LSB
- MOV A,H
- OUT HISC ; * MSB
- LDA SKDIR
- OUT EXTCMD ;SET SEEK DIRECTION
- MVI A,3
- OUT DRCSR ;ISSUE SEEK CMD
- ;
- ; ---> FALL THRU TO 'WSC' <---
- ;
- ; ---WAIT FOR SEEK COMPLETE---
- ;
- ;
- WSC: PUSH H ;SAVE REGS
- PUSH B
- LXI H,0 ;TIME-OUT DELAY COUNT
- MVI B,6 ;XCOMP HAD 3 NEED 6 FOR 5MHz
- ;
- WSC1: IN DRCSR ;DRIVE STATUS
- RAL
- JC WSC2 ;JIF SEEK DONE
- DCX H ;DECR DELAY COUNT
- MOV A,H
- ORA L
- JNZ WSC1 ;JIF CON'T WAITING
- DCR B
- JNZ WSC1
- ; TIME-OUT ERROR
- POP B ;RESTORE REGS
- POP H
- MVI A,1
- ORA A ;SET CPM ERROR FLAG
- STC ;SET INTERNAL ERROR FLAG
- RET
- ;
- WSC2: POP B ;RESTORE REGS
- POP H
- XRA A ;SET FLAG = OK
- RET
- ;
- ;
- ;
- ; ---CLEAR DRIVE FAULT---
- ;
- CLRDF: XRA A
- OUT EXTCMD ;DE-SELECT THE DRIVE (FALL THRU TO 'XSEL' TO
- ;RE-SELECT THE DRIVE)
- ;
- ; ---HEAD SELECT---
- ;
- XSEL: LDA @TRK ;REQUESTED TRACK
- ANI 1 ;2 HEADS
- STA RHD ;SAVE REAL HEAD #
- ADD A ;SHIFT HEAD # LEFT TWICE FOR H/W
- ADD A
- ORI 1 ;TO MAINTAIN DRIVE SLCT
- OUT EXTCMD ;SELECT HEAD 0 OR 1
- RET
- ;
- ; ---DRIVE READY TEST---
- ;
- XRDY: IN DRCSR ;DRIVE STATUS
- ANI 1 ;DRIVE RDY BIT
- XRI 1 ; MAKE IT LO-TRUE
- RZ ;RIF DRIVE READY
- LXI H,MSGH1 ;ERROR MSG
- CALL ?PMSG
- ORI 1 ;SET ERROR FLAG
- RET
- ;
- ;
- ; SHIFTS THE CONTENTS OF H/L RIGHT 'N' TIMES.
- ;
- DRS: PUSH PSW ;SAVE 'A'
- DRS1: MOV A,H ;MSB
- ORA A ;CLEAR CY
- RAR
- MOV H,A
- MOV A,L ;LSB
- RAR
- MOV L,A
- DCR B ;B = SHIFT COUNT
- JNZ DRS1
- POP PSW ;RESTORE 'A'
- RET
- ;
- SUBT: MOV A,L ;16 BIT SUBTRACTION
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A
- ORA L
- MOV A,H
- RET
- ;
- TSUB: PUSH H ;SAVE [HL]
- CALL SUBT
- POP H
- RET
- ;
- ;------------------------- DATA STORAGE AREA -------------------------------
- ;
- ; --- COMMAND TABLE TO SEEK SECTOR/TRACK ---
- ;
- ;
- WTBL: DB 5 ;RETRY COUNT
- DB 5 ;CMP BFR ENB
- DB 0E6H ;CMP BFR ADR
- DB BANK1 ;CNTL BANK
- DB 0D3H ;START ADR
- DB 0EH ;STATUS MASK
- ;
- RTBL: DB 10 ;RETRY COUNT
- DB 4 ;CMP BFR ENB
- DB 0EAH ;CMP BFR ADR
- DB BANK0 ;CNTL BANK
- DB 0D7H ;START ADDRESS
- DB 0EH ;STATUS MASK
- ;
- MSGH1: DB BELL,CR,LF,'Drive not Ready',0
- MSGH2: DB BELL,CR,LF,'Restore Failed',0
- SAYSIGNON: DB 'HHARD DISK ON DRIVE AEE ',0
- ;
- RCA: DS 2 ;REAL TRACK ADDRESS
- RHD: DS 1 ; HEAD
- RSA: DS 1 ; SECTOR
- ;
- RETRY: DS 1 ;RETRY COUNT
- CTA: DS 2 ;COMMAND TABLE ADDRESS
- ERFLG: DS 1 ;ERROR FLAG
- SKRTC: DS 1 ;SEEK RETRY COUNT
- VSRTC: DS 1 ;SEEK VERIFY COUNT
- SKDIR: DS 1 ;SEEK DIRECTION
- RSKNT: DS 2 ;RESIDUAL SEEK COUNT
- SPARE: DS 2
- ;
- ;
-
-