1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-21 23:30:58 +00:00

nes updates; new build script; fixed kbd shortcuts

This commit is contained in:
Steven Hugg 2019-04-05 08:58:26 -04:00
parent 4fc52a11f2
commit 810d0af58b
14 changed files with 89 additions and 81 deletions

View File

@ -1,7 +1,11 @@
TSC=./node_modules/typescript/bin/tsc
all: src/cpu/z80fast.js
all:
$(TSC)
cd jsnes && npm i
z80: src/cpu/z80fast.js
src/cpu/z80.js: src/cpu/z80.coffee
coffee -c $<

View File

@ -111,10 +111,11 @@ TODO:
- capture so we get mouseUp() out of frame
- per-View keyboard shortcuts
- parse labels
- editing too fast refreshes kills the editor
- editing too fast refreshes kills the editor, also doesn't update palette
- crt0.s compiled each time?
- debug highlight doesn't go away when debugging -> running
- replay doesn't work for nes
- replay doesn't work for nes (force background tile redraw)
- running profiler while replaying? grand unified replay?
WEB WORKER FORMAT

View File

@ -25,7 +25,7 @@
"test": "tests"
},
"scripts": {
"build": "./node_modules/typescript/bin/tsc",
"build": "make",
"test": "npm run test-node",
"test-one": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000",
"test-node": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli",

View File

@ -37,7 +37,7 @@ const unsigned char TEXT5[]={"Bank 5 @ A000"};
#pragma rodata-name("CODE6")
const unsigned char TEXT6[]={"Bank 6 @ C000"};
// put functions in bank 0
// put functions in bank 1
#pragma code-name("CODE1")
void draw_text(word addr, const char* text) {

View File

@ -47,4 +47,3 @@ void main(void)
show_title_screen(climbr_title_pal, climbr_title_rle);
while(1);//do nothing, infinite loop
}

View File

@ -27,17 +27,17 @@
/*{pal:"nes",layout:"nes"}*/
const char PALETTE[32] = {
0x0f,
0x0F,
0x11,0x24,0x3c, 0x0,
0x01,0x15,0x25, 0x0,
0x01,0x10,0x20, 0x0,
0x06,0x16,0x26, 0x0,
0x11,0x24,0x3C, 0x00,
0x01,0x15,0x25, 0x00,
0x01,0x10,0x20, 0x00,
0x06,0x16,0x26, 0x00,
0x11,0x24,0x3c, 0x0,
0x01,0x15,0x25, 0x0,
0x31,0x35,0x3c, 0x0,
0x01,0x17,0x30
0x11,0x24,0x3C, 0x00,
0x01,0x15,0x25, 0x00,
0x31,0x35,0x3C, 0x00,
0x25,0x1C,0x3D
};
#define COLOR_PLAYER 3
@ -55,15 +55,14 @@ const char TILESET[128*8*2] = {
0x00,0x7C,0xEE,0xEE,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x78,0x38,0x38,0x38,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x0E,0x7C,0xE0,0xEE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0E,0x3C,0x0E,0x0E,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0xEE,0xEE,0xFE,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xE0,0xFC,0x0E,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE0,0xFC,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xEE,0x1C,0x1C,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0x7C,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0x7E,0x0E,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x70,0x70,0x38,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x1C,0x1C,0x38,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0x1C,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x7C,0xEE,0xEE,0xEE,0xE0,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0xEE,0xFE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xEE,0xFC,0xEE,0xEE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xE0,0xE0,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEC,0xEE,0xEE,0xEE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xE0,0xF0,0xE0,0xE0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xE0,0xF8,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE0,0xEE,0xEE,0xEE,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xFE,0xEE,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x38,0x38,0x38,0x38,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xFC,0xF8,0xEC,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0xE0,0xEE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCE,0xEE,0xFE,0xFE,0xEE,0xE6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xFC,0xEE,0xEE,0xEE,0xFC,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0xEE,0xEC,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xEE,0xEE,0xEE,0xFC,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE0,0x7C,0x0E,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x38,0x38,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xFE,0xFE,0xEE,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x7C,0x38,0x7C,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0x7C,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*{w:16,h:16,bpp:1,count:16,brev:1,np:2,pofs:8,remap:[5,0,1,2,4,6,7,8,9,10,11,12]}*/
// formation enemy (64,66)
0x0F,0x13,0x03,0x03,0x01,0x01,0x00,0x00,0x0C,0x11,0x04,0x08,0x12,0x04,0x08,0x08,
0xF8,0xE4,0xE0,0xE0,0xC0,0xC0,0x80,0x00,0x18,0x44,0x10,0x08,0x24,0x10,0x08,0x08,
0x0C,0x13,0x03,0x03,0x03,0x01,0x01,0x00,0x0C,0x10,0x01,0x0C,0x30,0x02,0x04,0x18,
0xF8,0xE4,0xE0,0xE0,0xC0,0xC0,0x80,0x00,0x18,0x44,0x10,0x08,0x24,0x10,0x08,0x08,
0x18,0x64,0xE0,0xE0,0xE0,0xC0,0xC0,0x80,0x18,0x04,0x40,0x18,0x06,0x20,0x10,0x0C,
// attackers (68)
0x00,0x00,0x04,0x08,0x04,0x00,0x01,0x0C,0x00,0x00,0x04,0x08,0x04,0x03,0x03,0x03,
0x00,0x00,0x04,0x08,0x04,0x03,0x03,0x0F,0x00,0x00,0x04,0x08,0x04,0x00,0x01,0x00,
0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x30,0x02,0x04,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x08,0x10,0x60,0xE0,0xE0,0x00,0x00,0x10,0x08,0x10,0x00,0x40,0x18,
0xE0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x06,0x20,0x10,0x0C,0x00,0x00,0x00,0x00,
@ -133,10 +132,10 @@ const char TILESET[128*8*2] = {
0x86,0xC4,0x00,0x10,0x01,0x10,0x08,0x04,0x00,0x00,0x10,0x30,0x48,0x20,0x04,0x14,
0x04,0x00,0x20,0x89,0x00,0x84,0xC6,0x43,0x16,0x04,0x44,0xA0,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x08,0x00,0x06,0x02,0x00,0x00,0x00,0x08,0x01,0x11,0x15,0x00,0x38,
0x30,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x20,0x08,0x00,0x30,0x20,0x00,0x00,0x00,0x08,0x40,0x44,0x54,0x00,0x0E,
0x06,0x20,0x80,0x80,0x00,0x00,0x00,0x00,0x0C,0x80,0x04,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x08,0x00,0x06,0x02,0x00,0x00,0x40,0x08,0x01,0x11,0x15,0x00,0x38,
0x30,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x10,0x00,0x04,0x40,0x00,0x00,
0x00,0x00,0x20,0x08,0x00,0x30,0x20,0x00,0x02,0x00,0x08,0x40,0x44,0x54,0x00,0x0E,
0x06,0x20,0x80,0x80,0x00,0x00,0x00,0x00,0x0C,0x80,0x04,0x80,0x00,0x11,0x00,0x00,
};
#define CHAR(x) ((x)-' ')
@ -657,13 +656,26 @@ void init_stars() {
oamid = oam_spr(rand(), i*8, 103+(i&3), 0|OAM_BEHIND, oamid);
}
}
void draw_stars() {
/*
void draw_stars_c() {
byte i;
for (i=0; i<32; i++) {
++OAMBUF[i].y;
}
}
*/
void draw_stars() {
asm("ldy #0"); // start with Y = 0
asm("clc"); // clear carry for addition
asm("@1: lda $200,y");// read from OAM buffer
asm("adc #1"); // increment
asm("sta $200,y"); // write to OAM buffer
asm("iny"); // increment Y by 4
asm("iny");
asm("iny");
asm("iny");
asm("bpl @1"); // branch while < 128
}
void play_round() {
register byte framecount;
@ -733,7 +745,7 @@ void set_shifted_pattern(const byte* src, word dest, byte shift) {
byte y;
for (y=0; y<16; y++) {
byte a = src[y];
byte b = src[y+16];
byte b = src[y+32];
buf[y] = a>>shift;
buf[y+16] = b>>shift | a<<(8-shift);
buf[y+32] = b<<(8-shift);
@ -756,7 +768,7 @@ void setup_graphics() {
src = SSRC_FORM1*16;
dest = SDST_FORM1*16;
for (i=0; i<8; i++) {
if (i==4) src += 32;
if (i==4) src += 16;
set_shifted_pattern(&TILESET[src], dest, i);
dest += 3*16;
}

View File

@ -1,6 +1,7 @@
#include "neslib.h"
#include "vrambuf.h"
#include <string.h>
// index to end of buffer
byte updptr = 0;
@ -30,19 +31,19 @@ void cflushnow(void) {
// add multiple characters to update buffer
// using horizontal increment
void putbytes(word addr, const char* str, byte len) {
byte i;
void putbytes(word addr, register const char* str, byte len) {
// if bytes won't fit, wait for vsync and flush buffer
if (updptr >= VBUFSIZE-4-len) cflushnow();
if (VBUFSIZE-4-len < updptr) {
cflushnow();
}
// add vram address
VRAMBUF_ADD((addr >> 8) ^ NT_UPD_HORZ);
VRAMBUF_ADD(addr); // only lower 8 bits
// add length
VRAMBUF_ADD(len);
// add data
for (i=0; i<len; ++i) {
VRAMBUF_ADD(str[i]);
}
// add data to buffer
memcpy(updbuf+updptr, str, len);
updptr += len;
// place EOF mark
cendbuf();
}

View File

@ -13,20 +13,9 @@
// index to end of buffer
extern byte updptr;
// macro to set a single byte in buffer
#define VRAMBUF_SET(b)\
__A__ = (b);\
asm("ldy %v", updptr);\
asm("sta $100,y");
// macro to set a single byte to buffer, then increment
#define VRAMBUF_ADD(b)\
VRAMBUF_SET(b)\
asm("inc %v", updptr);
// C versions of macros
//#define VRAMBUF_SET(b) updbuf[updptr] = (b);
//#define VRAMBUF_ADD(b) VRAMBUF_SET(b); ++updptr
#define VRAMBUF_SET(b) updbuf[updptr] = (b);
#define VRAMBUF_ADD(b) VRAMBUF_SET(b); ++updptr
// macro to add a raw header (useful for single bytes)
#define VRAMBUF_PUT(addr,len,flags)\

View File

@ -506,8 +506,8 @@ export class Toolbar {
mousetrap;
boundkeys = [];
constructor(parentDiv:HTMLElement) {
this.mousetrap = new Mousetrap(parentDiv);
constructor(parentDiv:HTMLElement, focusDiv:HTMLElement) {
this.mousetrap = focusDiv ? new Mousetrap(focusDiv) : Mousetrap;
this.span = $(document.createElement("span")).addClass("btn_toolbar");
parentDiv.appendChild(this.span[0]);
this.newGroup();

View File

@ -32,11 +32,11 @@ const JSNES_PRESETS = [
{id:'siegegame.c', name:'Siege Game'},
{id:'shoot2.c', name:'Solarian Game'},
{id:'climber.c', name:'Platform Game'},
{id:'scrollrt.asm', name:'Split Screen Scroll (ASM)'},
{id:'fami.c', name:'Famitone Demo'},
{id:'musicdemo.asm', name:'Famitone Demo (ASM)'},
{id:'bankswitch.c', name:'Bank Switching'},
{id:'irq.c', name:'IRQ Scanline Counter'},
{id:'scrollrt.asm', name:'Line-by-line Scrolling (ASM)'},
];
/// JSNES

View File

@ -38,6 +38,23 @@ export var projectWindows : ProjectWindows; // window manager
var stateRecorder : StateRecorderImpl;
var userPaused : boolean; // did user explicitly pause?
var current_output : WorkerOutput; // current ROM
var current_preset_entry : Preset; // current preset object (if selected)
var main_file_id : string; // main file ID
var store; // persistent store
export var compparams; // received build params from worker
export var lastDebugState; // last debug state (object)
var lastDebugInfo; // last debug info (CPU text)
var debugCategory; // current debug category
var debugTickPaused = false;
var recorderActive = false;
var lastBreakExpr = "c.PC == 0x6000";
// TODO: codemirror multiplex support?
var TOOL_TO_SOURCE_STYLE = {
'dasm': '6502',
@ -59,19 +76,6 @@ function newWorker() : Worker {
return new Worker("./src/worker/loader.js");
}
var userPaused : boolean; // did user explicitly pause?
var current_output : WorkerOutput; // current ROM
var current_preset_entry : Preset; // current preset object (if selected)
var main_file_id : string; // main file ID
var store; // persistent store
export var compparams; // received build params from worker
export var lastDebugState; // last debug state (object)
var lastDebugInfo; // last debug info (CPU text)
var debugCategory; // current debug category
var hasLocalStorage : boolean = function() {
try {
const key = "__some_random_key_you_are_not_going_to_use__";
@ -857,7 +861,6 @@ function resetAndDebug() {
}
}
var lastBreakExpr = "c.PC == 0x6000";
function _breakExpression() {
console.log(platform.saveState());
var exprs = window.prompt("Enter break expression", lastBreakExpr);
@ -882,8 +885,6 @@ function getSymbolAtAddress(a : number) {
return '';
}
var debugTickPaused = false;
function updateDebugWindows() {
if (platform.isRunning()) {
projectWindows.tick();
@ -983,8 +984,6 @@ function traceTiming() {
}
}
var recorderActive = false;
function _disableRecording() {
if (recorderActive) {
platform.setRecorder(null);
@ -1071,25 +1070,25 @@ function _addLinkFile() {
function setupDebugControls() {
// create toolbar buttons
uitoolbar = new Toolbar($("#toolbar")[0]);
uitoolbar = new Toolbar($("#toolbar")[0], null);
uitoolbar.grp.prop('id','debug_bar');
uitoolbar.add('ctrl+alt+.', 'Reset', 'glyphicon-refresh', resetAndDebug).prop('id','dbg_reset');
uitoolbar.add('ctrl+alt+P', 'Pause', 'glyphicon-pause', pause).prop('id','dbg_pause');
uitoolbar.add('ctrl+alt+R', 'Resume', 'glyphicon-play', resume).prop('id','dbg_go');
uitoolbar.add('ctrl+alt+p', 'Pause', 'glyphicon-pause', pause).prop('id','dbg_pause');
uitoolbar.add('ctrl+alt+r', 'Resume', 'glyphicon-play', resume).prop('id','dbg_go');
if (platform.step) {
uitoolbar.add('ctrl+alt+S', 'Single Step', 'glyphicon-step-forward', singleStep).prop('id','dbg_step');
uitoolbar.add('ctrl+alt+s', 'Single Step', 'glyphicon-step-forward', singleStep).prop('id','dbg_step');
}
if (platform.runToVsync) {
uitoolbar.add('ctrl+alt+V', 'Next Frame', 'glyphicon-forward', singleFrameStep).prop('id','dbg_tovsync');
uitoolbar.add('ctrl+alt+v', 'Next Frame', 'glyphicon-forward', singleFrameStep).prop('id','dbg_tovsync');
}
if ((platform.runEval || platform.runToPC) && !platform_id.startsWith('verilog')) {
uitoolbar.add('ctrl+alt+L', 'Run To Line', 'glyphicon-save', runToCursor).prop('id','dbg_toline');
uitoolbar.add('ctrl+alt+l', 'Run To Line', 'glyphicon-save', runToCursor).prop('id','dbg_toline');
}
if (platform.runUntilReturn) {
uitoolbar.add('ctrl+alt+O', 'Step Out of Subroutine', 'glyphicon-hand-up', runUntilReturn).prop('id','dbg_stepout');
uitoolbar.add('ctrl+alt+o', 'Step Out of Subroutine', 'glyphicon-hand-up', runUntilReturn).prop('id','dbg_stepout');
}
if (platform.stepBack) {
uitoolbar.add('ctrl+alt+B', 'Step Backwards', 'glyphicon-step-backward', runStepBackwards).prop('id','dbg_stepback');
uitoolbar.add('ctrl+alt+b', 'Step Backwards', 'glyphicon-step-backward', runStepBackwards).prop('id','dbg_stepback');
}
uitoolbar.newGroup();
if (platform.newCodeAnalyzer) {

View File

@ -1228,6 +1228,7 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
}
setVisible?(showing : boolean) : void {
// TODO: make into toolbar?
if (showing) {
Mousetrap.bind('ctrl+z', projectWindows.undoStep.bind(projectWindows));
} else {

View File

@ -84,7 +84,7 @@ export class WaveformView {
var wlc = this.wavelist.container;
wlc.tabIndex = -1; // make it focusable
//wlc.style = "overflow-x: hidden"; // TODO?
this.toolbar = new Toolbar(this.parent);
this.toolbar = new Toolbar(this.parent, this.parent);
$(this.parent).append(wlc);
var down = false;
var selfn = (e) => {

View File

@ -7,15 +7,17 @@ MEMORY {
# INES Cartridge Header
HEADER: file = %O, start = $0000, size = $0010, fill = yes;
# 5 16K ROM Banks @ $8000
# 3 16K ROM Banks @ $8000
PRG0: start = $8000, size = $2000, file = %O ,fill = yes, define = yes;
PRG1: start = $8000, size = $2000, file = %O ,fill = yes, define = yes;
PRG2: start = $8000, size = $2000, file = %O ,fill = yes, define = yes;
PRG3: start = $8000, size = $2000, file = %O ,fill = yes, define = yes;
PRG4: start = $8000, size = $2000, file = %O ,fill = yes, define = yes;
# fixed 16K ROM banks @ $a000 and $c000
# 3 16K ROM Banks @ $a000
PRG3: start = $a000, size = $2000, file = %O ,fill = yes, define = yes;
PRG4: start = $a000, size = $2000, file = %O ,fill = yes, define = yes;
PRG5: start = $a000, size = $2000, file = %O ,fill = yes, define = yes;
# fixed 16K ROM banks @ $c000
PRG6: start = $c000, size = $2000, file = %O ,fill = yes, define = yes;
# final bank has