look in cache first, fetch local/ verilog includes too; apple2 reset; platform checkmark

This commit is contained in:
Steven Hugg 2018-07-24 11:38:56 -04:00
parent 4ea23e21f2
commit 6e5005f613
9 changed files with 82 additions and 45 deletions

View File

@ -19,7 +19,6 @@ TODO:
- can't step after reset (or when funky frame; TIA frame is out of sync)
- break on BRK/illegal opcode?
- multiple breakpoints, expression breakpoints
- run apple CPU until boot
- better disasm/listing selection
- disasm for z80
- watchpoints
@ -48,6 +47,7 @@ TODO:
- remove FPS and play controls when Verilog scope paused
- compile stuck when errors unchanged
- sound mute?
- $error updates source editor
WEB WORKER FORMAT

View File

@ -73,7 +73,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
<li><a class="dropdown-item" href="?platform=vcs-mame" id="item_platform_vcs">Atari VCS (MAME)</a></li>
<!--<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>-->
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
<li><a class="dropdown-item" href="?platform=vicdual" id="item_platform_vicdual">VIC Dual</a></li>
<li><a class="dropdown-item" href="?platform=mw8080bw" id="item_platform_mw8080bw">Midway 8080</a></li>
<li><a class="dropdown-item" href="?platform=galaxian-scramble" id="item_platform_galaxian_scramble">Galaxian/Scramble Hardware</a></li>

View File

@ -14,7 +14,7 @@
lda .loop+2 ; increment hi byte of instruction
clc
adc #1
sta .loop+2
sta .loop+2 ; self-modifying code
cmp #$40
bne .loop
lda #$20 ; reset to $2000

View File

@ -1,8 +1,6 @@
`ifndef RAM_H
`define RAM_H
`include "hvsync_generator.v"
module RAM_sync(clk, addr, din, dout, we);
parameter A = 10; // # of address bits

View File

@ -5,6 +5,7 @@ var APPLE2_PRESETS = [
{id:'mandel.c', name:'Mandelbrot'},
{id:'tgidemo.c', name:'TGI Graphics Demo'},
{id:'siegegame.c', name:'Siege Game'},
{id:'hgrtest.a', name:"HGR Test (asm)"},
{id:'conway.a', name:"Conway's Game of Life (asm)"},
// {id:'tb_6502.s', name:'Tom Bombem (assembler game)'},
];
@ -273,6 +274,14 @@ var Apple2Platform = function(mainElement) {
}
this.reset = function() {
cpu.reset();
// execute until $c600 boot
for (var i=0; i<2000000; i++) {
cpu.clockPulse();
if (this.getCPUState().PC == 0xc602) {
cpu.clockPulse();
break;
}
}
}
this.readAddress = function(addr) {
return bus.read(addr);

View File

@ -55,13 +55,14 @@ export class CodeProject {
parseFileDependencies(text:string):string[] {
var files = [];
if (this.platform_id == 'verilog') {
var re = /^(`include|[.]include)\s+"(.+?)"/gm;
var re = /^\s*(`include|[.]include)\s+"(.+?)"/gm;
var m;
while (m = re.exec(text)) {
files.push(m[2]);
files.push('local/'+m[2]); // TODO?
}
} else {
var re = /^([;#]|[/][/][#])link\s+"(.+?)"/gm;
var re = /^\s*([;#]|[/][/][#])link\s+"(.+?)"/gm;
var m;
while (m = re.exec(text)) {
files.push(m[2]);
@ -123,38 +124,42 @@ export class CodeProject {
// finished loading all files; return result
callback(null, result);
} else {
// look in store
this.store.getItem(path, (err, value) => {
if (err) { // err fetching from store
callback(err, result);
} else if (value) { // found in store?
this.filedata[path] = value;
addResult(path, value);
loadNext();
} else if (path in this.filedata) { // found in cache?
var data = this.filedata[path];
if (data)
addResult(path, data);
loadNext();
} else { // found on remote fetch?
var webpath = "presets/" + this.platform_id + "/" + path;
if (this.platform_id == 'vcs' && path.indexOf('.') <= 0)
webpath += ".a"; // legacy stuff
this.callbackGetRemote( webpath, (text:string) => {
console.log("GET",webpath,text.length,'bytes');
this.filedata[path] = text;
addResult(path, text);
// look in cache
if (path in this.filedata) { // found in cache?
var data = this.filedata[path];
if (data)
addResult(path, data);
loadNext();
} else {
// look in store
this.store.getItem(path, (err, value) => {
if (err) { // err fetching from store
callback(err, result);
} else if (value) { // found in store?
this.filedata[path] = value;
addResult(path, value);
loadNext();
}, 'text')
.fail( (err:XMLHttpRequest) => {
console.log("Could not load preset", path, err);
// only cache result if status is 404 (not found)
if (err.status && err.status == 404)
this.filedata[path] = null;
loadNext();
});
}
});
} else {
// found on remote fetch?
var webpath = "presets/" + this.platform_id + "/" + path;
if (this.platform_id == 'vcs' && path.indexOf('.') <= 0)
webpath += ".a"; // legacy stuff
this.callbackGetRemote( webpath, (text:string) => {
console.log("GET",webpath,text.length,'bytes');
this.filedata[path] = text;
addResult(path, text);
loadNext();
}, 'text')
.fail( (err:XMLHttpRequest) => {
console.log("Could not load preset", path, err);
// only cache result if status is 404 (not found)
if (err.status && err.status == 404)
this.filedata[path] = null;
loadNext();
});
}
});
}
}
}
loadNext(); // load first file

View File

@ -893,6 +893,7 @@ function startUI(loadplatform : boolean) {
if (!platform_id) {
platform_id = qs['platform'] = "vcs";
}
$("#item_platform_"+platform_id).addClass("dropdown-item-checked");
// parse query string
// is this a share URL?
if (qs['sharekey']) {

View File

@ -88,6 +88,23 @@ function buildModule(o : V2JS_Code) : string {
return m;
}
function getStats(o : V2JS_Code) {
var nmembits = 0;
var nlines = 0;
for (var sig of o.signals.concat(o.ports)) {
var len = sig.len || 0;
if (sig.arrdim)
for (var n of sig.arrdim)
len *= n;
nmembits += len;
}
for (var fn of o.funcs) {
nlines += fn.split('\n').length;
}
//console.log(nmembits,'bits',nlines,'lines');
return {bits:nmembits, lines:nlines};
}
function translateFunction(text : string) : string {
text = text.trim();
var funcname = text.match(/(\w+)/)[1];
@ -110,6 +127,7 @@ function translateFunction(text : string) : string {
text = text.replace(/^#/gm, '//#');
text = text.replace(/VL_LIKELY/g, '!!');
text = text.replace(/VL_UNLIKELY/g, '!!');
//[%0t] %Error: scoreboard.v:53: Assertion failed in %Nscoreboard_top.scoreboard_gen: reset 64 -935359306 Vscoreboard_top
text = text.replace(/Verilated::(\w+)Error/g, 'console.log');
text = text.replace(/vlSymsp.name[(][)]/g, '"'+moduleName+'"');
return "function " + text + "\nself." + funcname + " = " + funcname + ";\n";
@ -144,18 +162,21 @@ function translateStaticVars(text : string) : string {
var fntxt = translateFunction(functexts[i]);
funcs.push(fntxt);
}
var modinput = {
name:moduleName,
ports:ports,
signals:signals,
funcs:funcs,
};
return {
output:{
code:buildModule({
name:moduleName,
ports:ports,
signals:signals,
funcs:funcs,
}),
code:buildModule(modinput),
name:moduleName,
ports:ports,
signals:signals,
//stats:getStats(modinput),
}
};

View File

@ -9,6 +9,8 @@ includeInThisContext('src/platform/verilog.js');
function loadPlatform(msg) {
var platform = new VerilogPlatform();
try {
//console.log(msg.output.ports);
//console.log(msg.output.signals);
platform.loadROM("ROM", msg.output);
vl_finished = vl_stopped = false;
for (var i=0; i<10000 && !(vl_finished||vl_stopped); i++)
@ -53,6 +55,7 @@ describe('Verilog Worker', function() {
testVerilator('presets/verilog/hvsync_generator.v');
testVerilator('presets/verilog/lfsr.v');
testVerilator('presets/verilog/ram.v');
// TODO: how to include files?
//testVerilator('test/cli/verilog/t_tri_gate.v');