Z80: Corrected fetch state machine to cover all cases correctly

This commit is contained in:
David Banks 2018-09-22 10:43:01 +01:00
parent 379d2d1ea1
commit e33f40e60c
2 changed files with 66 additions and 65 deletions

View File

@ -121,14 +121,11 @@ function handleBusRead(){
writeDataBus(d); writeDataBus(d);
} }
// Prefic / Opcode parsing state machone // Prefix / displacement / opcode state machine, deals with:
// CB <op> // CB <op>
// DD <op>
// ED <op> // ED <op>
// FD <op> // [DD|FD]+ <op>
// DD CB <op> // [DD|FD]+ CB <displacement> <op>
// FD CB <op>
//
// Only advance the state machine on the falling edge of read // Only advance the state machine on the falling edge of read
if (last_rd_done && !isNodeHigh(nodenames['_rd']) && !isNodeHigh(nodenames['_mreq'])) { if (last_rd_done && !isNodeHigh(nodenames['_rd']) && !isNodeHigh(nodenames['_mreq'])) {
@ -136,53 +133,60 @@ function handleBusRead(){
case 0: case 0:
// In state 0 we are ready to start a new instruction // In state 0 we are ready to start a new instruction
if(!isNodeHigh(nodenames['_m1'])) { if(!isNodeHigh(nodenames['_m1'])) {
prefix = 0;
opcode = d;
switch (d) { switch (d) {
case 0xdd: case 0xcb: case 0xed:
case 0xfd:
prefix = d;
opcode = d;
state = 1; state = 1;
break; break;
case 0xcb: case 0xdd: case 0xfd:
case 0xed:
prefix = d;
opcode = 0x100;
state = 2; state = 2;
break; break;
default:
prefix = 0;
opcode = d;
break;
} }
} else {
// This case covers other reads in the instruction
prefix = 0;
opcode = -1; // If opcode < 0, then no fetch will be displayed
} }
break; break;
case 1: case 1:
// In state 1 we have just seen the 0xdd/0xfd prefix // In state 1 we have just seen the CB/ED prefix and expect the opcode
if(!isNodeHigh(nodenames['_mreq'])) { prefix = opcode; // The prefix(s) just seen
switch (d) { opcode = d;
case 0xdd: state = 0;
case 0xfd: break;
prefix = d; case 2:
opcode = d; // In state 2 we have just seen the DD/FD prefix
break; prefix = opcode; // the prefix just seen
case 0xcb: opcode = d;
prefix = (prefix << 8) | d; switch (d) {
opcode = 0x100; case 0xdd: case 0xfd:
state = 2; state = 2; // remain in state 1
break; break;
default: case 0xcb:
opcode = d; state = 3;
state = 0; break;
break; default:
} state = 0;
break;
} }
break; break;
case 3:
// In state 3 we expect the displacement byte
prefix = (prefix << 8) | opcode; // The prefix(s) just seen
opcode = 0x100; // Trick the disassembler into marking fetch as DISP
state = 4;
break;
case 4:
// In state 4 we expect the opcode
opcode = d;
state = 0;
break;
default: default:
// In state 2 the next read must be the opcode // This should never be needd
if(!isNodeHigh(nodenames['_mreq'])) { prefix = 0;
opcode = d; opcode = -1;
state = 0; state = 0;
}
break; break;
} }
} }
@ -485,7 +489,7 @@ function busToString(busname){
// if(busname=='Execute') // if(busname=='Execute')
// return disassemblytoHTML(readBits('ir',8)); // return disassemblytoHTML(readBits('ir',8));
if(busname=='Fetch') if(busname=='Fetch')
return (!isNodeHigh(nodenames['_m1']) && !isNodeHigh(nodenames['_mreq']) && !isNodeHigh(nodenames['_rd']))?disassemblytoHTML():""; return (!isNodeHigh(nodenames['_mreq']) && !isNodeHigh(nodenames['_rd']) && (opcode >= 0))?disassemblytoHTML(prefix,opcode):"";
if(busname[0]=="-"){ if(busname[0]=="-"){
// invert the value of the bus for display // invert the value of the bus for display
var value=busToHex(busname.slice(1)) var value=busToHex(busname.slice(1))
@ -541,7 +545,7 @@ function chipStatus(){
} }
// sanitised opcode for HTML output // sanitised opcode for HTML output
function disassemblytoHTML(){ function disassemblytoHTML(prefix, opcode){
var disassembly; var disassembly;
switch (prefix) { switch (prefix) {
@ -778,7 +782,7 @@ var disassembly_00={
0xC8: "RET Z", 0xC8: "RET Z",
0xC9: "RET", 0xC9: "RET",
0xCA: "JP Z,NNNN", 0xCA: "JP Z,NNNN",
0xCB: "PREFIX", 0xCB: "CB PREFIX",
0xCC: "CALL Z,NNNN", 0xCC: "CALL Z,NNNN",
0xCD: "CALL NNNN", 0xCD: "CALL NNNN",
0xCE: "ADC A,NN", 0xCE: "ADC A,NN",
@ -797,7 +801,7 @@ var disassembly_00={
0xDA: "JP C,NNNN", 0xDA: "JP C,NNNN",
0xDB: "IN A,(NN)", 0xDB: "IN A,(NN)",
0xDC: "CALL C,NNNN", 0xDC: "CALL C,NNNN",
0xDD: "PREFIX", 0xDD: "DD PREFIX",
0xDE: "SBC A,NN", 0xDE: "SBC A,NN",
0xDF: "RST 18h", 0xDF: "RST 18h",
@ -814,7 +818,7 @@ var disassembly_00={
0xEA: "JP PE,NNNN", 0xEA: "JP PE,NNNN",
0xEB: "EX DE,HL", 0xEB: "EX DE,HL",
0xEC: "CALL PE,NNNN", 0xEC: "CALL PE,NNNN",
0xED: "PREFIX", 0xED: "ED PREFIX",
0xEE: "XOR NN", 0xEE: "XOR NN",
0xEF: "RST 28h", 0xEF: "RST 28h",
@ -831,7 +835,7 @@ var disassembly_00={
0xFA: "JP M,NNNN", 0xFA: "JP M,NNNN",
0xFB: "EI", 0xFB: "EI",
0xFC: "CALL M,NNNN", 0xFC: "CALL M,NNNN",
0xFD: "PREFIX", 0xFD: "FD PREFIX",
0xFE: "CP NN", 0xFE: "CP NN",
0xFF: "RST 38h" 0xFF: "RST 38h"
}; };
@ -1108,9 +1112,7 @@ var disassembly_ed={
0xFC: "???", 0xFC: "???",
0xFD: "???", 0xFD: "???",
0xFE: "???", 0xFE: "???",
0xFF: "???", 0xFF: "???"
0x100: "PREFIX"
}; };
@ -1386,9 +1388,7 @@ var disassembly_cb={
0xFC: "SET 7,H", 0xFC: "SET 7,H",
0xFD: "SET 7,L", 0xFD: "SET 7,L",
0xFE: "SET 7,(HL)", 0xFE: "SET 7,(HL)",
0xFF: "SET 7,A", 0xFF: "SET 7,A"
0x100: "PREFIX"
}; };
@ -1609,7 +1609,7 @@ var disassembly_dd={
0xC8: "RET Z", 0xC8: "RET Z",
0xC9: "RET", 0xC9: "RET",
0xCA: "JP Z,NNNN", 0xCA: "JP Z,NNNN",
0xCB: "PREFIX", 0xCB: "CB PREFIX",
0xCC: "CALL Z,NNNN", 0xCC: "CALL Z,NNNN",
0xCD: "CALL NNNN", 0xCD: "CALL NNNN",
0xCE: "ADC A,NN", 0xCE: "ADC A,NN",
@ -1628,7 +1628,7 @@ var disassembly_dd={
0xDA: "JP C,NNNN", 0xDA: "JP C,NNNN",
0xDB: "IN A,(NN)", 0xDB: "IN A,(NN)",
0xDC: "CALL C,NNNN", 0xDC: "CALL C,NNNN",
0xDD: "PREFIX", 0xDD: "DD PREFIX",
0xDE: "SBC A,NN", 0xDE: "SBC A,NN",
0xDF: "RST 18h", 0xDF: "RST 18h",
@ -1645,7 +1645,7 @@ var disassembly_dd={
0xEA: "JP PE,NNNN", 0xEA: "JP PE,NNNN",
0xEB: "EX DE,HL", 0xEB: "EX DE,HL",
0xEC: "CALL PE,NNNN", 0xEC: "CALL PE,NNNN",
0xED: "PREFIX", 0xED: "ED PREFIX",
0xEE: "XOR NN", 0xEE: "XOR NN",
0xEF: "RST 28h", 0xEF: "RST 28h",
@ -1662,7 +1662,7 @@ var disassembly_dd={
0xFA: "JP M,NNNN", 0xFA: "JP M,NNNN",
0xFB: "EI", 0xFB: "EI",
0xFC: "CALL M,NNNN", 0xFC: "CALL M,NNNN",
0xFD: "PREFIX", 0xFD: "FD PREFIX",
0xFE: "CP NN", 0xFE: "CP NN",
0xFF: "RST 38h" 0xFF: "RST 38h"
}; };
@ -1884,7 +1884,7 @@ var disassembly_fd={
0xC8: "RET Z", 0xC8: "RET Z",
0xC9: "RET", 0xC9: "RET",
0xCA: "JP Z,NNNN", 0xCA: "JP Z,NNNN",
0xCB: "PREFIX", 0xCB: "CB PREFIX",
0xCC: "CALL Z,NNNN", 0xCC: "CALL Z,NNNN",
0xCD: "CALL NNNN", 0xCD: "CALL NNNN",
0xCE: "ADC A,NN", 0xCE: "ADC A,NN",
@ -1903,7 +1903,7 @@ var disassembly_fd={
0xDA: "JP C,NNNN", 0xDA: "JP C,NNNN",
0xDB: "IN A,(NN)", 0xDB: "IN A,(NN)",
0xDC: "CALL C,NNNN", 0xDC: "CALL C,NNNN",
0xDD: "PREFIX", 0xDD: "DD PREFIX",
0xDE: "SBC A,NN", 0xDE: "SBC A,NN",
0xDF: "RST 18h", 0xDF: "RST 18h",
@ -1920,7 +1920,7 @@ var disassembly_fd={
0xEA: "JP PE,NNNN", 0xEA: "JP PE,NNNN",
0xEB: "EX DE,HL", 0xEB: "EX DE,HL",
0xEC: "CALL PE,NNNN", 0xEC: "CALL PE,NNNN",
0xED: "PREFIX", 0xED: "ED PREFIX",
0xEE: "XOR NN", 0xEE: "XOR NN",
0xEF: "RST 28h", 0xEF: "RST 28h",
@ -1937,7 +1937,7 @@ var disassembly_fd={
0xFA: "JP M,NNNN", 0xFA: "JP M,NNNN",
0xFB: "EI", 0xFB: "EI",
0xFC: "CALL M,NNNN", 0xFC: "CALL M,NNNN",
0xFD: "PREFIX", 0xFD: "FD PREFIX",
0xFE: "CP NN", 0xFE: "CP NN",
0xFF: "RST 38h" 0xFF: "RST 38h"
}; };
@ -2216,7 +2216,7 @@ var disassembly_ddcb={
0xFE: "SET 7,(IX+d)", 0xFE: "SET 7,(IX+d)",
0xFF: "SET 7,(IX+d),A", 0xFF: "SET 7,(IX+d),A",
0x100: "PREFIX" 0x100: "DISPLACEMENT"
}; };
var disassembly_fdcb={ var disassembly_fdcb={
@ -2493,5 +2493,5 @@ var disassembly_fdcb={
0xFE: "SET 7,(IY+d)", 0xFE: "SET 7,(IY+d)",
0xFF: "SET 7,(IY+d),A", 0xFF: "SET 7,(IY+d),A",
0x100: "PREFIX" 0x100: "DISPLACEMENT"
}; };

View File

@ -19,9 +19,9 @@ testprogram = [
0x31, 0x00, 0x01, // LD SP,0x0100 0x31, 0x00, 0x01, // LD SP,0x0100
0xCD, 0x0B, 0x00, // CALL $000B 0xCD, 0x0B, 0x00, // CALL $000B
0x00, // NOP 0x00, // NOP
0x21, 0x34, 0x12, // LD HL,$1234
0x21, 0x78, 0x56, // LD HL,$5678 0x21, 0x78, 0x56, // LD HL,$5678
0xe5, // PUSH HL 0x21, 0x34, 0x12, // LD HL,$1234
// 0xe5, // PUSH HL
0x00, // NOP 0x00, // NOP
0x00, // NOP 0x00, // NOP
0x3C, // INC A 0x3C, // INC A
@ -61,6 +61,7 @@ testprogram = [
0x7E, // LD A, (HL) 0x7E, // LD A, (HL)
0x00, // NOP 0x00, // NOP
0x21, 0x34, 0x12, // LD HL,$1234 0x21, 0x34, 0x12, // LD HL,$1234
0xe5, // PUSH HL
0x21, 0x78, 0x56, // LD HL,$5678 0x21, 0x78, 0x56, // LD HL,$5678
0xe3, // EX (SP),HL 0xe3, // EX (SP),HL
0xdd, 0x21, 0xbc,0x9a, // LD IX, 0x9ABC 0xdd, 0x21, 0xbc,0x9a, // LD IX, 0x9ABC