Files
Z8C-Homebrew-Computer/OperatingSystem/Applications/displaydemo/include/kdrv_vdpterm.s
2024-11-30 15:41:09 +01:00

254 lines
5.5 KiB
ArmAsm

;; 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