ui: refresh windows when errors/EmuHalt; arm32 changes
This commit is contained in:
parent
d79f3c3da9
commit
240578d942
|
@ -201,11 +201,13 @@ TODO:
|
||||||
- show current tool for file
|
- show current tool for file
|
||||||
- download non-text incbin source file
|
- download non-text incbin source file
|
||||||
- show hidden header files that only exist in Emscripten FS
|
- show hidden header files that only exist in Emscripten FS
|
||||||
can't modify/delete an include file if project doesn't compile
|
|
||||||
|
|
||||||
Probing
|
Probing
|
||||||
- probe log doesn't start @ reset
|
- probe log doesn't start @ reset
|
||||||
|
- scroll to current probe log location
|
||||||
Debug, play then halt cpu doesn't highlight final line
|
Debug, play then halt cpu doesn't highlight final line
|
||||||
|
- illegal instruction should show debug info + jump to line
|
||||||
|
- halt cpu should show video too
|
||||||
vcs: input not preserved when replaying frames?
|
vcs: input not preserved when replaying frames?
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1126,7 +1126,6 @@ function showExceptionAsError(err, msg:string) {
|
||||||
werr = Object.create(err.$loc);
|
werr = Object.create(err.$loc);
|
||||||
werr.msg = msg;
|
werr.msg = msg;
|
||||||
console.log(werr);
|
console.log(werr);
|
||||||
projectWindows.refresh(false);
|
|
||||||
}
|
}
|
||||||
showErrorAlert([werr], true);
|
showErrorAlert([werr], true);
|
||||||
}
|
}
|
||||||
|
@ -1149,6 +1148,7 @@ function setCompileOutput(data: WorkerResult) {
|
||||||
if (data && data.errors && data.errors.length > 0) {
|
if (data && data.errors && data.errors.length > 0) {
|
||||||
toolbar.addClass("has-errors");
|
toolbar.addClass("has-errors");
|
||||||
projectWindows.setErrors(data.errors);
|
projectWindows.setErrors(data.errors);
|
||||||
|
refreshWindowList(); // to make sure windows are created for showErrorAlert()
|
||||||
showErrorAlert(data.errors, false);
|
showErrorAlert(data.errors, false);
|
||||||
} else {
|
} else {
|
||||||
toolbar.removeClass("has-errors"); // may be added in next callback
|
toolbar.removeClass("has-errors"); // may be added in next callback
|
||||||
|
@ -1657,14 +1657,15 @@ function addFileToProject(type, ext, linefn) {
|
||||||
function _addIncludeFile() {
|
function _addIncludeFile() {
|
||||||
var fn = getCurrentMainFilename();
|
var fn = getCurrentMainFilename();
|
||||||
var tool = platform.getToolForFilename(fn);
|
var tool = platform.getToolForFilename(fn);
|
||||||
|
// TODO: more tools?
|
||||||
if (fn.endsWith(".c") || tool == 'sdcc' || tool == 'cc65' || tool == 'cmoc' || tool == 'smlrc')
|
if (fn.endsWith(".c") || tool == 'sdcc' || tool == 'cc65' || tool == 'cmoc' || tool == 'smlrc')
|
||||||
addFileToProject("Header", ".h", (s) => { return '#include "'+s+'"' });
|
addFileToProject("Header", ".h", (s) => { return '#include "'+s+'"' });
|
||||||
else if (tool == 'dasm' || tool == 'zmac')
|
else if (tool == 'dasm' || tool == 'zmac')
|
||||||
addFileToProject("Include File", ".inc", (s) => { return '\tinclude "'+s+'"' });
|
addFileToProject("Include", ".inc", (s) => { return '\tinclude "'+s+'"' });
|
||||||
else if (tool == 'ca65' || tool == 'sdasz80')
|
else if (tool == 'ca65' || tool == 'sdasz80' || tool == 'vasm' || tool == 'armips')
|
||||||
addFileToProject("Include File", ".inc", (s) => { return '\t.include "'+s+'"' });
|
addFileToProject("Include", ".inc", (s) => { return '\t.include "'+s+'"' });
|
||||||
else if (tool == 'verilator')
|
else if (tool == 'verilator')
|
||||||
addFileToProject("Verilog File", ".v", (s) => { return '`include "'+s+'"' });
|
addFileToProject("Verilog", ".v", (s) => { return '`include "'+s+'"' });
|
||||||
else
|
else
|
||||||
alertError("Can't add include file to this project type (" + tool + ")");
|
alertError("Can't add include file to this project type (" + tool + ")");
|
||||||
}
|
}
|
||||||
|
@ -2340,6 +2341,8 @@ export function getSaveState() {
|
||||||
export function emulationHalted(err: EmuHalt) {
|
export function emulationHalted(err: EmuHalt) {
|
||||||
var msg = (err && err.message) || msg;
|
var msg = (err && err.message) || msg;
|
||||||
showExceptionAsError(err, msg);
|
showExceptionAsError(err, msg);
|
||||||
|
projectWindows.refresh(true);
|
||||||
|
if (platform.saveState) showDebugInfo(platform.saveState());
|
||||||
}
|
}
|
||||||
|
|
||||||
// get remote file from local fs
|
// get remote file from local fs
|
||||||
|
|
|
@ -6,23 +6,23 @@ import { TssChannelAdapter, MasterAudio, AY38910_Audio } from "../common/audio";
|
||||||
import { Debuggable, EmuState } from "../common/baseplatform";
|
import { Debuggable, EmuState } from "../common/baseplatform";
|
||||||
import { hex, lpad, printFlags } from "../common/util";
|
import { hex, lpad, printFlags } from "../common/util";
|
||||||
|
|
||||||
const SPACEINV_KEYCODE_MAP = makeKeycodeMap([
|
var GBA_KEYCODE_MAP = makeKeycodeMap([
|
||||||
[Keys.A, 1, 0x10], // P1
|
[Keys.A, 0, 0x1],
|
||||||
[Keys.LEFT, 1, 0x20],
|
[Keys.B, 0, 0x2],
|
||||||
[Keys.RIGHT, 1, 0x40],
|
[Keys.SELECT,0, 0x4],
|
||||||
[Keys.P2_A, 2, 0x10], // P2
|
[Keys.START ,0, 0x8],
|
||||||
[Keys.P2_LEFT, 2, 0x20],
|
[Keys.RIGHT, 0, 0x10],
|
||||||
[Keys.P2_RIGHT, 2, 0x40],
|
[Keys.LEFT, 0, 0x20],
|
||||||
[Keys.SELECT, 1, 0x1],
|
[Keys.UP, 0, 0x40],
|
||||||
[Keys.START, 1, 0x4],
|
[Keys.DOWN, 0, 0x80],
|
||||||
[Keys.P2_START, 1, 0x2],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ROM_START = 0x0;
|
const ROM_START = 0x0;
|
||||||
const ROM2_START= 0xff800000;
|
|
||||||
const ROM_SIZE = 0x80000;
|
const ROM_SIZE = 0x80000;
|
||||||
const RAM_START = 0x20000000;
|
const RAM_START = 0x2000000;
|
||||||
const RAM_SIZE = 0x80000;
|
const RAM_SIZE = 0x80000;
|
||||||
|
const IO_START = 0x4000000;
|
||||||
|
const IO_SIZE = 0x100;
|
||||||
|
|
||||||
const CPU_FREQ = 4000000; // 4 MHz
|
const CPU_FREQ = 4000000; // 4 MHz
|
||||||
|
|
||||||
|
@ -47,14 +47,13 @@ export class ARM32Machine extends BasicScanlineMachine implements Debuggable {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.connectCPUMemoryBus(this);
|
this.connectCPUMemoryBus(this);
|
||||||
this.handler = newKeyboardHandler(this.inputs, SPACEINV_KEYCODE_MAP);
|
this.handler = newKeyboardHandler(this.inputs, GBA_KEYCODE_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectVideo(pixels:Uint32Array) : void {
|
connectVideo(pixels:Uint32Array) : void {
|
||||||
super.connectVideo(pixels);
|
super.connectVideo(pixels);
|
||||||
this.pixels32 = pixels;
|
this.pixels32 = pixels;
|
||||||
this.pixels8 = new Uint8Array(pixels.buffer);
|
this.pixels8 = new Uint8Array(pixels.buffer);
|
||||||
//this.pixels.fill(0xff000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 32-bit bus?
|
// TODO: 32-bit bus?
|
||||||
|
@ -66,8 +65,8 @@ export class ARM32Machine extends BasicScanlineMachine implements Debuggable {
|
||||||
[RAM_START, RAM_START+RAM_SIZE-1, RAM_SIZE-1, (a) => {
|
[RAM_START, RAM_START+RAM_SIZE-1, RAM_SIZE-1, (a) => {
|
||||||
return this.ram[a];
|
return this.ram[a];
|
||||||
}],
|
}],
|
||||||
[ROM2_START, ROM2_START+ROM_SIZE-1, ROM_SIZE-1, (a) => {
|
[IO_START, IO_START+IO_SIZE-1, IO_SIZE-1, (a, v) => {
|
||||||
return this.rom ? this.rom[a] : 0;
|
return this.readIO(a);
|
||||||
}],
|
}],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -75,8 +74,28 @@ export class ARM32Machine extends BasicScanlineMachine implements Debuggable {
|
||||||
[RAM_START, RAM_START+RAM_SIZE-1, RAM_SIZE-1, (a, v) => {
|
[RAM_START, RAM_START+RAM_SIZE-1, RAM_SIZE-1, (a, v) => {
|
||||||
this.ram[a] = v;
|
this.ram[a] = v;
|
||||||
}],
|
}],
|
||||||
|
[IO_START, IO_START+IO_SIZE-1, IO_SIZE-1, (a, v) => {
|
||||||
|
this.writeIO(a, v);
|
||||||
|
}],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
readIO(a : number) : number {
|
||||||
|
switch (a) {
|
||||||
|
case 0x0:
|
||||||
|
return this.inputs[0];
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeIO(a : number, v : number) : void {
|
||||||
|
switch (a) {
|
||||||
|
case 0x0:
|
||||||
|
//this.brightness = v & 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
startScanline() {
|
startScanline() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,29 +115,32 @@ export class ARM32Machine extends BasicScanlineMachine implements Debuggable {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDebugCategories() {
|
getDebugCategories() {
|
||||||
return ['CPU'];
|
return ['CPU', 'Stack'];
|
||||||
}
|
}
|
||||||
|
|
||||||
getDebugInfo?(category: string, state: EmuState) : string {
|
getDebugInfo?(category: string, state: EmuState) : string {
|
||||||
var s = '';
|
switch (category) {
|
||||||
var c = state.c as ARMCoreState;
|
case 'CPU':
|
||||||
const EXEC_MODE = {2:'Thumb',4:'ARM'};
|
var s = '';
|
||||||
const REGNAMES = {15:'PC',14:'LR',13:'SP',12:'IP',11:'FP',9:'SB'};
|
var c = state.c as ARMCoreState;
|
||||||
for (var i=0; i<16; i++) {
|
const EXEC_MODE = {2:'Thumb',4:'ARM'};
|
||||||
s += lpad(REGNAMES[i]||'',3) + lpad('r'+i, 5) + ' ' + hex(c.gprs[i],8) + '\n';
|
const REGNAMES = {15:'PC',14:'LR',13:'SP',12:'IP',11:'FP',9:'SB'};
|
||||||
|
for (var i=0; i<16; i++) {
|
||||||
|
s += lpad(REGNAMES[i]||'',3) + lpad('r'+i, 5) + ' ' + hex(c.gprs[i],8) + '\n';
|
||||||
|
}
|
||||||
|
s += 'Flags ';
|
||||||
|
s += c.cpsrN ? " N" : " -";
|
||||||
|
s += c.cpsrV ? " V" : " -";
|
||||||
|
s += c.cpsrF ? " F" : " -";
|
||||||
|
s += c.cpsrZ ? " Z" : " -";
|
||||||
|
s += c.cpsrC ? " C" : " -";
|
||||||
|
s += c.cpsrI ? " I" : " -";
|
||||||
|
s += '\n';
|
||||||
|
s += 'MODE ' + EXEC_MODE[c.instructionWidth] + ' ' + MODE_NAMES[c.mode] + '\n';
|
||||||
|
s += 'SPSR ' + hex(c.spsr,8) + '\n';
|
||||||
|
s += 'cycl ' + c.cycles + '\n';
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
s += 'Flags ';
|
|
||||||
s += c.cpsrN ? " N" : " -";
|
|
||||||
s += c.cpsrV ? " V" : " -";
|
|
||||||
s += c.cpsrF ? " F" : " -";
|
|
||||||
s += c.cpsrZ ? " Z" : " -";
|
|
||||||
s += c.cpsrC ? " C" : " -";
|
|
||||||
s += c.cpsrI ? " I" : " -";
|
|
||||||
s += '\n';
|
|
||||||
s += 'MODE ' + EXEC_MODE[c.instructionWidth] + ' ' + MODE_NAMES[c.mode] + '\n';
|
|
||||||
s += 'SPSR ' + hex(c.spsr,8) + '\n';
|
|
||||||
s += 'cycl ' + c.cycles + '\n';
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,9 +251,8 @@ class ARM32Platform extends BaseARMMachinePlatform<ARM32Machine> implements Plat
|
||||||
newMachine() { return new ARM32Machine(); }
|
newMachine() { return new ARM32Machine(); }
|
||||||
readAddress(a) { return this.machine.read(a); }
|
readAddress(a) { return this.machine.read(a); }
|
||||||
getMemoryMap = function() { return { main:[
|
getMemoryMap = function() { return { main:[
|
||||||
{name:'ROM',start:0x00000000,size:0x80000,type:'rom'},
|
{name:'ROM',start:0x0000000,size:0x80000,type:'rom'},
|
||||||
{name:'RAM',start:0x20000000,size:0x80000,type:'ram'},
|
{name:'RAM',start:0x2000000,size:0x80000,type:'ram'},
|
||||||
{name:'Video RAM',start:0x40000000,size:0x20000,type:'ram'},
|
|
||||||
] } };
|
] } };
|
||||||
disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {
|
disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {
|
||||||
var is_thumb = this.machine.cpu.isThumb();
|
var is_thumb = this.machine.cpu.isThumb();
|
||||||
|
|
|
@ -455,15 +455,17 @@ function gatherFiles(step:BuildStep, options?:BuildOptions) {
|
||||||
step.files = [path];
|
step.files = [path];
|
||||||
}
|
}
|
||||||
if (step.path && !step.prefix) {
|
if (step.path && !step.prefix) {
|
||||||
step.prefix = step.path;
|
step.prefix = getPrefix(step.path);
|
||||||
var pos = step.prefix.lastIndexOf('.');
|
|
||||||
if (pos > 0)
|
|
||||||
step.prefix = step.prefix.substring(0, pos);
|
|
||||||
}
|
}
|
||||||
step.maxts = maxts;
|
step.maxts = maxts;
|
||||||
return maxts;
|
return maxts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPrefix(s : string) : string {
|
||||||
|
var pos = s.lastIndexOf('.');
|
||||||
|
return (pos > 0) ? s.substring(0, pos) : s;
|
||||||
|
}
|
||||||
|
|
||||||
function populateFiles(step:BuildStep, fs, options?:BuildOptions) {
|
function populateFiles(step:BuildStep, fs, options?:BuildOptions) {
|
||||||
gatherFiles(step, options);
|
gatherFiles(step, options);
|
||||||
if (!step.files) throw Error("call gatherFiles() first");
|
if (!step.files) throw Error("call gatherFiles() first");
|
||||||
|
@ -2903,6 +2905,10 @@ function assembleARMIPS(step:BuildStep) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var FS = armips['FS'];
|
var FS = armips['FS'];
|
||||||
|
var code = getWorkFileAsString(step.path);
|
||||||
|
code = `.arm.little :: .create "${objpath}",0 :: ${code}
|
||||||
|
.close`;
|
||||||
|
putWorkFile(step.path, code);
|
||||||
populateFiles(step, FS);
|
populateFiles(step, FS);
|
||||||
execMain(step, armips, args);
|
execMain(step, armips, args);
|
||||||
if (errors.length)
|
if (errors.length)
|
||||||
|
@ -2916,26 +2922,30 @@ function assembleARMIPS(step:BuildStep) {
|
||||||
var symbolmap = {};
|
var symbolmap = {};
|
||||||
var segments = [];
|
var segments = [];
|
||||||
var listings : CodeListingMap = {};
|
var listings : CodeListingMap = {};
|
||||||
|
|
||||||
var lstout = FS.readFile(lstpath, {encoding:'utf8'}) as string;
|
var lstout = FS.readFile(lstpath, {encoding:'utf8'}) as string;
|
||||||
var lines = lstout.split(re_crlf);
|
var lines = lstout.split(re_crlf);
|
||||||
var lstlines : SourceLine[] = [];
|
|
||||||
//00000034 .word 0x11223344 ; /vidfill.armips line 25
|
//00000034 .word 0x11223344 ; /vidfill.armips line 25
|
||||||
var re_asmline = /^([0-9A-F]+) (.+?); [/](.+?) line (\d+)/;
|
var re_asmline = /^([0-9A-F]+) (.+?); [/](.+?) line (\d+)/;
|
||||||
|
var lastofs = -1;
|
||||||
for (var line of lines) {
|
for (var line of lines) {
|
||||||
var m;
|
var m;
|
||||||
if (m = re_asmline.exec(line)) {
|
if (m = re_asmline.exec(line)) {
|
||||||
|
var path = m[3];
|
||||||
|
var path2 = getPrefix(path) + '.lst'; // TODO: don't rename listing
|
||||||
|
var lst = listings[path2];
|
||||||
|
if (lst == null) { lst = listings[path2] = {lines:[]}; }
|
||||||
var ofs = parseInt(m[1], 16);
|
var ofs = parseInt(m[1], 16);
|
||||||
var insn = objout.slice(ofs, ofs+4); // TODO: doesn't do thumb or !=4 bytes
|
var insn = objout.slice(ofs, ofs+4); // TODO: doesn't do thumb or !=4 bytes
|
||||||
lstlines.push({
|
if (lastofs == ofs) lst.lines.pop(); else lastofs = ofs;
|
||||||
path: m[3],
|
lst.lines.push({
|
||||||
|
path: path,
|
||||||
line: parseInt(m[4]),
|
line: parseInt(m[4]),
|
||||||
offset: ofs,
|
offset: ofs,
|
||||||
insns: hex(insn[0]) + hex(insn[1]) + hex(insn[2]) + hex(insn[3])
|
insns: hex(insn[3]) + hex(insn[2]) + hex(insn[1]) + hex(insn[0])
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
listings[lstpath] = {lines:lstlines, text:lstout};
|
//listings[lstpath] = {lines:lstlines, text:lstout};
|
||||||
|
|
||||||
var symout = FS.readFile(sympath, {encoding:'utf8'}) as string;
|
var symout = FS.readFile(sympath, {encoding:'utf8'}) as string;
|
||||||
//0000000C loop2
|
//0000000C loop2
|
||||||
|
@ -2988,7 +2998,6 @@ function assembleVASMARM(step:BuildStep) {
|
||||||
path:matches[4],
|
path:matches[4],
|
||||||
msg:matches[5],
|
msg:matches[5],
|
||||||
});
|
});
|
||||||
console.log(matches);
|
|
||||||
} else {
|
} else {
|
||||||
matches = re_err2.exec(s);
|
matches = re_err2.exec(s);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
|
|
Loading…
Reference in New Issue