From d78133e1f00be19929ca6ee920c30f782c502e8b Mon Sep 17 00:00:00 2001 From: Greg King Date: Sat, 16 Nov 2019 13:11:40 -0500 Subject: [PATCH 095/170] Updated cx16 to match the Commander X16 ROMs and emulator, release 34. --- asminc/cbm_kernal.inc | 4 +- asminc/cx16.inc | 87 ++++++++----- cfg/cx16-asm.cfg | 3 +- cfg/cx16-bank.cfg | 2 +- cfg/cx16.cfg | 2 +- doc/cx16.sgml | 50 ++++--- include/cx16.h | 23 +++- libsrc/cx16/break.s | 21 ++- libsrc/cx16/conio.s | 9 -- libsrc/cx16/cpeekc.s | 2 +- libsrc/cx16/cpeekrevers.s | 2 +- libsrc/cx16/cputc.s | 4 +- libsrc/cx16/crt0.s | 22 ++-- libsrc/cx16/devnum.s | 8 -- libsrc/cx16/exec.c | 122 ++++++++++++++++++ libsrc/cx16/execvars.s | 16 +++ libsrc/cx16/filevars.s | 39 ++++++ libsrc/cx16/getdevice.s | 67 ++++++++++ libsrc/cx16/gotox.s | 13 ++ libsrc/cx16/gotoxy.s | 18 +++ libsrc/cx16/gotoy.s | 13 ++ libsrc/cx16/joy/{cx16-stdjoy.s => cx16-std.s} | 76 ++++++----- libsrc/cx16/joy_stat_stddrv.s | 7 +- libsrc/cx16/joy_stddrv.s | 4 +- libsrc/cx16/joyref.s | 20 +++ libsrc/cx16/kbhit.s | 6 +- libsrc/cx16/kernal.s | 5 +- libsrc/cx16/libref.s | 4 +- libsrc/cx16/mainargs.s | 8 +- libsrc/cx16/set_tv.s | 16 +-- libsrc/cx16/status.s | 16 ++- libsrc/cx16/tgi_stat_stddrv.s | 11 ++ libsrc/cx16/tgi_stddrv.s | 13 ++ libsrc/cx16/videomode.s | 48 ++++--- libsrc/cx16/waitvsync.s | 2 +- libsrc/cx16/wherex.s | 15 +++ libsrc/cx16/wherey.s | 15 +++ 37 files changed, 609 insertions(+), 184 deletions(-) delete mode 100644 libsrc/cx16/conio.s delete mode 100644 libsrc/cx16/devnum.s create mode 100644 libsrc/cx16/exec.c create mode 100644 libsrc/cx16/execvars.s create mode 100644 libsrc/cx16/filevars.s create mode 100644 libsrc/cx16/getdevice.s create mode 100644 libsrc/cx16/gotox.s create mode 100644 libsrc/cx16/gotoxy.s create mode 100644 libsrc/cx16/gotoy.s rename libsrc/cx16/joy/{cx16-stdjoy.s => cx16-std.s} (58%) create mode 100644 libsrc/cx16/joyref.s create mode 100644 libsrc/cx16/tgi_stat_stddrv.s create mode 100644 libsrc/cx16/tgi_stddrv.s create mode 100644 libsrc/cx16/wherex.s create mode 100644 libsrc/cx16/wherey.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 6e1e1604..a38836ce 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -7,18 +7,20 @@ .if .def(__CX16__) ; CX16 extended jump table GETJOY := $FF06 + MOUSE := $FF09 + SCRMOD := $FF5F .endif .if .def(__C128__) ; C128 extended jump table C64MODE := $FF4D + SWAPPER := $FF5F SETBNK := $FF68 .endif .if .def(__C128__) || .def(__CX16__) ; Extended jump table CLSALL := $FF4A - SWAPPER := $FF5F JSRFAR := $FF6E INDFET := $FF74 INDSTA := $FF77 diff --git a/asminc/cx16.inc b/asminc/cx16.inc index 5b46908d..1c22c99b 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -44,42 +44,55 @@ ; --------------------------------------------------------------------------- ; 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 +FNAM := $84 ; Pointer to filename +KTEMP2 := $86 ; 2 bytes for temporary storage +SCREEN_PTR := $88 ; Pointer to current row on text screen (16 bits) +IMPARM := $8A ; Pointer for PRIMM function + +; BASIC +TXTPTR := $EE ; Pointer into BASIC source code ; Page two -BASIC_BUF := $200 ; Location of command-line -BASIC_BUF_LEN = 89 ; Maximum length of command-line +BASIC_BUF := $0200 ; Location of command-line +BASIC_BUF_LEN = 81 ; Maximum length of command-line -CHARCOLOR := $286 -CURS_COLOR := $287 ; Color under the cursor +CURS_COLOR := $027E ; 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 @@ -122,6 +135,12 @@ NMIVec := $0318 INC8192 = 14 << 4 INC16384 = 15 << 4 .endenum + .enum ; Interrupt request flags + VERT_SYNC = %00000001 + RASTER = %00000010 + SPR_COLLIDED = %00000100 + UART_IRQ = %00001000 + .endenum ; Internal RAM and registers VRAM := $000000 .scope COMPOSER ; Display composer @@ -263,7 +282,7 @@ NMIVec := $0318 .endscope .endscope -; 65c22 +; 65C22 .struct VIA1 ; Versatile Interface Adapter .org $9F60 PRB .byte ; ROM bank, IEC (Port Register B) @@ -281,10 +300,10 @@ NMIVec := $0318 PRA2 .byte ; RAM bank (Port Register A without handshaking) .endstruct -; 65c22 +; 65C22 .struct VIA2 .org $9F70 - PRB .byte + PRB .byte ; Mouse communication ? PRA .byte ; NES controller communication DDRB .byte DDRA .byte diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg index 53f6da17..4228f6da 100644 --- a/cfg/cx16-asm.cfg +++ b/cfg/cx16-asm.cfg @@ -6,12 +6,13 @@ SYMBOLS { __HIMEM__: type = weak, value = $9F00; } 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; MAIN: file = %O, start = %S, size = __HIMEM__ - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = MAIN, type = ro, optional = yes; LOWCODE: load = MAIN, type = ro, optional = yes; diff --git a/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg index 52438fba..ff5dded3 100644 --- a/cfg/cx16-bank.cfg +++ b/cfg/cx16-bank.cfg @@ -11,7 +11,7 @@ SYMBOLS { __BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM } 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; HEADER: file = %O, define = yes, start = %S, size = $000D; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; diff --git a/cfg/cx16.cfg b/cfg/cx16.cfg index f912e0f8..c72f6c35 100644 --- a/cfg/cx16.cfg +++ b/cfg/cx16.cfg @@ -8,7 +8,7 @@ SYMBOLS { __HIMEM__: type = weak, value = $9F00; } 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; HEADER: file = %O, define = yes, start = %S, size = $000D; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; diff --git a/doc/cx16.sgml b/doc/cx16.sgml index b739e6a9..16e43db9 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -17,14 +17,14 @@ compiler. Overview

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. +the ROMs in Commodore's VIC-20 and 64C. It has a couple of I/O chips +(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 -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. -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 . Even functions marked as "platform dependent" may be available on more than one platform. Please see the function reference for more @@ -35,19 +35,20 @@ information. Binary format

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. +is a machine language program that's prepended with a 16-bit load address and 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 program-header +file and linker config. Memory layout

-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. +cc65-generated programs with the default setup run with the I/O area, RAM bank +zero, 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: @@ -76,6 +77,9 @@ The ld65 linker comes with a default config. file for the Commander X16, which is used via Default config. file ( @@ -138,6 +142,8 @@ url="funcref.html" name="function reference"> for declarations and usage. get_ostype() set_tv() videomode() +vpeek() +vpoke() waitvsync() @@ -157,6 +163,7 @@ declarations and usage. cbm_k_ckout() cbm_k_close() cbm_k_clrch() +cbm_k_getin() cbm_k_load() cbm_k_open() cbm_k_readst() @@ -217,13 +224,13 @@ No extended memory drivers are available currently for the CX16. Joystick drivers

The default drivers, - - 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 - buttons. Button A is the primary fire button. + buttons. Buttons A and B are the primary and secondary fire buttons.

@@ -248,9 +255,16 @@ any time. Some changes could make old programs fail to work. Other hints

+STOP and RUN codes

+ +The Escape code

-For an Esc, press Passing arguments to the program

@@ -274,7 +288,7 @@ supported directly by BASIC, the following syntax was chosen: Program return code

-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 brk_handler @@ -54,6 +55,7 @@ L1: lda #$0002 sta _brk_pc+1 jsr uservec ; Call the user's routine @@ -99,11 +100,9 @@ L1: lda # +#include +#include +#include +#include +#include + + +/* 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__); +} diff --git a/libsrc/cx16/execvars.s b/libsrc/cx16/execvars.s new file mode 100644 index 00000000..2df647a5 --- /dev/null +++ b/libsrc/cx16/execvars.s @@ -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 diff --git a/libsrc/cx16/filevars.s b/libsrc/cx16/filevars.s new file mode 100644 index 00000000..f3fa6466 --- /dev/null +++ b/libsrc/cx16/filevars.s @@ -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 diff --git a/libsrc/cx16/getdevice.s b/libsrc/cx16/getdevice.s new file mode 100644 index 00000000..9b554900 --- /dev/null +++ b/libsrc/cx16/getdevice.s @@ -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 diff --git a/libsrc/cx16/gotox.s b/libsrc/cx16/gotox.s new file mode 100644 index 00000000..1cd7c693 --- /dev/null +++ b/libsrc/cx16/gotox.s @@ -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 diff --git a/libsrc/cx16/gotoxy.s b/libsrc/cx16/gotoxy.s new file mode 100644 index 00000000..1c1b60e2 --- /dev/null +++ b/libsrc/cx16/gotoxy.s @@ -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 diff --git a/libsrc/cx16/gotoy.s b/libsrc/cx16/gotoy.s new file mode 100644 index 00000000..487cfa79 --- /dev/null +++ b/libsrc/cx16/gotoy.s @@ -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 diff --git a/libsrc/cx16/joy/cx16-stdjoy.s b/libsrc/cx16/joy/cx16-std.s similarity index 58% rename from libsrc/cx16/joy/cx16-stdjoy.s rename to libsrc/cx16/joy/cx16-std.s index 8c7ddd2f..b41c6606 100644 --- a/libsrc/cx16/joy/cx16-stdjoy.s +++ b/libsrc/cx16/joy/cx16-std.s @@ -1,8 +1,8 @@ ; ; 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" @@ -18,7 +18,7 @@ ; ------------------------------------------------------------------------ ; Header. Includes jump table - module_header _cx16_stdjoy_joy + module_header _cx16_std_joy ; Driver signature @@ -48,11 +48,10 @@ JOY_COUNT = 2 ; Number of joysticks we support .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 ; of memory available. -; Must return a JOY_ERR_xx code in a/x. -; +; Must return a JOY_ERR_xx code in .XA . INSTALL: lda #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: Read a particular joystick passed in .A . -READ: pha - jsr GETJOY - pla - bne pad2 +READ: php + bit #JOY_COUNT - $01 + sei + bnz pad2 ; 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 - beq nes1 - asl JOY1 ; Get SNES's B button + bze nes1 + + asl JOY1 + 2 ; 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 JOY1 + 2 ; Drop SNES's Y button + asl a ; Get back the B button + ror JOY1 + 2 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 + ror JOY1 + 2 ; Make byte look like NES pad + +nes1: lda JOY1 + 2 + plp + eor #%11111111 ; (The controllers use negative logic) rts ; Read game pad 2 -pad2: lda JOY2 + 1 +pad2: ldy JOY2 + sty JOY2 + 2 + + lda JOY2 + 1 bit #%00001110 - beq nes2 - asl JOY2 + bze nes2 + + asl JOY2 + 2 ror a - asl JOY2 + asl JOY2 + 2 asl a - ror JOY2 + ror JOY2 + 2 asl a - ror JOY2 -nes2: lda JOY2 + ror JOY2 + 2 + +nes2: lda JOY2 + 2 + plp eor #%11111111 rts diff --git a/libsrc/cx16/joy_stat_stddrv.s b/libsrc/cx16/joy_stat_stddrv.s index 0e1a3e94..08cd2f95 100644 --- a/libsrc/cx16/joy_stat_stddrv.s +++ b/libsrc/cx16/joy_stat_stddrv.s @@ -1,10 +1,11 @@ ; ; Address of the static standard joystick driver ; -; 2019-09-19, Greg King +; 2019-11-10, Greg King ; ; const void joy_static_stddrv[]; ; - .import _cx16_stdjoy_joy - .export _joy_static_stddrv := _cx16_stdjoy_joy + .import _cx16_std_joy + + .export _joy_static_stddrv := _cx16_std_joy diff --git a/libsrc/cx16/joy_stddrv.s b/libsrc/cx16/joy_stddrv.s index 4edf9afc..ff2f54de 100644 --- a/libsrc/cx16/joy_stddrv.s +++ b/libsrc/cx16/joy_stddrv.s @@ -1,7 +1,7 @@ ; ; Name of the standard joystick driver ; -; 2019-09-19, Greg King +; 2019-11-10, Greg King ; ; const char joy_stddrv[]; ; @@ -10,4 +10,4 @@ .rodata -_joy_stddrv: .asciiz "cx16-stdjoy.joy" +_joy_stddrv: .asciiz "cx16-std.joy" diff --git a/libsrc/cx16/joyref.s b/libsrc/cx16/joyref.s new file mode 100644 index 00000000..fb21918c --- /dev/null +++ b/libsrc/cx16/joyref.s @@ -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 diff --git a/libsrc/cx16/kbhit.s b/libsrc/cx16/kbhit.s index 8ceba64b..a73533e2 100644 --- a/libsrc/cx16/kbhit.s +++ b/libsrc/cx16/kbhit.s @@ -1,5 +1,5 @@ ; -; 2019-09-20, Greg King +; 2019-11-06, Greg King ; ; unsigned char kbhit (void); ; /* Returns non-zero (true) if a typed character is waiting. */ @@ -11,7 +11,7 @@ .proc _kbhit - ldx #>$0000 ; High byte of return lda KEY_COUNT ; Get number of characters - rts + tax ; High byte of return (only its zero/nonzero ... + rts ; ... state matters) .endproc diff --git a/libsrc/cx16/kernal.s b/libsrc/cx16/kernal.s index faf91385..97443c82 100644 --- a/libsrc/cx16/kernal.s +++ b/libsrc/cx16/kernal.s @@ -1,5 +1,5 @@ ; -; 2019-09-22, Greg King +; 2019-11-05, Greg King ; ; CX16 Kernal functions ; @@ -7,9 +7,10 @@ .include "cbm_kernal.inc" .export GETJOY + .export MOUSE + .export SCRMOD .export CLSALL - .export SWAPPER .export JSRFAR .export INDFET .export INDSTA diff --git a/libsrc/cx16/libref.s b/libsrc/cx16/libref.s index 54ebb91d..0d85c7cd 100644 --- a/libsrc/cx16/libref.s +++ b/libsrc/cx16/libref.s @@ -1,10 +1,9 @@ ; ; 2013-05-31, Oliver Schmidt -; 2019-09-22, Greg King +; 2019-11-14, Greg King ; .export em_libref - .export joy_libref .export mouse_libref .export ser_libref .export tgi_libref @@ -12,7 +11,6 @@ .import _exit em_libref := _exit -joy_libref := _exit mouse_libref := _exit ser_libref := _exit tgi_libref := _exit diff --git a/libsrc/cx16/mainargs.s b/libsrc/cx16/mainargs.s index fe4a071c..1764b5e2 100644 --- a/libsrc/cx16/mainargs.s +++ b/libsrc/cx16/mainargs.s @@ -33,7 +33,7 @@ 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 +; which may be reused after the startup code is run. .segment "ONCE" @@ -64,7 +64,7 @@ L2: lda BASIC_BUF,x bne L2 ldy #1 * 2 -; Find the next argument +; Find the next argument. next: lda BASIC_BUF,x 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 ; 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. found: cmp #'"' ; Is the argument quoted? @@ -95,7 +95,7 @@ setterm:sta term ; Set end of argument marker iny inc __argc ; Found another arg -; Search for the end of the argument +; Search for the end of the argument. argloop:lda BASIC_BUF,x beq done diff --git a/libsrc/cx16/set_tv.s b/libsrc/cx16/set_tv.s index 0cf49aff..8b802f32 100644 --- a/libsrc/cx16/set_tv.s +++ b/libsrc/cx16/set_tv.s @@ -1,5 +1,5 @@ ; -; 2019-09-20, Greg King +; 2019-11-06, Greg King ; ; void __fastcall__ set_tv (unsigned char); ; /* Set the video mode the machine will use. */ @@ -12,20 +12,18 @@ .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 - ldy #^VERA::COMPOSER::VIDEO - sta VERA::ADDR - stx VERA::ADDR+1 - sty VERA::ADDR+2 + ldx #VERA::COMPOSER::VIDEO + stx VERA::ADDR + sty VERA::ADDR+1 + ldx #^VERA::COMPOSER::VIDEO + stx VERA::ADDR+2 - pla sta VERA::DATA0 plp ; Re-enable interrupts rts diff --git a/libsrc/cx16/status.s b/libsrc/cx16/status.s index 6292dc27..e3446637 100644 --- a/libsrc/cx16/status.s +++ b/libsrc/cx16/status.s @@ -1,6 +1,16 @@ ; -; 2012-09-30, Oliver Schmidt -; 2019-09-08, Greg King +; 2019-11-05, 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 diff --git a/libsrc/cx16/tgi_stat_stddrv.s b/libsrc/cx16/tgi_stat_stddrv.s new file mode 100644 index 00000000..566a3639 --- /dev/null +++ b/libsrc/cx16/tgi_stat_stddrv.s @@ -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 diff --git a/libsrc/cx16/tgi_stddrv.s b/libsrc/cx16/tgi_stddrv.s new file mode 100644 index 00000000..0f77e734 --- /dev/null +++ b/libsrc/cx16/tgi_stddrv.s @@ -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" diff --git a/libsrc/cx16/videomode.s b/libsrc/cx16/videomode.s index 4582ec1b..e3a777b8 100644 --- a/libsrc/cx16/videomode.s +++ b/libsrc/cx16/videomode.s @@ -1,30 +1,44 @@ ; -; 2009-09-07, Ullrich von Bassewitz -; 2019-09-23, Greg King +; 2019-11-06, Greg King ; -; unsigned __fastcall__ videomode (unsigned Mode); -; /* Set the video mode, return the old mode. */ +; /* Video mode defines */ +; #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 - .import SWAPPER - .include "cx16.inc" + .import SCRMOD .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 + tax + clc ; (Get old mode) + jsr SCRMOD + pha + txa + + sec ; (Set new mode) + jsr SCRMOD + + pla ; Get back old mode + bcs @L1 + ldx #>$0000 ; Clear high byte + rts -; Done, old mode is in .A +; The new mode is invalid. Go back to the old mode. Return -1. -@L9: ldx #>$0000 ; Clear high byte +@L1: sec + jsr SCRMOD + lda #<-1 + tax rts .endproc diff --git a/libsrc/cx16/waitvsync.s b/libsrc/cx16/waitvsync.s index 3fb6354f..09d01c6a 100644 --- a/libsrc/cx16/waitvsync.s +++ b/libsrc/cx16/waitvsync.s @@ -3,7 +3,7 @@ ; ; 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 diff --git a/libsrc/cx16/wherex.s b/libsrc/cx16/wherex.s new file mode 100644 index 00000000..56f42359 --- /dev/null +++ b/libsrc/cx16/wherex.s @@ -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 diff --git a/libsrc/cx16/wherey.s b/libsrc/cx16/wherey.s new file mode 100644 index 00000000..396a2d14 --- /dev/null +++ b/libsrc/cx16/wherey.s @@ -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 -- 2.26.0