- the NEC PC-Engine (aka TurboGrafx-16).
- the Nintendo Entertainment System (NES) console.
- the Watara Supervision console.
+- the VTech Creativision console.
- the Oric Atmos.
- the Oric Telestrat.
- the Lynx console.
--- /dev/null
+;*
+;** VTech Creativision Definitions
+;*
+
+;** Screen
+SCREEN_ROWS = 24
+SCREEN_COLS = 32
+SCREEN_PTR = $3A
+CURSOR_X = $3C
+CURSOR_Y = $3D
+
+;** VDP
+VDP_CONTROL_W = $3001
+VDP_DATA_W = $3000
+VDP_STATUS_R = $2001
+VDP_DATA_R = $2000
+
+;** PIA
+PIA0_DATA = $1000
+PIA0_STATUS = $1001
+PIA1_DATA = $1002
+PIA1_STATUS = $1003
+
+;** General
+CH_VLINE = 33
+CH_HLINE = 34
+CH_ULCORNER = 35
+CH_URCORNER = 36
+CH_LLCORNER = 37
+CH_LRCORNER = 38
+
+;** I/O (Zero-page variables)
+ZP_KEYBOARD = $10
+ZP_JOY0_DIR = $11
+ZP_JOY1_DIR = $13
+ZP_JOY0_BUTTONS = $16
+ZP_JOY1_BUTTONS = $17
+
--- /dev/null
+SYMBOLS {
+ __STACKSIZE__: type = weak, value = $0180;
+}
+MEMORY {
+ ZP: file = "", define = yes, start = $0020, size = $00E0;
+ RAM: file = "", define = yes, start = $01FA, size = $0206;
+ ROM: file = %O, define = yes, start = $B000, size = $1000;
+}
+SEGMENTS {
+ ZEROPAGE: load = ZP, type = zp;
+ ZP: load = ZP, type = zp, optional = yes;
+ VECTORS: load = ROM, run = RAM, type = rw, define = yes;
+ DATA: load = ROM, run = RAM, type = rw, define = yes, start = $0204;
+ BSS: load = RAM, type = bss, define = yes;
+ ONCE: load = ROM, type = ro, optional = yes;
+ CODE: load = ROM, type = ro;
+ INIT: load = ROM, type = ro;
+ RODATA: load = ROM, type = ro;
+ AUDIO: load = ROM, type = ro, optional = yes, start = $BF00;
+ SETUP: load = ROM, type = ro, start = $BFE8;
+}
+FEATURES {
+ CONDES: type = constructor,
+ label = __CONSTRUCTOR_TABLE__,
+ count = __CONSTRUCTOR_COUNT__,
+ segment = INIT;
+ CONDES: type = destructor,
+ label = __DESTRUCTOR_TABLE__,
+ count = __DESTRUCTOR_COUNT__,
+ segment = RODATA;
+ CONDES: type = interruptor,
+ label = __INTERRUPTOR_TABLE__,
+ count = __INTERRUPTOR_COUNT__,
+ segment = RODATA,
+ import = __CALLIRQ__;
+}
--- /dev/null
+<!doctype linuxdoc system>
+
+<article>
+
+<title>VTech Creativision (aka Funvision) specific information for cc65
+<author><url url="mailto:polluks+cc65@sdf.lonestar.org" name="Stefan A. Haubenthal">
+<date>2016-04-14
+
+<abstract>
+An overview over the Creativision runtime system as it is implemented for the
+cc65 C compiler.
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect>Overview<p>
+
+This file contains an overview of the Creativision runtime system as it comes
+with the cc65 C compiler. It describes the memory layout, Creativision specific header
+files, available drivers, and any pitfalls specific to that platform.
+
+Please note that Creativision specific functions are just 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 Creativision target
+is a 4 kbyte machine language program. It is of course possible to change
+this behaviour by using one of the different linker configs.
+
+<sect>Memory layout<p>
+
+cc65 generated programs with the default setup run with the I/O area enabled,
+which gives a usable memory range of $B000 - $BEFF.
+More ROM may need additional bankswitching code.
+
+Special locations:
+
+<descrip>
+ <tag/Text screen/
+ The text screen is located at VRAM $1000.
+
+ <tag/Stack/
+ The C runtime stack is located at $3FF and growing downwards.
+
+ <tag/Heap/
+ The C heap is located at the end of the program and grows towards the C
+ runtime stack.
+
+</descrip><p>
+
+
+
+<sect>Platform specific header files<p>
+
+Programs containing Creativision specific code may use the <tt/creativision.h/ header file.
+
+
+<sect1>Creativision specific functions<p>
+
+<itemize>
+<item>bios_playsound
+<item>psg_delay
+<item>psg_outb
+<item>psg_silence
+</itemize>
+
+
+
+<!--<sect1>Hardware access<p>
+
+The following pseudo variables declared in the <tt/creativision.inc/ include file do
+allow access to hardware located in the address space.
+
+<descrip>
+
+ <tag><tt/VDP/</tag>
+ The <tt/VDP/ defines allow access to the video chip.
+
+</descrip><p>
+
+<descrip>
+
+ <tag><tt/PIA/</tag>
+ The <tt/PIA/ defines allow access to the I/O chip.
+
+</descrip><p>-->
+
+
+
+<sect>Loadable drivers<p>
+
+<sect1>Graphics drivers<p>
+
+No graphics drivers are currently available for the Creativision.
+
+
+<sect1>Extended memory drivers<p>
+
+No extended memory drivers are currently available for the Creativision.
+
+
+<sect1>Joystick drivers<p>
+
+<descrip>
+
+ <tag><tt/creativision-stdjoy.joy (creativisionstd_joy)/</tag>
+ A joystick driver for the standard joystick is available.
+
+</descrip><p>
+
+<sect1>Mouse drivers<p>
+
+No mouse drivers are currently available for the Creativision.
+
+
+<sect1>RS232 device drivers<p>
+
+No communication port drivers are currently available for the Creativision.
+
+
+
+<sect>Limitations<p>
+
+<sect1>Disk I/O<p>
+
+The existing library for the Creativision doesn't implement C file
+I/O. There are even no hacks for the <tt/read()/ and <tt/write()/ routines.
+
+To be more concrete, this limitation means that you cannot use any of the
+following functions (and a few others):
+
+<itemize>
+<item>fclose
+<item>fopen
+<item>fread
+<item>fprintf
+<item>fputc
+<item>fscanf
+<item>fwrite
+<item>...
+</itemize>
+
+
+
+<sect>Other hints<p>
+
+
+
+<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>
<tag><htmlurl url="cbm610.html" name="cbm610.html"></tag>
Topics specific to the Commodore 610.
+ <tag><htmlurl url="creativision.html" name="creativision.html"></tag>
+ Topics specific to the Creativision Console.
+
<tag><htmlurl url="lynx.html" name="lynx.html"></tag>
Topics specific to the Atari Lynx Game Console.
--- /dev/null
+/* CreatiVision Header */
+
+#ifndef _CVISION_H
+
+#define _CVISION_H
+
+#define CH_VLINE 33
+#define CH_HLINE 34
+#define CH_ULCORNER 35
+#define CH_URCORNER 36
+#define CH_LLCORNER 37
+#define CH_LRCORNER 38
+
+#define DYN_DRV 0
+
+/* Colours - from TMS9918 */
+#define C_TRANSPARENT 0
+#define C_BLACK 1
+#define C_MED_GREEN 2
+#define C_LIGHT_GREEN 3
+#define C_DARK_BLUE 4
+#define C_LIGHT_BLUE 5
+#define C_DARK_RED 6
+#define C_CYAN 7
+#define C_MED_RED 8
+#define C_LIGHT_RED 9
+#define C_DARK_YELLOW 10
+#define C_LIGHT_YELLOW 11
+#define C_DARK_GREEN 12
+#define C_MAGENTA 13
+#define C_GREY 14
+#define C_WHITE 15
+
+/* Joystick states */
+#define JOY_UP 5
+#define JOY_DOWN 1
+#define JOY_LEFT 7
+#define JOY_RIGHT 3
+#define JOY_LEFT_UP 6
+#define JOY_LEFT_DOWN 8
+#define JOY_RIGHT_UP 4
+#define JOY_RIGHT_DOWN 2
+#define JOY_LBUTTON 1
+#define JOY_RBUTTON 2
+
+/* Joystick values */
+#define JOY_LEFT_DIR 1
+#define JOY_RIGHT_DIR 2
+#define JOY_LEFT_BUTTONS 3
+#define JOY_RIGHT_BUTTONS 4
+
+/* Protos */
+void __fastcall__ psg_outb( unsigned char b );
+void __fastcall__ psg_delay( unsigned char b );
+void psg_silence( void );
+void __fastcall__ bios_playsound( void *a, unsigned char b);
+unsigned char __fastcall__ joystate( unsigned char which );
+
+#endif
atari2600 \
atari5200 \
atmos \
+ creativision \
$(CBMS) \
$(GEOS) \
gamate \
--- /dev/null
+;*
+;** _scrsize.s
+;*
+
+ .export screensize
+
+ .include "creativision.inc"
+
+.proc screensize
+
+ ldx #SCREEN_COLS
+ ldy #SCREEN_ROWS
+ rts
+
+.endproc
--- /dev/null
+; Boxchars
+
+boxchars:
+ ; Vertical Line
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+
+ ; Horizontal Line
+ .byte $00
+ .byte $00
+ .byte $00
+ .byte $FF
+ .byte $00
+ .byte $00
+ .byte $00
+ .byte $00
+
+ ; Top Left
+ .byte $00
+ .byte $00
+ .byte $00
+ .byte $1F
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+
+ ; Top Right
+ .byte $00
+ .byte $00
+ .byte $00
+ .byte $F8
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $18
+
+ ; Bottom Left
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $1F
+ .byte $00
+ .byte $00
+ .byte $00
+ .byte $00
+
+ ; Bottom Right
+ .byte $18
+ .byte $18
+ .byte $18
+ .byte $F8
+ .byte $00
+ .byte $00
+ .byte $00
+ .byte $00
--- /dev/null
+;*
+;* void cclearxy (unsigned char x, unsigned char y, unsigned char length);
+;* void cclear (unsigned char length);
+;*
+
+ .export _cclearxy, _cclear
+ .import popa, _gotoxy, cputdirect
+ .importzp tmp1
+
+_cclearxy:
+ pha ; Save length
+ jsr popa ; get Y
+ jsr _gotoxy
+ pla
+
+_cclear:
+ cmp #0 ; Zero length?
+ beq L2
+ sta tmp1
+
+L1: lda #$20 ; Space
+ jsr cputdirect
+ dec tmp1
+ bne L1
+
+L2: rts
--- /dev/null
+;* cgetc
+
+ .export _cgetc
+ .include "creativision.inc"
+
+_cgetc:
+ lda #$80
+
+L1: bit ZP_KEYBOARD
+ bpl L1
+
+ lda ZP_KEYBOARD
+ and #$7F
+ rts
--- /dev/null
+;* void chlinexy (unsigned char x, unsigned char y, unsigned char length);
+;* void chline (unsigned char length);
+
+ .export _chlinexy, _chline
+ .import popa, _gotoxy, cputdirect
+ .importzp tmp1
+
+ .include "creativision.inc"
+
+_chlinexy:
+ pha ; Save the length
+ jsr popa ; Get y
+ jsr _gotoxy ; Call this one, will pop params
+ pla ; Restore the length
+
+_chline:
+ cmp #0 ; Is the length zero?
+ beq L9 ; Jump if done
+ sta tmp1
+L1: lda #CH_HLINE ; Horizontal line, screen code
+ jsr cputdirect ; Direct output
+ dec tmp1
+ bne L1
+L9: rts
--- /dev/null
+;*
+;* clrscr
+;*
+;* NB: All screen functions assume Graphics Mode 1 in a default configuration.
+;* Therefore, this is hard coded to use $1000-$12FF as screen VRAM.
+
+ .export _clrscr
+ .include "creativision.inc"
+
+_clrscr:
+
+ sei ; Disable interrupts. Default INT handler reads VDP_STATUS
+ ; and would lose any setup done here.
+
+ lda #$00 ; VRAM offset low
+ sta VDP_CONTROL_W
+
+ lda #$50 ; VRAM offset high ($10 OR $40)
+ sta VDP_CONTROL_W
+
+ lda #$C0 ; Space from ROM setup
+
+ ldx #0
+ ldy #3
+
+L1: sta VDP_DATA_W
+ inx
+ bne L1
+ dey
+ bne L1
+
+ cli ; Let interrupts go again
+
+ lda #0
+ sta CURSOR_X
+ sta CURSOR_Y
+ sta <SCREEN_PTR
+ lda #$10
+ sta >SCREEN_PTR
+
+ rts
--- /dev/null
+;*
+;* unsigned char __fastcall__ textcolor (unsigned char color);
+;* unsigned char __fastcall__ bgcolor (unsigned char color);
+;* unsigned char __fastcall__ bordercolor (unsigned char color);
+;*
+
+ .export _textcolor, _bgcolor, _bordercolor
+ .import return0
+ .include "creativision.inc"
+
+_bordercolor = return0;
+_textcolor = return0;
+_bgcolor = return0;
--- /dev/null
+;
+; Written by Groepaz/Hitmen <groepaz@gmx.net>
+; Cleanup by Ullrich von Bassewitz <uz@cc65.org>
+;
+; void cputcxy (unsigned char x, unsigned char y, char c);
+; void cputc (char c);
+;
+
+ .export _cputcxy, _cputc, cputdirect, putchar
+ .export newline
+ .constructor initconio
+ .import popa, _gotoxy
+ .import setcursor
+
+ .importzp tmp3,tmp4
+
+ .include "creativision.inc"
+ .include "boxchars.inc"
+
+;-----------------------------------------------------------------------------
+
+.code
+
+_cputcxy:
+ pha ; Save C
+ jsr popa ; Get Y
+ jsr _gotoxy ; Set cursor, drop x
+ pla ; Restore C
+
+; Plot a character - also used as internal function
+
+_cputc: cmp #$0D ; CR?
+ bne L1
+ lda #0
+ sta CURSOR_X
+ beq plot ; Recalculate pointers
+
+L1: cmp #$0A ; LF?
+ beq newline ; Recalculate pointers
+
+; Printable char of some sort
+
+cputdirect:
+ jsr putchar ; Write the character to the screen
+
+; Advance cursor position
+
+advance:
+ ldy CURSOR_X
+ iny
+ cpy #SCREEN_COLS
+ bne L3
+ inc CURSOR_Y ; new line
+ ldy #0 ; + cr
+L3: sty CURSOR_X
+ jmp plot
+
+newline:
+ inc CURSOR_Y
+
+; Set cursor position, calculate RAM pointers
+
+plot: ldy CURSOR_X
+ ldx CURSOR_Y
+ jmp setcursor ; Set the new cursor
+
+
+; Write one character to the screen without doing anything else, return X
+; position in Y
+
+putchar:
+ cmp #$5B
+ bcc IS_UPPER
+
+ clc
+ sbc #$1F
+
+IS_UPPER:
+ cmp #$20
+ bcc BAD_CHAR
+
+ pha
+ lda SCREEN_PTR
+ sei
+ sta VDP_CONTROL_W
+ lda SCREEN_PTR+1
+ ora #$40
+ sta VDP_CONTROL_W
+ pla
+ clc
+ adc #160
+ sta VDP_DATA_W
+ cli
+
+BAD_CHAR:
+ jmp plot
+
+;-----------------------------------------------------------------------------
+; Initialize the conio subsystem. Code goes into the INIT segment, which may
+; be reused after startup.
+
+.segment "INIT"
+
+initconio:
+ lda #$0
+ sta SCREEN_PTR
+ lda #$10
+ sta SCREEN_PTR+1
+
+ ; Copy box characters to slot
+ sei
+ lda #08
+ sta VDP_CONTROL_W
+ lda #$46
+ sta VDP_CONTROL_W
+ ldx #0
+
+LL: lda boxchars,x
+ sta VDP_DATA_W
+ inx
+ cpx #48
+ bne LL
+
+ cli
+ jmp plot
--- /dev/null
+;
+; Startup code for cc65 (CreatiVision version)
+;
+
+ .export _exit
+ .export __STARTUP__ : absolute = 1 ; Mark as startup
+ .import zerobss, copydata
+ .import initlib, donelib, callmain
+ .import __VECTORS_LOAD__, __VECTORS_RUN__, __VECTORS_SIZE__
+ .import __ZP_LAST__, __STACKSIZE__, __RAM_START__
+
+ .include "zeropage.inc"
+
+; ------------------------------------------------------------------------
+
+entry:
+ ; Init the CPU
+ sei
+ cld
+
+ ; Copy the IRQ vectors
+ ldx #<__VECTORS_SIZE__ - 1
+: lda __VECTORS_LOAD__,x
+ sta __VECTORS_RUN__,x
+ dex
+ bpl :-
+
+ ; Setup the CPU stack ptr
+ ldx #<__RAM_START__ - 1
+ txs
+
+ ; Start interrupts
+ cli
+
+ ; Clear the BSS data
+ jsr zerobss
+
+ ; Copy data from ROM to RAM
+ jsr copydata
+
+ ; Setup the argument stack ptr
+ lda #<(__ZP_LAST__ + __STACKSIZE__)
+ ldx #>(__ZP_LAST__ + __STACKSIZE__)
+ sta sp
+ stx sp+1
+
+ ; Call module constructors
+ jsr initlib
+
+ ; Call main()
+ jsr callmain
+
+ ; Call module destructors. This is also the _exit entry.
+_exit: jsr donelib
+
+ ; TODO: Replace with some sort of reset
+loop: jmp loop
+
+; ------------------------------------------------------------------------
+; Define the IRQ vectors.
+
+.segment "VECTORS"
+
+irq1: jmp $FF3F
+irq2: jmp $FF52
+
+; ------------------------------------------------------------------------
+; Define CART setup values for BIOS.
+
+.segment "SETUP"
+
+ ; BIOS Jump Start
+ ; This is where the entry point of the program needs to be
+ .addr entry
+ .addr irq2
+
+ .res 4
+
+ ; VDP Setup
+ ; This sets to Graphics Mode 1
+ .byte $00 ; Register 0
+ .byte $C0 ; Register 1 16K RAM, Active Display, Mode 1
+ .byte $04 ; Register 2 Name Table at $1000 - $12FF
+ .byte $60 ; Register 3 Colour Table at $1800 - $181F
+ .byte $00 ; Register 4 Pattern Table at $0000 - $07FF
+ .byte $10 ; Register 5 Sprite Attribute at $0800 - $087F
+ .byte $01 ; Register 6 Sprite Pattern
+ .byte $F1 ; Register 7 Text colour Foreground / background
+
+ .res 4
+
+ ; BIOS Vector after NMI or RESET
+ ; Keeping with retail cartridges, we jump back to BIOS ROM and have it
+ ; setup zeropage etc, and show the Creativision logo and copyright.
+ .addr $F808
+
+ ; BIOS Short Interrupt Handler
+ ; Vectored from BIOS ROM:FE2C. This should contain a pointer to the user's
+ ; BIOS interrupt handler.
+ .addr irq1
+
+; ------------------------------------------------------------------------
--- /dev/null
+;
+; Ullrich von Bassewitz, 02.06.1998
+;
+; Character specification table.
+;
+
+; The tables are readonly, put them into the rodata segment
+
+.rodata
+
+; The following 256 byte wide table specifies attributes for the isxxx type
+; of functions. Doing it by a table means some overhead in space, but it
+; has major advantages:
+;
+; * It is fast. If it were'nt for the slow parameter passing of cc65, one
+; could even define macros for the isxxx functions (this is usually
+; done on other platforms).
+;
+; * It is highly portable. The only unportable part is the table itself,
+; all real code goes into the common library.
+;
+; * We save some code in the isxxx functions.
+;
+;
+; Bit assignments:
+;
+; 0 - Lower case char
+; 1 - Upper case char
+; 2 - Numeric digit
+; 3 - Hex digit (both, lower and upper)
+; 4 - Control character
+; 5 - The space character itself
+; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v')
+; 7 - Space or tab character
+
+ .export __ctype
+
+__ctype:
+
+.repeat 2 ; 2 times for normal and inverted
+
+ .byte $10 ; 0/00 ___ctrl_@___
+ .byte $10 ; 1/01 ___ctrl_A___
+ .byte $10 ; 2/02 ___ctrl_B___
+ .byte $10 ; 3/03 ___ctrl_C___
+ .byte $10 ; 4/04 ___ctrl_D___
+ .byte $10 ; 5/05 ___ctrl_E___
+ .byte $10 ; 6/06 ___ctrl_F___
+ .byte $10 ; 7/07 ___ctrl_G___
+ .byte $10 ; 8/08 ___ctrl_H___
+ .byte $D0 ; 9/09 ___ctrl_I___
+ .byte $50 ; 10/0a ___ctrl_J___
+ .byte $50 ; 11/0b ___ctrl_K___
+ .byte $50 ; 12/0c ___ctrl_L___
+ .byte $50 ; 13/0d ___ctrl_M___
+ .byte $10 ; 14/0e ___ctrl_N___
+ .byte $10 ; 15/0f ___ctrl_O___
+ .byte $10 ; 16/10 ___ctrl_P___
+ .byte $10 ; 17/11 ___ctrl_Q___
+ .byte $10 ; 18/12 ___ctrl_R___
+ .byte $10 ; 19/13 ___ctrl_S___
+ .byte $10 ; 20/14 ___ctrl_T___
+ .byte $10 ; 21/15 ___ctrl_U___
+ .byte $10 ; 22/16 ___ctrl_V___
+ .byte $10 ; 23/17 ___ctrl_W___
+ .byte $10 ; 24/18 ___ctrl_X___
+ .byte $10 ; 25/19 ___ctrl_Y___
+ .byte $10 ; 26/1a ___ctrl_Z___
+ .byte $10 ; 27/1b ___ctrl_[___
+ .byte $10 ; 28/1c ___ctrl_\___
+ .byte $10 ; 29/1d ___ctrl_]___
+ .byte $10 ; 30/1e ___ctrl_^___
+ .byte $10 ; 31/1f ___ctrl_____
+ .byte $A0 ; 32/20 ___SPACE___
+ .byte $00 ; 33/21 _____!_____
+ .byte $00 ; 34/22 _____"_____
+ .byte $00 ; 35/23 _____#_____
+ .byte $00 ; 36/24 _____$_____
+ .byte $00 ; 37/25 _____%_____
+ .byte $00 ; 38/26 _____&_____
+ .byte $00 ; 39/27 _____'_____
+ .byte $00 ; 40/28 _____(_____
+ .byte $00 ; 41/29 _____)_____
+ .byte $00 ; 42/2a _____*_____
+ .byte $00 ; 43/2b _____+_____
+ .byte $00 ; 44/2c _____,_____
+ .byte $00 ; 45/2d _____-_____
+ .byte $00 ; 46/2e _____._____
+ .byte $00 ; 47/2f _____/_____
+ .byte $0C ; 48/30 _____0_____
+ .byte $0C ; 49/31 _____1_____
+ .byte $0C ; 50/32 _____2_____
+ .byte $0C ; 51/33 _____3_____
+ .byte $0C ; 52/34 _____4_____
+ .byte $0C ; 53/35 _____5_____
+ .byte $0C ; 54/36 _____6_____
+ .byte $0C ; 55/37 _____7_____
+ .byte $0C ; 56/38 _____8_____
+ .byte $0C ; 57/39 _____9_____
+ .byte $00 ; 58/3a _____:_____
+ .byte $00 ; 59/3b _____;_____
+ .byte $00 ; 60/3c _____<_____
+ .byte $00 ; 61/3d _____=_____
+ .byte $00 ; 62/3e _____>_____
+ .byte $00 ; 63/3f _____?_____
+
+ .byte $00 ; 64/40 _____@_____
+ .byte $0A ; 65/41 _____A_____
+ .byte $0A ; 66/42 _____B_____
+ .byte $0A ; 67/43 _____C_____
+ .byte $0A ; 68/44 _____D_____
+ .byte $0A ; 69/45 _____E_____
+ .byte $0A ; 70/46 _____F_____
+ .byte $02 ; 71/47 _____G_____
+ .byte $02 ; 72/48 _____H_____
+ .byte $02 ; 73/49 _____I_____
+ .byte $02 ; 74/4a _____J_____
+ .byte $02 ; 75/4b _____K_____
+ .byte $02 ; 76/4c _____L_____
+ .byte $02 ; 77/4d _____M_____
+ .byte $02 ; 78/4e _____N_____
+ .byte $02 ; 79/4f _____O_____
+ .byte $02 ; 80/50 _____P_____
+ .byte $02 ; 81/51 _____Q_____
+ .byte $02 ; 82/52 _____R_____
+ .byte $02 ; 83/53 _____S_____
+ .byte $02 ; 84/54 _____T_____
+ .byte $02 ; 85/55 _____U_____
+ .byte $02 ; 86/56 _____V_____
+ .byte $02 ; 87/57 _____W_____
+ .byte $02 ; 88/58 _____X_____
+ .byte $02 ; 89/59 _____Y_____
+ .byte $02 ; 90/5a _____Z_____
+ .byte $00 ; 91/5b _____[_____
+ .byte $00 ; 92/5c _____\_____
+ .byte $00 ; 93/5d _____]_____
+ .byte $00 ; 94/5e _____^_____
+ .byte $00 ; 95/5f _UNDERLINE_
+ .byte $00 ; 96/60 ___grave___
+ .byte $09 ; 97/61 _____a_____
+ .byte $09 ; 98/62 _____b_____
+ .byte $09 ; 99/63 _____c_____
+ .byte $09 ; 100/64 _____d_____
+ .byte $09 ; 101/65 _____e_____
+ .byte $09 ; 102/66 _____f_____
+ .byte $01 ; 103/67 _____g_____
+ .byte $01 ; 104/68 _____h_____
+ .byte $01 ; 105/69 _____i_____
+ .byte $01 ; 106/6a _____j_____
+ .byte $01 ; 107/6b _____k_____
+ .byte $01 ; 108/6c _____l_____
+ .byte $01 ; 109/6d _____m_____
+ .byte $01 ; 110/6e _____n_____
+ .byte $01 ; 111/6f _____o_____
+ .byte $01 ; 112/70 _____p_____
+ .byte $01 ; 113/71 _____q_____
+ .byte $01 ; 114/72 _____r_____
+ .byte $01 ; 115/73 _____s_____
+ .byte $01 ; 116/74 _____t_____
+ .byte $01 ; 117/75 _____u_____
+ .byte $01 ; 118/76 _____v_____
+ .byte $01 ; 119/77 _____w_____
+ .byte $01 ; 120/78 _____x_____
+ .byte $01 ; 121/79 _____y_____
+ .byte $01 ; 122/7a _____z_____
+ .byte $00 ; 123/7b _____{_____
+ .byte $00 ; 124/7c _____|_____
+ .byte $00 ; 125/7d _____}_____
+ .byte $00 ; 126/7e _____~_____
+ .byte $40 ; 127/7f ____DEL____
+
+.endrepeat
--- /dev/null
+;
+; Ullrich von Bassewitz, 08.08.1998
+;
+; void cvlinexy (unsigned char x, unsigned char y, unsigned char length);
+; void cvline (unsigned char length);
+;
+
+ .export _cvlinexy, _cvline
+ .import popa, _gotoxy, putchar, newline
+ .importzp tmp1
+
+ .include "creativision.inc"
+
+_cvlinexy:
+ pha ; Save the length
+ jsr popa ; Get y
+ jsr _gotoxy ; Call this one, will pop params
+ pla ; Restore the length and run into _cvline
+
+_cvline:
+ cmp #0 ; Is the length zero?
+ beq L9 ; Jump if done
+ sta tmp1
+L1: lda #CH_VLINE ; Vertical bar
+ jsr putchar ; Write, no cursor advance
+ jsr newline ; Advance cursor to next line
+ dec tmp1
+ bne L1
+L9: rts
--- /dev/null
+;
+; Ullrich von Bassewitz, 2003-05-02
+;
+; void gotox (unsigned char x);
+;
+
+ .export _gotox
+ .import setcursor
+
+ .include "creativision.inc"
+
+.proc _gotox
+
+ sta CURSOR_X ; Set new position
+ tay
+ ldx CURSOR_Y
+ jmp setcursor ; Set the cursor to the new position
+
+.endproc
--- /dev/null
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; void gotoxy (unsigned char x, unsigned char y);
+;
+
+ .export _gotoxy
+ .import setcursor
+ .import popa
+
+ .include "creativision.inc"
+
+.proc _gotoxy
+
+ sta CURSOR_Y ; Set Y
+ jsr popa ; Get X
+ sta CURSOR_X ; Set X
+ tay
+ ldx CURSOR_Y
+ jmp setcursor ; Set the cursor position
+
+.endproc
--- /dev/null
+;
+; Ullrich von Bassewitz, 2003-05-02
+;
+; void gotoy (unsigned char y);
+;
+
+ .export _gotoy
+ .import setcursor
+
+ .include "creativision.inc"
+
+.proc _gotoy
+
+ sta CURSOR_Y ; Set new position
+ tax
+ ldy CURSOR_X
+ jmp setcursor ; Set the cursor to the new position
+
+.endproc
--- /dev/null
+;*
+;* Creativision Joystick Function
+;*
+;* unsigned char __fastcall__ joystate(unsigned char joy);
+;*
+;* JOY_1 -> Return Left Joystick direction
+;* JOY_2 -> Return Right Joystick direction
+;* JOY_3 -> Return Left Joystick buttons
+;* JOY_4 -> Return Right Joystick buttons
+;*
+;* Will only work if interrupts are enabled.
+
+ .export _joystate
+ .include "creativision.inc"
+
+_joystate:
+ cmp #1 ; Left Direction
+ bne l1
+
+ lda $11
+ beq l5
+ and #$0F
+ lsr a
+ tax
+ inx
+ txa
+ rts
+
+l1: cmp #2 ; Right Direction
+ bne l2
+
+ lda $13
+ beq l5
+ and #$0F
+ lsr a
+ tax
+ inx
+ txa
+ rts
+
+l2: cmp #3 ; Left Buttons
+ bne l3
+
+ lda $16
+ beq l5
+ and #$0F
+ rts
+
+l3: cmp #4
+ bne l4
+
+ lda $17
+ beq l5
+ and #$0F
+ rts
+
+l4: lda #0
+l5: rts
--- /dev/null
+;
+; Standard joystick driver for the Creativision.
+;
+; Christian Groessler, 2017-02-06
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "creativision.inc"
+
+ .macpack module
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ module_header _creativisionstd_joy
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Library reference
+
+ .addr $0000
+
+; Button state masks (8 values)
+
+ .byte $10 ; JOY_UP
+ .byte $04 ; JOY_DOWN
+ .byte $20 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $01 ; JOY_FIRE (button #1)
+ .byte $02 ; JOY_FIRE2 (button #2)
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READJOY
+ .addr 0 ; IRQ entry not used
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+; ------------------------------------------------------------------------
+; Code
+
+ .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 an JOY_ERR_xx code in a/x.
+;
+
+INSTALL:
+ lda #JOY_ERR_OK
+ ldx #0
+; rts ; Fall through
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; COUNT: Return the total number of available joysticks in a/x.
+;
+
+COUNT:
+ lda #<JOY_COUNT
+ ldx #>JOY_COUNT
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READJOY:
+ and #1 ; fix joystick number
+ bne READJOY_1 ; read right joystick
+
+; Read left joystick
+
+ ldx ZP_JOY0_DIR
+ lda ZP_JOY0_BUTTONS
+ jmp convert ; convert joystick state to sane cc65 values
+
+; Read right joystick
+
+READJOY_1:
+
+ ldx ZP_JOY1_DIR
+ lda ZP_JOY1_BUTTONS
+ lsr a
+ lsr a
+ ;jmp convert ; convert joystick state to sane cc65 values
+ ; fall thru...
+
+; ------------------------------------------------------------------------
+; convert: make runtime lib compatible values
+; A - buttons
+; X - direction
+;
+
+convert:
+ ldy #0
+ sty retval ; initialize return value
+
+; ------
+; buttons:
+ ; Port values are for the left hand joystick (right hand joystick
+ ; values were shifted to the right to be identical).
+ ; Why are there two bits indicating a pressed trigger?
+ ; According to the "Second book of programs for the Dick Smith Wizard"
+ ; (pg. 88ff), the left hand fire button gives the value of
+ ; %00010001 and the right hand button gives %00100010
+ ; Why two bits? Am I missing something? Can there be cases that just
+ ; one of those bits is set?
+ ; We just test if any of those two bits is not zero...
+
+ tay
+ and #%00010001
+ beq cnv_1
+
+ inc retval ; left button pressed
+
+cnv_1: tya
+ and #%00100010
+ beq cnv_2
+
+ lda #$02
+ ora retval
+ sta retval ; right button pressed
+
+; ------
+; direction:
+cnv_2: txa
+ ; tested with https://sourceforge.net/projects/creativisionemulator
+ ; $49 - %01001001 - up
+ ; $41 - %01000001 - down
+ ; $4D - %01001101 - left
+ ; $45 - %01000101 - right
+ ;
+ ; are these correct? "Second book of programs for the Dick Smith Wizard" pg. 85 says something different
+ ; ignored for now...
+ ; $85 - %10000101 - up + right
+ ; $8D - %10001101 - down + left
+ ; $89 - %10001001 - up + left
+ ; $85 - %10000101 - down + right (emulator bug?)
+
+ bit testbit ; bit #0 set?
+ beq done ; no, no direction
+
+ and #%00001100 ; mask out other bits
+ tax
+ lda #%00000100 ; init bitmask
+loop: dex
+ bmi done2
+ asl a
+ bne loop
+
+done2: ora retval
+ rts
+
+done: lda retval
+ rts
+
+; ------------------------------------------------------------------------
+;
+ .data
+testbit:.byte $01
+
+; ------------------------------------------------------------------------
+;
+ .bss
+retval: .res 0
--- /dev/null
+;
+; Address of the static standard joystick driver
+;
+; Christian Groessler, 2017-02-06
+;
+; const void joy_static_stddrv[];
+;
+
+ .export _joy_static_stddrv
+ .import _creativisionstd_joy
+
+_joy_static_stddrv := _creativisionstd_joy
--- /dev/null
+;
+; Oliver Schmidt, 2013-05-31
+;
+
+ .export joy_libref
+ .import _exit
+
+joy_libref := _exit
--- /dev/null
+;
+; Ullrich von Bassewitz, 2003-03-07
+;
+; Setup arguments for main
+;
+
+
+ .constructor initmainargs, 24
+ .import __argc, __argv
+
+
+;---------------------------------------------------------------------------
+; Get possible command-line arguments. Goes into the special INIT segment,
+; which may be reused after the startup code is run
+
+.segment "INIT"
+
+.proc initmainargs
+
+ rts
+
+.endproc
--- /dev/null
+; void __fastcall__ psg_outb( unsigned char b );
+; void __fastcall__ psg_delayms( unsigned char c);
+; void __fastcall__ bios_playsound( void *b, unsigned char c);
+; void psg_silence( void );
+
+ .export _psg_outb, _psg_silence, _psg_delay
+ .export _bios_playsound
+ .import popa
+ .include "creativision.inc"
+
+_psg_outb:
+
+ ;* Let BIOS output the value
+ jmp $FE77
+
+_psg_silence:
+
+ jmp $FE54
+
+
+_psg_delay:
+
+ tay
+l1: lda #200
+l2: sbc #1
+ bne l2
+
+ lda #200
+l3: sbc #1
+ bne l3
+
+ dey
+ bne l1
+
+ rts
+
+
+;* Creativision Sound Player
+;*
+;* Based on BIOS sound player.
+;* Pass a pointer to a set of note triples, terminated with a tempo byte
+;* and the len (max 255)
+
+_bios_playsound:
+
+ pha ; Save Length Byte
+ sei
+
+ lda #$D5 ; BIOS volume table low
+ sta $4
+ lda #$FC ; BIOS volume table high
+ sta $5
+
+ jsr popa ; Get Sound table pointer low
+ sta $0
+ jsr popa ; Get Sound table pointer high
+ sta $1
+
+ pla
+ tay ; Put length in Y
+ dey
+ php
+ jmp $FBED ; Let BIOS do it's thing
--- /dev/null
+;
+; Written by Groepaz/Hitmen <groepaz@gmx.net>
+; Cleanup by Ullrich von Bassewitz <uz@cc65.org>
+;
+; Set the cursor position
+
+ .export setcursor
+
+ .include "creativision.inc"
+
+;-----------------------------------------------------------------------------
+
+.proc setcursor
+
+ tya
+ clc
+ adc addrlo,x
+ sta SCREEN_PTR
+
+ lda addrhi,x
+ adc #0
+ sta SCREEN_PTR+1
+ rts
+
+.endproc
+
+;-----------------------------------------------------------------------------
+; Tables with screen addresses
+
+addrlo: .repeat SCREEN_ROWS,line
+ .byte <($1000+(line*SCREEN_COLS))
+ .endrepeat
+
+addrhi: .repeat SCREEN_ROWS,line
+ .byte >($1000+(line*SCREEN_COLS))
+ .endrepeat
--- /dev/null
+;
+; Ullrich von Bassewitz, 2003-08-12
+;
+; 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 "CREATIVISION"
--- /dev/null
+;
+; Ullrich von Bassewitz, 2003-05-02
+;
+; unsigned char wherex (void);
+;
+
+ .export _wherex
+ .include "creativision.inc"
+
+.proc _wherex
+
+ lda CURSOR_X
+ ldx #$00
+ rts
+
+.endproc
--- /dev/null
+;
+; Ullrich von Bassewitz, 2003-05-02
+;
+; unsigned char wherey (void);
+;
+
+ .export _wherey
+ .include "creativision.inc"
+
+.proc _wherey
+
+ lda CURSOR_Y
+ ldx #$00
+ rts
+
+.endproc
NewSymbol ("__GEOS_CBM__", 1);
break;
+ case TGT_CREATIVISION:
+ NewSymbol ("__CREATIVISION__", 1);
+ break;
+
case TGT_GEOS_APPLE:
NewSymbol ("__GEOS__", 1);
NewSymbol ("__GEOS_APPLE__", 1);
DefineNumericMacro ("__GEOS_CBM__", 1);
break;
+ case TGT_CREATIVISION:
+ DefineNumericMacro ("__CREATIVISION__", 1);
+ break;
+
case TGT_GEOS_APPLE:
DefineNumericMacro ("__GEOS__", 1);
DefineNumericMacro ("__GEOS_APPLE__", 1);
/* One entry in the target map */
typedef struct TargetEntry TargetEntry;
struct TargetEntry {
- char Name[12]; /* Target name */
+ char Name[13]; /* Target name */
target_t Id; /* Target id */
};
** Allows multiple entries for one target id (target name aliases).
*/
static const TargetEntry TargetMap[] = {
- { "apple2", TGT_APPLE2 },
- { "apple2enh", TGT_APPLE2ENH },
- { "atari", TGT_ATARI },
- { "atari2600", TGT_ATARI2600 },
- { "atari5200", TGT_ATARI5200 },
- { "atarixl", TGT_ATARIXL },
- { "atmos", TGT_ATMOS },
- { "bbc", TGT_BBC },
- { "c128", TGT_C128 },
- { "c16", TGT_C16 },
- { "c64", TGT_C64 },
- { "c65", TGT_C65 },
- { "cbm510", TGT_CBM510 },
- { "cbm610", TGT_CBM610 },
- { "gamate", TGT_GAMATE },
- { "geos", TGT_GEOS_CBM },
- { "geos-apple", TGT_GEOS_APPLE },
- { "geos-cbm", TGT_GEOS_CBM },
- { "lunix", TGT_LUNIX },
- { "lynx", TGT_LYNX },
- { "module", TGT_MODULE },
- { "nes", TGT_NES },
- { "none", TGT_NONE },
- { "osic1p", TGT_OSIC1P },
- { "pce", TGT_PCENGINE },
- { "pet", TGT_PET },
- { "plus4", TGT_PLUS4 },
- { "sim6502", TGT_SIM6502 },
- { "sim65c02", TGT_SIM65C02 },
- { "supervision", TGT_SUPERVISION },
- { "telestrat", TGT_TELESTRAT },
- { "vic20", TGT_VIC20 },
+ { "apple2", TGT_APPLE2 },
+ { "apple2enh", TGT_APPLE2ENH },
+ { "atari", TGT_ATARI },
+ { "atari2600", TGT_ATARI2600 },
+ { "atari5200", TGT_ATARI5200 },
+ { "atarixl", TGT_ATARIXL },
+ { "atmos", TGT_ATMOS },
+ { "bbc", TGT_BBC },
+ { "c128", TGT_C128 },
+ { "c16", TGT_C16 },
+ { "c64", TGT_C64 },
+ { "c65", TGT_C65 },
+ { "cbm510", TGT_CBM510 },
+ { "cbm610", TGT_CBM610 },
+ { "creativision", TGT_CREATIVISION },
+ { "gamate", TGT_GAMATE },
+ { "geos", TGT_GEOS_CBM },
+ { "geos-apple", TGT_GEOS_APPLE },
+ { "geos-cbm", TGT_GEOS_CBM },
+ { "lunix", TGT_LUNIX },
+ { "lynx", TGT_LYNX },
+ { "module", TGT_MODULE },
+ { "nes", TGT_NES },
+ { "none", TGT_NONE },
+ { "osic1p", TGT_OSIC1P },
+ { "pce", TGT_PCENGINE },
+ { "pet", TGT_PET },
+ { "plus4", TGT_PLUS4 },
+ { "sim6502", TGT_SIM6502 },
+ { "sim65c02", TGT_SIM65C02 },
+ { "supervision", TGT_SUPERVISION },
+ { "telestrat", TGT_TELESTRAT },
+ { "vic20", TGT_VIC20 },
};
#define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0]))
{ "apple2", CPU_6502, BINFMT_BINARY, CTNone },
{ "apple2enh", CPU_65C02, BINFMT_BINARY, CTNone },
{ "geos-cbm", CPU_6502, BINFMT_BINARY, CTNone },
+ { "creativision", CPU_6502, BINFMT_BINARY, CTNone },
{ "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone },
{ "lunix", CPU_6502, BINFMT_O65, CTNone },
{ "atmos", CPU_6502, BINFMT_BINARY, CTNone },
TGT_APPLE2,
TGT_APPLE2ENH,
TGT_GEOS_CBM,
+ TGT_CREATIVISION,
TGT_GEOS_APPLE,
TGT_LUNIX,
TGT_ATMOS,
/* Collection of target properties */
typedef struct TargetProperties TargetProperties;
struct TargetProperties {
- const char Name[12]; /* Name of the target */
+ const char Name[13]; /* Name of the target */
cpu_t DefaultCPU; /* Default CPU for this target */
unsigned char BinFmt; /* Default binary format for this target */
const unsigned char* CharMap; /* Character translation table */