29 #include "sidplayfp/event.h"
30 #include "sidplayfp/component.h"
31 #include "sidplayfp/EventScheduler.h"
48 unsigned int rasterLines;
49 unsigned int cyclesPerLine;
50 event_clock_t (
MOS656X::*clock)();
54 static const char *credit;
59 static const int IRQ_RASTER = 1 << 0;
62 static const int IRQ_LIGHTPEN = 1 << 3;
65 static const unsigned int FIRST_DMA_LINE = 0x30;
68 static const unsigned int LAST_DMA_LINE = 0xf7;
71 event_clock_t (
MOS656X::*clock)();
73 event_clock_t rasterClk;
79 unsigned int cyclesPerLine;
82 unsigned int maxRasters;
85 unsigned int lineCycle;
94 bool areBadLinesEnabled;
100 bool rasterYIRQCondition;
119 uint8_t &sprite_enable, &sprite_y_expansion;
120 uint8_t sprite_exp_flop;
122 uint8_t sprite_mc_base[8];
123 uint8_t sprite_mc[8];
130 event_clock_t clockPAL();
131 event_clock_t clockNTSC();
132 event_clock_t clockOldNTSC();
137 void handleIrqState();
144 void badLineStateChange() { setBA(!isBadLine); }
151 void rasterYIRQEdgeDetector()
153 const bool oldRasterYIRQCondition = rasterYIRQCondition;
154 rasterYIRQCondition = rasterY == readRasterLineIRQ();
155 if (!oldRasterYIRQCondition && rasterYIRQCondition)
156 activateIRQFlag(IRQ_RASTER);
163 void activateIRQFlag(
int flag)
174 unsigned int readRasterLineIRQ()
const
176 return (regs[0x12] & 0xff) + ((regs[0x11] & 0x80) << 1);
184 bool readDEN()
const {
return (regs[0x11] & 0x10) != 0; }
189 inline unsigned int oldRasterY()
191 const int prevRasterY = rasterY - 1;
192 return prevRasterY >= 0 ? prevRasterY : cyclesPerLine - 1;
197 event_context.
cancel(*
this);
204 inline void checkVblank()
207 if (rasterY == (maxRasters - 1))
213 if (rasterY == FIRST_DMA_LINE
214 && !areBadLinesEnabled
217 areBadLinesEnabled =
true;
221 if (rasterY == LAST_DMA_LINE)
223 areBadLinesEnabled =
false;
231 rasterYIRQEdgeDetector();
240 vblanking = lp_triggered =
false;
242 rasterYIRQEdgeDetector();
250 inline void updateMc()
253 for (
unsigned int i=0; i<8; i++, mask<<=1)
255 if (sprite_dma & mask)
256 sprite_mc[i] = (sprite_mc[i] + 3) & 0x3f;
260 inline void updateMcBase()
263 for (
unsigned int i=0; i<8; i++, mask<<=1)
265 if (sprite_exp_flop & mask)
267 sprite_mc_base[i] = sprite_mc[i];
268 if (sprite_mc_base[i] == 0x3f)
277 inline void checkSpriteExp()
279 sprite_exp_flop ^= sprite_dma & sprite_y_expansion;
285 inline void checkSpriteDma()
287 const uint8_t y = rasterY & 0xff;
289 for (
unsigned int i=0; i<8; i++, mask<<=1)
291 if ((sprite_enable & mask) && (y == regs[(i << 1) + 1]) && !(sprite_dma & mask))
294 sprite_mc_base[i] = 0;
295 sprite_exp_flop |= mask;
300 inline void checkSpriteDisplay()
302 for (
unsigned int i=0; i<8; i++)
304 sprite_mc[i] = sprite_mc_base[i];
312 inline void startDma()
314 if (sprite_dma & (0x01 << n))
324 if (!(sprite_dma & (0x06 << n)))
331 inline void startBadline()
342 virtual void interrupt (
bool state) = 0;
343 virtual void setBA (
bool state) = 0;
351 uint8_t
read(uint_least8_t addr);
361 void write(uint_least8_t addr, uint8_t data);
372 const char *credits()
const {
return credit; }
381 inline void MOS656X::startDma<0>()
383 setBA(!(sprite_dma & 0x01));
390 inline void MOS656X::endDma<7>()