home *** CD-ROM | disk | FTP | other *** search
- ; MYDDBIOS.Z80
- ;
- ; THIS IS A ROM BASED BIOS SUITABLE TO RUN 2.2 CP/M ON A VERSAFLOPPY II BOARD
- ; THE BIOS AUTOMATICALLY FIGURES OUT THE DENSITY OF DRIVES A: & B:
- ; IT IS SETUP TO TALK TO A ZAPPLE LIKE MONITOR AT 0F000H
- ;
- ; VERSION 1.0 JOHN J.MONAHAN (201)779-0635 1/15/1981
- ;
- ZCI EQU 0F003H ;CONSOLE INPUT
- ZCO EQU 0F009H ;CONSOLE OUTPUT
- ZCSTS EQU 0F012H ;CONSOLE STATUS
- ZRI EQU 0F006H ;READER TO MONITOR
- ZPOO EQU 0F00CH ;PUNCH TO MONITOR
- ZLO EQU 0F00FH ;LIST TO MONITOR
- ZLISTS EQU 0F027H ;LIST STATUS TO MONITOR
- SSMVID EQU 0ED00H ;LOCATION FOR DUMP OF DISK INFO ON SCREEN
- SSMDSK EQU SSMVID+06H ;LOCATION TO PLACE UNIT#
- SSMTRK EQU SSMVID+12H ;LOCATION TO PLACE TRACK#
- SSMSEC EQU SSMVID+1FH ;LOCATION TO PLACE SECTOR#
- SSMDMA EQU SSMVID+2EH ;LOCATION TO PLACE DMA ADDRESS
- MONITOR EQU 0F000H ;ZAPPLE LIKE MONITOR (NOTE IT IS NOT ZAPPLE ITSELF)
- PANNEL EQU 0FFH ;FRONT PANEL SWITCH USED TO SWITCH ON/OFF DUMP TO VDM
- STORE EQU 0D8H ;PORT USED AS KIND OF IOBYTE WITHIN MY MONITOR (CAN BE
- ; ;REMOVED FROM CODE IF YOU LIKE )
- ;
- ;
- LF EQU 0AH
- CR EQU 0DH
- BELL EQU 07H
- CLEAR EQU 1AH
- TAB EQU 09H
- ;
- ;
- IOBYTE EQU 03H
- CDISK EQU 04H
- TADDR EQU 40H
- UNIT EQU 42H ;NEW UNIT BYTE
- SCTR EQU 43H ;SECTOR
- TRK EQU 44H ;TRACK
- NREC EQU 45H ;# OF SECTORS
- ERMASK EQU 46H ;ERROR MASK
- ERSTAT EQU 47H ;ERROR FLAG STORE
- IDSV EQU 48H ;6 BYTES (USED FOR TRACK ID COMMAND)
- CMDSV EQU 4EH ;COMMAND SAVE
- SPSV EQU 4FH ;SP SAVE
- TEMP2 EQU 51H ;2 BYTE TEMP RECORD
- COUNT EQU 53H ;SECTORS/TRACK STORE
- VDMFLG EQU 54H ;FLAG TO INDICATE ASCII TO VDM BOARD HAS BEEN PLACED
- UNITCK EQU 55H ;OLD UNIT BYTE
- RSEEK EQU 56H ;NBR OF RESEEKS
- RTRY EQU 57H ;NBR OF RTRYS
- ADRIVE EQU 58H ;STORE OF A: DRIVE DENSITY ETC TYPE
- BDRIVE EQU 59H ;STORE OF B: DRIVE TYPE
- CBFLAG EQU 5AH ;FLAG TO INDICATE WBOOT OR CBOOT FOR LOADER ON DISK
- SSTACK EQU 80H ;SYSTEM STACK
- COLD EQU 80H ;COLD START ADDRESS
- ;
- X EQU 60H ;PORTS FOR 1791
- RSET EQU X+0 ;CONTROLLER RESET ADDRESS
- SELECT EQU X+3 ;DRIVE SELECT PORT
- STATUS EQU X+4 ;STATUS PORT
- TRACK EQU X+5 ;TRACK PORT
- SECTOR EQU X+6 ;SECTOR PORT
- DATA EQU X+7 ;DATA PORT
- CMD EQU X+4 ;COMMAND PORT
- ;
- RDACMD EQU 0C0H ;READ ADDRESS CODE
- RDCMD EQU 088H ;READ SECTOR CODE
- WRCMD EQU 0A8H ;WRITE SECTOR CODE
- WRTCMD EQU 0F4H ;WRITE TRACK CODE
- RSCMD EQU 009H ;RESTORE COMMAND
- SKNCMD EQU 019H ;SEEK NO VERIFY
- SKCMD EQU 1DH ;SEEK WITH VERIFY
- ;
- STDSDT EQU 26 ;STANDARD 8" 26 SECTORS/TRACK
- STDDDT EQU 50 ;STANDARD DD 8" 50 SECTORS/TRACK
- NBYTES EQU 128 ;BYTES/SECTOR
- NTRKS EQU 77 ;TRACKS/DISK
- ;
- ;
- ;
- ;
- ORG 0F800H ;<--------- LOCATION OF 2716 PROM
- ;
- ; DOS SYSTEM LINKAGES (USED BY SDOS & 2.2 CP/M DO NOT CHANGE ORDER)
- ;
- CBOOT: JP BOOT ;COLD START ENTRY
- WBOOT: JP BOOTW ;WARM START ENTRY
- CSE: JP ZCSTS ;CONSOLE STATUS
- CIE: JP ZCI ;CONSOLE IN
- COE: JP ZCO ;CONSOLE OUT
- LIST: JP ZLO ;TO MONITOR FOR PRINTER
- PUNCH: JP ZPOO ;TO MONITOR FOR PUNCH
- READR: JP ZRI ;TO MONITOR FOR READER
- HME: JP HOME ;MOVE TO TRACK 0
- SDSKE: JP SELDSK
- STRKE: JP SETTRK
- SSECE: JP SETSEC
- SDMAE: JP SETDMA
- RDE: JP READ
- WRE: JP WRITE
- LISTS: JP ZLISTS ;LIST STATUS
- SECTR: JP SECTRAN ;FOR 2.2 SECTOR TRANSLATION TABLE
- ;
- DTYPE: JP UNITSL ;SET UP UNIT BYTE (DISK DENSITY)
- SVE: JP SAVER ;SAVE N RECORDS
- LDE: JP LOADER ;LOAD N SECTORS
- ;
- ;----------------------------------------------------------------------
- ;
- ;BOOT LOADS A SECTOR TO 80H AFTER CHECKING DISK TYPE THEN JUMPS TO 80H
- ;
- BOOT: XOR A
- LD (CDISK),A ;MAKE CURRENT DISK A:
- LD (IOBYTE),A ;CLEANUP IOBYTE
- LD (VDMFLG),A ;ASCII TO VDM BOARD NOT YET SENT
- DEC A
- LD (CBFLAG),A ;INDICATE A COLD BOOT TO LOADER
- LD HL,MSG0 ;SEND SIGNON MESSAGE
- CALL ZTOMM
- IN A,(STORE);---FOR MY SYSTEM I/O (CAN REMOVE THIS & NEXT 2 LINES)
- LD E,A
- CALL ZBITS
- JR BOOTW1
- ;
- BOOTW: XOR A ;INDICATE TO LOADER A WARM BOOT
- LD B,A
- LD (CBFLAG),A
- BOOTW1: LD SP,SSTACK
- LD A,8EH ;SWITCH ON DRIVE A DISABLE ANY WAIT STATES
- OUT (SELECT),A
- LD A,08H ;LOAD HEAD WITH A RESTORE (NO VERIFY)
- OUT (CMD),A ;THE HEAD LOAD STARTS MY DRIVE MOTOR
- BOOTW2: DJNZ BOOTW2 ;DELAY A LITTLE TO LET MOTOR GET TO SPEED
- PUSH HL ;SAVE [SP] HERE FOR ALL ERRORS ETC
- LD (SPSV),SP
- POP HL
- CALL FRCINT
- XOR A
- OUT (TRACK),A
- LD A,2
- LD (TRK),A
- LD A,SKNCMD
- CALL SEEK4
- BT2: XOR A ;COME UP ON A: DRIVE
- CALL UNITSL ;IS IT SD OR DD
- JR NZ,GOMON ;IF NONE OF THE ABOVE QUIT
- ;
- BT4: LD A,(UNIT)
- AND 01000000B ;ISOLATE ALL BUT DENSITY BIT
- LD (ADRIVE),A ;SO ADRIVE= 0H IF SD & 40H IF DD
- LD A,0FFH ;FLAG B: AS NOT YET OBTAINED
- LD (BDRIVE),A
- CALL BOOTLD
- LD HL,COLD
- LD A,(HL)
- CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H
- JR NZ,GOMON1 ;AS THE FIRST INSTRUCTION
- JP COLD ;IF ALL IS OK. JUMP TO 80H AND LOAD CP/M
- ;
- GOMON: LD HL,MSG1 ;"CANNOT SELECT DISK"
- JR GOMON2
- GOMON1: LD HL,MSG2 ;"ERROR READING LOADER"
- GOMON2: CALL ZTOMM
- JP MONITOR
- ;
- BOOTLD: LD HL,COLD
- BOOT1: LD (TADDR),HL
- BOOT2: XOR A
- LD (TRK),A ;SET TRACK 0
- INC A
- LD (SCTR),A
- CALL READ
- RET Z
- JR GOMON1
- ;
- ; THIS ROUTINE SETS UP THE UNIT BYTE
- ; THE REQUIRED DRIVE IS IN [A]
- ;
- UNITSL: LD B,5
- AND 0FH
- OR 40H ;COME UP DEFALT IN 8" DD
- LD (UNIT),A
- LD HL,(TADDR)
- LD (TEMP2),HL
- CALL USL1
- LD HL,(TEMP2)
- LD (TADDR),HL
- LD A,(UNIT)
- RET
- ;
- USL1: PUSH BC
- PUSH HL
- LD (SPSV),SP
- POP HL
- CALL DRVSET ;SELECT DRIVE IN HARDWARE
- CALL IDRD
- POP BC
- LD A,(IDSV+3) ;THIS CHECKS FOR 256 BYTES/SECTOR NOT
- RRCA ;USED IN THIS BIOS. IF CORRECT DENSITY
- RET Z ;IT WILL BE Z
- ;@ IDSV)
- DEC B ;DECREASE 5.......0 IF Z THEN ERROR
- JP Z,SPECIAL
- CALL CHGTYP
- JR USL1
- ;
- SPECIAL:XOR A ;COULD BE LATER USED FOR SPECIAL SECTOR SIZE
- DEC A
- RET ;RET NZ SO SELDSK KNOWS THERE IS A PROBLEM
- ;
- CHGTYP: LD A,(UNIT)
- ADD 01000000B ;TOGGLE DENSITY BIT
- AND 01111111B ;CLEAR BIT 7
- LD (UNIT),A
- RET
- ;
- ; DISK CONTROLLER LINKAGES
- ;
- HOME: XOR A ;THIS CUTS DOWN ON HEAD MOVEMENT SINCE MANY
- LD (TRK),A ;TIMES RESTORE IS NOT REQ
- RET
- ;
- ;
- SELDSK: LD A,C
- CP 2
- JP NC,HDBIO1 ;THIS WILL RETURN 0000 IN [HL] TO TELL CPM
- OR A ;THERE IS A PROBLEM
- JP NZ,BBBB ;IS B DRIVE
- LD A,(ADRIVE)
- OR C
- LD (UNIT),A ;SET A: TO CORRECT DENSITY
- JP ALLOK
- BBBB: LD A,(BDRIVE)
- CP 0FFH ;IS THIS FIRST TIME
- JP NZ,BBB1
- LD A,C ;IF SO GET DISK TYPE (AND SIZE)
- CALL UNITSL
- JP NZ,HDBIO1 ;BACK TO CPM WITH [HL]=0 & ERROR
- LD A,(UNIT)
- AND 01000000B
- LD (BDRIVE),A
- BBB1: OR C
- LD (UNIT),A
- ;
- ALLOK: BIT 6,A
- JP Z,ALLOK1 ;IS IT DD OR SD
- LD A,00000010B ;YES DD THEN CONVERT TO DD
- ADD C ;IE MAKE A:=C: AND B:=D:
- LD C,A ;NOTE THIS IS ONLY FOR CPM SOFTWARE
- ALLOK1: LD L,C
- LD H,0 ;ACTUAL DISK PARAMETER BLOCK IS GOT IN DDSKBIOS
- RET
- ;
- ;
- SETTRK: LD A,C
- LD (TRK),A
- RET
- ;
- SETSEC: LD A,C
- LD (SCTR),A
- RET
- ;
- SETDMA: LD (TADDR),BC
- RET
- ;
- SECTRAN:LD B,0
- EX DE,HL
- ADD HL,BC
- LD L,(HL)
- LD H,0
- RET
- ;
- ; READ A SECTOR
- READ: LD BC,301H
- READBT: LD (RSEEK),BC
- READ1: PUSH BC
- CALL RDSC
- POP BC
- RET Z
- CALL RETRY
- JR READ1
- ;
- ; WRITE A SECTOR
- WRITE: LD BC,301H
- WRBT: LD (RSEEK),BC
- WRITE1: PUSH BC
- CALL WRSC
- POP BC
- RET Z
- CALL RETRY
- JR WRITE1
- ;
- RETRY: DJNZ RETRY2
- LD A,(RTRY)
- LD B,A
- DEC C
- JP P,RETRY1
- POP AF
- XOR A
- INC A
- RET
- RETRY1: PUSH BC
- CALL HOME1
- POP BC
- RETRY2: RET
- HOME1: LD (SPSV),SP
- LD A,RSCMD
- CALL SEEK4
- XOR A
- RET
- ;
- ; SELECT DRIVE IN HARDWARE
- ;
- DRVSET:LD DE,UNIT
- LD A,(DE)
- AND 0E0H
- LD C,A ;STORE DRIVE TYPE IN [C]
- LD A,(DE)
- AND 03
- LD B,A ;STORE DRIVE # IN [B]
- LD A,1
- JR Z,DRVSEL
- CKDRV1: RLCA
- DJNZ CKDRV1
- DRVSEL: OR C ;COMBINE TYPE & DRIVE#
- AND 7FH
- LD B,A ;[B] CONTAINS INFO FOR HARDWARE
- LD A,STDSDT ;SETUP FOR SD
- LD (COUNT),A ;STORE AS 26 SECTORS/TRACK
- LD A,40H ;WAS IT DD
- DRV1: CP C
- JR NZ,CKDRV
- LD A,STDDDT ;SETUP FOR DD
- LD (COUNT),A ;SET TO 50 SECTORS/TRACK
- CKDRV: LD A,B ;GET HARDWARE SELECT DATA
- CPL ;HARDWARE IS INVERTED
- OUT (SELECT),A
- LD A,(DE)
- LD (UNITCK),A
- CALL DELAY
- RDYCK: IN A,(STATUS)
- AND 80H
- JP NZ,END2
- RET
- ;
- ; READ PRESENT DISK ADDRESS
- IDRD: CALL WAIT
- LD HL,IDSV
- LD BC,600H+DATA ;READ 6 BYTES
- LD A,0F8H
- LD (ERMASK),A
- CALL SWEB
- LD A,RDACMD ;DO THE ID READ
- CALL RDSCO
- LD A,(IDSV)
- CP NTRKS ;IS IT REASONABLE
- JP NC,SEEK0
- OUT (TRACK),A
- XOR A
- RET
- ;
- DELAY: LD A,40 ;DELAY ~32 MS (DOES NOT SEEM TO BE CRITICAL)
- DELAY1: LD B,0
- M0: DJNZ M0
- DEC A
- JR NZ,DELAY1
- RET
- ;
- ; READ SECTOR COMMAND
- RDSC: CALL DRINIT
- LD A,RDCMD
- RDSCO: LD (CMDSV),A
- DI
- OUT (CMD),A
- JR M2
- M2: JR MM2
- MM2: INIR
- EI
- JR END
- ;
- ;
- ; WRITE SECTOR COMMAND
- WRSC: CALL DRINIT
- LD A,WRCMD
- LD (CMDSV),A
- DI
- OUT (CMD),A
- JR H2
- H2: JR HM2
- HM2: OTIR
- EI
- ;
- ; END OF COMMAND
- END: CALL WAIT
- IN A,(STATUS)
- LD D,A
- LD A,(ERMASK)
- AND D
- RET Z
- END1: LD A,D
- END2: LD (ERSTAT),A
- CALL DELAY
- OR 1
- LD SP,(SPSV)
- CALL UNITFX
- RET
- ;
- ;
- ; DRIVE INITIALIZATION
- ;
- DRINIT: CALL VDMDUMP ;WILL SEE IF DISK TRACK/SECTOR INFO IS REQ.
- POP HL
- LD (SPSV),SP
- PUSH HL
- LD A,(UNIT)
- LD D,A
- LD A,(UNITCK)
- CP D
- JR Z,DINIT1
- CALL DRVSET
- CALL IDRD
- DINIT1: CALL SEEK
- LD A,0FEH
- LD (ERMASK),A
- ;
- TRINT: LD HL,(TADDR) ;SETUP DMA ADDRESS AND BYTE COUNT
- LD A,(SCTR)
- OUT (SECTOR),A
- LD BC,NBYTES*100H+DATA
- ;
- SWEB: IN A,(SELECT) ;ENABLE WAIT STATES
- AND 7FH
- OUT (SELECT),A
- RET
- ;
- ;
- ;
- ; SEEK TRACK
- ;
- SEEK: CALL RDYCK
- LD C,NTRKS ;MUST BE REASONABLE TRACK #
- LD A,(TRK)
- CP C
- JR C,SEEK1
- SEEK0: LD A,0FH
- JR END2
- SEEK1: LD C,A
- IN A,(TRACK)
- CP C
- RET Z ;IF SAME TRACK NO NEED TO SEEK
- LD A,SKCMD
- SEEK4: LD (CMDSV),A
- LD B,210
- S0: DJNZ S0
- CALL WAIT
- LD A,(TRK)
- OUT (DATA),A
- LD A,80H
- LD (ERMASK),A
- LD A,(CMDSV)
- OUT (CMD),A
- LD B,10
- D0: DJNZ D0
- CALL END
- CALL DELAY
- LD A,(CMDSV)
- CP RSCMD ;NO NEED TO CHECK RESTORE COMMAND
- RET Z
- IN A,(STATUS)
- AND 10H
- JR NZ,SEEK2
- IN A,(TRACK)
- CP C
- RET Z
- SEEK2: LD A,20H
- END2JP: JP END2
- ;
- WAIT: LD E,0
- PUSH BC
- LD C,2
- WAIT2: IN A,(STATUS)
- AND 1
- JR Z,DWAIT
- DJNZ WAIT2
- DEC E
- JR NZ,WAIT2
- DEC C
- JR NZ,WAIT2
- POP BC
- IN A,(SELECT) ;IF BY THIS TIME NOT READY FORCE
- OR 80H ;A HARDWARE RESET
- OUT (RSET),A
- F0: DJNZ F0
- IN A,(RSET)
- CALL FRCINT
- LD A,RSCMD
- CALL SEEK4
- LD A,0FEH
- JP END2JP
- ;
- ; DISABLE WAIT STATES
- DWAIT: POP BC ;TO BALANCE THE ABOVE PUSH IN WAIT
- IN A,(SELECT)
- OR 80H
- OUT (SELECT),A
- RET
- ;
- ;
- ;
- ; FORCE CHIP INTERUPT
- FRCINT: LD A,0D0H
- OUT (CMD),A
- LD A,10
- FRC1: DEC A
- JR NZ,FRC1
- IN A,(STATUS)
- RET
- ;
- ; LOAD A NUMBER OF SECTORS
- LOADER: CALL UNITFX
- LD1: CALL READ
- RET NZ
- CALL INCP
- JR NZ,LD1
- RET
- ;
- ; SAVE A NUMBER OF SECTORS
- SAVER: CALL UNITFX
- SV1: CALL WRITE
- RET NZ
- CALL INCP
- JR NZ,SV1
- RET
- ;
- ; INC SECTOR AND TRACK
- INCP: LD HL,(TADDR)
- LD DE,NBYTES
- INCP2: ADD HL,DE
- LD (TADDR),HL
- LD HL,NREC
- DEC (HL)
- RET Z
- LD HL,SCTR
- INC (HL)
- LD A,(COUNT) ;IS ONE TRACK DONE YET
- INC A
- CP (HL)
- RET NZ ;IF FULL GO TO NEXT TRACK
- LD (HL),1 ;SET SECTOR COUNT BACK TO 1
- INC HL ;ASSUMES TRK=SECTOR+1 IE 44H
- INC (HL)
- OR A ;MAKE SURE TO RETURN NZ
- RET
- ;
- ;
- UNITFX: LD A,0FFH
- LD (UNITCK),A
- RET
- ;
- ;THE FOLLOWING ARE MONITOR LIKE COMMANDS I HAVE ADDED
- ;
- ZTOMM: LD A,(HL)
- CP '$'
- RET Z
- LD C,A
- INC HL
- CALL ZCO
- JR ZTOMM
- ;
- ZBITS: PUSH BC ;DISPLAY BIT PATTERN IN [E]
- LD B,8
- BQ2: SLA E
- LD A,18H
- ADC A,A
- LD C,A
- CALL ZCO
- DJNZ BQ2
- POP BC
- RET
- ;
- ; THIS IS A ROUTINE THAT WILL PLACE ON A VDM THE CURRENT SELECTED TRACK/SECTOR
- ; INFORMATION. IT IS CONTINOUSLY UPDATED FOR EACH SECTOR READ OR WRITE IF BIT 7
- ; OF PORT "PANEL" IS RESET. NOTE IT ADDS EXTRA TIME TO DISK ASCESS SO BIT 7
- ; SHOULD BE USED ONLY FOR DEBUGGING ETC.
- ;
- VDMDUMP:IN A,(PANNEL) ;FIND OUT IF DISPLAY IS REQ
- BIT 7,A
- RET NZ ;NZ IF NO DISPLAY WANTED
- PUSH HL ;JUST IN CASE
- PUSH DE
- PUSH BC ;[AF] DOES NOT MATTER
- LD A,(VDMFLG) ;IS ASCII ALREADY THERE
- OR A
- JR NZ,VDM1
- LD HL,MSG3 ;DROP IN ASCII
- LD DE,SSMVID
- LD BC,MSGL-MSG3
- LDIR
- XOR A
- LD (VDMFLG),A ;SO NO UPDATE NEXT TIME
- VDM1: LD HL,SSMDSK
- LD A,(UNIT)
- CALL DUMP
- LD HL,SSMTRK
- LD A,(TRK)
- CALL DUMP
- LD HL,SSMSEC
- LD A,(SCTR)
- CALL DUMP
- LD HL,SSMDMA
- LD A,(TADDR+1)
- CALL DUMP
- LD HL,SSMDMA+2
- LD A,(TADDR)
- CALL DUMP
- POP BC
- POP DE
- POP HL
- RET
- ;
- DUMP: LD B,A ;STORE [A] FOR BELOW
- CALL CONVII
- LD A,B
- DEC HL ;DEC BECAUSE PRINTS RIGHT TO LEFT
- RRCA ;GET UPPER NIBBLE
- RRCA
- RRCA
- RRCA
- CONVII: AND 0FH ;CONVERT HEX TO ASCII
- ADD A,90H
- DAA
- ADC A,40H
- DAA
- LD (HL),A
- RET
- ;
- ;
- ;
- HDBIO1: LD HL,0H
- POP AF ;THIS POPS OFF THE RETURN THAT WOULD GO
- ;TO DSKBIOS INSTEAD IT RETURNS TO CP/M WITH
- XOR A ;0000 IN [HL]. THIS IS TAKEN AS AN ERROR BY CPM
- LD (CDISK),A ;SO WARMSTART WILL COME UP ON A:
- INC A
- RET
- ;
- MSG0: DB CLEAR,LF,01H,10H,11H,CR,TAB,TAB,'DISK LOADING'
- DB TAB,TAB,TAB,TAB,'STORE BYTE--',03H,5DH,' $'
- MSG1: DB CR,LF,BELL,'Cannot select disk',CR,LF,'$'
- MSG2: DB CR,LF,BELL,'Error reading CP/M loader',CR,LF,'$'
- MSG3: DB 'Disk Track Sector '
- DB ' Taddress '
- MSGL EQU $
- ;
- ;
- ;END DDBIOS.Z80
-