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
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, 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. 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> <sect>Platform-specific header files<p>
@@ -216,6 +249,9 @@ configuration.
palette of the 16 C64 colors). palette of the 16 C64 colors).
</descrip><p> </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> <sect1>Extended memory drivers<p>
@@ -241,7 +277,7 @@ configuration.
<tag><tt/c64-ram.emd (c64_ram_emd)/</tag> <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 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 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> <tag><tt/c64-ramcart.emd (c64_ramcart_emd)/</tag>
A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak. 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__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (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" .include "c64.inc"
@@ -23,11 +22,3 @@ _bgcolor:
sta VIC_BG_COLOR0 ; set new value sta VIC_BG_COLOR0 ; set new value
txa txa
rts 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(;;);
}