2011-11-04 11:57:54 +00:00
|
|
|
struct VRC3 : Chip {
|
2015-12-05 05:44:49 +00:00
|
|
|
VRC3(Board& board) : Chip(board) {
|
|
|
|
}
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto main() -> void {
|
2016-06-27 13:07:57 +00:00
|
|
|
if(irqEnable) {
|
|
|
|
if(irqMode == 0) { //16-bit
|
|
|
|
if(++irqCounter.w == 0) {
|
|
|
|
irqLine = 1;
|
|
|
|
irqEnable = irqAcknowledge;
|
|
|
|
irqCounter.w = irqLatch;
|
2011-11-04 11:57:54 +00:00
|
|
|
}
|
2016-02-09 11:51:12 +00:00
|
|
|
}
|
2016-06-27 13:07:57 +00:00
|
|
|
if(irqMode == 1) { //8-bit
|
|
|
|
if(++irqCounter.l == 0) {
|
|
|
|
irqLine = 1;
|
|
|
|
irqEnable = irqAcknowledge;
|
|
|
|
irqCounter.l = irqLatch;
|
2011-11-04 11:57:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-02-09 11:51:12 +00:00
|
|
|
|
2016-06-27 13:07:57 +00:00
|
|
|
cpu.irqLine(irqLine);
|
2016-02-09 11:51:12 +00:00
|
|
|
tick();
|
2015-12-05 05:44:49 +00:00
|
|
|
}
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2016-06-27 13:07:57 +00:00
|
|
|
auto addrPRG(uint addr) const -> uint {
|
|
|
|
uint bank = (addr < 0xc000 ? (uint)prgBank : 0x0f);
|
2015-12-05 05:44:49 +00:00
|
|
|
return (bank * 0x4000) + (addr & 0x3fff);
|
2011-11-04 11:57:54 +00:00
|
|
|
}
|
|
|
|
|
2016-06-27 13:07:57 +00:00
|
|
|
auto writeIO(uint addr, uint8 data) -> void {
|
2015-12-05 05:44:49 +00:00
|
|
|
switch(addr & 0xf000) {
|
2016-06-27 13:07:57 +00:00
|
|
|
case 0x8000: irqLatch = (irqLatch & 0xfff0) | ((data & 0x0f) << 0); break;
|
|
|
|
case 0x9000: irqLatch = (irqLatch & 0xff0f) | ((data & 0x0f) << 4); break;
|
|
|
|
case 0xa000: irqLatch = (irqLatch & 0xf0ff) | ((data & 0x0f) << 8); break;
|
|
|
|
case 0xb000: irqLatch = (irqLatch & 0x0fff) | ((data & 0x0f) << 12); break;
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
case 0xc000:
|
2016-06-27 13:07:57 +00:00
|
|
|
irqMode = data & 0x04;
|
|
|
|
irqEnable = data & 0x02;
|
|
|
|
irqAcknowledge = data & 0x01;
|
|
|
|
if(irqEnable) irqCounter.w = irqLatch;
|
2015-12-05 05:44:49 +00:00
|
|
|
break;
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
case 0xd000:
|
2016-06-27 13:07:57 +00:00
|
|
|
irqLine = 0;
|
|
|
|
irqEnable = irqAcknowledge;
|
2015-12-05 05:44:49 +00:00
|
|
|
break;
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
case 0xf000:
|
2016-06-27 13:07:57 +00:00
|
|
|
prgBank = data & 0x0f;
|
2015-12-05 05:44:49 +00:00
|
|
|
break;
|
|
|
|
}
|
2011-11-04 11:57:54 +00:00
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto power() -> void {
|
2016-06-27 13:07:57 +00:00
|
|
|
prgBank = 0;
|
|
|
|
irqMode = 0;
|
|
|
|
irqEnable = 0;
|
|
|
|
irqAcknowledge = 0;
|
|
|
|
irqLatch = 0;
|
|
|
|
irqCounter.w = 0;
|
|
|
|
irqLine = 0;
|
2015-12-05 05:44:49 +00:00
|
|
|
}
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto serialize(serializer& s) -> void {
|
2016-06-27 13:07:57 +00:00
|
|
|
s.integer(prgBank);
|
|
|
|
s.integer(irqMode);
|
|
|
|
s.integer(irqEnable);
|
|
|
|
s.integer(irqAcknowledge);
|
|
|
|
s.integer(irqLatch);
|
|
|
|
s.integer(irqCounter.w);
|
|
|
|
s.integer(irqLine);
|
2015-12-05 05:44:49 +00:00
|
|
|
}
|
2011-11-04 11:57:54 +00:00
|
|
|
|
2016-06-27 13:07:57 +00:00
|
|
|
uint4 prgBank;
|
|
|
|
bool irqMode;
|
|
|
|
bool irqEnable;
|
|
|
|
bool irqAcknowledge;
|
|
|
|
uint16 irqLatch;
|
2015-12-05 05:44:49 +00:00
|
|
|
struct {
|
|
|
|
union {
|
2016-02-16 09:27:55 +00:00
|
|
|
uint16_t w;
|
|
|
|
struct { uint8_t order_lsb2(l, h); };
|
2015-12-05 05:44:49 +00:00
|
|
|
};
|
2016-06-27 13:07:57 +00:00
|
|
|
} irqCounter;
|
|
|
|
bool irqLine;
|
2011-11-04 11:57:54 +00:00
|
|
|
};
|