diff options
Diffstat (limited to 'lib/rbcodec/codecs/cRSID/C64/VIC.c')
-rw-r--r-- | lib/rbcodec/codecs/cRSID/C64/VIC.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/cRSID/C64/VIC.c b/lib/rbcodec/codecs/cRSID/C64/VIC.c new file mode 100644 index 0000000000..1f9f736bbe --- /dev/null +++ b/lib/rbcodec/codecs/cRSID/C64/VIC.c | |||
@@ -0,0 +1,64 @@ | |||
1 | |||
2 | //VIC-II emulation | ||
3 | |||
4 | |||
5 | void cRSID_createVICchip (cRSID_C64instance* C64, cRSID_VICinstance* VIC, unsigned short baseaddress) { | ||
6 | VIC->C64 = C64; | ||
7 | VIC->ChipModel = 0; | ||
8 | VIC->BaseAddress = baseaddress; | ||
9 | VIC->BasePtrWR = &C64->IObankWR[baseaddress]; VIC->BasePtrRD = &C64->IObankRD[baseaddress]; | ||
10 | cRSID_initVICchip (VIC); | ||
11 | } | ||
12 | |||
13 | |||
14 | void cRSID_initVICchip (cRSID_VICinstance* VIC) { | ||
15 | unsigned char i; | ||
16 | for (i=0; i<0x3F; ++i) VIC->BasePtrWR[i] = VIC->BasePtrRD[i] = 0x00; | ||
17 | VIC->RowCycleCnt=0; | ||
18 | } | ||
19 | |||
20 | |||
21 | static inline char cRSID_emulateVIC (cRSID_VICinstance* VIC, char cycles) { | ||
22 | |||
23 | unsigned short RasterRow; | ||
24 | |||
25 | enum VICregisters { CONTROL = 0x11, RASTERROWL = 0x12, INTERRUPT = 0x19, INTERRUPT_ENABLE = 0x1A }; | ||
26 | |||
27 | enum ControlBitVal { RASTERROWMSB = 0x80, DISPLAY_ENABLE = 0x10, ROWS = 0x08, YSCROLL_MASK = 0x07 }; | ||
28 | |||
29 | enum InterruptBitVal { VIC_IRQ = 0x80, RASTERROW_MATCH_IRQ = 0x01 }; | ||
30 | |||
31 | |||
32 | VIC->RowCycleCnt += cycles; | ||
33 | if (VIC->RowCycleCnt >= VIC->RasterRowCycles) { | ||
34 | VIC->RowCycleCnt -= VIC->RasterRowCycles; | ||
35 | |||
36 | RasterRow = ( (VIC->BasePtrRD[CONTROL]&RASTERROWMSB) << 1 ) + VIC->BasePtrRD[RASTERROWL]; | ||
37 | ++RasterRow; if (RasterRow >= VIC->RasterLines) RasterRow = 0; | ||
38 | VIC->BasePtrRD[CONTROL] = ( VIC->BasePtrRD[CONTROL] & ~RASTERROWMSB ) | ((RasterRow&0x100)>>1); | ||
39 | VIC->BasePtrRD[RASTERROWL] = RasterRow & 0xFF; | ||
40 | |||
41 | if (VIC->BasePtrWR[INTERRUPT_ENABLE] & RASTERROW_MATCH_IRQ) { | ||
42 | if ( RasterRow == ( (VIC->BasePtrWR[CONTROL]&RASTERROWMSB) << 1 ) + VIC->BasePtrWR[RASTERROWL] ) { | ||
43 | VIC->BasePtrRD[INTERRUPT] |= VIC_IRQ | RASTERROW_MATCH_IRQ; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | } | ||
48 | |||
49 | return VIC->BasePtrRD[INTERRUPT] & VIC_IRQ; | ||
50 | } | ||
51 | |||
52 | |||
53 | static inline void cRSID_acknowledgeVICrasterIRQ (cRSID_VICinstance* VIC) { | ||
54 | enum VICregisters { INTERRUPT = 0x19 }; | ||
55 | enum InterruptBitVal { VIC_IRQ = 0x80, RASTERROW_MATCH_IRQ = 0x01 }; | ||
56 | //An 1 is to be written into the IRQ-flag (bit0) of $d019 to clear it and deassert IRQ signal | ||
57 | //if (VIC->BasePtrWR[INTERRUPT] & RASTERROW_MATCH_IRQ) { //acknowledge raster-interrupt by writing to $d019 bit0? | ||
58 | //But oftentimes INC/LSR/etc. RMW commands are used to acknowledge VIC IRQ, they work on real | ||
59 | //CPU because it writes the unmodified original value itself to memory before writing the modified there | ||
60 | VIC->BasePtrWR[INTERRUPT] &= ~RASTERROW_MATCH_IRQ; //prepare for next acknowledge-detection | ||
61 | VIC->BasePtrRD[INTERRUPT] &= ~(VIC_IRQ | RASTERROW_MATCH_IRQ); //remove IRQ flag and state | ||
62 | //} | ||
63 | } | ||
64 | |||