HALT fix, QoL tweaks
This commit is contained in:
parent
89feaaa3e9
commit
b33a6c3055
|
@ -121,7 +121,7 @@ globalThis.App = class App {
|
||||||
// ROM buffer has been configured
|
// ROM buffer has been configured
|
||||||
setROM(msg) {
|
setROM(msg) {
|
||||||
let dbg = this.debuggers[msg.sim];
|
let dbg = this.debuggers[msg.sim];
|
||||||
dbg.refresh();
|
dbg.refresh(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ globalThis.Debugger = class Debugger {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload all output
|
// Reload all output
|
||||||
refresh() {
|
refresh(seekToPC) {
|
||||||
this.cpu .refresh();
|
this.cpu .refresh(seekToPC);
|
||||||
this.memory.refresh();
|
this.memory.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@
|
||||||
case "ReadBuffer" : this.readBuffer (msg); break;
|
case "ReadBuffer" : this.readBuffer (msg); break;
|
||||||
case "SetRegister" : this.setRegister (msg); break;
|
case "SetRegister" : this.setRegister (msg); break;
|
||||||
case "RunNext": case "SingleStep":
|
case "RunNext": case "SingleStep":
|
||||||
this.refresh(true); break;
|
this.debug.refresh(true); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,8 +345,10 @@
|
||||||
let reg2 = this.PROREGNAMES[bits >> 21 & 31];
|
let reg2 = this.PROREGNAMES[bits >> 21 & 31];
|
||||||
let reg1 = this.PROREGNAMES[bits >> 16 & 31];
|
let reg1 = this.PROREGNAMES[bits >> 16 & 31];
|
||||||
let disp = this.signExtend(bits & 0xFFFF, 16);
|
let disp = this.signExtend(bits & 0xFFFF, 16);
|
||||||
disp = disp == 0 ? "" : (disp < 0 ? "-" : "") + "0x" +
|
disp = disp == 0 ? "" : (disp < -255 || disp > 255) ? "0x" +
|
||||||
Math.abs(disp).toString(16).toUpperCase();
|
("000" + (disp & 0xFFFF).toString(16).toUpperCase()).slice(-4) :
|
||||||
|
(disp < 0 ? "-" : "") + "0x" +
|
||||||
|
Math.abs(disp).toString(16).toUpperCase();
|
||||||
switch (inst.opcode) {
|
switch (inst.opcode) {
|
||||||
case 0b110000: // LD.B
|
case 0b110000: // LD.B
|
||||||
case 0b110001: // LD.H
|
case 0b110001: // LD.H
|
||||||
|
|
|
@ -99,8 +99,8 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
|
||||||
// Message received
|
// Message received
|
||||||
message(msg) {
|
message(msg) {
|
||||||
switch (msg.command) {
|
switch (msg.command) {
|
||||||
case "ReadBuffer": this.readBuffer(msg); break;
|
case "ReadBuffer": this.readBuffer(msg) ; break;
|
||||||
case "Write" : this.debug.refresh(); break;
|
case "Write" : this.debug.refresh(false); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,6 +380,7 @@ MemoryWindow.Row = class Row extends Toolkit.Panel {
|
||||||
|
|
||||||
// Configure element
|
// Configure element
|
||||||
this.element.setAttribute("role", "row");
|
this.element.setAttribute("role", "row");
|
||||||
|
this.element.addEventListener("pointerdown", e=>this.onpointerdown(e));
|
||||||
|
|
||||||
// Address label
|
// Address label
|
||||||
this.addr = this.add(parent.newLabel({ text: "\u00a0" }));
|
this.addr = this.add(parent.newLabel({ text: "\u00a0" }));
|
||||||
|
@ -418,6 +419,31 @@ MemoryWindow.Row = class Row extends Toolkit.Panel {
|
||||||
return (this.wnd.address + this.offset & 0xFFFFFFFF) >>> 0;
|
return (this.wnd.address + this.offset & 0xFFFFFFFF) >>> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pointer down event handler
|
||||||
|
onpointerdown(e) {
|
||||||
|
|
||||||
|
// Error checking
|
||||||
|
if (e.button != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check whether the click is within the columns of cells
|
||||||
|
let next = this.cells[0].getBounds();
|
||||||
|
if (e.x < next.left)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Compute which cell was clicked
|
||||||
|
for (let x = 0; x < 16; x++) {
|
||||||
|
let cur = next;
|
||||||
|
if (x < 15) {
|
||||||
|
next = this.cells[x + 1].getBounds();
|
||||||
|
if (e.x < (cur.right + next.left) / 2)
|
||||||
|
return this.wnd.setSelected(this.cells[x].address());
|
||||||
|
} else if (e.x < cur.right)
|
||||||
|
return this.wnd.setSelected(this.cells[x].address());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// One cell of output
|
// One cell of output
|
||||||
|
@ -435,7 +461,6 @@ MemoryWindow.Cell = class Cell extends Toolkit.Label {
|
||||||
// Configure element
|
// Configure element
|
||||||
this.element.setAttribute("role", "gridcell");
|
this.element.setAttribute("role", "gridcell");
|
||||||
this.element.setAttribute("name", "byte");
|
this.element.setAttribute("name", "byte");
|
||||||
this.element.addEventListener("pointerdown", e=>this.onpointerdown(e));
|
|
||||||
|
|
||||||
parent.add(this);
|
parent.add(this);
|
||||||
}
|
}
|
||||||
|
@ -473,10 +498,4 @@ MemoryWindow.Cell = class Cell extends Toolkit.Label {
|
||||||
return (this.wnd.address + this.offset & 0xFFFFFFFF) >>> 0;
|
return (this.wnd.address + this.offset & 0xFFFFFFFF) >>> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointer down event handler
|
|
||||||
onpointerdown(e) {
|
|
||||||
if (e.button == 0)
|
|
||||||
this.wnd.setSelected(this.address());
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
62
core/cpu.c
62
core/cpu.c
|
@ -979,7 +979,7 @@ static void cpuDIVU(VB *emu, VB_INSTRUCTION *inst) {
|
||||||
static void cpuHALT(VB *emu, VB_INSTRUCTION *inst) {
|
static void cpuHALT(VB *emu, VB_INSTRUCTION *inst) {
|
||||||
emu->cpu.state = CPU_HALTED;
|
emu->cpu.state = CPU_HALTED;
|
||||||
inst->size = 0;
|
inst->size = 0;
|
||||||
/* TODO: Find out how many clocks this takes */
|
/* emu->cpu.clocks = ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input Byte */
|
/* Input Byte */
|
||||||
|
@ -1491,8 +1491,8 @@ static int cpuExecute(VB *emu) {
|
||||||
/* Post-instruction tasks */
|
/* Post-instruction tasks */
|
||||||
if (emu->cpu.causeCode == 0 && !emu->cpu.busWait) {
|
if (emu->cpu.causeCode == 0 && !emu->cpu.busWait) {
|
||||||
|
|
||||||
/* Advance to next instruction if not processing a bit string */
|
/* Advance to next instruction */
|
||||||
if (!emu->cpu.substring)
|
if (emu->cpu.state != CPU_HALTED && !emu->cpu.substring)
|
||||||
emu->cpu.pc += inst->size;
|
emu->cpu.pc += inst->size;
|
||||||
|
|
||||||
/* Check for interrupts */
|
/* Check for interrupts */
|
||||||
|
@ -1505,11 +1505,10 @@ static int cpuExecute(VB *emu) {
|
||||||
emu->cpu.substring = 0;
|
emu->cpu.substring = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to fetch mode if not halting and execution has completed */
|
/* Switch to fetch mode */
|
||||||
else if (emu->cpu.state != CPU_HALTED &&
|
else if (emu->cpu.state != CPU_HALTED &&
|
||||||
!emu->cpu.busWait && !emu->cpu.substring) {
|
!emu->cpu.busWait && !emu->cpu.substring) {
|
||||||
emu->cpu.state = CPU_FETCH;
|
emu->cpu.state = CPU_FETCH;
|
||||||
emu->cpu.fetch = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1518,6 +1517,7 @@ static int cpuExecute(VB *emu) {
|
||||||
/* Enter an exception state */
|
/* Enter an exception state */
|
||||||
static int cpuException(VB *emu) {
|
static int cpuException(VB *emu) {
|
||||||
uint16_t causeCode = emu->cpu.causeCode;
|
uint16_t causeCode = emu->cpu.causeCode;
|
||||||
|
int irq = causeCode < 0xFF00;
|
||||||
|
|
||||||
/* Fatal exception */
|
/* Fatal exception */
|
||||||
if (emu->cpu.psw.np) {
|
if (emu->cpu.psw.np) {
|
||||||
|
@ -1587,7 +1587,7 @@ static int cpuException(VB *emu) {
|
||||||
else {
|
else {
|
||||||
emu->cpu.ecr.eicc = causeCode;
|
emu->cpu.ecr.eicc = causeCode;
|
||||||
emu->cpu.eipsw = vbGetSystemRegister(emu, VB_PSW);
|
emu->cpu.eipsw = vbGetSystemRegister(emu, VB_PSW);
|
||||||
emu->cpu.eipc = emu->cpu.pc;
|
emu->cpu.eipc = emu->cpu.pc + (irq ? 2 : 0);
|
||||||
emu->cpu.eipcFrom = emu->cpu.pcFrom;
|
emu->cpu.eipcFrom = emu->cpu.pcFrom;
|
||||||
emu->cpu.eipcTo = emu->cpu.pcTo;
|
emu->cpu.eipcTo = emu->cpu.pcTo;
|
||||||
emu->cpu.psw.ep = 1;
|
emu->cpu.psw.ep = 1;
|
||||||
|
@ -1596,7 +1596,7 @@ static int cpuException(VB *emu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interrupt */
|
/* Interrupt */
|
||||||
if (causeCode < 0xFF00)
|
if (irq)
|
||||||
emu->cpu.psw.i += emu->cpu.psw.i == 15 ? 0 : 1;
|
emu->cpu.psw.i += emu->cpu.psw.i == 15 ? 0 : 1;
|
||||||
|
|
||||||
/* Update state */
|
/* Update state */
|
||||||
|
@ -1690,10 +1690,11 @@ static int cpuEmulate(VB *emu, uint32_t clocks) {
|
||||||
|
|
||||||
/* Processing by operations state */
|
/* Processing by operations state */
|
||||||
switch (emu->cpu.state) {
|
switch (emu->cpu.state) {
|
||||||
case CPU_FETCH : if (cpuFetch (emu)) return 1; break;
|
case CPU_EXCEPTION: if ( cpuException(emu)) return 1; break;
|
||||||
case CPU_EXECUTE : if (cpuExecute (emu)) return 1; break;
|
case CPU_EXECUTE : if ( cpuExecute (emu)) return 1; break;
|
||||||
case CPU_EXCEPTION: if (cpuException(emu)) return 1; break;
|
case CPU_FATAL : return 0; break;
|
||||||
case CPU_HALTED : if (cpuCheckIRQs(emu)) return 0; break;
|
case CPU_FETCH : if ( cpuFetch (emu)) return 1; break;
|
||||||
|
case CPU_HALTED : if (!cpuCheckIRQs(emu)) return 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (clocks > 0);
|
} while (clocks > 0);
|
||||||
|
@ -1702,6 +1703,45 @@ static int cpuEmulate(VB *emu, uint32_t clocks) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Simulate a hardware reset */
|
||||||
|
static void cpuReset(VB *emu) {
|
||||||
|
int x; /* Iterator */
|
||||||
|
|
||||||
|
/* Registers */
|
||||||
|
vbSetProgramCounter(emu, 0xFFFFFFF0);
|
||||||
|
vbSetSystemRegister(emu, VB_ECR, 0x0000FFF0);
|
||||||
|
vbSetSystemRegister(emu, VB_PSW, 0x00008000);
|
||||||
|
|
||||||
|
/* Cache */
|
||||||
|
vbSetSystemRegister(emu, VB_CHCW, 0x00000000);
|
||||||
|
|
||||||
|
/* Other state */
|
||||||
|
emu->cpu.busWait = 0;
|
||||||
|
emu->cpu.state = CPU_FETCH;
|
||||||
|
emu->cpu.substring = 0;
|
||||||
|
for (x = 0; x < 5; x++)
|
||||||
|
emu->cpu.irq[x] = 0;
|
||||||
|
|
||||||
|
/* Other registers (the hardware does not do this) */
|
||||||
|
for (x = 0; x < 32; x++)
|
||||||
|
emu->cpu.program[x] = 0x00000000;
|
||||||
|
emu->cpu.adtre = 0x00000000;
|
||||||
|
emu->cpu.eipc = 0x00000000;
|
||||||
|
emu->cpu.eipsw = 0x00000000;
|
||||||
|
emu->cpu.fepc = 0x00000000;
|
||||||
|
emu->cpu.fepsw = 0x00000000;
|
||||||
|
emu->cpu.sr29 = 0x00000000;
|
||||||
|
emu->cpu.sr31 = 0x00000000;
|
||||||
|
|
||||||
|
/* History tracking */
|
||||||
|
emu->cpu.eipcFrom = 0xFFFFFFF0;
|
||||||
|
emu->cpu.eipcTo = 0xFFFFFFF0;
|
||||||
|
emu->cpu.fepcFrom = 0xFFFFFFF0;
|
||||||
|
emu->cpu.fepcTo = 0xFFFFFFF0;
|
||||||
|
emu->cpu.pcFrom = 0xFFFFFFF0;
|
||||||
|
emu->cpu.pcTo = 0xFFFFFFF0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine the number of clocks before a break condititon could occur */
|
/* Determine the number of clocks before a break condititon could occur */
|
||||||
static uint32_t cpuUntil(VB *emu, uint32_t clocks) {
|
static uint32_t cpuUntil(VB *emu, uint32_t clocks) {
|
||||||
|
|
||||||
|
|
32
core/vb.c
32
core/vb.c
|
@ -197,36 +197,8 @@ int32_t vbRead(VB *emu, uint32_t address, int type, int debug) {
|
||||||
void vbReset(VB *emu) {
|
void vbReset(VB *emu) {
|
||||||
uint32_t x; /* Iterator */
|
uint32_t x; /* Iterator */
|
||||||
|
|
||||||
/* CPU registers */
|
/* Subsystem components */
|
||||||
vbSetProgramCounter(emu, 0xFFFFFFF0);
|
cpuReset(emu);
|
||||||
vbSetSystemRegister(emu, VB_ECR, 0x0000FFF0);
|
|
||||||
vbSetSystemRegister(emu, VB_PSW, 0x00008000);
|
|
||||||
|
|
||||||
/* Extra CPU registers (the hardware does not do this) */
|
|
||||||
for (x = 0; x < 32; x++)
|
|
||||||
emu->cpu.program[x] = 0x00000000;
|
|
||||||
emu->cpu.adtre = 0x00000000;
|
|
||||||
emu->cpu.eipc = 0x00000000;
|
|
||||||
emu->cpu.eipsw = 0x00000000;
|
|
||||||
emu->cpu.fepc = 0x00000000;
|
|
||||||
emu->cpu.fepsw = 0x00000000;
|
|
||||||
emu->cpu.sr29 = 0x00000000;
|
|
||||||
emu->cpu.sr31 = 0x00000000;
|
|
||||||
|
|
||||||
/* History tracking */
|
|
||||||
emu->cpu.eipcFrom = 0xFFFFFFF0;
|
|
||||||
emu->cpu.eipcTo = 0xFFFFFFF0;
|
|
||||||
emu->cpu.fepcFrom = 0xFFFFFFF0;
|
|
||||||
emu->cpu.fepcTo = 0xFFFFFFF0;
|
|
||||||
emu->cpu.pcFrom = 0xFFFFFFF0;
|
|
||||||
emu->cpu.pcTo = 0xFFFFFFF0;
|
|
||||||
|
|
||||||
/* Other CPU state */
|
|
||||||
emu->cpu.busWait = 0;
|
|
||||||
emu->cpu.state = CPU_FETCH;
|
|
||||||
emu->cpu.substring = 0;
|
|
||||||
for (x = 0; x < 5; x++)
|
|
||||||
emu->cpu.irq[x] = 0;
|
|
||||||
|
|
||||||
/* WRAM (the hardware does not do this) */
|
/* WRAM (the hardware does not do this) */
|
||||||
for (x = 0; x < 0x10000; x++)
|
for (x = 0; x < 0x10000; x++)
|
||||||
|
|
Loading…
Reference in New Issue