From 2d12da4903be3d92292e63d6ce07a259b254106b Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Wed, 27 Jan 2021 19:33:37 -0800 Subject: [PATCH] Z280 Internal UART Support Z280 UART can only be used w/ native memory & interrupt mode 3. --- Binary/RomList.txt | 26 +- Doc/ChangeLog.txt | 2 + Source/HBIOS/Config/RCZ280_nat.asm | 1 + Source/HBIOS/cfg_dyno.asm | 2 + Source/HBIOS/cfg_ezz80.asm | 2 + Source/HBIOS/cfg_master.asm | 4 + Source/HBIOS/cfg_mk4.asm | 2 + Source/HBIOS/cfg_n8.asm | 2 + Source/HBIOS/cfg_rcz180.asm | 2 + Source/HBIOS/cfg_rcz280.asm | 4 + Source/HBIOS/cfg_rcz80.asm | 2 + Source/HBIOS/cfg_sbc.asm | 2 + Source/HBIOS/cfg_scz180.asm | 2 + Source/HBIOS/cfg_zeta.asm | 2 + Source/HBIOS/cfg_zeta2.asm | 2 + Source/HBIOS/hbios.asm | 192 +++++++--- Source/HBIOS/hbios.inc | 1 + Source/HBIOS/sio.asm | 2 +- Source/HBIOS/z280.inc | 27 +- Source/HBIOS/z2u.asm | 561 +++++++++++++++++++++++++++++ Source/ver.inc | 2 +- Source/ver.lib | 2 +- 22 files changed, 778 insertions(+), 66 deletions(-) create mode 100644 Source/HBIOS/z2u.asm diff --git a/Binary/RomList.txt b/Binary/RomList.txt index 50474f65..02ca2f53 100644 --- a/Binary/RomList.txt +++ b/Binary/RomList.txt @@ -189,7 +189,6 @@ RCZ180 (RCZ180_nat.rom & RCZ180_ext.rom): video, keyboard and SD Card support if present. RCZ280 (RCZ280_ext.rom): - *** Experimental *** - Assumes CPU oscillator of 24 MHz - Bus clock will be 6 MHz, so does not match RC2014 standard!!! - Requires 512K RAM/ROM module @@ -208,12 +207,31 @@ RCZ280 (RCZ280_ext.rom): enabled, will auto-detect and install associated video, keyboard and SD Card support if present. -SCZ180 (SCZ180_126.rom, SCZ180_130.rom, SCZ180_131.rom): +RCZ280 (RCZ280_nat.rom): + - Assumes CPU oscillator of 24 MHz + - Bus clock will be 6 MHz, so does not match RC2014 standard!!! + - Requires native RAM/ROM module (linear memory) + - Interrupt Mode 3 only (no ACIA support possible) + - Auto detects Dual Serial Module (SIO/2), and EP Dual UART. + - Console on whichever serial module is installed, + order of priority is UART, then SIO. + - Baud rate is determined by hardware, but normally 115200. + - Auto support for RC2014 Compact Flash Module + - Auto support for RC2014 PPIDE Module + - Support for Scott Baker SIO board may be enabled in config + - Support for Scott Baker floppy controllers (SMC & WDC) may + be enabled in config + - Support for J.B. Lang TMS9918 video card may be enabled in config + - Support for PropIO V2 may be enabled in config (PRPENABLE). If + enabled, will auto-detect and install associated + video, keyboard and SD Card support if present. + +SCZ180 (SCZ180_126.rom, SCZ180_130.rom, SCZ180_131.rom, SCZ140.rom): - Same as RCZ180 - Adds auto support for SPI SD Card - The 3 different variants of SCZ180 are provided to match the - 3 corresponding systems (SC126, SC130, and SC131) designed by - Stephen Cousins. + 3 corresponding systems (SC126, SC130, SC131, and SC140) + designed by Stephen Cousins. - Support for PropIO V2 may be enabled in config (PRPENABLE). If enabled, will auto-detect and install associated video, keyboard and SD Card support if present. diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index a978dd4a..a65e6837 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -14,6 +14,8 @@ Version 3.1.1 - PMS: Preliminary support for writing to FLASH ROMs - PMS: Creation of process to update ROM system area w/o updating ROM disk contents - PMS: Added "updater.asm" which allows uploading and updating ROM in one step +- WBW: Support for Z280 w/ native memory and interrupt mode 3 +- WBW: Support for Z280 UART (only for interrupt mode 3) Version 3.1 ----------- diff --git a/Source/HBIOS/Config/RCZ280_nat.asm b/Source/HBIOS/Config/RCZ280_nat.asm index 5a3a7555..1459c043 100644 --- a/Source/HBIOS/Config/RCZ280_nat.asm +++ b/Source/HBIOS/Config/RCZ280_nat.asm @@ -38,6 +38,7 @@ Z280_MEMWAIT .SET 0 ; Z280: MEMORY WAIT STATES (0-3) Z280_IOWAIT .SET 1 ; Z280: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3) Z280_INTWAIT .SET 0 ; Z280: INT ACK WAIT STATUS (0-3) ; +Z2UENABLE .SET TRUE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 84d6c6de..fa112c85 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -85,6 +85,8 @@ ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_ezz80.asm b/Source/HBIOS/cfg_ezz80.asm index b545f425..fc2e29e5 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -99,6 +99,8 @@ UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index 41001df5..aec799d8 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -129,6 +129,10 @@ ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +Z2U0BASE .EQU $10 ; Z2U 0: BASE I/O ADDRESS +Z2U0CFG .EQU DEFSERCFG ; Z2U 0: SERIAL LINE CONFIG +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT ACIACNT .EQU 1 ; ACIA: NUMBER OF CHIPS TO DETECT (1-2) diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index d22df261..1b6796a8 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -100,6 +100,8 @@ ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index ba20d707..c612c8dc 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -103,6 +103,8 @@ ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index bbc0dddc..e05513a8 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -102,6 +102,8 @@ ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_rcz280.asm b/Source/HBIOS/cfg_rcz280.asm index a620c197..29e5b669 100644 --- a/Source/HBIOS/cfg_rcz280.asm +++ b/Source/HBIOS/cfg_rcz280.asm @@ -102,6 +102,10 @@ UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +Z2U0BASE .EQU $10 ; Z2U 0: BASE I/O ADDRESS +Z2U0CFG .EQU DEFSERCFG ; Z2U 0: SERIAL LINE CONFIG +; ACIAENABLE .EQU TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT ACIACNT .EQU 1 ; ACIA: NUMBER OF CHIPS TO DETECT (1-2) diff --git a/Source/HBIOS/cfg_rcz80.asm b/Source/HBIOS/cfg_rcz80.asm index 9fb0f401..6430151c 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -98,6 +98,8 @@ UARTRC .EQU TRUE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT ACIACNT .EQU 1 ; ACIA: NUMBER OF CHIPS TO DETECT (1-2) diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index babfb669..b8dc97f0 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -94,6 +94,8 @@ UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index ff392d0b..af6b4b3e 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -97,6 +97,8 @@ ASCISWAP .EQU FALSE ; ASCI: SWAP CHANNELS ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index b05e3e18..026e471e 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -82,6 +82,8 @@ UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index 4c72a4db..9e7a447c 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -93,6 +93,8 @@ UARTRC .EQU FALSE ; UART: AUTO-DETECT RC UART ; ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM) ; +Z2UENABLE .EQU FALSE ; Z2U: ENABLE Z280 UART SERICAL DRIVER (Z2U.ASM) +; ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) ; SIOENABLE .EQU FALSE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 6f19af58..bd9bf181 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -115,12 +115,23 @@ MODCNT .SET MODCNT + 1 ; NO INTERRUPT HANDLING #DEFINE HB_DI ; #DEFINE HB_EI ; -#ENDIF -#IF ((INTMODE == 1) | (INTMODE == 2) | (INTMODE == 3)) -; MODE 1 OR 2 OR 3 INTERRUPT HANDLING +#ELSE + #IF (CPUFAM == CPU_Z280) + #IF (INTMODE == 3) +; Z280 MODE 3 INTERRUPT HANDLING (INTA & UART ENABLED) +#DEFINE HB_DI DI +#DEFINE HB_EI .DB $ED,$F7,$09 + #ELSE +; Z280 MODE 1/2 INTERRUPT HANDLING #DEFINE HB_DI DI #DEFINE HB_EI EI + #ENDIF + #ELSE +#DEFINE HB_DI DI +#DEFINE HB_EI EI + #ENDIF #ENDIF +; #IF (INTMODE > 3) .ECHO "*** ERROR: INVALID INTMODE SETTING!!!\n" !!! ; FORCE AN ASSEMBLY ERROR @@ -300,10 +311,7 @@ HBX_IDENT: ; ACCOMMODATE FREERTOS. HBX_BUF IS ONLY USED AS A BOUNCE BUFFER, SO IT'S ; USE WILL NEVER OVERLAP WITH BELOW. ; -; HBX_INVOKE IS NOT RE-ENTRANT! HB_INVBNK CAN BE USED GLOBALLY TO DETERMINE -; IF HBIOS IS ALREADY ACTIVE. HB_INVBNK WILL HAVE A VALUE != $FF WHEN HBIOS -; IS ACTIVE. ON RETURN, HB_INVBNK IS SET TO $FF TO INDICATE HBIOS IS NOT -; ACTIVE. +; WARNING: HBX_INVOKE IS *NOT* REENTRANT! ; HBX_INVOKE: @@ -500,10 +508,10 @@ HBX_BNKCPY: .DB $ED,$66 ; LDCTL HL,(C) POP BC EX (SP),HL - DI + HB_DI #ELSE LD A,I - DI + HB_DI PUSH AF #ENDIF LD (HBX_BC_SP),SP ; PUT STACK @@ -545,7 +553,7 @@ HBX_BC_SP .EQU $ - 2 ; ... TO ORIGINAL VALUE #ELSE POP AF JP PO,$+4 - EI + HB_EI #ENDIF RET ; @@ -576,6 +584,48 @@ HBX_BC_ITER: ; ON INPUT A=TARGET BANK, IX=TARGET ADDRESS ; HBX_BNKCALL: +; +#IF (MEMMGR == MM_Z280) + JR HBX_BNKCALL2 + + CP BID_BIOS ; CALLING HBIOS? + JR NZ,HBX_BNKCALL2 ; NOPE, DO NORMAL PROCESSING + + ;PUSH AF + ;LD A,'[' + ;.DB $ED,$71 ; SC + ;.DW COUT ; SC PARAMETER + ;POP AF + + ; + ;LD A,(HB_CURBNK) ; GET CURRENT BANK + ;LD (HB_INVBNK),A ; SAVE INVOCATION BANK + ; + ;LD A,BID_BIOS ; HBIOS BANK + ;LD (HB_CURBNK),A ; SET AS CURRENT BANK + + LD (HBX_BNKCALL1+2),IX ; SETUP TARGET ADDRESS +HBX_BNKCALL1: + .DB $ED,$71 ; SC + .DW $FFFF ; SC PARAMETER (SET ABOVE) + + ;PUSH AF + ;LD A,']' + ;.DB $ED,$71 ; SC + ;.DW COUT ; SC PARAMETER + ;POP AF + + ;PUSH AF + ;LD A,(HB_INVBNK) + ;LD (HB_CURBNK),A + ;POP AF + + + + RET +#ENDIF + +HBX_BNKCALL2: LD (HBX_TGTBNK),A ; STUFF TARGET BANK TO CALL INTO CODE BELOW LD (HBX_TGTADR),IX ; STUFF ADDRESS TO CALL INTO CODE BELOW LD A,(HB_CURBNK) ; GET CURRENT BANK @@ -956,7 +1006,7 @@ HB_START: ; INITIALIZE MMU ; START BY SELECTING I/O PAGE $FF LD L,$FF ; MMU AND DMA PAGE I/O REG IS $FF - LD C,$08 ; REG C POINTS TO I/O PAGE REGISTER + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER .DB $ED,$6E ; LDCTL (C),HL ; ; INITIALIZE ALL OF THE SYSTEM PAGE DESCRIPTORS WITH BLOCK MOVE @@ -979,13 +1029,18 @@ HB_START: LD C,Z280_MMUMCR ; MMU MASTER CONTROL REGISTER LD HL,$BBFF ; ENABLE USER & SYSTEM TRANSLATE .DB $ED,$BF ; OUTW (C),HL -; +; + ; DISABLE MEMORY REFRESH CYCLES + LD A,$08 ; DISABLED + OUT (Z280_RRR),A ; SET REFRESH RATE REGISTER + ; RESTORE I/O PAGE TO $00 LD L,$00 ; NORMAL I/O REG IS $00 - LD C,$08 ; REG C POINTS TO I/O PAGE REGISTER + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER .DB $ED,$6E ; LDCTL (C),HL ; ; CONFIGURE Z280 INT/TRAP VECTOR TABLE POINTER REGISTER + ; WILL POINT TO ROM COPY FOR NOW, UPDATED TO RAM LATER ON LD C,Z280_VPR LD HL,Z280_IVT >> 8 ; TOP 16 BITS OF PHYSICAL ADR OF IVT .DB $ED,$6E ; LDCTL (C),HL @@ -2037,6 +2092,9 @@ HB_PCINITTBL: #IF (ACIAENABLE) .DW ACIA_PREINIT #ENDIF +#IF (Z2UENABLE) + .DW Z2U_PREINIT +#ENDIF #IF (PIO_4P | PIO_ZP) .DW PIO_PREINIT #ENDIF @@ -2080,6 +2138,9 @@ HB_INITTBL: #IF (ACIAENABLE) .DW ACIA_INIT #ENDIF +#IF (Z2UENABLE) + .DW Z2U_INIT +#ENDIF #IF (DSRTCENABLE) .DW DSRTC_INIT #ENDIF @@ -3189,7 +3250,7 @@ SYS_PEEK: LD C,Z280_MSR .DB $FD,$ED,$66 ; LDCTL IY,(C) PUSH IY - DI + HB_DI #ELSE LD A,I DI @@ -3206,7 +3267,7 @@ SYS_PEEK: #ELSE POP AF JP PO,$+4 - EI + HB_EI #ENDIF #ENDIF XOR A @@ -3226,10 +3287,10 @@ SYS_POKE: LD C,Z280_MSR .DB $FD,$ED,$66 ; LDCTL IY,(C) PUSH IY - DI + HB_DI #ELSE LD A,I - DI + HB_DI PUSH AF #ENDIF #ENDIF @@ -3243,7 +3304,7 @@ SYS_POKE: #ELSE POP AF JP PO,$+4 - EI + HB_EI #ENDIF #ENDIF XOR A @@ -3495,63 +3556,65 @@ Z280_BADINTSTR .TEXT "\n\n*** Z280 BAD INT @$" #IF (MEMMGR == MM_Z280) ; Z280_PRIVINST: + ; SAVE HL AND MSR FOR POSSIBLE RETURN VIA RETIL EX (SP),HL ; GET MSR, SAVE HL LD (HB_MSRSAV),HL ; SAVE IT POP HL ; RECOVER HL, POP STACK EX (SP),HL ; GET ADR, SAVE HL - +; PUSH AF PUSH BC PUSH DE - +; .DB $ED,$96 ; LDUP A,(HL) - INC HL ; BUMP PAST PRIV INST ;CALL PC_LBKT ;CALL PRTHEXBYTE ;CALL PC_RBKT - +; ; HANDLE DI CP $F3 ; DI? JR NZ,Z280_PRIVINST2 - DI ; DO THE DI + HB_DI ; DO THE DI + INC HL ; BUMP PAST IT JR Z280_PRIVINSTX - +; Z280_PRIVINST2: ; HANDLE EI CP $FB ; EI? - JR NZ,Z280_PRIVINST_HALT - EI ; DO THE EI + JR NZ,Z280_PRIVINST3 + HB_EI ; DO THE EI + INC HL ; BUMP PAST IT JR Z280_PRIVINSTX - -Z280_PRIVINST_HALT: +; +Z280_PRIVINST3: ; SOMETHING ELSE, DIAGNOSE & HALT SYSTEM - - PUSH HL + LD DE,Z280_PRIVSTR + CALL WRITESTR + CALL PRTHEXWORDHL +; + ; DUMP 16 BYTES OF USER ADDRESS SPACE + CALL PC_SPACE CALL PC_LBKT - CALL PRTHEXBYTE + LD B,$10 +Z280_PRIVINST4: .DB $ED,$96 ; LDUP A,(HL) CALL PRTHEXBYTE INC HL - .DB $ED,$96 ; LDUP A,(HL) - CALL PRTHEXBYTE + DJNZ Z280_PRIVINST4 CALL PC_RBKT - POP HL - - CALL NEWLINE - LD DE,Z280_PRIVSTR - CALL WRITESTR - DEC HL - CALL PRTHEXWORDHL - +; + ; GO NO FURTHER DI HALT - -Z280_PRIVINSTX: +; +Z280_PRIVINSTX: + ; RESTORE REGISTERS POP DE POP BC POP AF - +; + ; RECOVER HL AND MSR, THEN RETURN VIA RETIL EX (SP),HL ; RECOVER HL, ADR TO STK PUSH HL ; SAVE HL LD HL,(HB_MSRSAV) ; GET SAVED MSR @@ -3560,7 +3623,7 @@ Z280_PRIVINSTX: ; HB_MSRSAV .DW 0 ; -Z280_PRIVSTR .TEXT "\n\n*** Privileged Instruction @$" +Z280_PRIVSTR .TEXT "\r\n\r\n*** Privileged Instruction @$" ; #ENDIF ; @@ -3737,7 +3800,7 @@ HB_TMPREF .DW 0 ; Z280 INTERRUPT VECTOR TABLE ;================================================================================================== ; -#IF (MEMMGR = MM_Z280) +#IF (MEMMGR == MM_Z280) ; .FILL $1000 - ($ & $FFF) ; MUST BE 4K ALIGNED! ; @@ -3834,19 +3897,17 @@ Z280_BNKSEL: LD C,Z280_IOPR ; I/O PAGE REGISTER TO C .DB $ED,$6E ; LDCTL (C),HL ; - ; POINT HL TO PORTION OF TABLE TO PROGRAM PDRS WITH - LD HL,Z280_PDRTBL ; POINT TO PDR TABLE - SLA A ; BANK ID TIMES TWO, RAM BIT TO C - JR NC,Z280_BNKSEL1 ; IF ROM, SKIP AHEAD - INC H ; HANDLE RAM OFFSET + ; POINT HL TO STARTING ENTRY TO PROGRAM + ; OPTIMIZED TO ASSUME HL IS PAGE ALIGNED! + LD H,Z280_PDRTBL >> 8 + SLA A + JR NC,Z280_BNKSEL1 + INC H Z280_BNKSEL1: RLCA RLCA RLCA - ADD A,L LD L,A - JR NC,Z280_BNKSEL2 ; NO CARRY, SKIP AHEAD - INC H ; HANDLE CARRY ; Z280_BNKSEL2: ; POINT TO FIRST PDR TO PROGRAM ($00=USER, $10=SYSTEM) @@ -3867,6 +3928,11 @@ Z280_BNKSEL2: POP BC RET ; +#IF (($ & $FF) != 0) + ; PAGE ALIGN THE TABLE + .FILL $100 - ($ & $FF) +#ENDIF +; #IF (($ % 2) == 1) ; BYTE ALIGN THE TABLE .DB 0 @@ -4172,7 +4238,7 @@ Z280_BNKSEL: PUSH DE PUSH BC LD L,$FF ; MMU PAGE I/O REG IS $FF - LD C,8 ; REG C POINTS TO I/O PAGE REGISTER + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER .DB $ED,$6E ; OP CODE FOR LDCTL (C),HL LD E,0 ; DE IS TEMPLATE BIT 7,A @@ -4236,7 +4302,7 @@ W_MMU1: W_MMU2: ;.DB $ED,$65 ; PCACHE LD L,0 ; RESTORE I/O PAGE REG TO 0 - LD C,8 + LD C,Z280_IOPR .DB $ED,$6E ; LDCTL (C),HL POP BC POP DE @@ -4453,6 +4519,15 @@ SIZ_ACIA .EQU $ - ORG_ACIA .ECHO " bytes.\n" #ENDIF ; +#IF (Z2UENABLE) +ORG_Z2U .EQU $ + #INCLUDE "z2u.asm" +SIZ_Z2U .EQU $ - ORG_Z2U + .ECHO "Z2U occupies " + .ECHO SIZ_Z2U + .ECHO " bytes.\n" +#ENDIF +; #IF (VGAENABLE) ORG_VGA .EQU $ #INCLUDE "vga.asm" @@ -5483,8 +5558,8 @@ PS_FLP_DSTR: .TEXT "SD$" ; PS_FLPSD ; CHARACTER DEVICE STRINGS ; PS_SDSTRREF: - .DW PS_SDUART, PS_SDASCI, PS_SDTERM - .DW PS_SDPRPCON, PS_SDPPPCON, PS_SDSIO, PS_SDACIA, PS_SDPIO,PS_SDUF,PS_SDDUART + .DW PS_SDUART, PS_SDASCI, PS_SDTERM, PS_SDPRPCON, PS_SDPPPCON + .DW PS_SDSIO, PS_SDACIA, PS_SDPIO, PS_SDUF, PS_SDDUART, PS_SDZ2U ; PS_SDUART .TEXT "UART$" PS_SDASCI .TEXT "ASCI$" @@ -5496,6 +5571,7 @@ PS_SDACIA .TEXT "ACIA$" PS_SDPIO .TEXT "PORT$" PS_SDUF .TEXT "UF$" PS_SDDUART .TEXT "DUART$" +PS_SDZ2U .TEXT "Z2U$" ; ; CHARACTER SUB TYPE STRINGS ; diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 2457bc9c..bdee24ed 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -161,6 +161,7 @@ CIODEV_ACIA .EQU $60 CIODEV_PIO .EQU $70 CIODEV_UF .EQU $80 CIODEV_DUART .EQU $90 +CIODEV_Z2U .EQU $A0 ; ; SUB TYPES OF CHAR DEVICES ; diff --git a/Source/HBIOS/sio.asm b/Source/HBIOS/sio.asm index aeb12f08..5a013853 100644 --- a/Source/HBIOS/sio.asm +++ b/Source/HBIOS/sio.asm @@ -145,7 +145,7 @@ SIO_PREINIT2: #ENDIF ; #IF ((INTMODE == 2) | (INTMODE == 3)) - ; SETUP IM2 VECTORS + ; SETUP IM2/3 VECTORS LD HL,SIO_INT0 LD (SIO0_IVT),HL ; IVT INDEX ; diff --git a/Source/HBIOS/z280.inc b/Source/HBIOS/z280.inc index 7c09e454..5da6234c 100644 --- a/Source/HBIOS/z280.inc +++ b/Source/HBIOS/z280.inc @@ -12,7 +12,9 @@ Z280_TCR .EQU $10 ; TRAP CONTROL REG Z280_CCR .EQU $12 ; CACHE CONTROL REG Z280_LAR .EQU $14 ; LOCAL ADDRESS REG ; -; Z280 MMU REGISTERS (I/O PAGE $FF, I/O ADDRESS $FF**NN) +; Z280 PAGE $FF REGSISTER ADDRESSES +; +Z280_RRR .EQU $E8 ; Z280 REFRESH RATE REG ; Z280_MMUMCR .EQU $F0 ; Z280 MMU MASTER CONTROL REG Z280_MMUPDRPTR .EQU $F1 ; Z280 MMU PDR POINTER REG @@ -47,5 +49,28 @@ Z280_DMA3_SRCL .EQU $1A ; DMA3 SOURCE ADDRESS LOW Z280_DMA3_SRCH .EQU $1B ; DMA3 SOURCE ADDRESS HIGH Z280_DMA3_CNT .EQU $1C ; DMA3 COUNT Z280_DMA3_TDR .EQU $1D ; DMA3 TRANSACTION DESCRIPTION REG +; +; Z280 PAGE $FE REGSISTER ADDRESSES +; +Z280_UARTCFG .EQU $10 ; UART CONFIG REG +Z280_UARTXCTL .EQU $12 ; UART TRANSMIT CONTROL/STATUS REG +Z280_UARTRCTL .EQU $14 ; UART RECEIVE CONTROL/STATUS REG +Z280_UARTRECV .EQU $16 ; UART RECEIVE DATA REG +Z280_UARTXMIT .EQU $18 ; UART TRANSMIT DATA REG +; +Z280_CT0_CFG .EQU $E0 ; COUNTER/TIMER 0 CONFIG REG +Z280_CT0_CMDST .EQU $E1 ; COUNTER/TIMER 0 COMMAND/STATUS REG +Z280_CT0_TC .EQU $E2 ; COUNTER/TIMER 0 TIME CONSTANT +Z280_CT0_CT .EQU $E3 ; COUNTER/TIMER 0 COUNT TIME +; +Z280_CT1_CFG .EQU $E8 ; COUNTER/TIMER 1 CONFIG REG +Z280_CT1_CMDST .EQU $E9 ; COUNTER/TIMER 1 COMMAND/STATUS REG +Z280_CT1_TC .EQU $EA ; COUNTER/TIMER 1 TIME CONSTANT +Z280_CT1_CT .EQU $EB ; COUNTER/TIMER 1 COUNT TIME +; +Z280_CT2_CFG .EQU $F8 ; COUNTER/TIMER 2 CONFIG REG +Z280_CT2_CMDST .EQU $F9 ; COUNTER/TIMER 2 COMMAND/STATUS REG +Z280_CT2_TC .EQU $FA ; COUNTER/TIMER 2 TIME CONSTANT +Z280_CT2_CT .EQU $FB ; COUNTER/TIMER 2 COUNT TIME diff --git a/Source/HBIOS/z2u.asm b/Source/HBIOS/z2u.asm new file mode 100644 index 00000000..4e4333cd --- /dev/null +++ b/Source/HBIOS/z2u.asm @@ -0,0 +1,561 @@ +; +;================================================================================================== +; Z280 UART DRIVER (Z280 BUILT-IN UART) +;================================================================================================== +; +; SETUP PARAMETER WORD: +; +-------+---+-------------------+ +---+---+-----------+---+-------+ +; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 | +; +-------+---+---+---------------+ ----+---+-----------+---+-------+ +; F E D C B A 9 8 7 6 5 4 3 2 1 0 +; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- +; +; CONFIG ($FE__10): +; 7 6 5 4 3 2 1 0 +; 1 1 0 0 0 0 1 0 DEFAULT VALUES +; | | | | | | | | +; | | | | | | | | +; | | | | | | | +-- LB: LOOP BACK ENABLE +; | | | | | + +---- CR: CLOCK RATE +; | | | | +-------- CS: CLOCK SELECT +; | | | +---------- E/O: EVEN/ODD +; | | +------------ P: PARITY +; + +-------------- B/C: BITS PER CHARACTER +; +; TRANSMITTER CONTROL/STATUS REGISTER ($FE__12) +; 7 6 5 4 3 2 1 0 +; 1 0 0 0 0 0 0 0 DEFAULT VALUES +; | | | | | | | | +; | | | | | | | +-- BE: BUFFER EMPTY +; | | | | | | +---- VAL: VALUE +; | | | | | +------ FRC: FORCE CHARACTER +; | | | | +-------- BRK: SEND BREAK +; | | | +---------- SB: STOP BITS +; | | +------------ 0: RESERVED (SET TO 0) +; | +-------------- IE: XMIT INT ENBABLE +; +---------------- EN: TRANSMITTER ENABLE +; +; RECEIVER CONTROL/STATUS REGISTER ($FE__14) +; 7 6 5 4 3 2 1 0 +; 1 0 0 0 0 0 0 0 DEFAULT VALUES +; | | | | | | | | +; | | | | | | | +-- ERR: LOGICAL OR OF (OVE, PE, FE) +; | | | | | | +---- OVE: OVERRUN ERROR +; | | | | | +------ PE: PARITY ERROR +; | | | | +-------- FE: FRAMING ERROR +; | | | +---------- CA: RECEIVE CHAR AVAILABLE +; | | +------------ 0: RESERVED (SET TO 0) +; | +-------------- IE: RECEIVER INT ENBABLE +; +---------------- EN: RECEIVER ENABLE +; +; THE Z280 UART USES MODE 3 INTERRUPT PROCESSING REGARDLESS OF THE INT +; MODE SETTING. SINCE MODE 3 REQUIRES A LARGE INTERRUPT VECTOR TABLE +; AND THAT TABLE MUST BE ACCESSIBLE WITHOUT USING EXTERNAL BANK +; SWITCHING, IT IS IMPRACTICAL TO SUPPORT THIS UART UNLESS NATIVE +; Z280 MEMORY MANAGEMENT IS IN USE. +; +#IF (MEMMGR != MM_Z280) + .ECHO "*** ERROR: Z280 UART REQUIRES NATIVE MEMORY MANAGER!!!\n" + !!! ; FORCE AN ASSEMBLY ERROR +#ENDIF +; +Z2U_BUFSZ .EQU 32 ; RECEIVE RING BUFFER SIZE +; +Z2U_NONE .EQU 0 ; NOT PRESENT +Z2U_PRESENT .EQU 1 ; PRESENT +; +; +; +Z2U_PREINIT: +; +; SETUP THE DISPATCH TABLE ENTRIES +; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMAIN +; DISABLED. +; + LD B,Z2U_CFGCNT ; LOOP CONTROL + XOR A ; ZERO TO ACCUM + LD (Z2U_DEV),A ; CURRENT DEVICE NUMBER + LD IY,Z2U_CFG ; POINT TO START OF CFG TABLE +Z2U_PREINIT0: + PUSH BC ; SAVE LOOP CONTROL + CALL Z2U_INITUNIT ; HAND OFF TO GENERIC INIT CODE + POP BC ; RESTORE LOOP CONTROL +; + LD A,(IY+1) ; GET THE Z280 UART TYPE DETECTED + OR A ; SET FLAGS + JR Z,Z2U_PREINIT2 ; SKIP IT IF NOTHING FOUND +; + PUSH BC ; SAVE LOOP CONTROL + PUSH IY ; CFG ENTRY ADDRESS + POP DE ; ... TO DE + LD BC,Z2U_FNTBL ; BC := FUNCTION TABLE ADDRESS + CALL NZ,CIO_ADDENT ; ADD ENTRY IF Z2U FOUND, BC:DE + POP BC ; RESTORE LOOP CONTROL +; +Z2U_PREINIT2: + LD DE,Z2U_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ Z2U_PREINIT0 ; LOOP UNTIL DONE +; +#IF (INTMODE > 0) + ; SETUP INT VECTORS AS APPROPRIATE + LD A,(Z2U_DEV) ; GET DEVICE COUNT + OR A ; SET FLAGS + JR Z,Z2U_PREINIT3 ; IF ZERO, NO Z2U DEVICES, ABORT +; + LD HL,Z2U_INT ; GET INT VECTOR + LD (Z280_IVT+$36),HL ; SET IT +#ENDIF +; +Z2U_PREINIT3: + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; Z280 UART INITIALIZATION ROUTINE +; +Z2U_INITUNIT: + CALL Z2U_DETECT ; DETERMINE Z280 UART TYPE + LD (IY+1),A ; SAVE IN CONFIG TABLE + OR A ; SET FLAGS + RET Z ; ABORT IF NOTHING THERE + + ; UPDATE WORKING Z280 UART DEVICE NUM + LD HL,Z2U_DEV ; POINT TO CURRENT UART DEVICE NUM + LD A,(HL) ; PUT IN ACCUM + INC (HL) ; INCREMENT IT (FOR NEXT LOOP) + LD (IY),A ; UPDATE UNIT NUM +; + ; IT IS EASY TO SPECIFY A SERIAL CONFIG THAT CANNOT BE IMPLEMENTED + ; DUE TO THE CONSTRAINTS OF THE Z280 UART. HERE WE FORCE A GENERIC + ; FAILSAFE CONFIG ONTO THE CHANNEL. IF THE SUBSEQUENT "REAL" + ; CONFIG FAILS, AT LEAST THE CHIP WILL BE ABLE TO SPIT DATA OUT + ; AT A RATIONAL BAUD/DATA/PARITY/STOP CONFIG. + CALL Z2U_INITSAFE +; + ; SET DEFAULT CONFIG + LD DE,-1 ; LEAVE CONFIG ALONE + ; CALL INITDEV TO IMPLEMENT CONFIG, BUT NOTE THAT WE CALL + ; THE INITDEVX ENTRY POINT THAT DOES NOT ENABLE/DISABLE INTS! + JP Z2U_INITDEVX ; IMPLEMENT IT AND RETURN +; +; +; +Z2U_INIT: + LD B,Z2U_CFGCNT ; COUNT OF POSSIBLE Z2U UNITS + LD IY,Z2U_CFG ; POINT TO START OF CFG TABLE +Z2U_INIT1: + PUSH BC ; SAVE LOOP CONTROL + LD A,(IY+1) ; GET Z2U TYPE + OR A ; SET FLAGS + CALL NZ,Z2U_PRTCFG ; PRINT IF NOT ZERO + POP BC ; RESTORE LOOP CONTROL + LD DE,Z2U_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ Z2U_INIT1 ; LOOP TILL DONE +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; RECEIVE INTERRUPT HANDLER +; +#IF (INTMODE > 0) +; +; INT ENTRY POINT +; +Z2U_INT: + ; DISCARD REASON CODE + INC SP + INC SP +; + ; SAVE REGISTERS + PUSH AF + PUSH BC + PUSH DE + PUSH HL +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; CHECK TO SEE IF SOMETHING IS ACTUALLY THERE + IN A,(Z280_UARTRCTL) ; GET STATUS + AND $10 ; ISOLATE CHAR AVAILABLE BIT + JR Z,Z2U_INTRCV4 ; IF NOT, BAIL OUT +; +Z2U_INTRCV1: + ; RECEIVE CHARACTER INTO BUFFER + IN A,(Z280_UARTRECV) ; GET A BYTE + LD B,A ; SAVE BYTE READ + LD HL,Z2U0_RCVBUF ; SET HL TO START OF BUFFER STRUCT + LD A,(HL) ; GET COUNT + CP Z2U_BUFSZ ; COMPARE TO BUFFER SIZE + JR Z,Z2U_INTRCV4 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED + INC A ; INCREMENT THE COUNT + LD (HL),A ; AND SAVE IT + CP Z2U_BUFSZ / 2 ; BUFFER GETTING FULL? + JR NZ,Z2U_INTRCV2 ; IF NOT, BYPASS CLEARING RTS + ; THIS IS WHERE WE SHOULD DEASSERT RTS, BUT THE Z2U HAS NONE +Z2U_INTRCV2: + INC HL ; HL NOW HAS ADR OF HEAD PTR + PUSH HL ; SAVE ADR OF HEAD PTR + LD A,(HL) ; DEREFERENCE HL + INC HL + LD H,(HL) + LD L,A ; HL IS NOW ACTUAL HEAD PTR + LD (HL),B ; SAVE CHARACTER RECEIVED IN BUFFER AT HEAD + INC HL ; BUMP HEAD POINTER + POP DE ; RECOVER ADR OF HEAD PTR + LD A,L ; GET LOW BYTE OF HEAD PTR + SUB Z2U_BUFSZ+4 ; SUBTRACT SIZE OF BUFFER AND POINTER + CP E ; IF EQUAL TO START, HEAD PTR IS PAST BUF END + JR NZ,Z2U_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 +Z2U_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... + IN A,(Z280_UARTRCTL) ; GET STATUS + AND $10 ; ISOLATE CHAR AVAILABLE BIT + JR NZ,Z2U_INTRCV1 +; +Z2U_INTRCV4: + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; RESTORE REGISTERS + POP HL + POP DE + POP BC + POP AF +; + .DB $ED,$55 ; RETIL +#ENDIF +; +; DRIVER FUNCTION TABLE +; +Z2U_FNTBL: + .DW Z2U_IN + .DW Z2U_OUT + .DW Z2U_IST + .DW Z2U_OST + .DW Z2U_INITDEV + .DW Z2U_QUERY + .DW Z2U_DEVICE +#IF (($ - Z2U_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID Z2U FUNCTION TABLE ***\n" +#ENDIF +; +#IF (INTMODE == 0) +; +Z2U_IN: + CALL Z2U_IST ; CHECK FOR CHAR READY + JR Z,Z2U_IN ; IF NOT, LOOP +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; GET CHAR + IN A,(Z280_UARTRECV) ; GET A BYTE + LD E,A ; PUT IN E FOR RETURN +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +#ELSE +; +Z2U_IN: + CALL Z2U_IST ; SEE IF CHAR AVAILABLE + JR Z,Z2U_IN ; LOOP UNTIL SO + HB_DI ; AVOID COLLISION WITH INT HANDLER + LD L,(IY+6) ; SET HL TO + LD H,(IY+7) ; ... START OF BUFFER STRUCT + LD A,(HL) ; GET COUNT + DEC A ; DECREMENT COUNT + LD (HL),A ; SAVE UPDATED COUNT + ; THIS IS WHERE WE SHOULD ASSERT RTS, BUT THE Z2U HAS NONE +Z2U_IN1: + INC HL ; HL := ADR OF TAIL PTR + INC HL ; " + INC HL ; " + PUSH HL ; SAVE ADR OF TAIL PTR + LD A,(HL) ; DEREFERENCE HL + INC HL + LD H,(HL) + LD L,A ; HL IS NOW ACTUAL TAIL PTR + 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 + SUB Z2U_BUFSZ+2 ; SUBTRACT SIZE OF BUFFER AND POINTER + CP E ; IF EQUAL TO START, TAIL PTR IS PAST BUF END + JR NZ,Z2U_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 +Z2U_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 + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +#ENDIF +; +; +; +Z2U_OUT: + CALL Z2U_OST ; CHECK IF OUTPUT REGISTER READY + JR Z,Z2U_OUT ; LOOP UNTIL SO +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; WRITE CHAR + LD A,E ; BYTE TO A + OUT (Z280_UARTXMIT),A ; SEND IT +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; +; +#IF (INTMODE == 0) +; +Z2U_IST: +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; GET RECEIVE STATUS + IN A,(Z280_UARTRCTL) ; GET STATUS + AND $10 ; ISOLATE CHAR AVAILABLE BIT +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + OR A ; SET FLAGS + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET +; +#ELSE +; +Z2U_IST: + LD L,(IY+6) ; GET ADDRESS + LD H,(IY+7) ; ... OF RECEIVE BUFFER + LD A,(HL) ; BUFFER UTILIZATION COUNT + OR A ; SET FLAGS + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET ; DONE +; +#ENDIF +; +; +; +Z2U_OST: +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; GET TRANSMIT STATUS + IN A,(Z280_UARTXCTL) ; GET STATUS +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; CHECK FOR CHAR AVAILABLE + AND $01 ; ISOLATE CHAR AVAILABLE BIT + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET ; DONE +; +; AT INITIALIZATION THE SETUP PARAMETER WORD IS TRANSLATED TO THE FORMAT +; REQUIRED BY THE Z2U AND STORED IN A PORT/REGISTER INITIALIZATION TABLE, +; WHICH IS THEN LOADED INTO THE Z2U. +; +; NOTE THAT THERE ARE TWO ENTRY POINTS. INITDEV WILL DISABLE/ENABLE INTS +; AND INITDEVX WILL NOT. THIS IS DONE SO THAT THE PREINIT ROUTINE ABOVE +; CAN AVOID ENABLING/DISABLING INTS. +; +Z2U_INITDEV: +Z2U_INITSAFE: + HB_DI ; DISABLE INTS + CALL Z2U_INITDEVX ; DO THE WORK + HB_EI ; INTS BACK ON + RET ; DONE +; +Z2U_INITDEVX: +; + ; START BY SELECTING I/O PAGE $FE + LD L,$FE ; Z280 UART REGISTERS AT I/O PAGE $FE + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; + ; SETUP + LD A,%11000010 ; 8N0, DIV 16, NO C/T + OUT (Z280_UARTCFG),A ; SET CONFIG REGISTER + LD A,%10000000 ; ENABLE, NO INTS, 1 STOP BITS + OUT (Z280_UARTXCTL),A ; SET CONFIG REGISTER +#IF (INTMODE > 0) + LD A,%11000000 ; ENABLE W/ INTS +#ELSE + LD A,%10000000 ; ENABLE, NO INTS +#ENDIF + OUT (Z280_UARTRCTL),A ; SET CONFIG REGISTER +; + ; RESTORE I/O PAGE TO $00 + LD L,$00 ; NORMAL I/O REG IS $00 + LD C,Z280_IOPR ; REG C POINTS TO I/O PAGE REGISTER + .DB $ED,$6E ; LDCTL (C),HL +; +#IF (INTMODE > 0) +; + ; RESET THE RECEIVE BUFFER + LD E,(IY+6) + LD D,(IY+7) ; DE := _CNT + XOR A ; A := 0 + LD (DE),A ; _CNT = 0 + INC DE ; DE := ADR OF _HD + PUSH DE ; SAVE IT + INC DE + INC DE + INC DE + INC DE ; DE := ADR OF _BUF + POP HL ; HL := ADR OF _HD + LD (HL),E + INC HL + LD (HL),D ; _HD := _BUF + INC HL + LD (HL),E + INC HL + LD (HL),D ; _TL := _BUF +; +#ENDIF +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; +; +Z2U_QUERY: + LD E,(IY+4) ; FIRST CONFIG BYTE TO E + LD D,(IY+5) ; SECOND CONFIG BYTE TO D + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; +; +Z2U_DEVICE: + LD D,CIODEV_Z2U ; D := DEVICE TYPE + LD E,(IY) ; E := PHYSICAL UNIT + LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 + LD H,0 ; H := 0, DRIVER HAS NO MODES + LD L,(IY+3) ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; +; Z280 UART DETECTION ROUTINE +; ALWAYS PRESENT, JUST SAY SO. +; +Z2U_DETECT: + LD A,Z2U_PRESENT ; PRESENT + RET +; +; +; +Z2U_PRTCFG: + ; ANNOUNCE PORT + CALL NEWLINE ; FORMATTING + PRTS("Z2U$") ; FORMATTING + LD A,(IY) ; DEVICE NUM + CALL PRTDECB ; PRINT DEVICE NUM + PRTS(": IO=0x$") ; FORMATTING + LD A,(IY+3) ; GET BASE PORT + CALL PRTHEXBYTE ; PRINT BASE PORT +; + ; ALL DONE IF NO Z2U WAS DETECTED + LD A,(IY+1) ; GET Z2U TYPE BYTE + OR A ; SET FLAGS + RET Z ; IF ZERO, NOT PRESENT +; + PRTS(" MODE=$") ; FORMATTING + LD E,(IY+4) ; LOAD CONFIG + LD D,(IY+5) ; ... WORD TO DE + CALL PS_PRTSC0 ; PRINT CONFIG +; + XOR A + RET +; +; WORKING VARIABLES +; +Z2U_DEV .DB 0 ; DEVICE NUM USED DURING INIT +; +#IF (INTMODE == 0) +; +Z2U0_RCVBUF .EQU 0 +; +#ELSE +; +; RECEIVE BUFFERS +; +Z2U0_RCVBUF: +Z2U0_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER +Z2U0_HD .DW Z2U0_BUF ; BUFFER HEAD POINTER +Z2U0_TL .DW Z2U0_BUF ; BUFFER TAIL POINTER +Z2U0_BUF .FILL 32,0 ; RECEIVE RING BUFFER +Z2U0_BUFEND .EQU $ ; END OF BUFFER +Z2U0_BUFSZ .EQU $ - Z2U0_BUF ; SIZE OF RING BUFFER +; +#ENDIF +; +; Z2U PORT TABLE +; +Z2U_CFG: +; +Z2U0_CFG: + ; Z2U CONFIG + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; Z280 UART TYPE (SET DURING INIT) + .DB 0 ; MODULE ID + .DB Z2U0BASE ; BASE PORT + .DW Z2U0CFG ; LINE CONFIGURATION + .DW Z2U0_RCVBUF ; POINTER TO RCV BUFFER STRUCT +; +Z2U_CFGSIZ .EQU $ - Z2U_CFG ; SIZE OF ONE CFG TABLE ENTRY +; +Z2U_CFGCNT .EQU ($ - Z2U_CFG) / Z2U_CFGSIZ diff --git a/Source/ver.inc b/Source/ver.inc index 37bae98b..8f7fe9e3 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1.1-pre.32" +#DEFINE BIOSVER "3.1.1-pre.33" diff --git a/Source/ver.lib b/Source/ver.lib index a1b492e0..fffe697e 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 1 rtp equ 0 biosver macro - db "3.1.1-pre.32" + db "3.1.1-pre.33" endm