mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 14:11:48 -06:00
- 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.
1307 lines
36 KiB
NASM
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
|
|
;===============================================================================
|
|
;
|