From 0c13a056b413c403de5d04c7d6f61977a6b4c650 Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Tue, 6 Jan 2026 19:51:39 +1100 Subject: [PATCH 1/3] hbios/tms: Added detection and reporting of vdp type (TMS9918/V9938/V9958) --- Source/HBIOS/tms.asm | 110 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index 8f89a318..cc555244 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -318,6 +318,34 @@ TMS_INIT: RET ; TMS_INIT1: + CALL PRTSTRD + .TEXT " VDP=$" + + CALL TMS_GETTYP ; A <- 0: TMS9918A, 1: V9938, 2: V9958, x: VDP ID + + INC A + DEC A + JR NZ, TMS_NOT9918 + + CALL PRTSTRD + .TEXT "TMS9918$" + JR TMS_INIT2 + +TMS_NOT9918: + DEC A + JR NZ, TMS_NOT9938 + + CALL PRTSTRD + .TEXT "V9938$" + JR TMS_INIT2 + +TMS_NOT9938: + ; ASSUME V9958 + CALL PRTSTRD + .TEXT "V9958$" + +TMS_INIT2: + #IF (TMSTIMENABLE) CALL PRTSTRD .TEXT " INTERRUPT ENABLED$" @@ -712,12 +740,10 @@ TMS_PROBE: LD A,$A5 ; FIRST BYTE EZ80_IO OUT (TMS_DATREG),A ; OUTPUT - ;TMS_IODELAY ; DELAY CALL DLY64 ; DELAY CPL ; COMPLEMENT ACCUM EZ80_IO OUT (TMS_DATREG),A ; SECOND BYTE - ;TMS_IODELAY ; DELAY CALL DLY64 ; DELAY ; ; SET READ ADDRESS TO $0000 @@ -727,18 +753,94 @@ TMS_PROBE: LD C,$A5 ; VALUE TO EXPECT EZ80_IO IN A,(TMS_DATREG) ; READ FIRST BYTE - ;TMS_IODELAY ; DELAY CALL DLY64 ; DELAY CP C ; COMPARE RET NZ ; RETURN ON MISCOMPARE EZ80_IO IN A,(TMS_DATREG) ; READ SECOND BYTE - ;TMS_IODELAY ; DELAY CALL DLY64 ; DELAY CPL ; COMPLEMENT IT CP C ; COMPARE RET ; RETURN WITH RESULT IN Z ; +; DETECT VDP VERSION +; +; ASSUMES INTERRUPTS ARE DISABLED (DI) +; +; A <- 0: TMS9918A, 1: V9938, 2: V9958, x: VDP ID +; F <- z: TMS9918A, nz: other +; +TMS_GETTYP: + ; Code sourced from https://map.grauw.nl/sources/vdp_detection.php + CALL TMS_IS9918 ; USE A DIFFERENT WAY TO DETECT TMS9918A + RET Z ; RETURN 0 FOR TMS9918 + LD A,1 ; SELECT S#1 + EZ80_IO + OUT (TMS_CMDREG),A + LD A,15 + 128 + EZ80_IO + OUT (TMS_CMDREG),A + EZ80_IO + IN A,(TMS_CMDREG) ; READ S#1 + AND 00111110B ; GET VDP ID + RRCA + + EX AF,AF' + XOR A ; RESTORE SELECT REGISTER TO S#0 FOR INT HANDLER + EZ80_IO + OUT (TMS_CMDREG),A + LD A,15 + 128 + EZ80_IO + OUT (TMS_CMDREG),A + EX AF,AF' + + RET NZ ; RETURN VDP ID FOR V9958 OR HIGHER + INC A ; RETURN 1 FOR V9938 + RET +; +; TEST IF THE VDP IS A TMS9918A. +; +; THE VDP ID NUMBER WAS ONLY INTRODUCED IN THE V9938, SO WE HAVE TO USE A +; DIFFERENT METHOD TO DETECT THE TMS9918A. WE WAIT FOR THE VERTICAL BLANKING +; INTERRUPT FLAG, AND THEN QUICKLY READ STATUS REGISTER 2 AND EXPECT BIT 6 +; (VR, VERTICAL RETRACE FLAG) TO BE SET AS WELL. THE TMS9918A HAS ONLY ONE +; STATUS REGISTER, SO BIT 6 (5S, 5TH SPRITE FLAG) WILL RETURN 0 INSTEAD. +; +; ASSUMES INTERRUPTS ARE DISABLED (DI) +; +; F <- Z: TMS9918A, NZ: V99X8 +; +TMS_IS9918: + EZ80_IO + IN A,(TMS_CMDREG) ; READ S#0, MAKE SURE INTERRUPT FLAG (F) IS RESET + +TMS_IS9918_WAIT: + EZ80_IO + IN A,(TMS_CMDREG) ; READ S#0 + AND A ; WAIT UNTIL INTERRUPT FLAG (F) IS SET + JP P,TMS_IS9918_WAIT + + LD A,2 ; SELECT S#2 ON V9938 + EZ80_IO + OUT (TMS_CMDREG),A + LD A,15 + 128 ; (THIS MIRRORS TO R#7 ON TMS9918 VDPS) + EZ80_IO + OUT (TMS_CMDREG),A + EZ80_IO + IN A,(TMS_CMDREG) ; READ S#2 / S#0 + + EX AF,AF' + XOR A ; RESTORE SELECT REGISTER TO S#0 FOR INT HANDLER + EZ80_IO + OUT (TMS_CMDREG),A + LD A,15 + 128 + EZ80_IO + OUT (TMS_CMDREG),A + EX AF,AF' + + AND 01000000B ; CHECK IF BIT 6 WAS 0 (S#0 5S) OR 1 (S#2 VR) + RET +; ;---------------------------------------------------------------------- ; TMS9918 DISPLAY CONTROLLER CHIP INITIALIZATION ;---------------------------------------------------------------------- From 56544dc315556ac8de9d87772023565a1551280f Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Wed, 7 Jan 2026 09:44:03 +1100 Subject: [PATCH 2/3] hbios/tms: Added vram size detection for V99x8 chips --- Source/HBIOS/tms.asm | 153 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 5 deletions(-) diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index cc555244..8ed55ebf 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -6,11 +6,14 @@ ; UPDATED BY: DEAN NETHERTON -- 5/26/2021 - V9958 SUPPORT ; UPDATED BY: JOSE L. COLLADO -- 11/15/2023 - MEMORY MAP CHANGES ; UPDATED BY: DAN WERNER -- 2/11/2024 - DUODYNE SUPPORT -; UPDATED BY: DAN WERNER -- 11/271/2025 - N8PC SUPPORT +; UPDATED BY: DAN WERNER -- 11/27/2025 - N8PC SUPPORT +; UPDATED BY: DEAN NETHERTON -- 1/7/2026 - ADDED RUNTIME DETECTION OF CHIP TYPE AND VRAM SIZE ;====================================================================== ; ; TODO: +; - CAN WE AUTO DETECT TMS VS V99x8 AND THUS AUTO SELECT TMS80COLS AT RUNTIME? +; - CAN WE AUTO DETECT TYPE FOR FPGA EMULATED VERSIONS? ; - IMPLEMENT SET CURSOR STYLE (VDASCS) FUNCTION? ; - IMPLEMENT ALTERNATE DISPLAY MODES? ; - IMPLEMENT DYNAMIC READ/WRITE OF CHARACTER BITMAP DATA? @@ -318,6 +321,10 @@ TMS_INIT: RET ; TMS_INIT1: + CALL TMS_CRTINIT ; SETUP THE TMS/V99x8 CHIP REGISTERS + ; THIS IS BEST DONE BEFORE DETECTION OF TYPE + ; AND VRAM SIZE + CALL PRTSTRD .TEXT " VDP=$" @@ -328,8 +335,8 @@ TMS_INIT1: JR NZ, TMS_NOT9918 CALL PRTSTRD - .TEXT "TMS9918$" - JR TMS_INIT2 + .TEXT "TMS9918 VRAM=16KB INTERRUPT=60HZ$" + JR TMS_INIT3 TMS_NOT9918: DEC A @@ -345,11 +352,37 @@ TMS_NOT9938: .TEXT "V9958$" TMS_INIT2: + CALL PRTSTRD + .TEXT " VRAM=$" + + CALL TMS_VRMPRB + + DEC A + JR NZ, NOT_64K + + PRTS("64KB$") + JR TMS_INIT3 + +NOT_64K: + DEC A + JR NZ, NOT_128K + + PRTS("128KB$") + JR TMS_INIT3 + +NOT_128K: + PRTS("192KB$") #IF (TMSTIMENABLE) CALL PRTSTRD - .TEXT " INTERRUPT ENABLED$" +#IF (TICKFREQ == 50) + .TEXT " INTERRUPT=50HZ$" +#ELSE + .TEXT " INTERRUPT=60HZ$" +#ENDIF + #ENDIF +TMS_INIT3: CALL PC_SPACE LD A,TMS_COLS CALL PRTDEC8 @@ -358,7 +391,6 @@ TMS_INIT2: LD A,TMS_ROWS CALL PRTDEC8 ; - CALL TMS_CRTINIT ; SETUP THE TMS CHIP REGISTERS CALL TMS_LOADFONT ; LOAD FONT DATA FROM ROM TO TMS STRORAGE ; *** DIAGNOSE FONT LOAD ERROR HERE!!! *** CALL TMS_CLEAR ; CLEAR SCREEN, HOME CURSOR @@ -840,6 +872,117 @@ TMS_IS9918_WAIT: AND 01000000B ; CHECK IF BIT 6 WAS 0 (S#0 5S) OR 1 (S#2 VR) RET + +; PROBE VRAM SIZE OF V99x8 VDP +; +; ASSUMES INTERRUPTS ARE DISABLED (DI) +; +; A <- 1: 64K, 2: 128K, 3: 192K +TMS_VRMPRB: + XOR A ; SET RETURN VALUE FOR 64K + INC A + EX AF,AF' + LD A,4 + ; USE 16 BIT I/O ADDRESS FOR EZ80 COMPATIBILITY + ; (AVOID NEED FOR EZ80_IO MACRO) + LD BC, (IO_SEGMENT<<8)+TMS_CMDREG + OUT (C),A + CALL DLY64 ; DELAY + LD A,$8E + OUT (C),A ; R#14 = 4 -> A16 = 1, A15..A14 = 0 + CALL DLY64 ; DELAY + XOR A + OUT (C),A ; A7..A0 = 0 + CALL DLY64 ; DELAY + OR $40 + OUT (C),A ; SET WR, A13..A8 = 0 + CALL DLY64 ; DELAY + LD A,$76 + CALL DLY64 ; DELAY + LD C, TMS_DATREG + OUT (C),A ; SET VRAM $10000 = $76 + CALL DLY64 ; DELAY + XOR A + LD C, TMS_CMDREG + OUT (C),A ; A7..A0 = 0 + CALL DLY64 ; DELAY + + OUT (C),A ; SET RD, A13..A8 = 0 + CALL DLY64 ; DELAY + LD C, TMS_DATREG + IN A,(C) ; A = VRAM $10000 + CALL DLY64 ; DELAY + CP $76 + JR Z,VRAMSIZE_128K ; IF ITS $76, WE HAVE AT LEAST 128K + + ; OTHERWISE ITS ONLY 64K + JR VRAMSIZE_DONE + +VRAMSIZE_128K: + ; WE HAVE AT LEAST 128K + EX AF, AF' + INC A ; SET RETURN VALUE TO 1 FOR 128K + EX AF, AF' + + LD A, $40 ; CHECK TO SEE IF WE HAVE 192K (EXPANSION RAM INSTALLED) + LD C, TMS_CMDREG + OUT (C), A ; ENABLE EXANSION MEMORY ACCESS + CALL DLY64 ; DELAY + LD A, $80 | 45 + OUT (C), A ; R#45 = $40 (MXC=1, MXD,MXS,DIY,DIX,EQ,MAJ=0) + CALL DLY64 ; DELAY + + LD A,1 + OUT (C),A + CALL DLY64 ; DELAY + LD A,$8E + OUT (C),A ; R#14 = 4 -> A16 = 0, A15..A14 = 1 + CALL DLY64 ; DELAY + XOR A + OUT (C),A ; A7..A0 = 0 + CALL DLY64 ; DELAY + OR $40 + OUT (C),A ; SET WR, A13..A8 = 0 + CALL DLY64 ; DELAY + LD A,$5A + CALL DLY64 ; DELAY + LD C, TMS_DATREG + OUT (C),A ; SET VRAM $14000 = $76 + CALL DLY64 ; DELAY + XOR A + LD C, TMS_CMDREG + OUT (C),A ; A7..A0 = 0 + CALL DLY64 ; DELAY + OUT (C),A ; SET RD, A13..A8 = 0 + CALL DLY64 ; DELAY + LD C, TMS_DATREG + IN A,(C) ; A = VRAM $14000 + CALL DLY64 ; DELAY + CP $5A + JR NZ,VRAMSIZE_DONE ; IF ITS $5A, WE HAVE EXAPANSION VRAM + + EX AF, AF' + INC A ; SET RETURN VALUE TO 2 FOR 192K + EX AF, AF' + +VRAMSIZE_DONE: + XOR A + LD C, TMS_CMDREG + OUT (C), A ; DISABLE EXANSION MEMORY ACCESS + CALL DLY64 ; DELAY + LD A, $80 | 45 + OUT (C), A ; R#45 = $00 (MXC=0, MXD,MXS,DIY,DIX,EQ,MAJ=0) + CALL DLY64 ; DELAY + + XOR A + OUT (C),A + CALL DLY64 ; DELAY + LD A,$8E + OUT (C),A ; R#14 = 0 -> A16..A14 = 0 + + EX AF, AF' + RET + ; ;---------------------------------------------------------------------- ; TMS9918 DISPLAY CONTROLLER CHIP INITIALIZATION From d1e9065d1904bf49954a8ffe214226d0a2cdbd3f Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Wed, 7 Jan 2026 10:31:26 +1100 Subject: [PATCH 3/3] hbios/tms: replace some spacing with tabs --- Source/HBIOS/tms.asm | 74 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index 8ed55ebf..1ee476ad 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -882,41 +882,41 @@ TMS_VRMPRB: XOR A ; SET RETURN VALUE FOR 64K INC A EX AF,AF' - LD A,4 + LD A,4 ; USE 16 BIT I/O ADDRESS FOR EZ80 COMPATIBILITY ; (AVOID NEED FOR EZ80_IO MACRO) LD BC, (IO_SEGMENT<<8)+TMS_CMDREG - OUT (C),A + OUT (C),A CALL DLY64 ; DELAY - LD A,$8E - OUT (C),A ; R#14 = 4 -> A16 = 1, A15..A14 = 0 + LD A,$8E + OUT (C),A ; R#14 = 4 -> A16 = 1, A15..A14 = 0 CALL DLY64 ; DELAY - XOR A - OUT (C),A ; A7..A0 = 0 + XOR A + OUT (C),A ; A7..A0 = 0 CALL DLY64 ; DELAY - OR $40 - OUT (C),A ; SET WR, A13..A8 = 0 + OR $40 + OUT (C),A ; SET WR, A13..A8 = 0 CALL DLY64 ; DELAY - LD A,$76 + LD A,$76 CALL DLY64 ; DELAY LD C, TMS_DATREG - OUT (C),A ; SET VRAM $10000 = $76 + OUT (C),A ; SET VRAM $10000 = $76 CALL DLY64 ; DELAY - XOR A + XOR A LD C, TMS_CMDREG - OUT (C),A ; A7..A0 = 0 + OUT (C),A ; A7..A0 = 0 CALL DLY64 ; DELAY - OUT (C),A ; SET RD, A13..A8 = 0 + OUT (C),A ; SET RD, A13..A8 = 0 CALL DLY64 ; DELAY LD C, TMS_DATREG - IN A,(C) ; A = VRAM $10000 + IN A,(C) ; A = VRAM $10000 CALL DLY64 ; DELAY - CP $76 - JR Z,VRAMSIZE_128K ; IF ITS $76, WE HAVE AT LEAST 128K + CP $76 + JR Z,VRAMSIZE_128K ; IF ITS $76, WE HAVE AT LEAST 128K ; OTHERWISE ITS ONLY 64K - JR VRAMSIZE_DONE + JR VRAMSIZE_DONE VRAMSIZE_128K: ; WE HAVE AT LEAST 128K @@ -932,34 +932,34 @@ VRAMSIZE_128K: OUT (C), A ; R#45 = $40 (MXC=1, MXD,MXS,DIY,DIX,EQ,MAJ=0) CALL DLY64 ; DELAY - LD A,1 - OUT (C),A + LD A,1 + OUT (C),A CALL DLY64 ; DELAY - LD A,$8E - OUT (C),A ; R#14 = 4 -> A16 = 0, A15..A14 = 1 + LD A,$8E + OUT (C),A ; R#14 = 4 -> A16 = 0, A15..A14 = 1 CALL DLY64 ; DELAY - XOR A - OUT (C),A ; A7..A0 = 0 + XOR A + OUT (C),A ; A7..A0 = 0 CALL DLY64 ; DELAY - OR $40 - OUT (C),A ; SET WR, A13..A8 = 0 + OR $40 + OUT (C),A ; SET WR, A13..A8 = 0 CALL DLY64 ; DELAY - LD A,$5A + LD A,$5A CALL DLY64 ; DELAY LD C, TMS_DATREG - OUT (C),A ; SET VRAM $14000 = $76 + OUT (C),A ; SET VRAM $14000 = $76 CALL DLY64 ; DELAY - XOR A + XOR A LD C, TMS_CMDREG - OUT (C),A ; A7..A0 = 0 + OUT (C),A ; A7..A0 = 0 CALL DLY64 ; DELAY - OUT (C),A ; SET RD, A13..A8 = 0 + OUT (C),A ; SET RD, A13..A8 = 0 CALL DLY64 ; DELAY LD C, TMS_DATREG - IN A,(C) ; A = VRAM $14000 + IN A,(C) ; A = VRAM $14000 CALL DLY64 ; DELAY - CP $5A - JR NZ,VRAMSIZE_DONE ; IF ITS $5A, WE HAVE EXAPANSION VRAM + CP $5A + JR NZ,VRAMSIZE_DONE ; IF ITS $5A, WE HAVE EXAPANSION VRAM EX AF, AF' INC A ; SET RETURN VALUE TO 2 FOR 192K @@ -974,11 +974,11 @@ VRAMSIZE_DONE: OUT (C), A ; R#45 = $00 (MXC=0, MXD,MXS,DIY,DIX,EQ,MAJ=0) CALL DLY64 ; DELAY - XOR A - OUT (C),A + XOR A + OUT (C),A CALL DLY64 ; DELAY - LD A,$8E - OUT (C),A ; R#14 = 0 -> A16..A14 = 0 + LD A,$8E + OUT (C),A ; R#14 = 0 -> A16..A14 = 0 EX AF, AF' RET