This commit is contained in:
b1ackmai1er
2019-08-04 18:36:06 +08:00
parent 7c622942e7
commit cf9d077057
13 changed files with 710 additions and 564 deletions

View File

@@ -3,6 +3,8 @@ Version 2.9.2
- PMS: Fixed DS1210-related issue resulting in "Invalid BIOS" errors - PMS: Fixed DS1210-related issue resulting in "Invalid BIOS" errors
- SCC: Support for SC126 motherboard - SCC: Support for SC126 motherboard
- WBW: Enable Auto-CTS/DCD in SIO driver for pacing output data - WBW: Enable Auto-CTS/DCD in SIO driver for pacing output data
- WBW: Support missing pull-up resistors in SD driver (a common occurence)
- WBW: Support two SIO modules w/ auto-detection
Version 2.9.1 Version 2.9.1
------------- -------------

View File

@@ -2,4 +2,4 @@
#DEFINE RMN 9 #DEFINE RMN 9
#DEFINE RUP 2 #DEFINE RUP 2
#DEFINE RTP 0 #DEFINE RTP 0
#DEFINE BIOSVER "2.9.2-pre.0" #DEFINE BIOSVER "2.9.2-pre.1"

View File

@@ -6,8 +6,8 @@
#include "cfg_mk4.asm" #include "cfg_mk4.asm"
; ;
Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES (0-3)
Z180_IOWAIT .SET 1 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .SET 1 ; ADD (0-3) I/O WAIT STATES ABOVE 1 W/S BUILT-IN
; ;
FDENABLE .SET FALSE ; TRUE FOR FLOPPY DEVICE SUPPORT FDENABLE .SET FALSE ; TRUE FOR FLOPPY DEVICE SUPPORT
FDMODE .SET FDMODE_DIDE ; FDMODE_DIO, FDMODE_DIDE, FDMODE_DIO3 FDMODE .SET FDMODE_DIDE ; FDMODE_DIO, FDMODE_DIDE, FDMODE_DIO3

View File

@@ -6,8 +6,8 @@
#include "cfg_n8.asm" #include "cfg_n8.asm"
; ;
Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .SET 1 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .SET 1 ; MEMORY WAIT STATES (0-3)
Z180_IOWAIT .SET 3 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .SET 3 ; ADD (0-3) I/O WAIT STATES ABOVE 1 W/S BUILT-IN
; ;
SDMODE .SET SDMODE_CSIO ; FOR N8 PROTOTYPE (DATECODE 2511), USE SDMODE_N8 SDMODE .SET SDMODE_CSIO ; FOR N8 PROTOTYPE (DATECODE 2511), USE SDMODE_N8
; ;

View File

@@ -7,15 +7,14 @@
; ;
MEMMGR .SET MM_Z2 ; 512K RAM/ROM MODULE MEM MGR MEMMGR .SET MM_Z2 ; 512K RAM/ROM MODULE MEM MGR
Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES (0-3)
Z180_IOWAIT .SET 1 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .SET 1 ; ADD (0-3) I/O WAIT STATES ABOVE 1 W/S BUILT-IN
; ;
CPUOSC .SET 18432000 ; CPU OSC FREQ CPUOSC .SET 18432000 ; CPU OSC FREQ
DEFSERCFG .SET SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG DEFSERCFG .SET SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG
; ;
ASCIENABLE .SET TRUE ; TRUE FOR Z180 ASCI SUPPORT ASCIENABLE .SET TRUE ; TRUE FOR Z180 ASCI SUPPORT
SIOENABLE .SET FALSE ; TRUE TO AUTO-DETECT ZILOG SIO/2 SIOENABLE .SET FALSE ; TRUE TO AUTO-DETECT ZILOG SIO/2
SIOMODE .SET SIOMODE_RC ; TYPE OF SIO/2 TO DETECT: SIOMODE_RC, SIOMODE_SMB
ACIAENABLE .SET FALSE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA ACIAENABLE .SET FALSE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA
; ;
FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT

View File

@@ -6,15 +6,14 @@
#include "cfg_rcz180.asm" #include "cfg_rcz180.asm"
; ;
Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES (0-3)
Z180_IOWAIT .SET 1 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .SET 1 ; ADD (0-3) I/O WAIT STATES ABOVE 1 W/S BUILT-IN
; ;
CPUOSC .SET 18432000 ; CPU OSC FREQ CPUOSC .SET 18432000 ; CPU OSC FREQ
DEFSERCFG .SET SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG DEFSERCFG .SET SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG
; ;
ASCIENABLE .SET TRUE ; TRUE FOR Z180 ASCI SUPPORT ASCIENABLE .SET TRUE ; TRUE FOR Z180 ASCI SUPPORT
SIOENABLE .SET FALSE ; TRUE TO AUTO-DETECT ZILOG SIO/2 SIOENABLE .SET FALSE ; TRUE TO AUTO-DETECT ZILOG SIO/2
SIOMODE .SET SIOMODE_RC ; TYPE OF SIO/2 TO DETECT: SIOMODE_RC, SIOMODE_SMB
ACIAENABLE .SET FALSE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA ACIAENABLE .SET FALSE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA
; ;
FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT

View File

@@ -6,15 +6,16 @@
#include "cfg_rcz180.asm" #include "cfg_rcz180.asm"
; ;
Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 Z180_CLKDIV .SET 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .SET 0 ; MEMORY WAIT STATES (0-3)
Z180_IOWAIT .SET 1 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .SET 1 ; ADD (0-3) I/O WAIT STATES ABOVE 1 W/S BUILT-IN
;
DIAGPORT .SET $0D ; DIAGNOSTIC PORT ADDRESS
; ;
CPUOSC .SET 18432000 ; CPU OSC FREQ CPUOSC .SET 18432000 ; CPU OSC FREQ
DEFSERCFG .SET SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG DEFSERCFG .SET SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG
; ;
ASCIENABLE .SET TRUE ; TRUE FOR Z180 ASCI SUPPORT ASCIENABLE .SET TRUE ; TRUE FOR Z180 ASCI SUPPORT
SIOENABLE .SET FALSE ; TRUE TO AUTO-DETECT ZILOG SIO/2 SIOENABLE .SET FALSE ; TRUE TO AUTO-DETECT ZILOG SIO/2
SIOMODE .SET SIOMODE_RC ; TYPE OF SIO/2 TO DETECT: SIOMODE_RC, SIOMODE_SMB
ACIAENABLE .SET FALSE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA ACIAENABLE .SET FALSE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA
; ;
FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT
@@ -28,5 +29,5 @@ DSRTCENABLE .SET TRUE ; DS-1302 CLOCK DRIVER
; ;
SDENABLE .SET TRUE ; TRUE FOR SD SUPPORT SDENABLE .SET TRUE ; TRUE FOR SD SUPPORT
SDMODE .SET SDMODE_SC126 ; SDMODE_JUHA, SDMODE_CSIO, SDMODE_UART, SDMODE_PPI, SDMODE_DSD SDMODE .SET SDMODE_SC126 ; SDMODE_JUHA, SDMODE_CSIO, SDMODE_UART, SDMODE_PPI, SDMODE_DSD
SDTRACE .SET 2 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) SDTRACE .SET 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE)
SDCSIOFAST .SET TRUE ; TABLE-DRIVEN BIT INVERTER SDCSIOFAST .SET TRUE ; TABLE-DRIVEN BIT INVERTER

View File

@@ -8,8 +8,7 @@
CPUOSC .SET 7372800 ; CPU OSC FREQ CPUOSC .SET 7372800 ; CPU OSC FREQ
DEFSERCFG .SET SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) DEFSERCFG .SET SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE)
; ;
SIOENABLE .SET TRUE ; TRUE TO AUTO-DETECT ZILOG SIO/2 SIOENABLE .SET TRUE ; TRUE TO AUTO-DETECT ZILOG SIO/2
SIOMODE .SET SIOMODE_RC ; TYPE OF SIO/2 TO DETECT: SIOMODE_RC, SIOMODE_SMB
ACIAENABLE .SET TRUE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA ACIAENABLE .SET TRUE ; TRUE TO AUTO-DETECT MOTOROLA 6850 ACIA
; ;
FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT FDENABLE .SET FALSE ; TRUE FOR FLOPPY SUPPORT

View File

@@ -101,7 +101,7 @@ ACIA_INITUNIT:
LD HL,ACIA_DEV ; POINT TO CURRENT UART DEVICE NUM LD HL,ACIA_DEV ; POINT TO CURRENT UART DEVICE NUM
LD A,(HL) ; PUT IN ACCUM LD A,(HL) ; PUT IN ACCUM
INC (HL) ; INCREMENT IT (FOR NEXT LOOP) INC (HL) ; INCREMENT IT (FOR NEXT LOOP)
LD (IY),A ; UDPATE UNIT NUM LD (IY),A ; UPDATE UNIT NUM
; ;
#IF (INTMODE == 1) #IF (INTMODE == 1)
; ADD IM1 INT CALL LIST ENTRY ; ADD IM1 INT CALL LIST ENTRY
@@ -171,11 +171,10 @@ ACIAA_INT00:
LD E,A ; SAVE BYTE READ LD E,A ; SAVE BYTE READ
LD A,(ACIAA_BUFCNT) ; GET CURRENT BUFFER USED COUNT LD A,(ACIAA_BUFCNT) ; GET CURRENT BUFFER USED COUNT
CP ACIAA_BUFSZ ; COMPARE TO BUFFER SIZE CP ACIAA_BUFSZ ; COMPARE TO BUFFER SIZE
;RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
JR Z,ACIAA_INT2 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED JR Z,ACIAA_INT2 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
INC A ; INCREMENT THE COUNT INC A ; INCREMENT THE COUNT
LD (ACIAA_BUFCNT),A ; AND SAVE IT LD (ACIAA_BUFCNT),A ; AND SAVE IT
CP ACIAA_BUFSZ - 5 ; BUFFER GETTING FULL? CP ACIAA_BUFSZ / 2 ; BUFFER GETTING FULL?
JR NZ,ACIAA_INT0 ; IF NOT, BYPASS DEASSERTING RTS JR NZ,ACIAA_INT0 ; IF NOT, BYPASS DEASSERTING RTS
LD A,ACIA_RTSOFF ; VALUE TO DEASSERT RTS LD A,ACIA_RTSOFF ; VALUE TO DEASSERT RTS
OUT (C),A ; DO IT OUT (C),A ; DO IT
@@ -216,11 +215,10 @@ ACIAB_INT00:
LD E,A ; SAVE BYTE READ LD E,A ; SAVE BYTE READ
LD A,(ACIAB_BUFCNT) ; GET CURRENT BUFFER USED COUNT LD A,(ACIAB_BUFCNT) ; GET CURRENT BUFFER USED COUNT
CP ACIAB_BUFSZ ; COMPARE TO BUFFER SIZE CP ACIAB_BUFSZ ; COMPARE TO BUFFER SIZE
;RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
JR Z,ACIAB_INT2 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED JR Z,ACIAB_INT2 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
INC A ; INCREMENT THE COUNT INC A ; INCREMENT THE COUNT
LD (ACIAB_BUFCNT),A ; AND SAVE IT LD (ACIAB_BUFCNT),A ; AND SAVE IT
CP ACIAB_BUFSZ - 5 ; BUFFER GETTING FULL? CP ACIAB_BUFSZ / 2 ; BUFFER GETTING FULL?
JR NZ,ACIAB_INT0 ; IF NOT, BYPASS DEASSERTING RTS JR NZ,ACIAB_INT0 ; IF NOT, BYPASS DEASSERTING RTS
LD A,ACIA_RTSOFF ; VALUE TO DEASSERT RTS LD A,ACIA_RTSOFF ; VALUE TO DEASSERT RTS
OUT (C),A ; DO IT OUT (C),A ; DO IT
@@ -291,9 +289,8 @@ ACIAA_IN:
LD A,(ACIAA_BUFCNT) ; GET COUNT LD A,(ACIAA_BUFCNT) ; GET COUNT
DEC A ; DECREMENT COUNT DEC A ; DECREMENT COUNT
LD (ACIAA_BUFCNT),A ; SAVE SAVE IT LD (ACIAA_BUFCNT),A ; SAVE SAVE IT
CP 5 ; BUFFER LOW THRESHOLD CP ACIAA_BUFSZ / 4 ; BUFFER LOW THRESHOLD
JR NZ,ACIAA_IN0 ; IF NOT, BYPASS SETTING RTS JR NZ,ACIAA_IN0 ; IF NOT, BYPASS SETTING RTS
LD C,(IY+3) ; C := ACIA CMD PORT LD C,(IY+3) ; C := ACIA CMD PORT
LD A,ACIA_RTSON ; ASSERT RTS LD A,ACIA_RTSON ; ASSERT RTS
OUT (C),A ; DO IT OUT (C),A ; DO IT
@@ -318,9 +315,8 @@ ACIAB_IN:
LD A,(ACIAB_BUFCNT) ; GET COUNT LD A,(ACIAB_BUFCNT) ; GET COUNT
DEC A ; DECREMENT COUNT DEC A ; DECREMENT COUNT
LD (ACIAB_BUFCNT),A ; SAVE SAVE IT LD (ACIAB_BUFCNT),A ; SAVE SAVE IT
CP 5 ; BUFFER LOW THRESHOLD CP ACIAB_BUFSZ / 4 ; BUFFER LOW THRESHOLD
JR NZ,ACIAB_IN0 ; IF NOT, BYPASS SETTING RTS JR NZ,ACIAB_IN0 ; IF NOT, BYPASS SETTING RTS
LD C,(IY+3) ; C := ACIA CMD PORT LD C,(IY+3) ; C := ACIA CMD PORT
LD A,ACIA_RTSON ; ASSERT RTS LD A,ACIA_RTSON ; ASSERT RTS
OUT (C),A ; DO IT OUT (C),A ; DO IT
@@ -458,46 +454,40 @@ ACIA_QUERY:
; ;
; ;
ACIA_DEVICE: ACIA_DEVICE:
LD D,CIODEV_ACIA ; D := DEVICE TYPE LD D,CIODEV_ACIA ; D := DEVICE TYPE
LD E,(IY) ; E := PHYSICAL UNIT LD E,(IY) ; E := PHYSICAL UNIT
LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
; ;
; ACIA DETECTION ROUTINE ; ACIA DETECTION ROUTINE
; ;
ACIA_DETECT: ACIA_DETECT:
;LD C,ACIA_BASE ; BASE PORT ADDRESS LD C,(IY+3) ; BASE PORT ADDRESS
LD C,(IY+3) ; BASE PORT ADDRESS CALL ACIA_DETECT2 ; CHECK IT
CALL ACIA_DETECT2 ; CHECK IT JR Z,ACIA_DETECT1 ; FOUND IT, RECORD IT
JR Z,ACIA_DETECT1 ; FOUND IT, RECORD IT LD A,ACIA_NONE ; NOTHING FOUND
;LD C,ACIA_ALTBASE ; ALT BASE PORT ADDRESS RET ; DONE
;CALL ACIA_DETECT2 ; CHECK IT ;
;JR Z,ACIA_DETECT1 ; FOUND IT, RECORD IT ACIA_DETECT1:
LD A,ACIA_NONE ; NOTHING FOUND ; ACIA FOUND, RECORD IT
RET ; DONE LD A,ACIA_ACIA ; RETURN CHIP TYPE
; RET ; DONE
ACIA_DETECT1:
; ACIA FOUND, RECORD IT
;LD A,C ; BASE PORT ADDRESS TO A
;LD (IY+3),A ; SAVE ACTIVE BASE PORT
LD A,ACIA_ACIA ; RETURN CHIP TYPE
RET ; DONE
; ;
ACIA_DETECT2: ACIA_DETECT2:
; LOOK FOR ACIA AT PORT ADDRESS IN C ; LOOK FOR ACIA AT PORT ADDRESS IN C
LD A,$03 ; MASTER RESET LD A,$03 ; MASTER RESET
OUT (C),A ; DO IT OUT (C),A ; DO IT
IN A,(C) ; GET STATUS IN A,(C) ; GET STATUS
OR A ; CHECK FOR ZERO OR A ; CHECK FOR ZERO
RET NZ ; RETURN IF NOT ZERO RET NZ ; RETURN IF NOT ZERO
LD A,$02 ; CLEAR MASTER RESET LD A,$02 ; CLEAR MASTER RESET
OUT (C),A ; DO IT OUT (C),A ; DO IT
; CHECK FOR EXPECTED BITS: ; CHECK FOR EXPECTED BITS:
; TDRE=1, DCD & CTS = 0 ; TDRE=1, DCD & CTS = 0
AND %00001110 ; BIT MASK FOR "STABLE" BITS AND %00001110 ; BIT MASK FOR "STABLE" BITS
CP %00000010 ; EXPECTED VALUE CP %00000010 ; EXPECTED VALUE
RET ; RETURN RESULT, Z = CHIP FOUND RET ; RETURN RESULT, Z = CHIP FOUND
; ;
; ;
; ;

View File

@@ -63,16 +63,37 @@
; ;
; CONSTANTS ; CONSTANTS
; ;
; RTC SBC SBC-004 MFPIC N8 N8-CSIO SC126
; ----- ------- ------- ------- ------- ------- -------
; D7 WR RTC_OUT RTC_OUT -- RTC_OUT RTC_OUT RTC_OUT, I2C_SDA
; D6 WR RTC_CLK RTC_CLK -- RTC_CLK RTC_CLK RTC_CLK
; D5 WR /RTC_WE /RTC_WE -- /RTC_WE /RTC_WE /RTC_WE
; D4 WR RTC_CE RTC_CE -- RTC_CE RTC_CE RTC_CE
; D3 WR NC SPK /RTC_CE NC NC /SPI_CS2
; D2 WR NC CLKHI RTC_CLK SPI_CS SPI_CS /SPI_CS1
; D1 WR -- -- RTC_WE SPI_CLK NC FS
; D0 WR -- -- RTC_OUT SPI_DI NC I2C_SCL
;
; D7 RD -- -- -- -- -- I2C_SDA
; D6 RD CFG CFG -- SPI_DO CFG --
; D5 RD -- -- -- -- -- --
; D4 RD -- -- -- -- -- --
; D3 RD -- -- -- -- -- --
; D2 RD -- -- -- -- -- --
; D1 RD -- -- -- -- -- --
; D0 RD RTC_IN RTC_IN RTC_IN RTC_IN RTC_IN RTC_IN
;
#IF (DSRTCMODE == DSRTCMODE_STD) #IF (DSRTCMODE == DSRTCMODE_STD)
; ;
DSRTC_BASE .EQU RTC ; RTC PORT ON ALL SBC SERIES Z80 PLATFORMS DSRTC_BASE .EQU RTC ; RTC PORT
; ;
DSRTC_DATA .EQU %10000000 ; BIT 7 CONTROLS RTC DATA (I/O) LINE DSRTC_DATA .EQU %10000000 ; BIT 7 IS RTC DATA OUT
DSRTC_CLK .EQU %01000000 ; BIT 6 CONTROLS RTC CLOCK LINE, 1 = HIGH DSRTC_CLK .EQU %01000000 ; BIT 6 IS RTC CLOCK (CLK)
DSRTC_RD .EQU %00100000 ; BIT 5 CONTROLS DATA DIRECTION, 1 = READ DSRTC_RD .EQU %00100000 ; BIT 5 IS DATA DIRECTION (/WE)
DSRTC_CE .EQU %00010000 ; BIT 4 CONTROLS RTC CE LINE, 1 = HIGH (ENABLED) DSRTC_CE .EQU %00010000 ; BIT 4 IS CHIP ENABLE (CE)
; ;
DSRTC_RESET .EQU %00000000 ; ALL LOW DSRTC_MASK .EQU %11110000 ; MASK FOR BITS WE OWN IN RTC LATCH PORT
DSRTC_IDLE .EQU %00100000 ; QUIESCENT STATE
; ;
#ENDIF #ENDIF
; ;
@@ -80,12 +101,13 @@ DSRTC_RESET .EQU %00000000 ; ALL LOW
; ;
DSRTC_BASE .EQU $43 ; RTC PORT ON MF/PIC DSRTC_BASE .EQU $43 ; RTC PORT ON MF/PIC
; ;
DSRTC_DATA .EQU %00000001 ; BIT 0 CONTROLS RTC DATA (I/O) LINE DSRTC_DATA .EQU %00000001 ; BIT 0 IS RTC DATA OUT
DSRTC_CLK .EQU %00000100 ; BIT 2 CONTROLS RTC CLOCK LINE, 1 = HIGH DSRTC_CLK .EQU %00000100 ; BIT 2 IS RTC CLOCK (CLK)
DSRTC_WR .EQU %00000010 ; BIT 1 CONTROLS DATA DIRECTION, 1 = WRITE DSRTC_WR .EQU %00000010 ; BIT 1 IS DATA DIRECTION (WE)
DSRTC_CE .EQU %00001000 ; BIT 3 CONTROLS RTC CE LINE, 0 = ENABLED DSRTC_CE .EQU %00001000 ; BIT 3 CHIP ENABLE (/CE)
; ;
DSRTC_RESET .EQU %00001000 ; ALL LOW, BUT CE = 1 DSRTC_MASK .EQU %00001111 ; MASK FOR BITS WE OWN IN RTC LATCH PORT
DSRTC_IDLE .EQU %00101000 ; QUIESCENT STATE
; ;
#ENDIF #ENDIF
; ;
@@ -103,6 +125,13 @@ DSRTC_INIT:
#IF (DSRTCMODE == DSRTCMODE_MFPIC) #IF (DSRTCMODE == DSRTCMODE_MFPIC)
PRTS("MFPIC$") PRTS("MFPIC$")
#ENDIF #ENDIF
;
; SET RELEVANT BITS IN RTC LATCH SHADOW REGISTER
; TO THEIR QUIESENT STATE
LD A,(RTCVAL)
AND DSRTC_MASK
OR DSRTC_IDLE
LD (RTCVAL),A
; ;
; CHECK FOR CLOCK HALTED ; CHECK FOR CLOCK HALTED
CALL DSRTC_TSTCLK CALL DSRTC_TSTCLK
@@ -123,22 +152,22 @@ DSRTC_INIT1:
LD HL,DSRTC_TIMBUF LD HL,DSRTC_TIMBUF
CALL PRTDT CALL PRTDT
#IF DSRTCCHG ; FORCE_RTC_CHARGE_ENABLE #IF DSRTCCHG ; FORCE_RTC_CHARGE_ENABLE
LD C,$8E ; ACCESS WRITE PROT REG LD E,$8E ; ACCESS WRITE PROT REG
CALL DSRTC_CMD ; CALL DSRTC_CMD ;
LD A,$00 ; WRITE PROTECT OFF LD E,$00 ; WRITE PROTECT OFF
CALL DSRTC_PUT ; CALL DSRTC_PUT ;
CALL DSRTC_END ; FINISH CMD CALL DSRTC_END ; FINISH CMD
LD C,$90 ; ACCESS CHARGE REGISTER LD E,$90 ; ACCESS CHARGE REGISTER
CALL DSRTC_CMD ; CALL DSRTC_CMD ;
LD A,$A5 ; STD CHARGE VALUES LD E,$A5 ; STD CHARGE VALUES
CALL DSRTC_PUT ; CALL DSRTC_PUT ;
CALL DSRTC_END ; FINISH REG WRITE CALL DSRTC_END ; FINISH REG WRITE
LD C,$8E ; ACCESS WRITE PROT REG LD E,$8E ; ACCESS WRITE PROT REG
CALL DSRTC_CMD ; CALL DSRTC_CMD ;
LD A,$80 ; WRITE PROTECT ON LD E,$80 ; WRITE PROTECT ON
CALL DSRTC_PUT ; CALL DSRTC_PUT ;
CALL DSRTC_END ; FINISH CMD CALL DSRTC_END ; FINISH CMD
#ENDIF #ENDIF
@@ -303,12 +332,13 @@ DSRTC_TIM2CLK:
; TEST CLOCK FOR CHARGE DATA ; TEST CLOCK FOR CHARGE DATA
; ;
DSRTC_TSTCHG: DSRTC_TSTCHG:
LD C,$91 ; CHARGE RESISTOR & DIODE VALUES LD E,$91 ; CHARGE RESISTOR & DIODE VALUES
CALL DSRTC_CMD ; SEND THE COMMAND CALL DSRTC_CMD ; SEND THE COMMAND
CALL DSRTC_GET ; READ THE REGISTER CALL DSRTC_GET ; READ THE REGISTER
CALL DSRTC_END ; FINISH IT CALL DSRTC_END ; FINISH IT
AND %11110000 ; CHECK FOR LD A,E ; VALUE TO A
CP %10100000 ; ENABLED FLAG AND %11110000 ; CHECK FOR
CP %10100000 ; ENABLED FLAG
RET RET
; ;
; TEST CLOCK FOR VALID DATA ; TEST CLOCK FOR VALID DATA
@@ -317,23 +347,24 @@ DSRTC_TSTCHG:
; 1 = HALTED ; 1 = HALTED
; ;
DSRTC_TSTCLK: DSRTC_TSTCLK:
LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG LD E,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG
CALL DSRTC_CMD ; SEND THE COMMAND CALL DSRTC_CMD ; SEND THE COMMAND
CALL DSRTC_GET ; READ THE REGISTER CALL DSRTC_GET ; READ THE REGISTER
CALL DSRTC_END ; FINISH IT CALL DSRTC_END ; FINISH IT
LD A,E ; VALUE TO A
AND %10000000 ; HIGH ORDER BIT IS CLOCK HALT AND %10000000 ; HIGH ORDER BIT IS CLOCK HALT
RET RET
; ;
; BURST READ CLOCK DATA INTO BUFFER AT HL ; BURST READ CLOCK DATA INTO BUFFER AT HL
; ;
DSRTC_RDCLK: DSRTC_RDCLK:
LD C,$BF ; COMMAND = $BF TO BURST READ CLOCK LD E,$BF ; COMMAND = $BF TO BURST READ CLOCK
CALL DSRTC_CMD ; SEND COMMAND TO RTC CALL DSRTC_CMD ; SEND COMMAND TO RTC
LD B,DSRTC_BUFSIZ ; B IS LOOP COUNTER LD B,DSRTC_BUFSIZ ; B IS LOOP COUNTER
DSRTC_RDCLK1: DSRTC_RDCLK1:
PUSH BC ; PRESERVE BC PUSH BC ; PRESERVE BC
CALL DSRTC_GET ; GET NEXT BYTE CALL DSRTC_GET ; GET NEXT BYTE
LD (HL),A ; SAVE IN BUFFER LD (HL),E ; SAVE IN BUFFER
INC HL ; INC BUF POINTER INC HL ; INC BUF POINTER
POP BC ; RESTORE BC POP BC ; RESTORE BC
DJNZ DSRTC_RDCLK1 ; LOOP IF NOT DONE DJNZ DSRTC_RDCLK1 ; LOOP IF NOT DONE
@@ -342,34 +373,35 @@ DSRTC_RDCLK1:
; BURST WRITE CLOCK DATA FROM BUFFER AT HL ; BURST WRITE CLOCK DATA FROM BUFFER AT HL
; ;
DSRTC_WRCLK: DSRTC_WRCLK:
LD C,$8E ; COMMAND = $8E TO WRITE CONTROL REGISTER LD E,$8E ; COMMAND = $8E TO WRITE CONTROL REGISTER
CALL DSRTC_CMD ; SEND COMMAND CALL DSRTC_CMD ; SEND COMMAND
XOR A ; $00 = UNPROTECT LD E,$00 ; $00 = UNPROTECT
CALL DSRTC_PUT ; SEND VALUE TO CONTROL REGISTER CALL DSRTC_PUT ; SEND VALUE TO CONTROL REGISTER
CALL DSRTC_END ; FINISH IT CALL DSRTC_END ; FINISH IT
; ;
LD C,$BE ; COMMAND = $BE TO BURST WRITE CLOCK LD E,$BE ; COMMAND = $BE TO BURST WRITE CLOCK
CALL DSRTC_CMD ; SEND COMMAND TO RTC CALL DSRTC_CMD ; SEND COMMAND TO RTC
LD B,DSRTC_BUFSIZ ; B IS LOOP COUNTER LD B,DSRTC_BUFSIZ ; B IS LOOP COUNTER
DSRTC_WRCLK1: DSRTC_WRCLK1:
PUSH BC ; PRESERVE BC PUSH BC ; PRESERVE BC
LD A,(HL) ; GET NEXT BYTE TO WRITE LD E,(HL) ; GET NEXT BYTE TO WRITE
CALL DSRTC_PUT ; PUT NEXT BYTE CALL DSRTC_PUT ; PUT NEXT BYTE
INC HL ; INC BUF POINTER INC HL ; INC BUF POINTER
POP BC ; RESTORE BC POP BC ; RESTORE BC
DJNZ DSRTC_WRCLK1 ; LOOP IF NOT DONE DJNZ DSRTC_WRCLK1 ; LOOP IF NOT DONE
LD A,$80 ; ADD CONTROL REG BYTE, $80 = PROTECT ON LD E,$80 ; ADD CONTROL REG BYTE, $80 = PROTECT ON
CALL DSRTC_PUT ; WRITE REQUIRED 8TH BYTE CALL DSRTC_PUT ; WRITE REQUIRED 8TH BYTE
JP DSRTC_END ; FINISH IT JP DSRTC_END ; FINISH IT
; ;
#IF (DSRTCMODE == DSRTCMODE_STD) ; SEND COMMAND IN E TO RTC
;
; SEND COMMAND IN C TO RTC
; ALL RTC SEQUENCES MUST CALL THIS FIRST TO SEND THE RTC COMMAND. ; ALL RTC SEQUENCES MUST CALL THIS FIRST TO SEND THE RTC COMMAND.
; THE COMMAND IS SENT VIA A PUT. CE AND CLK ARE LEFT HIGH! THIS ; THE COMMAND IS SENT VIA A PUT. CE AND CLK ARE LEFT ASSERTED! THIS
; IS INTENTIONAL BECAUSE WHEN THE CLOCK IS LOWERED, THE FIRST BIT ; IS INTENTIONAL BECAUSE WHEN THE CLOCK IS LOWERED, THE FIRST BIT
; WILL BE PRESENTED TO READ (IN THE CASE OF A READ CMD). ; WILL BE PRESENTED TO READ (IN THE CASE OF A READ CMD).
; ;
; N.B. REGISTER A CONTAINS WORKING VALUE OF LATCH PORT AND MUST NOT
; BE MODIFIED BETWEEN CALLS TO DSRTC_CMD, DSRTC_PUT, AND DSRTC_GET.
;
; 0) ASSUME ALL LINES UNDEFINED AT ENTRY ; 0) ASSUME ALL LINES UNDEFINED AT ENTRY
; 1) DEASSERT ALL LINES (CE, RD, CLOCK, & DATA) ; 1) DEASSERT ALL LINES (CE, RD, CLOCK, & DATA)
; 2) WAIT 1US ; 2) WAIT 1US
@@ -378,19 +410,22 @@ DSRTC_WRCLK1:
; 5) PUT COMMAND ; 5) PUT COMMAND
; ;
DSRTC_CMD: DSRTC_CMD:
XOR A ; ALL LINES LOW TO RESET LD A,(RTCVAL) ; INIT A WITH QUIESCENT STATE
OUT (DSRTC_BASE),A ; WRITE TO PORT
CALL DLY2 ; DELAY 2 * 27 T-STATES
#IF (DSRTCMODE == DSRTCMODE_MFPIC)
AND ~DSRTC_CE ; ASSERT CE (LOW)
#ELSE
OR DSRTC_CE ; ASSERT CE (HIGH)
#ENDIF
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY2 ; DELAY 2 * 27 T-STATES CALL DLY2 ; DELAY 2 * 27 T-STATES
XOR DSRTC_CE ; NOW SET CE HIGH
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY2 ; DELAY 2 * 27 T-STATES
LD A,C ; LOAD COMMAND
CALL DSRTC_PUT ; WRITE IT CALL DSRTC_PUT ; WRITE IT
RET RET
; ;
; WRITE BYTE IN A TO THE RTC ; WRITE BYTE IN E TO THE RTC
; WRITE BYTE IN A TO THE RTC. CE IS IMPLICITY ASSERTED AT ; WRITE BYTE IN E TO THE RTC. CE IS IMPLICITY ASSERTED AT
; THE START. CE AND CLK ARE LEFT HIGH AT THE END IN CASE ; THE START. CE AND CLK ARE LEFT ASSERTED AT THE END IN CASE
; NEXT ACTION IS A READ. ; NEXT ACTION IS A READ.
; ;
; 0) ASSUME ENTRY WITH CE HI, OTHERS UNDEFINED ; 0) ASSUME ENTRY WITH CE HI, OTHERS UNDEFINED
@@ -404,16 +439,25 @@ DSRTC_CMD:
; ;
DSRTC_PUT: DSRTC_PUT:
LD B,8 ; LOOP FOR 8 BITS LD B,8 ; LOOP FOR 8 BITS
LD C,A ; SAVE THE WORKING VALUE #IF (DSRTCMODE == DSRTCMODE_MFPIC)
OR DSRTC_WR ; SET WRITE MODE
#ELSE
AND ~DSRTC_RD ; SET WRITE MODE
#ENDIF
DSRTC_PUT1: DSRTC_PUT1:
LD A,DSRTC_CE ; SET CLOCK LOW AND ~DSRTC_CLK ; SET CLOCK LOW
OUT (DSRTC_BASE),A ; DO IT OUT (DSRTC_BASE),A ; DO IT
CALL DLY1 ; DELAY 27 T-STATES CALL DLY1 ; DELAY 27 T-STATES
LD A,C ; RECOVER WORKING VALUE
RRCA ; ROTATE NEXT BIT TO SEND INTO BIT 7 #IF (DSRTCMODE == DSRTCMODE_MFPIC)
LD C,A ; SAVE WORKING VALUE RRA ; PREP ACCUM TO GET DATA BIT IN CARRY
AND %10000000 ; ISOLATE THE DATA BIT RR E ; ROTATE NEXT BIT TO SEND INTO CARRY
OR DSRTC_CE ; KEEP CE HIGH RLA ; ROTATE BITS BACK TO CORRECT POSTIIONS
#ELSE
RLA ; PREP ACCUM TO GET DATA BIT IN CARRY
RR E ; ROTATE NEXT BIT TO SEND INTO CARRY
RRA ; ROTATE BITS BACK TO CORRECT POSTIIONS
#ENDIF
OUT (DSRTC_BASE),A ; ASSERT DATA BIT ON BUS OUT (DSRTC_BASE),A ; ASSERT DATA BIT ON BUS
OR DSRTC_CLK ; SET CLOCK HI OR DSRTC_CLK ; SET CLOCK HI
OUT (DSRTC_BASE),A ; DO IT OUT (DSRTC_BASE),A ; DO IT
@@ -421,10 +465,10 @@ DSRTC_PUT1:
DJNZ DSRTC_PUT1 ; LOOP IF NOT DONE DJNZ DSRTC_PUT1 ; LOOP IF NOT DONE
RET RET
; ;
; READ BYTE FROM RTC, RETURN VALUE IN A ; READ BYTE FROM RTC, RETURN VALUE IN E
; READ THE NEXT BYTE FROM THE RTC INTO A. CE IS IMPLICITLY ; READ THE NEXT BYTE FROM THE RTC INTO E. CE IS IMPLICITLY
; ASSERTED AT THE START. CE AND CLK ARE LEFT HIGH AT ; ASSERTED AT THE START. CE AND CLK ARE LEFT ASSERTED AT
; THE END. CLOCK *MUST* BE LEFT HIGH FROM DSRTC_CMD! ; THE END. CLOCK *MUST* BE LEFT ASSERTED FROM DSRTC_CMD!
; ;
; 0) ASSUME ENTRY WITH CE HI, OTHERS UNDEFINED ; 0) ASSUME ENTRY WITH CE HI, OTHERS UNDEFINED
; 1) SET RD HI AND CLOCK LOW ; 1) SET RD HI AND CLOCK LOW
@@ -436,146 +480,38 @@ DSRTC_PUT1:
; 8) EXIT WITH CE,CLK,RD HI ; 8) EXIT WITH CE,CLK,RD HI
; ;
DSRTC_GET: DSRTC_GET:
LD C,0 ; INITIALIZE WORKING VALUE TO 0 LD E,0 ; INITIALIZE WORKING VALUE TO 0
LD B,8 ; LOOP FOR 8 BITS LD B,8 ; LOOP FOR 8 BITS
#IF (DSRTCMODE == DSRTCMODE_MFPIC)
AND ~DSRTC_WR ; SET READ MODE
#ELSE
OR DSRTC_RD ; SET READ MODE
#ENDIF
DSRTC_GET1: DSRTC_GET1:
LD A,DSRTC_CE | DSRTC_RD ; SET CLK LO AND ~DSRTC_CLK ; SET CLK LO
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY2 ; DELAY 2 * 27 T-STATES CALL DLY1 ; DELAY 2 * 27 T-STATES
PUSH AF ; SAVE PORT VALUE
IN A,(DSRTC_BASE) ; READ THE RTC PORT IN A,(DSRTC_BASE) ; READ THE RTC PORT
AND %00000001 ; ISOLATE THE DATA BIT RRA ; DATA BIT TO CARRY
OR C ; COMBINE WITH WORKING VALUE RR E ; SHIFT INTO WORKING VALUE
RRCA ; ROTATE FOR NEXT BIT POP AF ; RESTORE PORT VALUE
LD C,A ; SAVE WORKING VALUE OR DSRTC_CLK ; CLOCK BACK TO HI
LD A,DSRTC_CE | DSRTC_CLK | DSRTC_RD ; CLOCK BACK TO HI
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY1 ; DELAY 27 T-STATES CALL DLY1 ; DELAY 27 T-STATES
DJNZ DSRTC_GET1 ; LOOP IF NOT DONE (13) DJNZ DSRTC_GET1 ; LOOP IF NOT DONE (13)
LD A,C ; GET RESULT INTO A
RET RET
; ;
; COMPLETE A COMMAND SEQUENCE ; COMPLETE A COMMAND SEQUENCE
; FINISHES UP A COMMAND SEQUENCE. ; FINISHES UP A COMMAND SEQUENCE.
; DOES NOT DESTROY ANY REGISTERS. ; DOES NOT DESTROY ANY REGISTERS.
; ;
; 1) SET ALL LINES LO ; 1) SET ALL LINES BACK TO QUIESCENT STATE
; ;
DSRTC_END: DSRTC_END:
PUSH AF ; SAVE AF LD A,(RTCVAL) ; INIT A WITH QUIESCENT STATE
XOR A ; ALL LINES OFF TO CLEAN UP OUT (DSRTC_BASE),A ; WRITE TO PORT
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT RET ; RETURN
POP AF ; RESTORE AF
RET
;
#ENDIF
;
#IF (DSRTCMODE == DSRTCMODE_MFPIC)
;
;
; SEND COMMAND IN C TO RTC
; ALL RTC SEQUENCES MUST CALL THIS FIRST TO SEND THE RTC COMMAND.
; THE COMMAND IS SENT VIA A PUT. CE AND CLK ARE LEFT ACTIVE! THIS
; IS INTENTIONAL BECAUSE WHEN THE CLOCK IS LOWERED, THE FIRST BIT
; WILL BE PRESENTED TO READ (IN THE CASE OF A READ CMD).
;
; 0) ASSUME ALL LINES UNDEFINED AT ENTRY
; 1) DEASSERT ALL LINES (CE, RD, CLOCK, & DATA)
; 2) WAIT 1US
; 3) SET CE HI
; 4) WAIT 1US
; 5) PUT COMMAND
;
DSRTC_CMD:
;XOR A ; ALL LINES LOW TO RESET
LD A,DSRTC_RESET ; QUIESCENT STATE
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY2 ; DELAY 2 * 27 T-STATES
XOR DSRTC_CE ; NOW ASSERT CE
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY2 ; DELAY 2 * 27 T-STATES
LD A,C ; LOAD COMMAND
CALL DSRTC_PUT ; WRITE IT
RET
;
; WRITE BYTE IN A TO THE RTC
; WRITE BYTE IN A TO THE RTC. CE IS IMPLICITY ASSERTED AT
; THE START. CE AND CLK ARE LEFT ASSERTED AT THE END IN CASE
; NEXT ACTION IS A READ.
;
; 0) ASSUME ENTRY WITH CE ASSERTED, OTHERS UNDEFINED
; 1) CLOCK -> LOW
; 2) WAIT 250NS
; 3) SET DATA ACCORDING TO BIT VALUE
; 4) CLOCK -> HIGH
; 5) WAIT 250NS (CLOCK READS DATA BIT FROM BUS)
; 6) LOOP FOR 8 DATA BITS
; 7) EXIT WITH CE AND CLOCK ASSERTED
;
DSRTC_PUT:
LD B,8 ; LOOP FOR 8 BITS
LD C,A ; SAVE THE WORKING VALUE
LD A,DSRTC_WR | DSRTC_CLK ; MODE=WRITE, CLOCK ON, CE ACTIVE (0)
DSRTC_PUT1:
XOR DSRTC_CLK ; FLIP CLOCK OFF
OUT (DSRTC_BASE),A ; DO IT
CALL DLY1 ; DELAY 27 T-STATES
RRA ; PREP ACCUM TO GET DATA BIT IN CARRY
RR C ; ROTATE NEXT BIT TO SEND INTO CARRY
RLA ; ROTATE BITS BACK TO CORRECT POSTIIONS
OUT (DSRTC_BASE),A ; ASSERT DATA BIT ON BUS
XOR DSRTC_CLK ; FLIP CLOCK ON
OUT (DSRTC_BASE),A ; DO IT, DATA BIT SENT ON RISING EDGE
CALL DLY1 ; DELAY 27 T-STATES
DJNZ DSRTC_PUT1 ; LOOP IF NOT DONE
RET
;
; READ BYTE FROM RTC, RETURN VALUE IN A
; READ THE NEXT BYTE FROM THE RTC INTO A. CE IS IMPLICITLY
; ASSERTED AT THE START. CE AND CLK ARE LEFT HIGH AT
; THE END. CLOCK *MUST* BE LEFT HIGH FROM DSRTC_CMD!
;
; 0) ASSUME ENTRY WITH CE HI, OTHERS UNDEFINED
; 1) SET RD HI AND CLOCK LOW
; 3) WAIT 250NS (CLOCK PUTS DATA BIT ON BUS)
; 4) READ DATA BIT
; 5) SET CLOCK HI
; 6) WAIT 250NS
; 7) LOOP FOR 8 DATA BITS
; 8) EXIT WITH CE,CLK,RD HI
;
DSRTC_GET:
LD C,0 ; INITIALIZE WORKING VALUE TO 0
LD B,8 ; LOOP FOR 8 BITS
LD A,DSRTC_CLK ; MODE=READ, CLOCK ON, CE ACTIVE (0)
DSRTC_GET1:
XOR DSRTC_CLK ; FLIP CLOCK OFF
OUT (DSRTC_BASE),A ; DO IT
CALL DLY2 ; DELAY 2 * 27 T-STATES
IN A,(DSRTC_BASE) ; READ THE RTC PORT
RRA ; DATA BIT TO CARRY
RR C ; SHIFT INTO WORKING VALUE
LD A,DSRTC_CLK ; CLOCK ON
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
CALL DLY1 ; DELAY 27 T-STATES
DJNZ DSRTC_GET1 ; LOOP IF NOT DONE
LD A,C ; GET RESULT INTO A
RET
;
; COMPLETE A COMMAND SEQUENCE
; FINISHES UP A COMMAND SEQUENCE.
; DOES NOT DESTROY ANY REGISTERS.
;
; 1) BACK TO QUIESCENT STATE
;
DSRTC_END:
PUSH AF ; SAVE AF
;XOR A ; ALL LINES OFF TO CLEAN UP
LD A,DSRTC_RESET ; QUIESCENT STATE
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
POP AF ; RESTORE AF
RET
;
#ENDIF
; ;
; WORKING VARIABLES ; WORKING VARIABLES
; ;

View File

@@ -9,14 +9,14 @@
; - TEST XC CARD TYPE DETECTION ; - TEST XC CARD TYPE DETECTION
; - TRY TO GET INIT TO FAIL, REMOVE DELAYS AT START OF GOIDLE? ; - TRY TO GET INIT TO FAIL, REMOVE DELAYS AT START OF GOIDLE?
; ;
;------------------------------------------------------------------------------ ;--------------------------------------------------------------------------------------
; SD Signal Active JUHA N8 CSIO PPI UART DSD MK4 ; SD Signal Active JUHA N8 CSIO PPI UART DSD MK4 SC126
; ------------ ------- ------- ------- ------- ------- ------- ------- ------- ; ------------ ------- ------- ------- ------- ------- ------- ------- ------- -------
; CS (DAT3) LO -> RTC:2 RTC:2 RTC:2 ~PC:4 ~MCR:3 OPR:2 MK4_SD:2 ; CS (DAT3) LO -> RTC:2 RTC:2 RTC:2 ~PC:4 ~MCR:3 OPR:2 SD:2 ~RTC:2
; CLK HI -> RTC:1 RTC:1 N/A PC:1 ~MCR:2 OPR:1 N/A ; CLK HI -> RTC:1 RTC:1 CSIO PC:1 ~MCR:2 OPR:1 CSIO CSIO
; DI (CMD) HI -> RTC:0 RTC:0 N/A PC:0 ~MCR:0 OPR:0 N/A ; DI (CMD) HI -> RTC:0 RTC:0 CSIO PC:0 ~MCR:0 OPR:0 CSIO CSIO
; DO (DAT0) HI -> RTC:7 RTC:6 N/A PB:7 ~MSR:5 OPR:0 N/A ; DO (DAT0) HI -> RTC:7 RTC:6 CSIO PB:7 ~MSR:5 OPR:0 CSIO CSIO
;------------------------------------------------------------------------------ ;--------------------------------------------------------------------------------------
; ;
; CS = CHIP SELECT (AKA DAT3 FOR NON-SPI MODE) ; CS = CHIP SELECT (AKA DAT3 FOR NON-SPI MODE)
; CLK = CLOCK ; CLK = CLOCK
@@ -79,10 +79,46 @@
; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA ; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA
; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD ; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD
; ;
;------------------------------------------------------------------------------
;
; *** HACK FOR MISSING PULLUP RESISTORS ***
;
; THERE IS A RECENT TREND FOR SD ADAPTER BOARDS (SUCH AS THOSE USED TO ATTACH AN
; SD CARD TO AN ARDUINO OR RASPBERRY PI) TO OMIT THE PULLUP RESISTORS THAT ARE SUPPOSED
; TO BE ON ALL LINES. DESPITE BEING A CLEAR VIOLATION OF THE SPEC, IT IS SOMETHING THAT
; WE WILL NOW NEED TO LIVE WITH. THE CLK, CS, AND MOSI SIGNALS ARE NOT AN ISSUE SINCE
; WE ARE DRIVING THOSE SIGNALS AS THE HOST. THE PROBLEM IS WITH THE MISO SIGNAL.
; FORTUNATELY, MOST OF THE TIME, THE SD CARD WILL BE DRIVING THE SIGNAL. HOWEVER,
; THERE ARE TWO SCEANRIOS WE NEED TO ACCOMMODATE IN THE CODE:
;
; 1. MISO WILL NOT BE DRIVEN BY THE SD CARD (FLOATING) PRIOR TO RESETING THE
; CARD WITH CMD0. NORMALLY, A COMMAND SEQUENCE INVOLVES WAITING FOR THE
; CARD TO BE "READY" BY READING BYTES FROM THE CARD AND LOOKING FOR $FF.
; WHEN MISO IS FLOATING THIS WILL NOT BE RELIABLE. SINCE THE SPEC INDICATES
; IT IS NOT NECESSARY TO WAIT FOR READY PRIOR TO CMD0, THE CODE HAS BEEN
; MODIFIED TO ISSUE CMD0 WITHOUT WAITING FOR READY.
;
; 2. MISO MAY NOT BE DRIVEN IMMEDIATELY AFTER SENDING A COMMAND (POSSIBLY
; JUST CMD0, BUT NOT SURE). NORMALLY, AFTER SENDING A COMMAND, YOU
; LOOK FOR "FILL" BYTES OF $FF THAT MAY OCCUR PRIOR TO THE RESULT. WHEN MISO
; IS FLOATING IT IS IMPOSSIBLE TO DETERMINE IF THE BYTE RECEIVED IS A FILL
; BYTE OR NOT. BASED ON WHAT I HAVE READ, THERE WILL ALWAYS BE AT LEAST
; ONE FILL BYTE PRIOR TO THE ACTUAL RESULT. ADDITIONALLY, THE SD CARD WILL
; START DRIVING MISO SOMETIME WITHING THAT FIRST FILL BYTE. SO, WE NOW
; JUST DISCARD THE FIRST BYTE RECEIVED AFTER A COMMAND IS SENT WITH THE
; ASSUMPTION THAT IT MUST BE A FILL BYTE AND IS NOT RELIABLE DUE TO FLOATING
; MISO.
;
; THESE CHANGES ARE CONSISTENT WITH THE POPULAR ARDUINO SDFAT LIBRARY, SO THEY ARE
; PROBABLY PRETTY SAFE. HOWEVER, I HAVE BRACKETED THE CHANGES WITH THE EQUATE BELOW.
; IF YOU WANT TO REVERT THESE HACKS, JUST SET THE EQUATE TO FALSE.
;
SD_NOPULLUP .EQU TRUE ; ASSUME NO PULLUP
;
#IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD #IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE??? SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE
SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC
SD_CS .EQU %00000100 ; RTC:2 IS SELECT SD_CS .EQU %00000100 ; RTC:2 IS SELECT
SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK
@@ -93,7 +129,7 @@ SD_DO .EQU %10000000 ; RTC:7 IS DATA OUT (CARD -> CPU)
#IF (SDMODE == SDMODE_N8) ; UNMODIFIED N8-2511 #IF (SDMODE == SDMODE_N8) ; UNMODIFIED N8-2511
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE??? SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE
SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC
SD_CS .EQU %00000100 ; RTC:2 IS SELECT SD_CS .EQU %00000100 ; RTC:2 IS SELECT
SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK
@@ -158,11 +194,11 @@ SD_CNTR .EQU Z180_CNTR
SD_TRDR .EQU Z180_TRDR SD_TRDR .EQU Z180_TRDR
#ENDIF #ENDIF
; ;
#IF (SDMODE == SDMODE_SC126) ; N8-2312 #IF (SDMODE == SDMODE_SC126) ; SC126
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
SD_OPRDEF .EQU %00001101 ; QUIESCENT STATE SD_OPRDEF .EQU %00001100 ; QUIESCENT STATE (DEASSERT /CS1 & /CS2)
SD_CS .EQU %00000100 ; RTC:2 IS SELECT SD_CS .EQU %00000100 ; RTC:2 IS SELECT FOR PRIMARY SPI CARD
SD_CNTR .EQU Z180_CNTR SD_CNTR .EQU Z180_CNTR
SD_TRDR .EQU Z180_TRDR SD_TRDR .EQU Z180_TRDR
#ENDIF #ENDIF
@@ -257,6 +293,10 @@ SD_INIT:
PRTS(" IO=0x$") PRTS(" IO=0x$")
LD A,SD_OPRREG LD A,SD_OPRREG
CALL PRTHEXBYTE CALL PRTHEXBYTE
;
LD A,(RTCVAL) ; GET RTC PORT SHADOW VALUE
OR SD_OPRDEF ; SET OUR BIT DEFAULTS
LD (RTCVAL),A ; SAVE IT
#ENDIF #ENDIF
; ;
#IF (SDMODE == SDMODE_N8) #IF (SDMODE == SDMODE_N8)
@@ -264,6 +304,10 @@ SD_INIT:
PRTS(" IO=0x$") PRTS(" IO=0x$")
LD A,SD_OPRREG LD A,SD_OPRREG
CALL PRTHEXBYTE CALL PRTHEXBYTE
;
LD A,(RTCVAL) ; GET RTC PORT SHADOW VALUE
OR SD_OPRDEF ; SET OUR BIT DEFAULTS
LD (RTCVAL),A ; SAVE IT
#ENDIF #ENDIF
; ;
#IF (SDMODE == SDMODE_CSIO) #IF (SDMODE == SDMODE_CSIO)
@@ -280,6 +324,10 @@ SD_INIT:
PRTS(" TRDR=0x$") PRTS(" TRDR=0x$")
LD A,SD_TRDR LD A,SD_TRDR
CALL PRTHEXBYTE CALL PRTHEXBYTE
;
LD A,(RTCVAL) ; GET RTC PORT SHADOW VALUE
OR SD_OPRDEF ; SET OUR BIT DEFAULTS
LD (RTCVAL),A ; SAVE IT
#ENDIF #ENDIF
; ;
#IF (SDMODE == SDMODE_PPI) #IF (SDMODE == SDMODE_PPI)
@@ -339,6 +387,10 @@ SD_INIT:
PRTS(" TRDR=0x$") PRTS(" TRDR=0x$")
LD A,SD_TRDR LD A,SD_TRDR
CALL PRTHEXBYTE CALL PRTHEXBYTE
;
LD A,(RTCVAL) ; GET RTC PORT SHADOW VALUE
OR SD_OPRDEF ; SET OUR BIT DEFAULTS
LD (RTCVAL),A ; SAVE IT
#ENDIF #ENDIF
; ;
CALL SD_PROBE ; CHECK FOR HARDWARE CALL SD_PROBE ; CHECK FOR HARDWARE
@@ -704,12 +756,6 @@ SD_GEOM:
; (RE)INITIALIZE CARD ; (RE)INITIALIZE CARD
; ;
SD_INITCARD: SD_INITCARD:
;
;; CLEAR OUT UNIT SPECIFIC DATA
;SD_DPTR(0) ; SET HL TO START OF UNIT DATA
;LD BC,SD_UNITDATALEN
;XOR A
;CALL FILL
; ;
CALL SD_CHKCD ; CHECK CARD DETECT CALL SD_CHKCD ; CHECK CARD DETECT
JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO
@@ -725,7 +771,7 @@ SD_INITCARD1:
; ;
; PUT CARD IN IDLE STATE ; PUT CARD IN IDLE STATE
CALL SD_GOIDLE ; GO TO IDLE CALL SD_GOIDLE ; GO TO IDLE
RET NZ ; ABORT IF FAILED JP NZ,SD_NOMEDIA ; CONVERT ERROR TO NO MEDIA
; ;
SD_INITCARD2: SD_INITCARD2:
LD (IY+SD_TYPE),SD_TYPESDSC ; ASSUME SDSC CARD TYPE LD (IY+SD_TYPE),SD_TYPESDSC ; ASSUME SDSC CARD TYPE
@@ -1106,9 +1152,8 @@ SD_GOIDLE1:
RET NZ ; ABORT ON ERROR RET NZ ; ABORT ON ERROR
LD A,(SD_RC) ; GET CARD RESULT LD A,(SD_RC) ; GET CARD RESULT
DEC A ; MAP EXPECTED $01 -> $00 DEC A ; MAP EXPECTED $01 -> $00
RET Z ; ALL IS GOOD, RETURN WITH Z=0 AND Z SET RET Z ; ALL IS GOOD, RETURN WITH A=0 AND Z SET
LD A,SD_STCMDERR ; SET COMMAND ERROR VALUE, NZ ALREADY SET JP SD_ERRCMD ; SET COMMAND ERROR VALUE
RET ; AND RETURN
; ;
; INITIALIZE COMMAND BUFFER ; INITIALIZE COMMAND BUFFER
; COMMAND BYTE IN ACCUM ; COMMAND BYTE IN ACCUM
@@ -1155,10 +1200,23 @@ SD_EXECCMD:
CALL WRITESTR CALL WRITESTR
POP AF POP AF
#ENDIF #ENDIF
;
CALL SD_SELECT
;
#IF (SD_NOPULLUP)
; DO NOT WAIT FOR READY PRIOR TO CMD0! THIS HACK IS REQUIRED BY
; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE
; COMMENTS AT TOP OF THIS FILE.
LD A,(SD_CMDBUF)
CP SD_CMD_GO_IDLE_STATE
JR Z,SD_EXECCMD0
#ENDIF
;
; WAIT FOR CARD TO BE READY ; WAIT FOR CARD TO BE READY
CALL SD_WAITRDY ; WAIT FOR CARD TO BE READY FOR A COMMAND CALL SD_WAITRDY ; WAIT FOR CARD TO BE READY FOR A COMMAND
JP NZ,SD_ERRRDYTO ; HANDLE TIMEOUT ERROR JP NZ,SD_ERRRDYTO ; HANDLE TIMEOUT ERROR
;
SD_EXECCMD0:
; SEND THE COMMAND ; SEND THE COMMAND
LD HL,SD_CMDBUF ; POINT TO COMMAND BUFFER LD HL,SD_CMDBUF ; POINT TO COMMAND BUFFER
LD E,6 ; COMMANDS ARE 6 BYTES LD E,6 ; COMMANDS ARE 6 BYTES
@@ -1168,6 +1226,13 @@ SD_EXECCMD1:
INC HL ; POINT TO NEXT BYTE INC HL ; POINT TO NEXT BYTE
DEC E ; DEC LOOP COUNTER DEC E ; DEC LOOP COUNTER
JR NZ,SD_EXECCMD1 ; LOOP TILL DONE W/ ALL 6 BYTES JR NZ,SD_EXECCMD1 ; LOOP TILL DONE W/ ALL 6 BYTES
;
#IF (SD_NOPULLUP)
; THE FIRST FILL BYTE IS DISCARDED! THIS HACK IS REQUIRED BY
; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE
; COMMENTS AT TOP OF THIS FILE.
CALL SD_GET ; GET A BYTE AND DISCARD IT
#ENDIF
; ;
; GET RESULT ; GET RESULT
LD E,0 ; INIT TIMEOUT LOOP COUNTER LD E,0 ; INIT TIMEOUT LOOP COUNTER
@@ -1277,10 +1342,9 @@ SD_PUTDATA3:
XOR A XOR A
RET RET
; ;
; SELECT CARD AND WAIT FOR IT TO BE READY ($FF) ; WAIT FOR CARD TO BE READY ($FF). MUST ALREADY BE SELECTED.
; ;
SD_WAITRDY: SD_WAITRDY:
CALL SD_SELECT ; SELECT CARD
LD DE,$FFFF ; LOOP MAX (TIMEOUT) LD DE,$FFFF ; LOOP MAX (TIMEOUT)
SD_WAITRDY1: SD_WAITRDY1:
CALL SD_GET CALL SD_GET
@@ -1320,27 +1384,27 @@ SD_DONE:
; ;
SD_SETUP: SD_SETUP:
; ;
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_N8) | (SDMODE == SDMODE_DSD))
LD A,SD_OPRDEF
LD (SD_OPRVAL),A
OUT (SD_OPRREG),A
#ENDIF
;
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC126))
; CSIO SETUP
; LD A,2 ; 18MHz/20 <= 400kHz
LD A,6 ; ???
OUT0 (SD_CNTR),A
LD A,SD_OPRDEF
LD (SD_OPRVAL),A
OUT (SD_OPRREG),A
#ENDIF
;
#IF (SDMODE == SDMODE_PPI) #IF (SDMODE == SDMODE_PPI)
; PPISD IS DESIGNED TO CORESIDE ON THE SAME PARALLEL PORT ; PPISD IS DESIGNED TO CORESIDE ON THE SAME PARALLEL PORT
; AS A DSKY. SEE DSKY.ASM FOR DETAILS. ; AS A DSKY. SEE DSKY.ASM FOR DETAILS.
LD A,82H ; PPI PORT A=OUT, B=IN, C=OUT LD A,82H ; PPI PORT A=OUT, B=IN, C=OUT
OUT (SD_PPIX),A OUT (SD_PPIX),A
#ENDIF
;
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC126))
; CSIO SETUP FOR Z180 CSIO
; LD A,2 ; 18MHz/20 <= 400kHz
LD A,6 ; ???
OUT0 (SD_CNTR),A
#ENDIF
;
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_N8) | (SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_SC126))
LD A,(RTCVAL)
LD (SD_OPRVAL),A
OUT (SD_OPRREG),A
#ENDIF
;
#IF ((SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_DSD) | (SDMODE == SDMODE_PPI))
LD A,SD_OPRDEF LD A,SD_OPRDEF
LD (SD_OPRVAL),A LD (SD_OPRVAL),A
OUT (SD_OPRREG),A OUT (SD_OPRREG),A

View File

@@ -15,38 +15,91 @@
; https://www.retrobrewcomputers.org/doku.php?id=boards:ecb:zilog-peripherals:clock-divider ; https://www.retrobrewcomputers.org/doku.php?id=boards:ecb:zilog-peripherals:clock-divider
; ;
; SIO PORT A (COM1:) and SIO PORT B (COM2:) ARE MAPPED TO DEVICE UC1: AND UL1: IN CP/M. ; SIO PORT A (COM1:) and SIO PORT B (COM2:) ARE MAPPED TO DEVICE UC1: AND UL1: IN CP/M.
; ;
SIO_BUFSZ .EQU 32 ; RECEIVE RING BUFFER SIZE
;
SIO_NONE .EQU 0 SIO_NONE .EQU 0
SIO_SIO .EQU 1 SIO_SIO .EQU 1
; ;
#IF (SIOMODE == SIOMODE_RC) SIO_RTSON .EQU $EA
SIOA_CMD .EQU SIOBASE + $00 SIO_RTSOFF .EQU $E8
SIOA_DAT .EQU SIOBASE + $01 ;
SIOB_CMD .EQU SIOBASE + $02 #IF (INTMODE == 2)
SIOB_DAT .EQU SIOBASE + $03 ;
#ENDIF #IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4) | (PLATFORM == PLT_RCZ180))
; SIO0_IVT .EQU HB_IVT0D
#IF (SIOMODE == SIOMODE_SMB) SIO1_IVT .EQU HB_IVT0E
SIOA_CMD .EQU SIOBASE + $02 SIO0_VEC .EQU IVT_SER2
SIOA_DAT .EQU SIOBASE + $00 SIO1_VEC .EQU IVT_SER3
SIOB_CMD .EQU SIOBASE + $03 #ELSE
SIOB_DAT .EQU SIOBASE + $01 SIO0_IVT .EQU HB_IVT07
SIO1_IVT .EQU HB_IVT08
SIO0_VEC .EQU IVT_SER0
SIO1_VEC .EQU IVT_SER1
#ENDIF #ENDIF
; ;
#IF (SIOMODE == SIOMODE_ZP)
SIOA_CMD .EQU SIOBASE + $06
SIOA_DAT .EQU SIOBASE + $04
SIOB_CMD .EQU SIOBASE + $07
SIOB_DAT .EQU SIOBASE + $05
#ENDIF #ENDIF
; ;
#IF (SIOMODE == SIOMODE_EZZ80) #IF (SIO0MODE == SIOMODE_RC)
SIOA_CMD .EQU SIOBASE + $01 SIO0A_CMD .EQU SIO0BASE + $00
SIOA_DAT .EQU SIOBASE + $00 SIO0A_DAT .EQU SIO0BASE + $01
SIOB_CMD .EQU SIOBASE + $03 SIO0B_CMD .EQU SIO0BASE + $02
SIOB_DAT .EQU SIOBASE + $02 SIO0B_DAT .EQU SIO0BASE + $03
#ENDIF #ENDIF
; ;
#IF (SIO0MODE == SIOMODE_SMB)
SIO0A_CMD .EQU SIO0BASE + $02
SIO0A_DAT .EQU SIO0BASE + $00
SIO0B_CMD .EQU SIO0BASE + $03
SIO0B_DAT .EQU SIO0BASE + $01
#ENDIF
;
#IF (SIO0MODE == SIOMODE_ZP)
SIO0A_CMD .EQU SIO0BASE + $06
SIO0A_DAT .EQU SIO0BASE + $04
SIO0B_CMD .EQU SIO0BASE + $07
SIO0B_DAT .EQU SIO0BASE + $05
#ENDIF
;
#IF (SIO0MODE == SIOMODE_EZZ80)
SIO0A_CMD .EQU SIO0BASE + $01
SIO0A_DAT .EQU SIO0BASE + $00
SIO0B_CMD .EQU SIO0BASE + $03
SIO0B_DAT .EQU SIO0BASE + $02
#ENDIF
;
#IF (SIOCNT >= 2)
;
#IF (SIO1MODE == SIOMODE_RC)
SIO1A_CMD .EQU SIO1BASE + $00
SIO1A_DAT .EQU SIO1BASE + $01
SIO1B_CMD .EQU SIO1BASE + $02
SIO1B_DAT .EQU SIO1BASE + $03
#ENDIF
;
#IF (SIO1MODE == SIOMODE_SMB)
SIO1A_CMD .EQU SIO1BASE + $02
SIO1A_DAT .EQU SIO1BASE + $00
SIO1B_CMD .EQU SIO1BASE + $03
SIO1B_DAT .EQU SIO1BASE + $01
#ENDIF
;
#IF (SIO1MODE == SIOMODE_ZP)
SIO1A_CMD .EQU SIO1BASE + $06
SIO1A_DAT .EQU SIO1BASE + $04
SIO1B_CMD .EQU SIO1BASE + $07
SIO1B_DAT .EQU SIO1BASE + $05
#ENDIF
;
#IF (SIO1MODE == SIOMODE_EZZ80)
SIO1A_CMD .EQU SIO1BASE + $01
SIO1A_DAT .EQU SIO1BASE + $00
SIO1B_CMD .EQU SIO1BASE + $03
SIO1B_DAT .EQU SIO1BASE + $02
#ENDIF
;
#ENDIF
;
; CONDITIONALS THAT DETERMINE THE ENCODED VALUE OF THE BAUD RATE ; CONDITIONALS THAT DETERMINE THE ENCODED VALUE OF THE BAUD RATE
; ;
#INCLUDE "siobaud.inc" #INCLUDE "siobaud.inc"
@@ -57,23 +110,15 @@ SIO_PREINIT:
; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMIAIN ; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMIAIN
; DISABLED. ; DISABLED.
; ;
LD B,SIO_CNT ; LOOP CONTROL CALL SIO_PROBE ; PROBE FOR CHIPS
LD C,0 ; PHYSICAL UNIT INDEX ;
LD B,SIO_CFGCNT ; LOOP CONTROL
XOR A ; ZERO TO ACCUM XOR A ; ZERO TO ACCUM
LD (SIO_DEV),A ; CURRENT DEVICE NUMBER LD (SIO_DEV),A ; CURRENT DEVICE NUMBER
LD IY,SIO_CFG ; POINT TO START OF CFG TABLE
SIO_PREINIT0: SIO_PREINIT0:
PUSH BC ; SAVE LOOP CONTROL PUSH BC ; SAVE LOOP CONTROL
LD A,C ; PHYSICAL UNIT TO A
RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES)
RLCA ; ...
RLCA ; ... TO GET OFFSET INTO CFG TABLE
LD HL,SIO_CFG ; POINT TO START OF CFG TABLE
CALL ADDHLA ; HL := ENTRY ADDRESS
PUSH HL ; SAVE IT
PUSH HL ; COPY CFG DATA PTR
POP IY ; ... TO IY
CALL SIO_INITUNIT ; HAND OFF TO GENERIC INIT CODE CALL SIO_INITUNIT ; HAND OFF TO GENERIC INIT CODE
POP DE ; GET ENTRY ADDRESS BACK, BUT PUT IN DE
POP BC ; RESTORE LOOP CONTROL POP BC ; RESTORE LOOP CONTROL
; ;
LD A,(IY+1) ; GET THE SIO TYPE DETECTED LD A,(IY+1) ; GET THE SIO TYPE DETECTED
@@ -81,16 +126,25 @@ SIO_PREINIT0:
JR Z,SIO_PREINIT2 ; SKIP IT IF NOTHING FOUND JR Z,SIO_PREINIT2 ; SKIP IT IF NOTHING FOUND
; ;
PUSH BC ; SAVE LOOP CONTROL PUSH BC ; SAVE LOOP CONTROL
PUSH IY ; CFG ENTRY ADDRESS
POP DE ; ... TO DE
LD BC,SIO_FNTBL ; BC := FUNCTION TABLE ADDRESS LD BC,SIO_FNTBL ; BC := FUNCTION TABLE ADDRESS
CALL NZ,CIO_ADDENT ; ADD ENTRY IF SIO FOUND, BC:DE CALL NZ,CIO_ADDENT ; ADD ENTRY IF SIO FOUND, BC:DE
POP BC ; RESTORE LOOP CONTROL POP BC ; RESTORE LOOP CONTROL
; ;
SIO_PREINIT2: SIO_PREINIT2:
INC C ; NEXT PHYSICAL UNIT LD DE,SIO_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,DE ; BUMP IY TO NEXT ENTRY
DJNZ SIO_PREINIT0 ; LOOP UNTIL DONE DJNZ SIO_PREINIT0 ; LOOP UNTIL DONE
; ;
#IF (INTMODE >= 1)
; SETUP INT VECTORS AS APPROPRIATE
LD A,(SIO_DEV) ; GET NEXT DEVICE NUM
OR A ; SET FLAGS
JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES, ABORT
;
#IF (INTMODE == 1) #IF (INTMODE == 1)
; ADD IM1 INT CALL LIST ENTRY IF APPROPRIATE ; ADD IM1 INT CALL LIST ENTRY
LD A,(SIO_DEV) ; GET NEXT DEVICE NUM LD A,(SIO_DEV) ; GET NEXT DEVICE NUM
OR A ; SET FLAGS OR A ; SET FLAGS
JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES
@@ -99,9 +153,17 @@ SIO_PREINIT2:
#ENDIF #ENDIF
; ;
#IF (INTMODE == 2) #IF (INTMODE == 2)
; SETUP SIO INTERRUPT VECTOR IN IVT ; SETUP IM2 VECTORS
LD HL,SIO_INT LD HL,SIO_INT0
LD (HB_IVT07 + 1),HL ; IVT INDEX 7 LD (SIO0_IVT + 1),HL ; IVT INDEX
;
#IF (SIOCNT >= 2)
LD HL,SIO_INT1
LD (SIO1_IVT + 1),HL ; IVT INDEX
#ENDIF
;
#ENDIF
;
#ENDIF #ENDIF
; ;
SIO_PREINIT3: SIO_PREINIT3:
@@ -131,26 +193,16 @@ SIO_INITUNIT:
; ;
; ;
SIO_INIT: SIO_INIT:
LD B,SIO_CNT ; COUNT OF POSSIBLE SIO UNITS LD B,SIO_CFGCNT ; COUNT OF POSSIBLE SIO UNITS
LD C,0 ; INDEX INTO SIO CONFIG TABLE LD IY,SIO_CFG ; POINT TO START OF CFG TABLE
SIO_INIT1: SIO_INIT1:
PUSH BC ; SAVE LOOP CONTROL PUSH BC ; SAVE LOOP CONTROL
LD A,C ; PHYSICAL UNIT TO A
RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES)
RLCA ; ...
RLCA ; ... TO GET OFFSET INTO CFG TABLE
LD HL,SIO_CFG ; POINT TO START OF CFG TABLE
CALL ADDHLA ; HL := ENTRY ADDRESS
PUSH HL ; COPY CFG DATA PTR
POP IY ; ... TO IY
LD A,(IY+1) ; GET SIO TYPE LD A,(IY+1) ; GET SIO TYPE
OR A ; SET FLAGS OR A ; SET FLAGS
CALL NZ,SIO_PRTCFG ; PRINT IF NOT ZERO CALL NZ,SIO_PRTCFG ; PRINT IF NOT ZERO
POP BC ; RESTORE LOOP CONTROL POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT UNIT LD DE,SIO_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,DE ; BUMP IY TO NEXT ENTRY
DJNZ SIO_INIT1 ; LOOP TILL DONE DJNZ SIO_INIT1 ; LOOP TILL DONE
; ;
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
@@ -160,96 +212,110 @@ SIO_INIT1:
; ;
#IF (INTMODE > 0) #IF (INTMODE > 0)
; ;
; IM0 ENTRY POINT
;
SIO_INT: SIO_INT:
SIOA_INT: ; CHECK/HANDLE FIRST CARD (SIO0) IF IT EXISTS
; CHECK FOR RECEIVE PENDING ON CHANNEL A LD A,(SIO0A_CFG + 1) ; GET SIO TYPE FOR FIRST CHANNEL OF FIRST SIO
OR A ; SET FLAGS
CALL NZ,SIO_INT0 ; CALL IF CARD EXISTS
RET NZ ; DONE IF INT HANDLED
;
#IF (SIOCNT >= 2)
; CHECK/HANDLE SECOND CARD (SIO1) IF IT EXISTS
LD A,(SIO1A_CFG + 1) ; GET SIO TYPE FOR FIRST CHANNEL OF SECOND SIO
OR A ; SET FLAGS
CALL NZ,SIO_INT1 ; CALL IF CARD EXISTS
#ENDIF
;
RET ; DONE
;
; IM1 ENTRY POINTS
;
SIO_INT0:
; INTERRUPT HANDLER FOR FIRST SIO (SIO0)
LD IY,SIO0A_CFG ; POINT TO SIO0A CFG
CALL SIO_INTRCV ; TRY TO RECEIVE FROM IT
RET NZ ; DONE IF INT HANDLED
LD IY,SIO0B_CFG ; POINT TO SIO0B CFG
JR SIO_INTRCV ; TRY TO RECEIVE FROM IT AND RETURN
;
#IF (SIOCNT >= 2)
;
SIO_INT1:
; INTERRUPT HANDLER FOR SECOND SIO (SIO1)
LD IY,SIO1A_CFG ; POINT TO SIO1A CFG
CALL SIO_INTRCV ; TRY TO RECEIVE FROM IT
RET NZ ; DONE IF INT HANDLED
LD IY,SIO1B_CFG ; POINT TO SIO1B CFG
JR SIO_INTRCV ; TRY TO RECEIVE FROM IT AND RETURN
;
#ENDIF
;
; HANDLE INT FOR A SPECIFIC CHANNEL
; BASED ON UNIT CFG POINTED TO BY IY
;
SIO_INTRCV:
; CHECK TO SEE IF SOMETHING IS ACTUALLY THERE
LD C,(IY+3) ; CMD/STAT PORT TO C
XOR A ; A := 0 XOR A ; A := 0
OUT (SIOA_CMD),A ; ADDRESS RD0 OUT (C),A ; ADDRESS RD0
IN A,(SIOA_CMD) ; GET RD0 IN A,(C) ; GET RD0
AND $01 ; ISOLATE RECEIVE READY BIT AND $01 ; ISOLATE RECEIVE READY BIT
JR Z,SIOB_INT ; CHECK CHANNEL B RET Z ; NOTHING AVAILABLE ON CURRENT CHANNEL
; ;
SIOA_INT00: SIO_INTRCV1:
; HANDLE CHANNEL A ; RECEIVE CHARACTER INTO BUFFER
IN A,(SIOA_DAT) ; READ PORT LD C,(IY+4) ; DATA PORT TO C
LD E,A ; SAVE BYTE READ IN A,(C) ; READ PORT
LD A,(SIOA_CNT) ; GET CURRENT BUFFER USED COUNT LD B,A ; SAVE BYTE READ
CP SIOA_BUFSZ ; COMPARE TO BUFFER SIZE LD L,(IY+7) ; SET HL TO
;RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED LD H,(IY+8) ; ... START OF BUFFER STRUCT
JR Z,SIOA_INT2 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED LD A,(HL) ; GET COUNT
CP SIO_BUFSZ ; COMPARE TO BUFFER SIZE
JR Z,SIO_INTRCV4 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
INC A ; INCREMENT THE COUNT INC A ; INCREMENT THE COUNT
LD (SIOA_CNT),A ; AND SAVE IT LD (HL),A ; AND SAVE IT
CP SIOA_BUFSZ / 2 ; BUFFER GETTING FULL? CP SIO_BUFSZ / 2 ; BUFFER GETTING FULL?
JR NZ,SIOA_INT0 ; IF NOT, BYPASS CLEARING RTS JR NZ,SIO_INTRCV2 ; IF NOT, BYPASS CLEARING RTS
LD C,(IY+3) ; CMD/STAT PORT TO C
LD A,5 ; RTS IS IN WR5 LD A,5 ; RTS IS IN WR5
OUT (SIOA_CMD),A ; ADDRESS WR5 OUT (C),A ; ADDRESS WR5
LD A,$E8 ; VALUE TO CLEAR RTS LD A,SIO_RTSOFF ; VALUE TO CLEAR RTS
OUT (SIOA_CMD),A ; DO IT OUT (C),A ; DO IT
SIOA_INT0: SIO_INTRCV2:
LD HL,(SIOA_HD) ; GET HEAD POINTER INC HL ; HL NOW HAS ADR OF HEAD PTR
LD A,L ; GET LOW BYTE PUSH HL ; SAVE ADR OF HEAD PTR
CP SIOA_BUFEND & $FF ; PAST END? LD A,(HL) ; DEREFERENCE HL
JR NZ,SIOA_INT1 ; IF NOT, BYPASS POINTER RESET INC HL
LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER LD H,(HL)
SIOA_INT1: LD L,A ; HL IS NOW ACTUAL HEAD PTR
LD A,E ; RECOVER BYTE READ LD (HL),B ; SAVE CHARACTER RECEIVED IN BUFFER AT HEAD
LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION INC HL ; BUMP HEAD POINTER
INC HL ; INCREMENT HEAD POINTER POP DE ; RECOVER ADR OF HEAD PTR
LD (SIOA_HD),HL ; SAVE IT LD A,L ; GET LOW BYTE OF HEAD PTR
; ADD A,-SIO_BUFSZ-4 ; SUBTRACT SIZE OF BUFFER AND POINTER
SIOA_INT2: CP E ; IF EQUAL TO START, HEAD PTR IS PAST BUF END
JR NZ,SIO_INTRCV3 ; IF NOT, BYPASS
LD H,D ; SET HL TO
LD L,E ; ... HEAD PTR ADR
INC HL ; BUMP PAST HEAD PTR
INC HL
INC HL
INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START
SIO_INTRCV3:
EX DE,HL ; DE := HEAD PTR VAL, HL := ADR OF HEAD PTR
LD (HL),E ; SAVE UPDATED HEAD PTR
INC HL
LD (HL),D
; CHECK FOR MORE PENDING... ; CHECK FOR MORE PENDING...
LD C,(IY+3) ; CMD/STAT PORT TO C
XOR A ; A := 0 XOR A ; A := 0
OUT (SIOA_CMD),A ; ADDRESS RD0 OUT (C),A ; ADDRESS RD0
IN A,(SIOA_CMD) ; GET RD0 IN A,(C) ; GET RD0
RRA ; READY BIT TO CF RRA ; READY BIT TO CF
JR C,SIOA_INT00 ; IF SET, DO SOME MORE JR C,SIO_INTRCV1 ; IF SET, DO SOME MORE
OR $FF ; NZ SET TO INDICATE INT HANDLED SIO_INTRCV4:
RET ; AND RETURN
;
SIOB_INT:
; CHECK FOR RECEIVE PENDING ON CHANNEL B
XOR A ; A := 0
OUT (SIOB_CMD),A ; ADDRESS RD0
IN A,(SIOB_CMD) ; GET RD0
AND $01 ; ISOLATE RECEIVE READY BIT
RET Z ; IF NOT, RETURN WITH Z SET
;
SIOB_INT00:
; HANDLE CHANNEL B
IN A,(SIOB_DAT) ; READ PORT
LD E,A ; SAVE BYTE READ
LD A,(SIOB_CNT) ; GET CURRENT BUFFER USED COUNT
CP SIOB_BUFSZ ; COMPARE TO BUFFER SIZE
;RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
JR Z,SIOB_INT2 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
INC A ; INCREMENT THE COUNT
LD (SIOB_CNT),A ; AND SAVE IT
CP SIOB_BUFSZ / 2 ; BUFFER GETTING FULL?
JR NZ,SIOB_INT0 ; IF NOT, BYPASS CLEARING RTS
LD A,5 ; RTS IS IN WR5
OUT (SIOB_CMD),A ; ADDRESS WR5
LD A,$E8 ; VALUE TO CLEAR RTS
OUT (SIOB_CMD),A ; DO IT
SIOB_INT0:
LD HL,(SIOB_HD) ; GET HEAD POINTER
LD A,L ; GET LOW BYTE
CP SIOB_BUFEND & $FF ; PAST END?
JR NZ,SIOB_INT1 ; IF NOT, BYPASS POINTER RESET
LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER
SIOB_INT1:
LD A,E ; RECOVER BYTE READ
LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION
INC HL ; INCREMENT HEAD POINTER
LD (SIOB_HD),HL ; SAVE IT
;
SIOB_INT2:
; CHECK FOR MORE PENDING...
XOR A ; A := 0
OUT (SIOB_CMD),A ; ADDRESS RD0
IN A,(SIOB_CMD) ; GET RD0
RRA ; READY BIT TO CF
JR C,SIOB_INT00 ; IF SET, DO SOME MORE
OR $FF ; NZ SET TO INDICATE INT HANDLED OR $FF ; NZ SET TO INDICATE INT HANDLED
RET ; AND RETURN RET ; AND RETURN
; ;
@@ -276,17 +342,7 @@ SIO_FNTBL:
SIO_IN: SIO_IN:
CALL SIO_IST ; CHAR WAITING? CALL SIO_IST ; CHAR WAITING?
JR Z,SIO_IN ; LOOP IF NOT JR Z,SIO_IN ; LOOP IF NOT
LD C,(IY+3) ; C := SIO CMD PORT LD C,(IY+4) ; DATA PORT
#IF (SIOMODE == SIOMODE_RC)
INC C ; BUMP TO DATA PORT
#ENDIF
#IF ((SIOMODE == SIOMODE_SMB) | (SIOMODE == SIOMODE_ZP))
DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT
DEC C
#ENDIF
#IF (SIOMODE == SIOMODE_EZZ80)
DEC C ; DECREMENT CMD PORT TO GET DATA PORT
#ENDIF
IN E,(C) ; GET CHAR IN E,(C) ; GET CHAR
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
@@ -294,68 +350,50 @@ SIO_IN:
#ELSE #ELSE
; ;
SIO_IN: SIO_IN:
LD A,(IY+2) ; GET CHANNEL CALL SIO_IST ; SEE IF CHAR AVAILABLE
OR A ; SET FLAGS JR Z,SIO_IN ; LOOP UNTIL SO
JR Z,SIOA_IN ; HANDLE CHANNEL A
DEC A ; TEST FOR NEXT DEVICE
JR Z,SIOB_IN ; HANDLE CHANNEL B
CALL PANIC ; ELSE FATAL ERROR
RET ; ... AND RETURN
;
SIOA_IN:
CALL SIOA_IST ; RECEIVED CHAR READY?
JR Z,SIOA_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER
HB_DI ; AVOID COLLISION WITH INT HANDLER HB_DI ; AVOID COLLISION WITH INT HANDLER
LD A,(SIOA_CNT) ; GET COUNT LD L,(IY+7) ; SET HL TO
LD H,(IY+8) ; ... START OF BUFFER STRUCT
LD A,(HL) ; GET COUNT
DEC A ; DECREMENT COUNT DEC A ; DECREMENT COUNT
LD (SIOA_CNT),A ; SAVE SAVE IT LD (HL),A ; SAVE UPDATED COUNT
CP 5 ; BUFFER LOW THRESHOLD CP SIO_BUFSZ / 4 ; BUFFER LOW THRESHOLD
JR NZ,SIOA_IN0 ; IF NOT, BYPASS SETTING RTS JR NZ,SIO_IN1 ; IF NOT, BYPASS SETTING RTS
LD C,(IY+3) ; C IS CMD/STATUS PORT ADR
LD A,5 ; RTS IS IN WR5 LD A,5 ; RTS IS IN WR5
OUT (SIOA_CMD),A ; ADDRESS WR5 OUT (C),A ; ADDRESS WR5
LD A,$EA ; VALUE TO SET RTS LD A,SIO_RTSON ; VALUE TO SET RTS
OUT (SIOA_CMD),A ; DO IT OUT (C),A ; DO IT
SIOA_IN0: SIO_IN1:
LD HL,(SIOA_TL) ; GET BUFFER TAIL POINTER INC HL
LD E,(HL) ; GET BYTE INC HL
INC HL ; BUMP TAIL POINTER INC HL ; HL NOW HAS ADR OF TAIL PTR
LD A,L ; GET LOW BYTE PUSH HL ; SAVE ADR OF TAIL PTR
CP SIOA_BUFEND & $FF ; PAST END? LD A,(HL) ; DEREFERENCE HL
JR NZ,SIOA_IN1 ; IF NOT, BYPASS POINTER RESET INC HL
LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER LD H,(HL)
SIOA_IN1: LD L,A ; HL IS NOW ACTUAL TAIL PTR
LD (SIOA_TL),HL ; SAVE UPDATED TAIL POINTER LD C,(HL) ; C := CHAR TO BE RETURNED
INC HL ; BUMP TAIL PTR
POP DE ; RECOVER ADR OF TAIL PTR
LD A,L ; GET LOW BYTE OF TAIL PTR
ADD A,-SIO_BUFSZ-2 ; SUBTRACT SIZE OF BUFFER AND POINTER
CP E ; IF EQUAL TO START, TAIL PTR IS PAST BUF END
JR NZ,SIO_IN2 ; IF NOT, BYPASS
LD H,D ; SET HL TO
LD L,E ; ... TAIL PTR ADR
INC HL ; BUMP PAST TAIL PTR
INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START
SIO_IN2:
EX DE,HL ; DE := TAIL PTR VAL, HL := ADR OF TAIL PTR
LD (HL),E ; SAVE UPDATED TAIL PTR
INC HL
LD (HL),D
LD E,C ; MOVE CHAR TO RETURN TO E
HB_EI ; INTERRUPTS OK AGAIN HB_EI ; INTERRUPTS OK AGAIN
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET ; AND DONE RET ; AND DONE
;
SIOB_IN:
CALL SIOB_IST ; RECEIVED CHAR READY?
JR Z,SIOB_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER
HB_DI ; AVOID COLLISION WITH INT HANDLER
LD A,(SIOB_CNT) ; GET COUNT
DEC A ; DECREMENT COUNT
LD (SIOB_CNT),A ; SAVE SAVE IT
CP 5 ; BUFFER LOW THRESHOLD
JR NZ,SIOB_IN0 ; IF NOT, BYPASS SETTING RTS
LD A,5 ; RTS IS IN WR5
OUT (SIOB_CMD),A ; ADDRESS WR5
LD A,$EA ; VALUE TO SET RTS
OUT (SIOB_CMD),A ; DO IT
SIOB_IN0:
LD HL,(SIOB_TL) ; GET BUFFER TAIL POINTER
LD E,(HL) ; GET BYTE
INC HL ; BUMP TAIL POINTER
LD A,L ; GET LOW BYTE
CP SIOB_BUFEND & $FF ; PAST END?
JR NZ,SIOB_IN1 ; IF NOT, BYPASS POINTER RESET
LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER
SIOB_IN1:
LD (SIOB_TL),HL ; SAVE UPDATED TAIL POINTER
HB_EI ; INTERRUPTS OK AGAIN
XOR A ; SIGNAL SUCCESS
RET ; AND DONE
;
#ENDIF #ENDIF
; ;
; ;
@@ -363,17 +401,7 @@ SIOB_IN1:
SIO_OUT: SIO_OUT:
CALL SIO_OST ; READY FOR CHAR? CALL SIO_OST ; READY FOR CHAR?
JR Z,SIO_OUT ; LOOP IF NOT JR Z,SIO_OUT ; LOOP IF NOT
LD C,(IY+3) ; C := SIO CMD PORT LD C,(IY+4) ; DATA PORT
#IF (SIOMODE == SIOMODE_RC)
INC C ; BUMP TO DATA PORT
#ENDIF
#IF ((SIOMODE == SIOMODE_SMB) | (SIOMODE == SIOMODE_ZP))
DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT
DEC C
#ENDIF
#IF (SIOMODE == SIOMODE_EZZ80)
DEC C ; DECREMENT CMD PORT TO GET DATA PORT
#ENDIF
OUT (C),E ; SEND CHAR FROM E OUT (C),E ; SEND CHAR FROM E
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
@@ -396,25 +424,12 @@ SIO_IST:
#ELSE #ELSE
; ;
SIO_IST: SIO_IST:
LD A,(IY+2) ; GET CHANNEL LD L,(IY+7) ; GET ADDRESS
OR A ; SET FLAGS LD H,(IY+8) ; ... OF RECEIVE BUFFER
JR Z,SIOA_IST ; HANDLE CHANNEL A LD A,(HL) ; BUFFER UTILIZATION COUNT
DEC A ; TEST FOR NEXT DEVICE
JR Z,SIOB_IST ; HANDLE CHANNEL B
CALL PANIC ; ELSE FATAL ERROR
RET ; ... AND RETURN
;
SIOA_IST:
LD A,(SIOA_CNT) ; GET BUFFER UTILIZATION COUNT
OR A ; SET FLAGS OR A ; SET FLAGS
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING
RET ; AND DONE RET
;
SIOB_IST:
LD A,(SIOB_CNT) ; GET BUFFER UTILIZATION COUNT
OR A ; SET FLAGS
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING
RET ; DONE
; ;
#ENDIF #ENDIF
; ;
@@ -461,8 +476,8 @@ SIO_INITDEVX:
JR NZ,SIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG JR NZ,SIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG
; ;
; LOAD EXISTING CONFIG TO REINIT ; LOAD EXISTING CONFIG TO REINIT
LD E,(IY+4) ; LOW BYTE LD E,(IY+5) ; LOW BYTE
LD D,(IY+5) ; HIGH BYTE LD D,(IY+6) ; HIGH BYTE
; ;
SIO_INITDEV1: SIO_INITDEV1:
PUSH DE ; SAVE CONFIG PUSH DE ; SAVE CONFIG
@@ -575,12 +590,37 @@ BROK:
CALL PRTHEXBYTE CALL PRTHEXBYTE
PRTC(']') PRTC(']')
POP AF POP AF
#ENDIF #ENDIF
;
; SET INTERRUPT VECTOR OFFSET WR2
;
#IF (INTMODE == 2)
LD A,(IY+2) ; CHIP / CHANNEL
SRL A ; SHIFT AWAY CHANNEL BIT
LD E,SIO0_VEC ; ASSUME CHIP 0
JR Z,SIO_IVT1 ; IF SO, DO IT
LD E,SIO1_VEC ; ASSUME CHIP 1
DEC A ; CHIP 1?
JR Z,SIO_IVT1 ; IF SO, TO IT
CALL PANIC ; IMPOSSIBLE SITUATION
SIO_IVT1:
LD A,E ; VALUE TO A
LD (SIO_INITVALS+7),A ; SAVE IT
#IF (SIODEBUG)
PUSH AF
PRTS(" WR2[$")
CALL PRTHEXBYTE
PRTC(']')
POP AF
#ENDIF
#ENDIF
POP DE ; RESTORE CONFIG POP DE ; RESTORE CONFIG
LD (IY+4),E ; SAVE LOW WORD LD (IY+5),E ; SAVE LOW WORD
LD (IY+5),D ; SAVE HI WORD LD (IY+6),D ; SAVE HI WORD
; ;
; PROGRAM THE SIO CHIP CHANNEL ; PROGRAM THE SIO CHIP CHANNEL
LD C,(IY+3) ; COMMAND PORT LD C,(IY+3) ; COMMAND PORT
@@ -591,8 +631,8 @@ BROK:
#IF (INTMODE > 0) #IF (INTMODE > 0)
; ;
; RESET THE RECEIVE BUFFER ; RESET THE RECEIVE BUFFER
LD E,(IY+6) LD E,(IY+7)
LD D,(IY+7) ; DE := _CNT LD D,(IY+8) ; DE := _CNT
XOR A ; A := 0 XOR A ; A := 0
LD (DE),A ; _CNT = 0 LD (DE),A ; _CNT = 0
INC DE ; DE := ADR OF _HD INC DE ; DE := ADR OF _HD
@@ -624,16 +664,16 @@ SIO_INITVALS:
#ELSE #ELSE
.DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS .DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS
#ENDIF #ENDIF
.DB $02, IVT_SER0 ; WR2: INTERRUPT VECTOR OFFSET .DB $02, IVT_SER0 ; WR2: IM2 INTERRUPT VECTOR OFFSET
.DB $03, $E1 ; WR3: 8 BIT RCV, CTS/DCD AUTO, RX ENABLE .DB $03, $E1 ; WR3: 8 BIT RCV, CTS/DCD AUTO, RX ENABLE
.DB $05, $EA ; WR5: DTR, 8 BITS SEND, TX ENABLE, RTS 1 11 0 1 0 1 0 (1=DTR,11=8bits,0=sendbreak,1=TxEnable,0=sdlc,1=RTS,0=txcrc) .DB $05, SIO_RTSON ; WR5: DTR, 8 BITS SEND, TX ENABLE, RTS 1 11 0 1 0 1 0 (1=DTR,11=8bits,0=sendbreak,1=TxEnable,0=sdlc,1=RTS,0=txcrc)
SIO_INITLEN .EQU $ - SIO_INITVALS SIO_INITLEN .EQU $ - SIO_INITVALS
; ;
; ;
; ;
SIO_QUERY: SIO_QUERY:
LD E,(IY+4) ; FIRST CONFIG BYTE TO E LD E,(IY+5) ; FIRST CONFIG BYTE TO E
LD D,(IY+5) ; SECOND CONFIG BYTE TO D LD D,(IY+6) ; SECOND CONFIG BYTE TO D
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET ; DONE RET ; DONE
; ;
@@ -646,21 +686,86 @@ SIO_DEVICE:
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
; ;
; SIO CHIP PROBE
; CHECK FOR PRESENCE OF SIO CHIPS AND POPULATE THE
; SIO_MAP BITMAP (ONE BIT PER CHIP). THIS DETECTS
; CHIPS, NOT CHANNELS. EACH CHIP HAS 2 CHANNELS.
; MAX OF TWO CHIPS CURRENTLY. INT VEC VALUE IS TRASHED!
;
SIO_PROBE:
; CLEAR THE PRESENCE BITMAP
LD HL,SIO_MAP ; HL POINTS TO BITMAP
XOR A ; ZERO
LD (SIO_MAP),A ; CLEAR CHIP PRESENT BITMAP
; INIT THE INT VEC REGISTER OF ALL POSSIBLE CHIPS
; TO ZERO. A IS STILL ZERO.
LD B,2 ; WR2 REGISTER (INT VEC)
LD C,SIO0B_CMD ; FIRST CHIP
CALL SIO_WR ; WRITE ZERO TO CHIP REG
#IF (SIOCNT >= 2)
LD C,SIO1B_CMD ; SECOND CHIP
CALL SIO_WR ; WRITE ZERO TO CHIP REG
#ENDIF
; FIRST POSSIBLE CHIP
LD C,SIO0B_CMD ; FIRST CHIP CMD/STAT PORT
CALL SIO_PROBECHIP ; PROBE IT
JR NZ,SIO_PROBE1 ; IF NOT ZERO, NOT FOUND
SET 0,(HL) ; SET BIT FOR FIRST CARD
SIO_PROBE1:
;
#IF (SIOCNT >= 2)
LD C,SIO1B_CMD ; SECOND CHIP CMD/STAT PORT
CALL SIO_PROBECHIP ; PROBE IT
JR NZ,SIO_PROBE2 ; IF NOT ZERO, NOT FOUND
SET 1,(HL) ; SET BIT FOR SECOND CARD
SIO_PROBE2:
#ENDIF
;
RET
;
SIO_PROBECHIP:
; READ WR2 TO ENSURE IT IS ZERO (AVOID PHANTOM PORTS)
CALL SIO_RD ; GET VALUE
AND $F0 ; ONLY TOP NIBBLE
RET NZ ; ABORT IF NOT ZERO
; WRITE INT VEC VALUE TO WR2
LD A,$FF ; TEST VALUE
CALL SIO_WR ; WRITE IT
; READ WR2 TO CONFIRM VALUE WRITTEN
CALL SIO_RD ; REREAD VALUE
AND $F0 ; ONLY TOP NIBBLE
CP $F0 ; COMPARE
RET ; DONE, Z IF FOUND, NZ IF MISCOMPARE
;
; READ/WRITE CHIP REGISTER. ENTER CHIP CMD/STAT PORT ADR IN C
; AND CHIP REGISTER NUMBER IN B. VALUE TO WRITE IN A OR VALUE
; RETURNED IN A.
;
SIO_WR:
OUT (C),B ; SELECT CHIP REGISTER
OUT (C),A ; WRITE VALUE
RET
;
SIO_RD:
OUT (C),B ; SELECT CHIP REGISTER
IN A,(C) ; GET VALUE
RET
;
; SIO DETECTION ROUTINE ; SIO DETECTION ROUTINE
; ;
SIO_DETECT: SIO_DETECT:
LD C,(IY+3) ; COMMAND PORT LD B,(IY+2) ; GET CHIP/CHANNEL
XOR A SRL B ; SHIFT AWAY THE CHANNEL BIT
OUT (C),A ; ACCESS RD0 INC B ; NUMBER OF TIMES TO ROTATE BITS
IN A,(C) ; GET RD0 VALUE LD A,(SIO_MAP) ; BIT MAP IN A
LD B,A ; SAVE IT SIO_DETECT1:
LD A,1 ; ROTATE DESIRED CHIP BIT INTO CF
OUT (C),A ; ACCESS RD1 RRA ; ROTATE NEXT BIT INTO CF
IN A,(C) ; GET RD1 VALUE DJNZ SIO_DETECT1 ; DO THIS UNTIL WE HAVE DESIRED BIT
CP B ; COMPARE ; RETURN CHIP TYPE
LD A,SIO_NONE ; ASSUME NOTHING THERE LD A,SIO_NONE ; ASSUME NOTHING HERE
RET Z ; RD0=RD1 MEANS NOTHING THERE RET NC ; IF CF NOT SET, RETURN
LD A,SIO_SIO ; GUESS WE HAVE A VALID SIO HERE LD A,SIO_SIO ; CHIP TYPE IS SIO
RET ; DONE RET ; DONE
; ;
; ;
@@ -692,8 +797,8 @@ SIO_PRTCFG:
RET Z ; IF ZERO, NOT PRESENT RET Z ; IF ZERO, NOT PRESENT
; ;
PRTS(" MODE=$") ; FORMATTING PRTS(" MODE=$") ; FORMATTING
LD E,(IY+4) ; LOAD CONFIG LD E,(IY+5) ; LOAD CONFIG
LD D,(IY+5) ; ... WORD TO DE LD D,(IY+6) ; ... WORD TO DE
CALL PS_PRTSC0 ; PRINT CONFIG CALL PS_PRTSC0 ; PRINT CONFIG
; ;
XOR A XOR A
@@ -711,51 +816,101 @@ SIO_STR_SIO .DB "SIO$"
; WORKING VARIABLES ; WORKING VARIABLES
; ;
SIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT SIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT
SIO_MAP .DB 0 ; CHIP PRESENCE BITMAP
; ;
#IF (INTMODE == 0) #IF (INTMODE == 0)
; ;
SIOA_RCVBUF .EQU 0 SIO0A_RCVBUF .EQU 0
SIOB_RCVBUF .EQU 0 SIO0B_RCVBUF .EQU 0
;
#IF (SIOCNT >= 2)
SIO1A_RCVBUF .EQU 0
SIO1B_RCVBUF .EQU 0
#ENDIF
; ;
#ELSE #ELSE
; ;
; CHANNEL A RECEIVE BUFFER ; SIO0 CHANNEL A RECEIVE BUFFER
SIOA_RCVBUF: SIO0A_RCVBUF:
SIOA_CNT .DB 0 ; CHARACTERS IN RING BUFFER SIO0A_CNT .DB 0 ; CHARACTERS IN RING BUFFER
SIOA_HD .DW SIOA_BUF ; BUFFER HEAD POINTER SIO0A_HD .DW SIO0A_BUF ; BUFFER HEAD POINTER
SIOA_TL .DW SIOA_BUF ; BUFFER TAIL POINTER SIO0A_TL .DW SIO0A_BUF ; BUFFER TAIL POINTER
SIOA_BUF .FILL 32,0 ; RECEIVE RING BUFFER SIO0A_BUF .FILL SIO_BUFSZ,0 ; RECEIVE RING BUFFER
SIOA_BUFEND .EQU $ ; END OF BUFFER
SIOA_BUFSZ .EQU $ - SIOA_BUF ; SIZE OF RING BUFFER
; ;
; CHANNEL B RECEIVE BUFFER ; SIO0 CHANNEL B RECEIVE BUFFER
SIOB_RCVBUF: SIO0B_RCVBUF:
SIOB_CNT .DB 0 ; CHARACTERS IN RING BUFFER SIO0B_CNT .DB 0 ; CHARACTERS IN RING BUFFER
SIOB_HD .DW SIOB_BUF ; BUFFER HEAD POINTER SIO0B_HD .DW SIO0B_BUF ; BUFFER HEAD POINTER
SIOB_TL .DW SIOB_BUF ; BUFFER TAIL POINTER SIO0B_TL .DW SIO0B_BUF ; BUFFER TAIL POINTER
SIOB_BUF .FILL 32,0 ; RECEIVE RING BUFFER SIO0B_BUF .FILL SIO_BUFSZ,0 ; RECEIVE RING BUFFER
SIOB_BUFEND .EQU $ ; END OF BUFFER ;
SIOB_BUFSZ .EQU $ - SIOB_BUF ; SIZE OF RING BUFFER #IF (SIOCNT >= 2)
;
; SIO1 CHANNEL A RECEIVE BUFFER
SIO1A_RCVBUF:
SIO1A_CNT .DB 0 ; CHARACTERS IN RING BUFFER
SIO1A_HD .DW SIO1A_BUF ; BUFFER HEAD POINTER
SIO1A_TL .DW SIO1A_BUF ; BUFFER TAIL POINTER
SIO1A_BUF .FILL SIO_BUFSZ,0 ; RECEIVE RING BUFFER
;
; SIO1 CHANNEL B RECEIVE BUFFER
SIO1B_RCVBUF:
SIO1B_CNT .DB 0 ; CHARACTERS IN RING BUFFER
SIO1B_HD .DW SIO1B_BUF ; BUFFER HEAD POINTER
SIO1B_TL .DW SIO1B_BUF ; BUFFER TAIL POINTER
SIO1B_BUF .FILL SIO_BUFSZ,0 ; RECEIVE RING BUFFER
;
#ENDIF
; ;
#ENDIF #ENDIF
; ;
; SIO PORT TABLE ; SIO PORT TABLE
; ;
SIO_CFG: SIO_CFG:
; SIO CHANNEL A ; SIO0 CHANNEL A
SIO0A_CFG:
.DB 0 ; DEVICE NUMBER (SET DURING INIT) .DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; SIO TYPE (SET DURING INIT) .DB 0 ; SIO TYPE (SET DURING INIT)
.DB 0 ; SIO CHANNEL (A) .DB $00 ; CHIP 0 / CHANNEL A (LOW BIT IS CHANNEL)
.DB SIOA_CMD ; BASE PORT (CMD PORT) .DB SIO0A_CMD ; CMD/STATUS PORT
.DW DEFSIOACFG ; LINE CONFIGURATION .DB SIO0A_DAT ; DATA PORT
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT .DW DEFSIO0ACFG ; LINE CONFIGURATION
.DW SIO0A_RCVBUF ; POINTER TO RCV BUFFER STRUCT
; ;
; SIO CHANNEL B SIO_CFGSIZ .EQU $ - SIO_CFG ; SIZE OF ONE CFG TABLE ENTRY
;
; SIO0 CHANNEL B
SIO0B_CFG:
.DB 0 ; DEVICE NUMBER (SET DURING INIT) .DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; SIO TYPE (SET DURING INIT) .DB 0 ; SIO TYPE (SET DURING INIT)
.DB 1 ; SIO CHANNEL (B) .DB $01 ; CHIP 0 / CHANNEL B (LOW BIT IS CHANNEL)
.DB SIOB_CMD ; BASE PORT (CMD PORT) .DB SIO0B_CMD ; CMD/STATUS PORT
.DW DEFSIOBCFG ; LINE CONFIGURATION .DB SIO0B_DAT ; DATA PORT
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT .DW DEFSIO0BCFG ; LINE CONFIGURATION
.DW SIO0B_RCVBUF ; POINTER TO RCV BUFFER STRUCT
; ;
SIO_CNT .EQU ($ - SIO_CFG) / 8 #IF (SIOCNT >= 2)
;
; SIO1 CHANNEL A
SIO1A_CFG:
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; SIO TYPE (SET DURING INIT)
.DB $02 ; CHIP 1 / CHANNEL A (LOW BIT IS CHANNEL)
.DB SIO1A_CMD ; CMD/STATUS PORT
.DB SIO1A_DAT ; DATA PORT
.DW DEFSIO1ACFG ; LINE CONFIGURATION
.DW SIO1A_RCVBUF ; POINTER TO RCV BUFFER STRUCT
;
; SIO1 CHANNEL B
SIO1B_CFG:
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; SIO TYPE (SET DURING INIT)
.DB $03 ; CHIP 1 / CHANNEL B (LOW BIT IS CHANNEL)
.DB SIO1B_CMD ; CMD/STATUS PORT
.DB SIO1B_DAT ; DATA PORT
.DW DEFSIO1BCFG ; LINE CONFIGURATION
.DW SIO1B_RCVBUF ; POINTER TO RCV BUFFER STRUCT
;
#ENDIF
;
SIO_CFGCNT .EQU ($ - SIO_CFG) / SIO_CFGSIZ

View File

@@ -9,7 +9,7 @@ SPK_INIT:
LD A,DSRTC_BASE LD A,DSRTC_BASE
CALL PRTHEXBYTE CALL PRTHEXBYTE
CALL SPK_BEEP CALL SPK_BEEP
XOR A XOR A
RET RET
; ;
SPK_BEEP: SPK_BEEP:
@@ -17,7 +17,8 @@ SPK_BEEP:
PUSH HL PUSH HL
LD HL,400 ; CYCLES OF TONE LD HL,400 ; CYCLES OF TONE
;LD B,%00000100 ; D2 MAPPED TO Q0 ;LD B,%00000100 ; D2 MAPPED TO Q0
LD A,DSRTC_RESET ;LD A,DSRTC_RESET
LD A,(RTCVAL) ; GET RTC PORT VALUE FROM SHADOW
OR %00000100 ; D2 MAPPED TO Q0 OR %00000100 ; D2 MAPPED TO Q0
LD B,A LD B,A
SPK_BEEP1: SPK_BEEP1: