From e33f40e60c11fb5df530c33653a8e62653972333 Mon Sep 17 00:00:00 2001 From: David Banks Date: Sat, 22 Sep 2018 10:43:01 +0100 Subject: [PATCH] Z80: Corrected fetch state machine to cover all cases correctly --- chip-z80/support.js | 126 ++++++++++++++++++++-------------------- chip-z80/testprogram.js | 5 +- 2 files changed, 66 insertions(+), 65 deletions(-) diff --git a/chip-z80/support.js b/chip-z80/support.js index d93f7e0..398cf76 100644 --- a/chip-z80/support.js +++ b/chip-z80/support.js @@ -121,14 +121,11 @@ function handleBusRead(){ writeDataBus(d); } - // Prefic / Opcode parsing state machone + // Prefix / displacement / opcode state machine, deals with: // CB - // DD // ED - // FD - // DD CB - // FD CB - // + // [DD|FD]+ + // [DD|FD]+ CB // Only advance the state machine on the falling edge of read if (last_rd_done && !isNodeHigh(nodenames['_rd']) && !isNodeHigh(nodenames['_mreq'])) { @@ -136,53 +133,60 @@ function handleBusRead(){ case 0: // In state 0 we are ready to start a new instruction if(!isNodeHigh(nodenames['_m1'])) { + prefix = 0; + opcode = d; switch (d) { - case 0xdd: - case 0xfd: - prefix = d; - opcode = d; + case 0xcb: case 0xed: state = 1; break; - case 0xcb: - case 0xed: - prefix = d; - opcode = 0x100; + case 0xdd: case 0xfd: state = 2; 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; case 1: - // In state 1 we have just seen the 0xdd/0xfd prefix - if(!isNodeHigh(nodenames['_mreq'])) { - switch (d) { - case 0xdd: - case 0xfd: - prefix = d; - opcode = d; - break; - case 0xcb: - prefix = (prefix << 8) | d; - opcode = 0x100; - state = 2; - break; - default: - opcode = d; - state = 0; - break; - } + // In state 1 we have just seen the CB/ED prefix and expect the opcode + prefix = opcode; // The prefix(s) just seen + opcode = d; + state = 0; + break; + case 2: + // In state 2 we have just seen the DD/FD prefix + prefix = opcode; // the prefix just seen + opcode = d; + switch (d) { + case 0xdd: case 0xfd: + state = 2; // remain in state 1 + break; + case 0xcb: + state = 3; + break; + default: + state = 0; + 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: - // In state 2 the next read must be the opcode - if(!isNodeHigh(nodenames['_mreq'])) { - opcode = d; - state = 0; - } + // This should never be needd + prefix = 0; + opcode = -1; + state = 0; break; } } @@ -485,7 +489,7 @@ function busToString(busname){ // if(busname=='Execute') // return disassemblytoHTML(readBits('ir',8)); 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]=="-"){ // invert the value of the bus for display var value=busToHex(busname.slice(1)) @@ -541,7 +545,7 @@ function chipStatus(){ } // sanitised opcode for HTML output -function disassemblytoHTML(){ +function disassemblytoHTML(prefix, opcode){ var disassembly; switch (prefix) { @@ -778,7 +782,7 @@ var disassembly_00={ 0xC8: "RET Z", 0xC9: "RET", 0xCA: "JP Z,NNNN", - 0xCB: "PREFIX", + 0xCB: "CB PREFIX", 0xCC: "CALL Z,NNNN", 0xCD: "CALL NNNN", 0xCE: "ADC A,NN", @@ -797,7 +801,7 @@ var disassembly_00={ 0xDA: "JP C,NNNN", 0xDB: "IN A,(NN)", 0xDC: "CALL C,NNNN", - 0xDD: "PREFIX", + 0xDD: "DD PREFIX", 0xDE: "SBC A,NN", 0xDF: "RST 18h", @@ -814,7 +818,7 @@ var disassembly_00={ 0xEA: "JP PE,NNNN", 0xEB: "EX DE,HL", 0xEC: "CALL PE,NNNN", - 0xED: "PREFIX", + 0xED: "ED PREFIX", 0xEE: "XOR NN", 0xEF: "RST 28h", @@ -831,7 +835,7 @@ var disassembly_00={ 0xFA: "JP M,NNNN", 0xFB: "EI", 0xFC: "CALL M,NNNN", - 0xFD: "PREFIX", + 0xFD: "FD PREFIX", 0xFE: "CP NN", 0xFF: "RST 38h" }; @@ -1108,9 +1112,7 @@ var disassembly_ed={ 0xFC: "???", 0xFD: "???", 0xFE: "???", - 0xFF: "???", - - 0x100: "PREFIX" + 0xFF: "???" }; @@ -1386,9 +1388,7 @@ var disassembly_cb={ 0xFC: "SET 7,H", 0xFD: "SET 7,L", 0xFE: "SET 7,(HL)", - 0xFF: "SET 7,A", - - 0x100: "PREFIX" + 0xFF: "SET 7,A" }; @@ -1609,7 +1609,7 @@ var disassembly_dd={ 0xC8: "RET Z", 0xC9: "RET", 0xCA: "JP Z,NNNN", - 0xCB: "PREFIX", + 0xCB: "CB PREFIX", 0xCC: "CALL Z,NNNN", 0xCD: "CALL NNNN", 0xCE: "ADC A,NN", @@ -1628,7 +1628,7 @@ var disassembly_dd={ 0xDA: "JP C,NNNN", 0xDB: "IN A,(NN)", 0xDC: "CALL C,NNNN", - 0xDD: "PREFIX", + 0xDD: "DD PREFIX", 0xDE: "SBC A,NN", 0xDF: "RST 18h", @@ -1645,7 +1645,7 @@ var disassembly_dd={ 0xEA: "JP PE,NNNN", 0xEB: "EX DE,HL", 0xEC: "CALL PE,NNNN", - 0xED: "PREFIX", + 0xED: "ED PREFIX", 0xEE: "XOR NN", 0xEF: "RST 28h", @@ -1662,7 +1662,7 @@ var disassembly_dd={ 0xFA: "JP M,NNNN", 0xFB: "EI", 0xFC: "CALL M,NNNN", - 0xFD: "PREFIX", + 0xFD: "FD PREFIX", 0xFE: "CP NN", 0xFF: "RST 38h" }; @@ -1884,7 +1884,7 @@ var disassembly_fd={ 0xC8: "RET Z", 0xC9: "RET", 0xCA: "JP Z,NNNN", - 0xCB: "PREFIX", + 0xCB: "CB PREFIX", 0xCC: "CALL Z,NNNN", 0xCD: "CALL NNNN", 0xCE: "ADC A,NN", @@ -1903,7 +1903,7 @@ var disassembly_fd={ 0xDA: "JP C,NNNN", 0xDB: "IN A,(NN)", 0xDC: "CALL C,NNNN", - 0xDD: "PREFIX", + 0xDD: "DD PREFIX", 0xDE: "SBC A,NN", 0xDF: "RST 18h", @@ -1920,7 +1920,7 @@ var disassembly_fd={ 0xEA: "JP PE,NNNN", 0xEB: "EX DE,HL", 0xEC: "CALL PE,NNNN", - 0xED: "PREFIX", + 0xED: "ED PREFIX", 0xEE: "XOR NN", 0xEF: "RST 28h", @@ -1937,7 +1937,7 @@ var disassembly_fd={ 0xFA: "JP M,NNNN", 0xFB: "EI", 0xFC: "CALL M,NNNN", - 0xFD: "PREFIX", + 0xFD: "FD PREFIX", 0xFE: "CP NN", 0xFF: "RST 38h" }; @@ -2216,7 +2216,7 @@ var disassembly_ddcb={ 0xFE: "SET 7,(IX+d)", 0xFF: "SET 7,(IX+d),A", - 0x100: "PREFIX" + 0x100: "DISPLACEMENT" }; var disassembly_fdcb={ @@ -2493,5 +2493,5 @@ var disassembly_fdcb={ 0xFE: "SET 7,(IY+d)", 0xFF: "SET 7,(IY+d),A", - 0x100: "PREFIX" + 0x100: "DISPLACEMENT" }; diff --git a/chip-z80/testprogram.js b/chip-z80/testprogram.js index c146d82..2afb726 100644 --- a/chip-z80/testprogram.js +++ b/chip-z80/testprogram.js @@ -19,9 +19,9 @@ testprogram = [ 0x31, 0x00, 0x01, // LD SP,0x0100 0xCD, 0x0B, 0x00, // CALL $000B 0x00, // NOP - 0x21, 0x34, 0x12, // LD HL,$1234 0x21, 0x78, 0x56, // LD HL,$5678 - 0xe5, // PUSH HL + 0x21, 0x34, 0x12, // LD HL,$1234 + // 0xe5, // PUSH HL 0x00, // NOP 0x00, // NOP 0x3C, // INC A @@ -61,6 +61,7 @@ testprogram = [ 0x7E, // LD A, (HL) 0x00, // NOP 0x21, 0x34, 0x12, // LD HL,$1234 + 0xe5, // PUSH HL 0x21, 0x78, 0x56, // LD HL,$5678 0xe3, // EX (SP),HL 0xdd, 0x21, 0xbc,0x9a, // LD IX, 0x9ABC