mirror of
https://github.com/trebonian/visual6502.git
synced 2024-09-26 23:54:32 +00:00
Z80: Corrected fetch state machine to cover all cases correctly
This commit is contained in:
parent
379d2d1ea1
commit
e33f40e60c
@ -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'])) {
|
||||||
switch (d) {
|
|
||||||
case 0xdd:
|
|
||||||
case 0xfd:
|
|
||||||
prefix = d;
|
|
||||||
opcode = d;
|
|
||||||
state = 1;
|
|
||||||
break;
|
|
||||||
case 0xcb:
|
|
||||||
case 0xed:
|
|
||||||
prefix = d;
|
|
||||||
opcode = 0x100;
|
|
||||||
state = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
prefix = 0;
|
prefix = 0;
|
||||||
opcode = d;
|
opcode = d;
|
||||||
|
switch (d) {
|
||||||
|
case 0xcb: case 0xed:
|
||||||
|
state = 1;
|
||||||
|
break;
|
||||||
|
case 0xdd: case 0xfd:
|
||||||
|
state = 2;
|
||||||
break;
|
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) {
|
|
||||||
case 0xdd:
|
|
||||||
case 0xfd:
|
|
||||||
prefix = d;
|
|
||||||
opcode = d;
|
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;
|
break;
|
||||||
case 0xcb:
|
case 0xcb:
|
||||||
prefix = (prefix << 8) | d;
|
state = 3;
|
||||||
opcode = 0x100;
|
|
||||||
state = 2;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
opcode = d;
|
|
||||||
state = 0;
|
state = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
case 3:
|
||||||
// In state 2 the next read must be the opcode
|
// In state 3 we expect the displacement byte
|
||||||
if(!isNodeHigh(nodenames['_mreq'])) {
|
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;
|
opcode = d;
|
||||||
state = 0;
|
state = 0;
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
|
// This should never be needd
|
||||||
|
prefix = 0;
|
||||||
|
opcode = -1;
|
||||||
|
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"
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user