2016-06-05 22:10:01 +00:00
|
|
|
struct Register {
|
2015-06-27 02:38:47 +00:00
|
|
|
uint16 data = 0;
|
2016-06-05 22:10:01 +00:00
|
|
|
bool modified = false;
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
inline operator uint() const {
|
2015-06-27 02:38:47 +00:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
inline auto assign(uint value) -> uint16 {
|
|
|
|
modified = true;
|
|
|
|
return data = value;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
inline auto operator++() { return assign(data + 1); }
|
|
|
|
inline auto operator--() { return assign(data - 1); }
|
2016-06-05 22:10:01 +00:00
|
|
|
inline auto operator++(int) { uint r = data; assign(data + 1); return r; }
|
|
|
|
inline auto operator--(int) { uint r = data; assign(data - 1); return r; }
|
|
|
|
inline auto operator = (uint i) { return assign(i); }
|
|
|
|
inline auto operator |= (uint i) { return assign(data | i); }
|
|
|
|
inline auto operator ^= (uint i) { return assign(data ^ i); }
|
|
|
|
inline auto operator &= (uint i) { return assign(data & i); }
|
|
|
|
inline auto operator <<= (uint i) { return assign(data << i); }
|
|
|
|
inline auto operator >>= (uint i) { return assign(data >> i); }
|
|
|
|
inline auto operator += (uint i) { return assign(data + i); }
|
|
|
|
inline auto operator -= (uint i) { return assign(data - i); }
|
|
|
|
inline auto operator *= (uint i) { return assign(data * i); }
|
|
|
|
inline auto operator /= (uint i) { return assign(data / i); }
|
|
|
|
inline auto operator %= (uint i) { return assign(data % i); }
|
|
|
|
|
|
|
|
inline auto operator = (const Register& value) { return assign(value); }
|
|
|
|
|
|
|
|
Register() = default;
|
|
|
|
Register(const Register&) = delete;
|
2010-08-09 13:28:56 +00:00
|
|
|
};
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct SFR {
|
2016-06-08 22:26:35 +00:00
|
|
|
union {
|
|
|
|
uint16_t data = 0;
|
2016-06-28 10:43:47 +00:00
|
|
|
BooleanBitField<uint16_t, 15> irq; //interrupt flag
|
|
|
|
BooleanBitField<uint16_t, 12> b; //with flag
|
|
|
|
BooleanBitField<uint16_t, 11> ih; //immediate higher 8-bit flag
|
|
|
|
BooleanBitField<uint16_t, 10> il; //immediate lower 8-bit flag
|
|
|
|
BooleanBitField<uint16_t, 9> alt2; //alt2 instruction mode
|
|
|
|
BooleanBitField<uint16_t, 8> alt1; //alt1 instruction mode
|
|
|
|
BooleanBitField<uint16_t, 6> r; //ROM r14 read flag
|
|
|
|
BooleanBitField<uint16_t, 5> g; //go flag
|
|
|
|
BooleanBitField<uint16_t, 4> ov; //overflow flag
|
|
|
|
BooleanBitField<uint16_t, 3> s; //sign flag
|
|
|
|
BooleanBitField<uint16_t, 2> cy; //carry flag
|
|
|
|
BooleanBitField<uint16_t, 1> z; //zero flag
|
|
|
|
NaturalBitField<uint16_t, 9, 8> alt; //instruction mode (composite flag)
|
2016-06-08 22:26:35 +00:00
|
|
|
};
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2016-06-08 22:26:35 +00:00
|
|
|
inline operator uint() const { return data & 0x9f7e; }
|
|
|
|
inline auto& operator=(const uint value) { return data = value, *this; }
|
2010-08-09 13:28:56 +00:00
|
|
|
};
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct SCMR {
|
|
|
|
uint ht;
|
2010-08-09 13:28:56 +00:00
|
|
|
bool ron;
|
|
|
|
bool ran;
|
2016-06-05 22:10:01 +00:00
|
|
|
uint md;
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
operator uint() const {
|
2010-08-09 13:28:56 +00:00
|
|
|
return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md);
|
|
|
|
}
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
auto& operator=(uint data) {
|
2010-08-09 13:28:56 +00:00
|
|
|
ht = (bool)(data & 0x20) << 1;
|
|
|
|
ht |= (bool)(data & 0x04) << 0;
|
|
|
|
ron = data & 0x10;
|
|
|
|
ran = data & 0x08;
|
|
|
|
md = data & 0x03;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct POR {
|
2010-08-09 13:28:56 +00:00
|
|
|
bool obj;
|
|
|
|
bool freezehigh;
|
|
|
|
bool highnibble;
|
|
|
|
bool dither;
|
|
|
|
bool transparent;
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
operator uint() const {
|
2010-08-09 13:28:56 +00:00
|
|
|
return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent);
|
|
|
|
}
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
auto& operator=(uint data) {
|
2010-08-09 13:28:56 +00:00
|
|
|
obj = data & 0x10;
|
|
|
|
freezehigh = data & 0x08;
|
|
|
|
highnibble = data & 0x04;
|
|
|
|
dither = data & 0x02;
|
|
|
|
transparent = data & 0x01;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct CFGR {
|
2010-08-09 13:28:56 +00:00
|
|
|
bool irq;
|
|
|
|
bool ms0;
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
operator uint() const {
|
2010-08-09 13:28:56 +00:00
|
|
|
return (irq << 7) | (ms0 << 5);
|
|
|
|
}
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
auto& operator=(uint data) {
|
2010-08-09 13:28:56 +00:00
|
|
|
irq = data & 0x80;
|
|
|
|
ms0 = data & 0x20;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct Registers {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 pipeline;
|
|
|
|
uint16 ramaddr;
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
Register r[16]; //general purpose registers
|
|
|
|
SFR sfr; //status flag register
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 pbr; //program bank register
|
|
|
|
uint8 rombr; //game pack ROM bank register
|
|
|
|
bool rambr; //game pack RAM bank register
|
|
|
|
uint16 cbr; //cache base register
|
|
|
|
uint8 scbr; //screen base register
|
2016-06-05 22:10:01 +00:00
|
|
|
SCMR scmr; //screen mode register
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 colr; //color register
|
2016-06-05 22:10:01 +00:00
|
|
|
POR por; //plot option register
|
2010-08-09 13:28:56 +00:00
|
|
|
bool bramr; //back-up RAM register
|
|
|
|
uint8 vcr; //version code register
|
2016-06-05 22:10:01 +00:00
|
|
|
CFGR cfgr; //config register
|
2010-08-09 13:28:56 +00:00
|
|
|
bool clsr; //clock select register
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
uint romcl; //clock ticks until romdr is valid
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 romdr; //ROM buffer data register
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
uint ramcl; //clock ticks until ramdr is valid
|
2010-08-09 13:28:56 +00:00
|
|
|
uint16 ramar; //RAM buffer address register
|
|
|
|
uint8 ramdr; //RAM buffer data register
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
uint sreg;
|
|
|
|
uint dreg;
|
2015-06-27 02:38:47 +00:00
|
|
|
auto& sr() { return r[sreg]; } //source register (from)
|
|
|
|
auto& dr() { return r[dreg]; } //destination register (to)
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto reset() -> void {
|
2010-08-09 13:28:56 +00:00
|
|
|
sfr.b = 0;
|
|
|
|
sfr.alt1 = 0;
|
|
|
|
sfr.alt2 = 0;
|
|
|
|
|
|
|
|
sreg = 0;
|
|
|
|
dreg = 0;
|
|
|
|
}
|
|
|
|
} regs;
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct Cache {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 buffer[512];
|
|
|
|
bool valid[32];
|
|
|
|
} cache;
|
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
struct PixelCache {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint16 offset;
|
|
|
|
uint8 bitpend;
|
|
|
|
uint8 data[8];
|
|
|
|
} pixelcache[2];
|