diff --git a/src/common/baseplatform.ts b/src/common/baseplatform.ts index 5248f69b..39200ab3 100644 --- a/src/common/baseplatform.ts +++ b/src/common/baseplatform.ts @@ -2,7 +2,7 @@ import { RAM, RasterVideo, KeyFlags, dumpRAM, AnimationTimer, setKeyboardFromMap, padBytes, ControllerPoller } from "./emu"; import { hex, printFlags, invertMap, getBasePlatform } from "./util"; import { CodeAnalyzer } from "./analysis"; -import { Segment } from "./workertypes"; +import { Segment, FileData } from "./workertypes"; import { disassemble6502 } from "./cpu/disasm6502"; import { disassembleZ80 } from "./cpu/disasmz80"; import { Z80 } from "./cpu/ZilogZ80"; @@ -80,6 +80,7 @@ export interface Platform { resume() : void; loadROM(title:string, rom:any); // TODO: Uint8Array loadBIOS?(title:string, rom:Uint8Array); + getROMExtension?(rom:FileData) : string; loadState?(state : EmuState) : void; saveState?() : EmuState; diff --git a/src/ide/ui.ts b/src/ide/ui.ts index 26628007..3923dc66 100644 --- a/src/ide/ui.ts +++ b/src/ide/ui.ts @@ -880,12 +880,15 @@ function _downloadROMImage(e) { alertError("Please finish compiling with no errors before downloading ROM."); return true; } + var prefix = getFilenamePrefix(getCurrentMainFilename()); if (current_output instanceof Uint8Array) { var blob = new Blob([current_output], {type: "application/octet-stream"}); - saveAs(blob, getCurrentMainFilename()+".rom"); + var suffix = (platform.getROMExtension && platform.getROMExtension(current_output)) + || "-" + getBasePlatform(platform_id) + ".bin"; + saveAs(blob, prefix + suffix); } else { var blob = new Blob([(current_output).code], {type: "text/plain"}); - saveAs(blob, getCurrentMainFilename()+".js"); + saveAs(blob, prefix + ".js"); } } @@ -905,7 +908,7 @@ function _downloadProjectZipFile(e) { } }); zip.generateAsync({type:"blob"}).then( (content) => { - saveAs(content, getCurrentMainFilename() + ".zip"); + saveAs(content, getCurrentMainFilename() + "-" + getBasePlatform(platform_id) + ".zip"); }); }); } @@ -923,7 +926,7 @@ function _downloadAllFilesZipFile(e) { })).then(() => { return zip.generateAsync({type:"blob"}); }).then( (content) => { - return saveAs(content, platform_id + "-all.zip"); + return saveAs(content, getBasePlatform(platform_id) + "-all.zip"); }); }); }); diff --git a/src/machine/sms.ts b/src/machine/sms.ts index 4b21297c..9b119816 100644 --- a/src/machine/sms.ts +++ b/src/machine/sms.ts @@ -50,7 +50,7 @@ export class SG1000 extends BaseZ80VDPBasedMachine { read = newAddressDecoder([ [0xc000, 0xffff, 0x3ff, (a) => { return this.ram[a]; }], - [0x0000, 0xbfff, 0xffff, (a) => { return this.rom[a]; }], + [0x0000, 0xbfff, 0xffff, (a) => { return this.rom && this.rom[a]; }], ]); write = newAddressDecoder([ [0xc000, 0xffff, 0x3ff, (a,v) => { this.ram[a] = v; }], @@ -141,7 +141,7 @@ export class SMS extends SG1000 { getPagedROM(a:number, reg:number) { //if (!(a&0xff)) console.log(hex(a), reg, this.pagingRegisters[reg], this.romPageMask); - return this.rom[a + ((this.pagingRegisters[reg] & this.romPageMask) << 14)]; // * $4000 + return this.rom && this.rom[a + ((this.pagingRegisters[reg] & this.romPageMask) << 14)]; // * $4000 } read = newAddressDecoder([ diff --git a/src/platform/apple2.ts b/src/platform/apple2.ts index 2474baf5..f80fc38f 100644 --- a/src/platform/apple2.ts +++ b/src/platform/apple2.ts @@ -76,6 +76,10 @@ class NewApple2Platform extends Base6502MachinePlatform implements Plat {name:'I/O',start:0xc000,size:0x1000,type:'io'}, {name:'ROM',start:0xd000,size:0x3000-6,type:'rom'}, ] } }; + getROMExtension(rom:Uint8Array) { + if (rom && rom.length == 35*16*256) return ".dsk"; // DSK image + return ".bin"; + }; } PLATFORMS['apple2.mame'] = Apple2MAMEPlatform; diff --git a/src/platform/atari7800.ts b/src/platform/atari7800.ts index 56f20fcf..5764fe3a 100644 --- a/src/platform/atari7800.ts +++ b/src/platform/atari7800.ts @@ -26,6 +26,7 @@ class Atari7800Platform extends Base6502MachinePlatform implements Pl {name:'RAM',start:0x1800,size:0x1000,type:'ram'}, // TODO: shadow ram {name:'Cartridge ROM',start:0x4000,size:0xc000,type:'rom'}, ] } }; + getROMExtension() { return ".a78"; } } /// diff --git a/src/platform/c64.ts b/src/platform/c64.ts index 60d2f808..df894651 100644 --- a/src/platform/c64.ts +++ b/src/platform/c64.ts @@ -65,6 +65,13 @@ class C64WASMPlatform extends Base6502MachinePlatform implement showHelp() { window.open("https://sta.c64.org/cbm64mem.html", "_help"); } + getROMExtension(rom:Uint8Array) { + /* + if (rom && rom[0] == 0x00 && rom[1] == 0x80 && rom[2+4] == 0xc3 && rom[2+5] == 0xc2) return ".crt"; + */ + if (rom && rom[0] == 0x01 && rom[1] == 0x08) return ".prg"; + else return ".bin"; + } } PLATFORMS['c64'] = C64WASMPlatform; diff --git a/src/platform/nes.ts b/src/platform/nes.ts index 738b9a8b..024e1b15 100644 --- a/src/platform/nes.ts +++ b/src/platform/nes.ts @@ -264,7 +264,9 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable { getOriginPC() { // TODO: is actually NMI return (this.readAddress(0xfffa) | (this.readAddress(0xfffb) << 8)) & 0xffff; } - getDefaultExtension() { return ".c"; }; + getDefaultExtension() { return ".c"; } + + getROMExtension() { return ".nes"; } reset() { //this.nes.cpu.reset(); // doesn't work right, crashes diff --git a/src/platform/vcs.ts b/src/platform/vcs.ts index 162da99f..f6b98c6d 100644 --- a/src/platform/vcs.ts +++ b/src/platform/vcs.ts @@ -248,7 +248,9 @@ class VCSPlatform extends BasePlatform { if (fn.endsWith(".bb") || fn.endsWith(".bas")) return "bataribasic"; return "dasm"; } - getDefaultExtension() { return ".a"; }; + getDefaultExtension() { return ".a"; } + + getROMExtension() { return ".a26"; } getDebugCategories() { return ['CPU','Stack','PIA','TIA']; diff --git a/src/platform/x86.ts b/src/platform/x86.ts index f2b09304..2fae9a83 100644 --- a/src/platform/x86.ts +++ b/src/platform/x86.ts @@ -159,6 +159,10 @@ class X86PCPlatform implements Platform { {name:'BIOS Expansions',start:0xc8000,size:0x28000,type:'rom'}, {name:'PC BIOS',start:0xf0000,size:0x10000,type:'rom'}, ] } }; - } + + getROMExtension(rom : Uint8Array) { + return ".exe"; + } +} PLATFORMS['x86'] = X86PCPlatform; diff --git a/src/platform/zmachine.ts b/src/platform/zmachine.ts index 98e1f848..973ef34d 100644 --- a/src/platform/zmachine.ts +++ b/src/platform/zmachine.ts @@ -809,6 +809,10 @@ class ZmachinePlatform implements Platform { this.reset(); } + getROMExtension() { + return ".z" + (this.zvm.version || 5); + } + reset(): void { if (this.zfile == null) return; this.zvm = new ZVM(); diff --git a/test/cli/testplatforms.js b/test/cli/testplatforms.js index 43829529..faee75e9 100644 --- a/test/cli/testplatforms.js +++ b/test/cli/testplatforms.js @@ -178,6 +178,7 @@ async function testPlatform(platid, romname, maxframes, callback) { assert.ok(dinfo && dinfo.length > 0, dcat + " empty"); assert.ok(dinfo.length < 80*24, dcat + " too long"); assert.ok(dinfo.indexOf('undefined') < 0, dcat + " undefined"); + assert.ok(dinfo.indexOf('Display On: false') < 0, dcat + " display off"); } if (lastrastervideo) { var png = new PNG({width:lastrastervideo.width, height:lastrastervideo.height}); @@ -190,6 +191,9 @@ async function testPlatform(platid, romname, maxframes, callback) { fs.writeFileSync("./test/output/"+platid+"-"+romname+".png", pngbuffer); } catch (e) { console.log(e) } } + // misc + assert.ok(platform.getDefaultExtension().startsWith('.')); + if (platform.getROMExtension) assert.ok(platform.getROMExtension().startsWith(".")); return platform; } @@ -308,6 +312,13 @@ describe('Platform Replay', () => { } }); }); + it('Should run sms-sms-libcv', async () => { + var platform = await testPlatform('sms-sms-libcv', 'climber.c-sms-sms-libcv.rom', 200, (platform, frameno) => { + if (frameno == 122) { + keycallback(Keys.RIGHT.c, Keys.VK_RIGHT.c, 1); + } + }); + }); it('Should run atari7800', async () => { var platform = await testPlatform('atari7800', 'sprites.dasm.rom', 92, (platform, frameno) => { if (frameno == 62) { diff --git a/test/roms/sms-sms-libcv/climber.c-sms-sms-libcv.rom b/test/roms/sms-sms-libcv/climber.c-sms-sms-libcv.rom new file mode 100644 index 00000000..92ff1705 Binary files /dev/null and b/test/roms/sms-sms-libcv/climber.c-sms-sms-libcv.rom differ