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

447 lines
8.7 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 Commodore-64
; 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 = 40
const ubyte DEFAULT_HEIGHT = 25
2024-11-06 21:14:53 +00:00
extsub $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() {
; beep
c64.MVOL = 11
c64.AD1 = %00110111
c64.SR1 = %00000000
c64.FREQ1 = 8500
c64.CR1 = %00010000
c64.CR1 = %00010001
}
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) {
2020-08-30 17:31:20 +00:00
; ---- fill the character screen with the given fill character and character color.
2019-01-06 01:11:16 +00:00
; (assumes screen and color matrix are at their default addresses)
%asm {{
2019-01-06 01:11:16 +00:00
pha
tya
jsr clear_screencolors
pla
jsr clear_screenchars
rts
}}
}
asmsub clear_screenchars (ubyte character @ A) clobbers(Y) {
2019-01-06 01:11:16 +00:00
; ---- clear the character screen with the given fill character (leaves colors)
; (assumes screen matrix is at the default address)
%asm {{
ldy #250
- sta cbm.Screen+250*0-1,y
sta cbm.Screen+250*1-1,y
sta cbm.Screen+250*2-1,y
sta cbm.Screen+250*3-1,y
dey
bne -
rts
}}
2019-01-06 01:11:16 +00:00
}
2020-09-21 19:39:36 +00:00
asmsub clear_screencolors (ubyte color @ A) clobbers(Y) {
2019-01-06 01:11:16 +00:00
; ---- clear the character screen colors with the given color (leaves characters).
; (assumes color matrix is at the default address)
%asm {{
ldy #250
- sta cbm.Colors+250*0-1,y
sta cbm.Colors+250*1-1,y
sta cbm.Colors+250*2-1,y
sta cbm.Colors+250*3-1,y
dey
bne -
2019-01-06 01:11:16 +00:00
rts
}}
}
sub color (ubyte txtcol) {
cbm.COLOR = txtcol
}
sub lowercase() {
c64.VMCSB |= 2
}
sub uppercase() {
c64.VMCSB &= ~2
}
asmsub scroll_left (bool alsocolors @ Pc) clobbers(A, X, Y) {
; ---- scroll the whole screen 1 character to the left
; contents of the rightmost column are unchanged, you should clear/refill this yourself
; Carry flag determines if screen color data must be scrolled too
2020-03-24 01:42:32 +00:00
%asm {{
bcc _scroll_screen
+ ; scroll the screen and the color memory
ldx #0
ldy #38
-
.for row=0, row<=24, row+=1
lda cbm.Screen + 40*row + 1,x
sta cbm.Screen + 40*row + 0,x
lda cbm.Colors + 40*row + 1,x
sta cbm.Colors + 40*row + 0,x
.next
inx
dey
bpl -
rts
_scroll_screen ; scroll only the screen memory
ldx #0
ldy #38
-
.for row=0, row<=24, row+=1
lda cbm.Screen + 40*row + 1,x
sta cbm.Screen + 40*row + 0,x
.next
inx
dey
bpl -
rts
}}
}
asmsub scroll_right (bool alsocolors @ Pc) clobbers(A,X) {
; ---- scroll the whole screen 1 character to the right
; contents of the leftmost column are unchanged, you should clear/refill this yourself
; Carry flag determines if screen color data must be scrolled too
%asm {{
bcc _scroll_screen
+ ; scroll the screen and the color memory
ldx #38
-
.for row=0, row<=24, row+=1
lda cbm.Screen + 40*row + 0,x
sta cbm.Screen + 40*row + 1,x
lda cbm.Colors + 40*row + 0,x
sta cbm.Colors + 40*row + 1,x
.next
dex
bpl -
rts
_scroll_screen ; scroll only the screen memory
ldx #38
-
.for row=0, row<=24, row+=1
lda cbm.Screen + 40*row + 0,x
sta cbm.Screen + 40*row + 1,x
.next
dex
bpl -
rts
}}
}
asmsub scroll_up (bool alsocolors @ Pc) clobbers(A,X) {
; ---- scroll the whole screen 1 character up
; contents of the bottom row are unchanged, you should refill/clear this yourself
; Carry flag determines if screen color data must be scrolled too
%asm {{
bcc _scroll_screen
+ ; scroll the screen and the color memory
ldx #39
-
.for row=1, row<=24, row+=1
lda cbm.Screen + 40*row,x
sta cbm.Screen + 40*(row-1),x
lda cbm.Colors + 40*row,x
sta cbm.Colors + 40*(row-1),x
.next
dex
bpl -
rts
_scroll_screen ; scroll only the screen memory
ldx #39
-
.for row=1, row<=24, row+=1
lda cbm.Screen + 40*row,x
sta cbm.Screen + 40*(row-1),x
.next
dex
bpl -
rts
}}
}
asmsub scroll_down (bool alsocolors @ Pc) clobbers(A,X) {
; ---- scroll the whole screen 1 character down
; contents of the top row are unchanged, you should refill/clear this yourself
; Carry flag determines if screen color data must be scrolled too
%asm {{
bcc _scroll_screen
+ ; scroll the screen and the color memory
ldx #39
-
.for row=23, row>=0, row-=1
lda cbm.Colors + 40*row,x
sta cbm.Colors + 40*(row+1),x
lda cbm.Screen + 40*row,x
sta cbm.Screen + 40*(row+1),x
.next
dex
bpl -
rts
_scroll_screen ; scroll only the screen memory
ldx #39
-
.for row=23, row>=0, row-=1
lda cbm.Screen + 40*row,x
sta cbm.Screen + 40*(row+1),x
.next
dex
bpl -
rts
}}
}
2020-09-19 20:10:33 +00:00
asmsub setchr (ubyte col @X, ubyte row @Y, ubyte character @A) clobbers(A, Y) {
; ---- sets the character in the screen matrix at the given position
2018-12-18 00:43:04 +00:00
%asm {{
2020-09-19 20:10:33 +00:00
pha
tya
2018-12-18 00:43:04 +00:00
asl a
tay
lda _screenrows+1,y
sta _mod+2
2020-09-19 20:10:33 +00:00
txa
2018-12-18 00:43:04 +00:00
clc
2020-09-19 20:10:33 +00:00
adc _screenrows,y
2018-12-18 00:43:04 +00:00
sta _mod+1
bcc +
inc _mod+2
2020-09-19 20:10:33 +00:00
+ pla
2018-12-18 00:43:04 +00:00
_mod sta $ffff ; modified
rts
2019-01-12 15:13:40 +00:00
_screenrows .word cbm.Screen + range(0, 1000, 40)
; !notreached!
2018-12-18 00:43:04 +00:00
}}
}
2020-09-19 20:10:33 +00:00
asmsub getchr (ubyte col @A, ubyte row @Y) clobbers(Y) -> ubyte @ A {
2019-02-21 00:31:33 +00:00
; ---- get the character in the screen matrix at the given location
%asm {{
2020-09-19 20:10:33 +00:00
pha
tya
2019-02-21 00:31:33 +00:00
asl a
tay
lda setchr._screenrows+1,y
sta _mod+2
2020-09-19 20:10:33 +00:00
pla
2019-02-21 00:31:33 +00:00
clc
2020-09-19 20:10:33 +00:00
adc setchr._screenrows,y
2019-02-21 00:31:33 +00:00
sta _mod+1
bcc _mod
inc _mod+2
_mod lda $ffff ; modified
rts
2019-02-21 00:31:33 +00:00
}}
}
2020-09-19 20:10:33 +00:00
asmsub setclr (ubyte col @X, ubyte row @Y, ubyte color @A) clobbers(A, Y) {
; ---- set the color in A on the screen matrix at the given position
2018-12-18 00:43:04 +00:00
%asm {{
2020-09-19 20:10:33 +00:00
pha
tya
2018-12-18 00:43:04 +00:00
asl a
tay
lda _colorrows+1,y
sta _mod+2
2020-09-19 20:10:33 +00:00
txa
2018-12-18 00:43:04 +00:00
clc
2020-09-19 20:10:33 +00:00
adc _colorrows,y
2018-12-18 00:43:04 +00:00
sta _mod+1
bcc +
inc _mod+2
2020-09-19 20:10:33 +00:00
+ pla
2018-12-18 00:43:04 +00:00
_mod sta $ffff ; modified
rts
2019-01-12 15:13:40 +00:00
2018-12-18 00:43:04 +00:00
_colorrows .word $d800 + range(0, 1000, 40)
; !notreached!
2018-12-18 00:43:04 +00:00
}}
}
2020-09-19 20:10:33 +00:00
asmsub getclr (ubyte col @A, ubyte row @Y) clobbers(Y) -> ubyte @ A {
2019-02-21 00:31:33 +00:00
; ---- get the color in the screen color matrix at the given location
%asm {{
2020-09-19 20:10:33 +00:00
pha
tya
2019-02-21 00:31:33 +00:00
asl a
tay
lda setclr._colorrows+1,y
sta _mod+2
2020-09-19 20:10:33 +00:00
pla
2019-02-21 00:31:33 +00:00
clc
2020-09-19 20:10:33 +00:00
adc setclr._colorrows,y
2019-02-21 00:31:33 +00:00
sta _mod+1
bcc _mod
inc _mod+2
_mod lda $ffff ; modified
rts
2019-02-21 00:31:33 +00:00
}}
}
2019-01-12 15:13:40 +00:00
sub setcc (ubyte col, ubyte row, ubyte character, ubyte charcolor) {
2018-12-18 00:43:04 +00:00
; ---- set char+color at the given position on the screen
%asm {{
2019-08-04 16:40:50 +00:00
lda row
2018-12-18 00:43:04 +00:00
asl a
tay
lda setchr._screenrows+1,y
sta _charmod+2
adc #$d4
sta _colormod+2
lda setchr._screenrows,y
clc
adc col
2018-12-18 00:43:04 +00:00
sta _charmod+1
sta _colormod+1
bcc +
inc _charmod+2
inc _colormod+2
+ lda character
2018-12-18 00:43:04 +00:00
_charmod sta $ffff ; modified
lda charcolor
2018-12-18 00:43:04 +00:00
_colormod sta $ffff ; modified
rts
2019-01-12 15:13:40 +00:00
}}
2018-12-18 00:43:04 +00:00
}
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
}}
}
2020-08-27 16:10:22 +00:00
}