loadBIOS() now on Machine interface, updated c64 BIOS, emulator types SYS command

This commit is contained in:
Steven Hugg 2020-07-18 15:38:39 -05:00
parent aba1072abd
commit 08af6ae3a5
13 changed files with 95 additions and 53 deletions

View File

@ -178,7 +178,8 @@ TODO:
- C64
- disk image support
- https://github.com/cc65/cc65/issues/946
- need to sync advanceFrame() w/ vsync
- player 2 joystick and keyboard conflict
- problems with cgetc()
- upgrade to ES2020?
- https://github.com/microsoft/TypeScript/issues/16577
@ -386,6 +387,7 @@ Emulator Lib
- MAME
- debugging?
- kbd instructions don't work
Markdown (showdown) interface
- add code patches to files

15
package-lock.json generated
View File

@ -32,9 +32,9 @@
}
},
"@types/node": {
"version": "14.0.22",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.22.tgz",
"integrity": "sha512-emeGcJvdiZ4Z3ohbmw93E/64jRzUHAItSHt8nF7M4TGgQTiWqFVGB8KNpLGFmUHmHLvjvBgFwVlqNcq+VuGv9g==",
"version": "14.0.23",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz",
"integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==",
"dev": true
},
"@types/sizzle": {
@ -1067,7 +1067,8 @@
"lodash": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
},
"lodash.sortby": {
"version": "4.7.0",
@ -1766,9 +1767,9 @@
}
},
"typescript": {
"version": "3.9.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz",
"integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==",
"version": "3.9.7",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
"dev": true
},
"typescript-formatter": {

View File

@ -18,7 +18,7 @@
"@types/bootbox": "^4.4.36",
"@types/bootstrap": "^3.4.0",
"@types/jquery": "^3.5.0",
"@types/node": "^14.0.22",
"@types/node": "^14.0.23",
"atob": "^2.1.x",
"btoa": "^1.2.x",
"clipboard": "^2.0.6",
@ -28,7 +28,7 @@
"octokat": "^0.10.0",
"pngjs": "^3.4.0",
"rgbquant": "^1.1.2",
"typescript": "^3.9.6",
"typescript": "^3.9.7",
"typescript-formatter": "^7.2.2",
"vgm-parser": "^0.6.3"
},

View File

@ -262,7 +262,7 @@ void readline(char *instr) {
printf("Exceeded Max Line Length\n");
}
c=getchar();
}
}
instr[slen]='\0';
}
@ -278,7 +278,7 @@ void main()
char inputstr[MAXLINELEN];
int x,s;
char *location;
// use the first reply for each keyword match the first time you see that keyword
for (x=0;x<NUMKEYWORDS; x++) {
whichReply[x] = 0;

View File

@ -6,7 +6,7 @@
;Character cell data for default font
;(built into BIOS on ColecoVision)
;;{w:8,h:8,brev:1,count:224};;
;;{w:8,h:8,brev:1,count:96};;
Font_Space:
.DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;32
.DB 0x10,0x38,0x38,0x10,0x10,0x00,0x10,0x00 ;33

View File

@ -4,7 +4,7 @@
.globl _font_bitmap_0
;Character cell data for default font
;;{w:8,h:8,brev:1,count:224};;
;;{w:8,h:8,brev:1,count:96};;
Font_Space:
.DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;32
.DB 0x10,0x38,0x38,0x10,0x10,0x00,0x10,0x00 ;33

Binary file not shown.

View File

@ -970,7 +970,7 @@ export function lookupSymbol(platform:Platform, addr:number, extra:boolean) {
/// new Machine platform adapters
import { Bus, Resettable, FrameBased, VideoSource, SampledAudioSource, AcceptsROM, AcceptsKeyInput, SavesState, SavesInputState, HasCPU, TrapCondition, CPU } from "./devices";
import { Bus, Resettable, FrameBased, VideoSource, SampledAudioSource, AcceptsROM, AcceptsBIOS, AcceptsKeyInput, SavesState, SavesInputState, HasCPU, TrapCondition, CPU } from "./devices";
import { Probeable, RasterFrameBased, AcceptsPaddleInput, SampledAudioSink, ProbeAll, NullProbe } from "./devices";
import { SampledAudio } from "./audio";
import { ProbeRecorder } from "./recorder";
@ -996,6 +996,9 @@ function isRaster(arg:any): arg is RasterFrameBased {
function hasProbe(arg:any): arg is Probeable {
return typeof arg.connectProbe == 'function';
}
function hasBIOS(arg:any): arg is AcceptsBIOS {
return typeof arg.loadBIOS == 'function';
}
export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPlatform implements Platform {
machine : T;
@ -1064,6 +1067,11 @@ export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPl
m.connectProbe(null);
};
}
if (hasBIOS(m)) {
this.loadBIOS = (title, data) => {
m.loadBIOS(data, title);
};
}
}
loadROM(title, data) {
@ -1071,12 +1079,18 @@ export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPl
this.reset();
}
loadBIOS; // only set if hasBIOS() is true
pollControls() {
this.poller && this.poller.poll();
if (hasPaddleInput(this.machine)) {
this.machine.setPaddleInput(0, this.video.paddle_x);
this.machine.setPaddleInput(1, this.video.paddle_y);
}
// TODO: put into interface
if (this.machine['pollControls']) {
this.machine['pollControls']();
}
}
advance(novideo:boolean) {
@ -1209,6 +1223,8 @@ export abstract class BaseWASMMachine {
romptr : number;
romlen : number;
romarr : Uint8Array;
biosptr : number;
biosarr : Uint8Array;
audio : SampledAudioSink;
audioarr : Float32Array;
probe : ProbeAll;
@ -1246,12 +1262,11 @@ export abstract class BaseWASMMachine {
// fetch BIOS
var biosResponse = await fetch('res/'+this.prefix+'.bios');
var biosBinary = await biosResponse.arrayBuffer();
const cBIOSPointer = this.exports.malloc(0x5000);
const srcArray = new Uint8Array(biosBinary);
const destArray = new Uint8Array(this.exports.memory.buffer, cBIOSPointer, 0x5000);
destArray.set(srcArray);
this.biosptr = this.exports.malloc(biosBinary.byteLength);
this.biosarr = new Uint8Array(this.exports.memory.buffer, this.biosptr, biosBinary.byteLength);
this.loadBIOS(new Uint8Array(biosBinary));
// init machine instance
this.sys = this.exports.machine_init(cBIOSPointer);
this.sys = this.exports.machine_init(this.biosptr);
console.log('machine_init', this.sys);
// create state buffers
var statesize = this.exports.machine_get_state_size();
@ -1287,9 +1302,18 @@ export abstract class BaseWASMMachine {
this.romlen = rom.length;
this.reset();
}
// TODO: can't load after machine_init
loadBIOS(srcArray: Uint8Array) {
this.biosarr.set(srcArray);
}
reset() {
this.exports.machine_reset(this.sys);
}
/* TODO: we don't need this because c64_exec does this?
pollControls() {
this.exports.machine_start_frame(this.sys);
}
*/
read(address: number) : number {
return this.exports.machine_mem_read(this.sys, address & 0xffff);
}

View File

@ -63,6 +63,10 @@ export interface AcceptsROM {
loadROM(data:Uint8Array, title?:string) : void;
}
export interface AcceptsBIOS {
loadBIOS(data:Uint8Array, title?:string) : void;
}
export interface Resettable {
reset() : void;
}

View File

@ -1076,8 +1076,8 @@ async function loadBIOSFromProject() {
var biospath = platform_id + '.rom';
var biosdata = await store.getItem(biospath);
if (biosdata instanceof Uint8Array) {
console.log('loading BIOS')
platform.loadBIOS('BIOS', biosdata);
console.log('loading BIOS', biospath, biosdata.length + " bytes")
platform.loadBIOS(biospath, biosdata);
} else {
console.log('BIOS file must be binary')
}

View File

@ -24,8 +24,17 @@ export class C64_WASMMachine extends BaseWASMMachine implements Machine, Probeab
joymask0 = 0;
joymask1 = 0;
loadBIOS(srcArray: Uint8Array) {
var patch1ofs = 0xea24 - 0xe000 + 0x3000;
/*if (srcArray[patch1ofs] == 0x02)*/ srcArray[patch1ofs] = 0x60; // cursor move, KIL -> RTS
super.loadBIOS(srcArray);
}
reset() {
super.reset();
// clear keyboard
for (var ch=0; ch<128; ch++) {
this.setKeyInput(ch, 0, KeyFlags.KeyUp);
}
// load rom
if (this.romptr && this.romlen) {
this.exports.machine_load_rom(this.sys, this.romptr, this.romlen);
@ -35,38 +44,36 @@ export class C64_WASMMachine extends BaseWASMMachine implements Machine, Probeab
this.prgstart = this.romarr[2] + (this.romarr[3]<<8) + 2; // point to after BASIC program
console.log("prgstart", hex(this.prgstart));
}
}
// clear keyboard
for (var ch=0; ch<128; ch++) {
this.setKeyInput(ch, 0, KeyFlags.KeyUp);
}
// is program loaded into RAM?
if (this.prgstart < 0x8000) {
// advance BIOS a few frames
this.exports.machine_exec(this.sys, 150000);
// set IRQ routine @ 0x314
var old0x314 = this.read(0x314) + this.read(0x315) * 256;
this.write(0x314, this.prgstart & 0xff);
this.write(0x315, (this.prgstart >> 8) & 0xff);
// wait until IRQ fires
for (var i=0; i<50000 && this.getPC() != this.prgstart; i++) {
this.exports.machine_tick(this.sys);
}
// reset 0x314 to old value
this.write(0x314, old0x314 & 0xff);
this.write(0x315, old0x314 >> 8);
} else {
// get out of reset
this.exports.machine_exec(this.sys, 100);
// wait until cartridge start
// TODO: detect ROM cartridge
var warmstart = this.romarr[0x4] + this.romarr[0x5]*256;
for (var i=0; i<150000 && this.getPC() != warmstart; i++) {
this.exports.machine_tick(this.sys);
// is program loaded into RAM?
if (this.prgstart < 0x8000) {
// advance BIOS a few frames
this.exports.machine_exec(this.sys, 250000);
// type in command (SYS 2061)
var cmd = "SYS "+this.prgstart+"\r";
for (var i=0; i<cmd.length; i++) {
var key = cmd.charCodeAt(i);
this.exports.machine_exec(this.sys, 10000);
this.exports.machine_key_down(this.sys, key);
this.exports.machine_exec(this.sys, 10000);
this.exports.machine_key_up(this.sys, key);
}
// advance clock until program starts
for (var i=0; i<100000 && this.getPC() != this.prgstart; i++) {
this.exports.machine_tick(this.sys);
}
} else {
// get out of reset
this.exports.machine_exec(this.sys, 100);
// wait until cartridge start
// TODO: detect ROM cartridge
var warmstart = this.romarr[0x4] + this.romarr[0x5]*256;
for (var i=0; i<150000 && this.getPC() != warmstart; i++) {
this.exports.machine_tick(this.sys);
}
}
// TODO: shouldn't we return here @ start of frame?
// and stop probing
}
// TODO: shouldn't we return here @ start of frame?
// and stop probing
}
advanceFrame(trap: TrapCondition) : number {
// TODO: does this sync with VSYNC?
@ -129,11 +136,13 @@ export class C64_WASMMachine extends BaseWASMMachine implements Machine, Probeab
if (key == 39) { key = 0x9; mask = 0x8; } // RIGHT
if (key == 40) { key = 0xa; mask = 0x2; } // DOWN
if (key == 32) { mask = 0x10; } // FIRE
/* player 2 (TODO)
if (key == 65) { key = 65; mask2 = 0x4; } // LEFT
if (key == 87) { key = 87; mask2 = 0x1; } // UP
if (key == 68) { key = 68; mask2 = 0x8; } // RIGHT
if (key == 83) { key = 83; mask2 = 0x2; } // DOWN
if (key == 69) { mask2 = 0x10; } // FIRE
*/
if (key == 113) { key = 0xf1; } // F2
if (key == 115) { key = 0xf3; } // F4
if (key == 119) { key = 0xf5; } // F8

View File

@ -32,7 +32,6 @@ class BallyAstrocadePlatform extends BaseZ80MachinePlatform<BallyAstrocade> impl
getPresets() { return ASTROCADE_PRESETS; }
getDefaultExtension() { return ".c"; };
readAddress(a) { return this.machine.read(a); }
loadBIOS(title,bios) { this.machine.loadBIOS(bios); }
getMemoryMap = function() { return { main:[
{name:'BIOS',start:0x0,size:0x2000,type:'rom'},
//{name:'Cart ROM',start:0x2000,size:0x2000,type:'rom'},

View File

@ -32,6 +32,9 @@ class ColecoVisionPlatform extends BaseZ80MachinePlatform<ColecoVision> implemen
{name:'BIOS',start:0x0,size:0x2000,type:'rom'},
{name:'Cartridge Header',start:0x8000,size:0x100,type:'rom'},
] } };
showHelp(tool:string, ident:string) {
window.open("https://8bitworkshop.com/blog/platforms/coleco/", "_help");
}
}
/// MAME support