From 229bdaa3089c8236a21912a05ed06305533e748e Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sat, 1 Jul 2023 15:33:18 -0700 Subject: [PATCH] Support Z180 IM1 Added proper support for interrupt mode 1 on Z180. --- Doc/ChangeLog.txt | 2 + Source/HBIOS/asci.asm | 32 ++----------- Source/HBIOS/hbios.asm | 104 +++++++++++++++++++--------------------- Source/HBIOS/romldr.asm | 6 ++- Source/HBIOS/std.asm | 31 ++++++------ Source/ver.inc | 2 +- Source/ver.lib | 2 +- 7 files changed, 76 insertions(+), 103 deletions(-) diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 62b5ba15..f7304f17 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -12,6 +12,8 @@ Version 3.3 - WBW: Support for SyQuest SparQ Drive on PPI interface (much inspiration from Alan Cox) - WBW: Support for ATAPI Disk Drives (not CD-ROMs) on IDE and PPIDE interfaces - R?P: Added new disk images: Aztec C, MS BASIC Compiler, MS Fortran, Games, HiTech-C, Turbo Pascal, SLR Z80ASM +- JBL: Added RCZ80 configuration for ColecoVision +- WBW: Support for Z180 running interrupt mode 1 Version 3.2.1 ------------- diff --git a/Source/HBIOS/asci.asm b/Source/HBIOS/asci.asm index a00e2e56..aa6cb090 100644 --- a/Source/HBIOS/asci.asm +++ b/Source/HBIOS/asci.asm @@ -81,7 +81,7 @@ ASCI_RTS .EQU %00010000 ; ~RTS BIT OF CNTLA REG ; #IF (ASCIINTS) ; - #IF (INTMODE == 2) + #IF (INTMODE > 0) ; ASCI0_IVT .EQU IVT(INT_SER0) ASCI1_IVT .EQU IVT(INT_SER1) @@ -125,25 +125,19 @@ ASCI_PREINIT2: ; #IF (ASCIINTS) ; - #IF (INTMODE >= 1) +; Z180 ASCI INTERRUPTS OPERATE LIKE IM2 EVEN WHEN IM1 IS ACTIVE. +; + #IF (INTMODE > 0) ; SETUP INT VECTORS AS APPROPRIATE LD A,(ASCI_DEV) ; GET DEVICE COUNT OR A ; SET FLAGS JR Z,ASCI_PREINIT3 ; IF ZERO, NO ASCI DEVICES, ABORT ; - #IF (INTMODE == 1) - ; ADD IM1 INT CALL LIST ENTRY - LD HL,ASCI_INT ; GET INT VECTOR - CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST - #ENDIF -; - #IF (INTMODE == 2) ; SETUP IM2 VECTORS LD HL,ASCI_INT0 LD (ASCI0_IVT),HL ; IVT INDEX LD HL,ASCI_INT1 LD (ASCI1_IVT),HL ; IVT INDEX - #ENDIF ; #ENDIF ; @@ -204,24 +198,6 @@ ASCI_INIT1: ; #IF (INTMODE > 0) ; -; IM1 ENTRY POINT -; -ASCI_INT: - ; CHECK/HANDLE FIRST PORT - LD A,(ASCI0_CFG + 1) ; GET ASCI TYPE FOR FIRST ASCI - OR A ; SET FLAGS - CALL NZ,ASCI_INT0 ; CALL IF EXISTS - RET NZ ; DONE IF INT HANDLED -; - ; CHECK/HANDLE SECOND PORT - LD A,(ASCI1_CFG + 1) ; GET ASCI TYPE FOR SECOND ASCI - OR A ; SET FLAGS - CALL NZ,ASCI_INT1 ; CALL IF EXISTS -; - RET ; DONE -; -; IM2 ENTRY POINTS -; ASCI_INT0: ; INTERRUPT HANDLER FOR FIRST ASCI (ASCI0) LD IY,ASCI0_CFG ; POINT TO ASCI0 CFG diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index c5ad4116..409bfeaa 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -247,7 +247,8 @@ RTCDEF .SET RTCDEF | %00001000 ; INITIAL SPEED LOW RET .FILL (038H - $),0FFH ; RST 38 / IM1 INT #IF (INTMODE == 1) - JP INT_IM1 ; JP TO INTERRUPT HANDLER IN HI MEM + CALL HBX_INT ; HANDLE IM1 INTERRUPTS + .DB $10 << 2 ; USE SPECIAL VECTOR #16 #ELSE RET ; RETURN W/ INTS DISABLED #ENDIF @@ -812,8 +813,6 @@ HBX_INTSTK .EQU $ !!! ; FORCE AN ASSEMBLY ERROR #ENDIF ; -#IF ((INTMODE == 2) | (INTMODE == 3)) -; ; HBIOS INTERRUPT SLOT ASSIGNMENTS ; ; # Z80 Z180 @@ -872,19 +871,9 @@ HBX_IV0D: CALL HBX_INT \ .DB $0D << 2 HBX_IV0E: CALL HBX_INT \ .DB $0E << 2 HBX_IV0F: CALL HBX_INT \ .DB $0F << 2 ; -#ENDIF -; -INT_IM1: -#IF (INTMODE == 1) - CALL HBX_INT - .DB $00 -#ELSE - RETI ; UNEXPECTED INT, RET W/ INTS LEFT DISABLED -#ENDIF +HBX_INT: ; COMMON INTERRUPT ROUTING CODE ; #IF (INTMODE > 0) -; -HBX_INT: ; COMMON INTERRUPT ROUTING CODE ; #IF (MEMMGR == MM_Z280) ; @@ -966,7 +955,11 @@ HBX_INT_SP .EQU $ - 2 RETI ; AND RETURN ; #ENDIF - +; +#ELSE +; + RET +; #ENDIF ; ; SMALL TEMPORARY STACK FOR USE BY HBX_BNKCPY @@ -1038,34 +1031,6 @@ HB_STACK .EQU $ ; TOP OF HBIOS STACK ; INTERRUPT VECTOR TABLE (MUST START AT PAGE BOUNDARY!!!) ;================================================================================================== ; -; IM1 INTERRUPTS ARRIVE HERE AFTER BANK SWITCH TO HBIOS BANK -; LIST OF IM1 INT CALLS IS BUILT DYNAMICALLY BELOW -; SEE HB_ADDIM1 ROUTINE -; EACH ENTRY WILL LOOK LIKE: -; CALL XXXX ; CALL INT HANDLER -; RET NZ ; RETURN IF HANDLED -; -; NOTE THAT THE LIST IS INITIALLY FILLED WITH CALLS TO HB_BADINT. -; AS THE TABLE IS POPULATED, THE ADDRESS OF HB_BADINT IS OVERLAID -; WITH THE ADDRESS OF A REAL INTERRUPT HANDLER. -; -; THERE IS ROOM FOR 8 ENTRIES PLUS A FINAL CALL TO HB_BADINT. -; -#IF (INTMODE < 2) -; -HB_IVT: - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ - CALL HB_BADINT \ RET NZ -; -#ENDIF -; ; IM2 INTERRUPTS ARRIVE HERE AFTER BANK SWITCH TO HBIOS BANK ; THE LIST OF JP TABLE ENTRIES MATCHES THE IM2 VECTORS ONE FOR ; ONE. ANY CALL TO THE PRIMARY IVT (HBX_IVT) WILL BE MAPPED TO @@ -1079,8 +1044,6 @@ HB_IVT: ; NOTE THAT EACH ENTRY HAS A FILLER BYTE OF VALUE ZERO. THIS BYTE ; HAS NO FUNCTION. IT IS JUST USED TO MAKE ENTRIES AN EVEN 4 BYTES. ; -#IF ((INTMODE == 2) | (INTMODE == 3)) -; HB_IVT: HB_IVT00: JP HB_BADINT \ .DB 0 HB_IVT01: JP HB_BADINT \ .DB 0 @@ -1098,8 +1061,31 @@ HB_IVT0C: JP HB_BADINT \ .DB 0 HB_IVT0D: JP HB_BADINT \ .DB 0 HB_IVT0E: JP HB_BADINT \ .DB 0 HB_IVT0F: JP HB_BADINT \ .DB 0 +HB_IVT10: JP HB_IM1INT \ .DB 0 ; -#ENDIF +; IM1 INTERRUPTS ARRIVE HERE AFTER BANK SWITCH TO HBIOS BANK +; LIST OF IM1 INT CALLS IS BUILT DYNAMICALLY BELOW +; SEE HB_ADDIM1 ROUTINE +; EACH ENTRY WILL LOOK LIKE: +; CALL XXXX ; CALL INT HANDLER +; RET NZ ; RETURN IF HANDLED +; +; NOTE THAT THE LIST IS INITIALLY FILLED WITH CALLS TO HB_BADINT. +; AS THE TABLE IS POPULATED, THE ADDRESS OF HB_BADINT IS OVERLAID +; WITH THE ADDRESS OF A REAL INTERRUPT HANDLER. +; +; THERE IS ROOM FOR 8 ENTRIES PLUS A FINAL CALL TO HB_BADINT. +; +HB_IM1INT: + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ + CALL HB_BADINT \ RET NZ ; ;================================================================================================== ; SYSTEM INITIALIZATION @@ -1711,11 +1697,14 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK ; ; MAKE SURE IM1 INT VECTOR IS RIGHT #IF (INTMODE == 1) - ; JP INT_IM1 IF INTERRUPT MODE ACTIVE - LD A,$C3 + ; CALL HBX_INT ; HANDLE IM1 INTERRUPTS + ; .DB $10 << 2 ; USE SPECIAL VECTOR #16 + LD A,$CD ; CALL OPCODE LD ($0038),A - LD HL,INT_IM1 + LD HL,HBX_INT ; ADDRESS LD ($0039),HL + LD A,$10 << 2 ; IM1 VECTOR + LD ($003B),A #ELSE ; RETI ($ED, $4D) IF NON-INTERRUPT MODE LD HL,$0038 @@ -1809,8 +1798,8 @@ SAVE_REC_M: ; ; TEST DEBUG *************************************************************************************** ; - PRTS("DEBUG-IVT$") - LD DE,HB_IVT + PRTS("DEBUG-IM1INT$") + LD DE,HB_IM1INT CALL DUMP_BUFFER CALL NEWLINE ; @@ -2116,7 +2105,7 @@ HB_CPU3: ; #IF (CPUFAM == CPU_Z180) ; - #IF (INTMODE == 2) + #IF (INTMODE > 0) ; ; MASK ALL EXTERNAL INTERRUPTS FOR NOW LD A,$01 ; INT0 ENABLED, INT1-2 DISABLED @@ -2327,8 +2316,8 @@ NXTMIO: LD A,(HL) ; TEST DEBUG *************************************************************************************** ; CALL NEWLINE2 - PRTS("DEBUG+IVT$") - LD DE,HB_IVT + PRTS("DEBUG+IM1INT$") + LD DE,HB_IM1INT CALL DUMP_BUFFER ; ; TEST DEBUG *************************************************************************************** @@ -5041,7 +5030,12 @@ SYS_INTGET1: INC A ; BUMP TO ADR FIELD LD H,0 LD L,A +#IF (INTMODE == 1) + LD DE,HB_IM1INT ; DE := START OF VECTOR TABLE +#ENDIF +#IF (INTMODE == 2) LD DE,HB_IVT ; DE := START OF VECTOR TABLE +#ENDIF ADD HL,DE ; HL := ADR OF VECTOR XOR A ; INDICATE SUCCESS RET @@ -5123,7 +5117,7 @@ HB_ADDIM1: ; HB_IM1CNT .DB 0 ; NUMBER OF ENTRIES IN CALL LIST HB_IM1MAX .DB 8 ; MAX ENTRIES IN CALL LIST -HB_IM1PTR .DW HB_IVT ; POINTER FOR NEXT IM1 ENTRY +HB_IM1PTR .DW HB_IM1INT ; POINTER FOR NEXT IM1 ENTRY ; #ENDIF ; diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index 4782d4d5..9994d3bb 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -47,7 +47,8 @@ cmdbuf .equ $80 ; cmd buf is in second half of page zero cmdmax .equ 60 ; max cmd len (arbitrary), must be < bufsiz bufsiz .equ $80 ; size of cmd buf ; -int_im1 .equ $FF00 ; IM1 vector target for RomWBW HBIOS proxy +;;int_im1 .equ $FF00 ; IM1 vector target for RomWBW HBIOS proxy +hbx_int .equ $FF60 ; IM1 vector target for RomWBW HBIOS proxy ; bid_cur .equ -1 ; used below to indicate current bank ; @@ -77,7 +78,8 @@ bid_cur .equ -1 ; used below to indicate current bank .fill ($38 - $) #if (BIOS == BIOS_WBW) #if (INTMODE == 1) - jp int_im1 ; go to handler in hi mem + call hbx_int ; handle im1 interrupts + .db $10 << 2 ; use special vector #16 #else ret ; return w/ ints left disabled #endif diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index f8a7be74..258295b6 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -728,12 +728,13 @@ MON_SERIAL .EQU MON_LOC + (1 * 3) ; MONITOR ENTRY (SERIAL PORT) ; ; INTERRUPT MODE 2 SLOT ASSIGNMENTS ; -#IF ((INTMODE == 2) | (INTMODE == 3)) +#IF (((CPUFAM == CPU_Z180) | (CPUFAM == CPU_Z280)) & (INTMODE > 0)) - #IF ((CPUFAM == CPU_Z180) | (CPUFAM == CPU_Z280)) +; NOTE THAT Z180 PROCESSES ALL INTERNAL INTERRUPTS JUST LIKE +; IM2 EVEN WHEN CHIP IS IN IM1 MODE. SO WE INCLUDE THE IM2 +; INTERRUPT ASSIGNMENTS FOR IM1 BELOW. ; Z180-BASED SYSTEMS - INT_INT1 .EQU 0 ; Z180 INT 1 INT_INT2 .EQU 1 ; Z180 INT 2 INT_TIM0 .EQU 2 ; Z180 TIMER 0 @@ -750,19 +751,18 @@ INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B INT_SIO0 .EQU 13 ; ZILOG SIO 0, CHANNEL A & B INT_SIO1 .EQU 14 ; ZILOG SIO 1, CHANNEL A & B - #ELSE - -; Z80-BASED SYSTEMS - +#ENDIF - #IF (PLATFORM == PLT_MBC) +#IF ((CPUFAM == CPU_Z80) & (INTMODE == 2)) + #IF (PLATFORM == PLT_MBC) +; MBC Z80 ;INT_CTC0A .EQU 0 ; ZILOG CTC 0, CHANNEL A ;INT_CTC0B .EQU 1 ; ZILOG CTC 0, CHANNEL B ;INT_CTC0C .EQU 2 ; ZILOG CTC 0, CHANNEL C ;INT_CTC0D .EQU 3 ; ZILOG CTC 0, CHANNEL D -INT_UART0 .EQU 4 ; MBC UART 0 -INT_UART1 .EQU 5 ; MBC UART 1 +INT_UART0 .EQU 4 ; UART 0 +INT_UART1 .EQU 5 ; UART 1 INT_SIO0 .EQU 8 ; ZILOG SIO 0, CHANNEL A & B INT_SIO1 .EQU 9 ; ZILOG SIO 1, CHANNEL A & B INT_CTC0A .EQU 12 ; ZILOG CTC 0, CHANNEL A @@ -774,14 +774,15 @@ INT_CTC0D .EQU 15 ; ZILOG CTC 0, CHANNEL D ;INT_PIO1A .EQU 11 ; ZILOG PIO 1, CHANNEL A ;INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B - #ELSE + #ELSE +; GENERIC Z80 INT_CTC0A .EQU 0 ; ZILOG CTC 0, CHANNEL A INT_CTC0B .EQU 1 ; ZILOG CTC 0, CHANNEL B INT_CTC0C .EQU 2 ; ZILOG CTC 0, CHANNEL C INT_CTC0D .EQU 3 ; ZILOG CTC 0, CHANNEL D -INT_UART0 .EQU 4 ; MBC UART 0 -INT_UART1 .EQU 5 ; MBC UART 1 +INT_UART0 .EQU 4 ; UART 0 +INT_UART1 .EQU 5 ; UART 1 INT_SIO0 .EQU 7 ; ZILOG SIO 0, CHANNEL A & B INT_SIO1 .EQU 8 ; ZILOG SIO 1, CHANNEL A & B INT_PIO0A .EQU 9 ; ZILOG PIO 0, CHANNEL A @@ -790,13 +791,11 @@ INT_PIO1A .EQU 11 ; ZILOG PIO 1, CHANNEL A INT_PIO1B .EQU 12 ; ZILOG PIO 1, CHANNEL B #ENDIF - - #ENDIF +#ENDIF #DEFINE IVT(INTX) HB_IVT+(INTX * 4)+1 #DEFINE VEC(INTX) INTX*2 -#ENDIF ; ; SET DEFAULT CSIO SPEED (INTERNAL CLOCK, SLOW AS POSSIBLE) ; DIV 1280, 14KHZ @ 18MHZ CLK diff --git a/Source/ver.inc b/Source/ver.inc index 075fc98c..0c15eff1 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,7 +2,7 @@ #DEFINE RMN 3 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.3.0-dev.28" +#DEFINE BIOSVER "3.3.0-dev.29" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index 515ced21..60766dd5 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 3 rup equ 0 rtp equ 0 biosver macro - db "3.3.0-dev.28" + db "3.3.0-dev.29" endm