1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-13 22:32:03 +00:00

Genericises RegisterPair.

This commit is contained in:
Thomas Harte 2019-03-09 21:16:11 -05:00
parent b9b52b7c8b
commit 4aeb9a7c56
7 changed files with 186 additions and 176 deletions

View File

@ -28,7 +28,7 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
// These plus program below act to give the compiler permission to update these values
// without touching the class storage (i.e. it explicitly says they need be completely up
// to date in this stack frame only); which saves some complicated addressing
RegisterPair nextAddress = next_address_;
RegisterPair16 nextAddress = next_address_;
BusOperation nextBusOperation = next_bus_operation_;
uint16_t busAddress = bus_address_;
uint8_t *busValue = bus_value_;
@ -147,8 +147,8 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
}
case CycleIncPCPushPCH: pc_.full++; // deliberate fallthrough
case CyclePushPCH: push(pc_.bytes.high); break;
case CyclePushPCL: push(pc_.bytes.low); break;
case CyclePushPCH: push(pc_.halves.high); break;
case CyclePushPCL: push(pc_.halves.low); break;
case CyclePushOperand: push(operand_); break;
case CyclePushA: push(a_); break;
case CyclePushX: push(x_); break;
@ -175,8 +175,8 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
continue;
case OperationNMIPickVector: nextAddress.full = 0xfffa; continue;
case OperationRSTPickVector: nextAddress.full = 0xfffc; continue;
case CycleReadVectorLow: read_mem(pc_.bytes.low, nextAddress.full); break;
case CycleReadVectorHigh: read_mem(pc_.bytes.high, nextAddress.full+1); break;
case CycleReadVectorLow: read_mem(pc_.halves.low, nextAddress.full); break;
case CycleReadVectorHigh: read_mem(pc_.halves.high, nextAddress.full+1); break;
case OperationSetIRQFlags:
inverse_interrupt_flag_ = 0;
if(is_65c02(personality)) decimal_flag_ = false;
@ -185,8 +185,8 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
if(is_65c02(personality)) decimal_flag_ = false;
continue;
case CyclePullPCL: s_++; read_mem(pc_.bytes.low, s_ | 0x100); break;
case CyclePullPCH: s_++; read_mem(pc_.bytes.high, s_ | 0x100); break;
case CyclePullPCL: s_++; read_mem(pc_.halves.low, s_ | 0x100); break;
case CyclePullPCH: s_++; read_mem(pc_.halves.high, s_ | 0x100); break;
case CyclePullA: s_++; read_mem(a_, s_ | 0x100); break;
case CyclePullX: s_++; read_mem(x_, s_ | 0x100); break;
case CyclePullY: s_++; read_mem(y_, s_ | 0x100); break;
@ -198,11 +198,11 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
case OperationSetFlagsFromX: zero_result_ = negative_result_ = x_; continue;
case OperationSetFlagsFromY: zero_result_ = negative_result_ = y_; continue;
case CycleIncrementPCAndReadStack: pc_.full++; throwaway_read(s_ | 0x100); break;
case CycleReadPCLFromAddress: read_mem(pc_.bytes.low, address_.full); break;
case CycleReadPCHFromAddressLowInc: address_.bytes.low++; read_mem(pc_.bytes.high, address_.full); break;
case CycleReadPCHFromAddressFixed: if(!address_.bytes.low) address_.bytes.high++; read_mem(pc_.bytes.high, address_.full); break;
case CycleReadPCHFromAddressInc: address_.full++; read_mem(pc_.bytes.high, address_.full); break;
case CycleIncrementPCAndReadStack: pc_.full++; throwaway_read(s_ | 0x100); break;
case CycleReadPCLFromAddress: read_mem(pc_.halves.low, address_.full); break;
case CycleReadPCHFromAddressLowInc: address_.halves.low++; read_mem(pc_.halves.high, address_.full); break;
case CycleReadPCHFromAddressFixed: if(!address_.halves.low) address_.halves.high++; read_mem(pc_.halves.high, address_.full); break;
case CycleReadPCHFromAddressInc: address_.full++; read_mem(pc_.halves.high, address_.full); break;
case CycleReadAndIncrementPC: {
uint16_t oldPC = pc_.full;
@ -244,10 +244,10 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
case OperationSTY: operand_ = y_; continue;
case OperationSTZ: operand_ = 0; continue;
case OperationSAX: operand_ = a_ & x_; continue;
case OperationSHA: operand_ = a_ & x_ & (address_.bytes.high+1); continue;
case OperationSHX: operand_ = x_ & (address_.bytes.high+1); continue;
case OperationSHY: operand_ = y_ & (address_.bytes.high+1); continue;
case OperationSHS: s_ = a_ & x_; operand_ = s_ & (address_.bytes.high+1); continue;
case OperationSHA: operand_ = a_ & x_ & (address_.halves.high+1); continue;
case OperationSHX: operand_ = x_ & (address_.halves.high+1); continue;
case OperationSHY: operand_ = y_ & (address_.halves.high+1); continue;
case OperationSHS: s_ = a_ & x_; operand_ = s_ & (address_.halves.high+1); continue;
case OperationLXA:
a_ = x_ = (a_ | 0xee) & operand_;
@ -475,28 +475,28 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
case CycleAddXToAddressLow:
nextAddress.full = address_.full + x_;
address_.bytes.low = nextAddress.bytes.low;
if(address_.bytes.high != nextAddress.bytes.high) {
address_.halves.low = nextAddress.halves.low;
if(address_.halves.high != nextAddress.halves.high) {
page_crossing_stall_read();
break;
}
continue;
case CycleAddXToAddressLowRead:
nextAddress.full = address_.full + x_;
address_.bytes.low = nextAddress.bytes.low;
address_.halves.low = nextAddress.halves.low;
page_crossing_stall_read();
break;
case CycleAddYToAddressLow:
nextAddress.full = address_.full + y_;
address_.bytes.low = nextAddress.bytes.low;
if(address_.bytes.high != nextAddress.bytes.high) {
address_.halves.low = nextAddress.halves.low;
if(address_.halves.high != nextAddress.halves.high) {
page_crossing_stall_read();
break;
}
continue;
case CycleAddYToAddressLowRead:
nextAddress.full = address_.full + y_;
address_.bytes.low = nextAddress.bytes.low;
address_.halves.low = nextAddress.halves.low;
page_crossing_stall_read();
break;
@ -507,37 +507,37 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
continue;
case CycleIncrementPCFetchAddressLowFromOperand:
pc_.full++;
read_mem(address_.bytes.low, operand_);
read_mem(address_.halves.low, operand_);
break;
case CycleAddXToOperandFetchAddressLow:
operand_ += x_;
read_mem(address_.bytes.low, operand_);
read_mem(address_.halves.low, operand_);
break;
case CycleFetchAddressLowFromOperand:
read_mem(address_.bytes.low, operand_);
read_mem(address_.halves.low, operand_);
break;
case CycleIncrementOperandFetchAddressHigh:
operand_++;
read_mem(address_.bytes.high, operand_);
read_mem(address_.halves.high, operand_);
break;
case CycleIncrementPCReadPCHLoadPCL: // deliberate fallthrough
pc_.full++;
case CycleReadPCHLoadPCL: {
uint16_t oldPC = pc_.full;
pc_.bytes.low = operand_;
read_mem(pc_.bytes.high, oldPC);
pc_.halves.low = operand_;
read_mem(pc_.halves.high, oldPC);
} break;
case CycleReadAddressHLoadAddressL:
address_.bytes.low = operand_; pc_.full++;
read_mem(address_.bytes.high, pc_.full);
address_.halves.low = operand_; pc_.full++;
read_mem(address_.halves.high, pc_.full);
break;
case CycleLoadAddressAbsolute: {
uint16_t nextPC = pc_.full+1;
pc_.full += 2;
address_.bytes.low = operand_;
read_mem(address_.bytes.high, nextPC);
address_.halves.low = operand_;
read_mem(address_.halves.high, nextPC);
} break;
case OperationLoadAddressZeroPage:
@ -583,8 +583,8 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
case CycleAddSignedOperandToPC:
nextAddress.full = static_cast<uint16_t>(pc_.full + (int8_t)operand_);
pc_.bytes.low = nextAddress.bytes.low;
if(nextAddress.bytes.high != pc_.bytes.high) {
pc_.halves.low = nextAddress.halves.low;
if(nextAddress.halves.high != pc_.halves.high) {
uint16_t halfUpdatedPc = pc_.full;
pc_.full = nextAddress.full;
throwaway_read(halfUpdatedPc);
@ -598,7 +598,7 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
continue;
case CycleFetchFromHalfUpdatedPC: {
uint16_t halfUpdatedPc = static_cast<uint16_t>(((pc_.bytes.low + (int8_t)operand_) & 0xff) | (pc_.bytes.high << 8));
uint16_t halfUpdatedPc = static_cast<uint16_t>(((pc_.halves.low + (int8_t)operand_) & 0xff) | (pc_.halves.high << 8));
throwaway_read(halfUpdatedPc);
} break;

View File

@ -205,7 +205,7 @@ class ProcessorStorage {
/*
Storage for the 6502 registers; F is stored as individual flags.
*/
RegisterPair pc_, last_operation_pc_;
RegisterPair16 pc_, last_operation_pc_;
uint8_t a_, x_, y_, s_ = 0;
uint8_t carry_flag_, negative_result_, zero_result_, decimal_flag_, overflow_flag_, inverse_interrupt_flag_ = 0;
@ -213,7 +213,7 @@ class ProcessorStorage {
Temporary state for the micro programs.
*/
uint8_t operation_, operand_;
RegisterPair address_, next_address_;
RegisterPair16 address_, next_address_;
/*
Temporary storage allowing a common dispatch point for calling perform_bus_operation;

View File

@ -13,16 +13,27 @@
namespace CPU {
union RegisterPair {
RegisterPair(uint16_t v) : full(v) {}
template <typename Full, typename Half> union RegisterPair {
RegisterPair(Full v) : full(v) {}
RegisterPair() {}
uint16_t full;
Full full;
#pragma pack(push, 1)
#if TARGET_RT_BIG_ENDIAN
struct {
uint8_t low, high;
} bytes;
Half high, low;
} halves;
#else
struct {
Half low, high;
} halves;
#endif
#pragma pack(pop)
};
typedef RegisterPair<uint16_t, uint8_t> RegisterPair16;
typedef RegisterPair<uint32_t, uint16_t> RegisterPair32;
}
#endif /* RegisterSizes_hpp */

View File

@ -23,38 +23,38 @@ uint16_t ProcessorBase::get_value_of_register(Register r) {
case Register::A: return a_;
case Register::Flags: return get_flags();
case Register::AF: return static_cast<uint16_t>((a_ << 8) | get_flags());
case Register::B: return bc_.bytes.high;
case Register::C: return bc_.bytes.low;
case Register::B: return bc_.halves.high;
case Register::C: return bc_.halves.low;
case Register::BC: return bc_.full;
case Register::D: return de_.bytes.high;
case Register::E: return de_.bytes.low;
case Register::D: return de_.halves.high;
case Register::E: return de_.halves.low;
case Register::DE: return de_.full;
case Register::H: return hl_.bytes.high;
case Register::L: return hl_.bytes.low;
case Register::H: return hl_.halves.high;
case Register::L: return hl_.halves.low;
case Register::HL: return hl_.full;
case Register::ADash: return afDash_.bytes.high;
case Register::FlagsDash: return afDash_.bytes.low;
case Register::ADash: return afDash_.halves.high;
case Register::FlagsDash: return afDash_.halves.low;
case Register::AFDash: return afDash_.full;
case Register::BDash: return bcDash_.bytes.high;
case Register::CDash: return bcDash_.bytes.low;
case Register::BDash: return bcDash_.halves.high;
case Register::CDash: return bcDash_.halves.low;
case Register::BCDash: return bcDash_.full;
case Register::DDash: return deDash_.bytes.high;
case Register::EDash: return deDash_.bytes.low;
case Register::DDash: return deDash_.halves.high;
case Register::EDash: return deDash_.halves.low;
case Register::DEDash: return deDash_.full;
case Register::HDash: return hlDash_.bytes.high;
case Register::LDash: return hlDash_.bytes.low;
case Register::HDash: return hlDash_.halves.high;
case Register::LDash: return hlDash_.halves.low;
case Register::HLDash: return hlDash_.full;
case Register::IXh: return ix_.bytes.high;
case Register::IXl: return ix_.bytes.low;
case Register::IXh: return ix_.halves.high;
case Register::IXl: return ix_.halves.low;
case Register::IX: return ix_.full;
case Register::IYh: return iy_.bytes.high;
case Register::IYl: return iy_.bytes.low;
case Register::IYh: return iy_.halves.high;
case Register::IYl: return iy_.halves.low;
case Register::IY: return iy_.full;
case Register::R: return ir_.bytes.low;
case Register::I: return ir_.bytes.high;
case Register::R: return ir_.halves.low;
case Register::I: return ir_.halves.high;
case Register::Refresh: return ir_.full;
case Register::IFF1: return iff1_ ? 1 : 0;
@ -76,38 +76,38 @@ void ProcessorBase::set_value_of_register(Register r, uint16_t value) {
case Register::AF: a_ = static_cast<uint8_t>(value >> 8); // deliberate fallthrough...
case Register::Flags: set_flags(static_cast<uint8_t>(value)); break;
case Register::B: bc_.bytes.high = static_cast<uint8_t>(value); break;
case Register::C: bc_.bytes.low = static_cast<uint8_t>(value); break;
case Register::B: bc_.halves.high = static_cast<uint8_t>(value); break;
case Register::C: bc_.halves.low = static_cast<uint8_t>(value); break;
case Register::BC: bc_.full = value; break;
case Register::D: de_.bytes.high = static_cast<uint8_t>(value); break;
case Register::E: de_.bytes.low = static_cast<uint8_t>(value); break;
case Register::D: de_.halves.high = static_cast<uint8_t>(value); break;
case Register::E: de_.halves.low = static_cast<uint8_t>(value); break;
case Register::DE: de_.full = value; break;
case Register::H: hl_.bytes.high = static_cast<uint8_t>(value); break;
case Register::L: hl_.bytes.low = static_cast<uint8_t>(value); break;
case Register::H: hl_.halves.high = static_cast<uint8_t>(value); break;
case Register::L: hl_.halves.low = static_cast<uint8_t>(value); break;
case Register::HL: hl_.full = value; break;
case Register::ADash: afDash_.bytes.high = static_cast<uint8_t>(value); break;
case Register::FlagsDash: afDash_.bytes.low = static_cast<uint8_t>(value); break;
case Register::ADash: afDash_.halves.high = static_cast<uint8_t>(value); break;
case Register::FlagsDash: afDash_.halves.low = static_cast<uint8_t>(value); break;
case Register::AFDash: afDash_.full = value; break;
case Register::BDash: bcDash_.bytes.high = static_cast<uint8_t>(value); break;
case Register::CDash: bcDash_.bytes.low = static_cast<uint8_t>(value); break;
case Register::BDash: bcDash_.halves.high = static_cast<uint8_t>(value); break;
case Register::CDash: bcDash_.halves.low = static_cast<uint8_t>(value); break;
case Register::BCDash: bcDash_.full = value; break;
case Register::DDash: deDash_.bytes.high = static_cast<uint8_t>(value); break;
case Register::EDash: deDash_.bytes.low = static_cast<uint8_t>(value); break;
case Register::DDash: deDash_.halves.high = static_cast<uint8_t>(value); break;
case Register::EDash: deDash_.halves.low = static_cast<uint8_t>(value); break;
case Register::DEDash: deDash_.full = value; break;
case Register::HDash: hlDash_.bytes.high = static_cast<uint8_t>(value); break;
case Register::LDash: hlDash_.bytes.low = static_cast<uint8_t>(value); break;
case Register::HDash: hlDash_.halves.high = static_cast<uint8_t>(value); break;
case Register::LDash: hlDash_.halves.low = static_cast<uint8_t>(value); break;
case Register::HLDash: hlDash_.full = value; break;
case Register::IXh: ix_.bytes.high = static_cast<uint8_t>(value); break;
case Register::IXl: ix_.bytes.low = static_cast<uint8_t>(value); break;
case Register::IXh: ix_.halves.high = static_cast<uint8_t>(value); break;
case Register::IXl: ix_.halves.low = static_cast<uint8_t>(value); break;
case Register::IX: ix_.full = value; break;
case Register::IYh: iy_.bytes.high = static_cast<uint8_t>(value); break;
case Register::IYl: iy_.bytes.low = static_cast<uint8_t>(value); break;
case Register::IYh: iy_.halves.high = static_cast<uint8_t>(value); break;
case Register::IYl: iy_.halves.low = static_cast<uint8_t>(value); break;
case Register::IY: iy_.full = value; break;
case Register::R: ir_.bytes.low = static_cast<uint8_t>(value); break;
case Register::I: ir_.bytes.high = static_cast<uint8_t>(value); break;
case Register::R: ir_.halves.low = static_cast<uint8_t>(value); break;
case Register::I: ir_.halves.high = static_cast<uint8_t>(value); break;
case Register::Refresh: ir_.full = value; break;
case Register::IFF1: iff1_ = !!value; break;

View File

@ -90,7 +90,7 @@ template < class T,
break;
case MicroOp::DecodeOperation:
refresh_addr_ = ir_;
ir_.bytes.low = (ir_.bytes.low & 0x80) | ((ir_.bytes.low + current_instruction_page_->r_step) & 0x7f);
ir_.halves.low = (ir_.halves.low & 0x80) | ((ir_.halves.low + current_instruction_page_->r_step) & 0x7f);
pc_.full += pc_increment_ & static_cast<uint16_t>(halt_mask_);
scheduled_program_counter_ = current_instruction_page_->instructions[operation_ & halt_mask_];
flag_adjustment_history_ <<= 1;
@ -108,13 +108,12 @@ template < class T,
case MicroOp::Move16: *static_cast<uint16_t *>(operation->destination) = *static_cast<uint16_t *>(operation->source); break;
case MicroOp::AssembleAF:
temp16_.bytes.high = a_;
temp16_.bytes.low = get_flags();
temp16_.halves.high = a_;
temp16_.halves.low = get_flags();
break;
case MicroOp::DisassembleAF:
a_ = temp16_.bytes.high;
set_flags(temp16_.bytes.low);
//
a_ = temp16_.halves.high;
set_flags(temp16_.halves.low);
break;
// MARK: - Logical
@ -179,8 +178,8 @@ template < class T,
// MARK: - Flow control
case MicroOp::DJNZ:
bc_.bytes.high--;
if(!bc_.bytes.high) {
bc_.halves.high--;
if(!bc_.halves.high) {
advance_operation();
}
break;
@ -460,10 +459,10 @@ template < class T,
case MicroOp::ExAFAFDash: {
const uint8_t a = a_;
const uint8_t f = get_flags();
set_flags(afDash_.bytes.low);
a_ = afDash_.bytes.high;
afDash_.bytes.high = a;
afDash_.bytes.low = f;
set_flags(afDash_.halves.low);
a_ = afDash_.halves.high;
afDash_.halves.high = a;
afDash_.halves.low = f;
} break;
case MicroOp::EXX: {
@ -554,13 +553,13 @@ template < class T,
#undef CPxR_STEP
#define INxR_STEP(dir) \
bc_.bytes.high--; \
bc_.halves.high--; \
hl_.full += dir; \
\
sign_result_ = zero_result_ = bit53_result_ = bc_.bytes.high; \
sign_result_ = zero_result_ = bit53_result_ = bc_.halves.high; \
subtract_flag_ = (temp8_ >> 6) & Flag::Subtract; \
\
const int next_bc = bc_.bytes.low + dir; \
const int next_bc = bc_.halves.low + dir; \
int summation = temp8_ + (next_bc&0xff); \
\
if(summation > 0xff) { \
@ -571,18 +570,18 @@ template < class T,
half_carry_result_ = 0; \
} \
\
summation = (summation&7) ^ bc_.bytes.high; \
summation = (summation&7) ^ bc_.halves.high; \
set_parity(summation); \
set_did_compute_flags();
case MicroOp::INDR: {
INxR_STEP(-1);
REPEAT(bc_.bytes.high);
REPEAT(bc_.halves.high);
} break;
case MicroOp::INIR: {
INxR_STEP(1);
REPEAT(bc_.bytes.high);
REPEAT(bc_.halves.high);
} break;
case MicroOp::IND: {
@ -598,13 +597,13 @@ template < class T,
#undef INxR_STEP
#define OUTxR_STEP(dir) \
bc_.bytes.high--; \
bc_.halves.high--; \
hl_.full += dir; \
\
sign_result_ = zero_result_ = bit53_result_ = bc_.bytes.high; \
sign_result_ = zero_result_ = bit53_result_ = bc_.halves.high; \
subtract_flag_ = (temp8_ >> 6) & Flag::Subtract; \
\
int summation = temp8_ + hl_.bytes.low; \
int summation = temp8_ + hl_.halves.low; \
if(summation > 0xff) { \
carry_result_ = Flag::Carry; \
half_carry_result_ = Flag::HalfCarry; \
@ -612,12 +611,12 @@ template < class T,
carry_result_ = half_carry_result_ = 0; \
} \
\
summation = (summation&7) ^ bc_.bytes.high; \
summation = (summation&7) ^ bc_.halves.high; \
set_parity(summation); \
set_did_compute_flags();
case MicroOp::OUT_R:
REPEAT(bc_.bytes.high);
REPEAT(bc_.halves.high);
break;
case MicroOp::OUTD: {
@ -638,7 +637,7 @@ template < class T,
const uint8_t result = *static_cast<uint8_t *>(operation->source) & (1 << ((operation_ >> 3)&7));
if(current_instruction_page_->is_indexed || ((operation_&0x07) == 6)) {
bit53_result_ = memptr_.bytes.high;
bit53_result_ = memptr_.halves.high;
} else {
bit53_result_ = *static_cast<uint8_t *>(operation->source);
}

View File

@ -86,48 +86,48 @@ ProcessorStorage::ProcessorStorage() {
#define Read5Inc(addr, val) Read5(addr, val), Inc16(addr)
#define WriteInc(addr, val) Write3(addr, val), {MicroOp::Increment16, &addr.full}
#define Read16Inc(addr, val) ReadInc(addr, val.bytes.low), ReadInc(addr, val.bytes.high)
#define Read16(addr, val) ReadInc(addr, val.bytes.low), Read3(addr, val.bytes.high)
#define Read16Inc(addr, val) ReadInc(addr, val.halves.low), ReadInc(addr, val.halves.high)
#define Read16(addr, val) ReadInc(addr, val.halves.low), Read3(addr, val.halves.high)
#define Write16(addr, val) WriteInc(addr, val.bytes.low), Write3(addr, val.bytes.high)
#define Write16(addr, val) WriteInc(addr, val.halves.low), Write3(addr, val.halves.high)
#define INDEX() {MicroOp::IndexedPlaceHolder}, ReadInc(pc_, temp8_), InternalOperation(10), {MicroOp::CalculateIndexAddress, &index}
#define FINDEX() {MicroOp::IndexedPlaceHolder}, ReadInc(pc_, temp8_), {MicroOp::CalculateIndexAddress, &index}
#define INDEX_ADDR() (add_offsets ? memptr_ : index)
#define Push(x) {MicroOp::Decrement16, &sp_.full}, Write3(sp_, x.bytes.high), {MicroOp::Decrement16, &sp_.full}, Write3(sp_, x.bytes.low)
#define Pop(x) Read3(sp_, x.bytes.low), {MicroOp::Increment16, &sp_.full}, Read3(sp_, x.bytes.high), {MicroOp::Increment16, &sp_.full}
#define Push(x) {MicroOp::Decrement16, &sp_.full}, Write3(sp_, x.halves.high), {MicroOp::Decrement16, &sp_.full}, Write3(sp_, x.halves.low)
#define Pop(x) Read3(sp_, x.halves.low), {MicroOp::Increment16, &sp_.full}, Read3(sp_, x.halves.high), {MicroOp::Increment16, &sp_.full}
#define Push8(x) {MicroOp::Decrement16, &sp_.full}, Write3(sp_, x.bytes.high), {MicroOp::Decrement16, &sp_.full}, Write5(sp_, x.bytes.low)
#define Pop7(x) Read3(sp_, x.bytes.low), {MicroOp::Increment16, &sp_.full}, Read4(sp_, x.bytes.high), {MicroOp::Increment16, &sp_.full}
#define Push8(x) {MicroOp::Decrement16, &sp_.full}, Write3(sp_, x.halves.high), {MicroOp::Decrement16, &sp_.full}, Write5(sp_, x.halves.low)
#define Pop7(x) Read3(sp_, x.halves.low), {MicroOp::Increment16, &sp_.full}, Read4(sp_, x.halves.high), {MicroOp::Increment16, &sp_.full}
/* The following are actual instructions */
#define NOP Sequence(BusOp(Refresh(4)))
#define JP(cc) StdInstr(Read16Inc(pc_, temp16_), {MicroOp::cc, nullptr}, {MicroOp::Move16, &temp16_.full, &pc_.full})
#define CALL(cc) StdInstr(ReadInc(pc_, temp16_.bytes.low), {MicroOp::cc, conditional_call_untaken_program_.data()}, Read4Inc(pc_, temp16_.bytes.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full})
#define CALL(cc) StdInstr(ReadInc(pc_, temp16_.halves.low), {MicroOp::cc, conditional_call_untaken_program_.data()}, Read4Inc(pc_, temp16_.halves.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full})
#define RET(cc) Instr(6, {MicroOp::cc, nullptr}, Pop(memptr_), {MicroOp::Move16, &memptr_.full, &pc_.full})
#define JR(cc) StdInstr(ReadInc(pc_, temp8_), {MicroOp::cc, nullptr}, InternalOperation(10), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full})
#define RST() Instr(6, {MicroOp::CalculateRSTDestination}, Push(pc_), {MicroOp::Move16, &memptr_.full, &pc_.full})
#define LD(a, b) StdInstr({MicroOp::Move8, &b, &a})
#define LD_GROUP(r, ri) \
LD(r, bc_.bytes.high), LD(r, bc_.bytes.low), LD(r, de_.bytes.high), LD(r, de_.bytes.low), \
LD(r, index.bytes.high), LD(r, index.bytes.low), \
LD(r, bc_.halves.high), LD(r, bc_.halves.low), LD(r, de_.halves.high), LD(r, de_.halves.low), \
LD(r, index.halves.high), LD(r, index.halves.low), \
StdInstr(INDEX(), Read3(INDEX_ADDR(), temp8_), {MicroOp::Move8, &temp8_, &ri}), \
LD(r, a_)
#define READ_OP_GROUP(op) \
StdInstr({MicroOp::op, &bc_.bytes.high}), StdInstr({MicroOp::op, &bc_.bytes.low}), \
StdInstr({MicroOp::op, &de_.bytes.high}), StdInstr({MicroOp::op, &de_.bytes.low}), \
StdInstr({MicroOp::op, &index.bytes.high}), StdInstr({MicroOp::op, &index.bytes.low}), \
StdInstr({MicroOp::op, &bc_.halves.high}), StdInstr({MicroOp::op, &bc_.halves.low}), \
StdInstr({MicroOp::op, &de_.halves.high}), StdInstr({MicroOp::op, &de_.halves.low}), \
StdInstr({MicroOp::op, &index.halves.high}), StdInstr({MicroOp::op, &index.halves.low}), \
StdInstr(INDEX(), Read3(INDEX_ADDR(), temp8_), {MicroOp::op, &temp8_}), \
StdInstr({MicroOp::op, &a_})
#define READ_OP_GROUP_D(op) \
StdInstr({MicroOp::op, &bc_.bytes.high}), StdInstr({MicroOp::op, &bc_.bytes.low}), \
StdInstr({MicroOp::op, &de_.bytes.high}), StdInstr({MicroOp::op, &de_.bytes.low}), \
StdInstr({MicroOp::op, &index.bytes.high}), StdInstr({MicroOp::op, &index.bytes.low}), \
StdInstr({MicroOp::op, &bc_.halves.high}), StdInstr({MicroOp::op, &bc_.halves.low}), \
StdInstr({MicroOp::op, &de_.halves.high}), StdInstr({MicroOp::op, &de_.halves.low}), \
StdInstr({MicroOp::op, &index.halves.high}), StdInstr({MicroOp::op, &index.halves.low}), \
StdInstr(INDEX(), Read4Pre(INDEX_ADDR(), temp8_), {MicroOp::op, &temp8_}), \
StdInstr({MicroOp::op, &a_})
@ -135,19 +135,19 @@ ProcessorStorage::ProcessorStorage() {
#define RMWI(x, op, ...) StdInstr(Read4(INDEX_ADDR(), x), {MicroOp::op, &x}, Write3(INDEX_ADDR(), x))
#define MODIFY_OP_GROUP(op) \
StdInstr({MicroOp::op, &bc_.bytes.high}), StdInstr({MicroOp::op, &bc_.bytes.low}), \
StdInstr({MicroOp::op, &de_.bytes.high}), StdInstr({MicroOp::op, &de_.bytes.low}), \
StdInstr({MicroOp::op, &index.bytes.high}), StdInstr({MicroOp::op, &index.bytes.low}), \
StdInstr({MicroOp::op, &bc_.halves.high}), StdInstr({MicroOp::op, &bc_.halves.low}), \
StdInstr({MicroOp::op, &de_.halves.high}), StdInstr({MicroOp::op, &de_.halves.low}), \
StdInstr({MicroOp::op, &index.halves.high}), StdInstr({MicroOp::op, &index.halves.low}), \
RMW(temp8_, op), \
StdInstr({MicroOp::op, &a_})
#define IX_MODIFY_OP_GROUP(op) \
RMWI(bc_.bytes.high, op), \
RMWI(bc_.bytes.low, op), \
RMWI(de_.bytes.high, op), \
RMWI(de_.bytes.low, op), \
RMWI(hl_.bytes.high, op), \
RMWI(hl_.bytes.low, op), \
RMWI(bc_.halves.high, op), \
RMWI(bc_.halves.low, op), \
RMWI(de_.halves.high, op), \
RMWI(de_.halves.low, op), \
RMWI(hl_.halves.high, op), \
RMWI(hl_.halves.low, op), \
RMWI(temp8_, op), \
RMWI(a_, op)
@ -166,7 +166,7 @@ ProcessorStorage::ProcessorStorage() {
#define SBC16(d, s) StdInstr(InternalOperation(8), InternalOperation(6), {MicroOp::SBC16, &s.full, &d.full})
void ProcessorStorage::install_default_instruction_set() {
MicroOp conditional_call_untaken_program[] = Sequence(ReadInc(pc_, temp16_.bytes.high));
MicroOp conditional_call_untaken_program[] = Sequence(ReadInc(pc_, temp16_.halves.high));
copy_program(conditional_call_untaken_program, conditional_call_untaken_program_);
assemble_base_page(base_page_, hl_, false, cb_page_);
@ -225,12 +225,12 @@ void ProcessorStorage::install_default_instruction_set() {
};
MicroOp irq_mode2_program[] = {
{ MicroOp::BeginIRQ },
BusOp(IntAckStart(7, temp16_.bytes.low)),
BusOp(IntWait(temp16_.bytes.low)),
BusOp(IntAckEnd(temp16_.bytes.low)),
BusOp(IntAckStart(7, temp16_.halves.low)),
BusOp(IntWait(temp16_.halves.low)),
BusOp(IntAckEnd(temp16_.halves.low)),
BusOp(Refresh(4)),
Push(pc_),
{ MicroOp::Move8, &ir_.bytes.high, &temp16_.bytes.high },
{ MicroOp::Move8, &ir_.halves.high, &temp16_.halves.high },
Read16(temp16_, pc_),
{ MicroOp::MoveToNextProgram }
};
@ -253,27 +253,27 @@ void ProcessorStorage::assemble_ed_page(InstructionPage &target) {
NOP_ROW(), /* 0x10 */
NOP_ROW(), /* 0x20 */
NOP_ROW(), /* 0x30 */
/* 0x40 IN B, (C); 0x41 OUT (C), B */ IN_OUT(bc_.bytes.high),
/* 0x40 IN B, (C); 0x41 OUT (C), B */ IN_OUT(bc_.halves.high),
/* 0x42 SBC HL, BC */ SBC16(hl_, bc_), /* 0x43 LD (nn), BC */ StdInstr(Read16Inc(pc_, memptr_), Write16(memptr_, bc_)),
/* 0x44 NEG */ StdInstr({MicroOp::NEG}), /* 0x45 RETN */ StdInstr(Pop(pc_), {MicroOp::RETN}),
/* 0x46 IM 0 */ StdInstr({MicroOp::IM}), /* 0x47 LD I, A */ Instr(6, {MicroOp::Move8, &a_, &ir_.bytes.high}),
/* 0x48 IN C, (C); 0x49 OUT (C), C */ IN_OUT(bc_.bytes.low),
/* 0x46 IM 0 */ StdInstr({MicroOp::IM}), /* 0x47 LD I, A */ Instr(6, {MicroOp::Move8, &a_, &ir_.halves.high}),
/* 0x48 IN C, (C); 0x49 OUT (C), C */ IN_OUT(bc_.halves.low),
/* 0x4a ADC HL, BC */ ADC16(hl_, bc_), /* 0x4b LD BC, (nn) */ StdInstr(Read16Inc(pc_, temp16_), Read16(temp16_, bc_)),
/* 0x4c NEG */ StdInstr({MicroOp::NEG}), /* 0x4d RETI */ StdInstr(Pop(pc_), {MicroOp::RETN}),
/* 0x4e IM 0/1 */ StdInstr({MicroOp::IM}), /* 0x4f LD R, A */ Instr(6, {MicroOp::Move8, &a_, &ir_.bytes.low}),
/* 0x50 IN D, (C); 0x51 OUT (C), D */ IN_OUT(de_.bytes.high),
/* 0x4e IM 0/1 */ StdInstr({MicroOp::IM}), /* 0x4f LD R, A */ Instr(6, {MicroOp::Move8, &a_, &ir_.halves.low}),
/* 0x50 IN D, (C); 0x51 OUT (C), D */ IN_OUT(de_.halves.high),
/* 0x52 SBC HL, DE */ SBC16(hl_, de_), /* 0x53 LD (nn), DE */ StdInstr(Read16Inc(pc_, memptr_), Write16(memptr_, de_)),
/* 0x54 NEG */ StdInstr({MicroOp::NEG}), /* 0x55 RETN */ StdInstr(Pop(pc_), {MicroOp::RETN}),
/* 0x56 IM 1 */ StdInstr({MicroOp::IM}), /* 0x57 LD A, I */ Instr(6, {MicroOp::Move8, &ir_.bytes.high, &a_}, {MicroOp::SetAFlags}),
/* 0x58 IN E, (C); 0x59 OUT (C), E */ IN_OUT(de_.bytes.low),
/* 0x56 IM 1 */ StdInstr({MicroOp::IM}), /* 0x57 LD A, I */ Instr(6, {MicroOp::Move8, &ir_.halves.high, &a_}, {MicroOp::SetAFlags}),
/* 0x58 IN E, (C); 0x59 OUT (C), E */ IN_OUT(de_.halves.low),
/* 0x5a ADC HL, DE */ ADC16(hl_, de_), /* 0x5b LD DE, (nn) */ StdInstr(Read16Inc(pc_, temp16_), Read16(temp16_, de_)),
/* 0x5c NEG */ StdInstr({MicroOp::NEG}), /* 0x5d RETN */ StdInstr(Pop(pc_), {MicroOp::RETN}),
/* 0x5e IM 2 */ StdInstr({MicroOp::IM}), /* 0x5f LD A, R */ Instr(6, {MicroOp::Move8, &ir_.bytes.low, &a_}, {MicroOp::SetAFlags}),
/* 0x60 IN H, (C); 0x61 OUT (C), H */ IN_OUT(hl_.bytes.high),
/* 0x5e IM 2 */ StdInstr({MicroOp::IM}), /* 0x5f LD A, R */ Instr(6, {MicroOp::Move8, &ir_.halves.low, &a_}, {MicroOp::SetAFlags}),
/* 0x60 IN H, (C); 0x61 OUT (C), H */ IN_OUT(hl_.halves.high),
/* 0x62 SBC HL, HL */ SBC16(hl_, hl_), /* 0x63 LD (nn), HL */ StdInstr(Read16Inc(pc_, memptr_), Write16(memptr_, hl_)),
/* 0x64 NEG */ StdInstr({MicroOp::NEG}), /* 0x65 RETN */ StdInstr(Pop(pc_), {MicroOp::RETN}),
/* 0x66 IM 0 */ StdInstr({MicroOp::IM}), /* 0x67 RRD */ StdInstr(Read3(hl_, temp8_), InternalOperation(8), {MicroOp::RRD}, Write3(hl_, temp8_)),
/* 0x68 IN L, (C); 0x69 OUT (C), L */ IN_OUT(hl_.bytes.low),
/* 0x68 IN L, (C); 0x69 OUT (C), L */ IN_OUT(hl_.halves.low),
/* 0x6a ADC HL, HL */ ADC16(hl_, hl_), /* 0x6b LD HL, (nn) */ StdInstr(Read16Inc(pc_, temp16_), Read16(temp16_, hl_)),
/* 0x6c NEG */ StdInstr({MicroOp::NEG}), /* 0x6d RETN */ StdInstr(Pop(pc_), {MicroOp::RETN}),
/* 0x6e IM 0/1 */ StdInstr({MicroOp::IM}), /* 0x6f RLD */ StdInstr(Read3(hl_, temp8_), InternalOperation(8), {MicroOp::RLD}, Write3(hl_, temp8_)),
@ -316,7 +316,7 @@ void ProcessorStorage::assemble_ed_page(InstructionPage &target) {
#undef NOP_ROW
}
void ProcessorStorage::assemble_cb_page(InstructionPage &target, RegisterPair &index, bool add_offsets) {
void ProcessorStorage::assemble_cb_page(InstructionPage &target, RegisterPair16 &index, bool add_offsets) {
#define OCTO_OP_GROUP(m, x) m(x), m(x), m(x), m(x), m(x), m(x), m(x), m(x)
#define CB_PAGE(m, p) m(RLC), m(RRC), m(RL), m(RR), m(SLA), m(SRA), m(SLL), m(SRL), OCTO_OP_GROUP(p, BIT), OCTO_OP_GROUP(m, RES), OCTO_OP_GROUP(m, SET)
@ -343,7 +343,7 @@ void ProcessorStorage::assemble_cb_page(InstructionPage &target, RegisterPair &i
#undef CB_PAGE
}
void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair &index, bool add_offsets, InstructionPage &cb_page) {
void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair16 &index, bool add_offsets, InstructionPage &cb_page) {
#define INC_DEC_LD(r) \
StdInstr({MicroOp::Increment8, &r}), \
StdInstr({MicroOp::Decrement8, &r}), \
@ -360,14 +360,14 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair
/* 0x02 LD (BC), A */ StdInstr({MicroOp::SetAddrAMemptr, &bc_.full}, Write3(bc_, a_)),
/* 0x03 INC BC; 0x04 INC B; 0x05 DEC B; 0x06 LD B, n */
INC_INC_DEC_LD(bc_, bc_.bytes.high),
INC_INC_DEC_LD(bc_, bc_.halves.high),
/* 0x07 RLCA */ StdInstr({MicroOp::RLCA}),
/* 0x08 EX AF, AF' */ StdInstr({MicroOp::ExAFAFDash}), /* 0x09 ADD HL, BC */ ADD16(index, bc_),
/* 0x0a LD A, (BC) */ StdInstr({MicroOp::Move16, &bc_.full, &memptr_.full}, Read3(memptr_, a_), Inc16(memptr_)),
/* 0x0b DEC BC; 0x0c INC C; 0x0d DEC C; 0x0e LD C, n */
DEC_INC_DEC_LD(bc_, bc_.bytes.low),
DEC_INC_DEC_LD(bc_, bc_.halves.low),
/* 0x0f RRCA */ StdInstr({MicroOp::RRCA}),
/* 0x10 DJNZ */ Instr(6, ReadInc(pc_, temp8_), {MicroOp::DJNZ}, InternalOperation(10), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full}),
@ -375,7 +375,7 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair
/* 0x12 LD (DE), A */ StdInstr({MicroOp::SetAddrAMemptr, &de_.full}, Write3(de_, a_)),
/* 0x13 INC DE; 0x14 INC D; 0x15 DEC D; 0x16 LD D, n */
INC_INC_DEC_LD(de_, de_.bytes.high),
INC_INC_DEC_LD(de_, de_.halves.high),
/* 0x17 RLA */ StdInstr({MicroOp::RLA}),
/* 0x18 JR */ StdInstr(ReadInc(pc_, temp8_), InternalOperation(10), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full}),
@ -383,21 +383,21 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair
/* 0x1a LD A, (DE) */ StdInstr({MicroOp::Move16, &de_.full, &memptr_.full}, Read3(memptr_, a_), Inc16(memptr_)),
/* 0x1b DEC DE; 0x1c INC E; 0x1d DEC E; 0x1e LD E, n */
DEC_INC_DEC_LD(de_, de_.bytes.low),
DEC_INC_DEC_LD(de_, de_.halves.low),
/* 0x1f RRA */ StdInstr({MicroOp::RRA}),
/* 0x20 JR NZ */ JR(TestNZ), /* 0x21 LD HL, nn */ StdInstr(Read16Inc(pc_, index)),
/* 0x22 LD (nn), HL */ StdInstr(Read16Inc(pc_, memptr_), Write16(memptr_, index)),
/* 0x23 INC HL; 0x24 INC H; 0x25 DEC H; 0x26 LD H, n */
INC_INC_DEC_LD(index, index.bytes.high),
INC_INC_DEC_LD(index, index.halves.high),
/* 0x27 DAA */ StdInstr({MicroOp::DAA}),
/* 0x28 JR Z */ JR(TestZ), /* 0x29 ADD HL, HL */ ADD16(index, index),
/* 0x2a LD HL, (nn) */ StdInstr(Read16Inc(pc_, temp16_), Read16(temp16_, index)),
/* 0x2b DEC HL; 0x2c INC L; 0x2d DEC L; 0x2e LD L, n */
DEC_INC_DEC_LD(index, index.bytes.low),
DEC_INC_DEC_LD(index, index.halves.low),
/* 0x2f CPL */ StdInstr({MicroOp::CPL}),
/* 0x30 JR NC */ JR(TestNC), /* 0x31 LD SP, nn */ StdInstr(Read16Inc(pc_, sp_)),
@ -418,29 +418,29 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair
/* 0x3f CCF */ StdInstr({MicroOp::CCF}),
/* 0x40 LD B, B; 0x41 LD B, C; 0x42 LD B, D; 0x43 LD B, E; 0x44 LD B, H; 0x45 LD B, L; 0x46 LD B, (HL); 0x47 LD B, A */
LD_GROUP(bc_.bytes.high, bc_.bytes.high),
LD_GROUP(bc_.halves.high, bc_.halves.high),
/* 0x48 LD C, B; 0x49 LD C, C; 0x4a LD C, D; 0x4b LD C, E; 0x4c LD C, H; 0x4d LD C, L; 0x4e LD C, (HL); 0x4f LD C, A */
LD_GROUP(bc_.bytes.low, bc_.bytes.low),
LD_GROUP(bc_.halves.low, bc_.halves.low),
/* 0x50 LD D, B; 0x51 LD D, C; 0x52 LD D, D; 0x53 LD D, E; 0x54 LD D, H; 0x55 LD D, L; 0x56 LD D, (HL); 0x57 LD D, A */
LD_GROUP(de_.bytes.high, de_.bytes.high),
LD_GROUP(de_.halves.high, de_.halves.high),
/* 0x58 LD E, B; 0x59 LD E, C; 0x5a LD E, D; 0x5b LD E, E; 0x5c LD E, H; 0x5d LD E, L; 0x5e LD E, (HL); 0x5f LD E, A */
LD_GROUP(de_.bytes.low, de_.bytes.low),
LD_GROUP(de_.halves.low, de_.halves.low),
/* 0x60 LD H, B; 0x61 LD H, C; 0x62 LD H, D; 0x63 LD H, E; 0x64 LD H, H; 0x65 LD H, L; 0x66 LD H, (HL); 0x67 LD H, A */
LD_GROUP(index.bytes.high, hl_.bytes.high),
LD_GROUP(index.halves.high, hl_.halves.high),
/* 0x68 LD L, B; 0x69 LD L, C; 0x6a LD L, D; 0x6b LD L, E; 0x6c LD L, H; 0x6d LD H, L; 0x6e LD L, (HL); 0x6f LD L, A */
LD_GROUP(index.bytes.low, hl_.bytes.low),
LD_GROUP(index.halves.low, hl_.halves.low),
/* 0x70 LD (HL), B */ StdInstr(INDEX(), Write3(INDEX_ADDR(), bc_.bytes.high)),
/* 0x71 LD (HL), C */ StdInstr(INDEX(), Write3(INDEX_ADDR(), bc_.bytes.low)),
/* 0x72 LD (HL), D */ StdInstr(INDEX(), Write3(INDEX_ADDR(), de_.bytes.high)),
/* 0x73 LD (HL), E */ StdInstr(INDEX(), Write3(INDEX_ADDR(), de_.bytes.low)),
/* 0x74 LD (HL), H */ StdInstr(INDEX(), Write3(INDEX_ADDR(), hl_.bytes.high)), // neither of these stores parts of the index register;
/* 0x75 LD (HL), L */ StdInstr(INDEX(), Write3(INDEX_ADDR(), hl_.bytes.low)), // they always store exactly H and L.
/* 0x70 LD (HL), B */ StdInstr(INDEX(), Write3(INDEX_ADDR(), bc_.halves.high)),
/* 0x71 LD (HL), C */ StdInstr(INDEX(), Write3(INDEX_ADDR(), bc_.halves.low)),
/* 0x72 LD (HL), D */ StdInstr(INDEX(), Write3(INDEX_ADDR(), de_.halves.high)),
/* 0x73 LD (HL), E */ StdInstr(INDEX(), Write3(INDEX_ADDR(), de_.halves.low)),
/* 0x74 LD (HL), H */ StdInstr(INDEX(), Write3(INDEX_ADDR(), hl_.halves.high)), // neither of these stores parts of the index register;
/* 0x75 LD (HL), L */ StdInstr(INDEX(), Write3(INDEX_ADDR(), hl_.halves.low)), // they always store exactly H and L.
/* 0x76 HALT */ StdInstr({MicroOp::HALT}),
/* 0x77 LD (HL), A */ StdInstr(INDEX(), Write3(INDEX_ADDR(), a_)),
@ -478,16 +478,16 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair
/* 0xc7 RST 00h */ RST(),
/* 0xc8 RET Z */ RET(TestZ), /* 0xc9 RET */ StdInstr(Pop(pc_)),
/* 0xca JP Z */ JP(TestZ), /* 0xcb [CB page] */StdInstr(FINDEX(), {MicroOp::SetInstructionPage, &cb_page}),
/* 0xcc CALL Z */ CALL(TestZ), /* 0xcd CALL */ StdInstr(ReadInc(pc_, temp16_.bytes.low), Read4Inc(pc_, temp16_.bytes.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full}),
/* 0xcc CALL Z */ CALL(TestZ), /* 0xcd CALL */ StdInstr(ReadInc(pc_, temp16_.halves.low), Read4Inc(pc_, temp16_.halves.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full}),
/* 0xce ADC A, n */ StdInstr(ReadInc(pc_, temp8_), {MicroOp::ADC8, &temp8_}),
/* 0xcf RST 08h */ RST(),
/* 0xd0 RET NC */ RET(TestNC), /* 0xd1 POP DE */ StdInstr(Pop(de_)),
/* 0xd2 JP NC */ JP(TestNC), /* 0xd3 OUT (n), A */StdInstr(ReadInc(pc_, temp16_.bytes.low), {MicroOp::Move8, &a_, &temp16_.bytes.high}, Output(temp16_, a_)),
/* 0xd2 JP NC */ JP(TestNC), /* 0xd3 OUT (n), A */StdInstr(ReadInc(pc_, temp16_.halves.low), {MicroOp::Move8, &a_, &temp16_.halves.high}, Output(temp16_, a_)),
/* 0xd4 CALL NC */ CALL(TestNC), /* 0xd5 PUSH DE */ Instr(6, Push(de_)),
/* 0xd6 SUB n */ StdInstr(ReadInc(pc_, temp8_), {MicroOp::SUB8, &temp8_}),
/* 0xd7 RST 10h */ RST(),
/* 0xd8 RET C */ RET(TestC), /* 0xd9 EXX */ StdInstr({MicroOp::EXX}),
/* 0xda JP C */ JP(TestC), /* 0xdb IN A, (n) */StdInstr(ReadInc(pc_, temp16_.bytes.low), {MicroOp::Move8, &a_, &temp16_.bytes.high}, Input(temp16_, a_)),
/* 0xda JP C */ JP(TestC), /* 0xdb IN A, (n) */StdInstr(ReadInc(pc_, temp16_.halves.low), {MicroOp::Move8, &a_, &temp16_.halves.high}, Input(temp16_, a_)),
/* 0xdc CALL C */ CALL(TestC), /* 0xdd [DD page] */StdInstr({MicroOp::SetInstructionPage, &dd_page_}),
/* 0xde SBC A, n */ StdInstr(ReadInc(pc_, temp8_), {MicroOp::SBC8, &temp8_}),
/* 0xdf RST 18h */ RST(),

View File

@ -118,10 +118,10 @@ class ProcessorStorage {
void install_default_instruction_set();
uint8_t a_;
RegisterPair bc_, de_, hl_;
RegisterPair afDash_, bcDash_, deDash_, hlDash_;
RegisterPair ix_, iy_, pc_, sp_;
RegisterPair ir_, refresh_addr_;
RegisterPair16 bc_, de_, hl_;
RegisterPair16 afDash_, bcDash_, deDash_, hlDash_;
RegisterPair16 ix_, iy_, pc_, sp_;
RegisterPair16 ir_, refresh_addr_;
bool iff1_ = false, iff2_ = false;
int interrupt_mode_ = 0;
uint16_t pc_increment_ = 1;
@ -153,7 +153,7 @@ class ProcessorStorage {
bool wait_line_ = false;
uint8_t operation_;
RegisterPair temp16_, memptr_;
RegisterPair16 temp16_, memptr_;
uint8_t temp8_;
const MicroOp *scheduled_program_counter_ = nullptr;
@ -214,7 +214,7 @@ class ProcessorStorage {
void assemble_fetch_decode_execute(InstructionPage &target, int length);
void assemble_ed_page(InstructionPage &target);
void assemble_cb_page(InstructionPage &target, RegisterPair &index, bool add_offsets);
void assemble_base_page(InstructionPage &target, RegisterPair &index, bool add_offsets, InstructionPage &cb_page);
void assemble_cb_page(InstructionPage &target, RegisterPair16 &index, bool add_offsets);
void assemble_base_page(InstructionPage &target, RegisterPair16 &index, bool add_offsets, InstructionPage &cb_page);
};