prog8/compiler/res/prog8lib/cx16/textio.p8

672 lines
17 KiB
Plaintext
Raw Normal View History

2020-08-27 16:10:22 +00:00
; Prog8 definitions for the Text I/O and Screen routines for the CommanderX16
; All routines work with Screencode character encoding, except `print`, `chrout` and `input_chars`,
; these work with PETSCII encoding instead.
%import syslib
%import conv
2024-03-27 23:04:49 +00:00
%import shared_cbm_textio_functions
2020-08-27 16:10:22 +00:00
txt {
%option no_symbol_prefixing, ignore_unused
2023-06-29 22:29:50 +00:00
2020-09-19 22:17:33 +00:00
const ubyte DEFAULT_WIDTH = 80
const ubyte DEFAULT_HEIGHT = 60
const ubyte VERA_TEXTMATRIX_BANK = 1
const uword VERA_TEXTMATRIX_ADDR = $b000
2024-03-27 23:04:49 +00:00
romsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character.
2020-09-19 22:17:33 +00:00
sub clear_screen() {
chrout(147)
2020-08-30 17:31:20 +00:00
}
sub cls() {
chrout(147)
}
2021-01-14 21:51:09 +00:00
sub home() {
chrout(19)
2021-01-14 21:51:09 +00:00
}
sub nl() {
chrout('\n')
}
2021-01-14 21:51:09 +00:00
sub spc() {
chrout(' ')
}
sub bell() {
chrout(7)
}
2021-02-10 21:47:49 +00:00
asmsub column(ubyte col @A) clobbers(A, X, Y) {
; ---- set the cursor on the given column (starting with 0) on the current line
%asm {{
2024-03-16 15:47:40 +00:00
pha
2021-02-10 21:47:49 +00:00
sec
jsr cbm.PLOT
2024-03-16 15:47:40 +00:00
pla
2021-02-10 21:47:49 +00:00
tay
clc
jmp cbm.PLOT
2021-02-10 21:47:49 +00:00
}}
}
2021-01-14 21:51:09 +00:00
asmsub get_column() -> ubyte @Y {
%asm {{
sec
jmp cbm.PLOT
}}
}
asmsub row(ubyte rownum @A) clobbers(A, X, Y) {
; ---- set the cursor on the given row (starting with 0) on the current line
%asm {{
2024-03-16 15:47:40 +00:00
pha
sec
jsr cbm.PLOT
2024-03-16 15:47:40 +00:00
pla
tax
clc
jmp cbm.PLOT
}}
}
asmsub get_row() -> ubyte @X {
%asm {{
sec
jmp cbm.PLOT
}}
}
sub get_cursor(uword colptr, uword rowptr) {
%asm {{
sec
jsr cbm.PLOT
tya
ldy #$00
sta (colptr),y
txa
sta (rowptr),y
}}
}
asmsub fill_screen (ubyte character @ A, ubyte color @ Y) clobbers(A, X) {
; ---- fill the character screen with the given fill character and character color.
%asm {{
sty _ly+1
pha
jsr cbm.SCREEN ; get dimensions in X/Y
txa
lsr a
lsr a
sta _lx+1
lda #%00010000
jsr set_vera_textmatrix_addresses
pla
_lx ldx #0 ; modified
phy
_ly ldy #1 ; modified
- sta cx16.VERA_DATA0
sty cx16.VERA_DATA0
sta cx16.VERA_DATA0
sty cx16.VERA_DATA0
sta cx16.VERA_DATA0
sty cx16.VERA_DATA0
sta cx16.VERA_DATA0
sty cx16.VERA_DATA0
dex
bne -
ply
dey
beq +
stz cx16.VERA_ADDR_L
inc cx16.VERA_ADDR_M ; next line
bra _lx
+ rts
set_vera_textmatrix_addresses:
stz cx16.VERA_CTRL
ora #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
stz cx16.VERA_ADDR_L ; start at (0,0)
lda #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
rts
}}
}
asmsub clear_screenchars (ubyte character @ A) clobbers(X, Y) {
; ---- clear the character screen with the given fill character (leaves colors)
; (assumes screen matrix is at the default address)
%asm {{
pha
jsr cbm.SCREEN ; get dimensions in X/Y
2020-09-21 16:42:28 +00:00
txa
lsr a
lsr a
sta _lx+1
lda #%00100000
jsr fill_screen.set_vera_textmatrix_addresses
2020-09-21 16:42:28 +00:00
pla
_lx ldx #0 ; modified
- sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
2020-09-21 16:42:28 +00:00
sta cx16.VERA_DATA0
dex
bne -
dey
beq +
stz cx16.VERA_ADDR_L
inc cx16.VERA_ADDR_M ; next line
bra _lx
+ rts
2020-09-21 16:42:28 +00:00
}}
}
asmsub clear_screencolors (ubyte color @ A) clobbers(X, Y) {
2020-09-21 16:42:28 +00:00
; ---- clear the character screen colors with the given color (leaves characters).
; (assumes color matrix is at the default address)
%asm {{
sta _la+1
jsr cbm.SCREEN ; get dimensions in X/Y
txa
lsr a
lsr a
sta _lx+1
2020-09-21 21:04:01 +00:00
stz cx16.VERA_CTRL
lda #%00100000
jsr fill_screen.set_vera_textmatrix_addresses
inc cx16.VERA_ADDR_L ; start at (1,0) - the color attribute byte
_lx ldx #0 ; modified
_la lda #0 ; modified
- sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
dex
bne -
dey
beq +
lda #1
sta cx16.VERA_ADDR_L
inc cx16.VERA_ADDR_M ; next line
bra _lx
+ rts
}}
}
2020-09-21 16:42:28 +00:00
ubyte[16] color_to_charcode = [$90,$05,$1c,$9f,$9c,$1e,$1f,$9e,$81,$95,$96,$97,$98,$99,$9a,$9b]
sub color (ubyte txtcol) {
txtcol &= 15
cbm.CHROUT(color_to_charcode[txtcol])
}
sub color2 (ubyte txtcol, ubyte bgcol) {
txtcol &= 15
bgcol &= 15
cbm.CHROUT(color_to_charcode[bgcol])
cbm.CHROUT(1) ; switch fg and bg colors
cbm.CHROUT(color_to_charcode[txtcol])
}
sub lowercase() {
cbm.CHROUT($0e)
; this is not 100% compatible: cx16.screen_set_charset(3, 0) ; lowercase petscii charset
}
sub uppercase() {
cbm.CHROUT($8e)
; this is not 100% compatible: cx16.screen_set_charset(2, 0) ; uppercase petscii charset
}
sub iso() {
; -- switch to iso-8859-15 character set
cbm.CHROUT($0f)
}
sub iso_off() {
; -- you have to call this first when switching back from iso charset to regular charset.
cbm.CHROUT($8f)
}
sub cp437() {
; -- switch to CP-437 (ibm PC) character set
cbm.CHROUT($0f) ; iso mode
cx16.screen_set_charset(7, 0) ; charset
%asm {{
clc
ldx #95 ; underscore
lda #cx16.EXTAPI_iso_cursor_char
jsr cx16.extapi
}}
}
sub iso5() {
; -- switch to iso-8859-5 character set (Cyrillic)
cbm.CHROUT($0f) ; iso mode
cx16.screen_set_charset(8, 0) ; charset
}
sub iso16() {
; -- switch to iso-8859-16 character set (Eastern Europe)
cbm.CHROUT($0f) ; iso mode
cx16.screen_set_charset(10, 0) ; charset
}
2024-08-20 19:40:43 +00:00
sub kata() {
2024-08-21 16:23:30 +00:00
; -- switch to katakana character set (requires rom 48+)
2024-08-20 19:40:43 +00:00
cbm.CHROUT($0f) ; iso mode
cx16.screen_set_charset(12, 0) ; charset
}
asmsub scroll_left() clobbers(A, X, Y) {
2022-04-04 19:11:09 +00:00
; ---- scroll the whole screen 1 character to the left
2020-09-21 19:39:36 +00:00
; contents of the rightmost column are unchanged, you should clear/refill this yourself
%asm {{
jsr cbm.SCREEN
2020-09-21 21:04:01 +00:00
dex
2020-09-21 21:39:25 +00:00
stx _lx+1
2020-09-21 21:04:01 +00:00
dey
sty P8ZP_SCRATCH_B1 ; number of rows to scroll
2020-09-21 21:39:25 +00:00
_nextline
stz cx16.VERA_CTRL ; data port 0: source column
lda #%00010000 | VERA_TEXTMATRIX_BANK ; auto increment 1
2020-09-21 21:39:25 +00:00
sta cx16.VERA_ADDR_H
lda #2
sta cx16.VERA_ADDR_L ; begin in column 1
lda P8ZP_SCRATCH_B1
clc
adc #>VERA_TEXTMATRIX_ADDR
tay
2020-09-21 21:39:25 +00:00
sty cx16.VERA_ADDR_M
lda #1
sta cx16.VERA_CTRL ; data port 1: destination column
lda #%00010000 | VERA_TEXTMATRIX_BANK ; auto increment 1
2020-09-21 21:39:25 +00:00
sta cx16.VERA_ADDR_H
2020-09-21 21:04:01 +00:00
stz cx16.VERA_ADDR_L
sty cx16.VERA_ADDR_M
2020-09-21 21:39:25 +00:00
_lx ldx #0 ; modified
- lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy char
lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy color
2020-09-21 21:04:01 +00:00
dex
2020-09-21 21:39:25 +00:00
bne -
2020-09-21 21:04:01 +00:00
dec P8ZP_SCRATCH_B1
2020-09-21 21:39:25 +00:00
bpl _nextline
lda #0
sta cx16.VERA_CTRL
rts
}}
2020-09-21 19:39:36 +00:00
}
asmsub scroll_right() clobbers(A,X,Y) {
2022-04-04 19:11:09 +00:00
; ---- scroll the whole screen 1 character to the right
2020-09-21 19:39:36 +00:00
; contents of the leftmost column are unchanged, you should clear/refill this yourself
2020-09-21 22:00:22 +00:00
%asm {{
jsr cbm.SCREEN
2020-09-21 22:00:22 +00:00
dex
stx _lx+1
txa
asl a
dea
sta _rcol+1
ina
ina
sta _rcol2+1
dey
sty P8ZP_SCRATCH_B1 ; number of rows to scroll
_nextline
stz cx16.VERA_CTRL ; data port 0: source column
lda #%00011000 | VERA_TEXTMATRIX_BANK ; auto decrement 1
2020-09-21 22:00:22 +00:00
sta cx16.VERA_ADDR_H
_rcol lda #79*2-1 ; modified
2020-09-21 22:00:22 +00:00
sta cx16.VERA_ADDR_L ; begin in rightmost column minus one
lda P8ZP_SCRATCH_B1
clc
adc #>VERA_TEXTMATRIX_ADDR
tay
2020-09-21 22:00:22 +00:00
sty cx16.VERA_ADDR_M
lda #1
sta cx16.VERA_CTRL ; data port 1: destination column
lda #%00011000 | VERA_TEXTMATRIX_BANK ; auto decrement 1
2020-09-21 22:00:22 +00:00
sta cx16.VERA_ADDR_H
_rcol2 lda #79*2+1 ; modified
2020-09-21 22:00:22 +00:00
sta cx16.VERA_ADDR_L
sty cx16.VERA_ADDR_M
_lx ldx #0 ; modified
- lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy char
lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy color
dex
bne -
dec P8ZP_SCRATCH_B1
bpl _nextline
lda #0
sta cx16.VERA_CTRL
rts
}}
2020-09-21 19:39:36 +00:00
}
asmsub scroll_up() clobbers(A, X, Y) {
2022-04-04 19:11:09 +00:00
; ---- scroll the whole screen 1 character up
2020-09-21 19:39:36 +00:00
; contents of the bottom row are unchanged, you should refill/clear this yourself
%asm {{
jsr cbm.SCREEN
stx _nextline+1
2020-09-21 19:39:36 +00:00
dey
sty P8ZP_SCRATCH_B1
stz cx16.VERA_CTRL ; data port 0 is source
lda #1 | (>VERA_TEXTMATRIX_ADDR)
sta cx16.VERA_ADDR_M ; start at second line
stz cx16.VERA_ADDR_L
lda #%00010000 | VERA_TEXTMATRIX_BANK
2020-09-21 19:39:36 +00:00
sta cx16.VERA_ADDR_H ; enable auto increment by 1, bank 0.
2020-09-21 20:06:48 +00:00
lda #1
sta cx16.VERA_CTRL ; data port 1 is destination
lda #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M ; start at top line
2020-09-21 19:39:36 +00:00
stz cx16.VERA_ADDR_L
lda #%00010000 | VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H ; enable auto increment by 1, bank 0.
_nextline
ldx #80 ; modified
2020-09-21 19:39:36 +00:00
- lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy char
2020-09-21 19:39:36 +00:00
lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy color
2020-09-21 19:39:36 +00:00
dex
bne -
dec P8ZP_SCRATCH_B1
beq +
stz cx16.VERA_CTRL ; data port 0
2020-09-21 20:06:48 +00:00
stz cx16.VERA_ADDR_L
inc cx16.VERA_ADDR_M
lda #1
sta cx16.VERA_CTRL ; data port 1
stz cx16.VERA_ADDR_L
inc cx16.VERA_ADDR_M
bra _nextline
2020-09-21 19:39:36 +00:00
+ lda #0
sta cx16.VERA_CTRL
rts
2020-09-21 19:39:36 +00:00
}}
}
asmsub scroll_down() clobbers(A, X, Y) {
2022-04-04 19:11:09 +00:00
; ---- scroll the whole screen 1 character down
2020-09-21 19:39:36 +00:00
; contents of the top row are unchanged, you should refill/clear this yourself
2020-09-21 20:06:48 +00:00
%asm {{
jsr cbm.SCREEN
stx _nextline+1
2020-09-21 20:06:48 +00:00
dey
sty P8ZP_SCRATCH_B1
stz cx16.VERA_CTRL ; data port 0 is source
dey
tya
clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M ; start at line before bottom line
stz cx16.VERA_ADDR_L
lda #%00010000 | VERA_TEXTMATRIX_BANK
2020-09-21 20:06:48 +00:00
sta cx16.VERA_ADDR_H ; enable auto increment by 1, bank 0.
lda #1
sta cx16.VERA_CTRL ; data port 1 is destination
iny
tya
clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M ; start at bottom line
stz cx16.VERA_ADDR_L
lda #%00010000 | VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H ; enable auto increment by 1, bank 0.
_nextline
ldx #80 ; modified
- lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy char
lda cx16.VERA_DATA0
sta cx16.VERA_DATA1 ; copy color
dex
bne -
dec P8ZP_SCRATCH_B1
beq +
stz cx16.VERA_CTRL ; data port 0
stz cx16.VERA_ADDR_L
2020-09-21 20:06:48 +00:00
dec cx16.VERA_ADDR_M
lda #1
sta cx16.VERA_CTRL ; data port 1
stz cx16.VERA_ADDR_L
2020-09-21 20:06:48 +00:00
dec cx16.VERA_ADDR_M
bra _nextline
+ lda #0
sta cx16.VERA_CTRL
2020-09-21 20:06:48 +00:00
rts
}}
2020-09-21 19:39:36 +00:00
}
2020-09-19 21:00:47 +00:00
asmsub setchr (ubyte col @X, ubyte row @Y, ubyte character @A) clobbers(A) {
; ---- sets the character in the screen matrix at the given position
%asm {{
2021-02-10 21:47:49 +00:00
pha
stz cx16.VERA_CTRL
lda #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
2021-02-10 21:47:49 +00:00
txa
asl a
sta cx16.VERA_ADDR_L
tya
2022-04-04 19:11:09 +00:00
; clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
2021-02-10 21:47:49 +00:00
pla
sta cx16.VERA_DATA0
rts
2020-09-19 21:00:47 +00:00
}}
}
asmsub getchr (ubyte col @A, ubyte row @Y) -> ubyte @ A {
; ---- get the character in the screen matrix at the given location
%asm {{
2021-02-10 21:47:49 +00:00
asl a
pha
2021-02-10 21:47:49 +00:00
stz cx16.VERA_CTRL
lda #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
pla
2021-02-10 21:47:49 +00:00
sta cx16.VERA_ADDR_L
tya
2022-04-04 19:11:09 +00:00
; clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
2021-02-10 21:47:49 +00:00
lda cx16.VERA_DATA0
rts
2020-09-19 21:00:47 +00:00
}}
}
asmsub setclr (ubyte col @X, ubyte row @Y, ubyte color @A) clobbers(A) {
; ---- set the color in A on the screen matrix at the given position
; note: on the CommanderX16 this allows you to set both Fg and Bg colors;
; use the high nybble in A to set the Bg color!
2020-09-19 21:00:47 +00:00
%asm {{
2021-02-10 21:47:49 +00:00
pha
stz cx16.VERA_CTRL
lda #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
2021-02-10 21:47:49 +00:00
txa
asl a
ina
sta cx16.VERA_ADDR_L
tya
2022-04-04 19:11:09 +00:00
; clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
2021-02-10 21:47:49 +00:00
pla
sta cx16.VERA_DATA0
rts
2020-09-19 21:00:47 +00:00
}}
}
asmsub getclr (ubyte col @A, ubyte row @Y) -> ubyte @ A {
; ---- get the color in the screen color matrix at the given location
%asm {{
2021-02-10 21:47:49 +00:00
asl a
ina
pha
2021-02-10 21:47:49 +00:00
stz cx16.VERA_CTRL
lda #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
pla
2021-02-10 21:47:49 +00:00
sta cx16.VERA_ADDR_L
tya
2022-04-04 19:11:09 +00:00
; clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
2021-02-10 21:47:49 +00:00
lda cx16.VERA_DATA0
rts
2020-09-19 21:00:47 +00:00
}}
}
sub setcc (ubyte col, ubyte row, ubyte character, ubyte charcolor) {
2022-04-04 19:11:09 +00:00
; ---- set char+color at the given position on the screen
; note: color handling is the same as on the C64: it only sets the foreground color and leaves the background color as is.
; Use setcc2 if you want Cx-16 specific feature of setting both Bg+Fg colors (is faster as well).
%asm {{
lda col
2021-02-10 21:47:49 +00:00
asl a
tax
ldy row
stz cx16.VERA_CTRL
lda #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
2021-02-10 21:47:49 +00:00
stx cx16.VERA_ADDR_L
tya
2022-04-04 19:11:09 +00:00
;clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
lda character
2021-02-10 21:47:49 +00:00
sta cx16.VERA_DATA0
2022-04-04 19:11:09 +00:00
inc cx16.VERA_ADDR_L
lda charcolor
and #$0f
sta P8ZP_SCRATCH_B1
2021-02-10 21:47:49 +00:00
lda cx16.VERA_DATA0
and #$f0
ora P8ZP_SCRATCH_B1
sta cx16.VERA_DATA0
rts
}}
}
sub setcc2 (ubyte col, ubyte row, ubyte character, ubyte colors) {
2022-04-04 19:11:09 +00:00
; ---- set char+color at the given position on the screen
; note: on the CommanderX16 this allows you to set both Fg and Bg colors;
2022-04-04 19:11:09 +00:00
; use the high nybble in A to set the Bg color! Is a bit faster than setcc() too.
%asm {{
lda col
asl a
tax
ldy row
stz cx16.VERA_CTRL
lda #VERA_TEXTMATRIX_BANK
sta cx16.VERA_ADDR_H
stx cx16.VERA_ADDR_L
tya
2022-04-04 19:11:09 +00:00
; clc
adc #>VERA_TEXTMATRIX_ADDR
sta cx16.VERA_ADDR_M
lda character
sta cx16.VERA_DATA0
2022-04-04 19:11:09 +00:00
inc cx16.VERA_ADDR_L
lda colors
sta cx16.VERA_DATA0
rts
}}
}
asmsub plot (ubyte col @ Y, ubyte row @ X) {
%asm {{
clc
jmp cbm.PLOT
}}
}
asmsub width() clobbers(X,Y) -> ubyte @A {
; -- returns the text screen width (number of columns)
%asm {{
jsr cbm.SCREEN
txa
rts
}}
}
asmsub height() clobbers(X, Y) -> ubyte @A {
; -- returns the text screen height (number of rows)
%asm {{
jsr cbm.SCREEN
tya
rts
}}
}
asmsub waitkey() -> ubyte @A {
%asm {{
- jsr cbm.GETIN
beq -
rts
}}
}
asmsub chrout_lit(ubyte character @A) {
; -- print the character always as a literal character, not as possible control code.
%asm {{
tax
lda #128
jsr cbm.CHROUT
txa
jmp cbm.CHROUT
}}
}
asmsub print_lit(str text @ AY) clobbers(A,Y) {
; -- print zero terminated string, from A/Y, as all literal characters (no control codes)
%asm {{
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
ldy #0
- lda (P8ZP_SCRATCH_W2),y
beq +
tax
lda #128
jsr cbm.CHROUT
txa
jsr cbm.CHROUT
iny
bne -
+ rts
}}
}
2020-08-27 16:10:22 +00:00
}