Insert a new synchronous event whenever the 6522 timer's counter is written. . NB. it doesn't matter if the timer's interrupt enable (IER) is set or not - the state of IER is only important when the counter underflows - see: MB_SyncEventCallback()
| 100 | // . NB. it doesn't matter if the timer's interrupt enable (IER) is set or not |
| 101 | // - the state of IER is only important when the counter underflows - see: MB_SyncEventCallback() |
| 102 | USHORT SY6522::SetTimerSyncEvent(BYTE reg, USHORT timerLatch) |
| 103 | { |
| 104 | _ASSERT(reg == rT1CH || reg == rT2CH); |
| 105 | SyncEvent* syncEvent = reg == rT1CH ? m_syncEvent[0] : m_syncEvent[1]; |
| 106 | |
| 107 | // NB. This TIMER adjustment value gets subtracted when this current opcode completes, so no need to persist to save-state |
| 108 | const UINT opcodeCycleAdjust = GetOpcodeCyclesForWrite(reg); |
| 109 | |
| 110 | if (syncEvent->m_active) |
| 111 | g_SynchronousEventMgr.Remove(syncEvent->m_id); |
| 112 | |
| 113 | if (m_isMegaAudio) |
| 114 | { |
| 115 | if (reg == rT1CH && timerLatch == 0x0000) |
| 116 | timerLatch = 0xFFFF; // MegaAudio && T1.LATCH=0: use 0xFFFF (or maybe 0x10000?) |
| 117 | syncEvent->SetCycles(timerLatch + kExtraMegaAudioTimerCycles + opcodeCycleAdjust); // MegaAudio asserts IRQ 1 cycle late! |
| 118 | } |
| 119 | else |
| 120 | { |
| 121 | syncEvent->SetCycles(timerLatch + kExtraTimerCycles + opcodeCycleAdjust); |
| 122 | } |
| 123 | g_SynchronousEventMgr.Insert(syncEvent); |
| 124 | |
| 125 | // It doesn't matter if this overflows (ie. >0xFFFF), since on completion of current opcode it'll be corrected |
| 126 | return (USHORT)(timerLatch + opcodeCycleAdjust); |
| 127 | } |
| 128 | |
| 129 | //----------------------------------------------------------------------------- |
| 130 |