--- /dev/null
+/*****************************************************************************/
+/* */
+/* c16.h */
+/* */
+/* C16 system specific definitions */
+/* */
+/* */
+/* */
+/* (C) 2002 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef _C16_H
+#define _C16_H
+
+
+
+/* Check for errors */
+#if !defined(__C16__)
+# error This module may only be used when compiling for the C16!
+#endif
+
+
+
+/* The C16 is actually the Plus/4 with less memory, so use the Plus/4
+ * include file.
+ */
+#ifndef _PLUS4_H
+#include <plus4.h>
+#endif
+
+
+
+/* End of c16.h */
+#endif
+
+
+
# include <c128.h>
#elif defined(__PLUS4__) && !defined(_PLUS4_H)
# include <plus4.h>
+#elif defined(__C16__) && !defined(_C16_H)
+# include <c16.h>
#elif defined(__CBM510__) && !defined(_CBM510_H)
# include <cbm510.h>
#elif defined(__CBM610__) && !defined(_CBM610_H)
* Returns the number of actually written bytes or -1 in case of an error.
* _oserror contains an errorcode then (see table below).
*/
-
+
/* Errorcodes of cbm_* I/O functions:
*
* errorcode BASIC error
/* */
/* */
/* */
-/* (C) 1998-2001 Ullrich von Bassewitz */
+/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* Check for errors */
-#if !defined(__PLUS4__)
-# error This module may only be used when compiling for the Plus/4!
+#if !defined(__PLUS4__) && !defined(__C16__)
+# error This module may only be used when compiling for the Plus/4 or C16!
#endif
atarilib \
atmoslib \
vic20lib \
+ c16lib \
c64lib \
c128lib \
cbm510lib \
$(AR) a vic20.lib $$i/*.o;\
done
+#-----------------------------------------------------------------------------
+# C16, C116
+
+c16lib:
+ for i in c16 cbm common runtime conio dbg tgi; do \
+ CC=$(CC) \
+ AS=$(AS) \
+ CFLAGS="-Osir -g -T -t plus4 -I../../include" \
+ AFLAGS="-t plus4 -I../../asminc" \
+ $(MAKE) -C $$i || exit 1; \
+ done
+ mv c16/crt0.o c16.o
+ for i in c16 cbm common runtime conio dbg tgi; do \
+ $(AR) a c16.lib $$i/*.o;\
+ done
+
#-----------------------------------------------------------------------------
# C64
done
#-----------------------------------------------------------------------------
-# Commodore C116, C16 and Plus/4
+# Commodore Plus/4
plus4lib:
for i in plus4 cbm common runtime conio dbg tgi; do \
--- /dev/null
+#
+# makefile for CC65 runtime library (C16)
+#
+
+.SUFFIXES: .o .s .c
+
+%.o: %.c
+ @$(CC) $(CFLAGS) $<
+ @$(AS) -o $@ $(AFLAGS) $(*).s
+
+%.o: %.s
+ @$(AS) -g -o $@ $(AFLAGS) $<
+
+OBJS = _scrsize.o \
+ break.o \
+ cgetc.o \
+ clrscr.o \
+ color.o \
+ conio.o \
+ cputc.o \
+ crt0.o \
+ kbhit.o \
+ kernal.o \
+ randomize.o \
+ readjoy.o
+
+all: $(OBJS)
+
+clean:
+ @rm -f $(OBJS)
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 26.10.2000
+;
+; Screen size variables
+;
+
+ .export xsize, ysize
+ .import SCREEN
+ .constructor initscrsize
+
+
+.code
+
+initscrsize:
+ jsr SCREEN
+ stx xsize
+ sty ysize
+ rts
+
+.bss
+
+xsize: .res 1
+ysize: .res 1
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 27.09.1998
+;
+; void set_brk (unsigned Addr);
+; void reset_brk (void);
+;
+
+ .export _set_brk, _reset_brk
+ .destructor _reset_brk
+ .export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
+
+ .include "../plus4/plus4.inc"
+
+
+.bss
+_brk_a: .res 1
+_brk_x: .res 1
+_brk_y: .res 1
+_brk_sr: .res 1
+_brk_pc: .res 2
+
+oldvec: .res 2 ; Old vector
+
+
+.data
+uservec: jmp $FFFF ; Patched at runtime
+
+
+.code
+
+; Set the break vector
+.proc _set_brk
+
+ sta uservec+1
+ stx uservec+2 ; Set the user vector
+
+ lda oldvec
+ ora oldvec+1 ; Did we save the vector already?
+ bne L1 ; Jump if we installed the handler already
+
+ lda BRKVec
+ sta oldvec
+ lda BRKVec+1
+ sta oldvec+1 ; Save the old vector
+
+L1: lda #<brk_handler ; Set the break vector to our routine
+ ldx #>brk_handler
+ sta BRKVec
+ stx BRKVec+1
+ rts
+
+.endproc
+
+
+; Reset the break vector
+.proc _reset_brk
+
+ lda oldvec
+ ldx oldvec+1
+ beq @L9 ; Jump if vector not installed
+ sta BRKVec
+ stx BRKVec+1
+ lda #$00
+ sta oldvec ; Clear the old vector
+ stx oldvec+1
+@L9: rts
+
+.endproc
+
+
+
+; Break handler, called if a break occurs
+
+.proc brk_handler
+
+ pla
+ sta _brk_y
+ pla
+ sta _brk_x
+ pla
+ sta _brk_a
+ pla
+ and #$EF ; Clear break bit
+ sta _brk_sr
+ pla ; PC low
+ sec
+ sbc #2 ; Point to start of brk
+ sta _brk_pc
+ pla ; PC high
+ sbc #0
+ sta _brk_pc+1
+
+ jsr uservec ; Call the user's routine
+
+ lda _brk_pc+1
+ pha
+ lda _brk_pc
+ pha
+ lda _brk_sr
+ pha
+ ldx _brk_x
+ ldy _brk_y
+ lda _brk_a
+ rti ; Jump back...
+
+.endproc
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; char cgetc (void);
+;
+
+ .export _cgetc
+ .import cursor
+
+ .include "../plus4/plus4.inc"
+
+
+; --------------------------------------------------------------------------
+
+_cgetc: lda KEY_COUNT ; Get number of characters
+ ora FKEY_COUNT ; Or with number of function key chars
+ bne L2 ; Jump if there are already chars waiting
+
+; Switch on the cursor if needed
+
+ ldy CURS_X
+ lda (CRAM_PTR),y ; Get current char
+ pha ; And save it
+ lda CHARCOLOR
+ sta (CRAM_PTR),y
+
+ lda cursor
+ beq L1 ; Jump if no cursor
+ tya
+ clc
+ adc SCREEN_PTR
+ sta TED_CURSLO
+ lda SCREEN_PTR+1
+ adc #$00
+ sbc #$0B ; + carry = $C00 (screen address)
+ sta TED_CURSHI
+
+L1: lda KEY_COUNT
+ ora FKEY_COUNT
+ beq L1
+ pla
+ sta (CRAM_PTR),y
+ lda #$ff
+ sta TED_CURSLO ; Cursor off
+ sta TED_CURSHI
+
+L2: jsr KBDREAD ; Read char and return in A
+ ldx #0
+ rts
+
+; --------------------------------------------------------------------------
+; Make the function keys return function key codes instead of the current
+; strings so the program will see and may handle them.
+; Undo this change when the program ends
+
+ .constructor initkbd
+ .destructor donekbd
+
+.proc initkbd
+
+ ldy #15
+@L1: lda fnkeys,y
+ sta FKEY_SPACE,y
+ dey
+ bpl @L1
+ rts
+
+.endproc
+
+
+.proc donekbd
+
+ ldx #$39 ; Copy the original function keys
+@L1: lda FKEY_ORIG,x
+ sta FKEY_SPACE,x
+ dex
+ bpl @L1
+ rts
+
+.endproc
+
+
+; Function key table, readonly
+
+.rodata
+fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01
+ .byte 133, 137, 134, 138, 135, 139, 136, 140
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; void clrscr (void);
+;
+
+ .export _clrscr
+
+ .include "../plus4/plus4.inc"
+
+_clrscr = CLRSCR
+
+
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; 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
+
+ .include "../plus4/plus4.inc"
+
+_textcolor:
+ ldx CHARCOLOR ; get old value
+ sta CHARCOLOR ; set new value
+ txa
+ rts
+
+
+_bgcolor:
+ ldx TED_BGCOLOR ; get old value
+ sta TED_BGCOLOR ; set new value
+ txa
+ rts
+
+
+_bordercolor:
+ ldx TED_BORDERCOLOR ; get old value
+ sta TED_BORDERCOLOR ; set new value
+ txa
+ rts
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; Low level stuff for screen output/console input
+;
+
+ .exportzp CURS_X, CURS_Y
+
+ .include "../plus4/plus4.inc"
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; void cputcxy (unsigned char x, unsigned char y, char c);
+; void cputc (char c);
+;
+
+ .export _cputcxy, _cputc, cputdirect, putchar
+ .export newline, plot
+ .import popa, _gotoxy
+ .import xsize, revers
+ .import PLOT
+
+ .include "../plus4/plus4.inc"
+
+
+_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
+
+_cputc: cmp #$0A ; CR?
+ bne L1
+ lda #0
+ sta CURS_X
+ beq plot ; Recalculate pointers
+
+L1: cmp #$0D ; LF?
+ beq newline ; Recalculate pointers
+
+; Printable char of some sort
+
+ cmp #' '
+ bcc cputdirect ; Other control char
+ tay
+ bmi L10
+ cmp #$60
+ bcc L2
+ and #$DF
+ bne cputdirect ; Branch always
+L2: and #$3F
+
+cputdirect:
+ jsr putchar ; Write the character to the screen
+
+; Advance cursor position
+
+advance:
+ iny
+ cpy xsize
+ bne L3
+ jsr newline ; new line
+ ldy #0 ; + cr
+L3: sty CURS_X
+ rts
+
+newline:
+ clc
+ lda xsize
+ adc SCREEN_PTR
+ sta SCREEN_PTR
+ bcc L4
+ inc SCREEN_PTR+1
+ clc
+L4: lda xsize
+ adc CRAM_PTR
+ sta CRAM_PTR
+ bcc L5
+ inc CRAM_PTR+1
+L5: inc CURS_Y
+ rts
+
+; Handle character if high bit set
+
+L10: and #$7F
+ cmp #$7E ; PI?
+ bne L11
+ lda #$5E ; Load screen code for PI
+ bne cputdirect
+L11: ora #$40
+ bne cputdirect
+
+
+
+; Set cursor position, calculate RAM pointers
+
+plot: ldy CURS_X
+ ldx CURS_Y
+ clc
+ jmp PLOT ; Set the new cursor
+
+
+
+; Write one character to the screen without doing anything else, return X
+; position in Y
+
+putchar:
+ ora revers ; Set revers bit
+ ldy CURS_X
+ sta (SCREEN_PTR),y ; Set char
+ lda CHARCOLOR
+ sta (CRAM_PTR),y ; Set color
+ rts
--- /dev/null
+;
+; Startup code for cc65 (C16 version)
+;
+; This must be the *first* file on the linker command line
+;
+; Note: The C16 is actually the Plus/4 with just 16KB of memory. So many
+; things are similar here, and we even use the plus4.inc include file.
+;
+
+ .export _exit
+ .import initlib, donelib
+ .import push0, _main, zerobss
+ .import MEMTOP, RESTOR, BSOUT, CLRCH
+
+ .include "zeropage.inc"
+ .include "../plus4/plus4.inc"
+
+
+; ------------------------------------------------------------------------
+; BASIC header with a SYS call
+
+.code
+
+ .org $0FFF
+ .word Head ; Load address
+Head: .word @Next
+ .word 1000 ; Line number
+ .byte $9E,"4109" ; SYS 4109
+ .byte $00 ; End of BASIC line
+@Next: .word 0 ; BASIC end marker
+ .reloc
+
+; ------------------------------------------------------------------------
+; Actual code
+
+ ldx #zpspace-1
+L1: lda sp,x
+ sta zpsave,x ; save the zero page locations we need
+ dex
+ bpl L1
+
+; Close open files
+
+ jsr CLRCH
+
+; Switch to second charset
+
+ lda #14
+ jsr BSOUT
+
+; Clear the BSS data
+
+ jsr zerobss
+
+; Save system stuff and setup the stack
+
+ tsx
+ stx spsave ; save system stk ptr
+
+ sec
+ jsr MEMTOP ; Get top memory
+ cpy #$80 ; We can only use the low 32K :-(
+ bcc MemOk
+ ldy #$80
+ ldx #$00
+MemOk: stx sp
+ sty sp+1 ; set argument stack ptr
+
+; Call module constructors
+
+ jsr initlib
+
+; Pass an empty command line
+
+ jsr push0 ; argc
+ jsr push0 ; argv
+
+ ldy #4 ; Argument size
+ jsr _main ; call the users code
+
+; Call module destructors. This is also the _exit entry.
+
+_exit: jsr donelib ; Run module destructors
+
+; Restore system stuff
+
+ ldx spsave
+ txs
+
+; Copy back the zero page stuff
+
+ ldx #zpspace-1
+L2: lda zpsave,x
+ sta sp,x
+ dex
+ bpl L2
+
+; Reset changed vectors
+
+ jmp RESTOR
+
+
+.data
+zpsave: .res zpspace
+
+.bss
+spsave: .res 1
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; int kbhit (void);
+;
+
+ .export _kbhit
+ .import return0, return1
+
+ .include "../plus4/plus4.inc"
+
+_kbhit:
+ lda KEY_COUNT ; Get number of characters
+ ora FKEY_COUNT ; Or with number of chars from function keys
+ bne L1
+ jmp return0
+L1: jmp return1
+
+
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 19.11.2002
+;
+; C16 kernal functions
+;
+
+ .export CINT
+ .export IOINIT
+ .export RAMTAS
+ .export RESTOR
+ .export VECTOR
+ .export SETMSG
+ .export SECOND
+ .export TKSA
+ .export MEMTOP
+ .export MEMBOT
+ .export SCNKEY
+ .export SETTMO
+ .export ACPTR
+ .export CIOUT
+ .export UNTLK
+ .export UNLSN
+ .export LISTEN
+ .export TALK
+ .export READST
+ .export SETLFS
+ .export SETNAM
+ .export OPEN
+ .export CLOSE
+ .export CHKIN
+ .export CKOUT
+ .export CLRCH
+ .export BASIN
+ .export BSOUT
+ .export LOAD
+ .export SAVE
+ .export SETTIM
+ .export RDTIM
+ .export STOP
+ .export GETIN
+ .export CLALL
+ .export UDTIM
+ .export SCREEN
+ .export PLOT
+ .export IOBASE
+
+
+;-----------------------------------------------------------------------------
+; All functions are available in the kernal jump table
+
+CINT = $FF81
+IOINIT = $FF84
+RAMTAS = $FF87
+RESTOR = $FF8A
+VECTOR = $FF8D
+SETMSG = $FF90
+SECOND = $FF93
+TKSA = $FF96
+MEMTOP = $FF99
+MEMBOT = $FF9C
+SCNKEY = $FF9F
+SETTMO = $FFA2
+ACPTR = $FFA5
+CIOUT = $FFA8
+UNTLK = $FFAB
+UNLSN = $FFAE
+LISTEN = $FFB1
+TALK = $FFB4
+READST = $FFB7
+SETLFS = $FFBA
+SETNAM = $FFBD
+OPEN = $FFC0
+CLOSE = $FFC3
+CHKIN = $FFC6
+CKOUT = $FFC9
+CLRCH = $FFCC
+BASIN = $FFCF
+BSOUT = $FFD2
+LOAD = $FFD5
+SAVE = $FFD8
+SETTIM = $FFDB
+RDTIM = $FFDE
+STOP = $FFE1
+GETIN = $FFE4
+CLALL = $FFE7
+UDTIM = $FFEA
+SCREEN = $FFED
+PLOT = $FFF0
+IOBASE = $FFF3
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 05.11.2002
+;
+; void _randomize (void);
+; /* Initialize the random number generator */
+;
+
+ .export __randomize
+ .import _srand
+
+ .include "../plus4/plus4.inc"
+
+__randomize:
+ ldx TED_VLINELO ; Use TED rasterline as high byte
+ lda TIME ; Use 60HZ clock as low byte
+ jmp _srand ; Initialize generator
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 23.09.1998
+;
+; unsigned readjoy (unsigned char joy);
+;
+
+ .export _readjoy
+
+ .include "../plus4/plus4.inc"
+
+
+.proc _readjoy
+
+ ldy #$FA ; Load index for joystick #1
+ tax ; Test joystick number
+ beq L1
+ ldy #$FB ; Load index for joystick #2
+L1: sei
+ sty TED_KBD
+ lda TED_KBD
+ cli
+ ldx #$00 ; Clear high byte
+ and #$1F
+ eor #$1F
+ rts
+
+.endproc
+
+
DefineNumericMacro ("__ATARI__", 1);
break;
+ case TGT_C16:
+ cbmsys ("__C16__");
+ break;
+
case TGT_C64:
cbmsys ("__C64__");
break;
static void OptDebugInfo (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Add debug info to the object file */
{
DebugInfo = 1;
"module",
"atari",
"vic20",
+ "c16",
"c64",
"c128",
"ace",
"geos",
"lunix",
"atmos"
-};
+};
TGT_MODULE,
TGT_ATARI,
TGT_VIC20,
+ TGT_C16,
TGT_C64,
TGT_C128,
TGT_ACE,
case TGT_MODULE: memcpy (Tab, CTNone, sizeof (Tab)); break;
case TGT_ATARI: memcpy (Tab, CTAtari, sizeof (Tab)); break;
case TGT_VIC20: memcpy (Tab, CTPET, sizeof (Tab)); break;
+ case TGT_C16: memcpy (Tab, CTPET, sizeof (Tab)); break;
case TGT_C64: memcpy (Tab, CTPET, sizeof (Tab)); break;
case TGT_C128: memcpy (Tab, CTPET, sizeof (Tab)); break;
case TGT_ACE: memcpy (Tab, CTPET, sizeof (Tab)); break;
atmos.inc
bbc.inc
c128.inc
+c16.inc
c64.inc
cbm510.inc
cbm610.inc
--- /dev/null
+MEMORY {
+ ZP: start = $02, size = $1A, type = rw, define = yes;
+ RAM: start = $0fff, size = $7001, file = %O;
+}
+SEGMENTS {
+ CODE: load = RAM, type = wprot;
+ RODATA: load = RAM, type = wprot;
+ DATA: load = RAM, type = rw;
+ BSS: load = RAM, type = bss, define = yes;
+ ZEROPAGE: load = ZP, type = zp;
+}
+FEATURES {
+ CONDES: segment = RODATA,
+ type = constructor,
+ label = __CONSTRUCTOR_TABLE__,
+ count = __CONSTRUCTOR_COUNT__;
+ CONDES: segment = RODATA,
+ type = destructor,
+ label = __DESTRUCTOR_TABLE__,
+ count = __DESTRUCTOR_COUNT__;
+}
+SYMBOLS {
+ __STACKSIZE__ = $800; # 2K stack
+}
atari.inc \
atmos.inc \
bbc.inc \
+ c16.inc \
c64.inc \
c128.inc \
cbm510.inc \
bbc.inc: cfg/bbc.cfg
@$(CVT) $< $@ CfgBBC
+c16.inc: cfg/c16.cfg
+ @$(CVT) $< $@ CfgC16
+
c64.inc: cfg/c64.cfg
@$(CVT) $< $@ CfgC64
#include "atmos.inc"
#include "bbc.inc"
#include "c128.inc"
+#include "c16.inc"
#include "c64.inc"
#include "cbm510.inc"
#include "cbm610.inc"
{ BINFMT_O65, CfgModule },
{ BINFMT_BINARY, CfgAtari },
{ BINFMT_BINARY, CfgVic20 },
+ { BINFMT_BINARY, CfgC16 },
{ BINFMT_BINARY, CfgC64 },
{ BINFMT_BINARY, CfgC128 },
{ BINFMT_BINARY, CfgEmpty }, /* Ace */
+