several fixes
This commit is contained in:
@@ -0,0 +1 @@
|
||||
../../../monitor_v2/zout/symbols.s
|
||||
2563
OperatingSystem/Applications/displaydemo/include/font1.s
Normal file
2563
OperatingSystem/Applications/displaydemo/include/font1.s
Normal file
File diff suppressed because it is too large
Load Diff
3073
OperatingSystem/Applications/displaydemo/include/font80.s
Normal file
3073
OperatingSystem/Applications/displaydemo/include/font80.s
Normal file
File diff suppressed because it is too large
Load Diff
16
OperatingSystem/Applications/displaydemo/include/kdrv_int.s
Normal file
16
OperatingSystem/Applications/displaydemo/include/kdrv_int.s
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
INT_VEC_TABLE .equ [interrupt_vectors]
|
||||
INT_PIO_ADDRD .equ CS_PIO_AD
|
||||
INT_PIO_ADDRC .equ CS_PIO_AC
|
||||
|
||||
|
||||
; jumps to isr. MUST be exited with RETI opcode!
|
||||
|
||||
_isr_pio_test:
|
||||
di
|
||||
ld hl, [_str_pio_interrupt]
|
||||
call print_str
|
||||
;get int from pio
|
||||
in a,(INT_PIO_ADDRD)
|
||||
call print_a_hex
|
||||
reti
|
||||
254
OperatingSystem/Applications/displaydemo/include/kdrv_vdpterm.s
Normal file
254
OperatingSystem/Applications/displaydemo/include/kdrv_vdpterm.s
Normal file
@@ -0,0 +1,254 @@
|
||||
;; VDP Terminal Driver
|
||||
|
||||
__VDPBUFFER_COUNTER equ var_idebuffer + 767
|
||||
__VDPBUFFER_CURSORADDR equ var_idebuffer + 768
|
||||
__VDPBUFFER_LINE equ var_idebuffer + 770
|
||||
|
||||
|
||||
__VTERM_MAX_LINES equ 23
|
||||
__VTERM_MAX_CPL equ 81
|
||||
|
||||
VTERM_INIT:
|
||||
; init variables
|
||||
xor a
|
||||
ld (var_curserx),a
|
||||
ld (var_cursery),a
|
||||
ld (var_curseron),a
|
||||
ld hl, 0x0A00
|
||||
ld (__VDPBUFFER_CURSORADDR),hl
|
||||
call _VTERM_SET_CURSORADDR
|
||||
ret
|
||||
|
||||
; --- Console enable cursor ---
|
||||
; destroy a
|
||||
VTERM_CURSOR_ON:
|
||||
push hl
|
||||
push bc
|
||||
push de
|
||||
ld a,1
|
||||
ld (var_curseron),a
|
||||
call _VTERM_MOVE_CURSOR
|
||||
pop de
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
; --- Console disable cursor ---
|
||||
; destroy a
|
||||
VTERM_CURSOR_OFF:
|
||||
push hl
|
||||
push bc
|
||||
xor a
|
||||
ld (var_curseron),a
|
||||
ld hl,(__VDPBUFFER_CURSORADDR)
|
||||
call VDP_RAMADDR_WR
|
||||
xor a
|
||||
out (VDP_RAM),a ;clear old cursor
|
||||
call _VTERM_SET_CURSORADDR
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
; --- Console print string (null terminated) ---
|
||||
; inputs: hl (pointer to string)
|
||||
; modify hl
|
||||
; destroy a
|
||||
VTERM_PRINT_STR:
|
||||
ld a,(hl)
|
||||
or a
|
||||
ret z
|
||||
call VTERM_PRINT
|
||||
inc hl
|
||||
jr VTERM_PRINT_STR
|
||||
|
||||
; --- Console print char ---
|
||||
; inputs: a (ascii char)
|
||||
VTERM_PRINT:
|
||||
push af
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
|
||||
push af
|
||||
call print_a_hex
|
||||
pop af
|
||||
cp 0x08
|
||||
jp z,_VTERM_PRINT_BACKSPC
|
||||
cp 13
|
||||
jp z, _VTERM_PRINT_CR
|
||||
cp 10
|
||||
jp z, _VTERM_PRINT_LF
|
||||
; else print a
|
||||
call _VTERM_CHAROUT
|
||||
_VTERM_PRINT_END:
|
||||
call _VTERM_MOVE_CURSOR
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
pop af
|
||||
ret
|
||||
_VTERM_PRINT_BACKSPC:
|
||||
call _VTERM_CURSOR_BACK
|
||||
ld a,' '
|
||||
out (VDP_RAM),a
|
||||
jp _VTERM_PRINT_END
|
||||
_VTERM_PRINT_CR:
|
||||
call _VTERM_CURSOR_START
|
||||
jp _VTERM_PRINT_END
|
||||
_VTERM_PRINT_LF:
|
||||
call _VTERM_CURSOR_NEWLINE
|
||||
jp _VTERM_PRINT_END
|
||||
|
||||
; only called by VTERM_PRINT
|
||||
; destroys af,bc,de,hl
|
||||
_VTERM_CHAROUT:
|
||||
push af ;store char
|
||||
ld a,(var_curserx) ;test for line wrap
|
||||
inc a
|
||||
cp __VTERM_MAX_CPL +1
|
||||
jr nz, __VTERM_CHAROUT_NOBREAK ; if linewrap:
|
||||
call _VTERM_CURSOR_START ; do new line
|
||||
call _VTERM_CURSOR_NEWLINE
|
||||
__VTERM_CHAROUT_NOBREAK: ; if not linewrap
|
||||
ld a,(var_curserx) ; move curser by one
|
||||
inc a
|
||||
ld (var_curserx),a
|
||||
pop af
|
||||
out (VDP_RAM),a
|
||||
ret
|
||||
|
||||
; destroys af,bc,de,hl
|
||||
_VTERM_CURSOR_BACK:
|
||||
ld a,(var_curserx)
|
||||
or a
|
||||
ret z;if line wrap, ignore
|
||||
dec a
|
||||
ld (var_curserx),a
|
||||
jp _VTERM_MOVE_CURSOR
|
||||
|
||||
; --- Move cursor to start of line ---
|
||||
; destroys af,bc,de,hl
|
||||
_VTERM_CURSOR_START:
|
||||
xor a
|
||||
ld (var_curserx),a
|
||||
jp _VTERM_MOVE_CURSOR
|
||||
|
||||
; --- Move cursor to next line ---
|
||||
; destroys af,bc,de,hl
|
||||
_VTERM_CURSOR_NEWLINE:
|
||||
ld a,(var_cursery)
|
||||
cp __VTERM_MAX_LINES
|
||||
jp z, _VTERM_SCROLL
|
||||
inc a
|
||||
ld (var_cursery),a
|
||||
jp _VTERM_MOVE_CURSOR
|
||||
|
||||
; --- Calculate 16bit VRAM adress of current char ---
|
||||
; destroy AF,DE
|
||||
; outputs HL
|
||||
_VTERM_CALC_CURSORADDR:
|
||||
ld d,0
|
||||
ld a,(var_cursery)
|
||||
ld e,a
|
||||
ld hl,0
|
||||
add hl, de ; Y x 1
|
||||
add hl, hl ; Y x 2
|
||||
add hl, hl ; Y x 4
|
||||
add hl, de ; Y x 5
|
||||
add hl, hl ; Y x 10
|
||||
add hl, hl ; Y x 20
|
||||
add hl, hl ; Y x 40
|
||||
add hl, hl ; Y x 80
|
||||
ld a,(var_curserx)
|
||||
ld e,a
|
||||
add hl, de ; add X for final address
|
||||
ret
|
||||
|
||||
; destroy AF,DE,HL
|
||||
_VTERM_SET_CURSORADDR:
|
||||
call _VTERM_CALC_CURSORADDR
|
||||
jp VDP_RAMADDR_WR
|
||||
|
||||
; destroy AF,DE,HL
|
||||
_VTERM_SET_CURSORADDR_RD:
|
||||
call _VTERM_CALC_CURSORADDR
|
||||
jp VDP_RAMADDR_RD
|
||||
|
||||
; destroys af,bc,de,hl
|
||||
_VTERM_MOVE_CURSOR:
|
||||
ld a,(var_curseron)
|
||||
or a
|
||||
jp z, _VTERM_SET_CURSORADDR ;if cursor disable, only set new memory location
|
||||
;if cursor is enabled
|
||||
ld hl,(__VDPBUFFER_CURSORADDR)
|
||||
call VDP_RAMADDR_WR
|
||||
xor a
|
||||
out (VDP_RAM),a ;clear old cursor
|
||||
; calulate new position
|
||||
call _VTERM_CALC_CURSORADDR
|
||||
ld a,l ;load lower byte
|
||||
and 0x07 ;mask lower 3 bits
|
||||
ld b,a ;save lower 3 bits
|
||||
srl h
|
||||
rr l
|
||||
srl h
|
||||
rr l
|
||||
srl h
|
||||
rr l
|
||||
ld de,0x0A00
|
||||
add hl,de
|
||||
ld (__VDPBUFFER_CURSORADDR), hl
|
||||
call VDP_RAMADDR_WR
|
||||
ld a,128
|
||||
_VTERM_MOVE_CURSOR_LOOP:
|
||||
rrca
|
||||
djnz _VTERM_MOVE_CURSOR_LOOP
|
||||
out (VDP_RAM),a
|
||||
jp _VTERM_SET_CURSORADDR
|
||||
|
||||
; --- Memory Scroll ---
|
||||
_VTERM_SCROLL:
|
||||
;COPY / Scroll up using VDP commands
|
||||
ld e,15 ;select status register
|
||||
ld a,2
|
||||
call VDP_SETREG
|
||||
in a,(VDP_REGISTER)
|
||||
and 0x40 ;Vertical retrace flag
|
||||
jr z, _VTERM_SCROLL; if not loop
|
||||
; else setup address
|
||||
xor a
|
||||
ld (var_curserx),a
|
||||
ld (__VDPBUFFER_COUNTER),a
|
||||
_VTERM_SCROLL_LINE:
|
||||
ld a,(__VDPBUFFER_COUNTER) ;set next line
|
||||
inc a
|
||||
ld (var_cursery),a
|
||||
call _VTERM_SET_CURSORADDR_RD
|
||||
ld b,__VTERM_MAX_CPL
|
||||
ld hl,__VDPBUFFER_LINE ;buffer location
|
||||
ld c, VDP_RAM
|
||||
_VTERM_SCROLL_LINE_L1:
|
||||
ini ;load 80 bytes to ram
|
||||
jr nz, _VTERM_SCROLL_LINE_L1
|
||||
;setup target row
|
||||
ld a,(__VDPBUFFER_COUNTER) ;set next line
|
||||
ld (var_cursery),a
|
||||
call _VTERM_SET_CURSORADDR
|
||||
ld b,__VTERM_MAX_CPL
|
||||
ld hl,__VDPBUFFER_LINE ;buffer location
|
||||
_VTERM_SCROLL_LINE_L2:
|
||||
outi ;store to vdp ram
|
||||
jr nz, _VTERM_SCROLL_LINE_L2
|
||||
;done with one line
|
||||
ld a,(__VDPBUFFER_COUNTER)
|
||||
inc a
|
||||
ld (__VDPBUFFER_COUNTER),a
|
||||
cp __VTERM_MAX_LINES
|
||||
jp nz, _VTERM_SCROLL_LINE
|
||||
ld (var_cursery),a
|
||||
call _VTERM_SET_CURSORADDR
|
||||
;fill
|
||||
ld b,__VTERM_MAX_CPL
|
||||
_VTERM_SCROLL_LINE_FILL:
|
||||
xor a
|
||||
out (VDP_RAM),a
|
||||
djnz _VTERM_SCROLL_LINE_FILL
|
||||
jp _VTERM_SET_CURSORADDR
|
||||
151
OperatingSystem/Applications/displaydemo/include/kdrv_vt82c42.s
Normal file
151
OperatingSystem/Applications/displaydemo/include/kdrv_vt82c42.s
Normal file
@@ -0,0 +1,151 @@
|
||||
;----------------------------------------------------------------
|
||||
;Keyboard interface driver for Z8C
|
||||
;Controller used: vt82c42
|
||||
;Datasheet: http://www.s100computers.com/My%20System%20Pages/MSDOS%20Board/vt82c42%20PC%20Keyboard%20conrtroller.pdf
|
||||
;by Dennis Gunia (04/2022)
|
||||
;----------------------------------------------------------------
|
||||
|
||||
;================================================================
|
||||
; I/O registers
|
||||
;================================================================
|
||||
CS_VT82C42_DATA .EQU 0xF0
|
||||
CS_VT82C42_CTRL .EQU 0xF1
|
||||
|
||||
;================================================================
|
||||
; I/O access functions
|
||||
;================================================================
|
||||
keyboard_init:
|
||||
ld a, 0xA7 ;Disable Mouse
|
||||
out (CS_VT82C42_CTRL), A
|
||||
ld a, 0xAD ;Disable Keyboard
|
||||
out (CS_VT82C42_CTRL), A
|
||||
_keyboard_init_flush_buffer:
|
||||
in a,(CS_VT82C42_DATA) ;Read buffer
|
||||
in a,(CS_VT82C42_CTRL) ;Read status byte
|
||||
bit 0,a ;Test if buffer is empty
|
||||
jr nz, _keyboard_init_flush_buffer
|
||||
;buffer is now flushed. Now set the Controller Configuration Byte
|
||||
|
||||
ld a, 0x60 ;next byte is command byte register write
|
||||
ld b, 11111100b ;Disable bits 0,1,6 (disable IRQ and Translation)
|
||||
call keyb_cmd_wr
|
||||
|
||||
;Perform Controller Self Test
|
||||
ld a, 0xAA
|
||||
call keyb_cmd_rd
|
||||
cp 0x55
|
||||
jr nz, _keyboard_init_failed
|
||||
|
||||
;Perform Interface Tests
|
||||
ld a, 0xAB
|
||||
call keyb_cmd_rd
|
||||
or a
|
||||
jr nz, _keyboard_init_failed
|
||||
|
||||
;Enable Devices
|
||||
ld a,0xAE
|
||||
out (CS_VT82C42_CTRL), A
|
||||
call keyb_wait_ibf_empty
|
||||
|
||||
;Test if device is present Devices
|
||||
ld a,0xEE
|
||||
out (CS_VT82C42_DATA), A ;Send echo to keboard (0xEE command)
|
||||
call keyb_wait_ibf_empty
|
||||
call keyb_wait_obf
|
||||
in a,(CS_VT82C42_DATA)
|
||||
cp a, 0xEE
|
||||
jr z, _keyboard_init_okay ; 0xFC -> Success. Init done!
|
||||
;Else device error
|
||||
ld hl, [STR_keyboard_init_failed]
|
||||
call print_str
|
||||
ret
|
||||
_keyboard_init_failed:
|
||||
LD HL, [STR_keyboard_init_err]
|
||||
CALL print_str
|
||||
RET
|
||||
_keyboard_init_dev_missing:
|
||||
LD HL, [STR_keyboard_init_missing]
|
||||
CALL print_str
|
||||
RET
|
||||
_keyboard_init_okay:
|
||||
LD HL, [STR_keyboard_init_okay]
|
||||
CALL print_str
|
||||
RET
|
||||
|
||||
keyb_cmd_enable:
|
||||
ld a, 0xF4
|
||||
call keyb_wr_wait_ack
|
||||
ld a, 0xED
|
||||
call keyb_wr_wait_ack
|
||||
ld a, 0x02
|
||||
call keyb_wr_wait_ack
|
||||
ret
|
||||
|
||||
keyb_enable_int:
|
||||
ld a, 0x60 ;next byte is command byte register write
|
||||
ld b, 00000001b ;Disable bits 0,1,6 (disable IRQ and Translation)
|
||||
call keyb_cmd_wr
|
||||
|
||||
|
||||
_keyb_enable_int_flush_buffer:
|
||||
in a,(CS_VT82C42_DATA) ;Read buffer
|
||||
in a,(CS_VT82C42_CTRL) ;Read status byte
|
||||
bit 0,a ;Test if buffer is empty
|
||||
jr nz, _keyb_enable_int_flush_buffer
|
||||
ret
|
||||
; a contains command
|
||||
; b conatins data
|
||||
keyb_cmd_wr:
|
||||
out (CS_VT82C42_CTRL),a ;write command byte
|
||||
ld a, b
|
||||
out (CS_VT82C42_DATA),a
|
||||
ret
|
||||
|
||||
; a contains command
|
||||
; a returns data
|
||||
keyb_cmd_rd:
|
||||
out (CS_VT82C42_CTRL),a ;write command byte
|
||||
_keyb_cmd_rd_l1:
|
||||
in a, (CS_VT82C42_CTRL) ;read status
|
||||
call print_a_hex
|
||||
rra
|
||||
jr nc, _keyb_cmd_rd_l1 ;wait until OBF is set (data avail)
|
||||
in a, (CS_VT82C42_DATA)
|
||||
ret
|
||||
|
||||
keyb_wait_ibf_empty:
|
||||
in a, (CS_VT82C42_CTRL) ;read status
|
||||
rra
|
||||
rra
|
||||
jr c, keyb_wait_ibf_empty ;if IBF, wait
|
||||
ret
|
||||
|
||||
keyb_wait_obf:
|
||||
in a, (CS_VT82C42_CTRL) ;read status
|
||||
rra
|
||||
jr nc, keyb_wait_obf ;if IBF, wait
|
||||
ret
|
||||
|
||||
|
||||
; a data
|
||||
; z is 0 if success
|
||||
keyb_wr_wait_ack:
|
||||
out (CS_VT82C42_DATA),a ;write command byte
|
||||
call keyb_wait_obf ;wait until sent
|
||||
_keyb_wr_wait_ack_l1: ;wait for reponse
|
||||
in a, (CS_VT82C42_CTRL) ;read status
|
||||
bit 1,a ;check input buffer full
|
||||
jr nz, _keyb_wr_wait_ack_l1
|
||||
in a, (CS_VT82C42_DATA)
|
||||
cp 0xFA
|
||||
ret
|
||||
|
||||
;Status message strings
|
||||
STR_keyboard_init_okay:
|
||||
.BYTE "PS/2 Keyboard initialized.",0
|
||||
STR_keyboard_init_err:
|
||||
.BYTE "PS/2 Controller error! System HALT!",0
|
||||
STR_keyboard_init_failed:
|
||||
.BYTE "PS/2 Keyboard error! System HALT!",0
|
||||
STR_keyboard_init_missing:
|
||||
.BYTE "PS/2 no keyboard found!",0
|
||||
256
OperatingSystem/Applications/displaydemo/include/krdv_vdp.s
Normal file
256
OperatingSystem/Applications/displaydemo/include/krdv_vdp.s
Normal file
@@ -0,0 +1,256 @@
|
||||
;----------------------------------------------------------------
|
||||
;BIOS Driver for VDP V9958
|
||||
;by Dennis Gunia (07/2024)
|
||||
;----------------------------------------------------------------
|
||||
|
||||
;================================================================
|
||||
; I/O registers
|
||||
;================================================================
|
||||
VDP_REGISTER .EQU 0xE1
|
||||
VDP_RAM .EQU 0xE0
|
||||
|
||||
;================================================================
|
||||
; VDP Registers
|
||||
;================================================================
|
||||
; registers
|
||||
VDPR_MODE0 .EQU 0
|
||||
VDPR_MODE1 .EQU 1
|
||||
VDPR_MODE2 .EQU 8
|
||||
VDPR_MODE3 .EQU 9
|
||||
VDPR_COLOR .EQU 7
|
||||
VDPR_PATNMEBASE .EQU 2
|
||||
VDPR_PATGENBASE .EQU 4
|
||||
VDPR_COLTBBASE0 .EQU 3
|
||||
VDPR_COLTBBASE1 .EQU 10
|
||||
; register bits
|
||||
TMS_R8_MS .EQU 128 ;Mouse: when set to 1, sets the color bus into input mode and enables mouse. If set to 0, sets color bus into output mode and disables mouse
|
||||
TMS_R8_LP .EQU 64 ;Light pen: when set to 1, enables light pen
|
||||
TMS_R8_TP .EQU 32 ;Sets the color of code 0 to the color of the palette
|
||||
TMS_R8_CB .EQU 16 ;Color bus: when set to 1, sets color bus into input mode. If set to 0, sets color bus into output mode
|
||||
TMS_R8_VR .EQU 8 ;If set to 1, VRAM is 64Kx1Bit or 64Kx4bits. If set to 0, VRAM is 16Kx1Bit or 16Kx4Bits
|
||||
TMS_R8_SPD .EQU 2 ;if set to 1, sprites are not displayed and related VRAM reads are not performed
|
||||
TMS_R8_BW .EQU 1 ;if set to 1, output is grayscale in 32 tones
|
||||
; colors
|
||||
TmsTransparent .EQU 0
|
||||
TmsBlack .EQU 1
|
||||
TmsMediumGreen .EQU 2
|
||||
TmsLightGreen .EQU 3
|
||||
TmsDarkBlue .EQU 4
|
||||
TmsLightBlue .EQU 5
|
||||
TmsDarkRed .EQU 6
|
||||
TmsCyan .EQU 7
|
||||
TmsMediumRed .EQU 8
|
||||
TmsLightRed .EQU 9
|
||||
TmsDarkYellow .EQU 0ah
|
||||
TmsLightYellow .EQU 0bh
|
||||
TmsDarkGreen .EQU 0ch
|
||||
TmsMagenta .EQU 0dh
|
||||
TmsGray .EQU 0eh
|
||||
TmsWhite .EQU 0fh
|
||||
;================================================================
|
||||
; I/O access functions
|
||||
;================================================================
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; set vdp register
|
||||
;
|
||||
; inputs: a (value), e (register)
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_SETREG:
|
||||
out (VDP_REGISTER), a
|
||||
ld a,e
|
||||
or 80h
|
||||
out (VDP_REGISTER), a
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; read vdp status register
|
||||
;
|
||||
; inputs: a (register)
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_STS:
|
||||
out (VDP_RAM),a ;write addr
|
||||
ld a,15 + 128
|
||||
out (VDP_RAM),a ;selct reg for read
|
||||
in a,(VDP_RAM)
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; set vdp ram pointer for read
|
||||
;
|
||||
; inputs: ahl (address)
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_RAMADDR_RD:
|
||||
rlc h
|
||||
rla
|
||||
rlc h
|
||||
rla
|
||||
srl h
|
||||
srl h
|
||||
out (VDP_REGISTER),a
|
||||
ld a,14 + 128
|
||||
out (VDP_REGISTER),a
|
||||
ld a,l
|
||||
out (VDP_REGISTER),a
|
||||
ld a,h
|
||||
out (VDP_REGISTER),a
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; set vdp ram pointer for write
|
||||
;
|
||||
; inputs: ahl (address)
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_RAMADDR_WR:
|
||||
rlc h
|
||||
rla
|
||||
rlc h
|
||||
rla
|
||||
srl h
|
||||
srl h
|
||||
out (VDP_REGISTER),a
|
||||
ld a,14 + 128
|
||||
out (VDP_REGISTER),a
|
||||
ld a,l
|
||||
out (VDP_REGISTER),a
|
||||
ld a,h
|
||||
or 64
|
||||
out (VDP_REGISTER),a
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; set vdp console color
|
||||
;
|
||||
; inputs: b (back color), c (front color)
|
||||
; destroys: e, af
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_COLOR:
|
||||
ld a,c ;load front color to a
|
||||
rlca
|
||||
rlca
|
||||
rlca
|
||||
rlca
|
||||
or b ;combine back color
|
||||
ld e, VDPR_COLOR
|
||||
call VDP_SETREG
|
||||
; set blink color
|
||||
ld e, 12 ; set blink color
|
||||
ld a,b ;load front color to a
|
||||
rlca
|
||||
rlca
|
||||
rlca
|
||||
rlca
|
||||
or c ;combine back color
|
||||
call VDP_SETREG
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; copy block of memory to vdp
|
||||
;
|
||||
; inputs: hl (source in local ram)
|
||||
; de (destination in vram)
|
||||
; bc (byte counter)
|
||||
; destroys: af
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_LOADRAM:
|
||||
;setup address
|
||||
push hl
|
||||
ex de,hl
|
||||
ld a,0
|
||||
call VDP_RAMADDR_WR
|
||||
pop hl
|
||||
_VDP_LOADRAM_LOOP:
|
||||
ld a,(hl) ;load byte from system
|
||||
inc hl
|
||||
out (VDP_RAM),a
|
||||
dec bc ;decrement counter
|
||||
ld a,b ;check if zero
|
||||
or c
|
||||
jr nz, _VDP_LOADRAM_LOOP ;if not loop
|
||||
ret ;else exit
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; fill block of memory in vdp
|
||||
;
|
||||
; inputs: a (value to write)
|
||||
; de (destination in vram)
|
||||
; bc (byte counter)
|
||||
; destroys: hl
|
||||
;------------------------------------------------------------------------------
|
||||
VDP_FILL:
|
||||
push af
|
||||
ex de,hl
|
||||
call VDP_RAMADDR_WR
|
||||
_VDP_FILL_LOOP:
|
||||
pop af
|
||||
out (VDP_RAM),a
|
||||
push af
|
||||
dec bc ;decrement counter
|
||||
ld a,b ;check if zero
|
||||
or c
|
||||
jr nz, _VDP_FILL_LOOP ;if not loop
|
||||
pop af
|
||||
ret
|
||||
|
||||
|
||||
;================================================================
|
||||
; Init screen modes
|
||||
;================================================================
|
||||
VDP_INIT_TEXT2:
|
||||
; init vdp (80col text)
|
||||
ld e, VDPR_MODE0
|
||||
ld a, 00000100b ;TEXT2
|
||||
call VDP_SETREG
|
||||
ld e, VDPR_MODE1 ;blank screen wit 64K enabled
|
||||
ld a, 00001000b
|
||||
call VDP_SETREG
|
||||
ld e, VDPR_MODE2
|
||||
ld a, TMS_R8_SPD
|
||||
call VDP_SETREG
|
||||
ld e, VDPR_MODE3
|
||||
ld a, 00000010b
|
||||
call VDP_SETREG
|
||||
; set memory layout
|
||||
; set pattern name table
|
||||
ld e, VDPR_PATNMEBASE
|
||||
ld a, 00000011b
|
||||
call VDP_SETREG
|
||||
ld e, VDPR_PATGENBASE
|
||||
ld a, 00000010b
|
||||
call VDP_SETREG
|
||||
ld e, VDPR_COLTBBASE0
|
||||
ld a, 00101111b
|
||||
call VDP_SETREG
|
||||
ld e, VDPR_COLTBBASE1
|
||||
ld a, 00000000b
|
||||
call VDP_SETREG
|
||||
;enable cpu wait (for fast writes. Required!!!!)
|
||||
ld e,25
|
||||
ld a,4
|
||||
call VDP_SETREG
|
||||
;setup cursor:
|
||||
ld e, 13 ; set blink rate
|
||||
ld a, 0x22
|
||||
call VDP_SETREG
|
||||
;fill nametable to 0
|
||||
ld de, 0x0000
|
||||
ld bc, 0x2000
|
||||
ld a, 0
|
||||
call VDP_FILL
|
||||
;load font
|
||||
ld hl, [VDP_FONT_6x8_80COL]
|
||||
ld bc, 256*8
|
||||
ld de, 0x1000
|
||||
call VDP_LOADRAM
|
||||
;enable screen wit 64K enabled
|
||||
ld e, VDPR_MODE1
|
||||
ld a, 01010000b
|
||||
call VDP_SETREG
|
||||
ret
|
||||
|
||||
;================================================================
|
||||
; Fonts
|
||||
;================================================================
|
||||
VDP_FONT_6x8_80COL:
|
||||
.include "font80.s"
|
||||
@@ -0,0 +1,5 @@
|
||||
;----------------------------------------------------------------
|
||||
;Ringbuffer data structure
|
||||
;by Dennis Gunia (07/2024)
|
||||
;----------------------------------------------------------------
|
||||
|
||||
706
OperatingSystem/Applications/displaydemo/include/tms.s
Normal file
706
OperatingSystem/Applications/displaydemo/include/tms.s
Normal file
@@ -0,0 +1,706 @@
|
||||
; TMS9918A graphics subroutines
|
||||
; Copyright 2018-2020 J.B. Langston
|
||||
;
|
||||
; Permission is hereby granted, free of charge, to any person obtaining a
|
||||
; copy of this software and associated documentation files (the "Software"),
|
||||
; to deal in the Software without restriction, including without limitation
|
||||
; the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
; and/or sell copies of the Software, and to permit persons to whom the
|
||||
; Software is furnished to do so, subject to the following conditions:
|
||||
;
|
||||
; The above copyright notice and this permission notice shall be included in
|
||||
; all copies or substantial portions of the Software.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
; DEALINGS IN THE SOFTWARE.
|
||||
|
||||
; VDP Programmer's Guide: http://map.grauw.nl/resources/video/ti-vdp-programmers-guide.pdf
|
||||
|
||||
phase 0xE400
|
||||
; ---------------------------------------------------------------------------
|
||||
; configuration parameters; can be changed at runtime
|
||||
TmsPort:
|
||||
defb 0xE0 ; port for TMS vram (reg is 1 higher)
|
||||
TmsWait:
|
||||
defb 64 ; iterations to wait after ram access
|
||||
TmsMode:
|
||||
defw 0 ; mode registers
|
||||
TmsNameAddr:
|
||||
defw 3800h ; name table address (multiples of 400H)
|
||||
TmsColorAddr:
|
||||
defw 2000h ; color table address (multiples of 40H)
|
||||
TmsPatternAddr:
|
||||
defw 0 ; pattern table (multiples of 800H)
|
||||
TmsSpritePatternAddr:
|
||||
defw 1800h ; sprite attribute table (multiples of 80H)
|
||||
TmsSpriteAttrAddr:
|
||||
defw 3bc0h ; sprite pattern table (multiples of 800H)
|
||||
TmsScreenColors:
|
||||
defb 0 ; background (low nybble), text color (high nybble)
|
||||
; ---------------------------------------------------------------------------
|
||||
; register constants
|
||||
dephase
|
||||
setup_vars:
|
||||
|
||||
ld a,0xE0
|
||||
ld (TmsPort),a
|
||||
|
||||
ld a,2
|
||||
ld (TmsWait),a
|
||||
|
||||
ld a,0
|
||||
ld (TmsMode),a
|
||||
ld a,0
|
||||
ld (TmsMode+1),a
|
||||
|
||||
ld a,0
|
||||
ld (TmsNameAddr),a
|
||||
ld a,38h
|
||||
ld (TmsNameAddr+1),a
|
||||
|
||||
ld a,0
|
||||
ld (TmsPatternAddr),a
|
||||
ld a,0
|
||||
ld (TmsPatternAddr+1),a
|
||||
|
||||
ld a,0
|
||||
ld (TmsColorAddr),a
|
||||
ld a,20h
|
||||
ld (TmsColorAddr+1),a
|
||||
|
||||
|
||||
ld a,0
|
||||
ld (TmsSpritePatternAddr),a
|
||||
ld a,0x18
|
||||
ld (TmsSpritePatternAddr+1),a
|
||||
|
||||
|
||||
ld a,0xc0
|
||||
ld (TmsSpriteAttrAddr),a
|
||||
ld a,0x3b
|
||||
ld (TmsSpriteAttrAddr+1),a
|
||||
|
||||
ret
|
||||
|
||||
TmsWriteBit: equ 40h ; bit to indicate memory write
|
||||
|
||||
; Registers
|
||||
TmsCtrl0Reg: equ 80h
|
||||
TmsCtrl1Reg: equ 81h
|
||||
TmsNameReg: equ 82h
|
||||
TmsColorTableReg: equ 83h
|
||||
TmsPatternReg: equ 84h
|
||||
TmsSpriteAttrReg: equ 85h
|
||||
TmsSpritePatternReg: equ 86h
|
||||
TmsColorReg: equ 87h
|
||||
|
||||
; Control Register Bits
|
||||
TmsM3: equ 200h
|
||||
TmsExtVideo: equ 100h
|
||||
Tms16k: equ 80h
|
||||
TmsDisplayEnable: equ 40h
|
||||
TmsIntEnableBit: equ 20h
|
||||
TmsM1: equ 10h
|
||||
TmsM2: equ 8
|
||||
TmsSprite32: equ 2
|
||||
TmsSpriteMag: equ 1
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; table lengths
|
||||
|
||||
TmsTileNameLen: equ 300h
|
||||
TmsTextNameLen: equ 3c0h
|
||||
|
||||
TmsTileColorLen: equ 20h
|
||||
TmsBitmapColorLen: equ 800h
|
||||
|
||||
TmsTilePatternLen: equ 800h
|
||||
TmsTextPatternLen: equ 800h
|
||||
TmsMulticolorPatternLen: equ 600h
|
||||
TmsBitmapPatternLen: equ 1800h
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; color constants
|
||||
|
||||
TmsTransparent: equ 0
|
||||
TmsBlack: equ 1
|
||||
TmsMediumGreen: equ 2
|
||||
TmsLightGreen: equ 3
|
||||
TmsDarkBlue: equ 4
|
||||
TmsLightBlue: equ 5
|
||||
TmsDarkRed: equ 6
|
||||
TmsCyan: equ 7
|
||||
TmsMediumRed: equ 8
|
||||
TmsLightRed: equ 9
|
||||
TmsDarkYellow: equ 0ah
|
||||
TmsLightYellow: equ 0bh
|
||||
TmsDarkGreen: equ 0ch
|
||||
TmsMagenta: equ 0dh
|
||||
TmsGray: equ 0eh
|
||||
TmsWhite: equ 0fh
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; port I/O routines
|
||||
|
||||
; These routines access the ports configured in TmsPort.
|
||||
|
||||
; These memory locations can be set at runtime to support different hardware
|
||||
; configurations from the same binary. TmsProbe automatically detects the
|
||||
; TMS9918A on common ports.
|
||||
|
||||
; The TMS9918A RAM must not be accessed more than once every 8 us or display
|
||||
; corruption may occur. During vblank and with the display disabled,
|
||||
; accesses can be 2 us apart, but we will always use 8 us minimum delay.
|
||||
|
||||
; TmsRamIn/TmsRamOut include a configurable delay loop, which waits for the
|
||||
; configured iterations between VRAM writes to work properly with faster CPUs
|
||||
|
||||
; Minimum time to execute each procedure call:
|
||||
; Z80: 88 cycles, 8.8 us @ 10 MHz
|
||||
; Z180: 80 cycles, 8.64 us @ 9.216 MHz, 4.32 us @ 18.432, 2.16 us @ 36.864
|
||||
;
|
||||
; Additional delay per djnz iteration:
|
||||
; Z80: 8 cycles * (iterations - 1)
|
||||
; 0.8 us @ 10 MHz
|
||||
; Z180: 7 cycles * (iterations - 1)
|
||||
; 0.756 us @ 9.216 MHz, 0.378 us @ 18.432, 0.189 us @ 36.864
|
||||
|
||||
; Delay loop iterations required for different CPU speeds:
|
||||
; Z80 @ 10 MHz or less: 1
|
||||
; Z180 @ 9.216 MHz or less: 1
|
||||
; Z180 @ 18.432 MHz: 10
|
||||
; Z180 @ 36.864 MHz: 31
|
||||
TmsWaits: defb 1, 10, 31 ; wait iterations to add for different CPU speeds
|
||||
|
||||
; set up wait time based on clock multiplier in E
|
||||
TmsSetWait:
|
||||
ld a,1
|
||||
ld (TmsWait), a
|
||||
ret
|
||||
|
||||
; try to find TMS9918A on common ports
|
||||
TmsProbe:
|
||||
ld hl, TmsPorts
|
||||
ld b, TmsNumPorts
|
||||
TmsProbeNext:
|
||||
ld a, (hl)
|
||||
ld (TmsPort), a
|
||||
call TmsRegIn ; clear vsync bit
|
||||
call TmsRegIn ; check it again
|
||||
jp m, TmsProbeFailed ; if still set, not a TMS9918A
|
||||
ld de, 0ffffh ; long enough for another vsync
|
||||
TmsProbeWait:
|
||||
call TmsRegIn ; check vsync bit again
|
||||
ret m ; if set, it's a TMS9918A (and Z is clear)
|
||||
dec de ; otherwise, keep waiting
|
||||
ld a, e
|
||||
or d
|
||||
jp nz, TmsProbeWait
|
||||
TmsProbeFailed:
|
||||
inc hl ; if still clear after this long, try next port
|
||||
djnz TmsProbeNext
|
||||
xor a ; set Z if we ran out of ports to check
|
||||
ret
|
||||
|
||||
TmsPorts: ; List of ports to probe:
|
||||
defb 0x80 ; ColecoVision / SG-1000
|
||||
defb 98h ; MSX
|
||||
defb 10h ; Sord M5 (conflicts with z80ctrl SIO port)
|
||||
;defb 8 ; Tatung Einstein (conflicts with z80ctrl drive ports)
|
||||
;defb 1 ; MTX (not supported by TMS9918A video card)
|
||||
; add additional ports to check here
|
||||
TmsNumPorts: equ $ - TmsPorts
|
||||
|
||||
; set a single register value
|
||||
; A = register value
|
||||
; E = register to set
|
||||
TmsSetReg:
|
||||
call TmsRegOut
|
||||
ld a, e
|
||||
; fallthrough to TmsRegOut
|
||||
|
||||
; write to configured register port
|
||||
; parameters:
|
||||
; A = value to write
|
||||
TmsRegOut:
|
||||
push bc
|
||||
ld bc, (TmsPort)
|
||||
inc c
|
||||
out (c), a
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; read from configured register port
|
||||
; returns:
|
||||
; A = value read
|
||||
TmsRegIn:
|
||||
push bc
|
||||
ld bc, (TmsPort)
|
||||
inc c
|
||||
in a, (c)
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; write to configured VRAM port
|
||||
; parameters:
|
||||
; A = value to write
|
||||
; Z80 | Z180 cycles...
|
||||
TmsRamOut: ; 17 | 16 (call)
|
||||
push bc ; 11 | 11
|
||||
ld bc, (TmsPort) ; 20 | 18
|
||||
out (c), a ; 12 | 10
|
||||
TmsRamOutDelay:
|
||||
djnz TmsRamOutDelay ; 8 | 7 plus (13 | 9) * (iterations-1)
|
||||
pop bc ; 10 | 9
|
||||
ret ; 10 | 9
|
||||
|
||||
; read from configured VRAM port
|
||||
; returns:
|
||||
; A = value read
|
||||
TmsRamIn:
|
||||
push bc
|
||||
ld bc, (TmsPort)
|
||||
TmsRamInDelay:
|
||||
djnz TmsRamInDelay
|
||||
in a, (c)
|
||||
ld bc, (TmsPort)
|
||||
TmsRamInDelay2:
|
||||
djnz TmsRamInDelay2
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; register configuration routines
|
||||
|
||||
; set the background color
|
||||
; A = requested color
|
||||
TmsBackground:
|
||||
and 0fh
|
||||
ld b, a
|
||||
ld a, (TmsScreenColors)
|
||||
and 0f0h
|
||||
or b
|
||||
ld (TmsScreenColors), a
|
||||
ld e, TmsColorReg
|
||||
jp TmsSetReg
|
||||
|
||||
; set the sprite configuration
|
||||
; A = sprite options
|
||||
TmsSpriteConfig:
|
||||
and TmsSprite32|TmsSpriteMag
|
||||
ld b, a
|
||||
ld a, (TmsMode)
|
||||
and ~(TmsSprite32|TmsSpriteMag)
|
||||
or b
|
||||
ld (TmsMode), a
|
||||
ld e, TmsCtrl1Reg
|
||||
jp TmsSetReg
|
||||
|
||||
|
||||
; enable vblank interrupts
|
||||
TmsIntEnable:
|
||||
ld a, (TmsMode)
|
||||
or TmsIntEnableBit
|
||||
ld (TmsMode), a
|
||||
ld e, TmsCtrl1Reg
|
||||
jp TmsSetReg
|
||||
|
||||
; disable vblank interrupts
|
||||
TmsIntDisable:
|
||||
ld a, (TmsMode)
|
||||
and ~TmsIntEnableBit
|
||||
ld (TmsMode), a
|
||||
ld e, TmsCtrl1Reg
|
||||
jp TmsSetReg
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; initialization routines
|
||||
|
||||
TmsBlankFlags: equ Tms16k
|
||||
TmsTileFlags: equ Tms16k | TmsDisplayEnable
|
||||
TmsTextFlags: equ Tms16k | TmsDisplayEnable | TmsM1
|
||||
TmsMulticolorFlags: equ Tms16k | TmsDisplayEnable | TmsM2
|
||||
TmsBitmapFlags: equ Tms16k | TmsDisplayEnable | TmsM3
|
||||
|
||||
; reset registers and clear all 16KB of video memory
|
||||
TmsReset:
|
||||
ld hl, TmsBlankFlags ; blank the screen with 16KB enabled
|
||||
ld (TmsMode), hl
|
||||
ld a, l
|
||||
ld e, TmsCtrl1Reg
|
||||
call TmsSetReg
|
||||
ld a, h
|
||||
ld e, TmsCtrl0Reg
|
||||
call TmsSetReg
|
||||
ld a, TmsTransparent
|
||||
call TmsBackground
|
||||
ld a, TmsTransparent
|
||||
call TmsTextColor
|
||||
ld de, 0 ; clear entire VRAM
|
||||
ld bc, 4000h
|
||||
ld a, 0
|
||||
call TmsFill
|
||||
ret
|
||||
|
||||
; initialize for multicolor mode
|
||||
TmsMulticolor:
|
||||
call TmsReset
|
||||
ld de, (TmsNameAddr)
|
||||
call TmsWriteAddr
|
||||
ld d, 6 ; name table has 6 sections
|
||||
ld e, 0 ; lines in first section start at 0
|
||||
TmsSectionLoop:
|
||||
ld c, 4 ; each section has 4 identical lines
|
||||
TmsLineLoop:
|
||||
ld b, 32 ; each line is 32 bytes long
|
||||
ld a, e ; same starting value for each line in section
|
||||
TmsByteLoop:
|
||||
call TmsRamOut
|
||||
inc a ; byte value
|
||||
djnz TmsByteLoop
|
||||
dec c ; line counter
|
||||
jp nz, TmsLineLoop
|
||||
ld e, a ; next starting value = current + 32
|
||||
dec d ; section counter
|
||||
jp nz, TmsSectionLoop
|
||||
ld hl, TmsMulticolorFlags
|
||||
ld (TmsMode), hl
|
||||
jp TmsInitNonBitmap
|
||||
|
||||
; initialize for tiled graphics
|
||||
TmsTile:
|
||||
call TmsReset
|
||||
ld hl, TmsTileFlags
|
||||
ld (TmsMode), hl
|
||||
jp TmsInitNonBitmap
|
||||
|
||||
; initialize for text mode
|
||||
; HL = address of font to load
|
||||
TmsTextMode:
|
||||
push hl
|
||||
call TmsReset
|
||||
pop hl
|
||||
ld de, (TmsPatternAddr) ; load font from address in hl
|
||||
ld bc, TmsTextPatternLen
|
||||
call TmsWrite
|
||||
ld hl, TmsTextFlags
|
||||
ld (TmsMode), hl
|
||||
; fallthrough to TmsInitNonBitmap
|
||||
|
||||
; non-bitmap color and pattern table configuration
|
||||
TmsInitNonBitmap:
|
||||
; set up color table address (register = address / 400H)
|
||||
ld a, (TmsColorAddr)
|
||||
and 0c0h
|
||||
ld (TmsColorAddr), a
|
||||
ld d, a
|
||||
ld a, (TmsColorAddr+1)
|
||||
and 3fh
|
||||
ld (TmsColorAddr+1), a
|
||||
rl d
|
||||
rla
|
||||
rl d
|
||||
rla
|
||||
ld e, TmsColorTableReg
|
||||
call TmsSetReg
|
||||
|
||||
; set up pattern table address (register = address / 800H)
|
||||
xor a
|
||||
ld (TmsPatternAddr), a
|
||||
ld a, (TmsPatternAddr+1)
|
||||
and 38h
|
||||
ld (TmsPatternAddr+1), a
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
ld e, TmsPatternReg
|
||||
call TmsSetReg
|
||||
jp TmsInitCommon
|
||||
|
||||
; initialize for bitmapped graphics
|
||||
TmsBitmap:
|
||||
call TmsReset
|
||||
ld de, (TmsNameAddr) ; initialize name table with 3 sets
|
||||
call TmsWriteAddr ; of 256 bytes ranging from 00-FF
|
||||
ld b, 3
|
||||
xor a
|
||||
TmsBitmapLoop:
|
||||
call TmsRamOut
|
||||
inc a
|
||||
jp nz, TmsBitmapLoop
|
||||
djnz TmsBitmapLoop
|
||||
ld hl, TmsBitmapFlags
|
||||
ld (TmsMode), hl
|
||||
|
||||
; set up color table at 0H (register = 7FH) or 2000H (register = 0FFH)
|
||||
xor a
|
||||
ld (TmsColorAddr), a
|
||||
ld (TmsPatternAddr), a
|
||||
ld a, (TmsColorAddr+1)
|
||||
and 20h
|
||||
ld (TmsColorAddr+1), a
|
||||
ld a, 0ffh ; color table at 2000H
|
||||
jp nz, TmsColorTableHigh
|
||||
ld a, 7fh ; color table at 0H
|
||||
TmsColorTableHigh:
|
||||
ld e, TmsColorTableReg
|
||||
call TmsSetReg
|
||||
|
||||
; set up pattern table at 0H (register = 3) or 2000H (register = 7)
|
||||
ld a, (TmsPatternAddr+1)
|
||||
and 20h
|
||||
ld (TmsPatternAddr+1), a
|
||||
ld a, 7 ; pattern table at 2000H
|
||||
jp nz, TmsPatternTableHigh
|
||||
ld a, 3 ; pattern table at 0H
|
||||
TmsPatternTableHigh:
|
||||
ld e, TmsPatternReg
|
||||
call TmsSetReg
|
||||
; fall through to TmsInitCommon
|
||||
|
||||
|
||||
; common initialization for all modes
|
||||
TmsInitCommon:
|
||||
; set up name table address (register = address / 400H)
|
||||
xor a
|
||||
ld (TmsNameAddr), a
|
||||
ld a, (TmsNameAddr+1)
|
||||
and 3ch
|
||||
ld (TmsNameAddr+1), a
|
||||
rrca
|
||||
rrca
|
||||
ld e, TmsNameReg
|
||||
call TmsSetReg
|
||||
|
||||
; set up sprite pattern table address (register = address / 80H)
|
||||
ld a, (TmsSpriteAttrAddr)
|
||||
and 80h
|
||||
ld (TmsSpriteAttrAddr), a
|
||||
ld d, a
|
||||
ld a, (TmsSpriteAttrAddr+1)
|
||||
and 7fh
|
||||
rl d
|
||||
rla
|
||||
ld e, TmsSpriteAttrReg
|
||||
call TmsSetReg
|
||||
|
||||
; set up sprite attribute table address (register = address / 800H)
|
||||
xor a
|
||||
ld (TmsSpritePatternAddr), a
|
||||
ld a, (TmsSpritePatternAddr+1)
|
||||
and 38h
|
||||
ld (TmsSpritePatternAddr+1), a
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
ld e, TmsSpritePatternReg
|
||||
call TmsSetReg
|
||||
|
||||
; set up control registers
|
||||
ld e, TmsCtrl1Reg
|
||||
ld a, (TmsMode)
|
||||
call TmsSetReg
|
||||
ld a, (TmsMode+1)
|
||||
ld e, TmsCtrl0Reg
|
||||
jp TmsSetReg
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; memory access routines
|
||||
|
||||
; set the next address of vram to write
|
||||
; DE = address
|
||||
TmsWriteAddr:
|
||||
ld a, e ; send lsb
|
||||
call TmsRegOut
|
||||
ld a, d ; mask off msb to max of 16KB
|
||||
and 3fh
|
||||
or TmsWriteBit ; indicate that this is a write
|
||||
call TmsRegOut
|
||||
ret
|
||||
|
||||
; set the next address of vram to read
|
||||
; DE = address
|
||||
TmsReadAddr:
|
||||
ld a, e ; send lsb
|
||||
call TmsRegOut
|
||||
ld a, d ; mask off msb to max of 16KB
|
||||
and 3Fh
|
||||
call TmsRegOut
|
||||
ret
|
||||
|
||||
; copy bytes from ram to vram
|
||||
; HL = ram source address
|
||||
; DE = vram destination address
|
||||
; BC = byte count
|
||||
TmsWrite:
|
||||
call TmsWriteAddr
|
||||
TmsWriteLoop:
|
||||
ld a, (hl)
|
||||
call TmsRamOut
|
||||
inc hl
|
||||
dec bc
|
||||
ld a, b
|
||||
or c
|
||||
jp nz, TmsWriteLoop
|
||||
ret
|
||||
|
||||
; fill a section of memory with a single value
|
||||
; A = value to fill
|
||||
; DE = vram destination address
|
||||
; BC = byte count
|
||||
TmsFill:
|
||||
push af
|
||||
call TmsWriteAddr
|
||||
pop af
|
||||
TmsFillLoop:
|
||||
call TmsRamOut
|
||||
dec c
|
||||
jp nz, TmsFillLoop
|
||||
djnz TmsFillLoop
|
||||
ret
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; text routines
|
||||
; set text color
|
||||
; A = requested color
|
||||
TmsTextColor:
|
||||
add a, a ; text color into high nybble
|
||||
add a, a
|
||||
add a, a
|
||||
add a, a
|
||||
ld b, a ; save for later
|
||||
ld a, (TmsScreenColors) ; get current colors
|
||||
and 0fh ; mask off old text color
|
||||
or b ; set new text color
|
||||
ld (TmsScreenColors), a
|
||||
ld e, TmsColorReg
|
||||
jp TmsSetReg ; save it back
|
||||
|
||||
; set the address to place text at X/Y coordinate
|
||||
; A = X
|
||||
; E = Y
|
||||
TmsTextPos:
|
||||
ld d, 0
|
||||
ld hl, 0
|
||||
add hl, de ; Y x 1
|
||||
add hl, hl ; Y x 2
|
||||
add hl, hl ; Y x 4
|
||||
add hl, de ; Y x 5
|
||||
add hl, hl ; Y x 10
|
||||
add hl, hl ; Y x 20
|
||||
add hl, hl ; Y x 40
|
||||
ld e, a
|
||||
add hl, de ; add X for final address
|
||||
ld de, (TmsNameAddr) ; add name table base address
|
||||
add hl, de
|
||||
ex de, hl
|
||||
jp TmsWriteAddr
|
||||
|
||||
; copy a null-terminated string to VRAM
|
||||
; HL = ram source address
|
||||
TmsStrOut:
|
||||
ld a, (hl)
|
||||
cp 0 ; return when NULL is encountered
|
||||
ret z
|
||||
call TmsRamOut
|
||||
inc hl
|
||||
jp TmsStrOut
|
||||
|
||||
; repeat a character a certain number of times
|
||||
; A = character to output
|
||||
; B = count
|
||||
TmsRepeat:
|
||||
call TmsRamOut
|
||||
djnz TmsRepeat
|
||||
ret
|
||||
|
||||
; output a character
|
||||
; A = character to output
|
||||
TmsChrOut: equ TmsRamOut
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; bitmap routines
|
||||
|
||||
TmsClearPixel: equ 0A02Fh ; cpl, and b
|
||||
TmsSetPixel: equ 0B0h ; nop, or b
|
||||
|
||||
; set operation for TmsPlotPixel to perform
|
||||
; HL = pixel operation (TmsClearPixel, TmsSetPixel)
|
||||
TmsPixelOp:
|
||||
ld (TmsPixelOpPlaceHolder), hl
|
||||
ret
|
||||
|
||||
; set or clear pixel at X, Y position
|
||||
; B = Y position
|
||||
; C = X position
|
||||
TmsPlotPixel:
|
||||
ld a, b ; bail out if Y coord > 191
|
||||
cp 192
|
||||
ret nc
|
||||
call TmsXYAddr ; get address in DE for X/Y coord in BC
|
||||
ld a, c ; get lower 3 bits of X coord
|
||||
and 7
|
||||
ld b, 0
|
||||
ld c, a
|
||||
ld hl, TmsMaskLookup ; address of mask in table
|
||||
add hl, bc
|
||||
ld b, (hl) ; save mask in B
|
||||
ld hl, (TmsPatternAddr) ; get base address for pattern table
|
||||
add hl, de
|
||||
ex de, hl
|
||||
call TmsReadAddr ; set read within pattern table
|
||||
call TmsRamIn
|
||||
TmsPixelOpPlaceHolder:
|
||||
or b ; mask bit in previous byte
|
||||
nop ; place holder for 2 byte mask operation
|
||||
push af
|
||||
call TmsWriteAddr ; set write address within pattern table
|
||||
pop af
|
||||
jp TmsRamOut
|
||||
|
||||
TmsMaskLookup:
|
||||
defb 80h, 40h, 20h, 10h, 8h, 4h, 2h, 1h
|
||||
|
||||
; set the color for a block of pixels in bitmap mode
|
||||
; B = Y position
|
||||
; C = X position
|
||||
; A = foreground/background color to set
|
||||
TmsPixelColor:
|
||||
push af
|
||||
ld a, b ; bail out if Y coord > 191
|
||||
cp 192
|
||||
ret nc
|
||||
call TmsXYAddr ; get address in DE for X/Y coord in BC
|
||||
ld hl, (TmsColorAddr) ; add the color table base address
|
||||
add hl, de
|
||||
ex de, hl
|
||||
call TmsWriteAddr ; set write address within color table
|
||||
pop af
|
||||
jp TmsRamOut
|
||||
|
||||
; calculate address byte containing X/Y coordinate
|
||||
; B = Y position
|
||||
; C = X position
|
||||
; returns address in DE
|
||||
TmsXYAddr:
|
||||
ld a, b ; d = (y / 8)
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
and 1fh
|
||||
ld d, a
|
||||
|
||||
ld a, c ; e = (x & f8)
|
||||
and 0f8h
|
||||
ld e, a
|
||||
|
||||
ld a, b ; e += (y & 7)
|
||||
and 7
|
||||
or e
|
||||
ld e, a
|
||||
ret
|
||||
2552
OperatingSystem/Applications/displaydemo/include/tmsfont.s
Normal file
2552
OperatingSystem/Applications/displaydemo/include/tmsfont.s
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user