mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-02 15:33:43 +00:00
nes: bank switching .cfg for MMC3 via NES_MAPPER=4; reverse A/B btns
This commit is contained in:
parent
1e44d05536
commit
98ccf2b26a
76
presets/nes/bankswitch.c
Normal file
76
presets/nes/bankswitch.c
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
// bank-switching configuration
|
||||
#define NES_MAPPER 4 // Mapper 4 (MMC3)
|
||||
#define NES_PRG_BANKS 4 // # of 16KB PRG banks
|
||||
#define NES_CHR_BANKS 8 // # of 8KB CHR banks
|
||||
|
||||
#include <peekpoke.h>
|
||||
#include <string.h>
|
||||
#include "neslib.h"
|
||||
|
||||
// link the pattern table into CHR ROM
|
||||
//#link "chr_generic.s"
|
||||
|
||||
#define MMC_MODE 0x00
|
||||
|
||||
#define MMC3_SET_REG(r,n)\
|
||||
POKE(0x8000, MMC_MODE|(r));\
|
||||
POKE(0x8001, (n));
|
||||
|
||||
#define MMC3_CHR_0000(n) MMC3_SET_REG(0,n)
|
||||
#define MMC3_CHR_0800(n) MMC3_SET_REG(1,n)
|
||||
#define MMC3_CHR_1000(n) MMC3_SET_REG(2,n)
|
||||
#define MMC3_CHR_1400(n) MMC3_SET_REG(3,n)
|
||||
#define MMC3_CHR_1800(n) MMC3_SET_REG(4,n)
|
||||
#define MMC3_CHR_1C00(n) MMC3_SET_REG(5,n)
|
||||
#define MMC3_PRG_8000(n) MMC3_SET_REG(6,n)
|
||||
#define MMC3_PRG_A000(n) MMC3_SET_REG(7,n)
|
||||
|
||||
#define MMC3_MIRROR(n) POKE(0xa000, (n))
|
||||
|
||||
#pragma rodata-name("CODE0")
|
||||
const unsigned char TEXT0[]={"Bank 0 @ 8000"};
|
||||
#pragma rodata-name("CODE1")
|
||||
const unsigned char TEXT1[]={"Bank 1 @ 8000"};
|
||||
#pragma rodata-name("CODE5")
|
||||
const unsigned char TEXT5[]={"Bank 5 @ A000"};
|
||||
#pragma rodata-name("CODE6")
|
||||
const unsigned char TEXT6[]={"Bank 6 @ C000"};
|
||||
|
||||
// put functions in bank 0
|
||||
#pragma code-name("CODE1")
|
||||
|
||||
void draw_text(word addr, const char* text) {
|
||||
vram_adr(addr);
|
||||
vram_write(text, strlen(text));
|
||||
}
|
||||
|
||||
// back to main code segment
|
||||
#pragma code-name("CODE")
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// set palette colors
|
||||
pal_col(1,0x04);
|
||||
pal_col(2,0x20);
|
||||
pal_col(3,0x30);
|
||||
// setup CHR bank switching for background
|
||||
MMC3_CHR_0000(0);
|
||||
MMC3_CHR_0800(1);
|
||||
// select bank 0 in $8000-$9fff
|
||||
MMC3_PRG_8000(0);
|
||||
vram_adr(NTADR_A(2,2));
|
||||
vram_write(TEXT0, 13);
|
||||
// select bank 1 in $8000-$9fff
|
||||
// also needed to call draw_text()
|
||||
MMC3_PRG_8000(1);
|
||||
draw_text(NTADR_A(2,3), TEXT1);
|
||||
// select bank 5 in $a000-$bfff
|
||||
MMC3_PRG_A000(5);
|
||||
draw_text(NTADR_A(2,4), TEXT5);
|
||||
// $c000-$dfff is fixed to bank 6
|
||||
draw_text(NTADR_A(2,5), TEXT6);
|
||||
//enable rendering
|
||||
ppu_on_all();
|
||||
while(1);//do nothing, infinite loop
|
||||
}
|
@ -47,3 +47,4 @@ void main(void)
|
||||
show_title_screen(climbr_title_pal, climbr_title_rle);
|
||||
while(1);//do nothing, infinite loop
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ const JSNES_PRESETS = [
|
||||
{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'},
|
||||
];
|
||||
|
||||
const NES_NESLIB_PRESETS = [
|
||||
@ -54,8 +55,8 @@ const NES_CONIO_PRESETS = [
|
||||
/// JSNES
|
||||
|
||||
const JSNES_KEYCODE_MAP = makeKeycodeMap([
|
||||
[Keys.VK_Z, 0, 0],
|
||||
[Keys.VK_X, 0, 1],
|
||||
[Keys.VK_X, 0, 0],
|
||||
[Keys.VK_Z, 0, 1],
|
||||
[Keys.VK_SPACE, 0, 2],
|
||||
[Keys.VK_ENTER, 0, 3],
|
||||
[Keys.VK_UP, 0, 4],
|
||||
|
@ -831,7 +831,7 @@ export class MemoryMapView implements ProjectView {
|
||||
var curofs = 0;
|
||||
for (var seg of segments) {
|
||||
//var used = seg.last ? (seg.last-seg.start) : seg.size;
|
||||
if (curofs != seg.start)
|
||||
if (seg.start > curofs)
|
||||
this.addSegment({name:'',start:curofs, size:seg.start-curofs});
|
||||
this.addSegment(seg);
|
||||
curofs = seg.start + seg.size;
|
||||
|
76
src/worker/lib/nes/nesbanked.cfg
Normal file
76
src/worker/lib/nes/nesbanked.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
SYMBOLS {
|
||||
__STACKSIZE__: type = weak, value = $0300; # 3 pages stack
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", start = $0002, size = $00FE, type = rw, define = yes;
|
||||
|
||||
# INES Cartridge Header
|
||||
HEADER: file = %O, start = $0000, size = $0010, fill = yes;
|
||||
|
||||
# 5 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
|
||||
PRG5: start = $a000, size = $2000, file = %O ,fill = yes, define = yes;
|
||||
PRG6: start = $c000, size = $2000, file = %O ,fill = yes, define = yes;
|
||||
|
||||
# final bank has
|
||||
# - startup
|
||||
# - code
|
||||
# - vectors
|
||||
PRG7: file = %O, start = $E000, size = $1FFA, fill = yes, define = yes;
|
||||
VECTORS: file = %O, start = $FFFA, size = $0006, fill = yes;
|
||||
|
||||
# 8 8k CHR Banks (64k)
|
||||
CHR: file = %O, start = $0000, size = $10000, fill = yes;
|
||||
|
||||
# standard 2k SRAM (-zeropage)
|
||||
# $0100-$0200 cpu stack
|
||||
# $0200-$0500 3 pages for ppu memory write buffer
|
||||
# $0500-$0800 3 pages for cc65 parameter stack
|
||||
SRAM: file = "", start = $0500, size = __STACKSIZE__, define = yes;
|
||||
|
||||
# additional 8K SRAM Bank
|
||||
# - data (run)
|
||||
# - bss
|
||||
# - heap
|
||||
RAM: file = "", start = $6000, size = $2000, define = yes;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
HEADER: load = HEADER, type = ro;
|
||||
CODE0: load = PRG0, type = ro, define = yes, optional = yes;
|
||||
CODE1: load = PRG1, type = ro, define = yes, optional = yes;
|
||||
CODE2: load = PRG2, type = ro, define = yes, optional = yes;
|
||||
CODE3: load = PRG3, type = ro, define = yes, optional = yes;
|
||||
CODE4: load = PRG4, type = ro, define = yes, optional = yes;
|
||||
CODE5: load = PRG5, type = ro, define = yes, optional = yes;
|
||||
CODE6: load = PRG6, type = ro, define = yes, optional = yes;
|
||||
RODATA: load = PRG6, type = ro, define = yes;
|
||||
ONCE: load = PRG6, type = ro, optional = yes;
|
||||
DATA: load = PRG6, run = RAM, type = rw, define = yes;
|
||||
STARTUP: load = PRG6, type = ro, define = yes;
|
||||
CODE: load = PRG7, type = ro, define = yes;
|
||||
VECTORS: load = VECTORS, type = rw;
|
||||
CHARS: load = CHR, type = rw;
|
||||
BSS: load = SRAM, type = bss, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
@ -168,12 +168,12 @@ var PLATFORM_PARAMS = {
|
||||
define: '__NES__',
|
||||
cfgfile: 'neslib.cfg',
|
||||
libargs: ['crt0.o', 'nes.lib',
|
||||
'-D', 'NES_MAPPER=0', // UxROM
|
||||
'-D', 'NES_PRG_BANKS=2', // 2 PRG banks
|
||||
'-D', 'NES_MAPPER=0', // NROM
|
||||
'-D', 'NES_PRG_BANKS=2', // 2 16K PRG banks
|
||||
'-D', 'NES_CHR_BANKS=1', // 1 CHR bank
|
||||
'-D', 'NES_MIRRORING=0', // horizontal mirroring
|
||||
],
|
||||
extra_link_files: ['crt0.o'],
|
||||
extra_link_files: ['crt0.o', 'nesbanked.cfg'],
|
||||
extra_segments:[
|
||||
//{name:'Work RAM',start:0x0,size:0x800,type:'ram'},
|
||||
{name:'OAM Buffer',start:0x200,size:0x100,type:'ram'},
|
||||
@ -492,7 +492,8 @@ function loadNative(modulename:string) {
|
||||
|
||||
// mount the filesystem at /share
|
||||
function setupFS(FS, name:string) {
|
||||
var WORKERFS = FS.filesystems['WORKERFS']
|
||||
var WORKERFS = FS.filesystems['WORKERFS'];
|
||||
if (!fsMeta[name]) throw "No filesystem for '" + name + "'";
|
||||
FS.mkdir('/share');
|
||||
FS.mount(WORKERFS, {
|
||||
packages: [{ metadata: fsMeta[name], blob: fsBlob[name] }]
|
||||
@ -901,16 +902,16 @@ function linkLD65(step:BuildStep) {
|
||||
printErr:function(s) { errors.push({msg:s,line:0}); }
|
||||
});
|
||||
var FS = LD65['FS'];
|
||||
var cfgfile = '/' + platform + '.cfg';
|
||||
setupFS(FS, '65-'+getRootPlatform(platform));
|
||||
populateFiles(step, FS);
|
||||
populateExtraFiles(step, FS, params.extra_link_files);
|
||||
var libargs = params.libargs;
|
||||
var cfgfile = params.cfgfile;
|
||||
var args = ['--cfg-path', '/share/cfg',
|
||||
'--lib-path', '/share/lib',
|
||||
'--lib-path', '/share/target/apple2/drv', // TODO
|
||||
'-D', '__EXEHDR__=0', // TODO
|
||||
'-C', params.cfgfile,
|
||||
'-C', cfgfile,
|
||||
'-Ln', 'main.vice',
|
||||
//'--dbgfile', 'main.dbg',
|
||||
'-o', 'main', '-m', 'main.map'].concat(step.args, libargs);
|
||||
@ -944,7 +945,7 @@ function linkLD65(step:BuildStep) {
|
||||
var seg_re = /^__(\w+)_SIZE__$/;
|
||||
var segments = [].concat(params.extra_segments||[]);
|
||||
segments.push({name:'CPU Stack',start:0x100,size:0x100,type:'ram'});
|
||||
segments.push({name:'CPU Vectors',start:0xfffc,size:0x6,type:'rom'});
|
||||
segments.push({name:'CPU Vectors',start:0xfffa,size:0x6,type:'rom'});
|
||||
// TODO: CHR, banks, etc
|
||||
for (let ident in symbolmap) {
|
||||
let m = seg_re.exec(ident);
|
||||
@ -953,9 +954,9 @@ function linkLD65(step:BuildStep) {
|
||||
let segstart = symbolmap['__'+seg+'_RUN__'] || symbolmap['__'+seg+'_START__'];
|
||||
let segsize = symbolmap['__'+seg+'_SIZE__'];
|
||||
let seglast = symbolmap['__'+seg+'_LAST__'];
|
||||
if (segstart >= 0 && segsize > 0 && seg != 'PRG' && seg != 'RAM') { // TODO
|
||||
if (segstart >= 0 && segsize > 0 && !seg.startsWith('PRG') && seg != 'RAM') { // TODO
|
||||
var type = null;
|
||||
if (seg == 'CODE' || seg == 'STARTUP' || seg == 'RODATA') type = 'rom';
|
||||
if (seg.startsWith('CODE') || seg == 'STARTUP' || seg == 'RODATA') type = 'rom';
|
||||
else if (seg == 'ZP' || seg == 'RAM' || seg == 'DATA' || seg == 'BSS') type = 'ram';
|
||||
segments.push({name:seg, start:segstart, size:segsize, last:seglast, type:type});
|
||||
}
|
||||
@ -986,7 +987,8 @@ function linkLD65(step:BuildStep) {
|
||||
}
|
||||
}
|
||||
|
||||
function fixParamsWithDefines(path:string, libargs:string[]){
|
||||
function fixParamsWithDefines(path:string, params){
|
||||
var libargs = params.libargs;
|
||||
if (path && libargs) {
|
||||
var code = getWorkFileAsString(path);
|
||||
if (code) {
|
||||
@ -999,7 +1001,7 @@ function fixParamsWithDefines(path:string, libargs:string[]){
|
||||
}
|
||||
}
|
||||
// find #defines and replace them
|
||||
var re = /^#define\s+(\w+)\s+(.+)/gmi;
|
||||
var re = /^#define\s+(\w+)\s+(\S+)/gmi;
|
||||
var m;
|
||||
while (m = re.exec(code)) {
|
||||
var ident = m[1];
|
||||
@ -1007,7 +1009,12 @@ function fixParamsWithDefines(path:string, libargs:string[]){
|
||||
var index = ident2index[ident];
|
||||
if (index >= 0) {
|
||||
libargs[index] = ident + "=" + value;
|
||||
console.log(index, libargs[index]);
|
||||
console.log('Using libargs', index, libargs[index]);
|
||||
// TODO: MMC3 mapper switch
|
||||
if (ident == 'NES_MAPPER' && value == '4') {
|
||||
params.cfgfile = 'nesbanked.cfg';
|
||||
console.log('Using config file', params.cfgfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1044,7 +1051,7 @@ function compileCC65(step:BuildStep) {
|
||||
var FS = CC65['FS'];
|
||||
setupFS(FS, '65-'+getRootPlatform(step.platform));
|
||||
populateFiles(step, FS);
|
||||
fixParamsWithDefines(step.path, params.libargs);
|
||||
fixParamsWithDefines(step.path, params);
|
||||
execMain(step, CC65, ['-T', '-g',
|
||||
'-Oirs',
|
||||
'-Cl', // static locals
|
||||
|
@ -97,6 +97,7 @@ describe('Worker', function() {
|
||||
compile('plasm', 'word x = ', 'apple2', done, 0, 0, 1);
|
||||
});
|
||||
*/
|
||||
// TODO: test NES bank switching, mapper
|
||||
it('should compile CC65', function(done) {
|
||||
compile('cc65', 'int main() {\nint x=1;\nreturn x+2;\n}', 'nes-conio', done, 40976, 3);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user