;(Listing for CP/M Non-DMA ROM ;12/17/80) ;CP/M BOOT ROM DTYPE EQU 11 ;0 FOR CMD, 11 FOR FUJITSU BTPS EQU 512 IOBASE EQU 90H BTRKU EQU 0 ;MSB OF BOOT TRACK BTRKL EQU 0 ;LSB BHD EQU 0 ;BOOT HEAD BFSC EQU 00 ;FIRST BOOT SECTOR BMADU EQU 000H ;MSB OF DMA ADDRESS BMADL EQU 0H ;LSB BSRC EQU 17 ;BOOT SECTOR COUNT BUNIT EQU 0 BJMP EQU 00000H ;JMPS TO SPECIFIED LOC AFTER BOOT BSPR EQU 6080H ;BOOT SCRATCH PAD BSP EQU 6100H ;BOOT STACK LOCATION FRCSEEK EQU 1 ; D R V R ;PN 9002-00-Y 12-17-80 ; L REVISION ALLOWS THE NUMBER OF BYTES PER ; SECTOR TO BE SET VIA AN EQUATE (BIPS) IN THE ; CUSTOMER FILES ; REVISION P CORRECTS TIMEOUT, ; ENTERED INCORRECTLY IN REVISION M, AND ; PREVENTS ILLEGAL RECOVERY ; ATTEMPTS ; REVISION R ADDS CHECK FOR DISK FAULT AFTER ; HEAD SELECT ; ALSO MAKES ROOM ; REVISION S CHANGES MVI A TO MVI M ; REVISION T CHANGES MVI A TO MVI M AND ; CORRECTS A PROBLEM INTRODUCED BY REVISION N. ; IN SOME CASES, SYSTEMS WITH MULTIPLE DISKS CAN WRITE ; DATA ON THE WRONG UNIT. ; SELECT IS CHANGED TO ALWAYS FORCE A HEAD SELECT ; AFTER A UNIT SELECT. ; RECAL OPERATIONS ALLOWED IN READ ERROR RECOVERY..... ; REVISION U CORRECTS THE ERROR CORRECTION ; REVISION V PREVENTS HANGING IN A READ ERROR LOOP ; REVISION W ADDS OUT STATU, ; TO CORRECT RECOVERYLOGIC ; REVISION X REMOVES WRITE RETRY TO AVOID ; WRITING THE CARTRIDGE ; WHEN THE FIXED IS WRITE PROTECTED AND ; ADDS FAULT CLEAR TO SETUP ; REVISION Y ADDS A DAD D ; THIS WAS CHANGED IN ERROR ON AN ; EARLIER REVISION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DTYPE IN CUSTOMER FILE SETS DISK TYPE; ; FU FOR FUJITSU AND CMD FOR CMD ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DRVR IS A ROM DRIVER FOR THE SMC-100 ; DISK CONTROLLER ; PARAMETERS RELATIVE TO THE DRIVER CALL: RTS EQU 1 ;RETURN STATU CMMD EQU 02H ;COMMAND 0=READ 1=WRITE NSCT EQU 09 ;NUMBER OF SECTORS UNIT EQU 10 ;UNIT NUMBER TRKU EQU 03 ;UPPER TRACK TRKL EQU 4 ;LOWER TRACK HEAD EQU 05 ;HEAD SCTR EQU 6 ;FIRST SECTOR DMAU EQU 07 ;MDB OF DMA DMAL EQU 08 ; THE FOLLOWING ARE SET AT POWER UP: ; RBW IS OPTIONS BYTE ; BIT 0 TRUE (1) = READ BEFOR WRITE ; BIT 1 TRUE (1) = REPORT SOFT ERRORS RBW EQU 11 ;OPTIONS BYTE MHEAD EQU 12 ;MAXIMUM NUMBER OF HEADS MTRK EQU 13 ;MAX TRACK, MDB MTRKL EQU 14 ;LSB MSC EQU 15 ; THE FOLLOWING IS THE DRIVERS SCRATCH PAD CUNIT EQU 16 ;CURRENT UNIT CTRKU EQU 17 ;CURRENT TRAC8 LSB CERRC EQU 19 ;ERROR COUNT ; PLACE BAD HEADER IN THE FOLLOWING BHDR1 EQU 20 BHDR2 EQU BHDR1+1 BHDR3 EQU BHDR1+2 BHDR4 EQU BHDR1+3 ; BAD TRACK TABLE FFH TERMINATES TABLE SBIT EQU 24 ;START OF BAD TRACK T ;;; END OF USER RAM TABLE DIF.;;; BUSU EQU IOBASE BUSL EQU IOBASE +1 CMND EQU IOBASE +2 SCTAD EQU IOBASE+3 SCTBU EQU IOBASE+4 DMACL EQU IOBASE+5 DMACU EQU IOBASE+6 STATU EQU IOBASE+7 BSPS EQU 0048 ;BOOT SCRATCH PAD SIZE/2 ORG 0F000H ;;;;;;;;;;; ; BOOT ; ;;;;;;;;;;; SBOOT: LXI SP,BSP LXI B,BPAR LXI D,BSPR MVI H,BSPS BNEXT: LDAX B ;GET WORD FOR BOOT SCRATCH PAD STAX D ;STORE IT INX B INX D DCR H JNZ BNEXT CALL BSPR ;DO IPL JC SBOOT ;RETRY ON ERROR JMP NPHAM ;GO TURN OFF PHANTOM BPAR: CALL DRVR RET DS 1 DB 0 ;READ COMMAND DB BTRKU ;MSB OF TRACK DB BTRKL ;LSB DB BHD ;HEAD DB BFSC ;SECTOR DB BMADU DB BMADL DB BSRC ;# OF SECTORS DB BUNIT ;BOOT UNIT # DS 1 DB 0FFH ;MAX HEAD DW 07F7FH ;MAX TRACK DB 3FH ;MAX SECTOR DB 07 ;SET FALSE UNIT TO SEL DW 0777H DS 5 DB 0FFH ORG 0F040H ;;;;;;;;;;;;;;;;;;;;;;;;; ; END OF BOOT ; ; BEGINNING OF DRIVER ; ;;;;;;;;;;;;;;;;;;;;;;;;; DRVR POP D ;SAVE BASE OF PARAMETERS PUSH D LXI H,RTS ;ZERO THE RET STAT DAD D XRA A MOV M,A CALL SETUP JC SETHE LXI H,NSCT ;IS NUMBER OF SECTORS 0? DAD D XRA A ADD M RZ ;IF DONE RETURN LXI H,CMMD DAD D MOV A,M ;GET COMMAND SBI 01 JZ WRITE JC READ CALL SETHE ;SETS H&L TO RTS ADDRESS MVI M,0D0H RET SETUP LXI H,DMAU DAD D MOV A,M OUT DMACU ;SET DMA UPPER INX H MOV A,M OUT DMACL ;SET LOWER ;TEST TO SEE IF FAULT IS PENDING, ;IF SO CLEAR. (ADDED BY REV. X) IN STATU ANI 20H JZ F0K OUT BUSU MVI A,10H ;FAULT CLEAR BIT OUT BUSL MVI A,80H ;FAULT CLEAR BIT OUT CMND XRA A OUT CMND OUT BUSL F0K: CALL HEADS ;(HEAD RESELECTED IF UNIT, VOL. OR TRK. CHANGE) LXI H,UNIT DAD D ORA M ;A NOW = NEW UNIT VOLUMN LXI H,TRKU DAD D MOV B,M ;B=UPPER TRACK, NEW INX H MOV C,M ;C=LOWER TRACK ADD, NEW DAD D LXI H,CUNIT CMP M JNZ NEW ;VOLUMN OR UNIT CHANGE MOV A,B INX H CMP M JNZ NEW ;MSB OF TRACK CHANGE MOV A,C INX H CMP M JNZ NEW ;LSB OF TRACK CHANGE CONTIN: CALL RBWT ;READ BEFORE ;WRITE IF OPTION IS SET RC ;RETURN IF ERROR LXI H,SCTR DAD D MOV A,M ;GET SECTOR OUT SCTAD ;SET SECTOR XRA A OUT BUSU OUT BUSL RET ;END OF SETUP ;NEW IS SELECTED IF TRACK, ;UNIT, OR VOLUMN CHANGES ;OR IF THE FORCE SEEK OPTION IS SET NEW: CALL SEL RC CALL SEEK RC JMP CONTIN SEEK: CALL GSEEK RNC ;RETURN IF SEEK GOOD CALL RECAL CALL GSEEK CC SETHE ;SET HARD ERROR RET RCLSK: CALL RECAL CALL SEEK RET GSEEK: LXI H,TRKU DAD D MOV B,M INX H MOV C,M ;GET LSB TRACK LXI H,MTRK DAD D MOV A,M SUB B JM ILAG ;ILLEGAL TRACK JNZ GTRK ;LEGAL TRACK INX H MOV A,M CMA ADD C JC ILAG GTRK: LXI H,CTRKU DAD D MOV M,B ;SET CURRENT TO NEW INX H MOV M,C LXI H,SBIT DAD D NTRK: MOV A,M ANI 80H JNZ GT MOV A,M ;MSB OF BAD TRACK SUB B JNZ INC4 INX H MOV A,M ;LSB OF BAD TRACK SUB C JNZ INC3 INX H MOV B,M INX H MOV C,M GT: MOV A,B OUT BUSU MOV A,C OUT BUSL MVI A,20H OUT CMND ;DO SEEK CALL WT ;WAIT FOR DONE RC ANI 02 RZ LXI H,RTS DAD D MVI A,82H ORA M MOV M,A STC RET INC4: INX H INC3: INX H INX H INX H JMP NTRK ILAG: CALL SETHE MVI M,0D1H RET READ XRA A LXI H,CERRC DAD D MOV M,A ;ZERO ERROR COUNT OUT BUSU OUT BUSL OUT STATU MVI A,88H ;READ DISK OUT CMND IN STATU ORI 0BEH ;CHECK FOR LOSS OF SELECT OR READY CPI 0FFH JNZ NR WAITR: IN STATU RLC JNC WAITR IN STATU ANI 24H JNZ ER24 ;GO RECOVER MVI B,04H CALL HDRT JC RCOVR GRD: LXI H,DMAU DAD D MOV B,M INX H MOV C,M LXI H,BTPS NRBYTE: IN SCTBU STAX B INX B DCR L JNZ NRBYTE DCR H JNZ NRBYTE CALL NEXT ;SET UP NEXT READ RC JMP READ SHALT: STC ;ABORT RET NEXT: LXI H,MSC DAD D MOV B,M LXI H,SCTR DAD D MOV A,M CMP B JZ INCTR INR A OUT SCTAD MOV M,A JMP NRDY ;JMP NEXT READY INCTR: XRA A MOV M,A OUT SCTAD ;ZERO SECTOR LXI H,TRKU DAD D MOV B,M ;GET TRACK MSB INX H MOV C,M ;LSB LXI H,MTRK DAD D MOV A,M SUB B JNZ TOK INX H MOV A,M SUB C JZ ILAG ;OVERRUN TOK: LXI H,TRKL DAD D INX B MOV M,C ;RETURN NEW TRACK LSB DCX H MOV M,B ;MSB CALL SEEK RC CALL RBWT RC NRDY: LXI H,DMAU DAD D MOV B,M INX H MOV C,M LXI H,BTPS ;BYTES PER SECTOR DAD B MOV B,H MOV C,L LXI H,DMAU DAD D MOV M,B INX H MOV M,C LXI H,RTS ;CHECK FOR SOFT ERROR ABORT DAD D XRA A ADD M JZ NSE LXI H,RBW DAD D MVI A,02 ANA M JNZ SHALT LXI H,RTS DAD D XRA A MOV M,A ;CLEAR RTS TO IGNORE SOFT ERROR NSE: LXI H,NSCT DAD D DCR M XRA A ADD M RNZ ;NOT DONE, RETURN POP D RET ER24: LXI H,RTS ;SET FAULT AND OR DAD D ;CHECKSUM IN STATUS ORI 80H ORA M MOV M,A RCOVR: CALL RERR RC OUT STATU ;REZERO THE BUFFER MVI A,88H OUT CMND ;DO READ (RECOVERY) CALL WT RC ANI 24H JNZ ER24 MVI B,04H CALL HDRT JC RCOVR CALL OFSTO JMP GRD RERR: LXI H,CERRC DAD D MOV C,M ;GET ERROR COUNT X: INR C MOV A,C ANI 03H CPI 03H ;IS IT AN 02? JZ X ;YESS INC AGAIN MOV A,C ANI 18H ;IS IT 0C? CPI 18H JZ X ;YES IC AGAIN MOV M,C ;SET NEW ERROR COUNT MOV A,C CPI 20H JNZ NRCL ;IS IT RECAL? CALL RCLSK RC NRCL: LXI H,CERRC DAD D MOV C,M MOV A,C ANI 3FH ADI 0DCH CC SETHE RC ;MAX ERROR MOV A,C RRC ;POSITION BITS ANI 8CH OUT BUSL MOV A,C RRC ANI 1 OUT BUSU LXI H,DMAU DAD D MOV A,M OUT DMACU INX H MOV A,M OUT DMACL ;LOW XRA A ;CLEAR CARRY RET WRITE: XRA A LXI H,CERRC DAD D MOV M,A ;ZERO ERROR COUNT WRTRT: XRA A ;WRITE ERROR RETURNS HERE OUT BUSL OUT BUSU OUT STATU LXI H,TRKU DAD D MVI B,04H ;NUMBER OF HEADER BYTES NH: MOV A,M ;GET BYTE OUT SCTBU INX H DCR B JNZ NH ;GET NEXT HEADER LXI H,DMAU DAD D MOV B,M INX H MOV C,M LXI H,BTPS NWBYTE LDAX B OUT SCTBU INX B DCR L JNZ NWBYTE DCR H JNZ NWBYTE OUT STATU MVI A,1 ;DISK WRITE OUT CMND CALL WT RC ANI 20H ;IS FAULT ON? JNZ SETHE CALL NEXT RC JMP WRITE RECAL: CALL SEL XRA A OUT BUSU MVI A,50H OUT BUSL ;SET FAULT CLEAR AND RTZ MVI A,80H OUT CMND XRA A OUT BUSL CALL WT RC XRA A OUT CMND RET SEL: CALL HEADS LXI H,UNIT DAD D ORA M LXI H,CUNIT DAD D MOV M,A RAL RAL RAL RAL ANI 0F0H ;GET SELECT BITS OUT BUSU MVI A,10H OUT CMND IN STATU ANI 01H ;IS UNIT SELECTED JZ NR ;SELECT FAILED, JMP NOT READY CALL HEADS RET RBWT LXI H,CERRC DAD D XRA A MOV M,A OUT BUSL OUT BUSU ;READS BEFOR WRITE TO VERIFY TRACK RBWA: LXI H,RBW DAD D MOV A,M RRC RNC LXI H,CMMD DAD D MOV A,M CPI 0 RZ LXI H,SCTR DAD D MOV A,M MOV C,A ;SAVE SECTOR DCR A DCR A JM DSO SETSC: OUT SCTAD OUT STATU MVI A,88H OUT CMND ;DO READ CALL WT RC MOV A,C OUT SCTAD MVI B,03H ;HEADER CHECK COUNT CALL HDRT ;CHECK HEADER TEST JC BADHD CALL OFSTO XRA A ;CLEAR CARRY RET DSO: XRA A JMP SETSC BADHD: CALL RERR JNC RBWA RET OFSTO: XRA A ;TURN OFFSET OFF OUT CMND ;TURN OFF COMMAND LXI H,CERRC ;GET ERROR COUNT DAD D MOV A,M ANI 18H ;IS OFFSET TRUE? CNZ DLY ;DELAY IF IT WAS RET DLY: LXI H,7D0H W: DCX H MOV A,L ORA H JNZ W RET HDRT: OUT STATU ;ZERO ADD COUNT LXI H,TRKU DAD D NRH: MOV C,M ;GET HEADER BYTE IN SCTBU ;READ HEADER BYTE SUB C JNZ C527 INX H DCR B JNZ NRH ;IF NOT DONE, READ NEXT HEADER RET ;STORE BAD HEADER C527: OUT STATU MVI B,04H LXI H,BHDR1 DAD D ;HL=STORAGE LOCATION SBH: IN SCTBU ;GET READ HEADER MOV M,A DCR B INX H JNZ SBH LXI H,RTS DAD D MOV A,M ORI 88H ;SET ERROR AND FORMAT MOV M,A STC RET SETHE: LXI H,RTS ;SET HARD ERROR AND C DAD D MVI A,0C0H ORA M MOV M,A STC RET ;WAIT FOR DONE SUBROUTINE ;RETURNS WITH CARRY SET IF ;DRIVE LOST SELECT OR READY WT: MVI H,0FFH WZ: IN STATU ORI 0FEH CPI 0FFH JNZ NR ;NOT READY DCX H MOV A,H ORA L JZ NR ;TIME OUT IN STATU ANI 80H JZ WZ ;NOT YET DONE IN STATU RET NR: LXI H,RTS ;SET BITS 7,6,5 IN RTS, SET C DAD D MVI A,0E0H ORA M MOV M,A STC RET NPHAM: MVI B,5 LXI H,PHOFF LXI D,BSPR+23 ;USE BOOT SCRATCH PAD NPHAMC MOV A,M STAX D ;MOV BYTE TO SCRATCH PAD DCR B JZ BSPR+23 INX D INX H JMP NPHAMC PHOFF: IN DMACL ;TURN OFF PHANTOM JMP BJMP ;THE FOLLOWING SUBROUTINE SELECTS THE ;HEAD AND RETURNS WITH BIT 4 ;OF THE ACCUMULATOR = TO THE VOLUMN TAG HEADS: LXI H,HEAD DAD D MOV A,M JMP CMD+DTYPE ;DTYPE = 0 FOR CMD, ;11 FOR ALL OTHERS CMD: XRI 01H ;MAKE 1=REMOVABLE, 0,2,3,4 ETC FIXED CPI 0 JZ FU ;IF REMOVABLE, A = HEAD, VOL = 0 ORI 10H ;SET VOLUMN SBI 01H FU: OUT BUSL ANI 10H MOV B,A MVI A,40H OUT CMND IN STATU XRI 40H ANI 60H JNZ SETHE MOV A,B RET