mirror of
https://github.com/cc65/cc65.git
synced 2025-01-26 17:36:57 +00:00
Created a target and a library for the Commander X16 prototype computer.
This commit is contained in:
parent
0896deedef
commit
18afc7c703
@ -1,30 +1,45 @@
|
||||
;
|
||||
; Olli Savia <ops@iki.fi>
|
||||
;
|
||||
; Commodore kernal functions
|
||||
; Commodore Kernal functions
|
||||
;
|
||||
|
||||
.if .def(__CX16__)
|
||||
; CX16 extended jump table
|
||||
GETJOY := $FF06
|
||||
.endif
|
||||
|
||||
.if .def(__C128__)
|
||||
; C128 Extended jump table
|
||||
; C128 extended jump table
|
||||
C64MODE := $FF4D
|
||||
SWAPPER := $FF5F
|
||||
SETBNK := $FF68
|
||||
.endif
|
||||
|
||||
.if .def(__C64__) || .def(__C128__) || .def(__C16__)
|
||||
.if .def(__C128__) || .def(__CX16__)
|
||||
; Extended jump table
|
||||
CLSALL := $FF4A
|
||||
SWAPPER := $FF5F
|
||||
JSRFAR := $FF6E
|
||||
INDFET := $FF74
|
||||
INDSTA := $FF77
|
||||
INDCMP := $FF7A
|
||||
PRIMM := $FF7D
|
||||
.endif
|
||||
|
||||
.if .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__)
|
||||
CINT := $FF81
|
||||
IOINIT := $FF84
|
||||
RAMTAS := $FF87
|
||||
.elseif .def(__VIC20__)
|
||||
CINT := $E518 ; No entries are in the kernal jump table of the Vic20 for these three (3) functions.
|
||||
CINT := $E518 ; No entries are in the Kernal jump table of the VIC-20 for these three (3) functions.
|
||||
IOINIT := $FDF9 ; The entries for these functions have been set to point directly to the functions
|
||||
RAMTAS := $FD8D ; in the kernal to maintain compatibility with the other Commodore platforms.
|
||||
RAMTAS := $FD8D ; in the Kernal, to maintain compatibility with the other Commodore platforms.
|
||||
.elseif .def(__CBM510__) || .def(__CBM610__)
|
||||
IOINIT := $FF7B
|
||||
CINT := $FF7E
|
||||
.endif
|
||||
|
||||
.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__)
|
||||
.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__)
|
||||
RESTOR := $FF8A
|
||||
VECTOR := $FF8D
|
||||
.elseif .def(__CBM510__) || .def(__CBM610__)
|
||||
@ -32,7 +47,7 @@
|
||||
RESTOR := $FF87
|
||||
.endif
|
||||
|
||||
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__)
|
||||
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__)
|
||||
SETMSG := $FF90
|
||||
SECOND := $FF93
|
||||
TKSA := $FF96
|
||||
@ -64,7 +79,7 @@ CHRIN := $FFCF
|
||||
BSOUT := $FFD2
|
||||
CHROUT := $FFD2
|
||||
|
||||
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__)
|
||||
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__)
|
||||
LOAD := $FFD5
|
||||
SAVE := $FFD8
|
||||
SETTIM := $FFDB
|
||||
@ -77,7 +92,7 @@ GETIN := $FFE4
|
||||
CLALL := $FFE7
|
||||
UDTIM := $FFEA
|
||||
|
||||
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__)
|
||||
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__)
|
||||
SCREEN := $FFED
|
||||
PLOT := $FFF0
|
||||
IOBASE := $FFF3
|
||||
@ -102,7 +117,6 @@ UDTIM := $FFEA
|
||||
CURS_SET := $CD57
|
||||
CURS_ON := $CD6F
|
||||
CURS_OFF := $CD9F
|
||||
INDFET := $FF74
|
||||
.elseif .def(__C16__)
|
||||
CLRSCR := $D88B
|
||||
KBDREAD := $D8C1
|
||||
|
316
asminc/cx16.inc
Normal file
316
asminc/cx16.inc
Normal file
@ -0,0 +1,316 @@
|
||||
;
|
||||
; CX16 definitions
|
||||
;
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Constants
|
||||
|
||||
.enum COLOR
|
||||
BLACK = $00
|
||||
WHITE
|
||||
RED
|
||||
CYAN
|
||||
VIOLET
|
||||
PURPLE = VIOLET
|
||||
GREEN
|
||||
BLUE
|
||||
YELLOW
|
||||
ORANGE
|
||||
BROWN
|
||||
LIGHTRED
|
||||
GRAY1
|
||||
GRAY2
|
||||
LIGHTGREEN
|
||||
LIGHTBLUE
|
||||
GRAY3
|
||||
.endenum
|
||||
|
||||
; Special keys
|
||||
.enum KEY
|
||||
F1 = $85
|
||||
F3
|
||||
F5
|
||||
F7
|
||||
F2
|
||||
F4
|
||||
F6
|
||||
F8
|
||||
F9 = $10
|
||||
F10 = $15
|
||||
F11
|
||||
F12
|
||||
.endenum
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Zero page
|
||||
|
||||
; BASIC
|
||||
VARTAB := $2D ; Pointer to start of BASIC variables
|
||||
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
||||
TXTPTR := $7A ; Pointer into BASIC source code
|
||||
|
||||
; Kernal
|
||||
IN_DEV := $99 ; Current input device number
|
||||
OUT_DEV := $9A ; Current output device number
|
||||
IMPARM := $9B ; Pointer for PRIMM function
|
||||
TIME := $A0 ; 60 Hz. clock
|
||||
FNAM_LEN := $B7 ; Length of filename
|
||||
SECADR := $B9 ; Secondary address
|
||||
DEVNUM := $BA ; Device number
|
||||
FNAM := $BB ; Pointer to filename
|
||||
KEY_COUNT := $C6 ; Number of keys in input buffer
|
||||
RVS := $C7 ; Reverse flag
|
||||
CURS_FLAG := $CC ; 1 = cursor off
|
||||
CURS_BLINK := $CD ; Blink counter
|
||||
CURS_CHAR := $CE ; Character under the cursor
|
||||
CURS_STATE := $CF ; Cursor blink state
|
||||
SCREEN_PTR := $D1 ; Pointer to current row on text screen (16 bits)
|
||||
CURS_X := $D3 ; Cursor column
|
||||
CURS_Y := $D6 ; Cursor row
|
||||
LLEN := $D9 ; Line length
|
||||
NLINES := $DA ; Number of screen lines
|
||||
JOY1 := $EF ; 3 bytes of NES/SNES gamepad data
|
||||
JOY2 := $F2
|
||||
FREKZP := $FB ; Five unused bytes
|
||||
|
||||
; Page two
|
||||
|
||||
BASIC_BUF := $200 ; Location of command-line
|
||||
BASIC_BUF_LEN = 89 ; Maximum length of command-line
|
||||
|
||||
CHARCOLOR := $286
|
||||
CURS_COLOR := $287 ; Color under the cursor
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Vector and other locations
|
||||
|
||||
IRQVec := $0314
|
||||
BRKVec := $0316
|
||||
NMIVec := $0318
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; I/O locations
|
||||
|
||||
; Video Enhanced Retro Adapter
|
||||
; Has audio, SPI, and UART.
|
||||
.scope VERA
|
||||
; External registers
|
||||
.struct
|
||||
.org $9F20
|
||||
ADDR .faraddr ; Address for data port access
|
||||
DATA0 .byte ; First data port
|
||||
DATA1 .byte ; Second data port
|
||||
CTRL .byte ; Control register
|
||||
IRQ_EN .byte ; Interrupt enable bits
|
||||
IRQ_FLAGS .byte ; Interrupt flags
|
||||
.endstruct
|
||||
.enum ; Address automatic increment amounts
|
||||
INC0 = 0 << 4
|
||||
INC1 = 1 << 4
|
||||
INC2 = 2 << 4
|
||||
INC4 = 3 << 4
|
||||
INC8 = 4 << 4
|
||||
INC16 = 5 << 4
|
||||
INC32 = 6 << 4
|
||||
INC64 = 7 << 4
|
||||
INC128 = 8 << 4
|
||||
INC256 = 9 << 4
|
||||
INC512 = 10 << 4
|
||||
INC1024 = 11 << 4
|
||||
INC2048 = 12 << 4
|
||||
INC4096 = 13 << 4
|
||||
INC8192 = 14 << 4
|
||||
INC16384 = 15 << 4
|
||||
.endenum
|
||||
; Internal RAM and registers
|
||||
VRAM := $000000
|
||||
.scope COMPOSER ; Display composer
|
||||
.struct
|
||||
.org $0F0000
|
||||
VIDEO .byte
|
||||
HSCALE .byte
|
||||
VSCALE .byte
|
||||
FRAME .byte
|
||||
HSTART_LO .byte
|
||||
HSTOP_LO .byte
|
||||
VSTART_LO .byte
|
||||
VSTOP_LO .byte
|
||||
STRTSTOP_HI .byte
|
||||
IRQ_LINE .word
|
||||
.endstruct
|
||||
.enum MODE ; Output mode
|
||||
DISABLE = 0
|
||||
VGA
|
||||
NTSC
|
||||
RGB ; Interlaced, composite sync
|
||||
.endenum
|
||||
.enum
|
||||
ENABLE_COLOR = 0 << 2
|
||||
DISABLE_COLOR = 1 << 2 ; NTSC monochrome
|
||||
.endenum
|
||||
.endscope
|
||||
PALETTE := $0F1000
|
||||
.struct L0 ; Layer 0 registers
|
||||
.org $0F2000
|
||||
CTRL0 .byte ; Display mode control
|
||||
CTRL1 .byte ; Geometry control
|
||||
MAP_BASE .addr
|
||||
TILE_BASE .addr
|
||||
HSCROLL .word ; Horizontal scroll
|
||||
VSCROLL .word ; Vertical scroll
|
||||
.endstruct
|
||||
.struct L1 ; Layer 1 registers (same as layer 0)
|
||||
.org $0F3000
|
||||
CTRL0 .byte
|
||||
CTRL1 .byte
|
||||
MAP_BASE .addr
|
||||
TILE_BASE .addr
|
||||
HSCROLL .word
|
||||
VSCROLL .word
|
||||
.endstruct
|
||||
.enum MAP ; Map geometry
|
||||
WIDTH32 = 0
|
||||
WIDTH64
|
||||
WIDTH128
|
||||
WIDTH256
|
||||
HEIGHT32 = 0 << 2
|
||||
HEIGHT64 = 1 << 2
|
||||
HEIGHT128 = 2 << 2
|
||||
HEIGHT256 = 3 << 2
|
||||
.endenum
|
||||
.scope TILE ; Tile geometry
|
||||
.enum
|
||||
WIDTH8 = 0 << 4
|
||||
WIDTH16 = 1 << 4
|
||||
WIDTH320 = WIDTH8
|
||||
WIDTH640 = WIDTH16
|
||||
HEIGHT8 = 0 << 5
|
||||
HEIGHT16 = 1 << 5
|
||||
.endenum
|
||||
.enum FLIP
|
||||
NONE = 0 << 2
|
||||
HORIZ = 1 << 2
|
||||
VERT = 2 << 2
|
||||
BOTH = 3 << 2
|
||||
.endenum
|
||||
.endscope
|
||||
.enum DMODE ; Display modes
|
||||
TEXT16 = 0 << 5
|
||||
TEXT256 = 1 << 5
|
||||
TILE4 = 2 << 5
|
||||
TILE16 = 3 << 5
|
||||
TILE256 = 4 << 5
|
||||
BITMAP4 = 5 << 5
|
||||
BITMAP16 = 6 << 5
|
||||
BITMAP256 = 7 << 5
|
||||
.endenum
|
||||
.scope SPRITE
|
||||
.struct
|
||||
.org $0F4000
|
||||
CTRL .byte ; Enables sprites
|
||||
COLLISION .byte
|
||||
.endstruct
|
||||
.enum FLIP
|
||||
NONE = 0
|
||||
HORIZ
|
||||
VERT
|
||||
BOTH
|
||||
.endenum
|
||||
.enum ; Sprite geometry
|
||||
WIDTH8 = 0 << 4
|
||||
WIDTH16 = 1 << 4
|
||||
WIDTH32 = 2 << 4
|
||||
WIDTH64 = 3 << 4
|
||||
HEIGHT8 = 0 << 6
|
||||
HEIGHT16 = 1 << 6
|
||||
HEIGHT32 = 2 << 6
|
||||
HEIGHT64 = 3 << 6
|
||||
COLORS16 = 0 << 7
|
||||
COLORS256 = 1 << 7
|
||||
.endenum
|
||||
.enum DEPTH
|
||||
DISABLE = 0 << 2
|
||||
CANVAS = 1 << 2
|
||||
LAYER0 = 2 << 2
|
||||
LAYER1 = 3 << 2
|
||||
.endenum
|
||||
ATTRIB := $0F5000 ; Sprite attributes
|
||||
.endscope
|
||||
AUDIO := $0F6000
|
||||
.scope SPI
|
||||
.struct
|
||||
.org $0F7000
|
||||
DATA .byte
|
||||
CONTROL .byte
|
||||
.endstruct
|
||||
.enum
|
||||
DESELECT = 0
|
||||
SELECT
|
||||
BUSY_MASK = 1 << 1
|
||||
.endenum
|
||||
.endscope
|
||||
.scope UART ; Universal Asyncronous Receiver Transmitter
|
||||
.struct
|
||||
.org $0F8000
|
||||
DATA .byte
|
||||
STATUS .byte
|
||||
BPS_DIV .word
|
||||
.endstruct
|
||||
.enum MASK
|
||||
RECEIVE = 1 << 0
|
||||
TRANSMIT = 1 << 1
|
||||
.endenum
|
||||
.endscope
|
||||
.endscope
|
||||
|
||||
; 65c22
|
||||
.struct VIA1 ; Versatile Interface Adapter
|
||||
.org $9F60
|
||||
PRB .byte ; ROM bank, IEC (Port Register B)
|
||||
PRA .byte ; RAM bank (Port Register A)
|
||||
DDRB .byte ; (Data Direction Register B)
|
||||
DDRA .byte ; (Data Direction Register A)
|
||||
T1 .word ; (Timer 1)
|
||||
T1L .word ; (Timer 1 Latch)
|
||||
T2 .word ; (Timer 2)
|
||||
SR .byte ; (Shift Register)
|
||||
ACR .byte ; (Auxiliary Control Register)
|
||||
PCR .byte ; (Peripheral Control Register)
|
||||
IFR .byte ; (Interrupt Flags Register)
|
||||
IER .byte ; (Interrupt Enable Register)
|
||||
PRA2 .byte ; RAM bank (Port Register A without handshaking)
|
||||
.endstruct
|
||||
|
||||
; 65c22
|
||||
.struct VIA2
|
||||
.org $9F70
|
||||
PRB .byte
|
||||
PRA .byte ; NES controller communication
|
||||
DDRB .byte
|
||||
DDRA .byte
|
||||
T1 .word
|
||||
T1L .word
|
||||
T2 .word
|
||||
SR .byte
|
||||
ACR .byte
|
||||
PCR .byte
|
||||
IFR .byte
|
||||
IER .byte
|
||||
PRA2 .byte
|
||||
.endstruct
|
||||
|
||||
; Real-Time Clock
|
||||
|
||||
; X16 Emulator device
|
||||
; This device doesn't exist on the real machine.
|
||||
.struct EMULATOR
|
||||
.org $9FB0
|
||||
DEBUG .byte ; Boolean: debugging enabled
|
||||
VIDACCESSLOG .byte ; Boolean: log VERA activity
|
||||
KEYBOARDLOG .byte ; Boolean: log keyboard data
|
||||
ECHO .byte ; Boolean: echo enabled
|
||||
SAVEXIT .byte ; Boolean: save on exit
|
||||
.res $D - $5
|
||||
KEYMAP .byte ; Current keyboard layout number
|
||||
DETECT .byte 2 ; If is "16" string, then running on emulator
|
||||
.endstruct
|
37
cfg/cx16-asm.cfg
Normal file
37
cfg/cx16-asm.cfg
Normal file
@ -0,0 +1,37 @@
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $0801;
|
||||
}
|
||||
SYMBOLS {
|
||||
__LOADADDR__: type = import;
|
||||
__HIMEM__: type = weak, value = $9F00;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", start = $0004, size = $0090 - $0004, define = yes;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
MAIN: file = %O, start = %S, size = __HIMEM__ - %S;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = MAIN, type = ro, optional = yes;
|
||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
BSS: load = MAIN, type = bss, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
112
cfg/cx16-bank.cfg
Normal file
112
cfg/cx16-bank.cfg
Normal file
@ -0,0 +1,112 @@
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $0801;
|
||||
}
|
||||
SYMBOLS {
|
||||
__LOADADDR__: type = import;
|
||||
__EXEHDR__: type = import;
|
||||
__BANKRAMADDR__: type = import;
|
||||
__STACKSIZE__: type = weak, value = $0800; # 2K stack
|
||||
__HIMEM__: type = weak, value = $9F00;
|
||||
__BANKRAMSTART__: type = export, value = $A000;
|
||||
__BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", define = yes, start = $0004, size = $0090 - $0004;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
||||
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__;
|
||||
BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM02: file = "%O.02", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM03ADDR: file = "%O.03", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM03: file = "%O.03", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM04ADDR: file = "%O.04", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM04: file = "%O.04", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM05ADDR: file = "%O.05", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM05: file = "%O.05", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM06ADDR: file = "%O.06", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM06: file = "%O.06", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM07ADDR: file = "%O.07", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM07: file = "%O.07", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM08ADDR: file = "%O.08", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM0AADDR: file = "%O.0a", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM0BADDR: file = "%O.0b", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM0CADDR: file = "%O.0c", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM0DADDR: file = "%O.0d", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM0EADDR: file = "%O.0e", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
BRAM0FADDR: file = "%O.0f", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||
BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
EXTZP: load = ZP, type = zp, optional = yes;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
INIT: load = MAIN, type = rw;
|
||||
ONCE: load = MAIN, type = ro, define = yes;
|
||||
BSS: load = BSS, type = bss, define = yes;
|
||||
BRAM00ADDR: load = BRAM00ADDR, type = ro, optional = yes;
|
||||
BANKRAM00: load = BRAM00, type = rw, define = yes, optional = yes;
|
||||
BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes;
|
||||
BANKRAM01: load = BRAM01, type = rw, define = yes, optional = yes;
|
||||
BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes;
|
||||
BANKRAM02: load = BRAM02, type = rw, define = yes, optional = yes;
|
||||
BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes;
|
||||
BANKRAM03: load = BRAM03, type = rw, define = yes, optional = yes;
|
||||
BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes;
|
||||
BANKRAM04: load = BRAM04, type = rw, define = yes, optional = yes;
|
||||
BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes;
|
||||
BANKRAM05: load = BRAM05, type = rw, define = yes, optional = yes;
|
||||
BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes;
|
||||
BANKRAM06: load = BRAM06, type = rw, define = yes, optional = yes;
|
||||
BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes;
|
||||
BANKRAM07: load = BRAM07, type = rw, define = yes, optional = yes;
|
||||
BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes;
|
||||
BANKRAM08: load = BRAM08, type = rw, define = yes, optional = yes;
|
||||
BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes;
|
||||
BANKRAM09: load = BRAM09, type = rw, define = yes, optional = yes;
|
||||
BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes;
|
||||
BANKRAM0A: load = BRAM0A, type = rw, define = yes, optional = yes;
|
||||
BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes;
|
||||
BANKRAM0B: load = BRAM0B, type = rw, define = yes, optional = yes;
|
||||
BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes;
|
||||
BANKRAM0C: load = BRAM0C, type = rw, define = yes, optional = yes;
|
||||
BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes;
|
||||
BANKRAM0D: load = BRAM0D, type = rw, define = yes, optional = yes;
|
||||
BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes;
|
||||
BANKRAM0E: load = BRAM0E, type = rw, define = yes, optional = yes;
|
||||
BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes;
|
||||
BANKRAM0F: load = BRAM0F, type = rw, define = yes, optional = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
45
cfg/cx16.cfg
Normal file
45
cfg/cx16.cfg
Normal file
@ -0,0 +1,45 @@
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $0801;
|
||||
}
|
||||
SYMBOLS {
|
||||
__LOADADDR__: type = import;
|
||||
__EXEHDR__: type = import;
|
||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||
__HIMEM__: type = weak, value = $9F00;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", define = yes, start = $0004, size = $0090 - $0004;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
||||
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
EXTZP: load = ZP, type = zp, optional = yes;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
INIT: load = MAIN, type = rw;
|
||||
ONCE: load = MAIN, type = ro, define = yes;
|
||||
BSS: load = BSS, type = bss, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
@ -4653,9 +4653,10 @@ compiler, depending on the target system selected:
|
||||
<item><tt/__C128__/ - Target system is <tt/c128/
|
||||
<item><tt/__C16__/ - Target system is <tt/c16/ or <tt/plus4/
|
||||
<item><tt/__C64__/ - Target system is <tt/c64/
|
||||
<item><tt/__CBM__/ - Target is a Commodore system
|
||||
<item><tt/__CBM__/ - Target is a Commodore or Commodore-alike system
|
||||
<item><tt/__CBM510__/ - Target system is <tt/cbm510/
|
||||
<item><tt/__CBM610__/ - Target system is <tt/cbm610/
|
||||
<item><tt/__CX16__/ - Target system is <tt/cx16/
|
||||
<item><tt/__GEOS__/ - Target is a GEOS system
|
||||
<item><tt/__GEOS_APPLE__/ - Target system is <tt/geos-apple/
|
||||
<item><tt/__GEOS_CBM__/ - Target system is <tt/geos-cbm/
|
||||
|
@ -901,6 +901,10 @@ The compiler defines several macros at startup:
|
||||
<item><tt/__CC65_STD_CC65__/
|
||||
</itemize>
|
||||
|
||||
<tag><tt>__CX16__</tt></tag>
|
||||
|
||||
This macro is defined if the target is the Commander X16 (-t cx16).
|
||||
|
||||
<tag><tt>__DATE__</tt></tag>
|
||||
|
||||
This macro expands to the date of translation of the preprocessing
|
||||
|
311
doc/cx16.sgml
Normal file
311
doc/cx16.sgml
Normal file
@ -0,0 +1,311 @@
|
||||
<!doctype linuxdoc system>
|
||||
|
||||
<article>
|
||||
<title>Commander X16-specific information for cc65
|
||||
<author><url url="mailto:greg.king5@verizon.net" name="Greg King">
|
||||
|
||||
<abstract>
|
||||
An overview over the CX16 run-time system as it's implemented for the cc65 C
|
||||
compiler.
|
||||
</abstract>
|
||||
|
||||
<!-- Table of contents -->
|
||||
<toc>
|
||||
|
||||
<!-- Begin the document -->
|
||||
|
||||
<sect>Overview<p>
|
||||
|
||||
The Commander X16 is a modern small computer with firmware that is based on
|
||||
the ROMs in Commodore's VIC-20 and 64C. It has a couple of the I/O chips that
|
||||
are in the VIC-20.
|
||||
|
||||
This file contains an overview of the CX16 run-time system as it comes with the
|
||||
cc65 C compiler. It describes the memory layout, CX16-specific header files,
|
||||
available drivers, and any pitfalls specific to that platform.
|
||||
|
||||
Please note that CX16-specific functions just are mentioned here; they are
|
||||
described in detail in the separate <url url="funcref.html" name="function
|
||||
reference">. Even functions marked as "platform dependent" may be available on
|
||||
more than one platform. Please see the function reference for more
|
||||
information.
|
||||
|
||||
|
||||
|
||||
<sect>Binary format<p>
|
||||
|
||||
The standard binary output format generated by the linker for the CX16 target
|
||||
is a machine language program with a one-line BASIC stub which calls the
|
||||
machine language part via SYS. That means that a program can be loaded as a
|
||||
BASIC program, and started with RUN. It is, of course, possible to change that
|
||||
behaviour by using a modified start-up file and linker config.
|
||||
|
||||
|
||||
|
||||
<sect>Memory layout<p>
|
||||
|
||||
cc65-generated programs with the default setup run with the I/O area and the
|
||||
Kernal ROM visible. That means that Kernal entry points can be called directly.
|
||||
The usable memory ranges are $0800 - $9EFF and $A000 -
|
||||
$BFFF.
|
||||
|
||||
Special locations:
|
||||
|
||||
<descrip>
|
||||
<tag/Stack/
|
||||
The C run-time stack is located at $9EFF, and grows downward.
|
||||
|
||||
<tag/Heap/
|
||||
The C heap is located at the end of the program, and grows toward the C
|
||||
run-time stack.
|
||||
|
||||
<tag/Bank RAM/
|
||||
Bank RAM is located at $A000 - $BFFF. It's an eight-Kibibyte
|
||||
window into a half Mibibyte or two Mibibytes of banked RAM.
|
||||
|
||||
<tag/Bank ROM/
|
||||
Bank ROM is located at $C000 - $FFFF. It's a sixteen-Kibibyte
|
||||
window into 128 Kibibytes of banked ROM.
|
||||
</descrip><p>
|
||||
|
||||
|
||||
|
||||
<sect>Linker configurations<p>
|
||||
|
||||
The ld65 linker comes with a default config. file for the Commander X16, which
|
||||
is used via <tt/-t cx16/. The cx16 package comes with additional secondary
|
||||
linker config. files which are used via <tt/-t cx16 -C <configfile>/.
|
||||
|
||||
|
||||
<sect1>Default config. file (<tt/cx16.cfg/)<p>
|
||||
|
||||
The default configuration is tailored to C programs. It supplies the load
|
||||
address and a small BASIC stub that starts the compiled program using a SYS
|
||||
command.
|
||||
|
||||
|
||||
<sect1><tt/cx16-asm.cfg/<p>
|
||||
|
||||
This configuration is made for Assembly programmers who don't need a special
|
||||
setup. The default start address is $0801. It can be changed with the
|
||||
linker command-line option <tt/--start-addr/ or <tt/-S/. All standard segments,
|
||||
with the exception of <tt/ZEROPAGE/, are written to the output file;
|
||||
and, a two-byte load address is prepended.
|
||||
|
||||
To use that config. file, assemble with <tt/-t cx16/, and link with <tt/-C
|
||||
cx16-asm.cfg/. The former will make sure that the correct character
|
||||
translations are in effect, while the latter supplies the actual config.
|
||||
When using <tt/cl65/, use both command-line options.
|
||||
|
||||
Sample command line for <tt/cl65/:
|
||||
<tscreen><verb>
|
||||
cl65 -o file.prg -t cx16 -C cx16-asm.cfg source.s
|
||||
</verb></tscreen>
|
||||
|
||||
To generate code that loads to $A000:
|
||||
<tscreen><verb>
|
||||
cl65 -o file.prg -Wl -S,$A000 -t cX16 -C cX16-asm.cfg source.s
|
||||
</verb></tscreen>
|
||||
|
||||
It also is possible to add a small BASIC header to the program, that uses SYS
|
||||
to jump to the program entry point (which is the start of the code segment).
|
||||
The advantage is that the program can be started using RUN.
|
||||
|
||||
To generate a program with a BASIC SYS header, use
|
||||
<tscreen><verb>
|
||||
cl65 -o file.prg -u __EXEHDR__ -t cx16 -C cx16-asm.cfg source.s
|
||||
</verb></tscreen>
|
||||
|
||||
Please note that, in this case, a changed start address doesn't make sense,
|
||||
because the program must be loaded to BASIC's start address.
|
||||
|
||||
|
||||
|
||||
<sect>Platform-specific header files<p>
|
||||
|
||||
Programs containing CX16-specific code may use the <tt/cx16.h/ or <tt/cbm.h/
|
||||
header files. Using the later may be an option when writing code for more than
|
||||
one CBM-like platform, because it includes <tt/cx16.h/, and declares several
|
||||
functions common to all CBM-like platforms.
|
||||
|
||||
|
||||
<sect1>CX16-specific functions<p>
|
||||
|
||||
The functions listed below are special for the CX16. See the <url
|
||||
url="funcref.html" name="function reference"> for declarations and usage.
|
||||
|
||||
<itemize>
|
||||
<item>get_ostype()
|
||||
<item>set_tv()
|
||||
<item>videomode()
|
||||
<item>waitvsync()
|
||||
</itemize>
|
||||
|
||||
|
||||
<sect1>CBM-specific functions<p>
|
||||
|
||||
Some functions are available for all (or, at least most) of the Commodore-like
|
||||
machines. See the <url url="funcref.html" name="function reference"> for
|
||||
declarations and usage.
|
||||
|
||||
<itemize>
|
||||
<item>cbm_close()
|
||||
<item>cbm_closedir()
|
||||
<item>cbm_k_basin()
|
||||
<item>cbm_k_bsout()
|
||||
<item>cbm_k_chkin()
|
||||
<item>cbm_k_ckout()
|
||||
<item>cbm_k_close()
|
||||
<item>cbm_k_clrch()
|
||||
<item>cbm_k_load()
|
||||
<item>cbm_k_open()
|
||||
<item>cbm_k_readst()
|
||||
<item>cbm_k_save()
|
||||
<item>cbm_k_second()
|
||||
<item>cbm_k_setlfs()
|
||||
<item>cbm_k_setnam()
|
||||
<item>cbm_k_tksa()
|
||||
<item>cbm_load()
|
||||
<item>cbm_open()
|
||||
<item>cbm_opendir()
|
||||
<item>cbm_read()
|
||||
<item>cbm_readdir()
|
||||
<item>cbm_save()
|
||||
<item>cbm_write()
|
||||
<item>get_tv()
|
||||
</itemize>
|
||||
|
||||
|
||||
<sect1>Hardware access<p>
|
||||
|
||||
The following pseudo variables declared in the <tt/cx16.h/ header file do allow
|
||||
access to hardware located in the address space. Some variables are
|
||||
structures, accessing the struct fields will access the chip registers.
|
||||
|
||||
<descrip>
|
||||
<tag><tt/VERA/</tag>
|
||||
The <tt/VERA/ structure allows access
|
||||
to the Video Enhanced Retro Adapter chip.
|
||||
|
||||
<tag><tt/VIA1, VIA2/</tag>
|
||||
Access to the two VIA (Versatile Interface Adapter) chips is available via
|
||||
the <tt/VIA1/ and <tt/VIA2/ variables. The structure behind those variables
|
||||
is explained in <tt/_6522.h/.
|
||||
|
||||
<tag><tt/BANK_RAM/</tag>
|
||||
A character array that mirrors the eight-Kibibyte window, at $A000,
|
||||
into banked RAM.
|
||||
</descrip><p>
|
||||
|
||||
|
||||
|
||||
<sect>Loadable drivers<p>
|
||||
|
||||
The names in the parentheses denote the symbols to be used for static linking of the drivers.
|
||||
|
||||
|
||||
<sect1>Graphics drivers<p>
|
||||
|
||||
No graphics drivers are available currently for the CX16.
|
||||
|
||||
|
||||
<sect1>Extended memory drivers<p>
|
||||
|
||||
No extended memory drivers are available currently for the CX16.
|
||||
|
||||
|
||||
<sect1>Joystick drivers<p>
|
||||
|
||||
The default drivers, <tt/joy_stddrv (joy_static_stddrv)/,
|
||||
point to <tt/cX16-stdjoy.joy (cx16_stdjoy_joy)/.
|
||||
|
||||
<descrip>
|
||||
<tag><tt/cX16-stdjoy.joy (cX16_stdjoy_joy)/</tag>
|
||||
Supports up to two NES and SNES controllers connected to the joystick ports
|
||||
of the CX16. It reads the four directions, and the A, B, Select, and Start
|
||||
buttons. Button A is the primary fire button.
|
||||
</descrip><p>
|
||||
|
||||
|
||||
<sect1>Mouse drivers<p>
|
||||
|
||||
No mouse drivers are available currently for the CX16.
|
||||
|
||||
|
||||
<sect1>RS232 device drivers<p>
|
||||
|
||||
No serial drivers are available currently for the CX16.
|
||||
|
||||
|
||||
|
||||
<sect>Limitations<p>
|
||||
|
||||
The Commander X16 still is being designed. It's configuration can change at
|
||||
any time. Some changes could make old programs fail to work.
|
||||
|
||||
|
||||
|
||||
<sect>Other hints<p>
|
||||
|
||||
|
||||
<sect1>Escape code<p>
|
||||
|
||||
For an Esc, press <tt/Ctrl/ and the <tt/[/ key.
|
||||
|
||||
|
||||
<sect1>Passing arguments to the program<p>
|
||||
|
||||
Command-line arguments can be passed to <tt/main()/. Because that is not
|
||||
supported directly by BASIC, the following syntax was chosen:
|
||||
<tscreen><verb>
|
||||
RUN:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5
|
||||
</verb></tscreen>
|
||||
|
||||
<enum>
|
||||
<item>Arguments are separated by spaces.
|
||||
<item>Arguments may be quoted.
|
||||
<item>Leading and trailing spaces around an argument are ignored. Spaces within
|
||||
a quoted argument are allowed.
|
||||
<item>The first argument passed to <tt/main()/ is the program name.
|
||||
<item>A maximum number of 10 arguments (including the program name) are
|
||||
supported.
|
||||
</enum>
|
||||
|
||||
|
||||
<sect1>Program return code<p>
|
||||
|
||||
The program return code (low byte) is passed back to BASIC by use of the
|
||||
<tt/ST/ variable.
|
||||
|
||||
|
||||
<sect1>Interrupts<p>
|
||||
|
||||
The run-time for the CX16 uses routines marked as <tt/.INTERRUPTOR/ for
|
||||
interrupt handlers. Such routines must be written as simple machine language
|
||||
subroutines, and will be called automatically by the interrupt handler code
|
||||
if they are linked into a program. See the discussion of the <tt/.CONDES/
|
||||
feature in the <url url="ca65.html" name="assembler manual">.
|
||||
|
||||
|
||||
|
||||
<sect>License<p>
|
||||
|
||||
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:
|
||||
<enum>
|
||||
<item> 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.
|
||||
<item> Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
<item> This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
</enum>
|
||||
|
||||
</article>
|
@ -145,6 +145,9 @@
|
||||
<tag><htmlurl url="creativision.html" name="creativision.html"></tag>
|
||||
Topics specific to the Creativision Console.
|
||||
|
||||
<tag><htmlurl url="cx16.html" name="cx16.html"></tag>
|
||||
Topics specific to the Commander X16.
|
||||
|
||||
<tag><htmlurl url="gamate.html" name="gamate.html"></tag>
|
||||
Topics specific to the Bit Corporation Gamate Console.
|
||||
|
||||
|
@ -402,11 +402,36 @@ RUN
|
||||
The emulation, also, supports that method.
|
||||
|
||||
|
||||
<sect1>Commander X16
|
||||
|
||||
<sect2>x16-emulator<p>
|
||||
Available at <url
|
||||
url="https://github.com/commanderx16/x16-emulator/releases">:
|
||||
|
||||
Emulates the Commander X16 Single Board Computer, with sound, SD card images,
|
||||
VGA and NTSC video, and a NES game controller emulation. Includes a monitor.
|
||||
It runs on all SDL2 platforms.
|
||||
|
||||
Compile the tutorial with
|
||||
<tscreen><verb>
|
||||
cl65 -O -t cx16 hello.c text.s
|
||||
</verb></tscreen>
|
||||
|
||||
Start the emulator. Then, type
|
||||
<tscreen><verb>
|
||||
LOAD"HELLO",1
|
||||
RUN
|
||||
</verb></tscreen>
|
||||
(Type those lines in lower-case; but, they will appear as upper-case.)
|
||||
|
||||
On a real computer, you would type an <tt/8/ instead of a <tt/1/.
|
||||
|
||||
|
||||
<sect1>Commodore
|
||||
|
||||
<sect2>VICE<p>
|
||||
Available at <url
|
||||
url="http://vice-emu.sourceforge.net/">:
|
||||
url="https://vice-emu.sourceforge.net/">:
|
||||
|
||||
Emulates Commodore 64/128/VIC-20/PET/CBM II/Plus 4 computers. Supports
|
||||
printers, serial port and adapters, stereo sound, disk drives and images, RAM expansions,
|
||||
|
@ -65,6 +65,8 @@
|
||||
# include <cbm610.h>
|
||||
#elif defined(__PET__) && !defined(_PET_H)
|
||||
# include <pet.h>
|
||||
#elif defined(__CX16__) && !defined(_CX16_H)
|
||||
# include <cx16.h>
|
||||
#endif
|
||||
|
||||
/* Include definitions for CBM file types */
|
||||
@ -300,5 +302,3 @@ void __fastcall__ cbm_closedir (unsigned char lfn);
|
||||
|
||||
/* End of cbm.h */
|
||||
#endif
|
||||
|
||||
|
||||
|
189
include/cx16.h
Normal file
189
include/cx16.h
Normal file
@ -0,0 +1,189 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* cx16.h */
|
||||
/* */
|
||||
/* CX16 system-specific definitions */
|
||||
/* */
|
||||
/* */
|
||||
/* 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 _CX16_H
|
||||
#define _CX16_H
|
||||
|
||||
|
||||
|
||||
/* Check for errors */
|
||||
#ifndef __CX16__
|
||||
# error This module may be used only when compiling for the CX16!
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Additional key defines */
|
||||
#define CH_F1 0x85
|
||||
#define CH_F2 0x89
|
||||
#define CH_F3 0x86
|
||||
#define CH_F4 0x8A
|
||||
#define CH_F5 0x87
|
||||
#define CH_F6 0x8B
|
||||
#define CH_F7 0x88
|
||||
#define CH_F8 0x8C
|
||||
#define CH_F9 0x10
|
||||
#define CH_F10 0x15
|
||||
#define CH_F11 0x16
|
||||
#define CH_F12 0x17
|
||||
|
||||
/* Color defines */
|
||||
#define COLOR_BLACK 0x00
|
||||
#define COLOR_WHITE 0x01
|
||||
#define COLOR_RED 0x02
|
||||
#define COLOR_CYAN 0x03
|
||||
#define COLOR_VIOLET 0x04
|
||||
#define COLOR_PURPLE COLOR_VIOLET
|
||||
#define COLOR_GREEN 0x05
|
||||
#define COLOR_BLUE 0x06
|
||||
#define COLOR_YELLOW 0x07
|
||||
#define COLOR_ORANGE 0x08
|
||||
#define COLOR_BROWN 0x09
|
||||
#define COLOR_LIGHTRED 0x0A
|
||||
#define COLOR_GRAY1 0x0B
|
||||
#define COLOR_GRAY2 0x0C
|
||||
#define COLOR_LIGHTGREEN 0x0D
|
||||
#define COLOR_LIGHTBLUE 0x0E
|
||||
#define COLOR_GRAY3 0x0F
|
||||
|
||||
/* Masks for joy_read() */
|
||||
#define JOY_BTN_1_MASK 0x80
|
||||
#define JOY_BTN_2_MASK 0x40
|
||||
#define JOY_BTN_3_MASK 0x20
|
||||
#define JOY_BTN_4_MASK 0x10
|
||||
#define JOY_UP_MASK 0x08
|
||||
#define JOY_DOWN_MASK 0x04
|
||||
#define JOY_LEFT_MASK 0x02
|
||||
#define JOY_RIGHT_MASK 0x01
|
||||
|
||||
#define JOY_BTN_A_MASK JOY_BTN_1_MASK
|
||||
#define JOY_BTN_B_MASK JOY_BTN_2_MASK
|
||||
#define JOY_SELECT_MASK JOY_BTN_3_MASK
|
||||
#define JOY_START_MASK JOY_BTN_4_MASK
|
||||
|
||||
#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK)
|
||||
#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK)
|
||||
#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK)
|
||||
#define JOY_START(v) ((v) & JOY_START_MASK)
|
||||
|
||||
#define JOY_FIRE2_MASK JOY_BTN_2_MASK
|
||||
#define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK)
|
||||
|
||||
/* get_tv() return codes
|
||||
** set_tv() argument codes
|
||||
*/
|
||||
#define TV_NONE 0
|
||||
#define TV_VGA 1
|
||||
#define TV_NTSC_COLOR 2
|
||||
#define TV_RGB 3
|
||||
#define TV_NONE2 4
|
||||
#define TV_VGA2 5
|
||||
#define TV_NTSC_MONO 6
|
||||
#define TV_RGB2 7
|
||||
|
||||
/* Video mode defines */
|
||||
#define VIDEOMODE_40x30 40u
|
||||
#define VIDEOMODE_80x60 80u
|
||||
#define VIDEOMODE_40COL VIDEOMODE_40x30
|
||||
#define VIDEOMODE_80COL VIDEOMODE_80x60
|
||||
|
||||
|
||||
/* Define hardware */
|
||||
|
||||
/* Define a structure with the Video Enhanced Retro Adapter's
|
||||
** external registers.
|
||||
*/
|
||||
struct __vera {
|
||||
unsigned short address; /* Address for data ports */
|
||||
unsigned char address_hi;
|
||||
unsigned char data0; /* Data port 0 */
|
||||
unsigned char data1; /* Data port 1 */
|
||||
unsigned char control; /* Control register */
|
||||
unsigned char irq_enable; /* Interrupt enable bits */
|
||||
unsigned char irq_flags; /* Interrupt flags */
|
||||
};
|
||||
#define VERA (*(volatile struct __vera *)0x9F20)
|
||||
|
||||
#include <_6522.h>
|
||||
#define VIA1 (*(volatile struct __6522 *)0x9F60)
|
||||
#define VIA2 (*(volatile struct __6522 *)0x9F70)
|
||||
|
||||
/* Define a structure with the x16emu's settings registers. */
|
||||
struct __emul {
|
||||
unsigned char debug; /* Boolean: debugging enabled */
|
||||
unsigned char vera_action; /* Boolean: displaying VERA activity */
|
||||
unsigned char keyboard; /* Boolean: displaying typed keys */
|
||||
unsigned char echo; /* Boolean: Kernal output echoed to host */
|
||||
unsigned char save_on_exit; /* Boolean: save SD card when quitting */
|
||||
unsigned char unused[0xD - 0x5];
|
||||
unsigned char keymap; /* Keyboard layout number */
|
||||
const char detect[2]; /* "16" if running on x16emu */
|
||||
};
|
||||
#define EMULATOR (*(volatile struct __emul)0x9FB0)
|
||||
|
||||
|
||||
|
||||
/* The addresses of the static drivers */
|
||||
|
||||
extern void cx16_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
signed char get_ostype (void);
|
||||
/* Get the ROM build version.
|
||||
** -1 -- custom build
|
||||
** Negative -- prerelease build
|
||||
** Positive -- release build
|
||||
*/
|
||||
|
||||
void __fastcall__ set_tv (unsigned char);
|
||||
/* Set the video mode the machine will use.
|
||||
** Call with a TV_xx constant.
|
||||
*/
|
||||
|
||||
unsigned char __fastcall__ videomode (unsigned char Mode);
|
||||
/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx
|
||||
** constants.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* End of cX16.h */
|
||||
#endif
|
@ -7,6 +7,7 @@ CBMS = c128 \
|
||||
c64 \
|
||||
cbm510 \
|
||||
cbm610 \
|
||||
cx16 \
|
||||
pet \
|
||||
plus4 \
|
||||
vic20
|
||||
|
14
libsrc/cx16/_scrsize.s
Normal file
14
libsrc/cx16/_scrsize.s
Normal file
@ -0,0 +1,14 @@
|
||||
;
|
||||
; 2019-09-16, Greg King
|
||||
;
|
||||
; Screen size info
|
||||
;
|
||||
|
||||
.export screensize
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
screensize:
|
||||
ldx LLEN
|
||||
ldy NLINES
|
||||
rts
|
50
libsrc/cx16/bankramaddr.s
Normal file
50
libsrc/cx16/bankramaddr.s
Normal file
@ -0,0 +1,50 @@
|
||||
;
|
||||
; 2019-09-16, Greg King
|
||||
;
|
||||
; This module supplies the load addresses that are expected
|
||||
; by a Commander X16 in the first two bytes of banked RAM load files.
|
||||
;
|
||||
|
||||
; The following symbol is used by a linker config. to force
|
||||
; this module to get included into the output files.
|
||||
.export __BANKRAMADDR__: abs = 1
|
||||
|
||||
.segment "BRAM00ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM01ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM02ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM03ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM04ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM05ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM06ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM07ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM08ADDR"
|
||||
|
||||
.addr *+2
|
||||
|
||||
.segment "BRAM09ADDR"
|
||||
|
||||
.addr *+2
|
27
libsrc/cx16/bordercolor.s
Normal file
27
libsrc/cx16/bordercolor.s
Normal file
@ -0,0 +1,27 @@
|
||||
;
|
||||
; 2019-09-23, Greg King
|
||||
;
|
||||
; unsigned char __fastcall__ bordercolor (unsigned char color);
|
||||
; /* Set the color for the border. The old color setting is returned. */
|
||||
;
|
||||
|
||||
.export _bordercolor
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
_bordercolor:
|
||||
tax
|
||||
|
||||
; Point to the border color register.
|
||||
|
||||
stz VERA::CTRL ; Use port 0
|
||||
lda #<VERA::COMPOSER::FRAME
|
||||
sta VERA::ADDR
|
||||
lda #>VERA::COMPOSER::FRAME
|
||||
sta VERA::ADDR+1
|
||||
ldy #^VERA::COMPOSER::FRAME | VERA::INC0
|
||||
sty VERA::ADDR+2
|
||||
|
||||
lda VERA::DATA0 ; get old value
|
||||
stx VERA::DATA0 ; set new value
|
||||
rts
|
109
libsrc/cx16/break.s
Normal file
109
libsrc/cx16/break.s
Normal file
@ -0,0 +1,109 @@
|
||||
;
|
||||
; 1998-09-27, Ullrich von Bassewitz
|
||||
; 2019-09-08, Greg King
|
||||
;
|
||||
; void __fastcall__ 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 "cx16.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
|
||||
|
||||
|
72
libsrc/cx16/cgetc.s
Normal file
72
libsrc/cx16/cgetc.s
Normal file
@ -0,0 +1,72 @@
|
||||
;
|
||||
; 2019-09-23, Greg King
|
||||
;
|
||||
; char cgetc (void);
|
||||
; /* Return a character from the keyboard. */
|
||||
;
|
||||
|
||||
.export _cgetc
|
||||
|
||||
.import cursor, GETIN
|
||||
|
||||
.include "cx16.inc"
|
||||
.macpack generic
|
||||
|
||||
|
||||
_cgetc: ldx KEY_COUNT ; Get number of characters
|
||||
bnz L3 ; Jump if there are already chars waiting
|
||||
|
||||
; Switch the cursor on if wanted.
|
||||
|
||||
lda CURS_FLAG ; Save cursor's current enable flag
|
||||
tay
|
||||
lda cursor
|
||||
jsr setcursor
|
||||
L1: lda KEY_COUNT
|
||||
bze L1 ; Wait for key
|
||||
tya
|
||||
eor #%00000001 ; (Cursor flag uses negative logic)
|
||||
jsr setcursor ; Restore previous cursor condition
|
||||
|
||||
; An internal Kernal function can't be used because it might be moved in future
|
||||
; revisions. Use an official function; but, make sure that it reads
|
||||
; the keyboard.
|
||||
|
||||
L3: ldy IN_DEV ; Save current input device
|
||||
stz IN_DEV ; Keyboard
|
||||
jsr GETIN ; Read char, and return in .A
|
||||
sty IN_DEV ; Restore input device
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
; Switch the cursor on or off.
|
||||
|
||||
setcursor:
|
||||
tax ; On or off?
|
||||
bnz seton ; Go set it on
|
||||
lda CURS_FLAG ; Is the cursor currently off?
|
||||
bnz crs9 ; Jump if yes
|
||||
inc CURS_FLAG ; Mark it as off
|
||||
ldx CURS_STATE ; Cursor currently displayed?
|
||||
bze crs9 ; Jump if not
|
||||
|
||||
; Restore the current character in video RAM.
|
||||
; Restore that character's colors.
|
||||
|
||||
stz VERA::CTRL ; Use port 0
|
||||
lda CURS_Y
|
||||
sta VERA::ADDR+1 ; Set row number
|
||||
lda #VERA::INC1 ; Increment address by one
|
||||
sta VERA::ADDR+2
|
||||
lda CURS_X ; Get character column
|
||||
asl a
|
||||
sta VERA::ADDR
|
||||
ldx CURS_CHAR
|
||||
stx VERA::DATA0
|
||||
ldx CURS_COLOR
|
||||
stx VERA::DATA0
|
||||
stz CURS_STATE ; Cursor not displayed
|
||||
crs9: rts
|
||||
|
||||
seton: stz CURS_FLAG
|
||||
rts
|
26
libsrc/cx16/clrscr.s
Normal file
26
libsrc/cx16/clrscr.s
Normal file
@ -0,0 +1,26 @@
|
||||
;
|
||||
; 2019-09-22, Greg King
|
||||
;
|
||||
; void clrscr (void);
|
||||
; /* Clear the screen. */
|
||||
;
|
||||
|
||||
.export _clrscr
|
||||
|
||||
.import CHROUT
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
; An internal Kernal function can't be used because it might be moved in future
|
||||
; revisions. Use an official function; but, make sure that it prints
|
||||
; to the screen.
|
||||
|
||||
_clrscr:
|
||||
ldy OUT_DEV ; Save current output device
|
||||
ldx #$03 ; Screen device
|
||||
stx OUT_DEV
|
||||
lda #$93
|
||||
jsr CHROUT ; Print clear-screen character
|
||||
sty OUT_DEV ; Restore output device
|
||||
rts
|
43
libsrc/cx16/color.s
Normal file
43
libsrc/cx16/color.s
Normal file
@ -0,0 +1,43 @@
|
||||
;
|
||||
; 2019-09-16, Greg King
|
||||
;
|
||||
; unsigned char __fastcall__ textcolor (unsigned char color);
|
||||
; unsigned char __fastcall__ bgcolor (unsigned char color);
|
||||
;
|
||||
|
||||
|
||||
.export _textcolor, _bgcolor
|
||||
|
||||
.importzp tmp1
|
||||
.include "cx16.inc"
|
||||
|
||||
_textcolor:
|
||||
and #$0F
|
||||
sta tmp1
|
||||
ldx CHARCOLOR ; get old values
|
||||
txa
|
||||
and #<~$0F ; keep screen color, remove text color
|
||||
ora tmp1
|
||||
sta CHARCOLOR ; set new values
|
||||
txa
|
||||
and #$0F
|
||||
rts
|
||||
|
||||
|
||||
_bgcolor:
|
||||
asl a ; move number to screen-color nybble
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
sta tmp1
|
||||
ldx CHARCOLOR ; get old values
|
||||
txa
|
||||
and #<~$F0 ; remove screen color, keep text color
|
||||
ora tmp1
|
||||
sta CHARCOLOR ; set new values
|
||||
txa
|
||||
lsr a ; get screen color
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
rts
|
9
libsrc/cx16/conio.s
Normal file
9
libsrc/cx16/conio.s
Normal file
@ -0,0 +1,9 @@
|
||||
;
|
||||
; 2019-09-23, Greg King
|
||||
;
|
||||
; Low-level stuff for screen output/console input
|
||||
;
|
||||
|
||||
.exportzp CURS_X, CURS_Y
|
||||
|
||||
.include "cx16.inc"
|
48
libsrc/cx16/cpeekc.s
Normal file
48
libsrc/cx16/cpeekc.s
Normal file
@ -0,0 +1,48 @@
|
||||
;
|
||||
; 2016-02-28, Groepaz
|
||||
; 2019-09-25, Greg King
|
||||
;
|
||||
; char cpeekc (void);
|
||||
; /* Return the character from the current cursor position. */
|
||||
;
|
||||
|
||||
.export _cpeekc
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
_cpeekc:
|
||||
php
|
||||
sei ; don't let cursor blinking interfere
|
||||
stz VERA::CTRL ; use port 0
|
||||
lda CURS_Y
|
||||
sta VERA::ADDR+1 ; set row number
|
||||
stz VERA::ADDR+2
|
||||
lda CURS_X ; get character column
|
||||
asl a
|
||||
sta VERA::ADDR
|
||||
lda VERA::DATA0 ; get screen code
|
||||
plp
|
||||
ldx #>$0000
|
||||
and #<~%10000000 ; remove reverse bit
|
||||
|
||||
; Convert the screen code into a PetSCII code.
|
||||
; $00 - $1F: +$40
|
||||
; $20 - $3F
|
||||
; $40 - $5f: +$20
|
||||
; $60 - $7F: +$40
|
||||
|
||||
cmp #$20
|
||||
bcs @sk1 ;(bge)
|
||||
ora #$40
|
||||
rts
|
||||
|
||||
@sk1: cmp #$40
|
||||
bcc @end ;(blt)
|
||||
cmp #$60
|
||||
bcc @sk2 ;(blt)
|
||||
;sec
|
||||
adc #$20 - $01
|
||||
@sk2: ;clc ; both above cmp and adc clear carry flag
|
||||
adc #$20
|
||||
@end: rts
|
27
libsrc/cx16/cpeekcolor.s
Normal file
27
libsrc/cx16/cpeekcolor.s
Normal file
@ -0,0 +1,27 @@
|
||||
;
|
||||
; 2019-09-25, Greg King
|
||||
;
|
||||
; unsigned char cpeekcolor (void);
|
||||
; /* Return the colors from the current cursor position. */
|
||||
;
|
||||
|
||||
.export _cpeekcolor
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
_cpeekcolor:
|
||||
php
|
||||
sei ; don't let cursor blinking interfere
|
||||
stz VERA::CTRL ; use port 0
|
||||
lda CURS_Y
|
||||
sta VERA::ADDR+1 ; set row number
|
||||
stz VERA::ADDR+2
|
||||
lda CURS_X ; get character column
|
||||
sec ; color attribute is second byte
|
||||
rol a
|
||||
sta VERA::ADDR
|
||||
lda VERA::DATA0 ; get color
|
||||
plp
|
||||
ldx #>$0000
|
||||
rts
|
32
libsrc/cx16/cpeekrevers.s
Normal file
32
libsrc/cx16/cpeekrevers.s
Normal file
@ -0,0 +1,32 @@
|
||||
;
|
||||
; 2016-02-28, Groepaz
|
||||
; 2019-09-25, Greg King
|
||||
;
|
||||
; unsigned char cpeekrevers (void);
|
||||
; /* Return the reverse attribute from the current cursor position.
|
||||
; ** If the character is reversed, then return 1; return 0 otherwise.
|
||||
; */
|
||||
;
|
||||
|
||||
.export _cpeekrevers
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
_cpeekrevers:
|
||||
php
|
||||
sei ; don't let cursor blinking interfere
|
||||
stz VERA::CTRL ; use port 0
|
||||
lda CURS_Y
|
||||
sta VERA::ADDR+1 ; set row number
|
||||
stz VERA::ADDR+2
|
||||
lda CURS_X ; get character column
|
||||
asl a
|
||||
sta VERA::ADDR
|
||||
lda VERA::DATA0 ; get screen code
|
||||
plp
|
||||
and #%10000000 ; get reverse bit
|
||||
asl a
|
||||
tax ; ldx #>$0000
|
||||
rol a ; return boolean value
|
||||
rts
|
0
libsrc/cx16/cpeeks.s
Normal file
0
libsrc/cx16/cpeeks.s
Normal file
98
libsrc/cx16/cputc.s
Normal file
98
libsrc/cx16/cputc.s
Normal file
@ -0,0 +1,98 @@
|
||||
;
|
||||
; 2019-09-23, Greg King
|
||||
;
|
||||
; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c);
|
||||
; void __fastcall__ cputc (char c);
|
||||
;
|
||||
|
||||
.export _cputcxy, _cputc, cputdirect, putchar
|
||||
.export newline, plot
|
||||
|
||||
.import gotoxy, PLOT
|
||||
|
||||
.include "cx16.inc"
|
||||
.macpack generic
|
||||
|
||||
|
||||
; First, move to a new position.
|
||||
|
||||
_cputcxy:
|
||||
pha ; Save C
|
||||
jsr gotoxy ; Set cursor, drop x and y
|
||||
pla ; Restore C
|
||||
|
||||
; Print a character.
|
||||
|
||||
_cputc: cmp #$0D ; LF?
|
||||
beq newline
|
||||
cmp #$0A ; CR?
|
||||
beq plotx0
|
||||
|
||||
; Printable char of some sort
|
||||
|
||||
cmp #' '
|
||||
blt cputdirect ; Other control char
|
||||
tay
|
||||
bmi L10
|
||||
cmp #$60
|
||||
blt L2
|
||||
and #<~%00100000
|
||||
bra cputdirect
|
||||
|
||||
; Handle character if high bit set
|
||||
|
||||
L10: and #<~%10000000 ; Remove high bit
|
||||
ora #%01000000
|
||||
bra cputdirect
|
||||
|
||||
L2: and #<~%01000000
|
||||
|
||||
cputdirect:
|
||||
jsr putchar ; Write character to screen, return .Y
|
||||
|
||||
; Advance cursor position.
|
||||
|
||||
iny
|
||||
cpy LLEN ; Reached end of line?
|
||||
bne L3
|
||||
jsr newline ; Next line
|
||||
ldy #$00 ; + CR
|
||||
L3: sty CURS_X
|
||||
rts
|
||||
|
||||
; Move down.
|
||||
|
||||
newline:
|
||||
inc SCREEN_PTR+1
|
||||
inc CURS_Y
|
||||
rts
|
||||
|
||||
|
||||
; Set the cursor's position, calculate RAM pointer.
|
||||
|
||||
plotx0: stz CURS_X
|
||||
plot: ldy CURS_X
|
||||
ldx CURS_Y
|
||||
clc
|
||||
jmp PLOT ; Set the new cursor
|
||||
|
||||
|
||||
; Write one screen-code and color to the video RAM without doing anything else.
|
||||
; Return the x position in Y.
|
||||
|
||||
putchar:
|
||||
ora RVS ; Set revers bit
|
||||
tax
|
||||
stz VERA::CTRL ; Use port 0
|
||||
lda CURS_Y
|
||||
sta VERA::ADDR+1 ; Set row number
|
||||
lda #VERA::INC1 ; Increment address by one
|
||||
sta VERA::ADDR+2
|
||||
ldy CURS_X ; Get character column
|
||||
tya
|
||||
asl a
|
||||
sta VERA::ADDR
|
||||
stx VERA::DATA0
|
||||
lda CHARCOLOR
|
||||
sta VERA::DATA0
|
||||
rts
|
115
libsrc/cx16/crt0.s
Normal file
115
libsrc/cx16/crt0.s
Normal file
@ -0,0 +1,115 @@
|
||||
;
|
||||
; Start-up code for cc65 (CX16 version)
|
||||
;
|
||||
|
||||
.export _exit
|
||||
.export __STARTUP__ : absolute = 1 ; Mark as start-up
|
||||
|
||||
.import initlib, donelib
|
||||
.import zerobss, callmain
|
||||
.import BSOUT
|
||||
.import __MAIN_START__, __MAIN_SIZE__ ; Linker-generated
|
||||
.importzp ST
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Start-up code
|
||||
|
||||
.segment "STARTUP"
|
||||
|
||||
Start: tsx
|
||||
stx spsave ; Save the system stack ptr
|
||||
|
||||
; Save space by putting some of the start-up code in the ONCE segment,
|
||||
; which will be re-used by the BSS segment, the heap, and the C stack.
|
||||
|
||||
jsr init
|
||||
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Back from main() [this is also the exit() entry]. Run the module destructors.
|
||||
|
||||
_exit: pha ; Save the return code on stack
|
||||
jsr donelib
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
|
||||
ldx #zpspace-1
|
||||
L2: lda zpsave,x
|
||||
sta sp,x
|
||||
dex
|
||||
bpl L2
|
||||
|
||||
; Place the program return code into BASIC's status variable.
|
||||
|
||||
pla
|
||||
sta ST
|
||||
|
||||
; Restore the system stuff.
|
||||
|
||||
ldx spsave
|
||||
txs ; Restore stack pointer
|
||||
ldx banksave
|
||||
stx VIA1::PRA2 ; Restore former RAM bank
|
||||
|
||||
; Back to BASIC.
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
init:
|
||||
|
||||
; Change to the first RAM bank.
|
||||
|
||||
lda VIA1::PRA2
|
||||
sta banksave ; Save the current bank number
|
||||
lda #$00 ; Choose RAM bank zero
|
||||
sta VIA1::PRA2
|
||||
|
||||
; Save the zero-page locations that we need.
|
||||
|
||||
ldx #zpspace-1
|
||||
L1: lda sp,x
|
||||
sta zpsave,x
|
||||
dex
|
||||
bpl L1
|
||||
|
||||
; Set up the stack.
|
||||
|
||||
lda #<(__MAIN_START__ + __MAIN_SIZE__)
|
||||
ldx #>(__MAIN_START__ + __MAIN_SIZE__)
|
||||
sta sp
|
||||
stx sp+1 ; Set argument stack ptr
|
||||
|
||||
; Switch to the second charset.
|
||||
|
||||
lda #$0E
|
||||
jsr BSOUT
|
||||
|
||||
; Call the module constructors.
|
||||
|
||||
jmp initlib
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
banksave:
|
||||
.res 1
|
||||
spsave: .res 1
|
||||
zpsave: .res zpspace
|
8
libsrc/cx16/devnum.s
Normal file
8
libsrc/cx16/devnum.s
Normal file
@ -0,0 +1,8 @@
|
||||
;
|
||||
; 2010-02-14, Oliver Schmidt
|
||||
; 2019-09-08, Greg King
|
||||
;
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
.exportzp devnum := DEVNUM
|
20
libsrc/cx16/get_ostype.s
Normal file
20
libsrc/cx16/get_ostype.s
Normal file
@ -0,0 +1,20 @@
|
||||
;
|
||||
; 2019-09-09, Greg King
|
||||
;
|
||||
; signed char get_ostype(void)
|
||||
; /* Return a "build version". */
|
||||
;
|
||||
; Positive number -- release build
|
||||
; Negative number -- prerelease build
|
||||
; -1 -- custom build
|
||||
;
|
||||
|
||||
.export _get_ostype
|
||||
|
||||
.proc _get_ostype
|
||||
ldx #>$0000
|
||||
lda $ff80
|
||||
bpl :+
|
||||
dex ; negative
|
||||
: rts
|
||||
.endproc
|
31
libsrc/cx16/get_tv.s
Normal file
31
libsrc/cx16/get_tv.s
Normal file
@ -0,0 +1,31 @@
|
||||
;
|
||||
; 2019-09-20, Greg King
|
||||
;
|
||||
; unsigned char get_tv (void);
|
||||
; /* Return the video mode the machine is using. */
|
||||
;
|
||||
|
||||
.export _get_tv
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
.proc _get_tv
|
||||
php
|
||||
sei ; Don't let interrupts interfere
|
||||
|
||||
; Point to the video output register.
|
||||
|
||||
stz VERA::CTRL ; Use port 0
|
||||
lda #<VERA::COMPOSER::VIDEO
|
||||
ldx #>VERA::COMPOSER::VIDEO
|
||||
ldy #^VERA::COMPOSER::VIDEO
|
||||
sta VERA::ADDR
|
||||
stx VERA::ADDR+1
|
||||
sty VERA::ADDR+2
|
||||
|
||||
lda VERA::DATA0
|
||||
plp ; Re-enable interrupts
|
||||
and #$07 ; Get the type of output signal
|
||||
rts
|
||||
.endproc
|
48
libsrc/cx16/irq.s
Normal file
48
libsrc/cx16/irq.s
Normal file
@ -0,0 +1,48 @@
|
||||
;
|
||||
; IRQ handling (CX16 version)
|
||||
;
|
||||
|
||||
.export initirq, doneirq
|
||||
.import callirq
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
initirq:
|
||||
lda IRQVec
|
||||
ldx IRQVec+1
|
||||
sta IRQInd+1
|
||||
stx IRQInd+2
|
||||
lda #<IRQStub
|
||||
ldx #>IRQStub
|
||||
jmp setvec
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
doneirq:
|
||||
lda IRQInd+1
|
||||
ldx IRQInd+2
|
||||
setvec: sei
|
||||
sta IRQVec
|
||||
stx IRQVec+1
|
||||
cli
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
IRQStub:
|
||||
jsr callirq ; Call the functions
|
||||
jmp IRQInd ; Jump to the saved IRQ vector
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
IRQInd: jmp $0000
|
119
libsrc/cx16/joy/cx16-stdjoy.s
Normal file
119
libsrc/cx16/joy/cx16-stdjoy.s
Normal file
@ -0,0 +1,119 @@
|
||||
;
|
||||
; Standard joystick driver for the CX16.
|
||||
; May be used multiple times when statically linked to the application.
|
||||
;
|
||||
; 2019-09-23, Greg King
|
||||
;
|
||||
|
||||
.include "joy-kernel.inc"
|
||||
.include "joy-error.inc"
|
||||
|
||||
.include "cbm_kernal.inc"
|
||||
.include "cx16.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
module_header _cx16_stdjoy_joy
|
||||
|
||||
; Driver signature
|
||||
|
||||
.byte $6A, $6F, $79 ; ASCII "joy"
|
||||
.byte JOY_API_VERSION ; Driver API version number
|
||||
|
||||
; Library reference
|
||||
|
||||
.addr $0000
|
||||
|
||||
; Jump table.
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr COUNT
|
||||
.addr READ
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Constant
|
||||
|
||||
JOY_COUNT = 2 ; Number of joysticks we support
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Data.
|
||||
|
||||
|
||||
.code
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; INSTALL routine. Is called after the driver is loaded into memory.
|
||||
; If possible, check if the hardware is present, and determine the amount
|
||||
; of memory available.
|
||||
; Must return a JOY_ERR_xx code in a/x.
|
||||
;
|
||||
|
||||
INSTALL:
|
||||
lda #<JOY_ERR_OK
|
||||
ldx #>JOY_ERR_OK
|
||||
; rts ; Run into UNINSTALL instead
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
; Can do clean-up or whatever. Must not return anything.
|
||||
;
|
||||
|
||||
UNINSTALL:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; COUNT: Return the total number of possible joysticks in a/x.
|
||||
;
|
||||
|
||||
COUNT: lda #<JOY_COUNT
|
||||
ldx #>JOY_COUNT
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; READ: Read a particular joystick passed in A.
|
||||
;
|
||||
; TODO: Find a way to report the SNES controller's extra four lines.
|
||||
;
|
||||
|
||||
READ: pha
|
||||
jsr GETJOY
|
||||
pla
|
||||
bne pad2
|
||||
|
||||
; Read game pad 1
|
||||
|
||||
pad1: lda JOY1 + 1
|
||||
bit #%00001110
|
||||
beq nes1
|
||||
asl JOY1 ; Get SNES's B button
|
||||
ror a ; Put it next to the A button
|
||||
asl JOY1 ; Drop SNES's Y button
|
||||
asl a ; Get the B button
|
||||
ror JOY1
|
||||
asl a ; Get SNES's A button
|
||||
ror JOY1 ; Make byte look like NES pad
|
||||
nes1: lda JOY1
|
||||
eor #%11111111 ; We don't want the pad's negative logic
|
||||
rts
|
||||
|
||||
; Read game pad 2
|
||||
|
||||
pad2: lda JOY2 + 1
|
||||
bit #%00001110
|
||||
beq nes2
|
||||
asl JOY2
|
||||
ror a
|
||||
asl JOY2
|
||||
asl a
|
||||
ror JOY2
|
||||
asl a
|
||||
ror JOY2
|
||||
nes2: lda JOY2
|
||||
eor #%11111111
|
||||
rts
|
10
libsrc/cx16/joy_stat_stddrv.s
Normal file
10
libsrc/cx16/joy_stat_stddrv.s
Normal file
@ -0,0 +1,10 @@
|
||||
;
|
||||
; Address of the static standard joystick driver
|
||||
;
|
||||
; 2019-09-19, Greg King
|
||||
;
|
||||
; const void joy_static_stddrv[];
|
||||
;
|
||||
|
||||
.import _cx16_stdjoy_joy
|
||||
.export _joy_static_stddrv := _cx16_stdjoy_joy
|
13
libsrc/cx16/joy_stddrv.s
Normal file
13
libsrc/cx16/joy_stddrv.s
Normal file
@ -0,0 +1,13 @@
|
||||
;
|
||||
; Name of the standard joystick driver
|
||||
;
|
||||
; 2019-09-19, Greg King
|
||||
;
|
||||
; const char joy_stddrv[];
|
||||
;
|
||||
|
||||
.export _joy_stddrv
|
||||
|
||||
.rodata
|
||||
|
||||
_joy_stddrv: .asciiz "cx16-stdjoy.joy"
|
17
libsrc/cx16/kbhit.s
Normal file
17
libsrc/cx16/kbhit.s
Normal file
@ -0,0 +1,17 @@
|
||||
;
|
||||
; 2019-09-20, Greg King
|
||||
;
|
||||
; unsigned char kbhit (void);
|
||||
; /* Returns non-zero (true) if a typed character is waiting. */
|
||||
;
|
||||
|
||||
.export _kbhit
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
.proc _kbhit
|
||||
ldx #>$0000 ; High byte of return
|
||||
lda KEY_COUNT ; Get number of characters
|
||||
rts
|
||||
.endproc
|
59
libsrc/cx16/kernal.s
Normal file
59
libsrc/cx16/kernal.s
Normal file
@ -0,0 +1,59 @@
|
||||
;
|
||||
; 2019-09-22, Greg King
|
||||
;
|
||||
; CX16 Kernal functions
|
||||
;
|
||||
|
||||
.include "cbm_kernal.inc"
|
||||
|
||||
.export GETJOY
|
||||
|
||||
.export CLSALL
|
||||
.export SWAPPER
|
||||
.export JSRFAR
|
||||
.export INDFET
|
||||
.export INDSTA
|
||||
.export INDCMP
|
||||
.export PRIMM
|
||||
|
||||
.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 CHRIN
|
||||
.export BSOUT
|
||||
.export CHROUT
|
||||
.export LOAD
|
||||
.export SAVE
|
||||
.export SETTIM
|
||||
.export RDTIM
|
||||
.export STOP
|
||||
.export GETIN
|
||||
.export CLALL
|
||||
.export UDTIM
|
||||
.export SCREEN
|
||||
.export PLOT
|
||||
.export IOBASE
|
18
libsrc/cx16/libref.s
Normal file
18
libsrc/cx16/libref.s
Normal file
@ -0,0 +1,18 @@
|
||||
;
|
||||
; 2013-05-31, Oliver Schmidt
|
||||
; 2019-09-22, Greg King
|
||||
;
|
||||
|
||||
.export em_libref
|
||||
.export joy_libref
|
||||
.export mouse_libref
|
||||
.export ser_libref
|
||||
.export tgi_libref
|
||||
|
||||
.import _exit
|
||||
|
||||
em_libref := _exit
|
||||
joy_libref := _exit
|
||||
mouse_libref := _exit
|
||||
ser_libref := _exit
|
||||
tgi_libref := _exit
|
137
libsrc/cx16/mainargs.s
Normal file
137
libsrc/cx16/mainargs.s
Normal file
@ -0,0 +1,137 @@
|
||||
; mainargs.s
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-03-07
|
||||
; Based on code from Stefan A. Haubenthal, <polluks@web.de>
|
||||
; 2005-02-26, Ullrich von Bassewitz
|
||||
; 2019-09-08, Greg King
|
||||
;
|
||||
; Scan a group of arguments that are in BASIC's input-buffer.
|
||||
; Build an array that points to the beginning of each argument.
|
||||
; Send, to main(), that array and the count of the arguments.
|
||||
;
|
||||
; Command-lines look like these lines:
|
||||
;
|
||||
; run
|
||||
; run : rem
|
||||
; run:rem arg1 " arg 2 is quoted " arg3 "" arg5
|
||||
;
|
||||
; "run" and "rem" are entokenned; the args. are not. Leading and trailing
|
||||
; spaces outside of quotes are ignored.
|
||||
;
|
||||
; TO-DO:
|
||||
; - The "file-name" might be a path-name; don't copy the directory-components.
|
||||
; - Add a control-character quoting mechanism.
|
||||
|
||||
.constructor initmainargs, 24
|
||||
.import __argc, __argv
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special ONCE segment,
|
||||
; which may be reused after the startup code is run
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
initmainargs:
|
||||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNAM_LEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (FNAM),y
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
ldy #1 * 2
|
||||
|
||||
; Find the next argument
|
||||
|
||||
next: lda BASIC_BUF,x
|
||||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
; will check now for a quoted argument, in which case we will have to skip this
|
||||
; first character.
|
||||
|
||||
found: cmp #'"' ; Is the argument quoted?
|
||||
beq setterm ; Jump if so
|
||||
dex ; Reset pointer to first argument character
|
||||
lda #' ' ; A space ends the argument
|
||||
setterm:sta term ; Set end of argument marker
|
||||
|
||||
; Now store a pointer to the argument into the next slot. Since the BASIC
|
||||
; input buffer is located at the start of a RAM page, no calculations are
|
||||
; necessary.
|
||||
|
||||
txa ; Get low byte
|
||||
sta argv,y ; argv[y]= &arg
|
||||
iny
|
||||
lda #>BASIC_BUF
|
||||
sta argv,y
|
||||
iny
|
||||
inc __argc ; Found another arg
|
||||
|
||||
; Search for the end of the argument
|
||||
|
||||
argloop:lda BASIC_BUF,x
|
||||
beq done
|
||||
inx
|
||||
cmp term
|
||||
bne argloop
|
||||
|
||||
; We've found the end of the argument. X points one character behind it, and
|
||||
; A contains the terminating character. To make the argument a valid C string,
|
||||
; replace the terminating character by a zero.
|
||||
|
||||
lda #0
|
||||
sta BASIC_BUF-1,x
|
||||
|
||||
; Check if the maximum number of command line arguments is reached. If not,
|
||||
; parse the next one.
|
||||
|
||||
lda __argc ; Get low byte of argument count
|
||||
cmp #MAXARGS ; Maximum number of arguments reached?
|
||||
bcc next ; Parse next one if not
|
||||
|
||||
; (The last vector in argv[] already is NULL.)
|
||||
|
||||
done: lda #<argv
|
||||
ldx #>argv
|
||||
sta __argv
|
||||
stx __argv + 1
|
||||
rts
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
23
libsrc/cx16/revers.s
Normal file
23
libsrc/cx16/revers.s
Normal file
@ -0,0 +1,23 @@
|
||||
;
|
||||
; 2019-09-16, Greg King
|
||||
;
|
||||
; unsigned char __fastcall__ revers (unsigned char onoff);
|
||||
;
|
||||
|
||||
.export _revers
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
.proc _revers
|
||||
ldy #$00 ; Assume revers off
|
||||
tax ; Test on/off
|
||||
beq :+ ; Jump if off
|
||||
ldy #$80 ; Load "on" value
|
||||
ldx #>$0000 ; Zero high byte of result
|
||||
: lda RVS ; Load old value
|
||||
sty RVS ; Set new value
|
||||
clc
|
||||
rol a ; Convert bit-mask into boolean
|
||||
rol a
|
||||
rts
|
||||
.endproc
|
32
libsrc/cx16/set_tv.s
Normal file
32
libsrc/cx16/set_tv.s
Normal file
@ -0,0 +1,32 @@
|
||||
;
|
||||
; 2019-09-20, Greg King
|
||||
;
|
||||
; void __fastcall__ set_tv (unsigned char);
|
||||
; /* Set the video mode the machine will use. */
|
||||
;
|
||||
|
||||
.export _set_tv
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
.proc _set_tv
|
||||
php
|
||||
pha
|
||||
sei ; Don't let interrupts interfere
|
||||
|
||||
; Point to the video output register.
|
||||
|
||||
stz VERA::CTRL ; Use port 0
|
||||
lda #<VERA::COMPOSER::VIDEO
|
||||
ldx #>VERA::COMPOSER::VIDEO
|
||||
ldy #^VERA::COMPOSER::VIDEO
|
||||
sta VERA::ADDR
|
||||
stx VERA::ADDR+1
|
||||
sty VERA::ADDR+2
|
||||
|
||||
pla
|
||||
sta VERA::DATA0
|
||||
plp ; Re-enable interrupts
|
||||
rts
|
||||
.endproc
|
6
libsrc/cx16/status.s
Normal file
6
libsrc/cx16/status.s
Normal file
@ -0,0 +1,6 @@
|
||||
;
|
||||
; 2012-09-30, Oliver Schmidt
|
||||
; 2019-09-08, Greg King
|
||||
;
|
||||
|
||||
.exportzp ST := $90 ; IEC status byte
|
37
libsrc/cx16/sysuname.s
Normal file
37
libsrc/cx16/sysuname.s
Normal file
@ -0,0 +1,37 @@
|
||||
;
|
||||
; 2003-08-12, Ullrich von Bassewitz
|
||||
; 2019-09-08, Greg King
|
||||
;
|
||||
; unsigned char __fastcall__ _sysuname (struct utsname* buf);
|
||||
;
|
||||
|
||||
.export __sysuname, utsdata
|
||||
|
||||
.import utscopy
|
||||
|
||||
__sysuname := utscopy
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; Data. We define a fixed utsname struct here, and just copy it.
|
||||
|
||||
.rodata
|
||||
|
||||
utsdata:
|
||||
; sysname
|
||||
.asciiz "cc65"
|
||||
|
||||
; nodename
|
||||
.asciiz ""
|
||||
|
||||
; release
|
||||
.byte ((.VERSION >> 8) & $0F) + '0'
|
||||
.byte '.'
|
||||
.byte ((.VERSION >> 4) & $0F) + '0'
|
||||
.byte $00
|
||||
|
||||
; version
|
||||
.byte (.VERSION & $0F) + '0'
|
||||
.byte $00
|
||||
|
||||
; machine
|
||||
.asciiz "Commander X16"
|
30
libsrc/cx16/videomode.s
Normal file
30
libsrc/cx16/videomode.s
Normal file
@ -0,0 +1,30 @@
|
||||
;
|
||||
; 2009-09-07, Ullrich von Bassewitz
|
||||
; 2019-09-23, Greg King
|
||||
;
|
||||
; unsigned __fastcall__ videomode (unsigned Mode);
|
||||
; /* Set the video mode, return the old mode. */
|
||||
;
|
||||
|
||||
.export _videomode
|
||||
.import SWAPPER
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
|
||||
.proc _videomode
|
||||
cmp LLEN ; Do we have this mode already?
|
||||
beq @L9
|
||||
|
||||
lda LLEN ; Get current mode ...
|
||||
pha ; ... and save it
|
||||
|
||||
jsr SWAPPER ; Toggle the mode
|
||||
|
||||
pla ; Get old mode into A
|
||||
|
||||
; Done, old mode is in .A
|
||||
|
||||
@L9: ldx #>$0000 ; Clear high byte
|
||||
rts
|
||||
.endproc
|
17
libsrc/cx16/waitvsync.s
Normal file
17
libsrc/cx16/waitvsync.s
Normal file
@ -0,0 +1,17 @@
|
||||
;
|
||||
; 2019-09-26, Greg King
|
||||
;
|
||||
; void waitvsync (void);
|
||||
;
|
||||
; VERA's vertical sync. causes IRQs which increment the jiffy clock.
|
||||
;
|
||||
|
||||
.export _waitvsync
|
||||
|
||||
.include "cx16.inc"
|
||||
|
||||
_waitvsync:
|
||||
lda TIME + 2
|
||||
: cmp TIME + 2
|
||||
beq :- ; Wait for next jiffy
|
||||
rts
|
@ -296,7 +296,7 @@ static void SetSys (const char* Sys)
|
||||
|
||||
case TGT_ATMOS:
|
||||
NewSymbol ("__ATMOS__", 1);
|
||||
break;
|
||||
break;
|
||||
|
||||
case TGT_TELESTRAT:
|
||||
NewSymbol ("__TELESTRAT__", 1);
|
||||
@ -330,6 +330,10 @@ static void SetSys (const char* Sys)
|
||||
NewSymbol ("__PCE__", 1);
|
||||
break;
|
||||
|
||||
case TGT_CX16:
|
||||
CBMSystem ("__CX16__");
|
||||
break;
|
||||
|
||||
default:
|
||||
AbEnd ("Invalid target name: '%s'", Sys);
|
||||
|
||||
|
@ -285,6 +285,10 @@ static void SetSys (const char* Sys)
|
||||
DefineNumericMacro ("__PCE__", 1);
|
||||
break;
|
||||
|
||||
case TGT_CX16:
|
||||
cbmsys ("__CX16__");
|
||||
break;
|
||||
|
||||
default:
|
||||
AbEnd ("Unknown target system type %d", Target);
|
||||
}
|
||||
|
@ -135,11 +135,11 @@ static const unsigned char CTPET[256] = {
|
||||
typedef struct TargetEntry TargetEntry;
|
||||
struct TargetEntry {
|
||||
char Name[13]; /* Target name */
|
||||
target_t Id; /* Target id */
|
||||
target_t Id; /* Target ID */
|
||||
};
|
||||
|
||||
/* Table that maps target names to ids. Sorted alphabetically for bsearch.
|
||||
** Allows multiple entries for one target id (target name aliases).
|
||||
/* Table that maps target names to IDs. Sorted alphabetically for bsearch().
|
||||
** Allows multiple entries for one target ID (target name aliases).
|
||||
*/
|
||||
static const TargetEntry TargetMap[] = {
|
||||
{ "apple2", TGT_APPLE2 },
|
||||
@ -157,6 +157,7 @@ static const TargetEntry TargetMap[] = {
|
||||
{ "cbm510", TGT_CBM510 },
|
||||
{ "cbm610", TGT_CBM610 },
|
||||
{ "creativision", TGT_CREATIVISION },
|
||||
{ "cx16", TGT_CX16 },
|
||||
{ "gamate", TGT_GAMATE },
|
||||
{ "geos", TGT_GEOS_CBM },
|
||||
{ "geos-apple", TGT_GEOS_APPLE },
|
||||
@ -179,7 +180,7 @@ static const TargetEntry TargetMap[] = {
|
||||
#define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0]))
|
||||
|
||||
|
||||
/* Table with target properties by target id */
|
||||
/* Table with target properties by target ID */
|
||||
static const TargetProperties PropertyTable[TGT_COUNT] = {
|
||||
{ "none", CPU_6502, BINFMT_BINARY, CTNone },
|
||||
{ "module", CPU_6502, BINFMT_O65, CTNone },
|
||||
@ -213,6 +214,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = {
|
||||
{ "pce", CPU_HUC6280, BINFMT_BINARY, CTNone },
|
||||
{ "gamate", CPU_6502, BINFMT_BINARY, CTNone },
|
||||
{ "c65", CPU_4510, BINFMT_BINARY, CTPET },
|
||||
{ "cx16", CPU_65C02, BINFMT_BINARY, CTPET },
|
||||
};
|
||||
|
||||
/* Target system */
|
||||
@ -235,7 +237,7 @@ static int Compare (const void* Key, const void* Entry)
|
||||
|
||||
|
||||
target_t FindTarget (const char* Name)
|
||||
/* Find a target by name and return the target id. TGT_UNKNOWN is returned if
|
||||
/* Find a target by name and return the target ID. TGT_UNKNOWN is returned if
|
||||
** the given name is no valid target.
|
||||
*/
|
||||
{
|
||||
@ -243,7 +245,7 @@ target_t FindTarget (const char* Name)
|
||||
const TargetEntry* T;
|
||||
T = bsearch (Name, TargetMap, MAP_ENTRY_COUNT, sizeof (TargetMap[0]), Compare);
|
||||
|
||||
/* Return the target id */
|
||||
/* Return the target ID */
|
||||
return (T == 0)? TGT_UNKNOWN : T->Id;
|
||||
}
|
||||
|
||||
@ -252,7 +254,7 @@ target_t FindTarget (const char* Name)
|
||||
const TargetProperties* GetTargetProperties (target_t Target)
|
||||
/* Return the properties for a target */
|
||||
{
|
||||
/* Must have a valid target id */
|
||||
/* Must have a valid target ID */
|
||||
PRECONDITION (Target >= 0 && Target < TGT_COUNT);
|
||||
|
||||
/* Return the array entry */
|
||||
|
@ -84,6 +84,7 @@ typedef enum {
|
||||
TGT_PCENGINE,
|
||||
TGT_GAMATE,
|
||||
TGT_C65,
|
||||
TGT_CX16,
|
||||
TGT_COUNT /* Number of target systems */
|
||||
} target_t;
|
||||
|
||||
@ -102,7 +103,7 @@ extern target_t Target;
|
||||
/* Types of available output formats */
|
||||
#define BINFMT_DEFAULT 0 /* Default (binary) */
|
||||
#define BINFMT_BINARY 1 /* Straight binary format */
|
||||
#define BINFMT_O65 2 /* Andre Fachats o65 format */
|
||||
#define BINFMT_O65 2 /* Andre Fachat's o65 format */
|
||||
#define BINFMT_ATARIEXE 3 /* Standard Atari binary load */
|
||||
|
||||
|
||||
@ -127,5 +128,4 @@ const char* GetTargetName (target_t Target);
|
||||
|
||||
|
||||
/* End of target.h */
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@ -14,16 +13,15 @@
|
||||
# define DYN_DRV 0
|
||||
|
||||
/*
|
||||
** link existing drivers like this:
|
||||
** Link existing drivers this way:
|
||||
**
|
||||
** cl65 -DJOYSTICK_DRIVER=c64_hitjoy_joy -o joy-test.prg joy-test.c
|
||||
**
|
||||
** for testing a new driver you will have to uncomment the define below, and
|
||||
** link your driver like this:
|
||||
** For testing a new driver, you need to uncomment the declaration below,
|
||||
** and link your driver this way:
|
||||
**
|
||||
** co65 ../../target/c64/drv/joy/c64-hitjoy.joy -o hitjoy.s --code-label _hitjoy
|
||||
** cl65 -DJOYSTICK_DRIVER=hitjoy -o joy-test.prg joy-test.c hitjoy.s
|
||||
**
|
||||
*/
|
||||
|
||||
/* extern char JOYSTICK_DRIVER; */
|
||||
@ -40,10 +38,8 @@
|
||||
int main (void)
|
||||
{
|
||||
unsigned char j;
|
||||
unsigned char count;
|
||||
unsigned char i;
|
||||
unsigned char i, count;
|
||||
unsigned char Res;
|
||||
unsigned char ch, kb;
|
||||
|
||||
clrscr ();
|
||||
|
||||
@ -58,47 +54,69 @@ int main (void)
|
||||
if (Res != JOY_ERR_OK) {
|
||||
cprintf ("Error in joy_load_driver: %u\r\n", Res);
|
||||
#if DYN_DRV
|
||||
cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror));
|
||||
cprintf ("OS: %u, %s\r\n", _oserror, _stroserror (_oserror));
|
||||
#endif
|
||||
exit (EXIT_FAILURE);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
count = joy_count ();
|
||||
#if defined(__ATARI5200__) || defined(__CREATIVISION__)
|
||||
cprintf ("JOYSTICKS: %d", count);
|
||||
cprintf ("JOYSTICKS: %u.", count);
|
||||
#else
|
||||
cprintf ("Driver supports %d joystick(s)", count);
|
||||
cprintf ("Driver supports %u joystick%s", count, count == 1 ? "." : "s.");
|
||||
#endif
|
||||
while (1) {
|
||||
for (i = 0; i < count; ++i) {
|
||||
gotoxy (0, i+1);
|
||||
j = joy_read (i);
|
||||
#if defined(__ATARI5200__) || defined(__CREATIVISION__)
|
||||
cprintf ("%1d:%-3s%-3s%-3s%-3s%-3s %02x",
|
||||
#if defined(__NES__) || defined(__CX16__)
|
||||
/* two lines for each device */
|
||||
gotoxy (0, i * 2 +1);
|
||||
cprintf ("%2u:%-6s%-6s%-6s%-6s\r\n"
|
||||
" %-6s%-6s%-6s%-6s $%02X",
|
||||
i,
|
||||
JOY_UP(j)? " U " : " - ",
|
||||
JOY_DOWN(j)? " D " : " - ",
|
||||
JOY_LEFT(j)? " L " : " - ",
|
||||
JOY_RIGHT(j)? " R " : " - ",
|
||||
JOY_BTN_1(j)? " 1 " : " - ", j);
|
||||
JOY_UP(j) ? " up " : " ---- ",
|
||||
JOY_DOWN(j) ? " down " : " ---- ",
|
||||
JOY_LEFT(j) ? " left " : " ---- ",
|
||||
JOY_RIGHT(j) ? " right" : " ---- ",
|
||||
JOY_BTN_1(j) ? "btn A " : " ---- ",
|
||||
JOY_BTN_2(j) ? "btn B " : " ---- ",
|
||||
JOY_BTN_3(j) ? "select" : " ---- ",
|
||||
JOY_BTN_4(j) ? " start" : " ---- ",
|
||||
j);
|
||||
#else
|
||||
cprintf ("%2d: %-6s%-6s%-6s%-6s%-6s %02x",
|
||||
/* one line for each device */
|
||||
gotoxy (0, i + 1);
|
||||
# if defined(__ATARI5200__) || defined(__CREATIVISION__)
|
||||
cprintf ("%1u:%-3s%-3s%-3s%-3s%-3s %02X",
|
||||
i,
|
||||
JOY_UP(j)? " up " : " ---- ",
|
||||
JOY_DOWN(j)? " down " : " ---- ",
|
||||
JOY_LEFT(j)? " left " : " ---- ",
|
||||
JOY_RIGHT(j)? "right " : " ---- ",
|
||||
JOY_BTN_1(j)? "button" : " ---- ", j);
|
||||
JOY_UP(j) ? " U " : " - ",
|
||||
JOY_DOWN(j) ? " D " : " - ",
|
||||
JOY_LEFT(j) ? " L " : " - ",
|
||||
JOY_RIGHT(j) ? " R " : " - ",
|
||||
JOY_BTN_1(j) ? " 1 " : " - ",
|
||||
j);
|
||||
# else
|
||||
cprintf ("%2u: %-6s%-6s%-6s%-6s%-6s $%02X",
|
||||
i,
|
||||
JOY_UP(j) ? " up " : " ---- ",
|
||||
JOY_DOWN(j) ? " down " : " ---- ",
|
||||
JOY_LEFT(j) ? " left " : " ---- ",
|
||||
JOY_RIGHT(j) ? "right " : " ---- ",
|
||||
JOY_BTN_1(j) ? "button" : " ---- ",
|
||||
j);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* show pressed key, so we can verify keyboard is working */
|
||||
kb = kbhit ();
|
||||
ch = kb ? cgetc () : ' ';
|
||||
gotoxy (1, i+2);
|
||||
revers (kb);
|
||||
cprintf ("kbd: %c", ch);
|
||||
revers (0);
|
||||
/* Show any pressed keys; so that we can verify that the keyboard is working. */
|
||||
if (kbhit ()) {
|
||||
#if defined(__NES__) || defined(__CX16__)
|
||||
gotoxy (1, i * 2 + 2);
|
||||
#else
|
||||
gotoxy (1, i + 2);
|
||||
#endif
|
||||
cprintf ("keyboard: $%02X", cgetc ());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user