Compare commits

...

6 Commits

Author SHA1 Message Date
Wayne Warthen
69716abb25 Regen Doc 2023-06-08 12:34:42 -07:00
Wayne Warthen
1f526d440a Add WDATE Command, Final PPA/IMM/SYQ Driver Cleanup
- Added WDATE command courtesy Kevin Boone.  See https://github.com/kevinboone/wdate-cpm for more information.
- Final cleanup of PPA/IMM/SYQ drivers including CPU speed compensated timeouts.
2023-06-08 11:59:07 -07:00
Wayne Warthen
84374c86e6 Cleanup and Optimizations for PPA/IMM/SYQ Drivers 2023-06-06 16:21:56 -07:00
Wayne Warthen
45ea46b105 Small Bug Fix for PPA/IMM/SYQ Drivers
Credit to Mark Elkin for testing and finding this issue.
2023-06-03 14:27:33 -07:00
Wayne Warthen
1333d6a491 Functional PPA Driver 2023-06-02 15:30:10 -07:00
Wayne Warthen
b7e865dbf1 Preliminary SyQuest Driver 2023-06-01 16:13:26 -07:00
40 changed files with 2636 additions and 306 deletions

View File

@@ -7,7 +7,9 @@ Version 3.3
- WBW: Support per-drive floppy configuration
- WBW: Support for Bill Shen's VGARC
- WBW: Support for MG014 Parallel Port module + printer
- WBW: Support for Zip Drive on emm interface (much inspiration from Alan Cox)
- WBW: Support for EMM Zip Drive on PPI interface (much inspiration from Alan Cox)
- WBW: Support for PPA Zip Drive on PPI interface (much inspiration from Alan Cox)
- WBW: Support for SyQuest SparQ Drive on PPI interface (much inspiration from Alan Cox)
Version 3.2.1
-------------

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3,7 +3,7 @@
**RomWBW ReadMe** \
Version 3.3 \
Wayne Warthen ([wwarthen@gmail.com](mailto:wwarthen@gmail.com)) \
23 May 2023
06 Jun 2023
# Overview

View File

@@ -1,6 +1,6 @@
RomWBW ReadMe
Wayne Warthen (wwarthen@gmail.com)
23 May 2023
06 Jun 2023

View File

@@ -1920,7 +1920,7 @@ dev08 .db "PPPSD",0
dev09 .db "HDSK",0
dev10 .db "PPA",0
dev11 .db "IMM",0
dev12 .equ devunk
dev12 .db "SYQ",0
dev13 .equ devunk
dev14 .equ devunk
dev15 .equ devunk

View File

@@ -2934,6 +2934,8 @@ DRV_INIT3A:
JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK
CP DIODEV_IMM ; IMM (ZIP DRIVE) IS REMOVABLE
JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK
CP DIODEV_SYQ ; IMM (ZIP DRIVE) IS REMOVABLE
JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK
; CHECK FOR ACTIVE AND RETURN IF NOT
PUSH DE ; SAVE DE (HARD DISK VOLUME COUNTER)
@@ -3401,7 +3403,7 @@ DEV08 .DB "PPPSD$"
DEV09 .DB "HDSK$"
DEV10 .DB "PPA$"
DEV11 .DB "IMM$"
DEV12 .EQU DEVUNK
DEV12 .DB "SYQ$"
DEV13 .EQU DEVUNK
DEV14 .EQU DEVUNK
DEV15 .EQU DEVUNK

View File

@@ -186,6 +186,8 @@ dinit3a:
jr z,dinit3b ; if so, skip media check
cp 0B0h ; imm (zip drive) is removable
jr z,dinit3b ; if so, skip media check
cp 0C0h ; syq (syquest drive) is removable
jr z,dinit3b ; if so, skip media check
; check for active and return if not
push de ; save de (hard disk volume counter)

View File

@@ -51,6 +51,7 @@ found:
| INTTEST | No | Yes | Yes |
| FAT | No | Yes | Yes |
| TUNE | No | Yes | Yes |
| WDATE | No | Yes | Yes |
`\clearpage`{=latex}
@@ -1128,3 +1129,85 @@ can be used to reduce your processor speed.
VGMPLAY is still under development. The source code is provided in the
RomWBW distribution.
`\clearpage`{=latex}
# WDATE
`wdate` is a utility for CP/M systems that have Wayne Warthen's
ROMWBW firmware. It reads or sets the real-time clock, using function
calls in the BIOS. It should work on any RTC device that is supported by
ROMWBW, including the internal interrupt-driven timer that is is available
on some systems.
`wdate` differs from the `rtc.com` utility that is provided with the
ROMWBW version of CP/M in that it only gets and sets the date/time.
`rtc.com` can also manipulate the nonvolatile RAM in certain clock
devices, and modify the charge controller. However, `wdate` is (I would
argue) easier to use, as it takes its input from the command line, which
can be edited, and it's less fussy about the format. It doesn't require
the date to be set if you only want to change the time, for example.
In addition, `wdate` has at least some error checking.
`wdate` displays the day-of-week and month as English text, not
numbers. It calculates the day-of-week from the year, month, and day.
RTC chips usually store a day-of-week value, but it's useless in this
application for two reasons: first, the BIOS does not expose it. Second,
there is no universally-accepted way to interpret it (which day does
the week start on? Is '0' a valid day of the week?)
## Syntax
| `WDATE`
| `WDATE ` *`<hr> <min>`*
| `WDATE ` *`<hr> <min> <sec>`*
| `WDATE ` *`<year> <month> <day> <hr> <min> <sec>`*
## Usage
A> wdate
Saturday 27 May 13:14:39 2023
With no arguments, displays the current date and time.
A> wdate hr min
With two arguments, sets the time in hours and minutes, without changing date
or seconds
A> wdate hr min sec
With three arguments, sets the time in hours, minutes, and seconds, without
changing date
A> wdate year month day hr min sec
With six arguments, sets date and time. All numbers are one or two digits. The
two-digit year starts at 2000.
A> wdate /?
Show a summary of the command-line usage.
## Notes
I've tested this utility with the DS1302 clock board designed by Ed
Brindly, and on the interrupt-driven timer built into my Z180 board.
However, it does not interact with hardware, only BIOS; I would expect
it to work with other hardware.
wdate checks for the non-existence of ROMWBW, and also for failing
operations on the RTC. It will display the terse "No RTC" message in
both cases.
The ROMWBW functions that manipulate the date and time operate on BCD
numbers, as RTC chips themselves usually do. wdate works in decimal, so
that it can check that the user input makes sense. A substantial part of
the program's code is taken up by number format conversion and range
checking.
## Etymology
The `WDATE` application was written and contributed by Kevin Boone.
The source code is available on GitHub at
[https://github.com/kevinboone/wdate-cpm/blob/main/README.md](https://github.com/kevinboone/wdate-cpm/blob/main/README.md).

View File

@@ -3901,6 +3901,7 @@ may be discovered by RomWBW in your system.
| GDC | Video | uPD7220 Video Display Controller |
| HDSK | Disk | SIMH Simulator Hard Disk |
| IDE | Disk | IDE/ATA Hard Disk Interface |
| IMM | Disk | IMM Zip Drive on PPI |
| INTRTC | RTC | Interrupt-based Real Time Clock |
| KBD | Kbd | 8242 PS/2 Keyboard Controller |
| KIO | System | Zilog Serial/ Parallel Counter/Timer |
@@ -3910,6 +3911,7 @@ may be discovered by RomWBW in your system.
| I2C | System | I2C Interface |
| PIO | Char | Zilog Parallel Interface Controller |
| PPIDE | Disk | 8255 IDE/ATA Hard Disk Interface |
| PPA | Disk | PPA Zip Drive on PPI |
| PPK | Kbd | Matrix Keyboard |
| PPPSD | Disk | ParPortProp SD Card Interface |
| PPPCON | Serial | ParPortProp Serial Console Interface |
@@ -3922,6 +3924,7 @@ may be discovered by RomWBW in your system.
| SIO | Char | Zilog Serial Port Interface |
| SN76489 | Sound | SN76489 Programmable Sound Generator |
| SPK | Sound | Bit-bang Speaker |
| SYQ | Disk | Iomega SparQ Drive on PPI |
| TMS | Video | TMS9918/38/58 Video Display Controller |
| UART | Char | 16C550 Family Serial Interface |
| USB-FIFO | Char | FT232H-based ECB USB FIFO |

View File

@@ -256,6 +256,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -320,17 +320,24 @@ LPT1BASE .EQU $EC ; LPT 1: REGISTERS BASE ADR
PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
PPACNT .EQU 1 ; PPA: NUMBER OF PPA DEVICES (1-2)
PPATRACE .EQU 1 ; PPA: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
PPAMODE .EQU PPAMODE_MG014 ; PPA: DRIVER MODE: PPAMODE_[NONE|SPP|MG014]
PPAMODE .EQU PPAMODE_SPP ; PPA: DRIVER MODE: PPAMODE_[NONE|SPP|MG014]
PPA0BASE .EQU LPT0BASE ; PPA 0: BASE I/O ADDRESS OF PPI FOR PPA
PPA1BASE .EQU LPT1BASE ; PPA 1: BASE I/O ADDRESS OF PPI FOR PPA
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
IMMCNT .EQU 1 ; IMM: NUMBER OF IMM DEVICES (1-2)
IMMTRACE .EQU 1 ; IMM: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMMMODE .EQU IMMMODE_SPP ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM
IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2)
SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
SYQMODE .EQU IMMMODE_SPP ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014]
SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ
SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)

View File

@@ -255,6 +255,13 @@ IMMMODE .EQU IMMMODE_SPP ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM
IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2)
SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
SYQMODE .EQU IMMMODE_SPP ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014]
SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ
SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)

View File

@@ -258,6 +258,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)

View File

@@ -251,6 +251,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)

View File

@@ -277,6 +277,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM
IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2)
SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014]
SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ
SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -281,6 +281,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM
IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2)
SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014]
SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ
SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -275,6 +275,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM
IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2)
SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014]
SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ
SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -240,6 +240,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)

View File

@@ -239,6 +239,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)

View File

@@ -271,6 +271,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014]
IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM
IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2)
SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL)
SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014]
SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ
SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -210,6 +210,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -181,6 +181,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -192,6 +192,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM)
;
IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM)
;
SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM)
;
PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD
PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM)
PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP

View File

@@ -3245,6 +3245,9 @@ HB_INITTBL:
#IF (IMMENABLE)
.DW IMM_INIT
#ENDIF
#IF (SYQENABLE)
.DW SYQ_INIT
#ENDIF
#IF (PRPENABLE)
.DW PRP_INIT
#ENDIF
@@ -6372,6 +6375,15 @@ SIZ_IMM .EQU $ - ORG_IMM
.ECHO " bytes.\n"
#ENDIF
;
#IF (SYQENABLE)
ORG_SYQ .EQU $
#INCLUDE "syq.asm"
SIZ_SYQ .EQU $ - ORG_SYQ
.ECHO "SYQ occupies "
.ECHO SIZ_SYQ
.ECHO " bytes.\n"
#ENDIF
;
#IF (TERMENABLE)
ORG_TERM .EQU $
#INCLUDE "term.asm"
@@ -7158,6 +7170,7 @@ PS_DDPPPSD .TEXT "PPPSD$"
PS_DDHDSK .TEXT "HDSK$"
PS_DDPPA .TEXT "PPA$"
PS_DDIMM .TEXT "IMM$"
PS_DDSYQ .TEXT "SYQ$"
;
; DISK TYPE STRINGS
;
@@ -7570,6 +7583,52 @@ HB_HASFP .DB 0 ; NON-ZERO MEANS FP EXISTS
;
HB_WRKBUF .FILL 512,0 ; INTERNAL DISK BUFFER
;
;
;
#IFDEF MG014_MAP
;
.FILL 32 - ($ & (32 - 1)) ; ALIGN TO 32 BYTE BOUNDARY
MG014_STATMAPLO:
; LOWER NIBBLE
.DB $08 ; 00
.DB $0C ; 01
.DB $00 ; 02
.DB $04 ; 03
.DB $0A ; 04
.DB $0E ; 05
.DB $02 ; 06
.DB $06 ; 07
.DB $09 ; 08
.DB $0D ; 09
.DB $01 ; 0A
.DB $05 ; 0B
.DB $0B ; 0C
.DB $0F ; 0D
.DB $03 ; 0E
.DB $07 ; 0F
;
MG014_STATMAPHI:
; UPPER NIBBLE
.DB $80 ; 00
.DB $C0 ; 01
.DB $00 ; 02
.DB $40 ; 03
.DB $A0 ; 04
.DB $E0 ; 05
.DB $20 ; 06
.DB $60 ; 07
.DB $90 ; 08
.DB $D0 ; 09
.DB $10 ; 0A
.DB $50 ; 0B
.DB $B0 ; 0C
.DB $F0 ; 0D
.DB $30 ; 0E
.DB $70 ; 0F
;
#ENDIF
;
HB_END .EQU $
;
SLACK .EQU BNKTOP - $

View File

@@ -323,6 +323,7 @@ DIODEV_PPPSD .EQU $80
DIODEV_HDSK .EQU $90
DIODEV_PPA .EQU $A0
DIODEV_IMM .EQU $B0
DIODEV_SYQ .EQU $C0
;
; RTC DEVICE IDS
;

View File

@@ -9,11 +9,14 @@
; INTENDED TO CO-EXIST WITH LPT DRIVER.
;
; CREATED BY WAYNE WARTHEN FOR ROMWBW HBIOS.
; MUCH OF THE CODE IS DERIVED FROM FUZIX (ALAN COX).
; MUCH OF THE CODE IS DERIVED FROM LINUX AND FUZIX (ALAN COX).
; - https://github.com/EtchedPixels/FUZIX
; - https://github.com/torvalds/linux
;
; 5/23/2023 WBW - INITIAL RELEASE
; 5/26/2023 WBW - CLEAN UP, LED ACTIVITY
; 5/27/2023 WBW - ADDED SPP MODE
; 05/23/2023 WBW - INITIAL RELEASE
; 05/26/2023 WBW - CLEAN UP, LED ACTIVITY
; 05/27/2023 WBW - ADDED SPP MODE
; 06/06/2023 WBW - OPTIMIZE BLOCK READ AND WRITE
;
;=============================================================================
;
@@ -71,22 +74,18 @@
;
; TODO:
;
; - OPTIMIZE READ/WRITE LOOPS
;
; NOTES:
;
; - THIS DRIVER IS FOR THE ZIP DRIVE IMM INTERFACE. IT WILL SIMPLY
; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE OLDER PPA INTERFACE.
; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP
; DRIVE IS IMM OR PPA. SIGH.
; DRIVE IS PPA OR IMM. SIGH.
;
; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE
; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON
; FASTER CPUS.
;
; - THIS DRIVER OPERATES PURELY IN NIBBLE MODE. I SUSPECT IT IS
; POSSIBLE TO USE FULL BYTE MODE (PS2 STYLE), BUT I HAVE NOT
; ATTEMPTED IT.
; - THIS DRIVER OPERATES USES NIBBLE READ MODE. ALTHOUGH THE 8255
; (MG014) CAN READ OR WRITE TO PORT A (DATA), IT "GLITCHES" WHEN
; THE MODE IS CHANGED CAUSING THE CONTROL LINES TO CHANGE AND
; BREAKS THE PROTOCOL. I SUSPECT THE MBC SPP CAN SUPPORT FULL BYTE
; MODE, (PS2 STYLE), BUT I HAVE NOT ATTEMPTED IT.
;
; - RELATIVE TO ABOVE, THIS BEAST IS SLOW. IN ADDITION TO THE
; NIBBLE MODE READS, THE MG014 ASSIGNS SIGNALS DIFFERENTLY THAN
@@ -130,6 +129,17 @@ IMM_IOBASE .EQU 3 ; IO BASE ADDRESS (BYTE)
IMM_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
IMM_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
; MACROS
;
#DEFINE IMM_WCTL(VAL) LD A,VAL \ CALL IMM_WRITECTRL
#DEFINE IMM_WDATA(VAL) LD A,VAL \ CALL IMM_WRITEDATA
;
; INCLUDE MG014 NIBBLE MAP FOR MG014 MODE
;
#IF (IMMMODE == IMMMODE_MG014)
#DEFINE MG014_MAP
#ENDIF
;
;=============================================================================
; INITIALIZATION ENTRY POINT
;=============================================================================
@@ -184,8 +194,8 @@ IMM_INIT4:
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
;
CALL IMM_RESET ; RESET/INIT THE INTERFACE
#IF (IMMTRACE == 0)
CALL IMM_PRTSTAT
#IF (IMMTRACE <= 1)
CALL NZ,IMM_PRTSTAT
#ENDIF
JR NZ,IMM_INIT6
;
@@ -219,6 +229,11 @@ IMM_INIT6:
; ON RETURN, ZF SET INDICATES HARDWARE FOUND
;
IMM_DETECT:
#IF (IMMTRACE >= 3)
PRTS("\r\nDETECT:$")
#ENDIF
;
#IF (IMMMODE == IMMMODE_MG014)
; INITIALIZE 8255
LD A,(IY+IMM_IOBASE) ; BASE PORT
ADD A,IMM_IOSETUP ; BUMP TO SETUP PORT
@@ -226,29 +241,53 @@ IMM_DETECT:
LD A,$82 ; CONFIG A OUT, B IN, C OUT
OUT (C),A ; DO IT
CALL DELAY ; BRIEF DELAY FOR GOOD MEASURE
#ENDIF
;
; WE USE THIS SEQUENCE TO DETECT AN ACTUAL IMM DEVICE ON THE
; PARALLEL PORT. THE VALUES RECORDED IN THE FINAL CALL TO
; IMM_DISCONNECT ARE USED TO CONFIRM DEVICE PRESENCE.
; NO ACTUAL SCSI COMMANDS ARE USED.
; ATTEMPT TO ESTABLISH A CONNECTION TO THE IMM DEVICE AND
; ISSUE A SCSI BUS RESET. WE DON'T KNOW IF DEVICE IS THERE
; YET. THIS IS DONE BLIND ASSUMING IT IS THERE.
CALL IMM_DISCONNECT
CALL IMM_CONNECT
CALL IMM_RESETPULSE ; ISSUE A SCSI BUS RESET
LD DE,62 ; WAIT A BIT
CALL VDELAY
;
; USE AN ABBREVIATED VERSION OF SELECT PROCESSING TO
; CHECK IF DEVICE EXISTS.
IMM_WCTL($0C)
CALL IMM_READSTATUS
;
#IF (IMMTRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
; READY FOR SELECT?
AND $08
CP $00
JR NZ,IMM_DETECT1
;
IMM_WCTL($04)
LD A,$80 | (1 << IMM_TGT)
CALL IMM_WRITEDATA
IMM_WCTL($0C)
IMM_WCTL($0D)
CALL DELAY
CALL IMM_READSTATUS
;
#IF (IMMTRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
; DID SELECT SUCCEED?
AND $08
CP $08
;
IMM_DETECT1:
PUSH AF
CALL IMM_DISCONNECT
;
; THE IMM_SN VALUES ARE RECORDED IN THE CPP ROUTINE USED BY
; IMM_CONNECT/DISCONNECT.
; EXPECTING S1=$B8, S2=$18, S3=$38
LD A,(IMM_S1)
CP $B8
RET NZ
LD A,(IMM_S2)
CP $18
RET NZ
LD A,(IMM_S3)
CP $38
RET NZ
;
XOR A
POP AF
RET
;
;=============================================================================
@@ -289,7 +328,7 @@ IMM_READ:
;
;
IMM_WRITE:
CALL HB_DSKREAD ; HOOK DISK WRITE CONTROLLER
CALL HB_DSKWRITE ; HOOK DISK WRITE CONTROLLER
LD A,SCSI_CMD_WRITE ; SETUP SCSI WRITE
LD (IMM_CMD_RW),A ; AND SAVE IT IN SCSI CMD
JP IMM_IO ; DO THE I/O
@@ -297,9 +336,18 @@ IMM_WRITE:
;
;
IMM_IO:
LD (IMM_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
PUSH HL
CALL IMM_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO
POP HL
JR NZ,IMM_IO3 ; BAIL OUT ON ERROR
;
LD (IMM_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
;
#IF (DSKYENABLE)
LD A,IMM_LBA
CALL LDHLIYA
CALL HB_DSKACT ; SHOW ACTIVITY
#ENDIF
;
; SETUP LBA
; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN
@@ -313,10 +361,9 @@ IMM_IO:
LD A,(IY+IMM_LBA+0)
LD (HL),A
INC HL
;
; DO SCSI IO
LD DE,(IMM_DSKBUF) ; DISK BUFFER TO DE
LD BC,512 ; ONE SECTOR, 512 BYTES
LD A,1 ; BLOCK I/O, ONE SECTOR
LD HL,IMM_CMD_RW ; POINT TO READ/WRITE CMD TEMPLATE
CALL IMM_RUNCMD ; RUN THE SCSI ENGINE
CALL Z,IMM_CHKCMD ; IF EXIT OK, CHECK SCSI RESULTS
@@ -445,6 +492,10 @@ IMM_WRITECTRL:
#IF (IMMMODE == IMMMODE_MG014
XOR $0B | $80 ; HIGH BIT IS MG014 LED
#ENDIF
;#IF (IMMMODE == IMMMODE_SPP
; AND %00001111
; OR %11000000
;#ENDIF
LD C,(IY+IMM_IOBASE) ; GET BASE IO ADDRESS
INC C ; BUMP TO CONTROL PORT
INC C
@@ -503,28 +554,28 @@ IMM_READSTATUS5:
;
IMM_CPP:
PUSH AF
LD A,$0C \ CALL IMM_WRITECTRL
LD A,$AA \ CALL IMM_WRITEDATA
LD A,$55 \ CALL IMM_WRITEDATA
LD A,$00 \ CALL IMM_WRITEDATA
LD A,$FF \ CALL IMM_WRITEDATA
IMM_WCTL($0C)
IMM_WDATA($AA)
IMM_WDATA($55)
IMM_WDATA($00)
IMM_WDATA($FF)
CALL IMM_READSTATUS
AND $B8
LD (IMM_S1),A
LD A,$87 \ CALL IMM_WRITEDATA
IMM_WDATA($87)
CALL IMM_READSTATUS
AND $B8
LD (IMM_S2),A
LD A,$78 \ CALL IMM_WRITEDATA
IMM_WDATA($78)
CALL IMM_READSTATUS
AND $38
LD (IMM_S3),A
POP AF
CALL IMM_WRITEDATA
LD A,$0C \ CALL IMM_WRITECTRL
LD A,$0D \ CALL IMM_WRITECTRL
LD A,$0C \ CALL IMM_WRITECTRL
LD A,$FF \ CALL IMM_WRITEDATA
IMM_WCTL($0C)
IMM_WCTL($0D)
IMM_WCTL($0C)
IMM_WDATA($FF)
;
; CONNECT: S1=$B8 S2=$18 S3=$30
; DISCONNECT: S1=$B8 S2=$18 S3=$38
@@ -567,23 +618,23 @@ IMM_DISCONNECT:
CALL IMM_CPP
;
; TURNS OFF MG014 LED
LD A,$8C \ CALL IMM_WRITECTRL
IMM_WCTL($8C)
;
RET
;
; INITIATE A SCSI BUS RESET.
;
IMM_RESETPULSE:
LD A,$04 \ CALL IMM_WRITECTRL
LD A,$40 \ CALL IMM_WRITEDATA
IMM_WCTL($04)
IMM_WDATA($40)
CALL DELAY ; 16 US, IDEALLY, 1 US
LD A,$0C \ CALL IMM_WRITECTRL
LD A,$0D \ CALL IMM_WRITECTRL
IMM_WCTL($0C)
IMM_WCTL($0D)
CALL DELAY ; 48 US, IDEALLY, 50 US
CALL DELAY
CALL DELAY
LD A,$0C \ CALL IMM_WRITECTRL
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($0C)
IMM_WCTL($04)
RET
;
; SCSI SELECT PROCESS
@@ -592,44 +643,29 @@ IMM_SELECT:
#IF (IMMTRACE >= 3)
PRTS("\r\nSELECT: $")
#ENDIF
LD A,$0C \ CALL IMM_WRITECTRL
;
LD HL,500 ; TIMEOUT COUNTER
IMM_WCTL($0C)
;
LD B,0 ; TIMEOUT COUNTER
IMM_SELECT1:
CALL IMM_READSTATUS
#IF (IMMTRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
AND $08
JR Z,IMM_SELECT2 ; IF CLEAR, MOVE ON
DEC HL
LD A,H
OR L
JP Z,IMM_CMD_TIMEOUT ; TIMEOUT
JR IMM_SELECT1
DJNZ IMM_SELECT1
JP IMM_CMD_TIMEOUT ; TIMEOUT
;
IMM_SELECT2:
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
; PLACE HOST AND TARGET BIT ON DATA BUS
LD A,$80 | (1 << IMM_TGT)
CALL IMM_WRITEDATA
CALL DELAY ; CONFIRM DELAY TIME?
LD A,$0C \ CALL IMM_WRITECTRL
;
#IF (IMMTRACE >= 3)
CALL IMM_READSTATUS
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
LD A,$0D \ CALL IMM_WRITECTRL
;
#IF (IMMTRACE >= 3)
CALL IMM_READSTATUS
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
LD HL,500 ; TIMEOUT COUNTER
IMM_WCTL($0C)
IMM_WCTL($0D)
;
LD B,0 ; TIMEOUT COUNTER
IMM_SELECT3:
CALL IMM_READSTATUS
#IF (IMMTRACE >= 3)
@@ -638,14 +674,11 @@ IMM_SELECT3:
#ENDIF
AND $08
JR NZ,IMM_SELECT4 ; IF SET, MOVE ON
DEC HL
LD A,H
OR L
JP Z,IMM_CMD_TIMEOUT ; TIMEOUT
JR IMM_SELECT3
DJNZ IMM_SELECT3
JP IMM_CMD_TIMEOUT ; TIMEOUT
;
IMM_SELECT4:
LD A,$0C \ CALL IMM_WRITECTRL
IMM_WCTL($0C)
;
XOR A
RET
@@ -675,7 +708,7 @@ IMM_SENDCMD:
;
INC HL ; BACK TO FIRST CMD BYTE
IMM_SENDCMD1:
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
LD A,(HL) ; LOAD CMD BYTE
;
#IF (IMMTRACE >= 3)
@@ -686,8 +719,8 @@ IMM_SENDCMD1:
CALL IMM_WRITEDATA ; PUT IT ON THE BUS
INC HL ; BUMP TO NEXT BYTE
DEC B ; DEC LOOP COUNTER
LD A,$05
CALL IMM_WRITECTRL \ LD A,(HL) ; LOAD CMD BYTE
IMM_WCTL($05)
LD A,(HL) ; LOAD CMD BYTE
;
#IF (IMMTRACE >= 3)
CALL PC_SPACE
@@ -696,11 +729,11 @@ IMM_SENDCMD1:
;
CALL IMM_WRITEDATA ; PUT IT ON THE BUS
INC HL ; BUMP TO NEXT BYTE
LD A,$00 \ CALL IMM_WRITECTRL
IMM_WCTL($00)
DJNZ IMM_SENDCMD1 ; LOOP TILL DONE
;
IMM_SENDCMD2:
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
;
RET
;
@@ -718,20 +751,23 @@ IMM_WAITLOOP:
;
IMM_WAIT:
LD HL,500 ; GOOD VALUE???
LD A,$0C \ CALL IMM_WRITECTRL
IMM_WCTL($0C)
CALL IMM_WAITLOOP
JP Z,IMM_CMD_TIMEOUT ; HANDLE TIMEOUT
PUSH AF
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
POP AF
AND $B8
RET ; RETURN W/ RESULT IN A
;
; MAX OBSERVED IMM_WAITLOOP ITERATIONS IS $0116B3
; MAX OBSERVED WAITLOOP ITERATIONS IS $0116B3 @ 7.3728 MHZ ON MG014
; MAX OBSERVED WAITLOOP ITERATIONS IS $028EFE @ 8.000 MHZ ON MBC SPP
;
IMM_LONGWAIT:
LD B,3 ; VALUE???
LD A,$0C \ CALL IMM_WRITECTRL
LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
SRL A ; DIVIDE BY 2, GOOD ENOUGH
LD B,A ; USE FOR OUTER LOOP COUNT
IMM_WCTL($0C)
IMM_LONGWAIT1:
LD HL,0
CALL IMM_WAITLOOP
@@ -741,7 +777,7 @@ IMM_LONGWAIT1:
;
IMM_LONGWAIT2:
PUSH AF
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
;
#IF 0
CALL PC_GT
@@ -761,19 +797,19 @@ IMM_NEGOTIATE:
#IF (IMMTRACE >= 3)
PRTS("\r\nNEGO: $")
#ENDIF
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
CALL DELAY ; 16 US, IDEALLY 5 US
LD A,$00 \ CALL IMM_WRITEDATA
IMM_WDATA($00)
LD DE,7 ; 112 US, IDEALLY 100 US
CALL VDELAY
LD A,$06 \ CALL IMM_WRITECTRL
IMM_WCTL($06)
CALL DELAY ; 16 US, IDEALLY 5 US
CALL IMM_READSTATUS
PUSH AF ; SAVE RESULT
CALL DELAY ; 16 US, IDEALLY 5 US
LD A,$07 \ CALL IMM_WRITECTRL
IMM_WCTL($07)
CALL DELAY ; 16 US, IDEALLY 5 US
LD A,$06 \ CALL IMM_WRITECTRL
IMM_WCTL($06)
;
POP AF
;
@@ -799,7 +835,7 @@ IMM_NEGOTIATE:
;
IMM_GETBYTE:
CALL IMM_WAIT
LD A,$06 \ CALL IMM_WRITECTRL
IMM_WCTL($06)
CALL IMM_READSTATUS
AND $F0
RRCA
@@ -807,32 +843,31 @@ IMM_GETBYTE:
RRCA
RRCA
PUSH AF
LD A,$05 \ CALL IMM_WRITECTRL
IMM_WCTL($05)
CALL IMM_READSTATUS
AND $F0
POP HL
OR H
PUSH AF
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
POP AF
RET
;
; GET A CHUNK OF DATA FROM SCSI BUS. THIS IS SPECIFICALLY FOR
; READ PHASE. IF A LENGTH IS SPECIFIED (NON-ZERO HL), THEN THE
; DATA IS BURST READ. IF NO LENGTH SPECIFIED, DATA IS READ AS
; LONG AS SCSI DEVICE WANTS TO CONTINUE SENDING (NO OVERRUN
; READ PHASE. IF TRANSFER MODE IS NON-ZERO, THEN A BLOCK (512 BYTES)
; OF DATA WILL BE READ. OTHERWISE, DATA IS WRITTEN AS
; LONG AS SCSI DEVICE WANTS TO CONTINUE RECEIVING (NO OVERRUN
; CHECK IN THIS CASE).
;
; THIS IS A NIBBLE READ.
;
; DE=BUFFER
; HL=LENGTH (0 FOR VARIABLE)
; A=TRANSFER MODE (0=VARIABLE, 1=BLOCK)
;
IMM_GETDATA:
; BRANCH TO CORRECT ROUTINE
LD A,H
OR L ; IF ZERO
JR NZ,IMM_GETDATALEN ; DO BURST READ
OR A
JR NZ,IMM_GETBLOCK ; DO BLOCK READ
;
#IF (IMMTRACE >= 3)
PRTS("\r\nGETDATA:$")
@@ -844,8 +879,7 @@ IMM_GETDATA1:
POP HL ; RESTORE BYTE COUNTER
CP $98 ; CHECK FOR READ PHASE
JR NZ,IMM_GETDATA2 ; IF NOT, ASSUME WE ARE DONE
LD A,$04 \ CALL IMM_WRITECTRL
LD A,$06 \ CALL IMM_WRITECTRL
IMM_WCTL($06)
CALL IMM_READSTATUS ; GET FIRST NIBBLE
AND $F0 ; ISOLATE BITS
RRCA ; AND SHIFT TO LOW NIBBLE
@@ -853,7 +887,7 @@ IMM_GETDATA1:
RRCA
RRCA
PUSH AF ; SAVE WORKING VALUE
LD A,$05 \ CALL IMM_WRITECTRL
IMM_WCTL($05)
CALL IMM_READSTATUS ; GET SECOND NIBBLE
AND $F0 ; ISOLATE BITS
POP BC ; RECOVER LOW NIBBLE
@@ -861,8 +895,7 @@ IMM_GETDATA1:
LD (DE),A ; AND SAVE THE FULL BYTE VALUE
INC DE ; NEXT BUFFER POS
INC HL ; INCREMENT BYTES COUNTER
LD A,$04 \ CALL IMM_WRITECTRL
LD A,$0C \ CALL IMM_WRITECTRL
IMM_WCTL($04)
JR IMM_GETDATA1 ; LOOP TILL DONE
;
IMM_GETDATA2:
@@ -873,57 +906,112 @@ IMM_GETDATA2:
PRTS(" BYTES$")
#ENDIF
;
IMM_WCTL($0C)
RET
;
IMM_GETDATALEN:
IMM_GETBLOCK:
;
#IF (IMMTRACE >= 3)
PRTS("\r\nGETDLEN:$")
CALL PC_SPACE
CALL PRTHEXWORDHL
PRTS(" BYTES$")
PRTS("\r\nGETBLK:$")
#ENDIF
;
LD A,$04 \ CALL IMM_WRITECTRL
IMM_GETDATALEN1:
LD A,$06 \ CALL IMM_WRITECTRL
CALL IMM_READSTATUS ; GET FIRST NIBBLE
AND $F0 ; ISOLATE BITS
RRCA ; MOVE TO LOW NIBBLE
RRCA
RRCA
RRCA
PUSH AF ; SAVE WORKING VALUE
LD A,$05 \ CALL IMM_WRITECTRL
CALL IMM_READSTATUS ; GET SECOND NIBBLE
AND $F0 ; ISOLATE BITS
POP BC ; RECOVER FIRST NIBBLE
OR B ; COMBINE
LD (DE),A ; SAVE FINAL BYTE VALUE
INC DE ; NEXT BUFFER POS
DEC HL ; DEC LOOP COUNTER
LD A,$04 \ CALL IMM_WRITECTRL
LD A,H ; CHECK LOOP COUNTER
OR L
JR NZ,IMM_GETDATALEN1 ; LOOP IF NOT DONE
LD A,$0C \ CALL IMM_WRITECTRL
IMM_WCTL($04)
LD B,0 ; LOOP COUNTER
EXX ; SWITCH TO ALT REGS
EX AF,AF' ; SWITCH TO ALT AF
; SAVE ALT REGS
PUSH AF
PUSH BC
PUSH DE
PUSH HL
; C: PORT C
LD A,(IY+IMM_IOBASE) ; BASE PORT
INC A ; STATUS PORT
LD (IMM_GETBLOCK_A),A ; FILL IN
LD (IMM_GETBLOCK_B),A ; ... DYNAMIC BITS OF CODE
INC A ; CONTROL PORT
LD C,A ; ... TO C
#IF (IMMMODE == IMMMODE_MG014)
; DE: CLOCK VALUES
LD D,$06 ^ ($0B | $80)
LD E,$05 ^ ($0B | $80)
; HL: STATMAP
LD H,MG014_STATMAPLO >> 8
#ENDIF
#IF (IMMMODE == IMMMODE_SPP)
; DE: CLOCK VALUES
LD D,$06
LD E,$05
#ENDIF
EXX ; SWITCH TO PRI REGS
EX AF,AF' ; SWITCH TO PRI AF
CALL IMM_GETBLOCK1 ; LOOP TWICE
CALL IMM_GETBLOCK1 ; ... FOR 512 BYTES
; RESTORE ALT REGS
EXX ; SWITCH TO ALT REGS
EX AF,AF' ; SWITCH TO ALT AF
POP HL
POP DE
POP BC
POP AF
EXX ; SWITCH TO PRI REGS
EX AF,AF' ; SWITCH TO PRI AF
IMM_WCTL($0C)
RET
;
IMM_GETBLOCK1:
EXX ; ALT REGS
OUT (C),D ; SEND FIRST CLOCK
IMM_GETBLOCK_A .EQU $+1
IN A,($FF) ; GET LOW NIBBLE
#IF (IMMMODE == IMMMODE_MG014)
AND $0F ; RELEVANT BITS ONLY
ADD A,MG014_STATMAPLO & $FF ; LOW BYTE OF MAP PTR
LD L,A ; PUT IN L
LD A,(HL) ; LOOKUP LOW NIBBLE VALUE
EX AF,AF' ; ALT AF, SAVE NIBBLE
#ENDIF
#IF (IMMMODE == IMMMODE_SPP)
AND $F0 ; RELEVANT BITS ONLY
RLCA ; MOVE TO LOW NIBBLE
RLCA ; MOVE TO LOW NIBBLE
RLCA ; MOVE TO LOW NIBBLE
RLCA ; MOVE TO LOW NIBBLE
LD L,A ; SAVE NIBBLE IN L
#ENDIF
OUT (C),E ; SEND SECOND CLOCK
IMM_GETBLOCK_B .EQU $+1
IN A,($FF) ; GET HIGH NIBBLE
#IF (IMMMODE == IMMMODE_MG014)
AND $0F ; RELEVANT BITS ONLY
ADD A,MG014_STATMAPHI & $FF ; HIGH BYTE OF MAP PTR
LD L,A ; PUT IN L
EX AF,AF' ; PRI AF, RECOVER LOW NIBBLE VALUE
OR (HL) ; COMBINE WITH HIGH NIB VALUE
#ENDIF
#IF (IMMMODE == IMMMODE_SPP)
AND $F0 ; RELEVANT BITS ONLY
OR L ; COMBINE WITH HIGH NIB VALUE
#ENDIF
EXX ; SWITCH TO PRI REGS
LD (DE),A ; SAVE BYTE
INC DE ; BUMP BUF PTR
DJNZ IMM_GETBLOCK1 ; LOOP
RET ; DONE
;
; PUT A CHUNK OF DATA TO THE SCSI BUS. THIS IS SPECIFICALLY FOR
; WRITE PHASE. IF A LENGTH IS SPECIFIED (NON-ZERO HL), THEN THE
; DATA IS BURST WRITTEN. IF NO LENGTH SPECIFIED, DATA IS WRITTEN AS
; WRITE PHASE. IF TRANSFER MODE IS NON-ZERO, THEN A BLOCK (512 BYTES)
; OF DATA WILL BE WRITTEN. OTHERWISE, DATA IS WRITTEN AS
; LONG AS SCSI DEVICE WANTS TO CONTINUE RECEIVING (NO OVERRUN
; CHECK IN THIS CASE).
;
; READS ARE DONE AS BYTE PAIRS. EACH LOOP READS 2 BYTES.
;
; DE=BUFFER
; HL=LENGTH (0 FOR VARIABLE)
; A=TRANSFER MODE (0=VARIABLE, 1=BLOCK)
;
IMM_PUTDATA:
LD A,H
OR L
JR NZ,IMM_PUTDATALEN
; BRANCH TO CORRECT ROUTINE
OR A
JR NZ,IMM_PUTBLOCK ; DO BLOCK WRITE
;
#IF (IMMTRACE >= 3)
PRTS("\r\nPUTDATA:$")
@@ -935,21 +1023,21 @@ IMM_PUTDATA1:
POP HL ; RESTORE BYTE COUNTER
CP $88 ; CHECK FOR WRITE PHASE
JR NZ,IMM_PUTDATA2 ; IF NOT, ASSUME WE ARE DONE
LD A,$04 \ CALL IMM_WRITECTRL
;IMM_WCTL($04)
LD A,(DE) ; GET NEXT BYTE TO WRITE (FIRST OF PAIR)
CALL IMM_WRITEDATA ; PUT ON BUS
INC DE ; BUMP TO NEXT BUF POS
INC HL ; INCREMENT COUNTER
LD A,$05 \ CALL IMM_WRITECTRL
IMM_WCTL($05)
LD A,(DE) ; GET NEXT BYTE TO WRITE (SECOND OF PAIR)
CALL IMM_WRITEDATA ; PUT ON BUS
INC DE ; BUMP TO NEXT BUF POS
INC HL ; INCREMENT COUNTER
LD A,$00 \ CALL IMM_WRITECTRL
IMM_WCTL($00)
JR IMM_PUTDATA1 ; LOOP TILL DONE
;
IMM_PUTDATA2:
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
;
#IF (IMMTRACE >= 3)
CALL PC_SPACE
@@ -959,33 +1047,47 @@ IMM_PUTDATA2:
;
RET
;
IMM_PUTDATALEN:
IMM_PUTBLOCK:
;
#IF (IMMTRACE >= 3)
PRTS("\r\nPUTDLEN:$")
CALL PC_SPACE
CALL PRTHEXWORDHL
PRTS(" BYTES$")
PRTS("\r\nPUTBLK:$")
#ENDIF
;
LD A,$04 \ CALL IMM_WRITECTRL
IMM_PUTDATALEN1:
LD A,(DE) ; GET NEXT BYTE (FIRST OF PAIR)
CALL IMM_WRITEDATA ; PUT ON BUS
INC DE ; INCREMENT BUF POS
DEC HL ; DEC LOOP COUNTER
LD A,$05 \ CALL IMM_WRITECTRL
LD A,(DE) ; GET NEXT BYTE (SECOND OF PAIR)
CALL IMM_WRITEDATA ; PUT ON BUS
INC DE ; INCREMENT BUF POS
DEC HL ; DEC LOOP COUNTER
LD A,$00 \ CALL IMM_WRITECTRL
LD A,H ; CHECK LOOP COUNTER
OR L
JR NZ,IMM_PUTDATALEN1 ; LOOP TILL DONE
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
LD B,0 ; LOOP COUNTER
LD A,(IY+IMM_IOBASE) ; GET BASE IO ADR
LD (IMM_PUTBLOCK_A),A ; FILL IN
LD (IMM_PUTBLOCK_B),A ; ... DYNAMIC BITS OF CODE
INC A ; STATUS PORT
INC A ; CONTROL PORT
LD C,A ; ... TO C
; HL: CLOCK VALUES
#IF (IMMMODE == IMMMODE_MG014)
LD H,$05 ^ ($0B | $80)
LD L,$00 ^ ($0B | $80)
#ENDIF
#IF (IMMMODE == IMMMODE_SPP)
LD H,$05
LD L,$00
#ENDIF
CALL IMM_PUTBLOCK1 ; ONE LOOP CUZ BYTE PAIRS
IMM_WCTL($04)
RET
;
IMM_PUTBLOCK1:
LD A,(DE) ; GET NEXT BYTE
IMM_PUTBLOCK_A .EQU $+1
OUT ($FF),A ; PUT ON BUS
INC DE ; INCREMENT BUF POS
OUT (C),H ; FIRST CLOCK
LD A,(DE) ; GET NEXT BYTE
IMM_PUTBLOCK_B .EQU $+1
OUT ($FF),A ; PUT ON BUS
INC DE ; INCREMENT BUF POS
OUT (C),L ; SECOND CLOCK
DJNZ IMM_PUTBLOCK1 ; LOOP
RET ; DONE
;
; READ SCSI COMMAND STATUS
;
IMM_GETSTATUS:
@@ -1015,13 +1117,13 @@ IMM_GETSTATUS:
;
RET
;
; TERMINATE A BULD READ OPERATION
; TERMINATE A BULK READ OPERATION
;
IMM_ENDREAD:
LD A,$04 \ CALL IMM_WRITECTRL
LD A,$0C \ CALL IMM_WRITECTRL
LD A,$0E \ CALL IMM_WRITECTRL
LD A,$04 \ CALL IMM_WRITECTRL
IMM_WCTL($04)
IMM_WCTL($0C)
IMM_WCTL($0E)
IMM_WCTL($04)
RET
;
; THIS IS THE MAIN SCSI ENGINE. BASICALLY, IT SELECTS THE DEVICE
@@ -1029,7 +1131,7 @@ IMM_ENDREAD:
;
; HL: COMMAND BUFFER
; DE: TRANSFER BUFFER
; BC: TRANSFER LENGTH (0=VARIABLE)
; A: TRANSFER MODE (0=VARIABLE, 1=BLOCK)
;
IMM_RUNCMD:
; THERE ARE MANY PLACES NESTED WITHIN THE ROUTINES THAT
@@ -1038,7 +1140,7 @@ IMM_RUNCMD:
; SEE IMM_CMD_ERR BELOW.
LD (IMM_CMDSTK),SP ; FOR ERROR ABORTS
LD (IMM_DSKBUF),DE ; SAVE BUF PTR
LD (IMM_XFRLEN),BC ; SAVE XFER LEN
LD (IMM_XFRMODE),A ; SAVE XFER LEN
PUSH HL
CALL IMM_CONNECT ; PARALLEL PORT BUS CONNECT
CALL IMM_SELECT ; SELECT TARGET DEVICE
@@ -1069,7 +1171,7 @@ IMM_RUNCMD_PHASE:
;
IMM_RUNCMD_WRITE:
LD DE,(IMM_DSKBUF) ; XFER BUFFER
LD HL,(IMM_XFRLEN) ; XFER LENGTH
LD A,(IMM_XFRMODE) ; XFER MODE
CALL IMM_PUTDATA ; SEND DATA NOW
JR IMM_RUNCMD_PHASE ; BACK TO DISPATCH
;
@@ -1078,7 +1180,7 @@ IMM_RUNCMD_READ:
CALL IMM_WAIT ; WAIT TILL READY
; CHECK FOR STATUS $98???
LD DE,(IMM_DSKBUF) ; XFER BUFFER
LD HL,(IMM_XFRLEN) ; XFER LENGTH
LD A,(IMM_XFRMODE) ; XFER MODE
CALL IMM_GETDATA ; GET THE DATA NOW
CALL IMM_ENDREAD ; TERMINATE THE READ
JR IMM_RUNCMD_PHASE ; BACK TO DISPATCH
@@ -1135,14 +1237,15 @@ IMM_CHKCMD:
IMM_CHKCMD1:
; USE REQUEST SENSE CMD TO GET ERROR DETAILS
LD DE,HB_WRKBUF ; PUT DATA IN WORK BUF
LD BC,0 ; VARIABLE LENGTH REQUEST
LD A,0 ; VARIABLE LENGTH REQUEST
LD HL,IMM_CMD_SENSE ; REQUEST SENSE CMD
CALL IMM_RUNCMD ; DO IT
JP NZ,IMM_IOERR ; BAIL IF ERROR IN CMD
;
; REQ SENSE CMD COMPLETED
#IF (IMMTRACE >= 3)
LD A,16
PRTS("\r\nSENSE:$")
LD A,$19
LD DE,HB_WRKBUF
CALL Z,PRTHEXBUF
#ENDIF
@@ -1171,6 +1274,8 @@ IMM_CHKERR:
; (RE)INITIALIZE DEVICE
;
IMM_INITDEV:
;
#IF (IMMMODE == IMMMODE_MG014)
; INITIALIZE 8255
LD A,(IY+IMM_IOBASE) ; BASE PORT
ADD A,IMM_IOSETUP ; BUMP TO SETUP PORT
@@ -1178,6 +1283,7 @@ IMM_INITDEV:
LD A,$82 ; CONFIG A OUT, B IN, C OUT
OUT (C),A ; DO IT
CALL DELAY ; SHORT DELAY FOR BUS SETTLE
#ENDIF
;
CALL IMM_DISCONNECT ; DISCONNECT FIRST JUST IN CASE
CALL IMM_CONNECT ; NOW CONNECT TO BUS
@@ -1199,7 +1305,7 @@ IMM_INITDEV1:
;
; REQUEST SENSE COMMAND
LD DE,HB_WRKBUF ; BUFFER FOR SENSE DATA
LD BC,0 ; READ WHATEVER IS SENT
LD A,0 ; READ WHATEVER IS SENT
LD HL,IMM_CMD_SENSE ; POINT TO CMD BUFFER
CALL IMM_RUNCMD ; RUN THE SCSI ENGINE
JR NZ,IMM_INITDEV2 ; CMD PROC ERROR
@@ -1210,7 +1316,8 @@ IMM_INITDEV1:
JR NZ,IMM_INITDEV2 ; IF ERROR, LOOP
;
#IF (IMMTRACE >= 3)
LD A,16
PRTS("\r\nSENSE:$")
LD A,$19
LD DE,HB_WRKBUF
CALL PRTHEXBUF
#ENDIF
@@ -1228,13 +1335,14 @@ IMM_INITDEV2:
IMM_INITDEV3:
; READ & RECORD DEVICE CAPACITY
LD DE,HB_WRKBUF ; BUFFER TO CAPACITY RESPONSE
LD BC,0 ; READ WHATEVER IS SENT
LD A,0 ; READ WHATEVER IS SENT
LD HL,IMM_CMD_RDCAP ; POINT TO READ CAPACITY CMD
CALL IMM_RUNCMD ; RUN THE SCSI ENGINE
CALL Z,IMM_CHKCMD ; CHECK AND RECORD ANY ERRORS
RET NZ ; BAIL ON ON ERROR
RET NZ ; BAIL OUT ON ERROR
;
#IF (IMMTRACE >= 3)
PRTS("\r\nRDCAP:$")
LD A,8
LD DE,HB_WRKBUF
CALL PRTHEXBUF
@@ -1293,7 +1401,7 @@ IMM_ERR:
LD (IY+IMM_STAT),A ; SAVE NEW STATUS
;
IMM_ERR2:
#IF (IMMTRACE >= 1)
#IF (IMMTRACE >= 2)
CALL IMM_PRTSTAT
#ENDIF
OR A ; SET FLAGS
@@ -1390,7 +1498,7 @@ IMM_STR_NOHW .TEXT "NOT PRESENT$"
IMM_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT
IMM_CMDSTK .DW 0 ; STACK PTR FOR CMD ABORTING
IMM_DSKBUF .DW 0 ; WORKING DISK BUFFER POINTER
IMM_XFRLEN .DW 0 ; WORKING TRANSFER LENGTH
IMM_XFRMODE .DB 0 ; 0=VARIABLE, 1=BLOCK (512 BYTES)
IMM_CMDSTAT .DB 0, 0 ; CMD RESULT STATUS
;
; SCSI COMMAND TEMPLATES (LENGTH PREFIXED)

View File

@@ -9,11 +9,14 @@
; INTENDED TO CO-EXIST WITH LPT DRIVER.
;
; CREATED BY WAYNE WARTHEN FOR ROMWBW HBIOS.
; MUCH OF THE CODE IS DERIVED FROM FUZIX (ALAN COX).
; MUCH OF THE CODE IS DERIVED FROM LINUX AND FUZIX (ALAN COX).
; - https://github.com/EtchedPixels/FUZIX
; - https://github.com/torvalds/linux
;
; 5/23/2023 WBW - INITIAL RELEASE
; 5/26/3023 WBW - CLEAN UP, LED ACTIVITY
; 5/27/2023 WBW - ADDED SPP MODE
; 05/23/2023 WBW - INITIAL RELEASE
; 05/26/3023 WBW - CLEAN UP, LED ACTIVITY
; 05/27/2023 WBW - ADDED SPP MODE
; 06/06/2023 WBW - OPTIMIZE BLOCK READ AND WRITE
;
;=============================================================================
;
@@ -71,22 +74,18 @@
;
; TODO:
;
; - OPTIMIZE READ/WRITE LOOPS
;
; NOTES:
;
; - THIS DRIVER IS FOR THE ZIP DRIVE PPA INTERFACE. IT WILL SIMPLY
; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE OLDER PPA INTERFACE.
; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE NEWER IMM INTERFACE.
; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP
; DRIVE IS PPA OR PPA. SIGH.
; DRIVE IS PPA OR IMM. SIGH.
;
; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE
; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON
; FASTER CPUS.
;
; - THIS DRIVER OPERATES PURELY IN NIBBLE MODE. I SUSPECT IT IS
; POSSIBLE TO USE FULL BYTE MODE (PS2 STYLE), BUT I HAVE NOT
; ATTEMPTED IT.
; - THIS DRIVER OPERATES USES NIBBLE READ MODE. ALTHOUGH THE 8255
; (MG014) CAN READ OR WRITE TO PORT A (DATA), IT "GLITCHES" WHEN
; THE MODE IS CHANGED CAUSING THE CONTROL LINES TO CHANGE AND
; BREAKS THE PROTOCOL. I SUSPECT THE MBC SPP CAN SUPPORT FULL BYTE
; MODE, (PS2 STYLE), BUT I HAVE NOT ATTEMPTED IT.
;
; - RELATIVE TO ABOVE, THIS BEAST IS SLOW. IN ADDITION TO THE
; NIBBLE MODE READS, THE MG014 ASSIGNS SIGNALS DIFFERENTLY THAN
@@ -130,6 +129,20 @@ PPA_IOBASE .EQU 3 ; IO BASE ADDRESS (BYTE)
PPA_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
PPA_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
; MACROS
;
#DEFINE PPA_WCTL(VAL) LD A,VAL \ CALL PPA_WRITECTRL
#DEFINE PPA_WDATA(VAL) LD A,VAL \ CALL PPA_WRITEDATA
;
#DEFINE PPA_DPUL(VAL) LD A,VAL \ CALL PPA_DPULSE
#DEFINE PPA_CPUL(VAL) LD A,VAL \ CALL PPA_CPULSE
;
; INCLUDE MG014 NIBBLE MAP FOR MG014 MODE
;
#IF (IMMMODE == IMMMODE_MG014)
#DEFINE MG014_MAP
#ENDIF
;
;=============================================================================
; INITIALIZATION ENTRY POINT
;=============================================================================
@@ -185,8 +198,8 @@ PPA_INIT4:
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
;
CALL PPA_RESET ; RESET/INIT THE INTERFACE
#IF (PPATRACE == 0)
CALL PPA_PRTSTAT
#IF (PPATRACE <= 1)
CALL NZ,PPA_PRTSTAT
#ENDIF
JR NZ,PPA_INIT6
;
@@ -220,6 +233,11 @@ PPA_INIT6:
; ON RETURN, ZF SET INDICATES HARDWARE FOUND
;
PPA_DETECT:
#IF (PPATRACE >= 3)
PRTS("\r\nDETECT:$")
#ENDIF
;
#IF (PPAMODE == PPAMODE_MG014)
; INITIALIZE 8255
LD A,(IY+PPA_IOBASE) ; BASE PORT
ADD A,PPA_IOSETUP ; BUMP TO SETUP PORT
@@ -227,35 +245,39 @@ PPA_DETECT:
LD A,$82 ; CONFIG A OUT, B IN, C OUT
OUT (C),A ; DO IT
CALL DELAY ; BRIEF DELAY FOR GOOD MEASURE
#ENDIF
;
LD A,$AA \ CALL PPA_WRITEDATA
PPA_WDATA($AA)
CALL PPA_DISCONNECT
CALL PPA_CONNECT
LD A,$06 \ CALL PPA_WRITECTRL
PPA_WCTL($0E)
CALL PPA_READSTATUS
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
AND $F0
CP $F0
AND $08
CP $08
JR NZ,PPA_DETECT_FAIL
LD A,$04 \ CALL PPA_WRITECTRL
;
PPA_WCTL($0C)
CALL PPA_READSTATUS
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
AND $F0
CP $80
AND $08
CP $00
JR NZ,PPA_DETECT_FAIL
LD A,$AA \ CALL PPA_WRITEDATA
LD A,$0C \ CALL PPA_WRITECTRL
CALL PPA_CONNECT
LD A,$40 \ CALL PPA_WRITEDATA
LD A,$08 \ CALL PPA_WRITECTRL
LD A,$0C \ CALL PPA_WRITECTRL
;
CALL PPA_DISCONNECT
;
PPA_WDATA($AA)
PPA_WCTL($0C)
;
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
@@ -263,7 +285,6 @@ PPA_DETECT:
PPA_DETECT_FAIL:
OR $FF ; SIGNAL FAILURE
RET NZ
;
;=============================================================================
; DRIVER FUNCTION TABLE
@@ -303,7 +324,7 @@ PPA_READ:
;
;
PPA_WRITE:
CALL HB_DSKREAD ; HOOK DISK WRITE CONTROLLER
CALL HB_DSKWRITE ; HOOK DISK WRITE CONTROLLER
LD A,SCSI_CMD_WRITE ; SETUP SCSI WRITE
LD (PPA_CMD_RW),A ; AND SAVE IT IN SCSI CMD
JP PPA_IO ; DO THE I/O
@@ -311,9 +332,18 @@ PPA_WRITE:
;
;
PPA_IO:
LD (PPA_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
PUSH HL
CALL PPA_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO
POP HL
JR NZ,PPA_IO3 ; BAIL OUT ON ERROR
;
LD (PPA_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
;
#IF (DSKYENABLE)
LD A,PPA_LBA
CALL LDHLIYA
CALL HB_DSKACT ; SHOW ACTIVITY
#ENDIF
;
; SETUP LBA
; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN
@@ -330,7 +360,7 @@ PPA_IO:
;
; DO SCSI IO
LD DE,(PPA_DSKBUF) ; DISK BUFFER TO DE
LD BC,512 ; ONE SECTOR, 512 BYTES
LD A,1 ; BLOCK I/O, ONE SECTOR
LD HL,PPA_CMD_RW ; POINT TO READ/WRITE CMD TEMPLATE
CALL PPA_RUNCMD ; RUN THE SCSI ENGINE
CALL Z,PPA_CHKCMD ; IF EXIT OK, CHECK SCSI RESULTS
@@ -440,32 +470,6 @@ PPA_GEOM:
; FUNCTION SUPPORT ROUTINES
;=============================================================================
;
;
;
PPA_DELAY:
PUSH AF
CALL DELAY
CALL DELAY
CALL DELAY
CALL DELAY
POP AF
RET
;
;
;
PPA_WAITDONE:
LD HL,0 ; TIMEOUT COUNTER
PPA_WAITDONE1:
CALL PPA_READSTATUS
AND $F0
BIT 7,A
RET NZ
DEC HL
LD A,H
OR L
JP Z,IMM_CMD_TIMEOUT ; TIMEOUT
JR PPA_WAITDONE1
;
; OUTPUT BYTE IN A TO THE DATA PORT
;
PPA_WRITEDATA:
@@ -541,64 +545,87 @@ PPA_READSTATUS5:
;
PPA_DPULSE:
CALL PPA_WRITEDATA
LD A,$0C \ CALL PPA_WRITECTRL
LD A,$0E \ CALL PPA_WRITECTRL
LD A,$0C \ CALL PPA_WRITECTRL
LD A,$04 \ CALL PPA_WRITECTRL
LD A,$0C \ CALL PPA_WRITECTRL
PPA_WCTL($0C)
PPA_WCTL($0E)
PPA_WCTL($0C)
PPA_WCTL($04)
PPA_WCTL($0C)
RET
;
;
;
PPA_CPULSE:
CALL PPA_WRITEDATA
LD A,$04 \ CALL PPA_WRITECTRL
LD A,$06 \ CALL PPA_WRITECTRL
LD A,$04 \ CALL PPA_WRITECTRL
LD A,$0C \ CALL PPA_WRITECTRL
PPA_WCTL($04)
PPA_WCTL($06)
PPA_WCTL($04)
PPA_WCTL($0C)
RET
;
;
;
PPA_CONNECT:
LD A,$00 \ CALL PPA_CPULSE
LD A,$3C \ CALL PPA_CPULSE
LD A,$20 \ CALL PPA_CPULSE
LD A,$8F \ CALL PPA_CPULSE
PPA_CPUL($00)
PPA_CPUL($3C)
PPA_CPUL($20)
PPA_CPUL($8F)
RET
;
;
;
PPA_DISCONNECT:
LD A,$00 \ CALL PPA_DPULSE
LD A,$3C \ CALL PPA_DPULSE
LD A,$20 \ CALL PPA_DPULSE
LD A,$0F \ CALL PPA_DPULSE
PPA_DPUL($00)
PPA_DPUL($3C)
PPA_DPUL($20)
PPA_DPUL($0F)
;
; TURNS OFF MG014 LED
PPA_WCTL($8C)
;
RET
;
; INITIATE A SCSI BUS RESET.
;
PPA_RESETPULSE:
PPA_WDATA($40)
PPA_WCTL($08)
CALL DELAY ; 32 US, IDEALLY 30 US
PPA_WCTL($0C)
RET
;
; SCSI SELECT PROCESS
;
;
PPA_SELECT:
#IF (PPATRACE >= 3)
PRTS("\r\nSELECT: $")
#ENDIF
;
#IF (PPATRACE >= 3)
CALL PPA_READSTATUS
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
LD A,1 << PPA_TGT
CALL PPA_WRITEDATA
LD A,$0E \ CALL PPA_WRITECTRL
LD A,$0C \ CALL PPA_WRITECTRL
PPA_WCTL($0E)
PPA_WCTL($0C)
LD A,1 << PPA_SELF
CALL PPA_WRITEDATA
LD A,$08 \ CALL PPA_WRITECTRL
;
LD HL,0 ; TIMEOUT COUNTER
PPA_WCTL($08)
;
LD B,0 ; TIMEOUT COUNTER
PPA_SELECT1:
CALL PPA_READSTATUS
OR $F0
RET NZ
DEC HL
LD A,H
OR L
RET Z ; TIMEOUT
JR PPA_SELECT1
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
AND $40
CP $40
RET Z
DJNZ PPA_SELECT1
JP PPA_CMD_TIMEOUT
;
; SEND SCSI CMD BYTE STRING. AT ENTRY, HL POINTS TO START OF
; COMMAND BYTES. THE LENGTH OF THE COMMAND STRING MUST PRECEED
@@ -608,16 +635,448 @@ PPA_SELECT1:
; DATA OUTPOUT IS BURSTED (NO CHECK FOR BUSY). SEEMS TO WORK FINE.
;
PPA_SENDCMD:
JP PPA_ERR ; NOW DO STANDARD ERR PROCESSING
;
#IF (PPATRACE >= 3)
PRTS("\r\nSENDCMD:$")
#ENDIF
;
DEC HL ; BACKUP TO LENGTH BYTE
LD B,(HL) ; PUT IN B FOR LOOP COUNTER
;
#IF (PPATRACE >= 3)
LD A,B
CALL PC_SPACE
CALL PRTHEXBYTE
PRTS(" BYTES$")
#ENDIF
;
INC HL ; BACK TO FIRST CMD BYTE
;
PPA_SENDCMD1:
;PPA_WCTL($0C)
LD A,(HL) ; LOAD CMD BYTE
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
CALL PPA_WRITEDATA ; PUT IT ON THE BUS
INC HL ; BUMP TO NEXT BYTE
PPA_WCTL($0E)
PPA_WCTL($0C)
DJNZ PPA_SENDCMD1 ; LOOP TILL DONE
;
RET
;
;
; WAIT FOR SCSI BUS TO BECOME READY WITH A TIMEOUT.
;
PPA_WAITLOOP:
CALL PPA_READSTATUS
BIT 7,A
RET NZ ; DONE, STATUS IN A
DEC HL
LD A,H
OR L
RET Z ; TIMEOUT
JR PPA_WAITLOOP
;
PPA_WAIT:
LD HL,500 ; GOOD VALUE???
PPA_WCTL($0C)
CALL PPA_WAITLOOP
JP Z,PPA_CMD_TIMEOUT ; HANDLE TIMEOUT
;PUSH AF
;IMM_WCTL($04)
;POP AF
AND $F0
RET ; RETURN W/ RESULT IN A
;
; MAX OBSERVED WAITLOOP ITERATIONS IS $0116B3 @ 7.372 MHZ ON MG014
; MAX OBSERVED WAITLOOP ITERATIONS IS $028EFE @ 8.000 MHZ ON MBC SPP
;
PPA_LONGWAIT:
LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
SRL A ; DIVIDE BY 2, GOOD ENOUGH
LD B,A ; USE FOR OUTER LOOP COUNT
PPA_WCTL($0C)
PPA_LONGWAIT1:
LD HL,0
CALL PPA_WAITLOOP
JR NZ,PPA_LONGWAIT2 ; HANDLE SUCCESS
DJNZ PPA_LONGWAIT1 ; LOOP TILL COUNTER EXHAUSTED
JP PPA_CMD_TIMEOUT ; HANDLE TIMEOUT
;
PPA_LONGWAIT2:
;PUSH AF
;PPA_WCTL($04)
;
#IF 0
PUSH AF
CALL PC_GT
LD A,B
CALL PRTHEXBYTE
CALL PC_COLON
CALL PRTHEXWORDHL
POP AF
#ENDIF
;
;POP AF
AND $F0
RET ; RETURN W/ RESULT IN A
;
; GET A BYTE OF DATA FROM THE SCSI DEVICE. THIS IS A NIBBLE READ.
; BYTE RETURNED IN A.
;
PPA_GETBYTE:
CALL PPA_WAIT
PPA_WCTL($04)
CALL PPA_READSTATUS
AND $F0
PUSH AF
PPA_WCTL($06)
CALL PPA_READSTATUS
AND $F0
RRCA
RRCA
RRCA
RRCA
POP HL
OR H
PUSH AF
PPA_WCTL($0C)
POP AF
RET
;
; GET A CHUNK OF DATA FROM SCSI BUS. THIS IS SPECIFICALLY FOR
; READ PHASE. IF TRANSFER MODE IS NON-ZERO, THEN A BLOCK (512 BYTES)
; OF DATA WILL BE READ. OTHERWISE, DATA IS WRITTEN AS
; LONG AS SCSI DEVICE WANTS TO CONTINUE RECEIVING (NO OVERRUN
; CHECK IN THIS CASE).
;
; THIS IS A NIBBLE READ.
;
; DE=BUFFER
; A=TRANSFER MODE (0=VARIABLE, 1=BLOCK)
;
PPA_GETDATA:
; BRANCH TO CORRECT ROUTINE
OR A
JR NZ,PPA_GETBLOCK ; DO BLOCK READ
;
#IF (PPATRACE >= 3)
PRTS("\r\nGETDATA:$")
#ENDIF
;
PPA_GETDATA1:
PUSH HL ; SAVE BYTE COUNTER
CALL PPA_WAIT ; WAIT FOR BUS READY
POP HL ; RESTORE BYTE COUNTER
CP $D0 ; CHECK FOR READ PHASE
JR NZ,PPA_GETDATA2 ; IF NOT, ASSUME WE ARE DONE
PPA_WCTL($04)
CALL PPA_READSTATUS ; GET FIRST NIBBLE
AND $F0 ; ISOLATE BITS
PUSH AF ; SAVE WORKING VALUE
PPA_WCTL($06)
CALL PPA_READSTATUS ; GET SECOND NIBBLE
AND $F0 ; ISOLATE BITS
RRCA ; AND SHIFT TO LOW NIBBLE
RRCA
RRCA
RRCA
POP BC ; RECOVER LOW NIBBLE
OR B ; COMBINE
LD (DE),A ; AND SAVE THE FULL BYTE VALUE
INC DE ; NEXT BUFFER POS
INC HL ; INCREMENT BYTES COUNTER
JR PPA_GETDATA1 ; LOOP TILL DONE
;
PPA_GETDATA2:
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXWORDHL
PRTS(" BYTES$")
#ENDIF
;
PPA_WCTL($0C)
RET
;
PPA_GETBLOCK:
;
#IF (PPATRACE >= 3)
PRTS("\r\nGETBLK:$")
#ENDIF
LD B,0 ; LOOP COUNTER
EXX ; SWITCH TO ALT
EX AF,AF' ; SWITCH TO ALT AF
; SAVE ALT REGS
PUSH AF
PUSH BC
PUSH DE
PUSH HL
; C: PORT C
LD A,(IY+PPA_IOBASE) ; BASE PORT
INC A ; STATUS PORT
LD (PPA_GETBLOCK_A),A ; FILL IN
LD (PPA_GETBLOCK_B),A ; ... DYNAMIC BITS OF CODE
INC A ; CONTROL PORT
LD C,A ; ... TO C
#IF (PPAMODE == PPAMODE_MG014)
; DE: CLOCK VALUES
LD D,$04 ^ ($0B | $80)
LD E,$06 ^ ($0B | $80)
; HL: STATMAP
LD H,MG014_STATMAPLO >> 8
#ENDIF
#IF (PPAMODE == PPAMODE_SPP)
; DE: CLOCK VALUES
LD D,$04
LD E,$06
#ENDIF
EXX ; SWITCH TO PRI
CALL PPA_GETBLOCK1 ; LOOP TWICE
CALL PPA_GETBLOCK1 ; ... FOR 512 BYTES
; RESTORE ALT REGS
EXX ; SWITCH TO ALT REGS
EX AF,AF' ; SWITCH TO ALT AF
POP HL
POP DE
POP BC
POP AF
EXX ; SWITCH TO PRI REGS
EX AF,AF' ; SWITCH TO PRI AF
RET
;
;
PPA_GETBLOCK1:
EXX ; ALT REGS
OUT (C),D ; SEND FIRST CLOCK
PPA_GETBLOCK_A .EQU $+1
IN A,($FF) ; GET HIGH NIBBLE
#IF (PPAMODE == PPAMODE_MG014)
AND $0F ; RELEVANT BITS ONLY
ADD A,MG014_STATMAPHI & $FF ; HIGH BYTE OF MAP PTR
LD L,A ; PUT IN L
LD A,(HL) ; LOOKUP HIGH NIBBLE VALUE
EX AF,AF' ; SAVE NIBBLE
#ENDIF
#IF (PPAMODE == PPAMODE_SPP)
AND $F0 ; RELEVANT BITS ONLY
LD L,A ; SAVE NIBBLE IN L
#ENDIF
OUT (C),E ; SEND SECOND CLOCK
PPA_GETBLOCK_B .EQU $+1
IN A,($FF) ; GET LOW NIBBLE
#IF (PPAMODE == PPAMODE_MG014)
AND $0F ; RELEVANT BITS ONLY
ADD A,MG014_STATMAPLO & $FF ; LOW BYTE OF MAP PTR
LD L,A ; PUT IN L
EX AF,AF' ; RECOVER HIGH NIBBLE VALUE
OR (HL) ; COMBINE WITH LOW NIB VALUE
#ENDIF
#IF (PPAMODE == PPAMODE_SPP)
AND $F0 ; RELEVANT BITS ONLY
RLCA ; MOVE TO LOW NIBBLE
RLCA ; MOVE TO LOW NIBBLE
RLCA ; MOVE TO LOW NIBBLE
RLCA ; MOVE TO LOW NIBBLE
OR L ; COMBINE WITH HIGH NIB VALUE
#ENDIF
EXX ; SWITCH TO PRI
LD (DE),A ; SAVE BYTE
INC DE ; BUMP BUF PTR
DJNZ PPA_GETBLOCK1 ; LOOP
RET ; DONE
;
; PUT A CHUNK OF DATA TO THE SCSI BUS. THIS IS SPECIFICALLY FOR
; WRITE PHASE. IF TRANSFER MODE IS NON-ZERO, THEN A BLOCK (512 BYTES)
; OF DATA WILL BE WRITTEN. OTHERWISE, DATA IS WRITTEN AS
; LONG AS SCSI DEVICE WANTS TO CONTINUE RECEIVING (NO OVERRUN
; CHECK IN THIS CASE).
;
; DE=BUFFER
; A=TRANSFER MODE (0=VARIABLE, 1=BLOCK)
;
PPA_PUTDATA:
; BRANCH TO CORRECT ROUTINE
OR A
JR NZ,PPA_PUTBLOCK ; DO BLOCK WRITE
;
#IF (PPATRACE >= 3)
PRTS("\r\nPUTDATA:$")
#ENDIF
;
PPA_PUTDATA1:
PUSH HL ; SAVE BYTE COUNTER
CALL PPA_WAIT ; WAIT FOR BUS READY
POP HL ; RESTORE BYTE COUNTER
CP $C0 ; CHECK FOR WRITE PHASE
JR NZ,PPA_PUTDATA2 ; IF NOT, ASSUME WE ARE DONE
LD A,(DE) ; GET NEXT BYTE TO WRITE (FIRST OF PAIR)
CALL PPA_WRITEDATA ; PUT ON BUS
INC DE ; BUMP TO NEXT BUF POS
INC HL ; INCREMENT COUNTER
PPA_WCTL($0E)
PPA_WCTL($0C)
LD A,(DE) ; GET NEXT BYTE TO WRITE (SECOND OF PAIR)
JR PPA_PUTDATA1 ; LOOP TILL DONE
;
PPA_PUTDATA2:
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXWORDHL
PRTS(" BYTES$")
#ENDIF
;
RET
;
PPA_PUTBLOCK:
;
#IF (PPATRACE >= 3)
PRTS("\r\nPUTBLK:$")
#ENDIF
;
LD B,0 ; LOOP COUNTER
LD A,(IY+PPA_IOBASE) ; GET BASE IO ADR
LD (PPA_PUTBLOCK_A),A ; FILL IN
INC A ; STATUS PORT
INC A ; CONTROL PORT
LD C,A ; ... TO C
; HL: CLOCK VALUES
#IF (PPAMODE == PPAMODE_MG014)
LD H,$0E ^ ($0B | $80)
LD L,$0C ^ ($0B | $80)
#ENDIF
#IF (PPAMODE == PPAMODE_SPP)
LD H,$0E
LD L,$0C
#ENDIF
CALL PPA_PUTBLOCK1 ; DO BELOW TWICE
CALL PPA_PUTBLOCK1 ; ... FOR 512 BYTES
RET
;
PPA_PUTBLOCK1:
LD A,(DE) ; GET NEXT BYTE
PPA_PUTBLOCK_A .EQU $+1
OUT ($FF),A ; PUT ON BUS
INC DE ; INCREMENT BUF POS
OUT (C),H ; FIRST CLOCK
OUT (C),L ; SECOND CLOCK
DJNZ PPA_PUTBLOCK1 ; LOOP
RET ; DONE
;
; READ SCSI COMMAND STATUS
;
PPA_GETSTATUS:
;
#IF (PPATRACE >= 3)
PRTS("\r\nSTATUS:$")
#ENDIF
;
CALL PPA_GETBYTE ; GET ONE BYTE
LD (PPA_CMDSTAT),A ; SAVE AS FIRST STATUS BYTE
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
CALL PPA_WAIT ; CHECK FOR OPTIONAL SECOND BYTE
CP $F0 ; STILL IN STATUS PHASE?
RET NZ ; IF NOT, DONE
CALL PPA_GETBYTE ; ELSE, GET THE SECOND BYTE
LD (PPA_CMDSTAT+1),A ; AND SAVE IT
;
#IF (PPATRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
RET
;
; THIS IS THE MAIN SCSI ENGINE. BASICALLY, IT SELECTS THE DEVICE
; ON THE BUS, SENDS THE COMMAND, THEN PROCESSES THE RESULT.
;
; HL: COMMAND BUFFER
; DE: TRANSFER BUFFER
; BC: TRANSFER LENGTH (0=VARIABLE)
; A: TRANSFER MODE (0=VARIABLE, 1=BLOCK)
;
PPA_RUNCMD:
; THERE ARE MANY PLACES NESTED WITHIN THE ROUTINES THAT
; ARE CALLED HERE. HERE WE SAVE THE STACK SO THAT WE CAN
; EASILY AND QUICKLY ABORT OUT OF ANY NESTED ROUTINE.
; SEE PPA_CMD_ERR BELOW.
LD (PPA_CMDSTK),SP ; FOR ERROR ABORTS
LD (PPA_DSKBUF),DE ; SAVE BUF PTR
LD (PPA_XFRMODE),A ; SAVE XFER LEN
PUSH HL
CALL PPA_CONNECT ; PARALLEL PORT BUS CONNECT
CALL PPA_SELECT ; SELECT TARGET DEVICE
CALL PPA_WAIT ; WAIT TILL READY
POP HL
CALL PPA_SENDCMD ; SEND THE COMMAND
;
PPA_RUNCMD_PHASE:
; WAIT FOR THE BUS TO BE READY. WE USE AN EXTRA LONG WAIT
; TIMEOUT HERE BECAUSE THIS IS WHERE WE WILL WAIT FOR LONG
; OPERATIONS TO COMPLETE. IT CAN TAKE SOME TIME IF THE
; DEVICE HAS GONE TO SLEEP BECAUSE IT WILL NEED TO WAKE UP
; AND SPIN UP BEFORE PROCESSING AN I/O COMMAND.
CALL PPA_LONGWAIT ; WAIT TILL READY
;
#IF (PPATRACE >= 3)
PRTS("\r\nPHASE: $")
CALL PRTHEXBYTE
#ENDIF
;
CP $C0 ; DEVICE WANTS TO RCV DATA
JR Z,PPA_RUNCMD_WRITE
CP $D0 ; DEVICE WANTS TO SEND DATA
JR Z,PPA_RUNCMD_READ
CP $F0 ; DEVICE WANTS TO BE DONE
JR Z,PPA_RUNCMD_END
JR PPA_CMD_IOERR
;
PPA_RUNCMD_WRITE:
LD DE,(PPA_DSKBUF) ; XFER BUFFER
LD A,(PPA_XFRMODE) ; XFER MODE
CALL PPA_PUTDATA ; SEND DATA NOW
JR PPA_RUNCMD_PHASE ; BACK TO DISPATCH
;
PPA_RUNCMD_READ:
LD DE,(PPA_DSKBUF) ; XFER BUFFER
LD A,(PPA_XFRMODE) ; XFER MODE
CALL PPA_GETDATA ; GET THE DATA NOW
JR PPA_RUNCMD_PHASE ; BACK TO DISPATCH
;
PPA_RUNCMD_END:
CALL PPA_GETSTATUS ; READ STATUS BYTES
CALL PPA_DISCONNECT ; PARALLEL PORT BUS DISCONNECT
XOR A ; SIGNAL SUCCESS
RET
;
PPA_CMD_IOERR:
LD A,PPA_STIOERR ; ERROR VALUE TO A
JR PPA_CMD_ERR ; CONTINUE
;
PPA_CMD_TIMEOUT:
LD A,PPA_STTO ; ERROR VALUE TO A
JR PPA_CMD_ERR ; CONTINUE
;
PPA_CMD_ERR:
LD SP,(PPA_CMDSTK) ; UNWIND STACK
PUSH AF ; SAVE STATUS
;CALL PPA_RESETPULSE ; CLEAN UP THE MESS???
LD DE,62 ; DELAY AFTER RESET PULSE
CALL VDELAY
CALL PPA_DISCONNECT ; PARALLEL PORT BUS DISCONNECT
LD DE,62 ; DELAY AFTER DISCONNECT
CALL VDELAY
POP AF ; RECOVER STATUS
JP PPA_ERR ; NOW DO STANDARD ERR PROCESSING
;
; ERRORS SHOULD GENERALLY NOT CAUSE SCSI PROCESSING TO FAIL. IF A
@@ -642,14 +1101,15 @@ PPA_CHKCMD:
PPA_CHKCMD1:
; USE REQUEST SENSE CMD TO GET ERROR DETAILS
LD DE,HB_WRKBUF ; PUT DATA IN WORK BUF
LD BC,0 ; VARIABLE LENGTH REQUEST
LD A,0 ; VARIABLE LENGTH READ
LD HL,PPA_CMD_SENSE ; REQUEST SENSE CMD
CALL PPA_RUNCMD ; DO IT
JP NZ,PPA_IOERR ; BAIL IF ERROR IN CMD
;
; REQ SENSE CMD COMPLETED
#IF (PPATRACE >= 3)
LD A,16
PRTS("\r\nSENSE:$")
LD A,$19
LD DE,HB_WRKBUF
CALL Z,PRTHEXBUF
#ENDIF
@@ -678,6 +1138,8 @@ PPA_CHKERR:
; (RE)INITIALIZE DEVICE
;
PPA_INITDEV:
;
#IF (PPAMODE == PPAMODE_MG014)
; INITIALIZE 8255
LD A,(IY+PPA_IOBASE) ; BASE PORT
ADD A,PPA_IOSETUP ; BUMP TO SETUP PORT
@@ -685,8 +1147,88 @@ PPA_INITDEV:
LD A,$82 ; CONFIG A OUT, B IN, C OUT
OUT (C),A ; DO IT
CALL DELAY ; SHORT DELAY FOR BUS SETTLE
#ENDIF
;
JP PPA_NOTSUP
; BUS RESET
CALL PPA_CONNECT
CALL PPA_RESETPULSE
LD DE,62 ; 1000 US
CALL VDELAY
CALL PPA_DISCONNECT
LD DE,62 ; 1000 US
CALL VDELAY
;
; INITIALLY, THE DEVICE MAY REQUIRE MULTIPLE REQUEST SENSE
; COMMANDS BEFORE IT WILL ACCEPT I/O COMMANDS. THIS IS DUE
; TO THINGS LIKE BUS RESET NOTIFICATION, MEDIA CHANGE, ETC.
; HERE, WE RUN A FEW REQUEST SENSE COMMANDS. AS SOON AS ONE
; INDICATES NO ERRORS, WE CAN CONTINUE.
LD B,4 ; TRY UP TO 4 TIMES
PPA_INITDEV1:
PUSH BC ; SAVE LOOP COUNTER
;
; REQUEST SENSE COMMAND
LD DE,HB_WRKBUF ; BUFFER FOR SENSE DATA
LD A,0 ; READ WHATEVER IS SENT
LD HL,PPA_CMD_SENSE ; POINT TO CMD BUFFER
CALL PPA_RUNCMD ; RUN THE SCSI ENGINE
JR NZ,PPA_INITDEV2 ; CMD PROC ERROR
;
#IF (PPATRACE >= 3)
PRTS("\r\nSENSE:$")
LD A,$19
LD DE,HB_WRKBUF
CALL PRTHEXBUF
#ENDIF
;
; CHECK SENSE KEY
LD A,(HB_WRKBUF + 2) ; GET SENSE KEY
OR A ; SET FLAGS
;
PPA_INITDEV2:
POP BC ; RESTORE LOOP COUNTER
JR Z,PPA_INITDEV3 ; IF NO ERROR, MOVE ON
DJNZ PPA_INITDEV1 ; TRY UNTIL COUNTER EXHAUSTED
JP PPA_IOERR ; BAIL OUT WITH ERROR
;
PPA_INITDEV3:
; READ & RECORD DEVICE CAPACITY
LD DE,HB_WRKBUF ; BUFFER TO CAPACITY RESPONSE
LD A,0 ; READ WHATEVER IS SENT
LD HL,PPA_CMD_RDCAP ; POINT TO READ CAPACITY CMD
CALL PPA_RUNCMD ; RUN THE SCSI ENGINE
CALL Z,PPA_CHKCMD ; CHECK AND RECORD ANY ERRORS
RET NZ ; BAIL OUT ON ERROR
;
#IF (PPATRACE >= 3)
PRTS("\r\nRDCAP:$")
LD A,8
LD DE,HB_WRKBUF
CALL PRTHEXBUF
#ENDIF
;
; CAPACITY IS RETURNED IN A 4 BYTE, BIG ENDIAN FIELD AND
; INDICATES THE LAST LBA VALUE. WE NEED TO CONVERT THIS TO
; LITTLE ENDIAN AND INCREMENT THE VALUE TO MAKE IT A CAPACITY
; COUNT INSTEAD OF A LAST LBA VALUE.
LD A,PPA_MEDCAP ; OFFSET IN CFG FOR CAPACITY
CALL LDHLIYA ; POINTER TO HL
PUSH HL ; SAVE IT
LD HL,HB_WRKBUF ; POINT TO VALUE IN CMD RESULT
CALL LD32 ; LOAD IT TO DE:HL
LD A,L ; FLIP BYTES
LD L,D ; ... BIG ENDIAN
LD D,A ; ... TO LITTLE ENDIAN
LD A,H
LD H,E
LD E,A
CALL INC32 ; INCREMENT TO FINAL VALUE
POP BC ; RECOVER SAVE LOCATION
CALL ST32 ; STORE VALUE
;
XOR A ; SIGNAL SUCCESS
LD (IY+PPA_STAT),A ; RECORD IT
RET
;
;=============================================================================
; ERROR HANDLING AND DIAGNOSTICS
@@ -719,7 +1261,7 @@ PPA_ERR:
LD (IY+PPA_STAT),A ; SAVE NEW STATUS
;
PPA_ERR2:
#IF (PPATRACE >= 1)
#IF (PPATRACE >= 2)
CALL PPA_PRTSTAT
#ENDIF
OR A ; SET FLAGS
@@ -772,7 +1314,7 @@ PPA_PRTPREFIX:
PUSH AF
CALL NEWLINE
PRTS("PPA$")
LD A,(IY+IMM_DEV) ; GET CURRENT DEVICE NUM
LD A,(IY+PPA_DEV) ; GET CURRENT DEVICE NUM
CALL PRTDECB
CALL PC_COLON
POP AF
@@ -816,7 +1358,7 @@ PPA_STR_NOHW .TEXT "NOT PRESENT$"
PPA_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT
PPA_CMDSTK .DW 0 ; STACK PTR FOR CMD ABORTING
PPA_DSKBUF .DW 0 ; WORKING DISK BUFFER POINTER
PPA_XFRLEN .DW 0 ; WORKING TRANSFER LENGTH
PPA_XFRMODE .DB 0 ; 0=VARIABLE, 1=BLOCK (512 BYTES)
PPA_CMDSTAT .DB 0, 0 ; CMD RESULT STATUS
;
; SCSI COMMAND TEMPLATES (LENGTH PREFIXED)

View File

@@ -260,6 +260,12 @@ IMMMODE_NONE .EQU 0 ; NONE
IMMMODE_SPP .EQU 1 ; IBM PC STANDARD PAR PORT (SPP)
IMMMODE_MG014 .EQU 2 ; RCBUS MG014 STYLE INTERFACE
;
; SYQ DRIVER MODE SELECTIONS
;
SYQMODE_NONE .EQU 0 ; NONE
SYQMODE_SPP .EQU 1 ; IBM PC STANDARD PAR PORT (SPP)
SYQMODE_MG014 .EQU 2 ; RCBUS MG014 STYLE INTERFACE
;
; GDC MONITOR SELECTIONS
;
GDCMON_NONE .EQU 0

1464
Source/HBIOS/syq.asm Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,7 +2,7 @@
#DEFINE RMN 3
#DEFINE RUP 0
#DEFINE RTP 0
#DEFINE BIOSVER "3.3.0-dev.17"
#DEFINE BIOSVER "3.3.0-dev.22"
#define rmj RMJ
#define rmn RMN
#define rup RUP

View File

@@ -3,5 +3,5 @@ rmn equ 3
rup equ 0
rtp equ 0
biosver macro
db "3.3.0-dev.17"
db "3.3.0-dev.22"
endm