Browse Source

Merge pull request #643 from dinoboards/dean-dev-2016-01-06-tms-vram-reporting

HBIOS/TMS Driver: updated to probe and detect VDP chip type and amount of VRAM available
pull/644/head
Wayne Warthen 3 weeks ago
committed by GitHub
parent
commit
31b2325037
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 259
      Source/HBIOS/tms.asm

259
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,10 +321,68 @@ 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=$"
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 VRAM=16KB INTERRUPT=60HZ$"
JR TMS_INIT3
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:
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
@ -330,7 +391,6 @@ TMS_INIT1:
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
@ -712,12 +772,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 +785,205 @@ 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
; 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
;----------------------------------------------------------------------

Loading…
Cancel
Save