1
0
mirror of https://github.com/cc65/cc65.git synced 2025-03-01 11:29:27 +00:00

Merge pull request #213 from mrdudz/soft80

soft80 implementation for C-64
This commit is contained in:
Oliver Schmidt 2015-10-22 17:56:21 +02:00
commit a957f80204
21 changed files with 2223 additions and 11 deletions

View File

@ -116,6 +116,39 @@ cl65 -o file.prg -u __EXEHDR__ -t c64 -C c64-asm.cfg source.s
Please note that in this case a changed start address doesn't make sense,
since the program must be loaded to the BASIC start address.
<sect>Extras<p>
<sect1>80 Columns conio driver<p>
The C64 package comes with an alternative software driven 80 columns
module <tt/c64-soft80.o/ which uses the memory under I/O between &dollar;d000
and &dollar;ffff.
In memory constrained situations the memory from &dollar;400 to &dollar;7FF
can be made available to a program by calling <tt/_heapadd ((void *) 0x400, 0x400);/
at the beginning of <tt/main()/. Doing so is beneficial even if the program
doesn't use the the heap explicitly because loading a driver uses the heap implicitly.
Using <tt/c64-soft80.o/ is as simple as placing it on the linker command
line like this:
<tscreen><verb>
cl65 -t c64 myprog.c c64-soft80.o
</verb></tscreen>
Note that the soft80 conio driver is incompatible with the
<tt/c64-ram.emd (c64_ram_emd)/ extended memory driver and the
<tt/c64-hi.tgi (c64_hi_tgi)/ graphics driver.
<sect2>80 Columns conio driver (monochrome)<p>
In an (even more) memory constrained situation, a size optimized version of the
software driven 80 columns module may be used, which only supports one common
text color for the whole screen.
<tscreen><verb>
cl65 -t c64 myprog.c c64-soft80mono.o
</verb></tscreen>
<sect>Platform-specific header files<p>
@ -216,6 +249,9 @@ configuration.
palette of the 16 C64 colors).
</descrip><p>
Note that the graphics drivers are incompatible with the
<tt/c64-ram.emd (c64_ram_emd)/ extended memory driver and the
<tt/c64-soft80.o/ software 80 columns conio driver.
<sect1>Extended memory drivers<p>
@ -241,7 +277,7 @@ configuration.
<tag><tt/c64-ram.emd (c64_ram_emd)/</tag>
A driver for the hidden RAM below the I/O area and kernal ROM. Supports 48
256 byte pages. Please note that this driver is incompatible with any of the
graphics drivers!
graphics drivers, or the soft80 conio driver!
<tag><tt/c64-ramcart.emd (c64_ramcart_emd)/</tag>
A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak.

17
libsrc/c64/bordercolor.s Normal file
View File

@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _bordercolor
.include "c64.inc"
_bordercolor:
ldx VIC_BORDERCOLOR ; get old value
sta VIC_BORDERCOLOR ; set new value
txa
rts

View File

@ -3,11 +3,10 @@
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _textcolor, _bgcolor, _bordercolor
.export _textcolor, _bgcolor
.include "c64.inc"
@ -23,11 +22,3 @@ _bgcolor:
sta VIC_BG_COLOR0 ; set new value
txa
rts
_bordercolor:
ldx VIC_BORDERCOLOR ; get old value
sta VIC_BORDERCOLOR ; set new value
txa
rts

52
libsrc/c64/extra/soft80.s Normal file
View File

@ -0,0 +1,52 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; import/overload stubs for the soft80 implementation
.include "../soft80.inc"
; soft80_cgetc.s
.import soft80_cgetc
.export _cgetc := soft80_cgetc ; cgetc.s
; soft80_color.s
.import soft80_textcolor
.import soft80_bgcolor
.export _textcolor := soft80_textcolor ; color.s
.export _bgcolor := soft80_bgcolor ; color.s
; soft80_cputc.s
.import soft80_cputc
.import soft80_cputcxy
.import soft80_cputdirect
.import soft80_putchar
.import soft80_newline
.import soft80_plot
.export _cputc := soft80_cputc ; cputc.s
.export _cputcxy := soft80_cputcxy ; cputc.s
.export cputdirect := soft80_cputdirect ; cputc.s
.export putchar := soft80_putchar ; cputc.s
.export newline := soft80_newline ; cputc.s
.export plot := soft80_plot ; cputc.s
; soft80_kclrscr.s
.import soft80_kclrscr
.export _clrscr := soft80_kclrscr ; clrscr.s
.export CLRSCR := soft80_kclrscr ; kernal func (c64.inc)
; soft80_kplot.s
.import soft80_kplot
.export PLOT := soft80_kplot ; kplot.s
; soft80_kscreen.s
.import soft80_screensize
.export screensize := soft80_screensize ; _scrsize.s
.export SCREEN := soft80_screensize ; kernal func (kernal.s)
; VIC sprite data for the mouse pointer
.export mcb_spritememory := soft80_spriteblock
.export mcb_spritepointer := (soft80_vram + $03F8)
; Chars used by chline () and cvline ()
.exportzp chlinechar = CH_HLINE
.exportzp cvlinechar = CH_VLINE

View File

@ -0,0 +1,55 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; import/overload stubs for the monochrome soft80 implementation
;
; - optimized for size, almost 1k smaller footprint than the full color version
; - textcolor() sets one common text color for the whole screen
;
.include "../soft80.inc"
; soft80mono_cgetc.s
.import soft80mono_cgetc
.export _cgetc := soft80mono_cgetc ; cgetc.s
; soft80mono_color.s
.import soft80mono_textcolor
.import soft80mono_bgcolor
.export _textcolor := soft80mono_textcolor ; color.s
.export _bgcolor := soft80mono_bgcolor ; color.s
; soft80mono_cputc.s
.import soft80mono_cputc
.import soft80mono_cputcxy
.import soft80mono_cputdirect
.import soft80mono_putchar
.import soft80mono_newline
.import soft80mono_plot
.export _cputc := soft80mono_cputc ; cputc.s
.export _cputcxy := soft80mono_cputcxy ; cputc.s
.export cputdirect := soft80mono_cputdirect ; cputc.s
.export putchar := soft80mono_putchar ; cputc.s
.export newline := soft80mono_newline ; cputc.s
.export plot := soft80mono_plot ; cputc.s
; soft80mono_kclrscr.s
.import soft80mono_kclrscr
.export _clrscr := soft80mono_kclrscr ; clrscr.s
.export CLRSCR := soft80mono_kclrscr ; kernal func (c64.inc)
; soft80mono_kplot.s
.import soft80mono_kplot
.export PLOT := soft80mono_kplot ; kplot.s
; soft80_kscreen.s
.import soft80_screensize
.export screensize := soft80_screensize ; _scrsize.s
.export SCREEN := soft80_screensize ; kernal func (kernal.s)
; VIC sprite data for the mouse pointer
.export mcb_spritememory := soft80_spriteblock
.export mcb_spritepointer := (soft80_vram + $03F8)
; Chars used by chline () and cvline ()
.exportzp chlinechar = CH_HLINE
.exportzp cvlinechar = CH_VLINE

46
libsrc/c64/soft80.inc Normal file
View File

@ -0,0 +1,46 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; internal constants for the soft80 implementation
soft80_lo_charset = $d000
soft80_hi_charset = $d400
soft80_vram = $d800 ; ram under i/o
soft80_colram = $d800 ; color ram (used for temp. storage)
soft80_spriteblock = $dc00 ; 64 bytes reserved for pointer sprite data
; tables for kplot
soft80_bitmapxlo = $dc40 ; (80 bytes)
soft80_bitmapxhi = $dc40 + 80 ; (80 bytes)
soft80_vramlo = $dc40 + 160 ; (25 bytes)
; align to next page for speed
soft80_vramhi = $dd00 ; (25 bytes)
soft80_bitmapylo = $dd00 + 25 ; (25 bytes)
soft80_bitmapyhi = $dd00 + 50 ; (25 bytes)
soft80_bitmap = $e000
charsperline = 80
screenrows = 25
; FIXME: these should match petscii and perhaps come from a common cbm.inc?
CH_ESC = 95
CH_HLINE = 96
CH_CROSS = 123
CH_VLINE = 125
CH_PI = 126
CH_LTEE = 171
CH_URCORNER = 174
CH_LLCORNER = 173
CH_ULCORNER = 176
CH_BTEE = 177
CH_TTEE = 178
CH_RTEE = 179
CH_LRCORNER = 189
;-------------------------------------------------------------------------------
; set to 0 to disable the color-ram "voodoo" for debugging purposes
.define SOFT80COLORVOODOO 1
; set to 0 to disable special case optimization for the "space" character
.define SOFT80FASTSPACE 1

90
libsrc/c64/soft80_cgetc.s Normal file
View File

@ -0,0 +1,90 @@
;
; Groepaz/Hitmen, 11.10.2015
;
; high level implementation for the soft80 implementation
;
; char cgetc (void);
;
.export soft80_cgetc
.import soft80_internal_cellcolor, soft80_internal_cursorxlsb
.import cursor
.importzp tmp1
.include "c64.inc"
.include "soft80.inc"
soft80_cgetc:
lda KEY_COUNT ; Get number of characters
bne @L3 ; Jump if there are already chars waiting
sec
jsr invertcursor ; set cursor on or off accordingly
@L1: lda KEY_COUNT ; wait for key
beq @L1
clc
jsr invertcursor ; set cursor on or off accordingly
@L3: jsr KBDREAD ; Read char and return in A
ldx #0
rts
; Switch the cursor on or off (invert)
invertcursor:
lda cursor
bne @invert
rts
@invert:
sei
lda $01 ; enable RAM under I/O
pha
lda #$34
sta $01
ldy #$00
jsr setcolor
ldx soft80_internal_cursorxlsb
@lp1:
lda (SCREEN_PTR),y
eor nibble,x
sta (SCREEN_PTR),y
iny
cpy #8
bne @lp1
pla
sta $01 ; enable I/O
cli
rts
; do not use soft80_putcolor here to make sure the cursor is always
; shown using the current textcolor without disturbing the "color voodoo"
; in soft80_cputc
setcolor:
;ldy #0 ; is 0
bcs @set
; restore old value
lda tmp1
sta (CRAM_PTR),y ; vram
rts
@set:
; save old value
lda (CRAM_PTR),y ; vram
sta tmp1
lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
rts
.rodata
nibble: .byte $f0, $0f
;-------------------------------------------------------------------------------
; force the init constructor to be imported
.import soft80_init
conio_init = soft80_init

182
libsrc/c64/soft80_charset.s Normal file
View File

@ -0,0 +1,182 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; character set for use with the soft80 implementations
;
; the format of the data follows the following layout:
;
; - to avoid unnecessary petscii->screencode conversions, the order of the
; individual characters is different to the C64 ROM charset:
; - $00 - $1f screencodes $60 - $7f (petscii codes $a0 - $bf)
; - $20 - $3f screencodes $20 - $3f (petscii codes $20 - $3f)
; - $40 - $5f screencodes $00 - $1f (petscii codes $40 - $5f)
; - $60 - $7f screencodes $40 - $5f (petscii codes $60 - $7f)
; - only 128 characters are defined here, the soft80 implementation will invert
; the graphics data for inverted display on the fly.
; - since the charset is 4 by 8 pixels, only the lower 4bit of each byte is
; used. the upper bits have to be 0.
; - finally the lower 4bits are "inverted", ie a space character is represented
; as $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
;
; the graphics data is arranged differently to normal C64 charsets for speed,
; first comes the first row of all characters, then the second row in the next
; block, etc. like this:
;
; +000 ....xxxx ......xx ....xxxx ........
; +080 ....xxxx ......xx ....xxxx ....xxxx
; +100 ....xxxx ......xx ....xxxx ....xxxx
; +180 ....x..x ......xx ....xxxx ....xxxx
; +200 ....x..x ......xx ........ ....xxxx
; +280 ....xxxx ......xx ........ ....xxxx
; +300 ....xxxx ......xx ........ ....xxxx
; +380 ....xxxx ......xx ........ ....xxxx
; [...]
; +040 ....x.xx ....xxxx ....xxxx ....xxxx
; +0c0 .....x.x ....xxxx .....xxx ....xxxx
; +140 .......x ....x.xx .....xxx ....x..x
; +1c0 .......x ....xx.x ......xx .....xxx
; +240 .....xxx ....x..x .....x.x .....xxx
; +2c0 .....x.x .....x.x .....x.x .....xxx
; +340 ....x.xx ....x..x ......xx ....x..x
; +3c0 ....xxxx ....xxxx ....xxxx ....xxxx
.export soft80_charset
.segment "INIT"
soft80_charset:
.byte $0f,$03,$0f,$00,$0f,$07,$05,$0e
.byte $0f,$05,$0e,$0b,$0f,$0b,$0f,$0f
.byte $0f,$0b,$0f,$0b,$07,$07,$0e,$00
.byte $00,$0f,$0e,$0f,$0c,$0b,$03,$03
.byte $0f,$0b,$05,$05,$0b,$05,$0b,$0b
.byte $0d,$07,$0f,$0f,$0f,$0f,$0f,$0d
.byte $0b,$0b,$0b,$0b,$05,$01,$0b,$01
.byte $0b,$0b,$0f,$0f,$0d,$0f,$07,$0b
.byte $0b,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$09,$07,$03,$0b,$0f
.byte $0f,$0b,$03,$0b,$03,$01,$01,$0b
.byte $05,$01,$09,$05,$07,$05,$05,$0b
.byte $03,$0b,$03,$0b,$01,$05,$05,$05
.byte $05,$05,$01,$0b,$07,$0b,$0f,$0a
.byte $0f,$03,$0f,$0f,$0f,$07,$05,$0e
.byte $0f,$0a,$0e,$0b,$0f,$0b,$0f,$0f
.byte $0f,$0b,$0f,$0b,$07,$07,$0e,$00
.byte $00,$0f,$0e,$0f,$0c,$0b,$03,$03
.byte $0f,$0b,$05,$05,$09,$05,$05,$0b
.byte $0b,$0b,$05,$0b,$0f,$0f,$0f,$0d
.byte $05,$0b,$05,$05,$05,$07,$05,$05
.byte $05,$05,$0f,$0f,$0b,$0f,$0b,$05
.byte $05,$0f,$07,$0f,$0d,$0f,$09,$0f
.byte $07,$0b,$0d,$07,$03,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0b,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0b,$07,$0b,$0b,$0b
.byte $0f,$0b,$05,$05,$05,$07,$07,$05
.byte $05,$0b,$0d,$05,$07,$01,$01,$05
.byte $05,$05,$05,$05,$0b,$05,$05,$05
.byte $05,$05,$0d,$0b,$07,$0b,$0f,$0a
.byte $0f,$03,$0f,$0f,$0f,$07,$0a,$0e
.byte $0f,$05,$0e,$0b,$0f,$0b,$0f,$0f
.byte $0f,$0b,$0f,$0b,$07,$07,$0e,$0f
.byte $00,$0f,$0d,$0f,$0c,$0b,$03,$03
.byte $0f,$0b,$05,$00,$07,$0d,$0b,$07
.byte $0b,$0b,$0b,$0b,$0f,$0f,$0f,$0b
.byte $01,$03,$0d,$0d,$05,$03,$07,$0d
.byte $05,$05,$0b,$0b,$0b,$08,$0b,$0d
.byte $01,$0b,$07,$09,$0d,$0b,$0b,$09
.byte $07,$0f,$0f,$07,$0b,$05,$03,$0b
.byte $03,$09,$03,$09,$01,$05,$05,$05
.byte $05,$05,$01,$0b,$0b,$0b,$05,$0b
.byte $0f,$05,$05,$07,$05,$07,$07,$07
.byte $05,$0b,$0d,$03,$07,$01,$01,$05
.byte $05,$05,$05,$07,$0b,$05,$05,$05
.byte $0b,$05,$0b,$0b,$0b,$0b,$0a,$05
.byte $09,$03,$0f,$0f,$0f,$07,$0a,$0e
.byte $0f,$0a,$0e,$08,$0f,$08,$03,$0f
.byte $08,$00,$00,$03,$07,$07,$0e,$0f
.byte $0f,$0f,$05,$0f,$0c,$03,$03,$03
.byte $0f,$0b,$0f,$05,$0b,$0b,$0b,$0f
.byte $0b,$0b,$01,$01,$0f,$01,$0f,$0b
.byte $05,$0b,$0b,$0b,$01,$0d,$03,$0b
.byte $0b,$09,$0f,$0f,$07,$0f,$0d,$0b
.byte $01,$0d,$03,$07,$09,$05,$01,$05
.byte $03,$03,$0d,$05,$0b,$01,$05,$05
.byte $05,$05,$05,$07,$0b,$05,$05,$05
.byte $05,$05,$0d,$0b,$0b,$0b,$05,$00
.byte $00,$01,$03,$07,$05,$03,$03,$01
.byte $01,$0b,$0d,$03,$07,$05,$01,$05
.byte $03,$05,$03,$0b,$0b,$05,$05,$01
.byte $0b,$0b,$0b,$00,$0b,$0b,$05,$05
.byte $09,$03,$00,$0f,$0f,$07,$05,$0e
.byte $05,$05,$0e,$08,$0c,$08,$03,$0f
.byte $08,$00,$00,$03,$07,$07,$0e,$0f
.byte $0f,$0f,$03,$03,$0f,$03,$0f,$0c
.byte $0f,$0f,$0f,$00,$0d,$07,$04,$0f
.byte $0b,$0b,$0b,$0b,$0f,$0f,$0f,$0b
.byte $05,$0b,$07,$0d,$0d,$0d,$05,$0b
.byte $05,$0d,$0f,$0f,$0b,$08,$0b,$0b
.byte $07,$09,$05,$07,$05,$01,$0b,$05
.byte $05,$0b,$0d,$03,$0b,$01,$05,$05
.byte $05,$05,$07,$0b,$0b,$05,$05,$01
.byte $0b,$05,$0b,$0b,$0b,$0b,$0f,$00
.byte $00,$05,$05,$07,$05,$07,$07,$05
.byte $05,$0b,$0d,$03,$07,$05,$01,$05
.byte $07,$05,$03,$0d,$0b,$05,$05,$01
.byte $0b,$0b,$0b,$00,$07,$0b,$05,$0a
.byte $0f,$03,$00,$0f,$0f,$07,$05,$0e
.byte $05,$0a,$0e,$0b,$0c,$0f,$0b,$0f
.byte $0b,$0f,$0b,$0b,$07,$07,$0e,$0f
.byte $0f,$00,$03,$03,$0f,$0f,$0f,$0c
.byte $0f,$0f,$0f,$05,$03,$05,$05,$0f
.byte $0b,$0b,$05,$0b,$0b,$0f,$0b,$07
.byte $05,$0b,$07,$05,$0d,$05,$05,$0b
.byte $05,$05,$0b,$0b,$0b,$0f,$0b,$0f
.byte $05,$05,$05,$07,$05,$07,$0b,$09
.byte $05,$0b,$0d,$05,$0b,$05,$05,$05
.byte $03,$09,$07,$0d,$0b,$05,$0b,$01
.byte $05,$09,$07,$0b,$0d,$0b,$0f,$0b
.byte $0f,$05,$05,$05,$05,$07,$07,$05
.byte $05,$0b,$05,$05,$07,$05,$05,$05
.byte $07,$0b,$05,$05,$0b,$05,$0b,$05
.byte $05,$0b,$07,$0b,$07,$0b,$05,$0a
.byte $0f,$03,$00,$0f,$0f,$07,$0a,$0e
.byte $0a,$05,$0e,$0b,$0c,$0f,$0b,$00
.byte $0b,$0f,$0b,$0b,$07,$07,$0e,$0f
.byte $0f,$00,$07,$03,$0f,$0f,$0f,$0c
.byte $0f,$0b,$0f,$05,$0b,$05,$08,$0f
.byte $0d,$07,$0f,$0f,$0b,$0f,$0b,$07
.byte $0b,$01,$01,$0b,$0d,$0b,$0b,$0b
.byte $0b,$0b,$0f,$0b,$0d,$0f,$07,$0b
.byte $0b,$09,$03,$09,$09,$09,$0b,$0d
.byte $05,$01,$0d,$05,$01,$05,$05,$0b
.byte $07,$0d,$07,$03,$0d,$09,$0b,$05
.byte $05,$0d,$01,$09,$0d,$03,$0f,$0b
.byte $0f,$05,$03,$0b,$03,$01,$07,$0b
.byte $05,$01,$0b,$05,$01,$05,$05,$0b
.byte $07,$0d,$05,$0b,$0b,$0b,$0b,$05
.byte $05,$0b,$01,$0b,$0b,$0b,$05,$05
.byte $0f,$03,$00,$0f,$00,$07,$0a,$0e
.byte $0a,$0a,$0e,$0b,$0c,$0f,$0b,$00
.byte $0b,$0f,$0b,$0b,$07,$07,$0e,$0f
.byte $0f,$00,$0f,$03,$0f,$0f,$0f,$0c
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$07,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$07,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$03
.byte $0f,$0f,$03,$0f,$0f,$0f,$0f,$0f
.byte $07,$0d,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$03,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
.byte $0f,$0f,$0f,$0b,$0b,$0b,$0f,$05

159
libsrc/c64/soft80_color.s Normal file
View File

@ -0,0 +1,159 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; high level implementation for the soft80 implementation
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
;
.export soft80_textcolor, soft80_bgcolor
.import soft80_internal_cellcolor, soft80_internal_bgcolor
.import soft80_internal_cursorxlsb
.import soft80_kplot, soft80_checkchar
.importzp tmp1, tmp2
.include "c64.inc"
.include "soft80.inc"
soft80_textcolor:
ldx CHARCOLOR ; get old value
sta CHARCOLOR ; set new value
mkcharcolor:
lda soft80_internal_bgcolor
asl a
asl a
asl a
asl a
sta tmp1 ; remember new bg color (high nibble)
ora CHARCOLOR
sta soft80_internal_cellcolor ; text/bg combo for new chars
txa ; get old value
rts
soft80_bgcolor:
ldx soft80_internal_bgcolor ; get old value
stx tmp2 ; save old value
sta soft80_internal_bgcolor ; set new value
jsr mkcharcolor
lda CURS_X
pha
lda CURS_Y
pha
ldy #0
ldx #0
clc
jsr soft80_kplot
sei
lda $01
pha
ldx #$34
stx $01 ; $34
;ldy #0 ; is still 0
lda #24
sta CURS_Y
lpy:
lda #39
sta CURS_X
lpx:
.if SOFT80COLORVOODOO = 1
; if the old bg color is equal to color ram of that cell, then also
; update the color ram to the new value.
inc $01 ; $35
lda (CRAM_PTR),y ; colram
stx $01 ; $34
and #$0f
cmp tmp2 ; old bg color
bne @sk1
; if the left character in the cell is not a space, then dont update
; the color ram
lda #1
sta soft80_internal_cursorxlsb
jsr soft80_checkchar
bcc @sk1
lda soft80_internal_bgcolor ; new bg color
inc $01 ; $35
sta (CRAM_PTR),y ; colram
stx $01 ; $34
@sk1:
.endif
; if the old bg color is equal to text color in this cell, then also
; update the text color to the new value.
lda (CRAM_PTR),y ; vram
and #$0f
cmp tmp2 ; old bg color
bne @sk2
; if there are non space characters in the cell, do not update the
; color ram
pha
lda #0
sta soft80_internal_cursorxlsb
jsr soft80_checkchar
pla
bcc @sk2
pha
inc soft80_internal_cursorxlsb
jsr soft80_checkchar
pla
bcc @sk2
lda soft80_internal_bgcolor ; new bg color
@sk2:
ora tmp1 ; new bg color (high nibble)
sta (CRAM_PTR),y ; vram
inc CRAM_PTR
bne @sk3
inc CRAM_PTR+1
@sk3:
lda SCREEN_PTR
clc
adc #8
sta SCREEN_PTR
bcc @sk4
inc SCREEN_PTR+1
@sk4:
dec CURS_X
bpl lpx
dec CURS_Y
bpl lpy
pla
sta $01 ; enable I/O
cli
pla ; CURS_Y
tax
pla ; CURS_X
tay
clc
jsr soft80_kplot
lda tmp2 ; get old value
rts
;-------------------------------------------------------------------------------
; force the init constructor to be imported
.import soft80_init
conio_init = soft80_init

162
libsrc/c64/soft80_conio.s Normal file
View File

@ -0,0 +1,162 @@
;
; Groepaz/Hitmen, 11.10.2015
;
; Low level init code for soft80 screen output/console input
;
.constructor soft80_init, 8
.destructor soft80_shutdown
.import soft80_kclrscr, soft80_charset
.export soft80_internal_bgcolor, soft80_internal_cellcolor
.export soft80_internal_cursorxlsb
.importzp ptr1, ptr2, ptr3
.include "c64.inc"
.include "soft80.inc"
soft80_init:
lda soft80_first_init
bne @skp
jsr firstinit
@skp:
; the "color voodoo" in other parts of the code relies on the vram and
; colorram being set up as expected, which is why we cant use the
; _bgcolor and _textcolor functions here.
lda CHARCOLOR ; use current textcolor
and #$0f ; make sure the upper nibble is 0s
sta CHARCOLOR
lda VIC_BG_COLOR0 ; use current bgcolor
and #$0f
sta soft80_internal_bgcolor
asl a
asl a
asl a
asl a
ora CHARCOLOR
sta soft80_internal_cellcolor
lda #$3b
sta VIC_CTRL1
lda #$00
sta CIA2_PRA
lda #$68
sta VIC_VIDEO_ADR
lda #$c8
sta VIC_CTRL2
jmp soft80_kclrscr
soft80_shutdown:
lda #$1b
sta VIC_CTRL1
lda #$03
sta CIA2_PRA
lda #$15
sta VIC_VIDEO_ADR
rts
.segment "INIT"
firstinit:
; copy charset to RAM under I/O
sei
lda $01
pha
lda #$34
sta $01
inc soft80_first_init
lda #>soft80_charset
sta ptr1+1
lda #<soft80_charset
sta ptr1
lda #>soft80_lo_charset
sta ptr2+1
lda #<soft80_lo_charset
sta ptr2
lda #>soft80_hi_charset
sta ptr3+1
lda #<soft80_hi_charset
sta ptr3
ldx #4
@l2:
ldy #0
@l1:
lda (ptr1),y
sta (ptr2),y
asl a
asl a
asl a
asl a
sta (ptr3),y
iny
bne @l1
inc ptr1+1
inc ptr2+1
inc ptr3+1
dex
bne @l2
; copy the kplot tables to ram under I/O
;ldx #0 ; is 0
@l3:
lda soft80_tables_data_start,x
sta soft80_bitmapxlo,x
lda soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $100) ,x
sta soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $100),x
inx
bne @l3
pla
sta $01
cli
rts
; the following tables take up 267 bytes, used by kplot
soft80_tables_data_start:
soft80_bitmapxlo_data:
.repeat 80,col
.byte <((col/2)*8)
.endrepeat
soft80_bitmapxhi_data:
.repeat 80,col
.byte >((col/2)*8)
.endrepeat
soft80_vramlo_data:
.repeat 25,row
.byte <(soft80_vram+(row*40))
.endrepeat
.byte 0,0,0,0,0,0,0 ; padding to next page
soft80_vramhi_data:
.repeat 25,row
.byte >(soft80_vram+(row*40))
.endrepeat
soft80_bitmapylo_data:
.repeat 25,row
.byte <(soft80_bitmap+(row*40*8))
.endrepeat
soft80_bitmapyhi_data:
.repeat 25,row
.byte >(soft80_bitmap+(row*40*8))
.endrepeat
soft80_tables_data_end:
;-------------------------------------------------------------------------------
.segment "INITBSS"
soft80_internal_cellcolor:
.res 1
soft80_internal_bgcolor:
.res 1
soft80_internal_cursorxlsb:
.res 1
.data
soft80_first_init:
.byte 0 ; flag to check first init, this really must be in .data

522
libsrc/c64/soft80_cputc.s Normal file
View File

@ -0,0 +1,522 @@
;
; Groepaz/Hitmen, 11.10.2015
;
; high level implementation for the soft80 implementation
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export soft80_cputcxy, soft80_cputc
.export soft80_cputdirect, soft80_putchar
.export soft80_newline, soft80_plot
.export soft80_checkchar
.import popa, _gotoxy
.import soft80_kplot
.import soft80_internal_bgcolor, soft80_internal_cellcolor
.import soft80_internal_cursorxlsb
.importzp tmp4,tmp3
.include "c64.inc"
.include "soft80.inc"
soft80_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
pla ; Restore C
; Plot a character - also used as internal function
soft80_cputc:
cmp #$0A ; CR?
bne L1
lda #0
sta CURS_X
; Set cursor position, calculate RAM pointers
soft80_plot:
ldx CURS_Y
ldy CURS_X
clc
jmp soft80_kplot ; Set the new cursor
L1: cmp #$0D ; LF?
beq soft80_newline ; Recalculate pointers
; shortcut for codes < $80 ... codes $20-$7f can be printed directly,
; codes $00-$1f are control codes which are not printable and thus may
; give undefined result.
tay
bpl @L10
; codes $80-$ff must get converted like this:
; $80-$9f -> dont care (control codes)
; $a0-$bf -> $00-$1f
; $c0-$df -> $60-$7f
; $e0-$ff -> $00-$1f
ora #%01000000 ; $40
clc
adc #%00100000 ; $20
and #%01111111 ; $7f
@L10:
; entry point for direct output of a character. the value passed in
; akku must match the offset in the charset.
; - the following may not modify tmp1
soft80_cputdirect:
jsr soft80_putchar ; Write the character to the screen
; Advance cursor position
iny ; contains CURS_X
cpy #charsperline
beq @L3
sty CURS_X
tya
and #$01
sta soft80_internal_cursorxlsb
bne @L5
lda SCREEN_PTR
clc
adc #8
sta SCREEN_PTR
bcc @L4
inc SCREEN_PTR+1
@L4:
inc CRAM_PTR
bne @L5
inc CRAM_PTR+1
@L5:
rts
@L3:
inc CURS_Y ; new line
ldy #0 ; + cr
sty CURS_X
jmp soft80_plot
; - the following may not modify tmp1
soft80_newline:
lda SCREEN_PTR
clc
adc #<(40*8)
sta SCREEN_PTR
lda SCREEN_PTR+1
adc #>(40*8)
sta SCREEN_PTR+1
lda CRAM_PTR
clc
adc #40
sta CRAM_PTR
bcc @L5
inc CRAM_PTR+1
@L5:
inc CURS_Y
rts
;-------------------------------------------------------------------------------
; All following code belongs to the character output to bitmap
;
; this stuff is going to be used a lot so we unroll it a bit for speed
;-------------------------------------------------------------------------------
.if SOFT80FASTSPACE = 1
; output inverted space (odd)
draw_spaceinvers_odd:
.repeat 8,line
lda (SCREEN_PTR),y
and #$f0
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
jmp draw_back
; output inverted space (general entry point)
; in: y must be $00
draw_spaceinvers:
.if SOFT80COLORVOODOO = 1
jsr soft80_putcolor
.else
lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
.endif
lda soft80_internal_cursorxlsb
bne draw_spaceinvers_odd
; output inverted space (even)
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
jmp draw_back
; output space (odd)
draw_space_odd:
.repeat 8,line
lda (SCREEN_PTR),y
ora #$0f
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
jmp draw_back
; output space (general entry point)
; in: y must be $00
draw_space:
lda RVS
bne draw_spaceinvers
.if SOFT80COLORVOODOO = 1
jsr remcolor
.endif
;ldy #$00 ; is still $00
lda soft80_internal_cursorxlsb
bne draw_space_odd
; output space (even)
.repeat 8,line
lda (SCREEN_PTR),y
ora #$f0
sta (SCREEN_PTR),y
.if (line < 7)
iny
.endif
.endrepeat
jmp draw_back
.endif
;-------------------------------------------------------------------------------
; output one character in internal encoding without advancing cursor position
; generic entry point
;
; - the following may not modify tmp1
; in: A: charcode
; out: Y: CURS_X
;
soft80_putchar:
sta tmp3 ; remember charcode
sei
ldx $01
stx tmp4
ldx #$34
stx $01 ; will stay $34 for space
ldy #$00 ; will be $00 from now on
.if SOFT80FASTSPACE = 1
cmp #' ' ; space is a special (optimized) case
beq draw_space
.endif
.if SOFT80COLORVOODOO = 1
jsr soft80_putcolor
.else
lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
.endif
; output character
ldx tmp3 ; get charcode
lda RVS
beq @skp
jmp draw_charinvers
@skp:
lda soft80_internal_cursorxlsb
bne draw_char_even
; output character (odd)
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
ora soft80_hi_charset+(line*$80),x
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
jmp draw_back
; output character (even)
draw_char_even:
.repeat 8,line
lda (SCREEN_PTR),y
and #$f0
ora soft80_lo_charset+(line*$80),x
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
draw_back:
lda tmp4
sta $01
cli
ldy CURS_X
rts
; output inverted character (odd)
draw_charinvers_odd:
.repeat 8,line
lda (SCREEN_PTR),y
ora #$0f
eor soft80_lo_charset+(line*$80),x
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
jmp draw_back
; output inverted character (generic)
draw_charinvers:
lda soft80_internal_cursorxlsb
bne draw_charinvers_odd
.repeat 8,line
lda (SCREEN_PTR),y
ora #$f0
eor soft80_hi_charset+(line*$80),x
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
jmp draw_back
;-------------------------------------------------------------------------------
; optional "color voodoo". the problem is that each 8x8 cell can only contain
; two colors, one of which is used for the background color, so two characters
; have to share the same text color.
;
; - in a cell that contains two spaces, both the color ram and the text color
; in vram contain the background color
;
; - in a cell that contains one character, its text color goes into vram. the
; color ram contains the background color.
;
; - in a cell that contains two characters, the color of the left character goes
; to vram (and is shared by both for display). the "would be" color of the
; right character goes to color ram as a reminder and can be restored when one
; of the two characters is cleared by a space.
.if SOFT80COLORVOODOO = 1
; remove color from cell, called before putting a "space" character to the bitmap
;
; __ -> __ -
; _A -> _A -
; B_ -> B_ -
; _A -> __ vram = bgcol
; B_ -> __ vram = bgcol
; BA -> _A vram = colram, colram = bgcol
; BA -> B_ colram = bgcol
;
; in: x must be $34
; y must be $00
; out: x = $34
; y = $00
remcolor:
;ldy #$00 ; is still $00
; if the textcolor in vram is equal to the background color, then
; no (visible) character is in the current cell and we can exit
; immediately.
lda (CRAM_PTR),y ; vram (textcolor)
and #$0f
cmp soft80_internal_bgcolor
beq @sk1 ; yes, vram==bgcolor
; now check if the textcolor in color ram is equal the background color,
; if yes then there is only one (visible) character in the current cell
inc $01 ; $35
lda (CRAM_PTR),y ; colram (2nd textcolor)
stx $01 ; $34
and #$0f
cmp soft80_internal_bgcolor
beq @sk2 ; yes, colram==bgcolor
sta tmp3 ; A contains colram
; two characters in the current cell, of which one will get removed
lda soft80_internal_cursorxlsb
bne @sk3
; vram = colram
lda (CRAM_PTR),y ; vram
and #$f0
ora tmp3 ; colram value
sta (CRAM_PTR),y ; vram
@sk3:
; colram = bgcolor
lda soft80_internal_bgcolor
inc $01 ; $35
sta (CRAM_PTR),y ; colram
stx $01 ; $34
rts
@sk2:
; colram is bgcolor
; => only one char in cell used
jsr soft80_checkchar
bcs @sk1 ; space at current position
; vram (textcolor) = bgcolor
lda (CRAM_PTR),y ; vram
and #$f0
ora soft80_internal_bgcolor
sta (CRAM_PTR),y ; vram
@sk1:
rts
; put color to cell
;
; __ -> _A vram = textcol
; __ -> B_ vram = textcol
; _A -> BA colram = vram, vram = textcol
; B_ -> BA colram = textcol
;
; _A -> _C vram = textcol
; B_ -> C_ vram = textcol
; BA -> BC colram = textcol
; BA -> CA vram = textcol
;
; in: $01 is $34 (RAM under I/O) when entering
; x must be $34
; y must be $00
; out: x = $34
; y = $00
soft80_putcolor:
;ldy #$00 ; is still $00
lda (CRAM_PTR),y ; vram
and #$0f
cmp soft80_internal_bgcolor
beq @sk1 ; vram==bgcolor => first char in cell
; vram!=bgcolor => second char in cell
inc $01 ; $35
lda (CRAM_PTR),y ; colram
stx $01 ; $34
and #$0f
cmp soft80_internal_bgcolor
beq @l2s ; colram==bgcolor -> second char in cell
; botch characters in the cell are used
lda soft80_internal_cursorxlsb
bne @sk2 ; jump if odd xpos
; vram = textcol
lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
rts
@l2s:
; one character in cell is already used
jsr soft80_checkchar
bcc @sk1 ; char at current position => overwrite 1st
lda soft80_internal_cursorxlsb
beq @sk3 ; jump if even xpos
@sk2:
; colram = textcol
lda CHARCOLOR
inc $01 ; $35
sta (CRAM_PTR),y ; colram
stx $01 ; $34
rts
@sk3:
; colram=vram
lda (CRAM_PTR),y ; vram
inc $01 ; $35
sta (CRAM_PTR),y ; colram
stx $01 ; $34
@sk1:
; vram = textcol
lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
rts
;
; test if there is a space or a character at current position
;
; in: x = $34
; $01 must be $34
;
; out: SEC: space
; CLC: character
; x = $34
; y = $00
soft80_checkchar:
lda soft80_internal_cursorxlsb
bne @l1a
; check charset data from bottom up, since a lot of eg lowercase chars
; have no data in the top rows, but all of them DO have data in the
; second to bottom row, this will likely be faster in average.
ldy #7
.repeat 8,line
lda (SCREEN_PTR),y
and #$f0
cmp #$f0
bne @ischar
.if (line < 7)
dey
.endif
.endrepeat
;ldy #$00 ; is 0
;sec ; is set
rts
@ischar:
ldy #$00
;clc ; is cleared
rts
@l1a:
ldy #$07
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
cmp #$0f
bne @ischar
.if line < 7
dey
.endif
.endrepeat
;ldy #$00 ; is 0
;sec ; is set
rts
.endif

View File

@ -0,0 +1,76 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; lowlevel kclrscr for soft80 implementation
;
.export soft80_kclrscr
.import soft80_kplot
.import soft80_internal_bgcolor, soft80_internal_cellcolor
.importzp ptr1
.include "c64.inc"
.include "soft80.inc"
soft80_kclrscr:
lda #<soft80_bitmap
sta ptr1
lda #>soft80_bitmap
sta ptr1+1
lda #$ff
ldx #$1f
@lp2:
ldy #0
@lp1:
sta (ptr1),y
iny
bne @lp1
inc ptr1+1
dex
bne @lp2
;ldx #$00
@lp3:
sta soft80_bitmap+$1e40,x
inx
bne @lp3
.if SOFT80COLORVOODOO = 1
lda soft80_internal_bgcolor
jsr clear ; clear color ram
.endif
sei
ldy $01
lda #$34 ; enable RAM under I/O
sta $01
lda soft80_internal_cellcolor
and #$f0
ora soft80_internal_bgcolor
jsr clear ; clear vram
sty $01
cli
ldx #0
ldy #0
clc
jmp soft80_kplot
; clear loop for colram and vram
clear:
;ldx #$00
@lp1:
sta soft80_colram,x
sta soft80_colram+$100,x
sta soft80_colram+$200,x
sta soft80_colram+$2e8,x
inx
bne @lp1
rts

63
libsrc/c64/soft80_kplot.s Normal file
View File

@ -0,0 +1,63 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; lowlevel kplot function for the soft80 implementation
;
.export soft80_kplot
.import soft80_internal_cursorxlsb
.include "c64.inc"
.include "soft80.inc"
soft80_kplot:
bcs @getpos
stx CURS_Y
sty CURS_X
sei
lda $01
pha
lda #$34 ; enable RAM under I/O
sta $01
; calc pointer to bitmap
lda soft80_bitmapylo,x
clc
adc soft80_bitmapxlo,y
sta SCREEN_PTR
lda soft80_bitmapyhi,x
adc soft80_bitmapxhi,y
sta SCREEN_PTR+1
tya
and #1
sta soft80_internal_cursorxlsb
; calc pointer to vram
tya
lsr a
clc
adc soft80_vramlo,x
sta CRAM_PTR
lda #0
adc soft80_vramhi,x
sta CRAM_PTR+1
pla
sta $01
cli
@getpos:
ldx CURS_Y
ldy CURS_X
rts
;-------------------------------------------------------------------------------
; force the init constructor to be imported
.import soft80_init
conio_init = soft80_init

View File

@ -0,0 +1,14 @@
;
; Groepaz/Hitmen, 12.10.2015
;
; lowlevel screensize function for the soft80 implementation
;
.export soft80_screensize
.include "soft80.inc"
soft80_screensize:
ldy #screenrows
ldx #charsperline
rts

View File

@ -0,0 +1,66 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; high level implementation for the monochrome soft80 implementation
;
; char cgetc (void);
;
.export soft80mono_cgetc
.import soft80mono_internal_cellcolor, soft80mono_internal_cursorxlsb
.import soft80mono_internal_nibble
.import cursor
.importzp tmp1
.include "c64.inc"
.include "soft80.inc"
soft80mono_cgetc:
lda KEY_COUNT ; Get number of characters
bne @L3 ; Jump if there are already chars waiting
jsr invertcursor ; set cursor on or off accordingly
@L1: lda KEY_COUNT ; wait for key
beq @L1
jsr invertcursor ; set cursor on or off accordingly
@L3: jsr KBDREAD ; Read char and return in A
ldx #0
rts
; Switch the cursor on or off (invert)
invertcursor:
lda cursor
bne @invert
rts
@invert:
sei
lda $01 ; enable RAM under I/O
pha
lda #$34
sta $01
ldy #$00
ldx soft80mono_internal_cursorxlsb
@lp1:
lda (SCREEN_PTR),y
eor soft80mono_internal_nibble,x
sta (SCREEN_PTR),y
iny
cpy #8
bne @lp1
pla
sta $01 ; enable I/O
cli
rts
;-------------------------------------------------------------------------------
; force the init constructor to be imported
.import soft80mono_init
conio_init = soft80mono_init

View File

@ -0,0 +1,65 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; high level implementation for the monochrome soft80 implementation
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
;
.export soft80mono_textcolor, soft80mono_bgcolor
.import soft80mono_internal_cellcolor, soft80mono_internal_bgcolor
.importzp tmp1
.include "c64.inc"
.include "soft80.inc"
soft80mono_textcolor:
ldx CHARCOLOR ; get old value
stx tmp1 ; save old value
sta CHARCOLOR ; set new value
mkcharcolor:
lda soft80mono_internal_bgcolor
asl a
asl a
asl a
asl a
ora CHARCOLOR
sta soft80mono_internal_cellcolor ; text/bg combo for new chars
sei
ldy $01
lda #$34 ; enable RAM under I/O
sta $01
lda soft80mono_internal_cellcolor
; clear loop for vram
ldx #$00
@lp1:
sta soft80_vram,x
sta soft80_vram+$100,x
sta soft80_vram+$200,x
sta soft80_vram+$2e8,x
inx
bne @lp1
sty $01
cli
lda tmp1 ; get old value
rts
soft80mono_bgcolor:
ldx soft80mono_internal_bgcolor ; get old value
stx tmp1 ; save old value
sta soft80mono_internal_bgcolor ; set new value
jmp mkcharcolor
;-------------------------------------------------------------------------------
; force the init constructor to be imported
.import soft80mono_init
conio_init = soft80mono_init

View File

@ -0,0 +1,168 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; Low level init code for the monochrome soft80 screen output/console input
;
.constructor soft80mono_init, 8
.destructor soft80mono_shutdown
.import soft80mono_kclrscr, soft80_charset
.export soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
.export soft80mono_internal_cursorxlsb
.export soft80mono_internal_nibble
.importzp ptr1, ptr2, ptr3
.include "c64.inc"
.include "soft80.inc"
soft80mono_init:
lda soft80mono_first_init
bne @skp
jsr firstinit
@skp:
; the "color voodoo" in other parts of the code relies on the vram and
; colorram being set up as expected, which is why we cant use the
; _bgcolor and _textcolor functions here.
lda CHARCOLOR ; use current textcolor
and #$0f ; make sure the upper nibble is 0s
sta CHARCOLOR
lda VIC_BG_COLOR0 ; use current bgcolor
and #$0f
sta soft80mono_internal_bgcolor
asl a
asl a
asl a
asl a
ora CHARCOLOR
sta soft80mono_internal_cellcolor
lda #$3b
sta VIC_CTRL1
lda #$00
sta CIA2_PRA
lda #$68
sta VIC_VIDEO_ADR
lda #$c8
sta VIC_CTRL2
jmp soft80mono_kclrscr
soft80mono_shutdown:
lda #$1b
sta VIC_CTRL1
lda #$03
sta CIA2_PRA
lda #$15
sta VIC_VIDEO_ADR
rts
.segment "INIT"
firstinit:
; copy charset to RAM under I/O
sei
lda $01
pha
lda #$34
sta $01
inc soft80mono_first_init
lda #>soft80_charset
sta ptr1+1
lda #<soft80_charset
sta ptr1
lda #>soft80_lo_charset
sta ptr2+1
lda #<soft80_lo_charset
sta ptr2
lda #>soft80_hi_charset
sta ptr3+1
lda #<soft80_hi_charset
sta ptr3
ldx #4
@l2:
ldy #0
@l1:
lda (ptr1),y
sta (ptr2),y
asl a
asl a
asl a
asl a
sta (ptr3),y
iny
bne @l1
inc ptr1+1
inc ptr2+1
inc ptr3+1
dex
bne @l2
; copy the kplot tables to ram under I/O
;ldx #0 ; is 0
@l3:
lda soft80_tables_data_start,x
sta soft80_bitmapxlo,x
lda soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $100) ,x
sta soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $100),x
inx
bne @l3
pla
sta $01
cli
rts
; the following tables take up 267 bytes, used by kplot
soft80_tables_data_start:
soft80_bitmapxlo_data:
.repeat 80,col
.byte <((col/2)*8)
.endrepeat
soft80_bitmapxhi_data:
.repeat 80,col
.byte >((col/2)*8)
.endrepeat
soft80_vramlo_data:
.repeat 25,row
.byte <(soft80_vram+(row*40))
.endrepeat
.byte 0,0,0,0,0,0,0 ; padding to next page
soft80_vramhi_data:
.repeat 25,row
.byte >(soft80_vram+(row*40))
.endrepeat
soft80_bitmapylo_data:
.repeat 25,row
.byte <(soft80_bitmap+(row*40*8))
.endrepeat
soft80_bitmapyhi_data:
.repeat 25,row
.byte >(soft80_bitmap+(row*40*8))
.endrepeat
soft80_tables_data_end:
;-------------------------------------------------------------------------------
.segment "INITBSS"
soft80mono_internal_cellcolor:
.res 1
soft80mono_internal_bgcolor:
.res 1
soft80mono_internal_cursorxlsb:
.res 1
.data
soft80mono_first_init:
.byte 0 ; flag to check first init, this really must be in .data
.rodata
soft80mono_internal_nibble:
.byte $f0, $0f

View File

@ -0,0 +1,205 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; high level implementation for the monochrome soft80 implementation
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export soft80mono_cputcxy, soft80mono_cputc
.export soft80mono_cputdirect, soft80mono_putchar
.export soft80mono_newline, soft80mono_plot
.import popa, _gotoxy
.import soft80mono_kplot
.import soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
.import soft80mono_internal_cursorxlsb, soft80mono_internal_nibble
.importzp tmp4, tmp3, ptr2
.include "c64.inc"
.include "soft80.inc"
soft80mono_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
pla ; Restore C
; Plot a character - also used as internal function
soft80mono_cputc:
cmp #$0A ; CR?
bne L1
lda #0
sta CURS_X
; Set cursor position, calculate RAM pointers
soft80mono_plot:
ldx CURS_Y
ldy CURS_X
clc
jmp soft80mono_kplot ; Set the new cursor
L1: cmp #$0D ; LF?
beq soft80mono_newline ; Recalculate pointers
; shortcut for codes < $80 ... codes $20-$7f can be printed directly,
; codes $00-$1f are control codes which are not printable and thus may
; give undefined result.
tay
bpl @L10
; codes $80-$ff must get converted like this:
; $80-$9f -> dont care (control codes)
; $a0-$bf -> $00-$1f
; $c0-$df -> $60-$7f
; $e0-$ff -> $00-$1f
ora #%01000000 ; $40
clc
adc #%00100000 ; $20
and #%01111111 ; $7f
@L10:
; entry point for direct output of a character. the value passed in
; akku must match the offset in the charset.
; - the following may not modify tmp1
soft80mono_cputdirect:
jsr soft80mono_putchar ; Write the character to the screen
; Advance cursor position
iny ; contains CURS_X
cpy #charsperline
beq @L3
sty CURS_X
tya
and #$01
sta soft80mono_internal_cursorxlsb
bne @L4
lda SCREEN_PTR
clc
adc #8
sta SCREEN_PTR
bcc @L4
inc SCREEN_PTR+1
@L4:
rts
@L3:
inc CURS_Y ; new line
ldy #0 ; + cr
sty CURS_X
jmp soft80mono_plot
; - the following may not modify tmp1
soft80mono_newline:
lda SCREEN_PTR
clc
adc #<(40*8)
sta SCREEN_PTR
lda SCREEN_PTR+1
adc #>(40*8)
sta SCREEN_PTR+1
inc CURS_Y
rts
;-------------------------------------------------------------------------------
; output one character in internal encoding without advancing cursor position
; generic entry point
;
; - the following may not modify tmp1
; in: A: charcode
; out: Y: CURS_X
;
soft80mono_putchar:
sta tmp3 ; save charcode
sei
lda $01
pha
lda #$34
sta $01 ; enable RAM under I/O
ldy #$00 ; will be $00 from now on
ldx soft80mono_internal_cursorxlsb
lda chardatal,x
clc
adc tmp3
sta ptr2
lda chardatah,x
adc #0
sta ptr2+1
lda RVS
bne draw_charinvers
lda nibble,x
sta tmp3
;ldy #0 ; is still $00
@lp1:
lda (SCREEN_PTR),y
and tmp3
ora (ptr2),y
sta (SCREEN_PTR),y
clc
lda ptr2
adc #$7f
sta ptr2
bcc @sk1
inc ptr2+1
@sk1:
iny
cpy #8
bne @lp1
draw_back:
pla
sta $01
cli
ldy CURS_X
rts
; output inverted character
draw_charinvers:
lda soft80mono_internal_nibble,x
sta tmp3
;ldy #0 ; is still $00
@lp1:
lda (SCREEN_PTR),y
ora tmp3
eor (ptr2),y
sta (SCREEN_PTR),y
clc
lda ptr2
adc #$7f
sta ptr2
bcc @sk1
inc ptr2+1
@sk1:
iny
cpy #8
bne @lp1
jmp draw_back
.rodata
chardatal:
.byte <soft80_hi_charset
.byte <soft80_lo_charset
chardatah:
.byte >soft80_hi_charset
.byte >soft80_lo_charset
nibble:
.byte $0f, $f0

View File

@ -0,0 +1,63 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; lowlevel kclrscr for the monochrome soft80 implementation
;
.export soft80mono_kclrscr
.import soft80mono_kplot
.import soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
.importzp ptr1
.include "c64.inc"
.include "soft80.inc"
soft80mono_kclrscr:
lda #<soft80_bitmap
sta ptr1
lda #>soft80_bitmap
sta ptr1+1
lda #$ff
ldx #$1f
@lp2:
ldy #0
@lp1:
sta (ptr1),y
iny
bne @lp1
inc ptr1+1
dex
bne @lp2
;ldx #$00
@lp3:
sta soft80_bitmap+$1e40,x
inx
bne @lp3
sei
ldy $01
lda #$34 ; enable RAM under I/O
sta $01
lda soft80mono_internal_cellcolor
; clear loop for vram
;ldx #$00
@lp4:
sta soft80_vram,x
sta soft80_vram+$100,x
sta soft80_vram+$200,x
sta soft80_vram+$2e8,x
inx
bne @lp4
sty $01
cli
ldx #0
ldy #0
clc
jmp soft80mono_kplot

View File

@ -0,0 +1,52 @@
;
; Groepaz/Hitmen, 19.10.2015
;
; lowlevel kplot function for the monochrome soft80 implementation
;
.export soft80mono_kplot
.import soft80mono_internal_cursorxlsb
.include "c64.inc"
.include "soft80.inc"
soft80mono_kplot:
bcs @getpos
stx CURS_Y
sty CURS_X
sei
lda $01
pha
lda #$34 ; enable RAM under I/O
sta $01
; calc pointer to bitmap
lda soft80_bitmapylo,x
clc
adc soft80_bitmapxlo,y
sta SCREEN_PTR
lda soft80_bitmapyhi,x
adc soft80_bitmapxhi,y
sta SCREEN_PTR+1
tya
and #1
sta soft80mono_internal_cursorxlsb
pla
sta $01
cli
@getpos:
ldx CURS_Y
ldy CURS_X
rts
;-------------------------------------------------------------------------------
; force the init constructor to be imported
.import soft80mono_init
conio_init = soft80mono_init

128
testcode/lib/conio.c Normal file
View File

@ -0,0 +1,128 @@
/*
* conio api test program
*
* keys:
*
* 1...0 change text color
* F5/F6 change border color
* F7/F8 change background color
*
*/
#include <conio.h>
#include <string.h>
#include <stdlib.h>
static char grid[5][5] = {
{ CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER },
{ CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
{ CH_LTEE, CH_HLINE, CH_CROSS, CH_HLINE, CH_RTEE },
{ CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
{ CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER },
};
void main(void)
{
int i, j, n;
unsigned char xsize, ysize, tcol, bgcol, bcol, inpos = 0;
clrscr();
screensize(&xsize, &ysize);
cputs("cc65 conio test\n\rInput: [ ]");
cputsxy(0, 2, "Colors:" );
tcol = textcolor(0); /* remember original textcolor */
bgcol = bgcolor(0); /* remember original background color */
bcol = bordercolor(0); /* remember original border color */
bgcolor(bgcol);bordercolor(bcol);
for (i = 0; i < 3; ++i) {
gotoxy(i,3 + i);
for (j = 0; j < 16; ++j) {
textcolor(j);
cputc('X');
}
}
textcolor(tcol);
cprintf("\n\n\r Screensize is: %dx%d", xsize, ysize );
chlinexy(0,6,xsize);
cvlinexy(0,6,3);
chlinexy(0,8,xsize);
cvlinexy(xsize-1,6,3);
cputcxy(0,6,CH_ULCORNER);
cputcxy(xsize-1,6,CH_URCORNER);
cputcxy(0,8,CH_LLCORNER);
cputcxy(xsize-1,8,CH_LRCORNER);
for (i = 0; i < 5; ++i) {
gotoxy(xsize - 5,i);
for (j = 0; j < 5; ++j) {
cputc(grid[i][j]);
}
}
gotoxy(0,ysize - 2 - ((256 + xsize) / xsize));
revers(1);
for (i = 0; i < xsize; ++i) {
cputc('0' + i % 10);
}
revers(0);
for (i = 0; i < 256; ++i) {
if ((i != '\n') && (i != '\r')) {
cputc(i);
} else {
cputc(' ');
}
}
while(wherex() > 0) {
cputc('#');
}
revers(1);
for (i = 0; i < xsize; ++i) {
cputc('0' + i % 10);
}
revers(0);
cursor(1);
for(;;) {
gotoxy(8, 2);
j = n & 1;
revers(j);
cputc(j ? 'R' : ' ');
revers(j ^ 1);
cputs(" revers");
revers(0);
gotoxy(8 + inpos,1);
i = cgetc();
if ((i >= '0') && (i<='9')) {
textcolor(i - '0');
} else if (i == CH_CURS_LEFT) {
inpos = (inpos - 1) & 7;
} else if (i == CH_CURS_RIGHT) {
inpos = (inpos + 1) & 7;
} else if (i == CH_F5) {
bgcol = (bgcol + 1) & 0x0f;
bordercolor(bgcol);
} else if (i == CH_F6) {
bgcol = (bgcol - 1) & 0x0f;
bordercolor(bgcol);
} else if (i == CH_F7) {
bgcol = (bgcol + 1) & 0x0f;
bgcolor(bgcol);
} else if (i == CH_F8) {
bgcol = (bgcol - 1) & 0x0f;
bgcolor(bgcol);
} else {
cputc(i);
inpos = (inpos + 1) & 7;
}
++n;
}
for(;;);
}