33 #include "EventCallback.h"
34 #include "EventScheduler.h"
38 namespace libsidplayfp
58 typedef event_clock_t (
MOS656X::*ClockFunc)();
62 unsigned int rasterLines;
63 unsigned int cyclesPerLine;
68 static const model_data_t modelData[];
71 static const int IRQ_RASTER = 1 << 0;
74 static const int IRQ_LIGHTPEN = 1 << 3;
77 static const unsigned int FIRST_DMA_LINE = 0x30;
80 static const unsigned int LAST_DMA_LINE = 0xf7;
87 event_clock_t rasterClk;
90 EventScheduler &eventScheduler;
93 unsigned int cyclesPerLine;
96 unsigned int maxRasters;
99 unsigned int lineCycle;
102 unsigned int rasterY;
105 unsigned int yscroll;
108 bool areBadLinesEnabled;
114 bool rasterYIRQCondition;
137 EventCallback<MOS656X> badLineStateChangeEvent;
139 EventCallback<MOS656X> rasterYIRQEdgeDetectorEvent;
142 event_clock_t clockPAL();
143 event_clock_t clockNTSC();
144 event_clock_t clockOldNTSC();
149 void handleIrqState();
154 void badLineStateChange() { setBA(!isBadLine); }
159 void rasterYIRQEdgeDetector()
161 const bool oldRasterYIRQCondition = rasterYIRQCondition;
162 rasterYIRQCondition = rasterY == readRasterLineIRQ();
163 if (!oldRasterYIRQCondition && rasterYIRQCondition)
164 activateIRQFlag(IRQ_RASTER);
171 void activateIRQFlag(
int flag)
182 unsigned int readRasterLineIRQ()
const
184 return (regs[0x12] & 0xff) + ((regs[0x11] & 0x80) << 1);
192 bool readDEN()
const {
return (regs[0x11] & 0x10) != 0; }
194 bool evaluateIsBadLine()
const
196 return areBadLinesEnabled
197 && rasterY >= FIRST_DMA_LINE
198 && rasterY <= LAST_DMA_LINE
199 && (rasterY & 7) == yscroll;
205 inline unsigned int oldRasterY()
const
207 return (rasterY > 0 ? rasterY : maxRasters) - 1;
212 eventScheduler.cancel(*
this);
219 inline void checkVblank()
222 if (rasterY == (maxRasters - 1))
228 if (rasterY == FIRST_DMA_LINE
229 && !areBadLinesEnabled
232 areBadLinesEnabled =
true;
236 if (rasterY == LAST_DMA_LINE)
238 areBadLinesEnabled =
false;
246 rasterYIRQEdgeDetector();
249 if (evaluateIsBadLine())
262 rasterYIRQEdgeDetector();
264 if (lpAsserted && lp.retrigger(lineCycle, rasterY))
266 activateIRQFlag(IRQ_LIGHTPEN);
275 inline void startDma()
277 if (sprites.isDma(0x01 << n))
287 if (!sprites.isDma(0x06 << n))
294 inline void startBadline()
301 MOS656X(EventScheduler &scheduler);
305 virtual void interrupt(
bool state) = 0;
306 virtual void setBA(
bool state) = 0;
314 uint8_t
read(uint_least8_t addr);
324 void write(uint_least8_t addr, uint8_t data);
327 void event()
override;
349 static const char *credits();
358 inline void MOS656X::startDma<0>()
360 setBA(!sprites.isDma(0x01));
367 inline void MOS656X::endDma<7>()