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
 | 
			
		||||
    setROM(msg) {
 | 
			
		||||
        let dbg = this.debuggers[msg.sim];
 | 
			
		||||
        dbg.refresh();
 | 
			
		||||
        dbg.refresh(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,8 +46,8 @@ globalThis.Debugger = class Debugger {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Reload all output
 | 
			
		||||
    refresh() {
 | 
			
		||||
        this.cpu   .refresh();
 | 
			
		||||
    refresh(seekToPC) {
 | 
			
		||||
        this.cpu   .refresh(seekToPC);
 | 
			
		||||
        this.memory.refresh();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -234,7 +234,7 @@
 | 
			
		|||
            case "ReadBuffer"  : this.readBuffer  (msg); break;
 | 
			
		||||
            case "SetRegister" : this.setRegister (msg); break;
 | 
			
		||||
            case "RunNext": case "SingleStep":
 | 
			
		||||
                this.refresh(true); break;
 | 
			
		||||
                this.debug.refresh(true); break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -345,7 +345,9 @@
 | 
			
		|||
        let reg2 = this.PROREGNAMES[bits >> 21 & 31];
 | 
			
		||||
        let reg1 = this.PROREGNAMES[bits >> 16 & 31];
 | 
			
		||||
        let disp = this.signExtend(bits & 0xFFFF, 16);
 | 
			
		||||
        disp = disp == 0 ? "" : (disp < 0 ? "-" : "") + "0x" +
 | 
			
		||||
        disp = disp == 0 ? "" : (disp < -255 || disp > 255) ? "0x" +
 | 
			
		||||
            ("000" + (disp & 0xFFFF).toString(16).toUpperCase()).slice(-4) :
 | 
			
		||||
            (disp < 0 ? "-" : "") + "0x" +
 | 
			
		||||
                Math.abs(disp).toString(16).toUpperCase();
 | 
			
		||||
        switch (inst.opcode) {
 | 
			
		||||
            case 0b110000: // LD.B
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
 | 
			
		|||
    message(msg) {
 | 
			
		||||
        switch (msg.command) {
 | 
			
		||||
            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
 | 
			
		||||
        this.element.setAttribute("role", "row");
 | 
			
		||||
        this.element.addEventListener("pointerdown", e=>this.onpointerdown(e));
 | 
			
		||||
 | 
			
		||||
        // Address label
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
| 
						 | 
				
			
			@ -435,7 +461,6 @@ MemoryWindow.Cell = class Cell extends Toolkit.Label {
 | 
			
		|||
        // Configure element
 | 
			
		||||
        this.element.setAttribute("role", "gridcell");
 | 
			
		||||
        this.element.setAttribute("name", "byte");
 | 
			
		||||
        this.element.addEventListener("pointerdown", e=>this.onpointerdown(e));
 | 
			
		||||
 | 
			
		||||
        parent.add(this);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -473,10 +498,4 @@ MemoryWindow.Cell = class Cell extends Toolkit.Label {
 | 
			
		|||
        return (this.wnd.address + this.offset & 0xFFFFFFFF) >>> 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Pointer down event handler
 | 
			
		||||
    onpointerdown(e) {
 | 
			
		||||
        if (e.button == 0)
 | 
			
		||||
            this.wnd.setSelected(this.address());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										60
									
								
								core/cpu.c
								
								
								
								
							
							
						
						
									
										60
									
								
								core/cpu.c
								
								
								
								
							| 
						 | 
				
			
			@ -979,7 +979,7 @@ static void cpuDIVU(VB *emu, VB_INSTRUCTION *inst) {
 | 
			
		|||
static void cpuHALT(VB *emu, VB_INSTRUCTION *inst) {
 | 
			
		||||
    emu->cpu.state = CPU_HALTED;
 | 
			
		||||
    inst->size     = 0;
 | 
			
		||||
    /* TODO: Find out how many clocks this takes */
 | 
			
		||||
    /* emu->cpu.clocks = ? */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Input Byte */
 | 
			
		||||
| 
						 | 
				
			
			@ -1491,8 +1491,8 @@ static int cpuExecute(VB *emu) {
 | 
			
		|||
    /* Post-instruction tasks */
 | 
			
		||||
    if (emu->cpu.causeCode == 0 && !emu->cpu.busWait) {
 | 
			
		||||
 | 
			
		||||
        /* Advance to next instruction if not processing a bit string */
 | 
			
		||||
        if (!emu->cpu.substring)
 | 
			
		||||
        /* Advance to next instruction */
 | 
			
		||||
        if (emu->cpu.state != CPU_HALTED && !emu->cpu.substring)
 | 
			
		||||
            emu->cpu.pc += inst->size;
 | 
			
		||||
 | 
			
		||||
        /* Check for interrupts */
 | 
			
		||||
| 
						 | 
				
			
			@ -1505,11 +1505,10 @@ static int cpuExecute(VB *emu) {
 | 
			
		|||
        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 &&
 | 
			
		||||
        !emu->cpu.busWait && !emu->cpu.substring) {
 | 
			
		||||
        emu->cpu.state = CPU_FETCH;
 | 
			
		||||
        emu->cpu.fetch = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1518,6 +1517,7 @@ static int cpuExecute(VB *emu) {
 | 
			
		|||
/* Enter an exception state */
 | 
			
		||||
static int cpuException(VB *emu) {
 | 
			
		||||
    uint16_t causeCode = emu->cpu.causeCode;
 | 
			
		||||
    int      irq       = causeCode < 0xFF00;
 | 
			
		||||
 | 
			
		||||
    /* Fatal exception */
 | 
			
		||||
    if (emu->cpu.psw.np) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1587,7 +1587,7 @@ static int cpuException(VB *emu) {
 | 
			
		|||
    else {
 | 
			
		||||
        emu->cpu.ecr.eicc = causeCode;
 | 
			
		||||
        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.eipcTo   = emu->cpu.pcTo;
 | 
			
		||||
        emu->cpu.psw.ep   = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1596,7 +1596,7 @@ static int cpuException(VB *emu) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* Interrupt */
 | 
			
		||||
    if (causeCode < 0xFF00)
 | 
			
		||||
    if (irq)
 | 
			
		||||
        emu->cpu.psw.i += emu->cpu.psw.i == 15 ? 0 : 1;
 | 
			
		||||
 | 
			
		||||
    /* Update state */
 | 
			
		||||
| 
						 | 
				
			
			@ -1690,10 +1690,11 @@ static int cpuEmulate(VB *emu, uint32_t clocks) {
 | 
			
		|||
 | 
			
		||||
        /* Processing by operations state */
 | 
			
		||||
        switch (emu->cpu.state) {
 | 
			
		||||
            case CPU_FETCH    : if (cpuFetch    (emu)) return 1; break;
 | 
			
		||||
            case CPU_EXECUTE  : if (cpuExecute  (emu)) return 1; break;
 | 
			
		||||
            case CPU_EXCEPTION: if ( cpuException(emu)) return 1; break;
 | 
			
		||||
            case CPU_HALTED   : if (cpuCheckIRQs(emu)) return 0; break;
 | 
			
		||||
            case CPU_EXECUTE  : if ( cpuExecute  (emu)) return 1; break;
 | 
			
		||||
            case CPU_FATAL    :                         return 0; break;
 | 
			
		||||
            case CPU_FETCH    : if ( cpuFetch    (emu)) return 1; break;
 | 
			
		||||
            case CPU_HALTED   : if (!cpuCheckIRQs(emu)) return 0; break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } while (clocks > 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1702,6 +1703,45 @@ static int cpuEmulate(VB *emu, uint32_t clocks) {
 | 
			
		|||
    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 */
 | 
			
		||||
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) {
 | 
			
		||||
    uint32_t x; /* Iterator */
 | 
			
		||||
 | 
			
		||||
    /* CPU registers */
 | 
			
		||||
    vbSetProgramCounter(emu,         0xFFFFFFF0);
 | 
			
		||||
    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;
 | 
			
		||||
    /* Subsystem components */
 | 
			
		||||
    cpuReset(emu);
 | 
			
		||||
 | 
			
		||||
    /* WRAM (the hardware does not do this) */
 | 
			
		||||
    for (x = 0; x < 0x10000; x++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue