]> git.sur5r.net Git - cc65/commitdiff
Merge pull request #213 from mrdudz/soft80
authorOliver Schmidt <ol.sc@web.de>
Thu, 22 Oct 2015 15:56:21 +0000 (17:56 +0200)
committerOliver Schmidt <ol.sc@web.de>
Thu, 22 Oct 2015 15:56:21 +0000 (17:56 +0200)
soft80 implementation for C-64

21 files changed:
doc/c64.sgml
libsrc/c64/bordercolor.s [new file with mode: 0644]
libsrc/c64/color.s
libsrc/c64/extra/soft80.s [new file with mode: 0644]
libsrc/c64/extra/soft80mono.s [new file with mode: 0644]
libsrc/c64/soft80.inc [new file with mode: 0644]
libsrc/c64/soft80_cgetc.s [new file with mode: 0644]
libsrc/c64/soft80_charset.s [new file with mode: 0644]
libsrc/c64/soft80_color.s [new file with mode: 0644]
libsrc/c64/soft80_conio.s [new file with mode: 0644]
libsrc/c64/soft80_cputc.s [new file with mode: 0644]
libsrc/c64/soft80_kclrscr.s [new file with mode: 0644]
libsrc/c64/soft80_kplot.s [new file with mode: 0644]
libsrc/c64/soft80_scrsize.s [new file with mode: 0644]
libsrc/c64/soft80mono_cgetc.s [new file with mode: 0644]
libsrc/c64/soft80mono_color.s [new file with mode: 0644]
libsrc/c64/soft80mono_conio.s [new file with mode: 0644]
libsrc/c64/soft80mono_cputc.s [new file with mode: 0644]
libsrc/c64/soft80mono_kclrscr.s [new file with mode: 0644]
libsrc/c64/soft80mono_kplot.s [new file with mode: 0644]
testcode/lib/conio.c [new file with mode: 0644]

index ca99e0061631083865afb1663ca92021923bc03e..a3e9e12910cb0e4270080e22e0aad0ecaa270e1d 100644 (file)
@@ -116,6 +116,39 @@ cl65 -o file.prg -u __EXEHDR__ -t c64 -C c64-asm.cfg source.s
 Please note that in this case a changed start address doesn't make sense,
 since the program must be loaded to the BASIC start address.
 
+<sect>Extras<p>
+
+<sect1>80 Columns conio driver<p>
+
+The C64 package comes with an alternative software driven 80 columns
+module <tt/c64-soft80.o/ which uses the memory under I/O between &dollar;d000
+and &dollar;ffff.
+
+In memory constrained situations the memory from &dollar;400 to &dollar;7FF
+can be made available to a program by calling <tt/_heapadd ((void *) 0x400, 0x400);/
+at the beginning of <tt/main()/. Doing so is beneficial even if the program
+doesn't use the the heap explicitly because loading a driver uses the heap implicitly.
+
+Using <tt/c64-soft80.o/ is as simple as placing it on the linker command
+line like this:
+
+<tscreen><verb>
+cl65 -t c64 myprog.c c64-soft80.o
+</verb></tscreen>
+
+Note that the soft80 conio driver is incompatible with the
+<tt/c64-ram.emd (c64_ram_emd)/ extended memory driver and the
+ <tt/c64-hi.tgi (c64_hi_tgi)/ graphics driver.
+
+<sect2>80 Columns conio driver (monochrome)<p>
+
+In an (even more) memory constrained situation, a size optimized version of the
+software driven 80 columns module may be used, which only supports one common
+text color for the whole screen.
+
+<tscreen><verb>
+cl65 -t c64 myprog.c c64-soft80mono.o
+</verb></tscreen>
 
 <sect>Platform-specific header files<p>
 
@@ -216,6 +249,9 @@ configuration.
   palette of the 16 C64 colors).
 </descrip><p>
 
+Note that the graphics drivers are incompatible with the
+<tt/c64-ram.emd (c64_ram_emd)/ extended memory driver and the
+ <tt/c64-soft80.o/ software 80 columns conio driver.
 
 <sect1>Extended memory drivers<p>
 
@@ -241,7 +277,7 @@ configuration.
   <tag><tt/c64-ram.emd (c64_ram_emd)/</tag>
   A driver for the hidden RAM below the I/O area and kernal ROM. Supports 48
   256 byte pages. Please note that this driver is incompatible with any of the
-  graphics drivers!
+  graphics drivers, or the soft80 conio driver!
 
   <tag><tt/c64-ramcart.emd (c64_ramcart_emd)/</tag>
   A driver for the RamCart 64/128 written and contributed by Maciej Witkowiak.
diff --git a/libsrc/c64/bordercolor.s b/libsrc/c64/bordercolor.s
new file mode 100644 (file)
index 0000000..73dfc0a
--- /dev/null
@@ -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
+
index bfc37193103cb711b4deb24a3b91ecec8539bda7..86d6aefe8758699d83d315f1d780780e600fc995 100644 (file)
@@ -3,11 +3,10 @@
 ;
 ; unsigned char __fastcall__ textcolor (unsigned char color);
 ; unsigned char __fastcall__ bgcolor (unsigned char color);
-; unsigned char __fastcall__ bordercolor (unsigned char color);
 ;
 
 
-        .export         _textcolor, _bgcolor, _bordercolor
+        .export         _textcolor, _bgcolor
 
         .include        "c64.inc"
 
@@ -23,11 +22,3 @@ _bgcolor:
         sta     VIC_BG_COLOR0   ; set new value
         txa
         rts
-
-
-_bordercolor:
-        ldx     VIC_BORDERCOLOR ; get old value
-        sta     VIC_BORDERCOLOR ; set new value
-        txa
-        rts
-
diff --git a/libsrc/c64/extra/soft80.s b/libsrc/c64/extra/soft80.s
new file mode 100644 (file)
index 0000000..4ee030c
--- /dev/null
@@ -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 (file)
index 0000000..f91f4a7
--- /dev/null
@@ -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 (file)
index 0000000..ca5c713
--- /dev/null
@@ -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 (file)
index 0000000..ae0e238
--- /dev/null
@@ -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 (file)
index 0000000..69fd352
--- /dev/null
@@ -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 (file)
index 0000000..8c1d113
--- /dev/null
@@ -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 (file)
index 0000000..4e24a03
--- /dev/null
@@ -0,0 +1,162 @@
+;
+; Groepaz/Hitmen, 11.10.2015
+;
+; Low level init code for soft80 screen output/console input
+;
+
+        .constructor    soft80_init, 8
+        .destructor     soft80_shutdown
+
+        .import         soft80_kclrscr, soft80_charset
+        .export         soft80_internal_bgcolor, soft80_internal_cellcolor
+        .export         soft80_internal_cursorxlsb
+
+        .importzp       ptr1, ptr2, ptr3
+
+        .include        "c64.inc"
+        .include        "soft80.inc"
+
+soft80_init:
+        lda     soft80_first_init
+        bne     @skp
+        jsr     firstinit
+@skp:
+        ; the "color voodoo" in other parts of the code relies on the vram and
+        ; colorram being set up as expected, which is why we cant use the
+        ; _bgcolor and _textcolor functions here.
+
+        lda     CHARCOLOR                       ; use current textcolor
+        and     #$0f                            ; make sure the upper nibble is 0s
+        sta     CHARCOLOR
+
+        lda     VIC_BG_COLOR0                   ; use current bgcolor
+        and     #$0f
+        sta     soft80_internal_bgcolor
+        asl     a
+        asl     a
+        asl     a
+        asl     a
+        ora     CHARCOLOR
+        sta     soft80_internal_cellcolor
+
+        lda     #$3b
+        sta     VIC_CTRL1
+        lda     #$00
+        sta     CIA2_PRA
+        lda     #$68
+        sta     VIC_VIDEO_ADR
+        lda     #$c8
+        sta     VIC_CTRL2
+
+        jmp     soft80_kclrscr
+
+soft80_shutdown:
+        lda     #$1b
+        sta     VIC_CTRL1
+        lda     #$03
+        sta     CIA2_PRA
+        lda     #$15
+        sta     VIC_VIDEO_ADR
+        rts
+
+        .segment "INIT"
+firstinit:
+        ; copy charset to RAM under I/O
+        sei
+        lda     $01
+        pha
+        lda     #$34
+        sta     $01
+
+        inc     soft80_first_init
+
+        lda     #>soft80_charset
+        sta     ptr1+1
+        lda     #<soft80_charset
+        sta     ptr1
+        lda     #>soft80_lo_charset
+        sta     ptr2+1
+        lda     #<soft80_lo_charset
+        sta     ptr2
+        lda     #>soft80_hi_charset
+        sta     ptr3+1
+        lda     #<soft80_hi_charset
+        sta     ptr3
+
+        ldx     #4
+@l2:
+        ldy     #0
+@l1:
+        lda     (ptr1),y
+        sta     (ptr2),y
+        asl     a
+        asl     a
+        asl     a
+        asl     a
+        sta     (ptr3),y
+        iny
+        bne     @l1
+        inc     ptr1+1
+        inc     ptr2+1
+        inc     ptr3+1
+        dex
+        bne     @l2
+
+        ; copy the kplot tables to ram under I/O
+        ;ldx     #0              ; is 0
+@l3:
+        lda     soft80_tables_data_start,x
+        sta     soft80_bitmapxlo,x
+        lda     soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $100) ,x
+        sta     soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $100),x
+        inx
+        bne     @l3
+
+        pla
+        sta     $01
+        cli
+        rts
+
+; the following tables take up 267 bytes, used by kplot
+soft80_tables_data_start:
+
+soft80_bitmapxlo_data:
+        .repeat 80,col
+        .byte <((col/2)*8)
+        .endrepeat
+soft80_bitmapxhi_data:
+        .repeat 80,col
+        .byte >((col/2)*8)
+        .endrepeat
+soft80_vramlo_data:
+        .repeat 25,row
+        .byte <(soft80_vram+(row*40))
+        .endrepeat
+        .byte 0,0,0,0,0,0,0     ; padding to next page
+soft80_vramhi_data:
+        .repeat 25,row
+        .byte >(soft80_vram+(row*40))
+        .endrepeat
+soft80_bitmapylo_data:
+        .repeat 25,row
+        .byte <(soft80_bitmap+(row*40*8))
+        .endrepeat
+soft80_bitmapyhi_data:
+        .repeat 25,row
+        .byte >(soft80_bitmap+(row*40*8))
+        .endrepeat
+
+soft80_tables_data_end:
+
+;-------------------------------------------------------------------------------
+        .segment "INITBSS"
+soft80_internal_cellcolor:
+        .res 1
+soft80_internal_bgcolor:
+        .res 1
+soft80_internal_cursorxlsb:
+        .res 1
+
+        .data
+soft80_first_init:
+        .byte 0         ; flag to check first init, this really must be in .data
diff --git a/libsrc/c64/soft80_cputc.s b/libsrc/c64/soft80_cputc.s
new file mode 100644 (file)
index 0000000..acbe5b5
--- /dev/null
@@ -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 (file)
index 0000000..7c313af
--- /dev/null
@@ -0,0 +1,76 @@
+;
+; Groepaz/Hitmen, 12.10.2015
+;
+; lowlevel kclrscr for soft80 implementation
+;
+
+        .export         soft80_kclrscr
+        .import         soft80_kplot
+        .import         soft80_internal_bgcolor, soft80_internal_cellcolor
+        .importzp       ptr1
+
+        .include        "c64.inc"
+        .include        "soft80.inc"
+
+soft80_kclrscr:
+
+        lda     #<soft80_bitmap
+        sta     ptr1
+        lda     #>soft80_bitmap
+        sta     ptr1+1
+
+        lda     #$ff
+
+        ldx     #$1f
+@lp2:
+        ldy     #0
+@lp1:
+        sta     (ptr1),y
+        iny
+        bne     @lp1
+        inc     ptr1+1
+        dex
+        bne     @lp2
+
+        ;ldx     #$00
+@lp3:
+        sta     soft80_bitmap+$1e40,x
+        inx
+        bne     @lp3
+
+.if SOFT80COLORVOODOO = 1
+        lda     soft80_internal_bgcolor
+        jsr     clear                           ; clear color ram
+.endif
+
+        sei
+        ldy     $01
+        lda     #$34                            ; enable RAM under I/O
+        sta     $01
+
+        lda     soft80_internal_cellcolor
+        and     #$f0
+        ora     soft80_internal_bgcolor
+        jsr     clear                           ; clear vram
+
+        sty     $01
+        cli
+
+        ldx     #0
+        ldy     #0
+        clc
+        jmp     soft80_kplot
+
+        ; clear loop for colram and vram
+clear:
+        ;ldx     #$00
+@lp1:
+        sta     soft80_colram,x
+        sta     soft80_colram+$100,x
+        sta     soft80_colram+$200,x
+        sta     soft80_colram+$2e8,x
+        inx
+        bne     @lp1
+        rts
+
+
diff --git a/libsrc/c64/soft80_kplot.s b/libsrc/c64/soft80_kplot.s
new file mode 100644 (file)
index 0000000..bd52ee6
--- /dev/null
@@ -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 (file)
index 0000000..9f1701a
--- /dev/null
@@ -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 (file)
index 0000000..d99dc77
--- /dev/null
@@ -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 (file)
index 0000000..aa24957
--- /dev/null
@@ -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 (file)
index 0000000..759b280
--- /dev/null
@@ -0,0 +1,168 @@
+;
+; Groepaz/Hitmen, 19.10.2015
+;
+; Low level init code for the monochrome soft80 screen output/console input
+;
+
+        .constructor    soft80mono_init, 8
+        .destructor     soft80mono_shutdown
+
+        .import         soft80mono_kclrscr, soft80_charset
+        .export         soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
+        .export         soft80mono_internal_cursorxlsb
+        .export         soft80mono_internal_nibble
+
+        .importzp       ptr1, ptr2, ptr3
+
+        .include        "c64.inc"
+        .include        "soft80.inc"
+
+soft80mono_init:
+        lda     soft80mono_first_init
+        bne     @skp
+        jsr     firstinit
+@skp:
+        ; the "color voodoo" in other parts of the code relies on the vram and
+        ; colorram being set up as expected, which is why we cant use the
+        ; _bgcolor and _textcolor functions here.
+
+        lda     CHARCOLOR                       ; use current textcolor
+        and     #$0f                            ; make sure the upper nibble is 0s
+        sta     CHARCOLOR
+
+        lda     VIC_BG_COLOR0                   ; use current bgcolor
+        and     #$0f
+        sta     soft80mono_internal_bgcolor
+        asl     a
+        asl     a
+        asl     a
+        asl     a
+        ora     CHARCOLOR
+        sta     soft80mono_internal_cellcolor
+
+        lda     #$3b
+        sta     VIC_CTRL1
+        lda     #$00
+        sta     CIA2_PRA
+        lda     #$68
+        sta     VIC_VIDEO_ADR
+        lda     #$c8
+        sta     VIC_CTRL2
+
+        jmp     soft80mono_kclrscr
+
+soft80mono_shutdown:
+        lda     #$1b
+        sta     VIC_CTRL1
+        lda     #$03
+        sta     CIA2_PRA
+        lda     #$15
+        sta     VIC_VIDEO_ADR
+        rts
+
+        .segment "INIT"
+firstinit:
+        ; copy charset to RAM under I/O
+        sei
+        lda     $01
+        pha
+        lda     #$34
+        sta     $01
+
+        inc     soft80mono_first_init
+
+        lda     #>soft80_charset
+        sta     ptr1+1
+        lda     #<soft80_charset
+        sta     ptr1
+        lda     #>soft80_lo_charset
+        sta     ptr2+1
+        lda     #<soft80_lo_charset
+        sta     ptr2
+        lda     #>soft80_hi_charset
+        sta     ptr3+1
+        lda     #<soft80_hi_charset
+        sta     ptr3
+
+        ldx     #4
+@l2:
+        ldy     #0
+@l1:
+        lda     (ptr1),y
+        sta     (ptr2),y
+        asl     a
+        asl     a
+        asl     a
+        asl     a
+        sta     (ptr3),y
+        iny
+        bne     @l1
+        inc     ptr1+1
+        inc     ptr2+1
+        inc     ptr3+1
+        dex
+        bne     @l2
+
+        ; copy the kplot tables to ram under I/O
+        ;ldx     #0              ; is 0
+@l3:
+        lda     soft80_tables_data_start,x
+        sta     soft80_bitmapxlo,x
+        lda     soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $100) ,x
+        sta     soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $100),x
+        inx
+        bne     @l3
+
+        pla
+        sta     $01
+        cli
+        rts
+
+; the following tables take up 267 bytes, used by kplot
+soft80_tables_data_start:
+
+soft80_bitmapxlo_data:
+        .repeat 80,col
+        .byte <((col/2)*8)
+        .endrepeat
+soft80_bitmapxhi_data:
+        .repeat 80,col
+        .byte >((col/2)*8)
+        .endrepeat
+soft80_vramlo_data:
+        .repeat 25,row
+        .byte <(soft80_vram+(row*40))
+        .endrepeat
+        .byte 0,0,0,0,0,0,0     ; padding to next page
+soft80_vramhi_data:
+        .repeat 25,row
+        .byte >(soft80_vram+(row*40))
+        .endrepeat
+soft80_bitmapylo_data:
+        .repeat 25,row
+        .byte <(soft80_bitmap+(row*40*8))
+        .endrepeat
+soft80_bitmapyhi_data:
+        .repeat 25,row
+        .byte >(soft80_bitmap+(row*40*8))
+        .endrepeat
+
+soft80_tables_data_end:
+
+;-------------------------------------------------------------------------------
+        .segment "INITBSS"
+soft80mono_internal_cellcolor:
+        .res 1
+soft80mono_internal_bgcolor:
+        .res 1
+soft80mono_internal_cursorxlsb:
+        .res 1
+
+        .data
+soft80mono_first_init:
+        .byte 0         ; flag to check first init, this really must be in .data
+
+        .rodata
+soft80mono_internal_nibble:
+        .byte $f0, $0f
+
diff --git a/libsrc/c64/soft80mono_cputc.s b/libsrc/c64/soft80mono_cputc.s
new file mode 100644 (file)
index 0000000..c89362c
--- /dev/null
@@ -0,0 +1,205 @@
+;
+; Groepaz/Hitmen, 19.10.2015
+;
+; high level implementation for the monochrome soft80 implementation
+;
+; void cputcxy (unsigned char x, unsigned char y, char c);
+; void cputc (char c);
+;
+
+        .export         soft80mono_cputcxy, soft80mono_cputc
+        .export         soft80mono_cputdirect, soft80mono_putchar
+        .export         soft80mono_newline, soft80mono_plot
+
+        .import         popa, _gotoxy
+
+        .import         soft80mono_kplot
+        .import         soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
+        .import         soft80mono_internal_cursorxlsb, soft80mono_internal_nibble
+
+        .importzp       tmp4, tmp3, ptr2
+
+        .include        "c64.inc"
+        .include        "soft80.inc"
+
+soft80mono_cputcxy:
+        pha                     ; Save C
+        jsr     popa            ; Get Y
+        jsr     _gotoxy         ; Set cursor, drop x
+        pla                     ; Restore C
+
+; Plot a character - also used as internal function
+
+soft80mono_cputc:
+        cmp     #$0A            ; CR?
+        bne     L1
+
+        lda     #0
+        sta     CURS_X
+
+        ; Set cursor position, calculate RAM pointers
+soft80mono_plot:
+        ldx     CURS_Y
+        ldy     CURS_X
+        clc
+        jmp     soft80mono_kplot        ; Set the new cursor
+
+L1:     cmp     #$0D                    ; LF?
+        beq     soft80mono_newline      ; Recalculate pointers
+
+        ; shortcut for codes < $80 ... codes $20-$7f can be printed directly,
+        ; codes $00-$1f are control codes which are not printable and thus may
+        ; give undefined result.
+        tay
+        bpl     @L10
+
+        ; codes $80-$ff must get converted like this:
+        ; $80-$9f  ->   dont care (control codes)
+        ; $a0-$bf  ->   $00-$1f
+        ; $c0-$df  ->   $60-$7f
+        ; $e0-$ff  ->   $00-$1f
+
+        ora     #%01000000      ; $40
+        clc
+        adc     #%00100000      ; $20
+        and     #%01111111      ; $7f
+@L10:
+
+        ; entry point for direct output of a character. the value passed in
+        ; akku must match the offset in the charset.
+        ; - the following may not modify tmp1
+soft80mono_cputdirect:
+        jsr     soft80mono_putchar      ; Write the character to the screen
+
+        ; Advance cursor position
+        iny                             ; contains CURS_X
+        cpy     #charsperline
+        beq     @L3
+
+        sty     CURS_X
+        tya
+        and     #$01
+        sta     soft80mono_internal_cursorxlsb
+        bne     @L4
+
+        lda     SCREEN_PTR
+        clc
+        adc     #8
+        sta     SCREEN_PTR
+        bcc     @L4
+        inc     SCREEN_PTR+1
+@L4:
+        rts
+@L3:
+        inc     CURS_Y          ; new line
+        ldy     #0              ; + cr
+        sty     CURS_X
+        jmp     soft80mono_plot
+
+        ; - the following may not modify tmp1
+soft80mono_newline:
+
+        lda     SCREEN_PTR
+        clc
+        adc     #<(40*8)
+        sta     SCREEN_PTR
+
+        lda     SCREEN_PTR+1
+        adc     #>(40*8)
+        sta     SCREEN_PTR+1
+
+        inc     CURS_Y
+        rts
+
+;-------------------------------------------------------------------------------
+; output one character in internal encoding without advancing cursor position
+; generic entry point
+;
+; - the following may not modify tmp1
+; in:   A: charcode
+; out:  Y: CURS_X
+;
+soft80mono_putchar:
+        sta     tmp3            ; save charcode
+
+        sei
+        lda     $01
+        pha
+        lda     #$34
+        sta     $01             ; enable RAM under I/O
+
+        ldy     #$00            ; will be $00 from now on
+
+        ldx     soft80mono_internal_cursorxlsb
+        lda     chardatal,x
+        clc
+        adc     tmp3
+        sta     ptr2
+        lda     chardatah,x
+        adc     #0
+        sta     ptr2+1
+
+        lda     RVS
+        bne     draw_charinvers
+
+        lda     nibble,x
+        sta     tmp3
+
+        ;ldy     #0                      ; is still $00
+@lp1:
+        lda     (SCREEN_PTR),y
+        and     tmp3
+        ora     (ptr2),y
+        sta     (SCREEN_PTR),y
+        clc
+        lda     ptr2
+        adc     #$7f
+        sta     ptr2
+        bcc     @sk1
+        inc     ptr2+1
+@sk1:
+        iny
+        cpy     #8
+        bne     @lp1
+
+draw_back:
+        pla
+        sta     $01
+        cli
+
+        ldy     CURS_X
+        rts
+
+; output inverted character
+draw_charinvers:
+        lda     soft80mono_internal_nibble,x
+        sta     tmp3
+
+        ;ldy     #0                      ; is still $00
+@lp1:
+        lda     (SCREEN_PTR),y
+        ora     tmp3
+        eor     (ptr2),y
+        sta     (SCREEN_PTR),y
+        clc
+        lda     ptr2
+        adc     #$7f
+        sta     ptr2
+        bcc     @sk1
+        inc     ptr2+1
+@sk1:
+        iny
+        cpy     #8
+        bne     @lp1
+        jmp     draw_back
+
+        .rodata
+chardatal:
+        .byte <soft80_hi_charset
+        .byte <soft80_lo_charset
+chardatah:
+        .byte >soft80_hi_charset
+        .byte >soft80_lo_charset
+nibble:
+        .byte $0f, $f0
+
diff --git a/libsrc/c64/soft80mono_kclrscr.s b/libsrc/c64/soft80mono_kclrscr.s
new file mode 100644 (file)
index 0000000..99243c6
--- /dev/null
@@ -0,0 +1,63 @@
+;
+; Groepaz/Hitmen, 19.10.2015
+;
+; lowlevel kclrscr for the monochrome soft80 implementation
+;
+
+        .export         soft80mono_kclrscr
+        .import         soft80mono_kplot
+        .import         soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
+        .importzp       ptr1
+
+        .include        "c64.inc"
+        .include        "soft80.inc"
+
+soft80mono_kclrscr:
+
+        lda     #<soft80_bitmap
+        sta     ptr1
+        lda     #>soft80_bitmap
+        sta     ptr1+1
+
+        lda     #$ff
+
+        ldx     #$1f
+@lp2:
+        ldy     #0
+@lp1:
+        sta     (ptr1),y
+        iny
+        bne     @lp1
+        inc     ptr1+1
+        dex
+        bne     @lp2
+
+        ;ldx     #$00
+@lp3:
+        sta     soft80_bitmap+$1e40,x
+        inx
+        bne     @lp3
+
+        sei
+        ldy     $01
+        lda     #$34                            ; enable RAM under I/O
+        sta     $01
+
+        lda     soft80mono_internal_cellcolor
+        ; clear loop for vram
+        ;ldx     #$00
+@lp4:
+        sta     soft80_vram,x
+        sta     soft80_vram+$100,x
+        sta     soft80_vram+$200,x
+        sta     soft80_vram+$2e8,x
+        inx
+        bne     @lp4
+
+        sty     $01
+        cli
+
+        ldx     #0
+        ldy     #0
+        clc
+        jmp     soft80mono_kplot
diff --git a/libsrc/c64/soft80mono_kplot.s b/libsrc/c64/soft80mono_kplot.s
new file mode 100644 (file)
index 0000000..b987924
--- /dev/null
@@ -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 (file)
index 0000000..3a80486
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * conio api test program
+ *
+ * keys:
+ *
+ * 1...0        change text color
+ * F5/F6        change border color
+ * F7/F8        change background color
+ *
+ */
+
+
+#include <conio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static char grid[5][5] = {
+    { CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER },
+    { CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
+    { CH_LTEE, CH_HLINE, CH_CROSS, CH_HLINE, CH_RTEE },
+    { CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
+    { CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER },
+};
+
+void main(void)
+{
+        int i, j, n;
+        unsigned char xsize, ysize, tcol, bgcol, bcol, inpos = 0;
+
+        clrscr();
+        screensize(&xsize, &ysize);
+        cputs("cc65 conio test\n\rInput: [        ]");
+
+        cputsxy(0, 2, "Colors:" );
+        tcol = textcolor(0); /* remember original textcolor */
+        bgcol = bgcolor(0); /* remember original background color */
+        bcol = bordercolor(0); /* remember original border color */
+        bgcolor(bgcol);bordercolor(bcol);
+        for (i = 0; i < 3; ++i) {
+                gotoxy(i,3 + i);
+                for (j = 0; j < 16; ++j) {
+                        textcolor(j);
+                        cputc('X');
+                }
+        }
+        textcolor(tcol);
+
+        cprintf("\n\n\r Screensize is: %dx%d", xsize, ysize );
+
+        chlinexy(0,6,xsize);
+        cvlinexy(0,6,3);
+        chlinexy(0,8,xsize);
+        cvlinexy(xsize-1,6,3);
+        cputcxy(0,6,CH_ULCORNER);
+        cputcxy(xsize-1,6,CH_URCORNER);
+        cputcxy(0,8,CH_LLCORNER);
+        cputcxy(xsize-1,8,CH_LRCORNER);
+
+        for (i = 0; i < 5; ++i) {
+                gotoxy(xsize - 5,i);
+                for (j = 0; j < 5; ++j) {
+                        cputc(grid[i][j]);
+                }
+        }
+
+        gotoxy(0,ysize - 2 - ((256 + xsize) / xsize));
+        revers(1);
+        for (i = 0; i < xsize; ++i) {
+                cputc('0' + i % 10);
+        }
+        revers(0);
+        for (i = 0; i < 256; ++i) {
+            if ((i != '\n') && (i != '\r')) {
+                    cputc(i);
+            } else {
+                    cputc(' ');
+            }
+        }
+        while(wherex() > 0) {
+                cputc('#');
+        }
+        revers(1);
+        for (i = 0; i < xsize; ++i) {
+                cputc('0' + i % 10);
+        }
+        revers(0);
+
+        cursor(1);
+        for(;;) {
+
+                gotoxy(8, 2);
+                j = n & 1;
+                revers(j);
+                cputc(j ? 'R' : ' ');
+                revers(j ^ 1);
+                cputs(" revers");
+                revers(0);
+
+                gotoxy(8 + inpos,1);
+                i = cgetc();
+                if ((i >= '0') && (i<='9')) {
+                    textcolor(i - '0');
+                } else if (i == CH_CURS_LEFT) {
+                    inpos = (inpos - 1) & 7;
+                } else if (i == CH_CURS_RIGHT) {
+                    inpos = (inpos + 1) & 7;
+                } else if (i == CH_F5) {
+                    bgcol = (bgcol + 1) & 0x0f;
+                    bordercolor(bgcol);
+                } else if (i == CH_F6) {
+                    bgcol = (bgcol - 1) & 0x0f;
+                    bordercolor(bgcol);
+                } else if (i == CH_F7) {
+                    bgcol = (bgcol + 1) & 0x0f;
+                    bgcolor(bgcol);
+                } else if (i == CH_F8) {
+                    bgcol = (bgcol - 1) & 0x0f;
+                    bgcolor(bgcol);
+                } else {
+                    cputc(i);
+                    inpos = (inpos + 1) & 7;
+                }
+
+                ++n;
+        }
+
+        for(;;);
+}