From 55f9e6ac2555d31517bf96d5d910161b329735a7 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Mon, 20 May 2013 20:35:42 +0200 Subject: [PATCH] Added 'sim6502' and 'sim65C02' targets. The targets allow to run cc65 programs in the sim65 exection einvironment. As there are no "real" i/o facilities there's no need for header files. Paravirtualized entry points are mapped to $FFF0 ff. There's a large cc65 progam area from $0200-$FFEF. The binary format includes a one-byte header indicating the required execution environment: The value 0 means 6502 and the value 1 means 65C02. The load adress for the binary is fixed to $0200. Note: Running sim65C02 programs currently doesn't work bcause sim65 doesn't actually implement 65C02 opcodes. --- cfg/sim6502.cfg | 35 +++++++++ cfg/sim65c02.cfg | 35 +++++++++ libsrc/Makefile | 4 + libsrc/dbg/dbg.c | 2 +- libsrc/sim6502/crt0.s | 32 ++++++++ libsrc/sim6502/ctype.s | 159 ++++++++++++++++++++++++++++++++++++++ libsrc/sim6502/errno.s | 14 ++++ libsrc/sim6502/exehdr.s | 13 ++++ libsrc/sim6502/paravirt.s | 16 ++++ src/ca65/main.c | 8 ++ src/cc65/main.c | 8 ++ src/common/target.c | 4 + src/common/target.h | 2 + 13 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 cfg/sim6502.cfg create mode 100644 cfg/sim65c02.cfg create mode 100644 libsrc/sim6502/crt0.s create mode 100644 libsrc/sim6502/ctype.s create mode 100644 libsrc/sim6502/errno.s create mode 100644 libsrc/sim6502/exehdr.s create mode 100644 libsrc/sim6502/paravirt.s diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg new file mode 100644 index 000000000..edb630d7f --- /dev/null +++ b/cfg/sim6502.cfg @@ -0,0 +1,35 @@ +SYMBOLS { + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack +} +MEMORY { + ZP: file = "", start = $0000, size = $001A; + HEADER: file = %O, start = $0000, size = $0001; + RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; +} +SEGMENTS { + EXEHDR: load = HEADER, type = ro; + STARTUP: load = RAM, type = ro; + LOWCODE: load = RAM, type = ro, optional = yes; + INIT: load = RAM, type = ro, define = yes, optional = yes; + CODE: load = RAM, type = ro; + RODATA: load = RAM, type = ro; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; +} +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__; +} diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg new file mode 100644 index 000000000..edb630d7f --- /dev/null +++ b/cfg/sim65c02.cfg @@ -0,0 +1,35 @@ +SYMBOLS { + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack +} +MEMORY { + ZP: file = "", start = $0000, size = $001A; + HEADER: file = %O, start = $0000, size = $0001; + RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; +} +SEGMENTS { + EXEHDR: load = HEADER, type = ro; + STARTUP: load = RAM, type = ro; + LOWCODE: load = RAM, type = ro, optional = yes; + INIT: load = RAM, type = ro, define = yes, optional = yes; + CODE: load = RAM, type = ro; + RODATA: load = RAM, type = ro; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; +} +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__; +} diff --git a/libsrc/Makefile b/libsrc/Makefile index aa61dda6b..1c5547cd0 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -18,6 +18,8 @@ TARGETS = apple2 \ $(GEOS) \ lynx \ nes \ + sim6502 \ + sim65c02 \ supervision DRVTYPES = emd \ @@ -94,6 +96,8 @@ ifeq ($(TARGET),apple2enh) OBJPFX = a2 DRVPFX = a2e SRCDIR = apple2 +else ifeq ($(TARGET),sim65c02) + SRCDIR = sim6502 else SRCDIR = $(TARGET) endif diff --git a/libsrc/dbg/dbg.c b/libsrc/dbg/dbg.c index e6d8c5c88..3d7b8dd91 100644 --- a/libsrc/dbg/dbg.c +++ b/libsrc/dbg/dbg.c @@ -104,7 +104,7 @@ static char GetKeyUpdate (void); #endif /* Replacement key definitions */ -#if defined(__APPLE2__) || defined(__LYNX__) || defined(__SUPERVISION__) +#if defined(__APPLE2__) || defined(__LYNX__) || defined(__SIM6502__) || defined (__SIM65C02__) || defined(__SUPERVISION__) # define CH_DEL ('H' - 'A' + 1) /* Ctrl+H */ #endif diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s new file mode 100644 index 000000000..68587703f --- /dev/null +++ b/libsrc/sim6502/crt0.s @@ -0,0 +1,32 @@ +; +; Oliver Schmidt, 2013-05-16 +; +; Startup code for cc65 (sim6502 version) +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + .import zerobss, callmain + .import initlib, donelib + .import exit + .import __RAM_START__, __RAM_SIZE__ ; Linker generated + .import __STACKSIZE__ ; Linker generated + + .include "zeropage.inc" + + .segment "STARTUP" + + cld + ldx #$FF + txs + lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + sta sp + stx sp+1 + jsr zerobss + jsr initlib + jsr callmain +_exit: pha + jsr donelib + pla + jsr exit diff --git a/libsrc/sim6502/ctype.s b/libsrc/sim6502/ctype.s new file mode 100644 index 000000000..35968f982 --- /dev/null +++ b/libsrc/sim6502/ctype.s @@ -0,0 +1,159 @@ +; +; Ullrich von Bassewitz, 2003-10-10 +; +; Character specification table. +; + + .include "ctype.inc" + +; 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 weren't 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. + + +__ctype: + .byte CT_CTRL ; 0/00 ___ctrl_@___ + .byte CT_CTRL ; 1/01 ___ctrl_A___ + .byte CT_CTRL ; 2/02 ___ctrl_B___ + .byte CT_CTRL ; 3/03 ___ctrl_C___ + .byte CT_CTRL ; 4/04 ___ctrl_D___ + .byte CT_CTRL ; 5/05 ___ctrl_E___ + .byte CT_CTRL ; 6/06 ___ctrl_F___ + .byte CT_CTRL ; 7/07 ___ctrl_G___ + .byte CT_CTRL ; 8/08 ___ctrl_H___ + .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB + ; 9/09 ___ctrl_I___ + .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ + .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ + .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ + .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ + .byte CT_CTRL ; 14/0e ___ctrl_N___ + .byte CT_CTRL ; 15/0f ___ctrl_O___ + .byte CT_CTRL ; 16/10 ___ctrl_P___ + .byte CT_CTRL ; 17/11 ___ctrl_Q___ + .byte CT_CTRL ; 18/12 ___ctrl_R___ + .byte CT_CTRL ; 19/13 ___ctrl_S___ + .byte CT_CTRL ; 20/14 ___ctrl_T___ + .byte CT_CTRL ; 21/15 ___ctrl_U___ + .byte CT_CTRL ; 22/16 ___ctrl_V___ + .byte CT_CTRL ; 23/17 ___ctrl_W___ + .byte CT_CTRL ; 24/18 ___ctrl_X___ + .byte CT_CTRL ; 25/19 ___ctrl_Y___ + .byte CT_CTRL ; 26/1a ___ctrl_Z___ + .byte CT_CTRL ; 27/1b ___ctrl_[___ + .byte CT_CTRL ; 28/1c ___ctrl_\___ + .byte CT_CTRL ; 29/1d ___ctrl_]___ + .byte CT_CTRL ; 30/1e ___ctrl_^___ + .byte CT_CTRL ; 31/1f ___ctrl_____ + .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ + .byte CT_NONE ; 33/21 _____!_____ + .byte CT_NONE ; 34/22 _____"_____ + .byte CT_NONE ; 35/23 _____#_____ + .byte CT_NONE ; 36/24 _____$_____ + .byte CT_NONE ; 37/25 _____%_____ + .byte CT_NONE ; 38/26 _____&_____ + .byte CT_NONE ; 39/27 _____'_____ + .byte CT_NONE ; 40/28 _____(_____ + .byte CT_NONE ; 41/29 _____)_____ + .byte CT_NONE ; 42/2a _____*_____ + .byte CT_NONE ; 43/2b _____+_____ + .byte CT_NONE ; 44/2c _____,_____ + .byte CT_NONE ; 45/2d _____-_____ + .byte CT_NONE ; 46/2e _____._____ + .byte CT_NONE ; 47/2f _____/_____ + .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ + .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ + .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ + .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ + .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ + .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ + .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ + .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ + .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ + .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ + .byte CT_NONE ; 58/3a _____:_____ + .byte CT_NONE ; 59/3b _____;_____ + .byte CT_NONE ; 60/3c _____<_____ + .byte CT_NONE ; 61/3d _____=_____ + .byte CT_NONE ; 62/3e _____>_____ + .byte CT_NONE ; 63/3f _____?_____ + + .byte CT_NONE ; 64/40 _____@_____ + .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ + .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ + .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ + .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ + .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ + .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ + .byte CT_UPPER ; 71/47 _____G_____ + .byte CT_UPPER ; 72/48 _____H_____ + .byte CT_UPPER ; 73/49 _____I_____ + .byte CT_UPPER ; 74/4a _____J_____ + .byte CT_UPPER ; 75/4b _____K_____ + .byte CT_UPPER ; 76/4c _____L_____ + .byte CT_UPPER ; 77/4d _____M_____ + .byte CT_UPPER ; 78/4e _____N_____ + .byte CT_UPPER ; 79/4f _____O_____ + .byte CT_UPPER ; 80/50 _____P_____ + .byte CT_UPPER ; 81/51 _____Q_____ + .byte CT_UPPER ; 82/52 _____R_____ + .byte CT_UPPER ; 83/53 _____S_____ + .byte CT_UPPER ; 84/54 _____T_____ + .byte CT_UPPER ; 85/55 _____U_____ + .byte CT_UPPER ; 86/56 _____V_____ + .byte CT_UPPER ; 87/57 _____W_____ + .byte CT_UPPER ; 88/58 _____X_____ + .byte CT_UPPER ; 89/59 _____Y_____ + .byte CT_UPPER ; 90/5a _____Z_____ + .byte CT_NONE ; 91/5b _____[_____ + .byte CT_NONE ; 92/5c _____\_____ + .byte CT_NONE ; 93/5d _____]_____ + .byte CT_NONE ; 94/5e _____^_____ + .byte CT_NONE ; 95/5f _UNDERLINE_ + .byte CT_NONE ; 96/60 ___grave___ + .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ + .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ + .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ + .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ + .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ + .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ + .byte CT_LOWER ; 103/67 _____g_____ + .byte CT_LOWER ; 104/68 _____h_____ + .byte CT_LOWER ; 105/69 _____i_____ + .byte CT_LOWER ; 106/6a _____j_____ + .byte CT_LOWER ; 107/6b _____k_____ + .byte CT_LOWER ; 108/6c _____l_____ + .byte CT_LOWER ; 109/6d _____m_____ + .byte CT_LOWER ; 110/6e _____n_____ + .byte CT_LOWER ; 111/6f _____o_____ + .byte CT_LOWER ; 112/70 _____p_____ + .byte CT_LOWER ; 113/71 _____q_____ + .byte CT_LOWER ; 114/72 _____r_____ + .byte CT_LOWER ; 115/73 _____s_____ + .byte CT_LOWER ; 116/74 _____t_____ + .byte CT_LOWER ; 117/75 _____u_____ + .byte CT_LOWER ; 118/76 _____v_____ + .byte CT_LOWER ; 119/77 _____w_____ + .byte CT_LOWER ; 120/78 _____x_____ + .byte CT_LOWER ; 121/79 _____y_____ + .byte CT_LOWER ; 122/7a _____z_____ + .byte CT_NONE ; 123/7b _____{_____ + .byte CT_NONE ; 124/7c _____|_____ + .byte CT_NONE ; 125/7d _____}_____ + .byte CT_NONE ; 126/7e _____~_____ + .byte CT_OTHER_WS ; 127/7f ____DEL____ + + .res 128, CT_NONE ; 128-255 diff --git a/libsrc/sim6502/errno.s b/libsrc/sim6502/errno.s new file mode 100644 index 000000000..c8485c59b --- /dev/null +++ b/libsrc/sim6502/errno.s @@ -0,0 +1,14 @@ +; +; Oliver Schmidt, 2013-05-16 +; +; extern int errno; +; + + .include "errno.inc" + +; ------------------------------------------------------------------------ + + .bss + +__errno: + .word 0 diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s new file mode 100644 index 000000000..9c895834c --- /dev/null +++ b/libsrc/sim6502/exehdr.s @@ -0,0 +1,13 @@ +; +; Oliver Schmidt, 2013-05-16 +; +; This module supplies a 1 byte header identifying the simulator type +; + + .export __EXEHDR__ : absolute = 1 ; Linker referenced + +; ------------------------------------------------------------------------ + + .segment "EXEHDR" + + .byte .defined(__SIM65C02__) diff --git a/libsrc/sim6502/paravirt.s b/libsrc/sim6502/paravirt.s new file mode 100644 index 000000000..8c12cf85d --- /dev/null +++ b/libsrc/sim6502/paravirt.s @@ -0,0 +1,16 @@ +; +; Oliver Schmidt, 2013-05-16 +; +; int open (const char* name, int flags, ...); +; int __fastcall__ close (int fd); +; int __fastcall__ read (int fd, void* buf, unsigned count); +; int __fastcall__ write (int fd, const void* buf, unsigned count); +; + + .export exit, _open, _close, _read, _write + +exit := $FFF0 +_open := $FFF1 +_close := $FFF2 +_read := $FFF3 +_write := $FFF4 diff --git a/src/ca65/main.c b/src/ca65/main.c index 9bf08f347..b3e855e98 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -283,6 +283,14 @@ static void SetSys (const char* Sys) NewSymbol ("__LYNX__", 1); break; + case TGT_SIM6502: + NewSymbol ("__SIM6502__", 1); + break; + + case TGT_SIM65C02: + NewSymbol ("__SIM65C02__", 1); + break; + default: AbEnd ("Invalid target name: `%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index 71fbb022f..a9d94ba9d 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -239,6 +239,14 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__LYNX__", 1); break; + case TGT_SIM6502: + DefineNumericMacro ("__SIM6502__", 1); + break; + + case TGT_SIM65C02: + DefineNumericMacro ("__SIM65C02__", 1); + break; + default: AbEnd ("Unknown target system type %d", Target); } diff --git a/src/common/target.c b/src/common/target.c index d42d82429..c4d1d1dde 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -142,6 +142,8 @@ static const TargetEntry TargetMap[] = { { "none", TGT_NONE }, { "pet", TGT_PET }, { "plus4", TGT_PLUS4 }, + { "sim6502", TGT_SIM6502 }, + { "sim65c02", TGT_SIM65C02 }, { "supervision", TGT_SUPERVISION }, { "vc20", TGT_VIC20 }, { "vic20", TGT_VIC20 }, @@ -172,6 +174,8 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "nes", CPU_6502, BINFMT_BINARY, CTNone }, { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, { "lynx", CPU_65C02, BINFMT_BINARY, CTNone }, + { "sim6502", CPU_6502, BINFMT_BINARY, CTNone }, + { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 07bc55d49..4b5eec385 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -73,6 +73,8 @@ typedef enum { TGT_NES, TGT_SUPERVISION, TGT_LYNX, + TGT_SIM6502, + TGT_SIM65C02, TGT_COUNT /* Number of target systems */ } target_t; -- 2.39.5