mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-18 17:42:36 -05:00
codec: sid: add cRSID-1.0 for 21st century SID playback
Plain import of the library parts first. Adaptions to Rockbox will follow. A *lot* of kudos go to Mihaly Horvath for creating this library from his already lightweight cSID-light, mainly for Rockbox. Besides a lot of other things, he made his algorithms integer-only and significantly improved the C64 emulation, so finally RSIDs could be played as well as PSIDs. TinySID was nice for what it is, but this is a quantum leap in SID playback quality for Rockbox. Check for example: https://hvsc.csdb.dk/MUSICIANS/P/Page_Jason/Eighth.sid https://hvsc.csdb.dk/MUSICIANS/J/Jeff/Blowing.sid Change-Id: I353e12fbfd7cd8696b834616e55743e7b844a73e
This commit is contained in:
parent
1c26f565bf
commit
e8135fea5a
12 changed files with 2525 additions and 0 deletions
64
lib/rbcodec/codecs/cRSID/C64/VIC.c
Normal file
64
lib/rbcodec/codecs/cRSID/C64/VIC.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
//VIC-II emulation
|
||||
|
||||
|
||||
void cRSID_createVICchip (cRSID_C64instance* C64, cRSID_VICinstance* VIC, unsigned short baseaddress) {
|
||||
VIC->C64 = C64;
|
||||
VIC->ChipModel = 0;
|
||||
VIC->BaseAddress = baseaddress;
|
||||
VIC->BasePtrWR = &C64->IObankWR[baseaddress]; VIC->BasePtrRD = &C64->IObankRD[baseaddress];
|
||||
cRSID_initVICchip (VIC);
|
||||
}
|
||||
|
||||
|
||||
void cRSID_initVICchip (cRSID_VICinstance* VIC) {
|
||||
unsigned char i;
|
||||
for (i=0; i<0x3F; ++i) VIC->BasePtrWR[i] = VIC->BasePtrRD[i] = 0x00;
|
||||
VIC->RowCycleCnt=0;
|
||||
}
|
||||
|
||||
|
||||
static inline char cRSID_emulateVIC (cRSID_VICinstance* VIC, char cycles) {
|
||||
|
||||
unsigned short RasterRow;
|
||||
|
||||
enum VICregisters { CONTROL = 0x11, RASTERROWL = 0x12, INTERRUPT = 0x19, INTERRUPT_ENABLE = 0x1A };
|
||||
|
||||
enum ControlBitVal { RASTERROWMSB = 0x80, DISPLAY_ENABLE = 0x10, ROWS = 0x08, YSCROLL_MASK = 0x07 };
|
||||
|
||||
enum InterruptBitVal { VIC_IRQ = 0x80, RASTERROW_MATCH_IRQ = 0x01 };
|
||||
|
||||
|
||||
VIC->RowCycleCnt += cycles;
|
||||
if (VIC->RowCycleCnt >= VIC->RasterRowCycles) {
|
||||
VIC->RowCycleCnt -= VIC->RasterRowCycles;
|
||||
|
||||
RasterRow = ( (VIC->BasePtrRD[CONTROL]&RASTERROWMSB) << 1 ) + VIC->BasePtrRD[RASTERROWL];
|
||||
++RasterRow; if (RasterRow >= VIC->RasterLines) RasterRow = 0;
|
||||
VIC->BasePtrRD[CONTROL] = ( VIC->BasePtrRD[CONTROL] & ~RASTERROWMSB ) | ((RasterRow&0x100)>>1);
|
||||
VIC->BasePtrRD[RASTERROWL] = RasterRow & 0xFF;
|
||||
|
||||
if (VIC->BasePtrWR[INTERRUPT_ENABLE] & RASTERROW_MATCH_IRQ) {
|
||||
if ( RasterRow == ( (VIC->BasePtrWR[CONTROL]&RASTERROWMSB) << 1 ) + VIC->BasePtrWR[RASTERROWL] ) {
|
||||
VIC->BasePtrRD[INTERRUPT] |= VIC_IRQ | RASTERROW_MATCH_IRQ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return VIC->BasePtrRD[INTERRUPT] & VIC_IRQ;
|
||||
}
|
||||
|
||||
|
||||
static inline void cRSID_acknowledgeVICrasterIRQ (cRSID_VICinstance* VIC) {
|
||||
enum VICregisters { INTERRUPT = 0x19 };
|
||||
enum InterruptBitVal { VIC_IRQ = 0x80, RASTERROW_MATCH_IRQ = 0x01 };
|
||||
//An 1 is to be written into the IRQ-flag (bit0) of $d019 to clear it and deassert IRQ signal
|
||||
//if (VIC->BasePtrWR[INTERRUPT] & RASTERROW_MATCH_IRQ) { //acknowledge raster-interrupt by writing to $d019 bit0?
|
||||
//But oftentimes INC/LSR/etc. RMW commands are used to acknowledge VIC IRQ, they work on real
|
||||
//CPU because it writes the unmodified original value itself to memory before writing the modified there
|
||||
VIC->BasePtrWR[INTERRUPT] &= ~RASTERROW_MATCH_IRQ; //prepare for next acknowledge-detection
|
||||
VIC->BasePtrRD[INTERRUPT] &= ~(VIC_IRQ | RASTERROW_MATCH_IRQ); //remove IRQ flag and state
|
||||
//}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue