struct VRC3 : Chip { VRC3(Board& board) : Chip(board) { } auto main() -> void { if(irqEnable) { if(irqMode == 0) { //16-bit if(++irqCounter.w == 0) { irqLine = 1; irqEnable = irqAcknowledge; irqCounter.w = irqLatch; } } if(irqMode == 1) { //8-bit if(++irqCounter.l == 0) { irqLine = 1; irqEnable = irqAcknowledge; irqCounter.l = irqLatch; } } } cpu.irqLine(irqLine); tick(); } auto addrPRG(uint addr) const -> uint { uint bank = (addr < 0xc000 ? (uint)prgBank : 0x0f); return (bank * 0x4000) + (addr & 0x3fff); } auto writeIO(uint addr, uint8 data) -> void { switch(addr & 0xf000) { 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; case 0xc000: irqMode = data & 0x04; irqEnable = data & 0x02; irqAcknowledge = data & 0x01; if(irqEnable) irqCounter.w = irqLatch; break; case 0xd000: irqLine = 0; irqEnable = irqAcknowledge; break; case 0xf000: prgBank = data & 0x0f; break; } } auto power() -> void { prgBank = 0; irqMode = 0; irqEnable = 0; irqAcknowledge = 0; irqLatch = 0; irqCounter.w = 0; irqLine = 0; } auto serialize(serializer& s) -> void { s.integer(prgBank); s.integer(irqMode); s.integer(irqEnable); s.integer(irqAcknowledge); s.integer(irqLatch); s.integer(irqCounter.w); s.integer(irqLine); } uint4 prgBank; bool irqMode; bool irqEnable; bool irqAcknowledge; uint16 irqLatch; struct { union { uint16_t w; struct { uint8_t order_lsb2(l, h); }; }; } irqCounter; bool irqLine; };