cpu/decoder - Implement PREFIX (bit shift & bit ops)
This commit is contained in:
parent
cf54c7ec5f
commit
50cac936b9
1 changed files with 98 additions and 0 deletions
|
@ -181,6 +181,104 @@ void Cpu::executeInstruction()
|
|||
u16 rst_addr = op & 0x38;
|
||||
doCall(rst_addr);
|
||||
}
|
||||
else if(op == 0xCB) // PREFIX
|
||||
{
|
||||
currentpc = state.PC;
|
||||
opcode_t prefix_op = readPC8();
|
||||
|
||||
#if 0
|
||||
printf("@0x%04x: CB opcode %02X\n", currentpc, prefix_op);
|
||||
#endif
|
||||
|
||||
u8 reg = prefix_op & 0x7;
|
||||
|
||||
u8 data;
|
||||
switch(reg)
|
||||
{
|
||||
case 0x6: data = bus->read8(state.HL); mcycles = 3; break;
|
||||
default: data = state.reg8(reg); mcycles = 2; break;
|
||||
}
|
||||
|
||||
// For BIT, RES, SET
|
||||
u8 bit = (prefix_op >> 3) & 0x7;
|
||||
|
||||
switch(prefix_op & 0xC0)
|
||||
{
|
||||
case 0x00:
|
||||
switch(prefix_op & 0xF1)
|
||||
{
|
||||
case 0x00: // RLC
|
||||
{
|
||||
bool msb_set = (data & 0x80);
|
||||
data = (data << 1) | (msb_set ? 0x1 : 0x0);
|
||||
state.carry = msb_set;
|
||||
}
|
||||
break;
|
||||
case 0x08: // RRC
|
||||
{
|
||||
bool lsb_set = (data & 0x01);
|
||||
data = (data >> 1) | (lsb_set ? 0x80 : 0x00);
|
||||
state.carry = lsb_set;
|
||||
}
|
||||
break;
|
||||
case 0x10: // RL
|
||||
{
|
||||
bool msb_set = (data & 0x80);
|
||||
data = (data << 1) | (state.carry ? 0x1 : 0x0);
|
||||
state.carry = msb_set;
|
||||
}
|
||||
break;
|
||||
case 0x18: // RR
|
||||
{
|
||||
bool lsb_set = (data & 0x01) != 0;
|
||||
data = (data >> 1) | (state.carry ? 0x80 : 0x00);
|
||||
state.carry = lsb_set;
|
||||
}
|
||||
break;
|
||||
case 0x20: // SLA
|
||||
state.carry = (data & 0x80);
|
||||
data = (data << 1);
|
||||
break;
|
||||
case 0x28: // SRA
|
||||
state.carry = (data & 0x01);
|
||||
data = (data >> 1) | (data & 0x80);
|
||||
break;
|
||||
case 0x30: // SWAP
|
||||
data = ((data >> 4) & 0x0F) | ((data << 4) & 0xF0);
|
||||
break;
|
||||
case 0x38: // SRL
|
||||
state.carry = (data & 0x01);
|
||||
data = (data >> 1);
|
||||
break;
|
||||
}
|
||||
state.halfcarry = false;
|
||||
state.subtract = false;
|
||||
state.zero = (data == 0);
|
||||
break;
|
||||
case 0x40: // BIT
|
||||
{
|
||||
state.zero = (data & (1 << bit)) == 0;
|
||||
state.subtract = false;
|
||||
state.halfcarry = true;
|
||||
}
|
||||
break;
|
||||
case 0x80: // RES
|
||||
data &= ~(1 << bit);
|
||||
break;
|
||||
case 0xC0: // SET
|
||||
data |= (1 << bit);
|
||||
break;
|
||||
}
|
||||
// All ops except for BIT write the data back to where it came from
|
||||
if ((prefix_op & 0xC0) != 0x40)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 0x6: bus->write8(state.HL, data); mcycles = 4; break;
|
||||
default: state.reg8(reg) = data; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(op)
|
||||
|
|
Loading…
Reference in a new issue