diff --git a/doc/c64.sgml b/doc/c64.sgml index ca99e0061..a3e9e1291 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -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. +Extras

+ +80 Columns conio driver

+ +The C64 package comes with an alternative software driven 80 columns +module +cl65 -t c64 myprog.c c64-soft80.o + + +Note that the soft80 conio driver is incompatible with the +80 Columns conio driver (monochrome)

+ +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. + + +cl65 -t c64 myprog.c c64-soft80mono.o + Platform-specific header files

@@ -216,6 +249,9 @@ configuration. palette of the 16 C64 colors).

+Note that the graphics drivers are incompatible with the +Extended memory drivers

@@ -241,7 +277,7 @@ configuration. 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! A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak. diff --git a/libsrc/c64/bordercolor.s b/libsrc/c64/bordercolor.s new file mode 100644 index 000000000..73dfc0a99 --- /dev/null +++ b/libsrc/c64/bordercolor.s @@ -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 + diff --git a/libsrc/c64/color.s b/libsrc/c64/color.s index bfc371931..86d6aefe8 100644 --- a/libsrc/c64/color.s +++ b/libsrc/c64/color.s @@ -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 - diff --git a/libsrc/c64/extra/soft80.s b/libsrc/c64/extra/soft80.s new file mode 100644 index 000000000..4ee030c81 --- /dev/null +++ b/libsrc/c64/extra/soft80.s @@ -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 diff --git a/libsrc/c64/extra/soft80mono.s b/libsrc/c64/extra/soft80mono.s new file mode 100644 index 000000000..f91f4a76a --- /dev/null +++ b/libsrc/c64/extra/soft80mono.s @@ -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 diff --git a/libsrc/c64/soft80.inc b/libsrc/c64/soft80.inc new file mode 100644 index 000000000..ca5c713ce --- /dev/null +++ b/libsrc/c64/soft80.inc @@ -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 + diff --git a/libsrc/c64/soft80_cgetc.s b/libsrc/c64/soft80_cgetc.s new file mode 100644 index 000000000..ae0e23857 --- /dev/null +++ b/libsrc/c64/soft80_cgetc.s @@ -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 diff --git a/libsrc/c64/soft80_charset.s b/libsrc/c64/soft80_charset.s new file mode 100644 index 000000000..69fd3527f --- /dev/null +++ b/libsrc/c64/soft80_charset.s @@ -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 diff --git a/libsrc/c64/soft80_color.s b/libsrc/c64/soft80_color.s new file mode 100644 index 000000000..8c1d113ac --- /dev/null +++ b/libsrc/c64/soft80_color.s @@ -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 diff --git a/libsrc/c64/soft80_conio.s b/libsrc/c64/soft80_conio.s new file mode 100644 index 000000000..4e24a0341 --- /dev/null +++ b/libsrc/c64/soft80_conio.s @@ -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_lo_charset + sta ptr2+1 + lda #soft80_hi_charset + sta ptr3+1 + lda #((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 diff --git a/libsrc/c64/soft80_cputc.s b/libsrc/c64/soft80_cputc.s new file mode 100644 index 000000000..acbe5b560 --- /dev/null +++ b/libsrc/c64/soft80_cputc.s @@ -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 diff --git a/libsrc/c64/soft80_kclrscr.s b/libsrc/c64/soft80_kclrscr.s new file mode 100644 index 000000000..7c313afcf --- /dev/null +++ b/libsrc/c64/soft80_kclrscr.s @@ -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+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 + + diff --git a/libsrc/c64/soft80_kplot.s b/libsrc/c64/soft80_kplot.s new file mode 100644 index 000000000..bd52ee6d3 --- /dev/null +++ b/libsrc/c64/soft80_kplot.s @@ -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 diff --git a/libsrc/c64/soft80_scrsize.s b/libsrc/c64/soft80_scrsize.s new file mode 100644 index 000000000..9f1701a9a --- /dev/null +++ b/libsrc/c64/soft80_scrsize.s @@ -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 diff --git a/libsrc/c64/soft80mono_cgetc.s b/libsrc/c64/soft80mono_cgetc.s new file mode 100644 index 000000000..d99dc7775 --- /dev/null +++ b/libsrc/c64/soft80mono_cgetc.s @@ -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 diff --git a/libsrc/c64/soft80mono_color.s b/libsrc/c64/soft80mono_color.s new file mode 100644 index 000000000..aa24957d5 --- /dev/null +++ b/libsrc/c64/soft80mono_color.s @@ -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 diff --git a/libsrc/c64/soft80mono_conio.s b/libsrc/c64/soft80mono_conio.s new file mode 100644 index 000000000..759b280c6 --- /dev/null +++ b/libsrc/c64/soft80mono_conio.s @@ -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_lo_charset + sta ptr2+1 + lda #soft80_hi_charset + sta ptr3+1 + lda #((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 + diff --git a/libsrc/c64/soft80mono_cputc.s b/libsrc/c64/soft80mono_cputc.s new file mode 100644 index 000000000..c89362cb5 --- /dev/null +++ b/libsrc/c64/soft80mono_cputc.s @@ -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 +nibble: + .byte $0f, $f0 + diff --git a/libsrc/c64/soft80mono_kclrscr.s b/libsrc/c64/soft80mono_kclrscr.s new file mode 100644 index 000000000..99243c699 --- /dev/null +++ b/libsrc/c64/soft80mono_kclrscr.s @@ -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+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 diff --git a/libsrc/c64/soft80mono_kplot.s b/libsrc/c64/soft80mono_kplot.s new file mode 100644 index 000000000..b987924f3 --- /dev/null +++ b/libsrc/c64/soft80mono_kplot.s @@ -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 diff --git a/testcode/lib/conio.c b/testcode/lib/conio.c new file mode 100644 index 000000000..3a8048632 --- /dev/null +++ b/testcode/lib/conio.c @@ -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 +#include +#include + +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(;;); +}