Updated cx16 to match the Commander X16 ROMs and emulator, release 34.
This commit is contained in:
@@ -7,18 +7,20 @@
|
|||||||
.if .def(__CX16__)
|
.if .def(__CX16__)
|
||||||
; CX16 extended jump table
|
; CX16 extended jump table
|
||||||
GETJOY := $FF06
|
GETJOY := $FF06
|
||||||
|
MOUSE := $FF09
|
||||||
|
SCRMOD := $FF5F
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if .def(__C128__)
|
.if .def(__C128__)
|
||||||
; C128 extended jump table
|
; C128 extended jump table
|
||||||
C64MODE := $FF4D
|
C64MODE := $FF4D
|
||||||
|
SWAPPER := $FF5F
|
||||||
SETBNK := $FF68
|
SETBNK := $FF68
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if .def(__C128__) || .def(__CX16__)
|
.if .def(__C128__) || .def(__CX16__)
|
||||||
; Extended jump table
|
; Extended jump table
|
||||||
CLSALL := $FF4A
|
CLSALL := $FF4A
|
||||||
SWAPPER := $FF5F
|
|
||||||
JSRFAR := $FF6E
|
JSRFAR := $FF6E
|
||||||
INDFET := $FF74
|
INDFET := $FF74
|
||||||
INDSTA := $FF77
|
INDSTA := $FF77
|
||||||
|
|||||||
@@ -44,42 +44,55 @@
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Zero page
|
; 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
|
; Kernal
|
||||||
IN_DEV := $99 ; Current input device number
|
FNAM := $84 ; Pointer to filename
|
||||||
OUT_DEV := $9A ; Current output device number
|
KTEMP2 := $86 ; 2 bytes for temporary storage
|
||||||
IMPARM := $9B ; Pointer for PRIMM function
|
SCREEN_PTR := $88 ; Pointer to current row on text screen (16 bits)
|
||||||
TIME := $A0 ; 60 Hz. clock
|
IMPARM := $8A ; Pointer for PRIMM function
|
||||||
FNAM_LEN := $B7 ; Length of filename
|
|
||||||
SECADR := $B9 ; Secondary address
|
; BASIC
|
||||||
DEVNUM := $BA ; Device number
|
TXTPTR := $EE ; Pointer into BASIC source code
|
||||||
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
|
; Page two
|
||||||
|
|
||||||
BASIC_BUF := $200 ; Location of command-line
|
BASIC_BUF := $0200 ; Location of command-line
|
||||||
BASIC_BUF_LEN = 89 ; Maximum length of command-line
|
BASIC_BUF_LEN = 81 ; Maximum length of command-line
|
||||||
|
|
||||||
CHARCOLOR := $286
|
CURS_COLOR := $027E ; Color under the cursor
|
||||||
CURS_COLOR := $287 ; Color under the cursor
|
CHARCOLOR := $0286 ; Cursor's color nybbles (high: background, low: foreground)
|
||||||
|
STATUS := $0287 ; Status from previous I/O operation
|
||||||
|
IN_DEV := $028E ; Current input device number
|
||||||
|
OUT_DEV := $028F ; Current output device number
|
||||||
|
TIME := $0292 ; 60 Hz. clock (3 bytes, big-endian)
|
||||||
|
FNAM_LEN := $0298 ; Length of filename
|
||||||
|
SECADR := $029A ; Secondary address
|
||||||
|
DEVNUM := $029B ; Device number
|
||||||
|
KEY_COUNT := $029E ; Number of keys in input buffer
|
||||||
|
RVS := $029F ; Reverse flag
|
||||||
|
CURS_FLAG := $02A3 ; 1 = cursor off
|
||||||
|
CURS_BLINK := $02A4 ; Blink counter
|
||||||
|
CURS_CHAR := $02A5 ; Character under the cursor
|
||||||
|
CURS_STATE := $02A6 ; Cursor blink state
|
||||||
|
CURS_X := $02A8 ; Cursor column
|
||||||
|
CURS_Y := $02AB ; Cursor row
|
||||||
|
LLEN := $02AE ; Line length
|
||||||
|
NLINES := $02AF ; Number of screen lines
|
||||||
|
JOY1 := $02BC ; 3 bytes of NES/SNES gamepad data
|
||||||
|
JOY2 := $02BF
|
||||||
|
|
||||||
|
; BASIC
|
||||||
|
VARTAB := $02DD ; Pointer to start of BASIC variables
|
||||||
|
MEMSIZE := $02E5 ; Pointer to highest BASIC RAM location (+1)
|
||||||
|
|
||||||
|
; Kernal mouse
|
||||||
|
MSEPAR := $0371 ; mouse: $8x=sprite on, 1/2: scale
|
||||||
|
MOUSEL := $0372 ; min. x co-ordinate
|
||||||
|
MOUSER := $0374 ; max. x co-ordinate
|
||||||
|
MOUSET := $0376 ; min. y co-ordinate
|
||||||
|
MOUSEB := $0378 ; max. y co-ordinate
|
||||||
|
MOUSEX := $037A ; x co-ordinate
|
||||||
|
MOUSEY := $037C ; y co-ordinate
|
||||||
|
MOUSEBT := $037E ; buttons (bits 2: middle, 1: right, 0: left)
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Vector and other locations
|
; Vector and other locations
|
||||||
@@ -122,6 +135,12 @@ NMIVec := $0318
|
|||||||
INC8192 = 14 << 4
|
INC8192 = 14 << 4
|
||||||
INC16384 = 15 << 4
|
INC16384 = 15 << 4
|
||||||
.endenum
|
.endenum
|
||||||
|
.enum ; Interrupt request flags
|
||||||
|
VERT_SYNC = %00000001
|
||||||
|
RASTER = %00000010
|
||||||
|
SPR_COLLIDED = %00000100
|
||||||
|
UART_IRQ = %00001000
|
||||||
|
.endenum
|
||||||
; Internal RAM and registers
|
; Internal RAM and registers
|
||||||
VRAM := $000000
|
VRAM := $000000
|
||||||
.scope COMPOSER ; Display composer
|
.scope COMPOSER ; Display composer
|
||||||
@@ -263,7 +282,7 @@ NMIVec := $0318
|
|||||||
.endscope
|
.endscope
|
||||||
.endscope
|
.endscope
|
||||||
|
|
||||||
; 65c22
|
; 65C22
|
||||||
.struct VIA1 ; Versatile Interface Adapter
|
.struct VIA1 ; Versatile Interface Adapter
|
||||||
.org $9F60
|
.org $9F60
|
||||||
PRB .byte ; ROM bank, IEC (Port Register B)
|
PRB .byte ; ROM bank, IEC (Port Register B)
|
||||||
@@ -281,10 +300,10 @@ NMIVec := $0318
|
|||||||
PRA2 .byte ; RAM bank (Port Register A without handshaking)
|
PRA2 .byte ; RAM bank (Port Register A without handshaking)
|
||||||
.endstruct
|
.endstruct
|
||||||
|
|
||||||
; 65c22
|
; 65C22
|
||||||
.struct VIA2
|
.struct VIA2
|
||||||
.org $9F70
|
.org $9F70
|
||||||
PRB .byte
|
PRB .byte ; Mouse communication ?
|
||||||
PRA .byte ; NES controller communication
|
PRA .byte ; NES controller communication
|
||||||
DDRB .byte
|
DDRB .byte
|
||||||
DDRA .byte
|
DDRA .byte
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ SYMBOLS {
|
|||||||
__HIMEM__: type = weak, value = $9F00;
|
__HIMEM__: type = weak, value = $9F00;
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ZP: file = "", start = $0004, size = $0090 - $0004, define = yes;
|
ZP: file = "", start = $0002, size = $0080 - $0002, define = yes;
|
||||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||||
MAIN: file = %O, start = %S, size = __HIMEM__ - %S;
|
MAIN: file = %O, start = %S, size = __HIMEM__ - %S;
|
||||||
}
|
}
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
ZEROPAGE: load = ZP, type = zp;
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
|
EXTZP: load = ZP, type = zp, optional = yes;
|
||||||
LOADADDR: load = LOADADDR, type = ro;
|
LOADADDR: load = LOADADDR, type = ro;
|
||||||
EXEHDR: load = MAIN, type = ro, optional = yes;
|
EXEHDR: load = MAIN, type = ro, optional = yes;
|
||||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ SYMBOLS {
|
|||||||
__BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM
|
__BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ZP: file = "", define = yes, start = $0004, size = $0090 - $0004;
|
ZP: file = "", define = yes, start = $0002, size = $0080 - $0002;
|
||||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ SYMBOLS {
|
|||||||
__HIMEM__: type = weak, value = $9F00;
|
__HIMEM__: type = weak, value = $9F00;
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ZP: file = "", define = yes, start = $0004, size = $0090 - $0004;
|
ZP: file = "", define = yes, start = $0002, size = $0080 - $0002;
|
||||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ compiler.
|
|||||||
<sect>Overview<p>
|
<sect>Overview<p>
|
||||||
|
|
||||||
The Commander X16 is a modern small computer with firmware that is based on
|
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
|
the ROMs in Commodore's VIC-20 and 64C. It has a couple of I/O chips
|
||||||
are in the VIC-20.
|
(WDC65C22 VIA) that are like the ones in the VIC-20.
|
||||||
|
|
||||||
This file contains an overview of the CX16 run-time system as it comes with the
|
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,
|
cc65 C compiler. It describes the memory layout, CX16-specific header files,
|
||||||
available drivers, and any pitfalls specific to that platform.
|
available drivers, and any pitfalls specific to that platform.
|
||||||
|
|
||||||
Please note that CX16-specific functions just are mentioned here; they are
|
Please note that CX16-specific functions just are mentioned here; they might be
|
||||||
described in detail in the separate <url url="funcref.html" name="function
|
described in detail in the separate <url url="funcref.html" name="function
|
||||||
reference">. Even functions marked as "platform dependent" may be available on
|
reference">. Even functions marked as "platform dependent" may be available on
|
||||||
more than one platform. Please see the function reference for more
|
more than one platform. Please see the function reference for more
|
||||||
@@ -35,19 +35,20 @@ information.
|
|||||||
<sect>Binary format<p>
|
<sect>Binary format<p>
|
||||||
|
|
||||||
The standard binary output format generated by the linker for the CX16 target
|
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
|
is a machine language program that's prepended with a 16-bit load address and a
|
||||||
machine language part via SYS. That means that a program can be loaded as a
|
one-line BASIC stub which calls the machine language part via SYS. That means
|
||||||
BASIC program, and started with RUN. It is, of course, possible to change that
|
that a program can be loaded as a BASIC program, and started with RUN. It is,
|
||||||
behaviour by using a modified start-up file and linker config.
|
of course, possible to change that behaviour by using a modified program-header
|
||||||
|
file and linker config.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<sect>Memory layout<p>
|
<sect>Memory layout<p>
|
||||||
|
|
||||||
cc65-generated programs with the default setup run with the I/O area and the
|
cc65-generated programs with the default setup run with the I/O area, RAM bank
|
||||||
Kernal ROM visible. That means that Kernal entry points can be called directly.
|
zero, and the Kernal ROM visible. That means that Kernal entry points can be
|
||||||
The usable memory ranges are $0800 - $9EFF and $A000 -
|
called directly. The usable memory ranges are $0800 - $9EFF and
|
||||||
$BFFF.
|
$A000 - $BFFF.
|
||||||
|
|
||||||
Special locations:
|
Special locations:
|
||||||
|
|
||||||
@@ -76,6 +77,9 @@ 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
|
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>/.
|
linker config. files which are used via <tt/-t cx16 -C <configfile>/.
|
||||||
|
|
||||||
|
Those files use 126 bytes in the zero page. (The rest of page zero is reserved
|
||||||
|
for Kernal and BASIC.)
|
||||||
|
|
||||||
|
|
||||||
<sect1>Default config. file (<tt/cx16.cfg/)<p>
|
<sect1>Default config. file (<tt/cx16.cfg/)<p>
|
||||||
|
|
||||||
@@ -138,6 +142,8 @@ url="funcref.html" name="function reference"> for declarations and usage.
|
|||||||
<item>get_ostype()
|
<item>get_ostype()
|
||||||
<item>set_tv()
|
<item>set_tv()
|
||||||
<item>videomode()
|
<item>videomode()
|
||||||
|
<item>vpeek()
|
||||||
|
<item>vpoke()
|
||||||
<item>waitvsync()
|
<item>waitvsync()
|
||||||
</itemize>
|
</itemize>
|
||||||
|
|
||||||
@@ -157,6 +163,7 @@ declarations and usage.
|
|||||||
<item>cbm_k_ckout()
|
<item>cbm_k_ckout()
|
||||||
<item>cbm_k_close()
|
<item>cbm_k_close()
|
||||||
<item>cbm_k_clrch()
|
<item>cbm_k_clrch()
|
||||||
|
<item>cbm_k_getin()
|
||||||
<item>cbm_k_load()
|
<item>cbm_k_load()
|
||||||
<item>cbm_k_open()
|
<item>cbm_k_open()
|
||||||
<item>cbm_k_readst()
|
<item>cbm_k_readst()
|
||||||
@@ -217,13 +224,13 @@ No extended memory drivers are available currently for the CX16.
|
|||||||
<sect1>Joystick drivers<p>
|
<sect1>Joystick drivers<p>
|
||||||
|
|
||||||
The default drivers, <tt/joy_stddrv (joy_static_stddrv)/,
|
The default drivers, <tt/joy_stddrv (joy_static_stddrv)/,
|
||||||
point to <tt/cX16-stdjoy.joy (cx16_stdjoy_joy)/.
|
point to <tt/cX16-std.joy (cx16_std_joy)/.
|
||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
<tag><tt/cX16-stdjoy.joy (cX16_stdjoy_joy)/</tag>
|
<tag><tt/cX16-std.joy (cX16_std_joy)/</tag>
|
||||||
Supports up to two NES and SNES controllers connected to the joystick ports
|
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
|
of the CX16. It reads the four directions, and the A, B, Select, and Start
|
||||||
buttons. Button A is the primary fire button.
|
buttons. Buttons A and B are the primary and secondary fire buttons.
|
||||||
</descrip><p>
|
</descrip><p>
|
||||||
|
|
||||||
|
|
||||||
@@ -248,9 +255,16 @@ any time. Some changes could make old programs fail to work.
|
|||||||
<sect>Other hints<p>
|
<sect>Other hints<p>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>STOP and RUN codes<p>
|
||||||
|
|
||||||
|
The <tt/Esc/ key acts as Commodore's <tt/STOP/ key -- or, you can press the
|
||||||
|
<tt/Ctrl/ key and the <tt/C/ key together. Pressing the <tt/Shift/ and the
|
||||||
|
<tt/Esc/ keys together will type Commodore's <tt/RUN/ key.
|
||||||
|
|
||||||
|
|
||||||
<sect1>Escape code<p>
|
<sect1>Escape code<p>
|
||||||
|
|
||||||
For an Esc, press <tt/Ctrl/ and the <tt/[/ key.
|
For an <tt/Esc/, press the <tt/Ctrl/ key and the <tt/[/ key together.
|
||||||
|
|
||||||
|
|
||||||
<sect1>Passing arguments to the program<p>
|
<sect1>Passing arguments to the program<p>
|
||||||
@@ -274,7 +288,7 @@ supported directly by BASIC, the following syntax was chosen:
|
|||||||
|
|
||||||
<sect1>Program return code<p>
|
<sect1>Program return code<p>
|
||||||
|
|
||||||
The program return code (low byte) is passed back to BASIC by use of the
|
The program return code (low byte) is passed back to BASIC by the use of its
|
||||||
<tt/ST/ variable.
|
<tt/ST/ variable.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,9 @@
|
|||||||
#define JOY_FIRE2_MASK JOY_BTN_2_MASK
|
#define JOY_FIRE2_MASK JOY_BTN_2_MASK
|
||||||
#define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK)
|
#define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK)
|
||||||
|
|
||||||
|
/* Additional mouse button mask */
|
||||||
|
#define MOUSE_BTN_MIDDLE 0x02
|
||||||
|
|
||||||
/* get_tv() return codes
|
/* get_tv() return codes
|
||||||
** set_tv() argument codes
|
** set_tv() argument codes
|
||||||
*/
|
*/
|
||||||
@@ -113,10 +116,12 @@
|
|||||||
#define TV_RGB2 7
|
#define TV_RGB2 7
|
||||||
|
|
||||||
/* Video mode defines */
|
/* Video mode defines */
|
||||||
#define VIDEOMODE_40x30 40u
|
#define VIDEOMODE_40x30 0x00
|
||||||
#define VIDEOMODE_80x60 80u
|
#define VIDEOMODE_80x60 0x02
|
||||||
#define VIDEOMODE_40COL VIDEOMODE_40x30
|
#define VIDEOMODE_40COL VIDEOMODE_40x30
|
||||||
#define VIDEOMODE_80COL VIDEOMODE_80x60
|
#define VIDEOMODE_80COL VIDEOMODE_80x60
|
||||||
|
#define VIDEOMODE_320x240 0x80
|
||||||
|
#define VIDEOMODE_SWAP (-1)
|
||||||
|
|
||||||
|
|
||||||
/* Define hardware */
|
/* Define hardware */
|
||||||
@@ -157,7 +162,7 @@ struct __emul {
|
|||||||
|
|
||||||
/* The addresses of the static drivers */
|
/* The addresses of the static drivers */
|
||||||
|
|
||||||
extern void cx16_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */
|
extern void cx16_std_joy[]; /* Referred to by joy_static_stddrv[] */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -174,14 +179,20 @@ signed char get_ostype (void);
|
|||||||
** Positive -- release build
|
** Positive -- release build
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
unsigned char get_tv (void);
|
||||||
|
/* Return the video type that the machine is using.
|
||||||
|
** Return a TV_xx constant.
|
||||||
|
*/
|
||||||
|
|
||||||
void __fastcall__ set_tv (unsigned char type);
|
void __fastcall__ set_tv (unsigned char type);
|
||||||
/* Set the video type that the machine will use.
|
/* Set the video type that the machine will use.
|
||||||
** Call with a TV_xx constant.
|
** Call with a TV_xx constant.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned char __fastcall__ videomode (unsigned char mode);
|
signed char __fastcall__ videomode (signed char mode);
|
||||||
/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx
|
/* Set the video mode, return the old mode.
|
||||||
** constants.
|
** Return -1 if Mode isn't valid.
|
||||||
|
** Call with one of the VIDEOMODE_xx constants.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned char __fastcall__ vpeek (unsigned long addr);
|
unsigned char __fastcall__ vpeek (unsigned long addr);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
;
|
;
|
||||||
; 1998-09-27, Ullrich von Bassewitz
|
; 1998-09-27, Ullrich von Bassewitz
|
||||||
; 2019-09-08, Greg King
|
; 2019-11-06, Greg King
|
||||||
;
|
;
|
||||||
; void __fastcall__ set_brk (unsigned Addr);
|
; void __fastcall__ set_brk (unsigned Addr);
|
||||||
; void reset_brk (void);
|
; void reset_brk (void);
|
||||||
@@ -30,6 +30,7 @@ uservec: jmp $FFFF ; Patched at runtime
|
|||||||
.code
|
.code
|
||||||
|
|
||||||
; Set the break vector
|
; Set the break vector
|
||||||
|
|
||||||
.proc _set_brk
|
.proc _set_brk
|
||||||
|
|
||||||
sta uservec+1
|
sta uservec+1
|
||||||
@@ -40,9 +41,9 @@ uservec: jmp $FFFF ; Patched at runtime
|
|||||||
bne L1 ; Jump if we installed the handler already
|
bne L1 ; Jump if we installed the handler already
|
||||||
|
|
||||||
lda BRKVec
|
lda BRKVec
|
||||||
|
ldx BRKVec+1
|
||||||
sta oldvec
|
sta oldvec
|
||||||
lda BRKVec+1
|
stx oldvec+1 ; Save the old vector
|
||||||
sta oldvec+1 ; Save the old vector
|
|
||||||
|
|
||||||
L1: lda #<brk_handler ; Set the break vector to our routine
|
L1: lda #<brk_handler ; Set the break vector to our routine
|
||||||
ldx #>brk_handler
|
ldx #>brk_handler
|
||||||
@@ -54,6 +55,7 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
|||||||
|
|
||||||
|
|
||||||
; Reset the break vector
|
; Reset the break vector
|
||||||
|
|
||||||
.proc _reset_brk
|
.proc _reset_brk
|
||||||
|
|
||||||
lda oldvec
|
lda oldvec
|
||||||
@@ -61,15 +63,15 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
|||||||
beq @L9 ; Jump if vector not installed
|
beq @L9 ; Jump if vector not installed
|
||||||
sta BRKVec
|
sta BRKVec
|
||||||
stx BRKVec+1
|
stx BRKVec+1
|
||||||
|
|
||||||
lda #$00
|
lda #$00
|
||||||
sta oldvec ; Clear the old vector
|
sta oldvec ; Clear the old vector
|
||||||
stx oldvec+1
|
sta oldvec+1
|
||||||
@L9: rts
|
@L9: rts
|
||||||
|
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Break handler, called if a break occurs
|
; Break handler, called if a break occurs
|
||||||
|
|
||||||
.proc brk_handler
|
.proc brk_handler
|
||||||
@@ -81,14 +83,13 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
|||||||
pla
|
pla
|
||||||
sta _brk_a
|
sta _brk_a
|
||||||
pla
|
pla
|
||||||
and #$EF ; Clear break bit
|
|
||||||
sta _brk_sr
|
sta _brk_sr
|
||||||
pla ; PC low
|
pla ; PC low
|
||||||
sec
|
sec
|
||||||
sbc #2 ; Point to start of brk
|
sbc #<$0002 ; Point to start of BRK
|
||||||
sta _brk_pc
|
sta _brk_pc
|
||||||
pla ; PC high
|
pla ; PC high
|
||||||
sbc #0
|
sbc #>$0002
|
||||||
sta _brk_pc+1
|
sta _brk_pc+1
|
||||||
|
|
||||||
jsr uservec ; Call the user's routine
|
jsr uservec ; Call the user's routine
|
||||||
@@ -99,11 +100,9 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
|||||||
pha
|
pha
|
||||||
lda _brk_sr
|
lda _brk_sr
|
||||||
pha
|
pha
|
||||||
ldx _brk_x
|
|
||||||
ldy _brk_y
|
ldy _brk_y
|
||||||
|
ldx _brk_x
|
||||||
lda _brk_a
|
lda _brk_a
|
||||||
rti ; Jump back...
|
rti ; Jump back...
|
||||||
|
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
;
|
|
||||||
; 2019-09-23, Greg King
|
|
||||||
;
|
|
||||||
; Low-level stuff for screen output/console input
|
|
||||||
;
|
|
||||||
|
|
||||||
.exportzp CURS_X, CURS_Y
|
|
||||||
|
|
||||||
.include "cx16.inc"
|
|
||||||
@@ -19,7 +19,7 @@ _cpeekc:
|
|||||||
sta VERA::ADDR+1 ; set row number
|
sta VERA::ADDR+1 ; set row number
|
||||||
stz VERA::ADDR+2
|
stz VERA::ADDR+2
|
||||||
lda CURS_X ; get character column
|
lda CURS_X ; get character column
|
||||||
asl a
|
asl a ; each character has two bytes
|
||||||
sta VERA::ADDR
|
sta VERA::ADDR
|
||||||
lda VERA::DATA0 ; get screen code
|
lda VERA::DATA0 ; get screen code
|
||||||
plp
|
plp
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ _cpeekrevers:
|
|||||||
sta VERA::ADDR+1 ; set row number
|
sta VERA::ADDR+1 ; set row number
|
||||||
stz VERA::ADDR+2
|
stz VERA::ADDR+2
|
||||||
lda CURS_X ; get character column
|
lda CURS_X ; get character column
|
||||||
asl a
|
asl a ; each character has two bytes
|
||||||
sta VERA::ADDR
|
sta VERA::ADDR
|
||||||
lda VERA::DATA0 ; get screen code
|
lda VERA::DATA0 ; get screen code
|
||||||
plp
|
plp
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ plot: ldy CURS_X
|
|||||||
|
|
||||||
|
|
||||||
; Write one screen-code and color to the video RAM without doing anything else.
|
; Write one screen-code and color to the video RAM without doing anything else.
|
||||||
; Return the x position in Y.
|
; Return the x position in .Y .
|
||||||
|
|
||||||
putchar:
|
putchar:
|
||||||
ora RVS ; Set revers bit
|
ora RVS ; Set revers bit
|
||||||
@@ -90,7 +90,7 @@ putchar:
|
|||||||
sta VERA::ADDR+2
|
sta VERA::ADDR+2
|
||||||
ldy CURS_X ; Get character column
|
ldy CURS_X ; Get character column
|
||||||
tya
|
tya
|
||||||
asl a
|
asl a ; Each character has two bytes
|
||||||
sta VERA::ADDR
|
sta VERA::ADDR
|
||||||
stx VERA::DATA0
|
stx VERA::DATA0
|
||||||
lda CHARCOLOR
|
lda CHARCOLOR
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
.import zerobss, callmain
|
.import zerobss, callmain
|
||||||
.import CHROUT
|
.import CHROUT
|
||||||
.import __MAIN_START__, __MAIN_SIZE__ ; Linker-generated
|
.import __MAIN_START__, __MAIN_SIZE__ ; Linker-generated
|
||||||
.importzp ST
|
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "cx16.inc"
|
.include "cx16.inc"
|
||||||
@@ -36,11 +35,18 @@ Start: tsx
|
|||||||
|
|
||||||
jsr callmain
|
jsr callmain
|
||||||
|
|
||||||
; Back from main() [this is also the exit() entry]. Run the module destructors.
|
; Back from main() [this is also the exit() entry].
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
; Put the program return code into BASIC's status variable.
|
||||||
|
|
||||||
|
sta STATUS
|
||||||
|
|
||||||
|
; Run the module destructors.
|
||||||
|
|
||||||
_exit: pha ; Save the return code on stack
|
|
||||||
jsr donelib
|
jsr donelib
|
||||||
|
|
||||||
|
.if 0 ; We no longer need to preserve zero-page space for cc65's variables.
|
||||||
; Copy back the zero-page stuff.
|
; Copy back the zero-page stuff.
|
||||||
|
|
||||||
ldx #zpspace-1
|
ldx #zpspace-1
|
||||||
@@ -48,11 +54,7 @@ L2: lda zpsave,x
|
|||||||
sta sp,x
|
sta sp,x
|
||||||
dex
|
dex
|
||||||
bpl L2
|
bpl L2
|
||||||
|
.endif
|
||||||
; Place the program return code into BASIC's status variable.
|
|
||||||
|
|
||||||
pla
|
|
||||||
sta ST
|
|
||||||
|
|
||||||
; Restore the system stuff.
|
; Restore the system stuff.
|
||||||
|
|
||||||
@@ -88,6 +90,7 @@ init:
|
|||||||
lda #$00 ; Choose RAM bank zero
|
lda #$00 ; Choose RAM bank zero
|
||||||
sta VIA1::PRA2
|
sta VIA1::PRA2
|
||||||
|
|
||||||
|
.if 0 ; We no longer need to preserve zero-page space for cc65's variables.
|
||||||
; Save the zero-page locations that we need.
|
; Save the zero-page locations that we need.
|
||||||
|
|
||||||
ldx #zpspace-1
|
ldx #zpspace-1
|
||||||
@@ -95,6 +98,7 @@ L1: lda sp,x
|
|||||||
sta zpsave,x
|
sta zpsave,x
|
||||||
dex
|
dex
|
||||||
bpl L1
|
bpl L1
|
||||||
|
.endif
|
||||||
|
|
||||||
; Set up the stack.
|
; Set up the stack.
|
||||||
|
|
||||||
@@ -121,4 +125,6 @@ L1: lda sp,x
|
|||||||
ramsave:
|
ramsave:
|
||||||
.res 1
|
.res 1
|
||||||
spsave: .res 1
|
spsave: .res 1
|
||||||
|
.if 0
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
.endif
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
;
|
|
||||||
; 2010-02-14, Oliver Schmidt
|
|
||||||
; 2019-09-08, Greg King
|
|
||||||
;
|
|
||||||
|
|
||||||
.include "cx16.inc"
|
|
||||||
|
|
||||||
.exportzp devnum := DEVNUM
|
|
||||||
122
libsrc/cx16/exec.c
Normal file
122
libsrc/cx16/exec.c
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
** Program-chaining function for Commodore platforms.
|
||||||
|
**
|
||||||
|
** 2019-11-08, Greg King
|
||||||
|
**
|
||||||
|
** This function exploits the program-chaining feature in Commander X16 BASIC's ROM.
|
||||||
|
**
|
||||||
|
** CC65's CBM programs have a BASIC program stub. We start those programs by
|
||||||
|
** RUNning that stub; it SYSes to the Machine Language code. Normally, after
|
||||||
|
** the ML code exits, the BASIC ROM continues running the stub. But, it has
|
||||||
|
** no more statements; so, the program stops.
|
||||||
|
**
|
||||||
|
** This function puts the desired program's name and device number into a LOAD
|
||||||
|
** statement. Then, it points BASIC to that statement, so that the ROM will run
|
||||||
|
** that statement after this program quits. The ROM will load the next program,
|
||||||
|
** and will execute it (because the LOAD will be seen in a running program).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* The struct below is a line of BASIC code. It sits in the LOWCODE segment
|
||||||
|
** to make sure that it won't be hidden by a ROM when BASIC is re-enabled.
|
||||||
|
** The line is:
|
||||||
|
** 0 CLR:LOAD""+"" ,01
|
||||||
|
** After this function has written into the line, it might look like this:
|
||||||
|
** 0 CLR:LOAD""+"program name" ,08
|
||||||
|
**
|
||||||
|
** When BASIC's LOAD command asks the Kernal to load a file, it gives the
|
||||||
|
** Kernal a pointer to a file-name string. CC65's CBM programs use that
|
||||||
|
** pointer to give a copy of the program's name to main()'s argv[0] parameter.
|
||||||
|
** But, when BASIC uses a string literal that is in a program, it points
|
||||||
|
** directly to that literal -- in the models that don't use banked RAM
|
||||||
|
** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program
|
||||||
|
** that is loaded. So, argv[0] would point to machine code. String operations
|
||||||
|
** create a new result string -- even when that operation changes nothing. The
|
||||||
|
** result is put in the string space at the top of BASIC's memory. So, the ""+
|
||||||
|
** in this BASIC line guarantees that argv[0] will get a name from a safe place.
|
||||||
|
*/
|
||||||
|
#pragma data-name(push, "LOWCODE")
|
||||||
|
static struct line {
|
||||||
|
const char end_of_line; /* fake previous line */
|
||||||
|
const struct line* const next;
|
||||||
|
const unsigned line_num;
|
||||||
|
const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote;
|
||||||
|
char name[21];
|
||||||
|
const char comma;
|
||||||
|
char unit[3];
|
||||||
|
} basic = {
|
||||||
|
'\0', &basic + 1, /* high byte of link must be non-zero */
|
||||||
|
0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"',
|
||||||
|
"\" ", /* format: "123:1234567890123456\"" */
|
||||||
|
',', "01"
|
||||||
|
};
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
|
/* These values are platform-specific. */
|
||||||
|
extern const void* vartab; /* points to BASIC program variables */
|
||||||
|
extern const void* memsize; /* points to top of BASIC RAM */
|
||||||
|
extern const struct line* txtptr; /* points to BASIC code */
|
||||||
|
#pragma zpsym("txtptr")
|
||||||
|
extern char basbuf[]; /* BASIC's input buffer */
|
||||||
|
extern void basbuf_len[];
|
||||||
|
#pragma zpsym("basbuf_len")
|
||||||
|
|
||||||
|
|
||||||
|
int __fastcall__ exec (const char* progname, const char* cmdline)
|
||||||
|
{
|
||||||
|
static int fd;
|
||||||
|
static unsigned char dv, n;
|
||||||
|
|
||||||
|
/* Exclude devices that can't load files. */
|
||||||
|
/* (Use hand optimization, to make smaller code.) */
|
||||||
|
dv = getcurrentdevice ();
|
||||||
|
if (dv < 8 && __AX__ != 1 || __AX__ > 30) {
|
||||||
|
return _mappederrno (9); /* illegal device number */
|
||||||
|
}
|
||||||
|
utoa (dv, basic.unit, 10);
|
||||||
|
|
||||||
|
/* Don't try to run a program that doesn't exist. */
|
||||||
|
fd = open (progname, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
return _mappederrno (4); /* file not found */
|
||||||
|
}
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
do {
|
||||||
|
if ((basic.name[n] = progname[n]) == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (++n < 20); /* truncate long names */
|
||||||
|
basic.name[n] = '\"';
|
||||||
|
|
||||||
|
/* cc65 program loads might extend beyond the end of the RAM that is allowed
|
||||||
|
** for BASIC. Then, the LOAD statement would complain that it is "out of
|
||||||
|
** memory". Some pointers that say where to put BASIC program variables
|
||||||
|
** must be changed, so that we do not get that error. One pointer is
|
||||||
|
** changed here; a BASIC CLR statement changes the others.
|
||||||
|
*/
|
||||||
|
vartab = (char*)memsize - 256;
|
||||||
|
|
||||||
|
/* Build the next program's argument list. */
|
||||||
|
basbuf[0] = 0x8F; /* REM token */
|
||||||
|
basbuf[1] = '\0';
|
||||||
|
if (cmdline != NULL) {
|
||||||
|
strncat (basbuf, cmdline, (size_t)basbuf_len - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell the ROM where to find that BASIC program. */
|
||||||
|
txtptr = &basic;
|
||||||
|
|
||||||
|
/* (The return code, in STATUS, will be destroyed by LOAD.
|
||||||
|
** So, don't bother to set it here.)
|
||||||
|
*/
|
||||||
|
exit (__AX__);
|
||||||
|
}
|
||||||
16
libsrc/cx16/execvars.s
Normal file
16
libsrc/cx16/execvars.s
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
;
|
||||||
|
; Platform-specific variables for the exec program-chaining function
|
||||||
|
;
|
||||||
|
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
; exec() is written in C.
|
||||||
|
; Provide the spellings that the C compiler wants to use.
|
||||||
|
|
||||||
|
.export _vartab := VARTAB
|
||||||
|
.export _memsize := MEMSIZE
|
||||||
|
|
||||||
|
.exportzp _txtptr := TXTPTR
|
||||||
|
|
||||||
|
.export _basbuf := BASIC_BUF
|
||||||
|
.exportzp _basbuf_len = BASIC_BUF_LEN
|
||||||
39
libsrc/cx16/filevars.s
Normal file
39
libsrc/cx16/filevars.s
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
;
|
||||||
|
; 2002-11-15, Ullrich von Bassewitz
|
||||||
|
; 2019-11-08, Greg King
|
||||||
|
;
|
||||||
|
; Variables used for CBM file I/O
|
||||||
|
;
|
||||||
|
|
||||||
|
.export curunit
|
||||||
|
.constructor initcurunit, 30
|
||||||
|
.destructor updatedevnum, 30
|
||||||
|
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
|
||||||
|
.segment "INIT"
|
||||||
|
|
||||||
|
curunit:
|
||||||
|
.res 1
|
||||||
|
|
||||||
|
|
||||||
|
.segment "ONCE"
|
||||||
|
|
||||||
|
.proc initcurunit
|
||||||
|
lda DEVNUM
|
||||||
|
bne L0
|
||||||
|
lda #8 ; Default is SD card
|
||||||
|
sta DEVNUM
|
||||||
|
L0: sta curunit
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
.proc updatedevnum
|
||||||
|
lda curunit
|
||||||
|
sta DEVNUM
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
67
libsrc/cx16/getdevice.s
Normal file
67
libsrc/cx16/getdevice.s
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
;
|
||||||
|
; 2012-09-04, Oliver Schmidt
|
||||||
|
; 2019-11-08, Greg King
|
||||||
|
;
|
||||||
|
; unsigned char getfirstdevice (void);
|
||||||
|
; unsigned char __fastcall__ getnextdevice (unsigned char device);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _getfirstdevice
|
||||||
|
.export _getnextdevice
|
||||||
|
.import isdisk
|
||||||
|
.import opencmdchannel
|
||||||
|
.import closecmdchannel
|
||||||
|
.importzp tmp2
|
||||||
|
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; getfirstdevice()
|
||||||
|
|
||||||
|
_getfirstdevice:
|
||||||
|
lda #$FF
|
||||||
|
; Fall through
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; getnextdevice()
|
||||||
|
|
||||||
|
_getnextdevice:
|
||||||
|
tax
|
||||||
|
next: inx
|
||||||
|
cpx #$FF
|
||||||
|
beq done
|
||||||
|
|
||||||
|
; [open|close]cmdchannel already call isdisk internally; but, they
|
||||||
|
; interpret a non-disk as a no-op, while we need to interpret it
|
||||||
|
; as an error here.
|
||||||
|
|
||||||
|
jsr isdisk
|
||||||
|
bcs next
|
||||||
|
|
||||||
|
; [open|close]cmdchannel don't call into the Kernal, at all, if they
|
||||||
|
; only [in|de]crement the reference count of the shared cmdchannel.
|
||||||
|
; Therefore, we need to initiate STATUS explicitly here.
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta STATUS
|
||||||
|
|
||||||
|
stx tmp2
|
||||||
|
jsr opencmdchannel
|
||||||
|
ldx tmp2
|
||||||
|
jsr closecmdchannel
|
||||||
|
ldx tmp2
|
||||||
|
|
||||||
|
; As we had to reference ST above anyway, we can do so, as well,
|
||||||
|
; here too (instead of calling READST).
|
||||||
|
|
||||||
|
lda STATUS
|
||||||
|
|
||||||
|
; Either the Kernal calls above were successfull, or there was
|
||||||
|
; already a cmdchannel to the device open -- which is a pretty
|
||||||
|
; good indication of its existence. ;-)
|
||||||
|
|
||||||
|
bmi next
|
||||||
|
|
||||||
|
done: txa
|
||||||
|
ldx #$00
|
||||||
|
rts
|
||||||
13
libsrc/cx16/gotox.s
Normal file
13
libsrc/cx16/gotox.s
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; void fastcall gotox (unsigned char x);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _gotox
|
||||||
|
|
||||||
|
.import plot
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
_gotox: sta CURS_X ; Set new position
|
||||||
|
jmp plot ; And activate it
|
||||||
18
libsrc/cx16/gotoxy.s
Normal file
18
libsrc/cx16/gotoxy.s
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; void fastcall gotoxy (unsigned char x, unsigned char y);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export gotoxy, _gotoxy
|
||||||
|
|
||||||
|
.import popa, plot
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
gotoxy: jsr popa ; Get Y
|
||||||
|
|
||||||
|
_gotoxy:
|
||||||
|
sta CURS_Y ; Set Y
|
||||||
|
jsr popa ; Get X
|
||||||
|
sta CURS_X ; Set X
|
||||||
|
jmp plot ; Set the cursor position
|
||||||
13
libsrc/cx16/gotoy.s
Normal file
13
libsrc/cx16/gotoy.s
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; void gotoy (unsigned char y);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _gotoy
|
||||||
|
|
||||||
|
.import plot
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
_gotoy: sta CURS_Y ; Set the new position
|
||||||
|
jmp plot ; And activate it
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
;
|
;
|
||||||
; Standard joystick driver for the CX16.
|
; Standard joystick driver for the CX16.
|
||||||
; May be used multiple times when statically linked to the application.
|
; May be installed multiple times when statically linked to the application.
|
||||||
;
|
;
|
||||||
; 2019-09-23, Greg King
|
; 2019-11-15 Greg King
|
||||||
;
|
;
|
||||||
|
|
||||||
.include "joy-kernel.inc"
|
.include "joy-kernel.inc"
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Header. Includes jump table
|
; Header. Includes jump table
|
||||||
|
|
||||||
module_header _cx16_stdjoy_joy
|
module_header _cx16_std_joy
|
||||||
|
|
||||||
; Driver signature
|
; Driver signature
|
||||||
|
|
||||||
@@ -48,11 +48,10 @@ JOY_COUNT = 2 ; Number of joysticks we support
|
|||||||
.code
|
.code
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; INSTALL routine. Is called after the driver is loaded into memory.
|
; INSTALL routine -- is called after the driver is loaded into memory.
|
||||||
; If possible, check if the hardware is present, and determine the amount
|
; If possible, check if the hardware is present, and determine the amount
|
||||||
; of memory available.
|
; of memory available.
|
||||||
; Must return a JOY_ERR_xx code in a/x.
|
; Must return a JOY_ERR_xx code in .XA .
|
||||||
;
|
|
||||||
|
|
||||||
INSTALL:
|
INSTALL:
|
||||||
lda #<JOY_ERR_OK
|
lda #<JOY_ERR_OK
|
||||||
@@ -60,60 +59,67 @@ INSTALL:
|
|||||||
; rts ; Run into UNINSTALL instead
|
; rts ; Run into UNINSTALL instead
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
; UNINSTALL routine -- is called before the driver is removed from memory.
|
||||||
; Can do clean-up or whatever. Must not return anything.
|
; Can do clean-up or whatever. Shouldn't return anything.
|
||||||
;
|
|
||||||
|
|
||||||
UNINSTALL:
|
UNINSTALL:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; COUNT: Return the total number of possible joysticks in a/x.
|
; COUNT: Return the total number of possible joysticks, in .XA .
|
||||||
;
|
|
||||||
|
|
||||||
COUNT: lda #<JOY_COUNT
|
COUNT: lda #<JOY_COUNT
|
||||||
ldx #>JOY_COUNT
|
ldx #>JOY_COUNT
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; READ: Read a particular joystick passed in A.
|
; READ: Read a particular joystick passed in .A .
|
||||||
;
|
|
||||||
; TODO: Find a way to report the SNES controller's extra four lines.
|
|
||||||
;
|
|
||||||
|
|
||||||
READ: pha
|
READ: php
|
||||||
jsr GETJOY
|
bit #JOY_COUNT - $01
|
||||||
pla
|
sei
|
||||||
bne pad2
|
bnz pad2
|
||||||
|
|
||||||
; Read game pad 1
|
; Read game pad 1
|
||||||
|
|
||||||
pad1: lda JOY1 + 1
|
pad1: ldy JOY1 ; Allow JOY1 to be reread between interrupts
|
||||||
|
sty JOY1 + 2
|
||||||
|
|
||||||
|
lda JOY1 + 1
|
||||||
bit #%00001110
|
bit #%00001110
|
||||||
beq nes1
|
bze nes1
|
||||||
asl JOY1 ; Get SNES's B button
|
|
||||||
|
asl JOY1 + 2 ; Get SNES's B button
|
||||||
ror a ; Put it next to the A button
|
ror a ; Put it next to the A button
|
||||||
asl JOY1 ; Drop SNES's Y button
|
asl JOY1 + 2 ; Drop SNES's Y button
|
||||||
asl a ; Get the B button
|
asl a ; Get back the B button
|
||||||
ror JOY1
|
ror JOY1 + 2
|
||||||
asl a ; Get SNES's A button
|
asl a ; Get SNES's A button
|
||||||
ror JOY1 ; Make byte look like NES pad
|
ror JOY1 + 2 ; Make byte look like NES pad
|
||||||
nes1: lda JOY1
|
|
||||||
eor #%11111111 ; We don't want the pad's negative logic
|
nes1: lda JOY1 + 2
|
||||||
|
plp
|
||||||
|
eor #%11111111 ; (The controllers use negative logic)
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Read game pad 2
|
; Read game pad 2
|
||||||
|
|
||||||
pad2: lda JOY2 + 1
|
pad2: ldy JOY2
|
||||||
|
sty JOY2 + 2
|
||||||
|
|
||||||
|
lda JOY2 + 1
|
||||||
bit #%00001110
|
bit #%00001110
|
||||||
beq nes2
|
bze nes2
|
||||||
asl JOY2
|
|
||||||
|
asl JOY2 + 2
|
||||||
ror a
|
ror a
|
||||||
asl JOY2
|
asl JOY2 + 2
|
||||||
asl a
|
asl a
|
||||||
ror JOY2
|
ror JOY2 + 2
|
||||||
asl a
|
asl a
|
||||||
ror JOY2
|
ror JOY2 + 2
|
||||||
nes2: lda JOY2
|
|
||||||
|
nes2: lda JOY2 + 2
|
||||||
|
plp
|
||||||
eor #%11111111
|
eor #%11111111
|
||||||
rts
|
rts
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
;
|
;
|
||||||
; Address of the static standard joystick driver
|
; Address of the static standard joystick driver
|
||||||
;
|
;
|
||||||
; 2019-09-19, Greg King
|
; 2019-11-10, Greg King
|
||||||
;
|
;
|
||||||
; const void joy_static_stddrv[];
|
; const void joy_static_stddrv[];
|
||||||
;
|
;
|
||||||
|
|
||||||
.import _cx16_stdjoy_joy
|
.import _cx16_std_joy
|
||||||
.export _joy_static_stddrv := _cx16_stdjoy_joy
|
|
||||||
|
.export _joy_static_stddrv := _cx16_std_joy
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
;
|
;
|
||||||
; Name of the standard joystick driver
|
; Name of the standard joystick driver
|
||||||
;
|
;
|
||||||
; 2019-09-19, Greg King
|
; 2019-11-10, Greg King
|
||||||
;
|
;
|
||||||
; const char joy_stddrv[];
|
; const char joy_stddrv[];
|
||||||
;
|
;
|
||||||
@@ -10,4 +10,4 @@
|
|||||||
|
|
||||||
.rodata
|
.rodata
|
||||||
|
|
||||||
_joy_stddrv: .asciiz "cx16-stdjoy.joy"
|
_joy_stddrv: .asciiz "cx16-std.joy"
|
||||||
|
|||||||
20
libsrc/cx16/joyref.s
Normal file
20
libsrc/cx16/joyref.s
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
;
|
||||||
|
; 2019-11-14, Greg King
|
||||||
|
;
|
||||||
|
; Link an interrupt handler if joysticks are used by a program.
|
||||||
|
;
|
||||||
|
|
||||||
|
.interruptor joy_libref, 9
|
||||||
|
|
||||||
|
.include "cbm_kernal.inc"
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
|
||||||
|
joy_libref:
|
||||||
|
lda VERA::IRQ_FLAGS
|
||||||
|
lsr a
|
||||||
|
bcc not_vsync
|
||||||
|
jsr GETJOY ; Bit-bang game controllers
|
||||||
|
clc ; Let other Jiffy handlers run
|
||||||
|
not_vsync:
|
||||||
|
rts
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
;
|
;
|
||||||
; 2019-09-20, Greg King
|
; 2019-11-06, Greg King
|
||||||
;
|
;
|
||||||
; unsigned char kbhit (void);
|
; unsigned char kbhit (void);
|
||||||
; /* Returns non-zero (true) if a typed character is waiting. */
|
; /* Returns non-zero (true) if a typed character is waiting. */
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
.proc _kbhit
|
.proc _kbhit
|
||||||
ldx #>$0000 ; High byte of return
|
|
||||||
lda KEY_COUNT ; Get number of characters
|
lda KEY_COUNT ; Get number of characters
|
||||||
rts
|
tax ; High byte of return (only its zero/nonzero ...
|
||||||
|
rts ; ... state matters)
|
||||||
.endproc
|
.endproc
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
;
|
;
|
||||||
; 2019-09-22, Greg King
|
; 2019-11-05, Greg King
|
||||||
;
|
;
|
||||||
; CX16 Kernal functions
|
; CX16 Kernal functions
|
||||||
;
|
;
|
||||||
@@ -7,9 +7,10 @@
|
|||||||
.include "cbm_kernal.inc"
|
.include "cbm_kernal.inc"
|
||||||
|
|
||||||
.export GETJOY
|
.export GETJOY
|
||||||
|
.export MOUSE
|
||||||
|
.export SCRMOD
|
||||||
|
|
||||||
.export CLSALL
|
.export CLSALL
|
||||||
.export SWAPPER
|
|
||||||
.export JSRFAR
|
.export JSRFAR
|
||||||
.export INDFET
|
.export INDFET
|
||||||
.export INDSTA
|
.export INDSTA
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
;
|
;
|
||||||
; 2013-05-31, Oliver Schmidt
|
; 2013-05-31, Oliver Schmidt
|
||||||
; 2019-09-22, Greg King
|
; 2019-11-14, Greg King
|
||||||
;
|
;
|
||||||
|
|
||||||
.export em_libref
|
.export em_libref
|
||||||
.export joy_libref
|
|
||||||
.export mouse_libref
|
.export mouse_libref
|
||||||
.export ser_libref
|
.export ser_libref
|
||||||
.export tgi_libref
|
.export tgi_libref
|
||||||
@@ -12,7 +11,6 @@
|
|||||||
.import _exit
|
.import _exit
|
||||||
|
|
||||||
em_libref := _exit
|
em_libref := _exit
|
||||||
joy_libref := _exit
|
|
||||||
mouse_libref := _exit
|
mouse_libref := _exit
|
||||||
ser_libref := _exit
|
ser_libref := _exit
|
||||||
tgi_libref := _exit
|
tgi_libref := _exit
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ REM = $8f ; BASIC token-code
|
|||||||
NAME_LEN = 16 ; Maximum length of command-name
|
NAME_LEN = 16 ; Maximum length of command-name
|
||||||
|
|
||||||
; Get possible command-line arguments. Goes into the special ONCE segment,
|
; Get possible command-line arguments. Goes into the special ONCE segment,
|
||||||
; which may be reused after the startup code is run
|
; which may be reused after the startup code is run.
|
||||||
|
|
||||||
.segment "ONCE"
|
.segment "ONCE"
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ L2: lda BASIC_BUF,x
|
|||||||
bne L2
|
bne L2
|
||||||
ldy #1 * 2
|
ldy #1 * 2
|
||||||
|
|
||||||
; Find the next argument
|
; Find the next argument.
|
||||||
|
|
||||||
next: lda BASIC_BUF,x
|
next: lda BASIC_BUF,x
|
||||||
beq done ; End of line reached
|
beq done ; End of line reached
|
||||||
@@ -74,7 +74,7 @@ next: lda BASIC_BUF,x
|
|||||||
|
|
||||||
; Found start of next argument. We've incremented the pointer in X already, so
|
; 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
|
; 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
|
; will check now for a quoted argument, in which case, we will have to skip this
|
||||||
; first character.
|
; first character.
|
||||||
|
|
||||||
found: cmp #'"' ; Is the argument quoted?
|
found: cmp #'"' ; Is the argument quoted?
|
||||||
@@ -95,7 +95,7 @@ setterm:sta term ; Set end of argument marker
|
|||||||
iny
|
iny
|
||||||
inc __argc ; Found another arg
|
inc __argc ; Found another arg
|
||||||
|
|
||||||
; Search for the end of the argument
|
; Search for the end of the argument.
|
||||||
|
|
||||||
argloop:lda BASIC_BUF,x
|
argloop:lda BASIC_BUF,x
|
||||||
beq done
|
beq done
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
;
|
;
|
||||||
; 2019-09-20, Greg King
|
; 2019-11-06, Greg King
|
||||||
;
|
;
|
||||||
; void __fastcall__ set_tv (unsigned char);
|
; void __fastcall__ set_tv (unsigned char);
|
||||||
; /* Set the video mode the machine will use. */
|
; /* Set the video mode the machine will use. */
|
||||||
@@ -12,20 +12,18 @@
|
|||||||
|
|
||||||
.proc _set_tv
|
.proc _set_tv
|
||||||
php
|
php
|
||||||
pha
|
|
||||||
sei ; Don't let interrupts interfere
|
sei ; Don't let interrupts interfere
|
||||||
|
|
||||||
; Point to the video output register.
|
; Point to the video output register.
|
||||||
|
|
||||||
stz VERA::CTRL ; Use port 0
|
stz VERA::CTRL ; Use port 0
|
||||||
lda #<VERA::COMPOSER::VIDEO
|
ldx #<VERA::COMPOSER::VIDEO
|
||||||
ldx #>VERA::COMPOSER::VIDEO
|
ldy #>VERA::COMPOSER::VIDEO
|
||||||
ldy #^VERA::COMPOSER::VIDEO
|
stx VERA::ADDR
|
||||||
sta VERA::ADDR
|
sty VERA::ADDR+1
|
||||||
stx VERA::ADDR+1
|
ldx #^VERA::COMPOSER::VIDEO
|
||||||
sty VERA::ADDR+2
|
stx VERA::ADDR+2
|
||||||
|
|
||||||
pla
|
|
||||||
sta VERA::DATA0
|
sta VERA::DATA0
|
||||||
plp ; Re-enable interrupts
|
plp ; Re-enable interrupts
|
||||||
rts
|
rts
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
;
|
;
|
||||||
; 2012-09-30, Oliver Schmidt
|
; 2019-11-05, Greg King
|
||||||
; 2019-09-08, Greg King
|
|
||||||
;
|
;
|
||||||
|
|
||||||
.exportzp ST := $90 ; IEC status byte
|
.export ST: zp
|
||||||
|
|
||||||
|
.segment "EXTZP": zp
|
||||||
|
|
||||||
|
; This is a temporary hack.
|
||||||
|
|
||||||
|
; A zero-page copy of the IEC status byte.
|
||||||
|
; This is needed because the Commander X16's Kernal's status
|
||||||
|
; variable was moved out of the zero page. But, the common
|
||||||
|
; CBM file function modules import this as a zero-page variable.
|
||||||
|
|
||||||
|
ST: .res 1
|
||||||
|
|||||||
11
libsrc/cx16/tgi_stat_stddrv.s
Normal file
11
libsrc/cx16/tgi_stat_stddrv.s
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
;
|
||||||
|
; Address of the static standard TGI driver
|
||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; const void tgi_static_stddrv[];
|
||||||
|
;
|
||||||
|
|
||||||
|
.import _cx16_640x4c_tgi
|
||||||
|
|
||||||
|
.export _tgi_static_stddrv := _cx16_640x4c_tgi
|
||||||
13
libsrc/cx16/tgi_stddrv.s
Normal file
13
libsrc/cx16/tgi_stddrv.s
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
;
|
||||||
|
; Name of the standard TGI driver
|
||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; const char tgi_stddrv[];
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _tgi_stddrv
|
||||||
|
|
||||||
|
.rodata
|
||||||
|
|
||||||
|
_tgi_stddrv: .asciiz "cx16-640x4c.tgi"
|
||||||
@@ -1,30 +1,44 @@
|
|||||||
;
|
;
|
||||||
; 2009-09-07, Ullrich von Bassewitz
|
; 2019-11-06, Greg King
|
||||||
; 2019-09-23, Greg King
|
|
||||||
;
|
;
|
||||||
; unsigned __fastcall__ videomode (unsigned Mode);
|
; /* Video mode defines */
|
||||||
; /* Set the video mode, return the old mode. */
|
; #define VIDEOMODE_40x30 0x00
|
||||||
|
; #define VIDEOMODE_80x60 0x02
|
||||||
|
; #define VIDEOMODE_320x240 0x80
|
||||||
|
; #define VIDEOMODE_SWAP (-1)
|
||||||
|
;
|
||||||
|
; signed char __fastcall__ videomode (signed char Mode);
|
||||||
|
; /* Set the video mode, return the old mode.
|
||||||
|
; ** Return -1 if Mode isn't valid.
|
||||||
|
; ** Call with one of the VIDEOMODE_xx constants.
|
||||||
|
; */
|
||||||
;
|
;
|
||||||
|
|
||||||
.export _videomode
|
.export _videomode
|
||||||
.import SWAPPER
|
|
||||||
|
|
||||||
.include "cx16.inc"
|
.import SCRMOD
|
||||||
|
|
||||||
|
|
||||||
.proc _videomode
|
.proc _videomode
|
||||||
cmp LLEN ; Do we have this mode already?
|
tax
|
||||||
beq @L9
|
clc ; (Get old mode)
|
||||||
|
jsr SCRMOD
|
||||||
|
pha
|
||||||
|
txa
|
||||||
|
|
||||||
lda LLEN ; Get current mode ...
|
sec ; (Set new mode)
|
||||||
pha ; ... and save it
|
jsr SCRMOD
|
||||||
|
|
||||||
jsr SWAPPER ; Toggle the mode
|
pla ; Get back old mode
|
||||||
|
bcs @L1
|
||||||
|
ldx #>$0000 ; Clear high byte
|
||||||
|
rts
|
||||||
|
|
||||||
pla ; Get old mode into A
|
; The new mode is invalid. Go back to the old mode. Return -1.
|
||||||
|
|
||||||
; Done, old mode is in .A
|
@L1: sec
|
||||||
|
jsr SCRMOD
|
||||||
@L9: ldx #>$0000 ; Clear high byte
|
lda #<-1
|
||||||
|
tax
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;
|
;
|
||||||
; void waitvsync (void);
|
; void waitvsync (void);
|
||||||
;
|
;
|
||||||
; VERA's vertical sync. causes IRQs which increment the jiffy clock.
|
; VERA's vertical sync causes IRQs which increment the jiffy clock.
|
||||||
;
|
;
|
||||||
|
|
||||||
.export _waitvsync
|
.export _waitvsync
|
||||||
|
|||||||
15
libsrc/cx16/wherex.s
Normal file
15
libsrc/cx16/wherex.s
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; unsigned char wherex (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _wherex
|
||||||
|
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
.proc _wherex
|
||||||
|
lda CURS_X
|
||||||
|
ldx #>$0000
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
15
libsrc/cx16/wherey.s
Normal file
15
libsrc/cx16/wherey.s
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
;
|
||||||
|
; 2019-11-06, Greg King
|
||||||
|
;
|
||||||
|
; unsigned char wherey (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _wherey
|
||||||
|
|
||||||
|
.include "cx16.inc"
|
||||||
|
|
||||||
|
.proc _wherey
|
||||||
|
lda CURS_Y
|
||||||
|
ldx #>$0000
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
Reference in New Issue
Block a user