Please note that in this case a changed start address doesn't make sense,
since the program must be loaded to the BASIC start address.
+<sect>Extras<p>
+
+<sect1>80 Columns conio driver<p>
+
+The C64 package comes with an alternative software driven 80 columns
+module <tt/c64-soft80.o/ which uses the memory under I/O between $d000
+and $ffff.
+
+In memory constrained situations the memory from $400 to $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>
palette of the 16 C64 colors).
</descrip><p>
+Note that the graphics drivers are incompatible with the
+<tt/c64-ram.emd (c64_ram_emd)/ extended memory driver and the
+ <tt/c64-soft80.o/ software 80 columns conio driver.
<sect1>Extended memory drivers<p>
<tag><tt/c64-ram.emd (c64_ram_emd)/</tag>
A driver for the hidden RAM below the I/O area and kernal ROM. Supports 48
256 byte pages. Please note that this driver is incompatible with any of the
- graphics drivers!
+ graphics drivers, or the soft80 conio driver!
<tag><tt/c64-ramcart.emd (c64_ramcart_emd)/</tag>
A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak.
--- /dev/null
+;
+; 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
+
;
; 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"
sta VIC_BG_COLOR0 ; set new value
txa
rts
-
-
-_bordercolor:
- ldx VIC_BORDERCOLOR ; get old value
- sta VIC_BORDERCOLOR ; set new value
- txa
- rts
-
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
+
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
+
+
--- /dev/null
+
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
+
--- /dev/null
+;
+; 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
+
--- /dev/null
+;
+; 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
--- /dev/null
+
+;
+; 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
jsr zerobss
; Copy the .data segment to RAM
- lda #<(__DATA_LOAD__)
- sta ptr1
- lda #>(__DATA_LOAD__)
- sta ptr1+1
- lda #<(__DATA_RUN__)
- sta ptr2
- lda #>(__DATA_RUN__)
- sta ptr2+1
-
- ldx #>(__DATA_SIZE__)
-@l2:
- beq @s1 ; no more full pages
-
- ; copy one page
- ldy #0
-@l1:
- lda (ptr1),y
- sta (ptr2),y
- iny
- bne @l1
-
- inc ptr1+1
- inc ptr2+1
-
- dex
- bne @l2
-
- ; copy remaining bytes
-@s1:
- ; copy one page
- ldy #0
-@l3:
- lda (ptr1),y
- sta (ptr2),y
- iny
- cpy #<(__DATA_SIZE__)
- bne @l3
+ tii __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
; setup the stack
lda #<(__RAM_START__+__RAM_SIZE__)
--- /dev/null
+/*
+ * 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(;;);
+}