Files
RomWBW/Source/HBIOS/tms.asm
Wayne Warthen 1d8c0c9c46 eZ80 Follow-up
- Added RCEZ80 platform option to Build.ps1
- Added EZ80 config settings to MASTER config (required to get build to work for some situations)
- Modified a .EQU in cfg_RCEZ80.asm to a .SET.  After adding config setting to MASTER config, the .EQU was causing a redefinition error.
- I have temporarily removed some "TRANSLATE" lines in ez80uart.asm.  They were attempting to place a value greater that 0xFFFF in a register and generated an assembly error.
- Modified a few JR instructions in hbios.asm to JP due to out-of-range errors.
- Modified std.asm to "nest" a conditional.  The Windows assembler does not ignore the remainder of a complex conditional when it should.
- Modified tms.asm to replace the PRTS macro with alternative lines.  The Windows assembler cannot handle a string longer than about 8 characters in a macro argument.
- Added the TIMER utility to the ROM disk.  Not sure what happened there.  It was included in the Windows build, but not the Linux build.  There is room for it, so I added it to the Linux build to get a binary exact build compare.
2024-09-15 13:54:31 -07:00

1307 lines
36 KiB
NASM

;======================================================================
; TMS9918, V9938/58 VDU DRIVER
;
; WRITTEN BY: DOUGLAS GOODALL
; UPDATED BY: WAYNE WARTHEN -- 4/7/2013
; 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
;======================================================================
;
; TODO:
; - IMPLEMENT SET CURSOR STYLE (VDASCS) FUNCTION?
; - IMPLEMENT ALTERNATE DISPLAY MODES?
; - IMPLEMENT DYNAMIC READ/WRITE OF CHARACTER BITMAP DATA?
;
;======================================================================
; TMS DRIVER - CONSTANTS
;======================================================================
;
;
;
; 40 Column Video Memory Map
; -----------------------------------
; Start Length
; Pattern Table: $0000 $0800 Font data (8 x 256)
; Unused: $0800 $1000
; Sprite Patterns: $1800 $0800
; Color Table: $2000 $1800
; Name Table: $3800 $0400 Display characters (40 x 25)
; Sprite Attributes: $3B00 $0100
; Unused: $3C00 $0400
;
; 80 Column Video Memory Map (MSX like)
; -------------------------------------
; Start Length
; Pattern Table: $1000 $0800 Font data (8 x 256)
; Sprite Patterns: $???? $????
; Color Table: $???? $????
; Name Table: $0000 $0800 Display characters (80 x 25)
; Sprite Attributes: $???? $????
; Unused: $???? $????
;
TMSCTRL1: .EQU 1 ; CONTROL BITS
TMSINTEN: .EQU 5 ; INTERRUPT ENABLE BIT
;
TMSKBD_NONE .EQU 0
TMSKBD_KBD .EQU 1
TMSKBD_PPK .EQU 2
TMSKBD_MKY .EQU 3
TMSKBD_NABU .EQU 4
;
TMSKBD .EQU TMSKBD_NONE ; ASSUME NONE
;
DEVECHO "TMS: MODE="
;
#IF (TMSMODE == TMSMODE_SCG)
TMS_DATREG .EQU $98 ; READ/WRITE DATA
TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL
TMS_ACR .EQU $9C ; AUX CONTROL REGISTER
DEVECHO "SCG"
#ENDIF
;
#IF (TMSMODE == TMSMODE_N8)
TMS_DATREG .EQU $98 ; READ/WRITE DATA
TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL
TMS_PPIA .EQU $84 ; PPI PORT A
TMS_PPIB .EQU $85 ; PPI PORT B
TMS_PPIC .EQU $86 ; PPI PORT C
TMS_PPIX .EQU $87 ; PPI CONTROL PORT
TMSKBD .SET TMSKBD_PPK ; PPK KEYBOARD
DEVECHO "N8"
#ENDIF
;
#IF (TMSMODE == TMSMODE_MSX)
TMS_DATREG .EQU $98 ; READ/WRITE DATA
TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL
#ENDIF
;
#IF (TMSMODE == TMSMODE_MSXKBD)
TMS_DATREG .EQU $98 ; READ/WRITE DATA
TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL
TMS_KBDDATA .EQU $60 ; KBD CTLR DATA PORT
TMS_KBDST .EQU $64 ; KBD CTLR STATUS/CMD PORT
TMSKBD .SET TMSKBD_KBD ; PS2 KEYBOARD
DEVECHO "MSXKBD"
#ENDIF
;
#IF (TMSMODE == TMSMODE_MSXMKY)
TMS_DATREG .EQU $98 ; READ/WRITE DATA
TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL
TMSKBD .SET TMSKBD_MKY ; MSX KEYBOARD
DEVECHO "MSXMKY"
#ENDIF
;
#IF (TMSMODE == TMSMODE_MBC)
TMS_DATREG .EQU $98 ; READ/WRITE DATA
TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL
TMS_ACR .EQU $9C ; AUX CONTROL REGISTER
TMS_KBDDATA .EQU $E2 ; KBD CTLR DATA PORT
TMS_KBDST .EQU $E3 ; KBD CTLR STATUS/CMD PORT
TMSKBD .SET TMSKBD_KBD ; PS2 KEYBOARD
DEVECHO "MBC"
#ENDIF
;
#IF (TMSMODE == TMSMODE_COLECO)
TMS_DATREG .EQU $BE ; READ/WRITE DATA
TMS_CMDREG .EQU $BF ; READ STATUS / WRITE REG SEL
DEVECHO "COLECO"
#ENDIF
;
#IF (TMSMODE == TMSMODE_DUO)
TMS_DATREG .EQU $A0 ; READ/WRITE DATA
TMS_CMDREG .EQU $A1 ; READ STATUS / WRITE REG SEL
TMS_ACR .EQU $A6 ; AUX CONTROL REGISTER
TMS_KBDDATA .EQU $4C ; KBD CTLR DATA PORT
TMS_KBDST .EQU $4D ; KBD CTLR STATUS/CMD PORT
TMSKBD .SET TMSKBD_KBD ; PS2 KEYBOARD
DEVECHO "DUO"
#ENDIF
;
#IF (TMSMODE == TMSMODE_NABU)
TMS_DATREG .EQU $A0 ; READ/WRITE DATA
TMS_CMDREG .EQU $A1 ; READ STATUS / WRITE REG SEL
TMSKBD .SET TMSKBD_NABU ; NABU KEYBOARD
#ENDIF
;
DEVECHO ", IO="
DEVECHO TMS_DATREG
;
TMS_ROWS .EQU 24
;
#IF (TMS80COLS)
TMS_FNTVADDR .EQU $1000 ; VRAM ADDRESS OF FONT DATA
TMS_FNTSIZE .EQU 8*256 ; ### JLC Mod for JBL compatibility ### = 8x8 Font 256 Chars
TMS_CHRVADDR .EQU $0000 ; VRAM ADDRESS OF CHAR SCREEN DATA (NEW CONSTANT) = REG2 * $400
TMS_COLS .EQU 80
#ELSE ; ALL OTHER MODES...
;TMS_FNTVADDR .EQU $0800 ; VRAM ADDRESS OF FONT DATA
TMS_FNTVADDR .EQU $0000 ; VRAM ADDRESS OF FONT DATA ### JLC Mod for JBL compatibility ### = REG4 * $800
TMS_FNTSIZE .EQU 8*256 ; ### JLC Mod for JBL compatibility ### = 8x8 Font 256 Chars
; ### JLC Fix to allow Name Table Addresses other than $0000 and JBL Compatibility ###
TMS_CHRVADDR .EQU $3800 ; VRAM ADDRESS OF CHAR SCREEN DATA (NEW CONSTANT) = REG2 * $400
TMS_COLS .EQU 40
#ENDIF
;
DEVECHO ", SCREEN="
DEVECHO TMS_COLS
DEVECHO "X"
DEVECHO TMS_ROWS
;
#DEFINE USEFONT8X8
#DEFINE TMS_FONT FONT8X8
;
TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER
;
DEVECHO ", KEYBOARD="
;
#IF (TMSKBD == TMSKBD_NONE)
DEVECHO "NONE"
#ENDIF
;
#IF (TMSKBD == TMSKBD_PPK)
PPKENABLE .SET TRUE ; INCLUDE PPK KEYBOARD SUPPORT
DEVECHO "PPK"
#ENDIF
;
#IF (TMSKBD == TMSKBD_KBD)
KBDENABLE .SET TRUE ; INCLUDE PS2 KEYBOARD SUPPORT
DEVECHO "KBD"
#ENDIF
;
#IF (TMSKBD == TMSKBD_MKY)
MKYENABLE .SET TRUE ; INCLUDE MSX KEYBOARD SUPPORT
DEVECHO "MKY"
#ENDIF
;
#IF (TMSKBD == TMSKBD_NABU)
NABUKBENABLE .SET TRUE ; INCLUDE NABU KEYBOARD SUPPORT
DEVECHO "NABU"
#ENDIF
;
#IF (TMSTIMENABLE & (INTMODE > 0))
DEVECHO ", INTERRUPTS ENABLED"
#ENDIF
DEVECHO "\n"
;
; TMS_IODELAY IS USED TO ADD RECOVERY TIME TO TMS9918/V9958 ACCESSES
; IF YOU SEE SCREEN CORRUPTION, ADJUST THIS!!!
;
#IF (CPUFAM == CPU_Z180)
; BELOW WAS TUNED FOR Z180 AT 18MHZ
#DEFINE TMS_IODELAY EX (SP),HL \ EX (SP),HL ; 38 W/S
;#DEFINE TMS_IODELAY NOP \ NOP \ NOP \ NOP \ NOP ; 20 W/S ### JLC Mod for Clock/2 (9 MHz) ###
#ELSE
; BELOW WAS TUNED FOR Z80 AT 8MHZ
#IF (TMS80COLS)
#DEFINE TMS_IODELAY NOP \ NOP \ NOP \ NOP \ NOP \ NOP \ NOP ; V9958 NEEDS AT WORST CASE, APPROX 4us (28T) DELAY BETWEEN I/O (WHEN IN TEXT MODE)
#ELSE
#DEFINE TMS_IODELAY NOP \ NOP ; 8 W/S
#ENDIF
#ENDIF
;
;======================================================================
; TMS DRIVER - INITIALIZATION
;======================================================================
;
TMS_PREINIT:
; DISABLE INTERRUPT GENERATION UNTIL AFTER INTERRUPT HANDLER
; HAS BEEN INSTALLED.
LD A, (TMS_INITVDU_REG_1)
RES TMSINTEN, A ; RESET INTERRUPT ENABLE BIT
LD (TMS_INITVDU_REG_1), A
LD C, TMSCTRL1
JP TMS_SET
;
TMS_INIT:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
;
#IF ((TMSMODE == TMSMODE_SCG) | (TMSMODE == TMSMODE_MBC) | (TMSMODE == TMSMODE_DUO))
LD A,$FF
EZ80_IO
OUT (TMS_ACR),A ; INIT AUX CONTROL REG
#ENDIF
;
CALL NEWLINE ; FORMATTING
PRTS("TMS: MODE=$")
#IF ((TMSMODE == TMSMODE_MBC) | (TMSMODE == TMSMODE_DUO))
LD A,$FE
EZ80_IO
OUT (TMS_ACR),A ; CLEAR VDP RESET
#ENDIF
;
LD IY,TMS_IDAT ; POINTER TO INSTANCE DATA
;
#IF (TMSMODE == TMSMODE_SCG)
PRTS("SCG$")
#ENDIF
#IF (TMSMODE == TMSMODE_N8)
PRTS("N8$")
#ENDIF
#IF (TMSMODE == TMSMODE_MSX)
PRTS("MSX$")
#ENDIF
#IF (TMSMODE == TMSMODE_MSXKBD)
PRTS("MSXKBD$")
#ENDIF
#IF (TMSMODE == TMSMODE_MSXMKY)
PRTS("MSXMKY$")
#ENDIF
#IF (TMSMODE == TMSMODE_MBC)
PRTS("MBC$")
#ENDIF
#IF (TMSMODE == TMSMODE_COLECO)
PRTS("COLECO$")
#ENDIF
#IF (TMSMODE == TMSMODE_DUO)
PRTS("DUO$")
#ENDIF
#IF (TMSMODE == TMSMODE_NABU)
PRTS("NABU$")
#ENDIF
;
PRTS(" IO=0x$")
LD A,TMS_DATREG
CALL PRTHEXBYTE
CALL TMS_PROBE ; CHECK FOR HW EXISTENCE
JR Z,TMS_INIT1 ; CONTINUE IF PRESENT
;
; *** HARDWARE NOT PRESENT ***
PRTS(" NOT PRESENT$")
OR $FF ; SIGNAL FAILURE
RET
;
TMS_INIT1:
#IF (TMSTIMENABLE)
CALL PRTSTRD
.TEXT " INTERRUPT ENABLED$"
#ENDIF
CALL PC_SPACE
LD A,TMS_COLS
CALL PRTDEC8
LD A,'X'
CALL COUT
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
CALL TMS_CLEAR ; CLEAR SCREEN, HOME CURSOR
#IF (TMSKBD == TMSKBD_PPK)
CALL PPK_INIT ; INITIALIZE PPI KEYBOARD DRIVER
#ENDIF
#IF (TMSKBD == TMSKBD_KBD)
CALL KBD_INIT ; INITIALIZE 8242 KEYBOARD DRIVER
#ENDIF
#IF (TMSKBD == TMSKBD_MKY)
CALL MKY_INIT ; INITIALIZE MKY KEYBOARD DRIVER
#ENDIF
#IF (TMSKBD == TMSKBD_NABU)
CALL NABUKB_INIT ; INITIALIZE NABU KEYBOARD DRIVER
#ENDIF
#IF (TMSTIMENABLE & (INTMODE > 0))
;
#IF (INTMODE == 1)
; ADD IM1 INT CALL LIST ENTRY
LD HL,TMS_TSTINT ; GET INT VECTOR
CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST
#ELSE
; INSTALL VECTOR
LD HL,TMS_TSTINT
LD (IVT(INT_VDP)),HL ; IVT INDEX
#ENDIF
;
; ENABLE VDP INTERRUPTS NOW
LD A, (TMS_INITVDU_REG_1)
SET TMSINTEN,A ; SET INTERRUPT ENABLE BIT
LD (TMS_INITVDU_REG_1),A
LD C, TMSCTRL1
CALL TMS_SET
;
#IF (TMSMODE == TMSMODE_NABU)
; ENABLE VDP INTERRUPTS ON NABU INTERRUPT CONTROLLER
LD A,14 ; PSG R14 (PORT A DATA)
OUT (NABU_RSEL),A ; SELECT IT
LD A,(NABU_CTLVAL) ; GET NABU CTL PORT SHADOW REG
SET 4,A ; ENABLE VDP INTERRUPTS
LD (NABU_CTLVAL),A ; UPDATE SHADOW REG
OUT (NABU_RDAT),A ; WRITE TO HARDWARE
#ENDIF
;
#ENDIF
;
; ADD OURSELVES TO VDA DISPATCH TABLE
LD BC,TMS_FNTBL ; BC := FUNCTION TABLE ADDRESS
LD DE,TMS_IDAT ; DE := TMS INSTANCE DATA PTR
CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
;
; INITIALIZE EMULATION
LD C,A ; C := ASSIGNED VIDEO DEVICE NUM
LD DE,TMS_FNTBL ; DE := FUNCTION TABLE ADDRESS
LD HL,TMS_IDAT ; HL := TMS INSTANCE DATA PTR
CALL TERM_ATTACH ; DO IT
;
XOR A ; SIGNAL SUCCESS
RET
;
;======================================================================
; TMS DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS
;======================================================================
;
TMS_FNTBL:
.DW TMS_VDAINI
.DW TMS_VDAQRY
.DW TMS_VDARES
.DW TMS_VDADEV
.DW TMS_VDASCS
.DW TMS_VDASCP
.DW TMS_VDASAT
.DW TMS_VDASCO
.DW TMS_VDAWRC
.DW TMS_VDAFIL
.DW TMS_VDACPY
.DW TMS_VDASCR
#IF (TMSKBD == TMSKBD_NONE)
.DW TMS_STAT
.DW TMS_FLUSH
.DW TMS_READ
#ENDIF
#IF (TMSKBD == TMSKBD_PPK)
.DW PPK_STAT
.DW PPK_FLUSH
.DW PPK_READ
#ENDIF
#IF (TMSKBD == TMSKBD_KBD)
.DW KBD_STAT
.DW KBD_FLUSH
.DW KBD_READ
#ENDIF
#IF (TMSKBD == TMSKBD_MKY)
.DW MKY_STAT
.DW MKY_FLUSH
.DW MKY_READ
#ENDIF
#IF (TMSKBD == TMSKBD_NABU)
.DW NABUKB_STAT
.DW NABUKB_FLUSH
.DW NABUKB_READ
#ENDIF
.DW TMS_VDARDC
#IF (($ - TMS_FNTBL) != (VDA_FNCNT * 2))
.ECHO "*** INVALID TMS FUNCTION TABLE ***\n"
!!!!!
#ENDIF
;
TMS_VDAINI:
; RESET VDA
; CURRENTLY IGNORES VIDEO MODE AND BITMAP DATA
CALL TMS_VDARES ; RESET VDA
CALL TMS_CLEAR ; CLEAR SCREEN
XOR A ; SIGNAL SUCCESS
RET
;
TMS_VDAQRY:
LD C,$00 ; MODE ZERO IS ALL WE KNOW
LD D,TMS_ROWS ; ROWS
LD E,TMS_COLS ; COLS
LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET
XOR A ; SIGNAL SUCCESS
RET
;
TMS_VDARES:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
CALL TMS_CRTINIT1A
CALL TMS_CLRCUR ; CLEAR CURSOR
CALL TMS_LOADFONT ; RELOAD FONT
LD A,$FF ; REMOVE
LD (TMS_CURSAV),A ; ... SAVED CURSOR CHAR
CALL TMS_SETCUR ; RESTORE CURSOR
XOR A
RET
TMS_VDADEV:
LD D,VDADEV_TMS ; D := DEVICE TYPE
LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO
LD H,TMSMODE ; H := MODE
LD L,TMS_DATREG ; L := BASE I/O ADDRESS
XOR A ; SIGNAL SUCCESS
RET
TMS_VDASCS:
SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED (YET)
RET
TMS_VDASCP:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
CALL TMS_CLRCUR
CALL TMS_XY ; SET CURSOR POSITION
CALL TMS_SETCUR
XOR A ; SIGNAL SUCCESS
RET
TMS_VDASAT:
XOR A ; NOT POSSIBLE, JUST SIGNAL SUCCESS
RET
TMS_VDASCO:
; ### JLC Mod - Implement Default Text Mode Colors via ANSI_VDASCO or direct HBIOS Call
;
; Color setting is in reg D in ANSI Format as described in RomWBW System Guide
; Convert Color Format from ANSI to TMS shuffling bits arround and using
; Color Conversion Table at TMS_COLOR_TBL (approximated equivalences)
; Save converted value to (TMS_TMSCOLOR)
;
; TMS hardware only allows setting a global (screen) foreground/background color. So, we
; only process this command if E is 1.
;
LD A,D ; GET CHAR/SCREEN SCOPE
CP 1 ; SCREEN?
JR NZ,TMS_VDASCO_Z ; IF NOT, JUST RETURN
;
LD A,E ; GET COLOR BYTE
AND $F0 ; ISOLATE BACKGROUND
RRCA \ RRCA \ RRCA \ RRCA ; MOVE TO LOWER NIBBLE
LD HL,TMS_COLOR_TBL ; POINT TO COLOR CONVERSION TABLE
CALL ADDHLA ; OFFSET TO DESIRED COLOR
LD B,(HL) ; PUT NEW BG IN B
;
LD A,E ; GET COLOR BYTE
AND $0F ; ISOLATE FOREGROUND
LD HL,TMS_COLOR_TBL ; POINT TO COLOR CONVERSION TABLE
CALL ADDHLA ; OFFSET TO DESIRED COLOR
LD A,(HL) ; PUT NEW FG IN A
RLCA \ RLCA \ RLCA \ RLCA ; MOVE TO UPPER NIBBLE
;
OR B ; COMBINE WITH FG
LD C, 7 ; C = Color Register, A = Desired new Color in TMS Format
CALL TMS_SET ; Write to specific TMS Register, Change Default Text Color
;
TMS_VDASCO_Z:
XOR A ; SIGNAL SUCCESS
RET
TMS_VDAWRC:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
CALL TMS_CLRCUR ; CURSOR OFF
LD A,E ; CHARACTER TO WRITE GOES IN A
CALL TMS_PUTCHAR ; PUT IT ON THE SCREEN
CALL TMS_SETCUR
XOR A ; SIGNAL SUCCESS
RET
TMS_VDAFIL:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
CALL TMS_CLRCUR
LD A,E ; FILL CHARACTER GOES IN A
EX DE,HL ; FILL LENGTH GOES IN DE
CALL TMS_FILL ; DO THE FILL
CALL TMS_SETCUR
XOR A ; SIGNAL SUCCESS
RET
TMS_VDACPY:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
CALL TMS_CLRCUR
; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS TMS_POS
; BLKCPY USES: HL=SOURCE, DE=DEST, BC=COUNT
PUSH HL ; SAVE LENGTH
CALL TMS_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL
POP BC ; RECOVER LENGTH IN BC
LD DE,(TMS_POS) ; PUT DEST IN DE
CALL TMS_BLKCPY ; DO A BLOCK COPY
CALL TMS_SETCUR
XOR A
RET
TMS_VDASCR:
#IF (CPUFAM == CPU_Z180)
CALL TMS_Z180IO
#ENDIF
CALL TMS_CLRCUR
TMS_VDASCR0:
LD A,E ; LOAD E INTO A
OR A ; SET FLAGS
JR Z,TMS_VDASCR2 ; IF ZERO, WE ARE DONE
PUSH DE ; SAVE E
JP M,TMS_VDASCR1 ; E IS NEGATIVE, REVERSE SCROLL
CALL TMS_SCROLL ; SCROLL FORWARD ONE LINE
POP DE ; RECOVER E
DEC E ; DECREMENT IT
JR TMS_VDASCR0 ; LOOP
TMS_VDASCR1:
CALL TMS_RSCROLL ; SCROLL REVERSE ONE LINE
POP DE ; RECOVER E
INC E ; INCREMENT IT
JR TMS_VDASCR0 ; LOOP
TMS_VDASCR2:
CALL TMS_SETCUR
XOR A
RET
;----------------------------------------------------------------------
; READ VALUE AT CURRENT VDU BUFFER POSITION
; RETURN E = CHARACTER, B = COLOUR, C = ATTRIBUTES
;----------------------------------------------------------------------
TMS_VDARDC:
OR $FF ; UNSUPPORTED FUNCTION
RET
; DUMMY FUNCTIONS BELOW BECAUSE SCG BOARD HAS NO
; KEYBOARD INTERFACE
TMS_STAT:
XOR A ; SIGNAL NOTHING READY
JP CIO_IDLE ; DO IDLE PROCESSING
TMS_FLUSH:
XOR A ; SIGNAL SUCCESS
RET
TMS_READ:
LD E,26 ; RETURN <SUB> (CTRL-Z)
XOR A ; SIGNAL SUCCESS
RET
;
;======================================================================
; TMS DRIVER - PRIVATE DRIVER FUNCTIONS
;======================================================================
;
;----------------------------------------------------------------------
; SET TMS9918 REGISTER VALUE
; TMS_SET WRITES VALUE IN A TO VDU REGISTER SPECIFIED IN C
;----------------------------------------------------------------------
;
TMS_SET:
HB_DI
EZ80_IO
OUT (TMS_CMDREG),A ; WRITE IT
TMS_IODELAY
LD A,C ; GET THE DESIRED REGISTER
OR $80 ; SET BIT 7
EZ80_IO
OUT (TMS_CMDREG),A ; SELECT THE DESIRED REGISTER
TMS_IODELAY
HB_EI
RET
;
;----------------------------------------------------------------------
; SET TMS9918 READ/WRITE ADDRESS
; TMS_WR SETS TMS9918 TO BEGIN WRITING AT VDU ADDRESS SPECIFIED IN HL
; TMS_RD SETS TMS9918 TO BEGIN READING AT VDU ADDRESS SPECIFIED IN HL
;----------------------------------------------------------------------
;
TMS_WR:
#IF (TMS80COLS)
; CLEAR R#14 FOR V9958
HB_DI
XOR A
EZ80_IO
OUT (TMS_CMDREG), A
TMS_IODELAY
LD A, $80 | 14
EZ80_IO
OUT (TMS_CMDREG), A
TMS_IODELAY
HB_EI
#ENDIF
PUSH HL
SET 6,H ; SET WRITE BIT
CALL TMS_RD
POP HL
RET
;
TMS_RD:
HB_DI
LD A,L
EZ80_IO
OUT (TMS_CMDREG),A
TMS_IODELAY
LD A,H
EZ80_IO
OUT (TMS_CMDREG),A
TMS_IODELAY
HB_EI
RET
;
;----------------------------------------------------------------------
; PROBE FOR TMS HARDWARE
;----------------------------------------------------------------------
;
; ON RETURN, ZF SET INDICATES HARDWARE FOUND
;
TMS_PROBE:
; SET WRITE ADDRESS TO $0000
LD HL,0
CALL TMS_WR
; WRITE TEST PATTERN TO FIRST TWO BYTES
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
LD HL,0
CALL TMS_RD
; READ TEST PATTERN
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
;
;----------------------------------------------------------------------
; TMS9918 DISPLAY CONTROLLER CHIP INITIALIZATION
;----------------------------------------------------------------------
;
TMS_CRTINIT:
; SET WRITE ADDRESS TO $0000 Beginning of VRAM
LD HL,0
CALL TMS_WR
;
; FILL ENTIRE 16KB VRAM CONTENTS with $00
LD DE,$4000 ; 16KB
TMS_CRTINIT1:
XOR A
EZ80_IO
OUT (TMS_DATREG),A
TMS_IODELAY ; DELAY
DEC DE
LD A,D
OR E
JR NZ,TMS_CRTINIT1
;
TMS_CRTINIT1A:
;
; INITIALIZE VDU REGISTERS
LD C,0 ; START WITH REGISTER 0
LD B,TMS_INITVDULEN ; NUMBER OF REGISTERS TO INIT
LD HL,TMS_INITVDU ; HL = POINTER TO THE DEFAULT VALUES
TMS_CRTINIT2:
LD A,(HL) ; GET VALUE
CALL TMS_SET ; WRITE IT
INC HL ; POINT TO NEXT VALUE
INC C ; POINT TO NEXT REGISTER
DJNZ TMS_CRTINIT2 ; LOOP
;
; ENABLE WAIT SIGNAL IF 9938/58
#IF (TMS80COLS)
LD C,25 ; REGISTER 25
LD A,%00000100 ; ONLY WTE BIT SET
CALL TMS_SET ; DO IT
#ENDIF
RET
;
;----------------------------------------------------------------------
; CLEAR SCREEN AND HOME CURSOR
;----------------------------------------------------------------------
;
TMS_CLEAR:
LD DE,0 ; ROW = 0, COL = 0
CALL TMS_XY ; SEND CURSOR TO TOP LEFT
LD A,' ' ; BLANK THE SCREEN
LD DE,TMS_ROWS * TMS_COLS ; FILL ENTIRE BUFFER
CALL TMS_FILL ; DO IT
LD DE,0 ; ROW = 0, COL = 0
CALL TMS_XY ; SEND CURSOR TO TOP LEFT
XOR A
DEC A
LD (TMS_CURSAV),A
CALL TMS_SETCUR ; SET CURSOR
;
XOR A ; SIGNAL SUCCESS
RET
;
;----------------------------------------------------------------------
; LOAD FONT DATA
;----------------------------------------------------------------------
;
TMS_LOADFONT:
; SET WRITE ADDRESS TO TMS_FNTVADDR
LD HL,TMS_FNTVADDR
CALL TMS_WR
;
; THE USE OF COMPRESSED FONT STORAGE FOR THE TMS DRIVER IS DISABLED
; SO THAT WE CAN RELOAD THE FONT DATA ON USER RESET. THE TMS CHIP
; IS FREQUENTLY REPROGRAMMED BY GAMES, ETC., SO IT IS NECESSARY TO
; REINIT AND RELOAD FONTS. RELOADING A COMPRESSED FONT AFTER
; SYSTEM INITIALIZATION REQUIRES A LARGE DECOMPRESSION BUFFER THAT WE
; HAVE NO WAY TO ACCOMMODATE WITHOUT TRASHING OS/APP MEMORY.
;
#IF USELZSA2 & FALSE
LD (TMS_STACK),SP ; SAVE STACK
LD HL,(TMS_STACK) ; AND SHIFT IT
LD DE,$2000 ; DOWN 4KB TO
CCF ; CREATE A
SBC HL,DE ; DECOMPRESSION BUFFER
LD SP,HL ; HL POINTS TO BUFFER
EX DE,HL ; START OF STACK BUFFER
PUSH DE ; SAVE IT
LD HL,TMS_FONT ; START OF FONT DATA
CALL DLZSA2 ; DECOMPRESS TO DE
POP HL ; RECALL STACK BUFFER POSITION
#ELSE
LD HL,TMS_FONT ; START OF FONT DATA
#ENDIF
;
; FILL TMS_FNTVADDR BYTES FROM FONTDATA
LD DE,TMS_FNTSIZE
TMS_LOADFONT1:
LD A,(HL)
EZ80_IO
OUT (TMS_DATREG),A
TMS_IODELAY ; DELAY
INC HL
DEC DE
LD A,D
OR E
JR NZ,TMS_LOADFONT1
;
#IF USELZSA2 & FALSE
LD HL,(TMS_STACK) ; ERASE DECOMPRESS BUFFER
LD SP,HL ; BY RESTORING THE STACK
RET ; DONE
TMS_STACK .DW 0
#ELSE
RET
#ENDIF
;
;----------------------------------------------------------------------
; VIRTUAL CURSOR MANAGEMENT
; TMS_SETCUR CONFIGURES AND DISPLAYS CURSOR AT CURRENT CURSOR LOCATION
; TMS_CLRCUR REMOVES THE CURSOR
;
; VIRTUAL CURSOR IS GENERATED BY DYNAMICALLY CHANGING FONT GLYPH
; FOR CHAR 255 TO BE THE INVERSE OF THE GLYPH OF THE CHARACTER UNDER
; THE CURRENT CURSOR POSITION. THE CHARACTER CODE IS THEN SWITCHED TO
; THE VALUE 255 AND THE ORIGINAL VALUE IS SAVED. WHEN THE DISPLAY
; NEEDS TO BE CHANGED THE PROCESS IS UNDONE. IT IS ESSENTIAL THAT
; ALL DISPLAY CHANGES BE BRACKETED WITH CALLS TO TMS_CLRCUR PRIOR TO
; CHANGES AND TMS_SETCUR AFTER CHANGES.
;----------------------------------------------------------------------
;
TMS_SETCUR:
PUSH HL ; PRESERVE HL
PUSH DE ; PRESERVE DE
LD HL,(TMS_POS) ; GET CURSOR POSITION
CALL TMS_RD ; SETUP TO READ VDU BUF
EZ80_IO
IN A,(TMS_DATREG) ; GET REAL CHAR UNDER CURSOR
TMS_IODELAY ; DELAY
PUSH AF ; SAVE THE CHARACTER
CALL TMS_WR ; SETUP TO WRITE TO THE SAME PLACE
LD A,$FF ; REPLACE REAL CHAR WITH 255
EZ80_IO
OUT (TMS_DATREG),A ; DO IT
TMS_IODELAY ; DELAY
POP AF ; RECOVER THE REAL CHARACTER
LD B,A ; PUT IT IN B
LD A,(TMS_CURSAV) ; GET THE CURRENTLY SAVED CHAR
CP B ; COMPARE TO CURRENT
JR Z,TMS_SETCUR3 ; IF EQUAL, BYPASS EXTRA WORK
LD A,B ; GET REAL CHAR BACK TO A
LD (TMS_CURSAV),A ; SAVE IT
; GET THE GLYPH DATA FOR REAL CHARACTER
LD HL,0 ; ZERO HL
LD L,A ; HL IS NOW RAW CHAR INDEX
LD B,3 ; LEFT SHIFT BY 3 BITS
TMS_SETCUR0: ; MULT BY 8 FOR FONT INDEX
SLA L ; SHIFT LSB INTO CARRY
RL H ; SHFT MSB FROM CARRY
DJNZ TMS_SETCUR0 ; LOOP 3 TIMES
LD DE,TMS_FNTVADDR ; OFFSET TO START OF FONT TABLE
ADD HL,DE ; ADD TO FONT INDEX
CALL TMS_RD ; SETUP TO READ GLYPH
LD B,8 ; 8 BYTES
LD HL,TMS_BUF ; INTO BUFFER
TMS_SETCUR1: ; READ GLYPH LOOP
EZ80_IO
IN A,(TMS_DATREG) ; GET NEXT BYTE
TMS_IODELAY ; IO DELAY
LD (HL),A ; SAVE VALUE IN BUF
INC HL ; BUMP BUF POINTER
DJNZ TMS_SETCUR1 ; LOOP FOR 8 BYTES
;
; NOW WRITE INVERTED GLYPH INTO FONT INDEX 255
LD HL,TMS_FNTVADDR + (255 * 8) ; LOC OF GLPYPH DATA FOR CHAR 255
CALL TMS_WR ; SETUP TO WRITE THE INVERTED GLYPH
LD B,8 ; 8 BYTES PER GLYPH
LD HL,TMS_BUF ; POINT TO BUFFER
TMS_SETCUR2: ; WRITE INVERTED GLYPH LOOP
LD A,(HL) ; GET THE BYTE
INC HL ; BUMP THE BUF POINTER
XOR $FF ; INVERT THE VALUE
EZ80_IO
OUT (TMS_DATREG),A ; WRITE IT TO VDU
TMS_IODELAY ; IO DELAY
DJNZ TMS_SETCUR2 ; LOOP FOR ALL 8 BYTES OF GLYPH
;
TMS_SETCUR3: ; RESTORE REGISTERS AND RETURN
POP DE ; RECOVER DE
POP HL ; RECOVER HL
RET ; RETURN
;
;
;
TMS_CLRCUR: ; REMOVE VIRTUAL CURSOR FROM SCREEN
PUSH HL ; SAVE HL
LD HL,(TMS_POS) ; POINT TO CURRENT CURSOR POS
CALL TMS_WR ; SET UP TO WRITE TO VDU
LD A,(TMS_CURSAV) ; GET THE REAL CHARACTER
EZ80_IO
OUT (TMS_DATREG),A ; WRITE IT
TMS_IODELAY ; IO DELAY
POP HL ; RECOVER HL
RET ; RETURN
;
;----------------------------------------------------------------------
; SET CURSOR POSITION TO ROW IN D AND COLUMN IN E
;----------------------------------------------------------------------
;
TMS_XY:
CALL TMS_XY2IDX ; CONVERT ROW/COL TO BUF IDX
LD (TMS_POS),HL ; SAVE THE RESULT (DISPLAY POSITION)
RET
;
;----------------------------------------------------------------------
; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL
; D=ROW, E=COL
;----------------------------------------------------------------------
;
TMS_XY2IDX:
LD A,E ; SAVE COLUMN NUMBER IN A
LD H,D ; SET H TO ROW NUMBER
LD E,TMS_COLS ; SET E TO ROW LENGTH
CALL MULT8 ; MULTIPLY TO GET ROW OFFSET
LD E,A ; GET COLUMN BACK
ADD HL,DE ; ADD IT IN
LD DE,TMS_CHRVADDR ; Add offset Address to start of Name Table (Char)
ADD HL,DE
RET ; RETURN
;
;----------------------------------------------------------------------
; WRITE VALUE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR
;----------------------------------------------------------------------
;
TMS_PUTCHAR:
PUSH AF ; SAVE CHARACTER
LD HL,(TMS_POS) ; LOAD CURRENT POSITION INTO HL
CALL TMS_WR ; SET THE WRITE ADDRESS
POP AF ; RECOVER CHARACTER TO WRITE
EZ80_IO
OUT (TMS_DATREG),A ; WRITE THE CHARACTER
TMS_IODELAY
LD HL,(TMS_POS) ; LOAD CURRENT POSITION INTO HL
INC HL
LD (TMS_POS),HL
RET
;
;----------------------------------------------------------------------
; FILL AREA IN BUFFER WITH SPECIFIED CHARACTER AND CURRENT COLOR/ATTRIBUTE
; STARTING AT THE CURRENT FRAME BUFFER POSITION
; A: FILL CHARACTER
; DE: NUMBER OF CHARACTERS TO FILL
;----------------------------------------------------------------------
;
TMS_FILL:
LD C,A ; SAVE THE CHARACTER TO WRITE
LD HL,(TMS_POS) ; SET STARTING POSITION
CALL TMS_WR ; SET UP FOR WRITE
;
TMS_FILL1:
LD A,C ; RECOVER CHARACTER TO WRITE
EZ80_IO
OUT (TMS_DATREG),A
TMS_IODELAY
DEC DE
LD A,D
OR E
JR NZ,TMS_FILL1
;
RET
;
;----------------------------------------------------------------------
; SCROLL ENTIRE SCREEN FORWARD BY ONE LINE (CURSOR POSITION UNCHANGED)
;----------------------------------------------------------------------
;
TMS_SCROLL:
LD HL,TMS_CHRVADDR ; SOURCE ADDRESS OF CHARACTER BUFFER
LD C,TMS_ROWS - 1 ; SET UP LOOP COUNTER FOR ROWS - 1
;
TMS_SCROLL0: ; READ LINE THAT IS ONE PAST CURRENT DESTINATION
PUSH HL ; SAVE CURRENT DESTINATION
LD DE,TMS_COLS
ADD HL,DE ; POINT TO NEXT ROW SOURCE
CALL TMS_RD ; SET UP TO READ
LD DE,TMS_BUF
LD B,TMS_COLS
TMS_SCROLL1:
EZ80_IO
IN A,(TMS_DATREG)
TMS_IODELAY
LD (DE),A
INC DE
DJNZ TMS_SCROLL1
POP HL ; RECOVER THE DESTINATION
;
; WRITE THE BUFFERED LINE TO CURRENT DESTINATION
CALL TMS_WR ; SET UP TO WRITE
LD DE,TMS_BUF
LD B,TMS_COLS
TMS_SCROLL2:
LD A,(DE)
EZ80_IO
OUT (TMS_DATREG),A
TMS_IODELAY
INC DE
DJNZ TMS_SCROLL2
;
; BUMP TO NEXT LINE
LD DE,TMS_COLS
ADD HL,DE
DEC C ; DECREMENT ROW COUNTER
JR NZ,TMS_SCROLL0 ; LOOP THRU ALL ROWS
;
; FILL THE NEWLY EXPOSED BOTTOM LINE
CALL TMS_WR
LD A,' '
LD B,TMS_COLS
TMS_SCROLL3:
EZ80_IO
OUT (TMS_DATREG),A
TMS_IODELAY
DJNZ TMS_SCROLL3
;
RET
;
;----------------------------------------------------------------------
; REVERSE SCROLL ENTIRE SCREEN BY ONE LINE (CURSOR POSITION UNCHANGED)
;----------------------------------------------------------------------
;
TMS_RSCROLL:
LD HL,TMS_COLS * (TMS_ROWS - 1)
LD DE,TMS_CHRVADDR ; Add offset Address to start of Name Table (Char)
ADD HL,DE
LD C,TMS_ROWS - 1
;
TMS_RSCROLL0: ; READ THE LINE THAT IS ONE PRIOR TO CURRENT DESTINATION
PUSH HL ; SAVE THE DESTINATION ADDRESS
LD DE,-TMS_COLS
ADD HL,DE ; SET SOURCE ADDRESS
CALL TMS_RD ; SET UP TO READ
LD DE,TMS_BUF ; POINT TO BUFFER
LD B,TMS_COLS ; LOOP FOR EACH COLUMN
TMS_RSCROLL1:
EZ80_IO
IN A,(TMS_DATREG) ; GET THE CHAR
TMS_IODELAY ; RECOVER
LD (DE),A ; SAVE IN BUFFER
INC DE ; BUMP BUFFER POINTER
DJNZ TMS_RSCROLL1 ; LOOP THRU ALL COLS
POP HL ; RECOVER THE DESTINATION ADDRESS
;
; WRITE THE BUFFERED LINE TO CURRENT DESTINATION
CALL TMS_WR ; SET THE WRITE ADDRESS
LD DE,TMS_BUF ; POINT TO BUFFER
LD B,TMS_COLS ; INIT LOOP COUNTER
TMS_RSCROLL2:
LD A,(DE) ; LOAD THE CHAR
EZ80_IO
OUT (TMS_DATREG),A ; WRITE TO SCREEN
TMS_IODELAY ; DELAY
INC DE ; BUMP BUF POINTER
DJNZ TMS_RSCROLL2 ; LOOP THRU ALL COLS
;
; BUMP TO THE PRIOR LINE
LD DE,-TMS_COLS ; LOAD COLS (NEGATIVE)
ADD HL,DE ; BACK UP THE ADDRESS
DEC C ; DECREMENT ROW COUNTER
JR NZ,TMS_RSCROLL0 ; LOOP THRU ALL ROWS
;
; FILL THE NEWLY EXPOSED BOTTOM LINE
CALL TMS_WR
LD A,' '
LD B,TMS_COLS
TMS_RSCROLL3:
EZ80_IO
OUT (TMS_DATREG),A
TMS_IODELAY
DJNZ TMS_RSCROLL3
;
RET
;
;----------------------------------------------------------------------
; BLOCK COPY BC BYTES FROM HL TO DE
;----------------------------------------------------------------------
;
TMS_BLKCPY:
; SAVE DESTINATION AND LENGTH
PUSH BC ; LENGTH
PUSH DE ; DEST
;
; READ FROM THE SOURCE LOCATION
TMS_BLKCPY1:
CALL TMS_RD ; SET UP TO READ FROM ADDRESS IN HL
LD DE,TMS_BUF ; POINT TO BUFFER
LD B,C
TMS_BLKCPY2:
EZ80_IO
IN A,(TMS_DATREG) ; GET THE NEXT BYTE
TMS_IODELAY ; DELAY
LD (DE),A ; SAVE IN BUFFER
INC DE ; BUMP BUF PTR
DJNZ TMS_BLKCPY2 ; LOOP AS NEEDED
;
; WRITE TO THE DESTINATION LOCATION
POP HL ; RECOVER DESTINATION INTO HL
CALL TMS_WR ; SET UP TO WRITE
LD DE,TMS_BUF ; POINT TO BUFFER
POP BC ; GET LOOP COUNTER BACK
LD B,C
TMS_BLKCPY3:
LD A,(DE) ; GET THE CHAR FROM BUFFER
EZ80_IO
OUT (TMS_DATREG),A ; WRITE TO VDU
TMS_IODELAY ; DELAY
INC DE ; BUMP BUF PTR
DJNZ TMS_BLKCPY3 ; LOOP AS NEEDED
;
RET
;
;----------------------------------------------------------------------
; Z180 LOW SPEED I/O CODE BRACKETING
;----------------------------------------------------------------------
;
#IF (CPUFAM == CPU_Z180)
;
TMS_Z180IO:
; HOOK CALLERS RETURN TO RESTORE DCNTL
EX (SP),HL ; SAVE HL & HL := RET ADR
LD (TMS_Z180IOR),HL ; SET RET ADR
LD HL,TMS_Z180IOX ; HL := SPECIAL RETURN ADR
EX (SP),HL ; RESTORE HL, INS NEW RET ADR
; SET Z180 MAX I/O WAIT STATES
PUSH AF ; SAVE AF
IN0 A,(Z180_DCNTL) ; GET CURRENT Z180 DCNTL
LD (TMS_DCNTL),A ; SAVE IT
OR %00110000 ; NEW DCNTL VALUE (MAX I/O W/S)
OUT0 (Z180_DCNTL),A ; IMPLEMENT IT
POP AF ; RESTORE AF
; BACK TO CALLER
TMS_Z180IOR .EQU $+1
JP $0000 ; BACK TO CALLER
;
TMS_Z180IOX:
; RESTORE ORIGINAL DCNTL
PUSH AF ; SAVE AF
LD A,(TMS_DCNTL) ; ORIG DCNTL
OUT0 (Z180_DCNTL),A ; IMPLEMENT IT
POP AF ; RESTORE AF
RET ; DONE
;
#ENDIF
#IF (TMSTIMENABLE & (INTMODE > 0))
TMS_TSTINT:
IN_A_NN(TMS_CMDREG)
AND $80
JR NZ,TMS_INTHNDL
AND $00 ; RETURN Z - NOT HANDLED
RET
TMS_INTHNDL:
#IF (TMSKBD == TMSKBD_MKY)
CALL MKY_INT
#ENDIF
CALL HB_TIMINT ; RETURN NZ - HANDLED
OR $FF
RET
#ENDIF
;
;==================================================================================================
; TMS DRIVER - DATA
;==================================================================================================
;
TMS_POS .DW 0 ; CURRENT DISPLAY POSITION
TMS_CURSAV .DB 0 ; SAVES ORIGINAL CHARACTER UNDER CURSOR
TMS_BUF .FILL 256,0 ; COPY BUFFER
;
; ### JLC Mod
; ANSI-->TMS Color Conversion Table
TMS_COLOR_TBL .DB $01,$08,$02,$0A,$04,$06,$0C,$0F,$0E,$09,$03,$0B,$05,$0D,$07,$0F
;
;==================================================================================================
; TMS DRIVER - INSTANCE DATA
;==================================================================================================
;
TMS_IDAT:
#IF ((TMSKBD == TMSKBD_NONE) | (TMSKBD == TMSKBD_MKY) | (TMSKBD == TMSKBD_NABU))
.FILL 4,0 ; DUMMY KEYBOARD CONFIG DATA
#ENDIF
#IF (TMSKBD == TMSKBD_PPK)
.DB TMS_PPIA ; PPI PORT A
.DB TMS_PPIB ; PPI PORT B
.DB TMS_PPIC ; PPI PORT C
.DB TMS_PPIX ; PPI CONTROL PORT
#ENDIF
#IF (TMSKBD == TMSKBD_KBD)
.DB KBDMODE_PS2 ; PS/2 8242 KEYBOARD CONTROLLER
.DB TMS_KBDST ; 8242 CMD/STATUS PORT
.DB TMS_KBDDATA ; 8242 DATA PORT
.DB 0 ; FILLER
#ENDIF
;
.DB TMS_DATREG
.DB TMS_CMDREG
;
;==================================================================================================
; TMS DRIVER - TMS9918 REGISTER INITIALIZATION
;==================================================================================================
;
; Control Registers (write CMDREG):
;
; Reg Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Description
; 0 - - - - - - M3 EXTVID
; 1 4/16K BL GINT M1 M2 - SI MAG
; 2 - - - - PN13 PN12 PN11 PN10
; 3 CT13 CT12 CT11 CT10 CT9 CT8 CT7 CT6
; 4 - - - - - PG13 PG12 PG11
; 5 - SA13 SA12 SA11 SA10 SA9 SA8 SA7
; 6 - - - - - SG13 SG12 SG11
; 7 TC3 TC2 TC1 TC0 BD3 BD2 BD1 BD0
;
; Status (read CMDREG):
;
; Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Description
; INT 5S C FS4 FS3 FS2 FS1 FS0
;
; M1,M2,M3 Select screen mode
; EXTVID Enables external video input.
; 4/16K Selects 16kB RAM if set. No effect in MSX1 system.
; BL Blank screen if reset; just backdrop. Sprite system inactive
; SI 16x16 sprites if set; 8x8 if reset
; MAG Sprites enlarged if set (sprite pixels are 2x2)
; GINT Generate interrupts if set
; PN* Address for pattern name table
; CT* Address for colour table (special meaning in M2)
; PG* Address for pattern generator table (special meaning in M2)
; SA* Address for sprite attribute table
; SG* Address for sprite generator table
; TC* Text colour (foreground)
; BD* Back drop (background). Sets the colour of the border around
; the drawable area. If it is 0, it is black (like colour 1).
; FS* Fifth sprite (first sprite that's not displayed). Only valid
; if 5S is set.
; C Sprite collision detected
; 5S Fifth sprite (not displayed) detected. Value in FS* is valid.
; INT Set at each screen update, used for interrupts.
;
#IF (TMS80COLS)
;
; NOTE: YAMAHA 9938/58 DOCUMENTATION SAYS R3 IS SAME AS 9918 (ADR >> 10),
; BUT THIS SEEMS TO BE WRONG AND CORRECTLY DOCUMENTED AT
; https://www.msx.org/wiki/Screen_Modes_Description#SCREEN_0_in_80-column_.28Text_mode_2.29
; BITS 1-0 SHOULD BE 1. BITS 8-2 SHOULD BE (ADR >> 8).
;
; ### JLC Mod
; TEXT MODE DEFAULT COLOR (REG 7) CAN BE CHANGED INVOKING VDASCO
; OR VIA ANSI PRIVATE ESC SEQ. (SEE ANSI.ASM FOR DETAILS)
;
TMS_INITVDU: ; V9958 REGISTER SET
.DB $04 ; REG 0 - NO EXTERNAL VID, SET M4 = 1 FOR 80 COLS
TMS_INITVDU_REG_1:
.DB $50 ; REG 1 - ENABLE SCREEN, SET M1
.DB $03 ; REG 2 - SET PATTERN NAME TABLE TO (TMS_CHRVADDR >> 8) | $03
.DB $00 ; REG 3 - NO COLOR TABLE
.DB $02 ; REG 4 - SET PATTERN GENERATOR TABLE TO (TMS_FNTVADDR -> $1000)
.DB $00 ; REG 5 - SPRITE ATTRIBUTE IRRELEVANT
.DB $00 ; REG 6 - NO SPRITE GENERATOR TABLE
.DB $F0 ; REG 7 - WHITE ON BLACK
.DB $88 ; REG 8 - COLOUR BUS INPUT, DRAM 64K
#IF (TICKFREQ == 50)
.DB $02 ; REG 9
#ELSE
.DB $00 ; REG 9
#ENDIF
.DB $00 ; REG 10 - COLOUR TABLE A14-A16 (TMS_FNTVADDR - $1000)
;
#ELSE ; _______TMS9918 REGISTER SET_______
;
TMS_INITVDU: ; V9918 REGISTER SET
.DB $00 ; REG 0 - SET TEXT MODE, NO EXTERNAL VID
TMS_INITVDU_REG_1:
.DB $D0 ; REG 1 - SET 16K VRAM, ENABLE SCREEN, NO INTERRUPTS, TEXT MODE ($50 TO BLANK SCREEN)
.DB $0E ; REG 2 - SET PATTERN NAME TABLE TO (TMS_CHRVADDR >> 10)
.DB $FF ; REG 3 - NO COLOR TABLE, SET TO MODE II DEFAULT VALUE
.DB $00 ; REG 4 - SET PATTERN GENERATOR TABLE TO (TMS_FNTVADDR -> $0000)
.DB $76 ; REG 5 - SPRITE ATTRIBUTE IRRELEVANT, SET TO MODE II DEFAULT VALUE
.DB $03 ; REG 6 - NO SPRITE GENERATOR TABLE, SET TO MODE II DEFAULT VALUE
.DB $E1 ; REG 7 - TEXT COLOR
;
#ENDIF
;
TMS_INITVDULEN .EQU $ - TMS_INITVDU
;
;
#IF (CPUFAM == CPU_Z180)
TMS_DCNTL .DB $00 ; SAVE Z180 DCNTL AS NEEDED
#ENDIF
;
; ### JLC Mod
;===============================================================================
; BASIC ANSI to TMS COLOR CONVERSION TABLE (NIBBLES FOR FOREGROUND & BACKGROUND)
; Follows RomWBW System Guide Chapter 8, HBIOS Reference
;-------------------------------------------------------------------------------
; ANSI Color TMS Equivalent
;-------------------------------------------------------------------------------
; 0 Black 1
; 1 Red 8
; 2 Green 2
; 3 Brown A
; 4 Blue 4
; 5 Magenta 6
; 6 Cyan C
; 7 White F
; 8 Gray E
; 9 Light Red 9
; A Light Green 3
; B Yellow B
; C Light Blue 5
; D Light Magenta D
; E Light Cyan 7
; F Bright White F
;===============================================================================
;