summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec/codecs
diff options
context:
space:
mode:
authorWolfram Sang <wsa@the-dreams.de>2022-03-04 18:37:30 +0100
committerSolomon Peachy <pizza@shaftnet.org>2023-02-07 09:19:32 -0500
commite8135fea5a10dba25fefe991bf6bc36f351e2919 (patch)
treea17571dc0c1bc25a824f639be88d461245d62e89 /lib/rbcodec/codecs
parent1c26f565bf0ae50495dc8d2139f76bd367728cd6 (diff)
downloadrockbox-e8135fea5a10dba25fefe991bf6bc36f351e2919.tar.gz
rockbox-e8135fea5a10dba25fefe991bf6bc36f351e2919.zip
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
Diffstat (limited to 'lib/rbcodec/codecs')
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/C64.c197
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/CIA.c93
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/CPU.c423
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/MEM.c132
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/SID.c276
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/SID.h824
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/VIC.c64
-rw-r--r--lib/rbcodec/codecs/cRSID/README.txt39
-rw-r--r--lib/rbcodec/codecs/cRSID/host/audio.c62
-rw-r--r--lib/rbcodec/codecs/cRSID/host/file.c60
-rw-r--r--lib/rbcodec/codecs/cRSID/libcRSID.c134
-rw-r--r--lib/rbcodec/codecs/cRSID/libcRSID.h221
12 files changed, 2525 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/cRSID/C64/C64.c b/lib/rbcodec/codecs/cRSID/C64/C64.c
new file mode 100644
index 0000000000..81dca35542
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/C64/C64.c
@@ -0,0 +1,197 @@
+
+//C64 emulation (SID-playback related)
+
+
+#include "../libcRSID.h"
+
+#include "MEM.c"
+#include "CPU.c"
+#include "CIA.c"
+#include "VIC.c"
+#include "SID.c"
+
+
+cRSID_C64instance* cRSID_createC64 (cRSID_C64instance* C64, unsigned short samplerate) { //init a basic PAL C64 instance
+ if(samplerate) C64->SampleRate = samplerate;
+ else C64->SampleRate = samplerate = 44100;
+ C64->SampleClockRatio = (985248<<4)/samplerate; //shifting (multiplication) enhances SampleClockRatio precision
+ C64->Attenuation = 26;
+ C64->CPU.C64 = C64;
+ cRSID_createSIDchip ( C64, &C64->SID[1], 8580, 0xD400 ); //default C64 setup with only 1 SID and 2 CIAs and 1 VIC
+ cRSID_createCIAchip ( C64, &C64->CIA[1], 0xDC00 );
+ cRSID_createCIAchip ( C64, &C64->CIA[2], 0xDD00 );
+ cRSID_createVICchip ( C64, &C64->VIC, 0xD000 );
+ //if(C64->RealSIDmode) {
+ cRSID_setROMcontent ( C64 );
+ //}
+ cRSID_initC64(C64);
+ return C64;
+}
+
+
+void cRSID_setC64 (cRSID_C64instance* C64) { //set hardware-parameters (Models, SIDs) for playback of loaded SID-tune
+ enum C64clocks { C64_PAL_CPUCLK=985248, C64_NTSC_CPUCLK=1022727 };
+ enum C64scanlines { C64_PAL_SCANLINES = 312, C64_NTSC_SCANLINES = 263 };
+ enum C64scanlineCycles { C64_PAL_SCANLINE_CYCLES = 63, C64_NTSC_SCANLINE_CYCLES = 65 };
+ //enum C64framerates { PAL_FRAMERATE = 50, NTSC_FRAMERATE = 60 }; //Hz
+
+ static const unsigned int CPUspeeds[] = { C64_NTSC_CPUCLK, C64_PAL_CPUCLK };
+ static const unsigned short ScanLines[] = { C64_NTSC_SCANLINES, C64_PAL_SCANLINES };
+ static const unsigned char ScanLineCycles[] = { C64_NTSC_SCANLINE_CYCLES, C64_PAL_SCANLINE_CYCLES };
+ //unsigned char FrameRates[] = { NTSC_FRAMERATE, PAL_FRAMERATE };
+
+ static const short Attenuations[]={0,26,43,137}; //increase for 2SID (to 43) and 3SID (to 137)
+ short SIDmodel;
+ unsigned char SIDchipCount;
+
+
+ C64->VideoStandard = ( (C64->SIDheader->ModelFormatStandard & 0x0C) >> 2 ) != 2;
+ if (C64->SampleRate==0) C64->SampleRate = 44100;
+ C64->CPUfrequency = CPUspeeds[C64->VideoStandard];
+ C64->SampleClockRatio = ( C64->CPUfrequency << 4 ) / C64->SampleRate; //shifting (multiplication) enhances SampleClockRatio precision
+
+ C64->VIC.RasterLines = ScanLines[C64->VideoStandard];
+ C64->VIC.RasterRowCycles = ScanLineCycles[C64->VideoStandard];
+ C64->FrameCycles = C64->VIC.RasterLines * C64->VIC.RasterRowCycles; ///C64->SampleRate / PAL_FRAMERATE; //1x speed tune with VIC Vertical-blank timing
+
+ C64->PrevRasterLine=-1; //so if $d012 is set once only don't disturb FrameCycleCnt
+
+ C64->SID[1].ChipModel = (C64->SIDheader->ModelFormatStandard&0x30) >= 0x20? 8580:6581;
+
+ SIDmodel = C64->SIDheader->ModelFormatStandard & 0xC0;
+ if (SIDmodel) SIDmodel = (SIDmodel >= 0x80) ? 8580:6581; else SIDmodel = C64->SID[1].ChipModel;
+ cRSID_createSIDchip ( C64, &C64->SID[2], SIDmodel, 0xD000 + C64->SIDheader->SID2baseAddress*16 );
+
+ SIDmodel = C64->SIDheader->ModelFormatStandardH & 0x03;
+ if (SIDmodel) SIDmodel = (SIDmodel >= 0x02) ? 8580:6581; else SIDmodel = C64->SID[1].ChipModel;
+ cRSID_createSIDchip ( C64, &C64->SID[3], SIDmodel, 0xD000 + C64->SIDheader->SID3baseAddress*16 );
+
+ SIDchipCount = 1 + (C64->SID[2].BaseAddress > 0) + (C64->SID[3].BaseAddress > 0);
+ C64->Attenuation = Attenuations[SIDchipCount];
+}
+
+
+void cRSID_initC64 (cRSID_C64instance* C64) { //C64 Reset
+ cRSID_initSIDchip( &C64->SID[1] );
+ cRSID_initCIAchip( &C64->CIA[1] ); cRSID_initCIAchip( &C64->CIA[2] );
+ cRSID_initMem(C64);
+ cRSID_initCPU( &C64->CPU, (cRSID_readMemC64(C64,0xFFFD)<<8) + cRSID_readMemC64(C64,0xFFFC) );
+ C64->IRQ = C64->NMI = 0;
+}
+
+
+int cRSID_emulateC64 (cRSID_C64instance *C64) {
+ static unsigned char InstructionCycles;
+ static int Output;
+
+
+ //Cycle-based part of emulations:
+
+
+ while (C64->SampleCycleCnt <= C64->SampleClockRatio) {
+
+ if (!C64->RealSIDmode) {
+ if (C64->FrameCycleCnt >= C64->FrameCycles) {
+ C64->FrameCycleCnt -= C64->FrameCycles;
+ if (C64->Finished) { //some tunes (e.g. Barbarian, A-Maze-Ing) doesn't always finish in 1 frame
+ cRSID_initCPU ( &C64->CPU, C64->PlayAddress ); //(PSID docs say bank-register should always be set for each call's region)
+ C64->Finished=0; //C64->SampleCycleCnt=0; //PSID workaround for some tunes (e.g. Galdrumway):
+ if (C64->TimerSource==0) C64->IObankRD[0xD019] = 0x81; //always simulate to player-calls that VIC-IRQ happened
+ else C64->IObankRD[0xDC0D] = 0x83; //always simulate to player-calls that CIA TIMERA/TIMERB-IRQ happened
+ }}
+ if (C64->Finished==0) {
+ if ( (InstructionCycles = cRSID_emulateCPU()) >= 0xFE ) { InstructionCycles=6; C64->Finished=1; }
+ }
+ else InstructionCycles=7; //idle between player-calls
+ C64->FrameCycleCnt += InstructionCycles;
+ C64->IObankRD[0xDC04] += InstructionCycles; //very simple CIA1 TimerA simulation for PSID (e.g. Delta-Mix_E-Load_loader)
+ }
+
+ else { //RealSID emulations:
+ if ( cRSID_handleCPUinterrupts(&C64->CPU) ) { C64->Finished=0; InstructionCycles=7; }
+ else if (C64->Finished==0) {
+ if ( (InstructionCycles = cRSID_emulateCPU()) >= 0xFE ) {
+ InstructionCycles=6; C64->Finished=1;
+ }
+ }
+ else InstructionCycles=7; //idle between IRQ-calls
+ C64->IRQ = C64->NMI = 0; //prepare for collecting IRQ sources
+ C64->IRQ |= cRSID_emulateCIA (&C64->CIA[1], InstructionCycles);
+ C64->NMI |= cRSID_emulateCIA (&C64->CIA[2], InstructionCycles);
+ C64->IRQ |= cRSID_emulateVIC (&C64->VIC, InstructionCycles);
+ }
+
+ C64->SampleCycleCnt += (InstructionCycles<<4);
+
+ cRSID_emulateADSRs (&C64->SID[1], InstructionCycles);
+ if ( C64->SID[2].BaseAddress != 0 ) cRSID_emulateADSRs (&C64->SID[2], InstructionCycles);
+ if ( C64->SID[3].BaseAddress != 0 ) cRSID_emulateADSRs (&C64->SID[3], InstructionCycles);
+
+ }
+ C64->SampleCycleCnt -= C64->SampleClockRatio;
+
+
+ //Samplerate-based part of emulations:
+
+
+ if (!C64->RealSIDmode) { //some PSID tunes use CIA TOD-clock (e.g. Kawasaki Synthesizer Demo)
+ --C64->TenthSecondCnt;
+ if (C64->TenthSecondCnt <= 0) {
+ C64->TenthSecondCnt = C64->SampleRate / 10;
+ ++(C64->IObankRD[0xDC08]);
+ if(C64->IObankRD[0xDC08]>=10) {
+ C64->IObankRD[0xDC08]=0; ++(C64->IObankRD[0xDC09]);
+ //if(C64->IObankRD[0xDC09]%
+ }
+ }
+ }
+
+ Output = cRSID_emulateWaves (&C64->SID[1]);
+ if ( C64->SID[2].BaseAddress != 0 ) Output += cRSID_emulateWaves (&C64->SID[2]);
+ if ( C64->SID[3].BaseAddress != 0 ) Output += cRSID_emulateWaves (&C64->SID[3]);
+
+ return Output;
+}
+
+
+static inline short cRSID_playPSIDdigi(cRSID_C64instance* C64) {
+ enum PSIDdigiSpecs { DIGI_VOLUME = 1200 }; //80 };
+ static unsigned char PlaybackEnabled=0, NybbleCounter=0, RepeatCounter=0, Shifts;
+ static unsigned short SampleAddress, RatePeriod;
+ static short Output=0;
+ static int PeriodCounter;
+
+ if (C64->IObankWR[0xD41D]) {
+ PlaybackEnabled = (C64->IObankWR[0xD41D] >= 0xFE);
+ PeriodCounter = 0; NybbleCounter = 0;
+ SampleAddress = C64->IObankWR[0xD41E] + (C64->IObankWR[0xD41F]<<8);
+ RepeatCounter = C64->IObankWR[0xD43F];
+ }
+ C64->IObankWR[0xD41D] = 0;
+
+ if (PlaybackEnabled) {
+ RatePeriod = C64->IObankWR[0xD45D] + (C64->IObankWR[0xD45E]<<8);
+ if (RatePeriod) PeriodCounter += C64->CPUfrequency / RatePeriod;
+ if ( PeriodCounter >= C64->SampleRate ) {
+ PeriodCounter -= C64->SampleRate;
+
+ if ( SampleAddress < C64->IObankWR[0xD43D] + (C64->IObankWR[0xD43E]<<8) ) {
+ if (NybbleCounter) {
+ Shifts = C64->IObankWR[0xD47D] ? 4:0;
+ ++SampleAddress;
+ }
+ else Shifts = C64->IObankWR[0xD47D] ? 0:4;
+ Output = ( ( (C64->RAMbank[SampleAddress]>>Shifts) & 0xF) - 8 ) * DIGI_VOLUME; //* (C64->IObankWR[0xD418]&0xF);
+ NybbleCounter^=1;
+ }
+ else if (RepeatCounter) {
+ SampleAddress = C64->IObankWR[0xD47F] + (C64->IObankWR[0xD47E]<<8);
+ RepeatCounter--;
+ }
+
+ }
+ }
+
+ return Output;
+}
+
diff --git a/lib/rbcodec/codecs/cRSID/C64/CIA.c b/lib/rbcodec/codecs/cRSID/C64/CIA.c
new file mode 100644
index 0000000000..b562417480
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/C64/CIA.c
@@ -0,0 +1,93 @@
+
+//cRSID CIA emulation
+
+
+void cRSID_createCIAchip (cRSID_C64instance* C64, cRSID_CIAinstance* CIA, unsigned short baseaddress) {
+ CIA->C64 = C64;
+ CIA->ChipModel = 0;
+ CIA->BaseAddress = baseaddress;
+ CIA->BasePtrWR = &C64->IObankWR[baseaddress]; CIA->BasePtrRD = &C64->IObankRD[baseaddress];
+ cRSID_initCIAchip(CIA);
+}
+
+
+void cRSID_initCIAchip (cRSID_CIAinstance* CIA) {
+ unsigned char i;
+ for (i=0; i<0x10; ++i) CIA->BasePtrWR[i] = CIA->BasePtrRD[i] = 0x00;
+}
+
+
+static inline char cRSID_emulateCIA (cRSID_CIAinstance* CIA, char cycles) {
+ static int Tmp;
+
+ enum CIAregisters { PORTA=0, PORTB=1, DDRA=2, DDRB=3,
+ TIMERAL=4, TIMERAH=5, TIMERBL=6, TIMERBH=7, //Write:Set Timer-latch, Read: read Timer
+ TOD_TENTHSECONDS=8, TOD_SECONDS=9, TOD_MINUTES=0xA, TOD_HOURS=0xB,
+ SERIAL_DATA=0xC, INTERRUPTS=0xD, CONTROLA=0xE, CONTROLB=0xF };
+
+ enum InterruptBitVal { INTERRUPT_HAPPENED=0x80, SET_OR_CLEAR_FLAGS=0x80, //(Read or Write operation determines which one:)
+ FLAGn=0x10, SERIALPORT=0x08, ALARM=0x04, TIMERB=0x02, TIMERA=0x01 }; //flags/masks of interrupt-sources
+
+ enum ControlAbitVal { ENABLE_TIMERA=0x01, PORTB6_TIMERA=0x02, TOGGLED_PORTB6=0x04, ONESHOT_TIMERA=0x08,
+ FORCELOADA_STROBE=0x10, TIMERA_FROM_CNT=0x20, SERIALPORT_IS_OUTPUT=0x40, TIMEOFDAY_50Hz=0x80 };
+
+ enum ControlBbitVal { ENABLE_TIMERB=0x01, PORTB7_TIMERB=0x02, TOGGLED_PORTB7=0x04, ONESHOT_TIMERB=0x08,
+ FORCELOADB_STROBE=0x10, TIMERB_FROM_CPUCLK=0x00, TIMERB_FROM_CNT=0x20, TIMERB_FROM_TIMERA=0x40,
+ TIMERB_FROM_TIMERA_AND_CNT = 0x60, TIMEOFDAY_WRITE_SETS_ALARM = 0x80 };
+
+ //TimerA
+ if (CIA->BasePtrWR[CONTROLA] & FORCELOADA_STROBE) { //force latch into counter (strobe-input)
+ CIA->BasePtrRD[TIMERAH] = CIA->BasePtrWR[TIMERAH]; CIA->BasePtrRD[TIMERAL] = CIA->BasePtrWR[TIMERAL];
+ }
+ else if ( (CIA->BasePtrWR[CONTROLA] & (ENABLE_TIMERA|TIMERA_FROM_CNT)) == ENABLE_TIMERA ) { //Enabled, counts Phi2
+ Tmp = ( (CIA->BasePtrRD[TIMERAH]<<8) + CIA->BasePtrRD[TIMERAL] ) - cycles; //count timer
+ if (Tmp <= 0) { //Timer counted down
+ Tmp += (CIA->BasePtrWR[TIMERAH]<<8) + CIA->BasePtrWR[TIMERAL]; //reload timer
+ if (CIA->BasePtrWR[CONTROLA] & ONESHOT_TIMERA) CIA->BasePtrWR[CONTROLA] &= ~ENABLE_TIMERA; //disable if one-shot
+ CIA->BasePtrRD[INTERRUPTS] |= TIMERA;
+ if (CIA->BasePtrWR[INTERRUPTS] & TIMERA) { //generate interrupt if mask allows
+ CIA->BasePtrRD[INTERRUPTS] |= INTERRUPT_HAPPENED;
+ }
+ }
+ CIA->BasePtrRD[TIMERAH] = (Tmp >> 8); CIA->BasePtrRD[TIMERAL] = Tmp & 0xFF;
+ }
+ CIA->BasePtrWR[CONTROLA] &= ~FORCELOADA_STROBE; //strobe is edge-sensitive
+ CIA->BasePtrRD[CONTROLA] = CIA->BasePtrWR[CONTROLA]; //control-registers are readable
+
+ //TimerB
+ if (CIA->BasePtrWR[CONTROLB] & FORCELOADB_STROBE) { //force latch into counter (strobe-input)
+ CIA->BasePtrRD[TIMERBH] = CIA->BasePtrWR[TIMERBH]; CIA->BasePtrRD[TIMERBL] = CIA->BasePtrWR[TIMERBL];
+ } //what about clocking TimerB by TimerA? (maybe not used in any music)
+ else if ( (CIA->BasePtrWR[CONTROLB] & (ENABLE_TIMERB|TIMERB_FROM_TIMERA)) == ENABLE_TIMERB ) { //Enabled, counts Phi2
+ Tmp = ( (CIA->BasePtrRD[TIMERBH]<<8) + CIA->BasePtrRD[TIMERBL] ) - cycles;//count timer
+ if (Tmp <= 0) { //Timer counted down
+ Tmp += (CIA->BasePtrWR[TIMERBH]<<8) + CIA->BasePtrWR[TIMERBL]; //reload timer
+ if (CIA->BasePtrWR[CONTROLB] & ONESHOT_TIMERB) CIA->BasePtrWR[CONTROLB] &= ~ENABLE_TIMERB; //disable if one-shot
+ CIA->BasePtrRD[INTERRUPTS] |= TIMERB;
+ if (CIA->BasePtrWR[INTERRUPTS] & TIMERB) { //generate interrupt if mask allows
+ CIA->BasePtrRD[INTERRUPTS] |= INTERRUPT_HAPPENED;
+ }
+ }
+ CIA->BasePtrRD[TIMERBH] = (Tmp >> 8); CIA->BasePtrRD[TIMERBL] = Tmp & 0xFF;
+ }
+ CIA->BasePtrWR[CONTROLB] &= ~FORCELOADB_STROBE; //strobe is edge-sensitive
+ CIA->BasePtrRD[CONTROLB] = CIA->BasePtrWR[CONTROLB]; //control-registers are readable
+
+ return (CIA->BasePtrRD[INTERRUPTS] & INTERRUPT_HAPPENED);
+}
+
+
+static inline void cRSID_writeCIAIRQmask (cRSID_CIAinstance* CIA, unsigned char value) {
+ if (value&0x80) CIA->BasePtrWR[0xD] |= (value&0x1F);
+ else CIA->BasePtrWR[0xD] &= ~(value&0x1F);
+}
+
+
+static inline void cRSID_acknowledgeCIAIRQ (cRSID_CIAinstance* CIA) {
+ CIA->BasePtrRD[0xD] = 0x00; //reading a CIA interrupt-register clears its read-part and IRQ-flag
+}
+
+
+//static inline void cRSID_writeCIARWreg () {
+ //mirroring write-latch to read-latch for Readable-Writeable registers?
+//}
diff --git a/lib/rbcodec/codecs/cRSID/C64/CPU.c b/lib/rbcodec/codecs/cRSID/C64/CPU.c
new file mode 100644
index 0000000000..692e666f8a
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/C64/CPU.c
@@ -0,0 +1,423 @@
+
+//cRSID CPU-emulation
+
+
+void cRSID_initCPU (cRSID_CPUinstance* CPU, unsigned short mempos) {
+ CPU->PC = mempos; CPU->A = 0; CPU->X = 0; CPU->Y = 0; CPU->ST = 0x04; CPU->SP = 0xFF; CPU->PrevNMI = 0;
+}
+
+
+unsigned char cRSID_emulateCPU (void) { //the CPU emulation for SID/PRG playback (ToDo: CIA/VIC-IRQ/NMI/RESET vectors, BCD-mode)
+
+ enum StatusFlagBitValues { N=0x80, V=0x40, B=0x10, D=0x08, I=0x04, Z=0x02, C=0x01 };
+
+ static const unsigned char FlagSwitches[]={0x01,0x21,0x04,0x24,0x00,0x40,0x08,0x28}, BranchFlags[]={0x80,0x40,0x01,0x02};
+
+
+ static cRSID_C64instance* const C64 = &cRSID_C64; //could be a parameter but function-call is faster this way if only 1 main CPU exists
+ static cRSID_CPUinstance* const CPU = &C64->CPU;
+
+ static char Cycles, SamePage;
+ static unsigned char IR, ST, X, Y;
+ static short int A, SP, T;
+ static unsigned int PC, Addr, PrevPC;
+
+
+ inline void loadReg (void) { PC = CPU->PC; SP = CPU->SP; ST = CPU->ST; A = CPU->A; X = CPU->X; Y = CPU->Y; }
+ inline void storeReg (void) { CPU->PC = PC; CPU->SP = SP; CPU->ST = ST; CPU->A = A; CPU->X = X; CPU->Y = Y; }
+
+ inline unsigned char rd (register unsigned short address) {
+ static unsigned char value;
+ value = *cRSID_getMemReadPtr(address);
+ if (C64->RealSIDmode) {
+ if ( C64->RAMbank[1] & 3 ) {
+ if (address==0xDC0D) { cRSID_acknowledgeCIAIRQ( &C64->CIA[1] ); }
+ else if (address==0xDD0D) { cRSID_acknowledgeCIAIRQ( &C64->CIA[2] ); }
+ }
+ }
+ return value;
+ }
+
+ inline void wr (register unsigned short address, register unsigned char data) {
+ *cRSID_getMemWritePtr(address)=data;
+ if ( C64->RealSIDmode && (C64->RAMbank[1] & 3) ) {
+ //if(data&1) { //only writing 1 to $d019 bit0 would acknowledge, not any value (but RMW instructions write $d019 back before mod.)
+ if (address==0xD019) { cRSID_acknowledgeVICrasterIRQ( &C64->VIC ); }
+ //}
+ }
+ }
+
+ inline void wr2 (register unsigned short address, register unsigned char data) { //PSID-hack specific memory-write
+ static int Tmp;
+ *cRSID_getMemWritePtr(address)=data;
+ if ( C64->RAMbank[1] & 3 ) {
+ if (C64->RealSIDmode) {
+ if (address==0xDC0D) cRSID_writeCIAIRQmask( &C64->CIA[1], data );
+ else if (address==0xDD0D) cRSID_writeCIAIRQmask( &C64->CIA[2], data );
+ else if (address==0xDD0C) C64->IObankRD[address]=data; //mirror WR to RD (e.g. Wonderland_XIII_tune_1.sid)
+ //#ifdef CRSID_PLATFORM_PC //just for info displayer
+ // else if (address==0xDC05 || address==0xDC04) C64->FrameCycles = ( (C64->IObankWR[0xDC04] + (C64->IObankWR[0xDC05]<<8)) );
+ //#endif
+ else if(address==0xD019 && data&1) { //only writing 1 to $d019 bit0 would acknowledge
+ cRSID_acknowledgeVICrasterIRQ( &C64->VIC );
+ }
+ }
+
+ else {
+ switch (address) {
+ case 0xDC05: case 0xDC04:
+ if (C64->TimerSource ) { //dynamic CIA-setting (Galway/Rubicon workaround)
+ C64->FrameCycles = ( (C64->IObankWR[0xDC04] + (C64->IObankWR[0xDC05]<<8)) ); //<< 4) / C64->SampleClockRatio;
+ }
+ break;
+ case 0xDC08: C64->IObankRD[0xDC08] = data; break; //refresh TOD-clock
+ case 0xDC09: C64->IObankRD[0xDC09] = data; break; //refresh TOD-clock
+ case 0xD012: //dynamic VIC IRQ-rasterline setting (Microprose Soccer V1 workaround)
+ if (C64->PrevRasterLine>=0) { //was $d012 set before? (or set only once?)
+ if (C64->IObankWR[0xD012] != C64->PrevRasterLine) {
+ Tmp = C64->IObankWR[0xD012] - C64->PrevRasterLine;
+ if (Tmp<0) Tmp += C64->VIC.RasterLines;
+ C64->FrameCycleCnt = C64->FrameCycles - Tmp * C64->VIC.RasterRowCycles;
+ }
+ }
+ C64->PrevRasterLine = C64->IObankWR[0xD012];
+ break;
+ }
+ }
+
+ }
+ }
+
+
+ inline void addrModeImmediate (void) { ++PC; Addr=PC; Cycles=2; } //imm.
+ inline void addrModeZeropage (void) { ++PC; Addr=rd(PC); Cycles=3; } //zp
+ inline void addrModeAbsolute (void) { ++PC; Addr = rd(PC); ++PC; Addr += rd(PC)<<8; Cycles=4; } //abs
+ inline void addrModeZeropageXindexed (void) { ++PC; Addr = (rd(PC) + X) & 0xFF; Cycles=4; } //zp,x (with zeropage-wraparound of 6502)
+ inline void addrModeZeropageYindexed (void) { ++PC; Addr = (rd(PC) + Y) & 0xFF; Cycles=4; } //zp,y (with zeropage-wraparound of 6502)
+
+ inline void addrModeXindexed (void) { // abs,x (only STA is 5 cycles, others are 4 if page not crossed, RMW:7)
+ ++PC; Addr = rd(PC) + X; ++PC; SamePage = (Addr <= 0xFF); Addr += rd(PC)<<8; Cycles=5;
+ }
+
+ inline void addrModeYindexed (void) { // abs,y (only STA is 5 cycles, others are 4 if page not crossed, RMW:7)
+ ++PC; Addr = rd(PC) + Y; ++PC; SamePage = (Addr <= 0xFF); Addr += rd(PC)<<8; Cycles=5;
+ }
+
+ inline void addrModeIndirectYindexed (void) { // (zp),y (only STA is 6 cycles, others are 5 if page not crossed, RMW:8)
+ ++PC; Addr = rd(rd(PC)) + Y; SamePage = (Addr <= 0xFF); Addr += rd( (rd(PC)+1)&0xFF ) << 8; Cycles=6;
+ }
+
+ inline void addrModeXindexedIndirect (void) { // (zp,x)
+ ++PC; Addr = ( rd(rd(PC)+X)&0xFF ) + ( ( rd(rd(PC)+X+1)&0xFF ) << 8 ); Cycles=6;
+ }
+
+
+ inline void clrC (void) { ST &= ~C; } //clear Carry-flag
+ inline void setC (unsigned char expr) { ST &= ~C; ST |= (expr!=0); } //set Carry-flag if expression is not zero
+ inline void clrNZC (void) { ST &= ~(N|Z|C); } //clear flags
+ inline void clrNVZC (void) { ST &= ~(N|V|Z|C); } //clear flags
+ inline void setNZbyA (void) { ST &= ~(N|Z); ST |= ((!A)<<1) | (A&N); } //set Negative-flag and Zero-flag based on result in Accumulator
+ inline void setNZbyT (void) { T&=0xFF; ST &= ~(N|Z); ST |= ((!T)<<1) | (T&N); }
+ inline void setNZbyX (void) { ST &= ~(N|Z); ST |= ((!X)<<1) | (X&N); } //set Negative-flag and Zero-flag based on result in X-register
+ inline void setNZbyY (void) { ST &= ~(N|Z); ST |= ((!Y)<<1) | (Y&N); } //set Negative-flag and Zero-flag based on result in Y-register
+ inline void setNZbyM (void) { ST &= ~(N|Z); ST |= ((!rd(Addr))<<1) | (rd(Addr)&N); } //set Negative-flag and Zero-flag based on result at Memory-Address
+ inline void setNZCbyAdd (void) { ST &= ~(N|Z|C); ST |= (A&N)|(A>255); A&=0xFF; ST|=(!A)<<1; } //after increase/addition
+ inline void setVbyAdd (unsigned char M) { ST &= ~V; ST |= ( (~(T^M)) & (T^A) & N ) >> 1; } //calculate V-flag from A and T (previous A) and input2 (Memory)
+ inline void setNZCbySub (signed short* obj) { ST &= ~(N|Z|C); ST |= (*obj&N) | (*obj>=0); *obj&=0xFF; ST |= ((!(*obj))<<1); }
+
+ inline void push (unsigned char value) { C64->RAMbank[0x100+SP] = value; --SP; SP&=0xFF; } //push a value to stack
+ inline unsigned char pop (void) { ++SP; SP&=0xFF; return C64->RAMbank[0x100+SP]; } //pop a value from stack
+
+
+ loadReg(); PrevPC=PC;
+ IR = rd(PC); Cycles=2; SamePage=0; //'Cycles': ensure smallest 6510 runtime (for implied/register instructions)
+
+
+ if(IR&1) { //nybble2: 1/5/9/D:accu.instructions, 3/7/B/F:illegal opcodes
+
+ switch ( (IR & 0x1F) >> 1 ) { //value-forming to cause jump-table //PC wraparound not handled inside to save codespace
+ case 0: case 1: addrModeXindexedIndirect(); break; //(zp,x)
+ case 2: case 3: addrModeZeropage(); break;
+ case 4: case 5: addrModeImmediate(); break;
+ case 6: case 7: addrModeAbsolute(); break;
+ case 8: case 9: addrModeIndirectYindexed(); break; //(zp),y (5..6 cycles, 8 for R-M-W)
+ case 0xA: addrModeZeropageXindexed(); break; //zp,x
+ case 0xB: if ((IR&0xC0)!=0x80) addrModeZeropageXindexed(); //zp,x for illegal opcodes
+ else addrModeZeropageYindexed(); //zp,y for LAX/SAX illegal opcodes
+ break;
+ case 0xC: case 0xD: addrModeYindexed(); break;
+ case 0xE: addrModeXindexed(); break;
+ case 0xF: if ((IR&0xC0)!=0x80) addrModeXindexed(); //abs,x for illegal opcodes
+ else addrModeYindexed(); //abs,y for LAX/SAX illegal opcodes
+ break;
+ }
+ Addr&=0xFFFF;
+
+ switch ( (IR & 0xE0) >> 5 ) { //value-forming to cause gapless case-values and faster jump-table creation from switch-case
+
+ case 0: if ( (IR&0x1F) != 0xB ) { //ORA / SLO(ASO)=ASL+ORA
+ if ( (IR&3) == 3 ) { clrNZC(); setC(rd(Addr)>=N); wr( Addr, rd(Addr)<<1 ); Cycles+=2; } //for SLO
+ else Cycles -= SamePage;
+ A |= rd(Addr); setNZbyA(); //ORA
+ }
+ else { A&=rd(Addr); setNZbyA(); setC(A>=N); } //ANC (AND+Carry=bit7)
+ break;
+
+ case 1: if ( (IR&0x1F) != 0xB ) { //AND / RLA (ROL+AND)
+ if ( (IR&3) == 3 ) { //for RLA
+ T = (rd(Addr)<<1) + (ST&C); clrNZC(); setC(T>255); T&=0xFF; wr(Addr,T); Cycles+=2;
+ }
+ else Cycles -= SamePage;
+ A &= rd(Addr); setNZbyA(); //AND
+ }
+ else { A&=rd(Addr); setNZbyA(); setC(A>=N); } //ANC (AND+Carry=bit7)
+ break;
+
+ case 2: if ( (IR&0x1F) != 0xB ) { //EOR / SRE(LSE)=LSR+EOR
+ if ( (IR&3) == 3 ) { clrNZC(); setC(rd(Addr)&1); wr(Addr,rd(Addr)>>1); Cycles+=2; } //for SRE
+ else Cycles -= SamePage;
+ A ^= rd(Addr); setNZbyA(); //EOR
+ }
+ else { A&=rd(Addr); setC(A&1); A>>=1; A&=0xFF; setNZbyA(); } //ALR(ASR)=(AND+LSR)
+ break;
+
+ case 3: if ( (IR&0x1F) != 0xB ) { //RRA (ROR+ADC) / ADC
+ if( (IR&3) == 3 ) { //for RRA
+ T = (rd(Addr)>>1) + ((ST&C)<<7); clrNZC(); setC(T&1); wr(Addr,T); Cycles+=2;
+ }
+ else Cycles -= SamePage;
+ T=A; A += rd(Addr)+(ST&C); setNZCbyAdd(); setVbyAdd(rd(Addr)); //ADC
+ }
+ else { // ARR (AND+ROR, bit0 not going to C, but C and bit7 get exchanged.)
+ A &= rd(Addr); T += rd(Addr) + (ST&C);
+ clrNVZC(); setC(T>255); setVbyAdd(rd(Addr)); //V-flag set by intermediate ADC mechanism: (A&mem)+mem
+ T=A; A = (A>>1) + ((ST&C)<<7); setC(T>=N); setNZbyA();
+ }
+ break;
+
+ case 4: if ( (IR&0x1F) == 0xB ) { A = X & rd(Addr); setNZbyA(); } //XAA (TXA+AND), highly unstable on real 6502!
+ else if ( (IR&0x1F) == 0x1B ) { SP = A&X; wr( Addr, SP&((Addr>>8)+1) ); } //TAS(SHS) (SP=A&X, mem=S&H} - unstable on real 6502
+ else { wr2( Addr, A & (((IR&3)==3)? X:0xFF) ); } //STA / SAX (at times same as AHX/SHX/SHY) (illegal)
+ break;
+
+ case 5: if ( (IR&0x1F) != 0x1B ) { A=rd(Addr); if((IR&3)==3) X=A; } //LDA / LAX (illegal, used by my 1 rasterline player) (LAX #imm is unstable on C64)
+ else { A=X=SP = rd(Addr) & SP; } //LAS(LAR)
+ setNZbyA(); Cycles -= SamePage;
+ break;
+
+ case 6: if( (IR&0x1F) != 0xB ) { // CMP / DCP(DEC+CMP)
+ if ( (IR&3) == 3 ) { wr(Addr,rd(Addr)-1); Cycles+=2;} //DCP
+ else Cycles -= SamePage;
+ T = A-rd(Addr);
+ }
+ else { X = T = (A&X) - rd(Addr); } //SBX(AXS) //SBX (AXS) (CMP+DEX at the same time)
+ setNZCbySub(&T);
+ break;
+
+ case 7: if( (IR&3)==3 && (IR&0x1F)!=0xB ) { wr( Addr, rd(Addr)+1 ); Cycles+=2; } //ISC(ISB)=INC+SBC / SBC
+ else Cycles -= SamePage;
+ T=A; A -= rd(Addr) + !(ST&C);
+ setNZCbySub(&A); setVbyAdd(~rd(Addr));
+ break;
+ }
+ }
+
+
+ else if (IR&2) { //nybble2: 2:illegal/LDX, 6:A/X/INC/DEC, A:Accu-shift/reg.transfer/NOP, E:shift/X/INC/DEC
+
+ switch (IR & 0x1F) { //Addressing modes
+ case 2: addrModeImmediate(); break;
+ case 6: addrModeZeropage(); break;
+ case 0xE: addrModeAbsolute(); break;
+ case 0x16: if ( (IR&0xC0) != 0x80 ) addrModeZeropageXindexed(); //zp,x
+ else addrModeZeropageYindexed(); //zp,y
+ break;
+ case 0x1E: if ( (IR&0xC0) != 0x80 ) addrModeXindexed(); //abs,x
+ else addrModeYindexed(); //abs,y
+ break;
+ }
+ Addr&=0xFFFF;
+
+ switch ( (IR & 0xE0) >> 5 ) {
+
+ case 0: clrC(); case 1:
+ if((IR&0xF)==0xA) { A = (A<<1) + (ST&C); setNZCbyAdd(); } //ASL/ROL (Accu)
+ else { T = (rd(Addr)<<1) + (ST&C); setC(T>255); setNZbyT(); wr(Addr,T); Cycles+=2; } //RMW (Read-Write-Modify)
+ break;
+
+ case 2: clrC(); case 3:
+ if((IR&0xF)==0xA) { T=A; A=(A>>1)+((ST&C)<<7); setC(T&1); A&=0xFF; setNZbyA(); } //LSR/ROR (Accu)
+ else { T = (rd(Addr)>>1) + ((ST&C)<<7); setC(rd(Addr)&1); setNZbyT(); wr(Addr,T); Cycles+=2; } //memory (RMW)
+ break;
+
+ case 4: if (IR&4) {wr2(Addr,X);} //STX
+ else if(IR&0x10) SP=X; //TXS
+ else { A=X; setNZbyA(); } //TXA
+ break;
+
+ case 5: if ( (IR&0xF) != 0xA ) { X=rd(Addr); Cycles -= SamePage; } //LDX
+ else if (IR & 0x10) X=SP; //TSX
+ else X=A; //TAX
+ setNZbyX();
+ break;
+
+ case 6: if (IR&4) { wr(Addr,rd(Addr)-1); setNZbyM(); Cycles+=2; } //DEC
+ else { --X; setNZbyX(); } //DEX
+ break;
+
+ case 7: if (IR&4) { wr(Addr,rd(Addr)+1); setNZbyM(); Cycles+=2; } //INC/NOP
+ break;
+ }
+ }
+
+
+ else if ( (IR & 0xC) == 8 ) { //nybble2: 8:register/statusflag
+ if ( IR&0x10 ) {
+ if ( IR == 0x98 ) { A=Y; setNZbyA(); } //TYA
+ else { //CLC/SEC/CLI/SEI/CLV/CLD/SED
+ if (FlagSwitches[IR>>5] & 0x20) ST |= (FlagSwitches[IR>>5] & 0xDF);
+ else ST &= ~( FlagSwitches[IR>>5] & 0xDF );
+ }
+ }
+ else {
+ switch ( (IR & 0xF0) >> 5 ) {
+ case 0: push(ST); Cycles=3; break; //PHP
+ case 1: ST=pop(); Cycles=4; break; //PLP
+ case 2: push(A); Cycles=3; break; //PHA
+ case 3: A=pop(); setNZbyA(); Cycles=4; break; //PLA
+ case 4: --Y; setNZbyY(); break; //DEY
+ case 5: Y=A; setNZbyY(); break; //TAY
+ case 6: ++Y; setNZbyY(); break; //INY
+ case 7: ++X; setNZbyX(); break; //INX
+ }
+ }
+ }
+
+
+ else { //nybble2: 0: control/branch/Y/compare 4: Y/compare C:Y/compare/JMP
+
+ if ( (IR&0x1F) == 0x10 ) { //BPL/BMI/BVC/BVS/BCC/BCS/BNE/BEQ relative branch
+ ++PC;
+ T=rd(PC); if (T & 0x80) T-=0x100;
+ if (IR & 0x20) {
+ if (ST & BranchFlags[IR>>6]) { PC+=T; Cycles=3; }
+ }
+ else {
+ if ( !(ST & BranchFlags[IR>>6]) ) { PC+=T; Cycles=3; } //plus 1 cycle if page is crossed?
+ }
+ }
+
+ else { //nybble2: 0:Y/control/Y/compare 4:Y/compare C:Y/compare/JMP
+ switch (IR&0x1F) { //Addressing modes
+ case 0: addrModeImmediate(); break; //imm. (or abs.low for JSR/BRK)
+ case 4: addrModeZeropage(); break;
+ case 0xC: addrModeAbsolute(); break;
+ case 0x14: addrModeZeropageXindexed(); break; //zp,x
+ case 0x1C: addrModeXindexed(); break; //abs,x
+ }
+ Addr&=0xFFFF;
+
+ switch ( (IR & 0xE0) >> 5 ) {
+
+ case 0: if( !(IR&4) ) { //BRK / NOP-absolute/abs,x/zp/zp,x
+ push((PC+2-1)>>8); push((PC+2-1)&0xFF); push(ST|B); ST |= I; //BRK
+ PC = rd(0xFFFE) + (rd(0xFFFF)<<8) - 1; Cycles=7;
+ }
+ else if (IR == 0x1C) Cycles -= SamePage; //NOP abs,x
+ break;
+
+ case 1: if (IR & 0xF) { //BIT / NOP-abs,x/zp,x
+ if ( !(IR&0x10) ) { ST &= 0x3D; ST |= (rd(Addr)&0xC0) | ( (!(A&rd(Addr))) << 1 ); } //BIT
+ else if (IR == 0x3C) Cycles -= SamePage; //NOP abs,x
+ }
+ else { //JSR
+ push((PC+2-1)>>8); push((PC+2-1)&0xFF);
+ PC=rd(Addr)+rd(Addr+1)*256-1; Cycles=6;
+ }
+ break;
+
+ case 2: if (IR & 0xF) { //JMP / NOP-abs,x/zp/zp,x
+ if (IR == 0x4C) { //JMP
+ PC = Addr-1; Cycles=3;
+ rd(Addr+1); //a read from jump-address highbyte is used in some tunes with jmp DD0C (e.g. Wonderland_XIII_tune_1.sid)
+ //if (Addr==PrevPC) {storeReg(); C64->Returned=1; return 0xFF;} //turn self-jump mainloop (after init) into idle time
+ }
+ else if (IR==0x5C) Cycles -= SamePage; //NOP abs,x
+ }
+ else { //RTI
+ ST=pop(); T=pop(); PC = (pop()<<8) + T - 1; Cycles=6;
+ if (C64->Returned && SP>=0xFF) { ++PC; storeReg(); return 0xFE; }
+ }
+ break;
+
+ case 3: if (IR & 0xF) { //JMP() (indirect) / NOP-abs,x/zp/zp,x
+ if (IR == 0x6C) { //JMP() (indirect)
+ PC = rd( (Addr&0xFF00) + ((Addr+1)&0xFF) ); //(with highbyte-wraparound bug)
+ PC = (PC<<8) + rd(Addr) - 1; Cycles=5;
+ }
+ else if (IR == 0x7C) Cycles -= SamePage; //NOP abs,x
+ }
+ else { //RTS
+ if (SP>=0xFF) {storeReg(); C64->Returned=1; return 0xFF;} //Init returns, provide idle-time between IRQs
+ T=pop(); PC = (pop()<<8) + T; Cycles=6;
+ }
+ break;
+
+ case 4: if (IR & 4) { wr2( Addr, Y ); } //STY / NOP #imm
+ break;
+
+ case 5: Y=rd(Addr); setNZbyY(); Cycles -= SamePage; //LDY
+ break;
+
+ case 6: if ( !(IR&0x10) ) { //CPY / NOP abs,x/zp,x
+ T=Y-rd(Addr); setNZCbySub(&T); //CPY
+ }
+ else if (IR==0xDC) Cycles -= SamePage; //NOP abs,x
+ break;
+
+ case 7: if ( !(IR&0x10) ) { //CPX / NOP abs,x/zp,x
+ T=X-rd(Addr); setNZCbySub(&T); //CPX
+ }
+ else if (IR==0xFC) Cycles -= SamePage; //NOP abs,x
+ break;
+ }
+ }
+ }
+
+
+ ++PC; //PC&=0xFFFF;
+
+ storeReg();
+
+
+ if (!C64->RealSIDmode) { //substitute KERNAL IRQ-return in PSID (e.g. Microprose Soccer)
+ if ( (C64->RAMbank[1]&3)>1 && PrevPC<0xE000 && (PC==0xEA31 || PC==0xEA81 || PC==0xEA7E) ) return 0xFE;
+ }
+
+
+ return Cycles;
+}
+
+
+
+ //handle entering into IRQ and NMI interrupt
+static inline char cRSID_handleCPUinterrupts (cRSID_CPUinstance* CPU) {
+ enum StatusFlagBitValues { B=0x10, I=0x04 };
+ inline void push (unsigned char value) { CPU->C64->RAMbank[0x100+CPU->SP] = value; --CPU->SP; CPU->SP&=0xFF; } //push a value to stack
+
+ if (CPU->C64->NMI > CPU->PrevNMI) { //if IRQ and NMI at the same time, NMI is serviced first
+ push(CPU->PC>>8); push(CPU->PC&0xFF); push(CPU->ST); CPU->ST |= I;
+ CPU->PC = *cRSID_getMemReadPtr(0xFFFA) + (*cRSID_getMemReadPtr(0xFFFB)<<8); //NMI-vector
+ CPU->PrevNMI = CPU->C64->NMI;
+ return 1;
+ }
+ else if ( CPU->C64->IRQ && !(CPU->ST&I) ) {
+ push(CPU->PC>>8); push(CPU->PC&0xFF); push(CPU->ST); CPU->ST |= I;
+ CPU->PC = *cRSID_getMemReadPtr(0xFFFE) + (*cRSID_getMemReadPtr(0xFFFF)<<8); //maskable IRQ-vector
+ CPU->PrevNMI = CPU->C64->NMI;
+ return 1;
+ }
+ CPU->PrevNMI = CPU->C64->NMI; //prepare for NMI edge-detection
+
+ return 0;
+}
diff --git a/lib/rbcodec/codecs/cRSID/C64/MEM.c b/lib/rbcodec/codecs/cRSID/C64/MEM.c
new file mode 100644
index 0000000000..5be0fc47db
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/C64/MEM.c
@@ -0,0 +1,132 @@
+
+//Emulation of C64 memories and memory bus (PLA & MUXes)
+
+
+static inline unsigned char* cRSID_getMemReadPtr (register unsigned short address) {
+ //cRSID_C64instance* const C64 = &cRSID_C64; //for faster (?) operation we use a global object as memory
+ if (address<0xA000) return &cRSID_C64.RAMbank[address];
+ else if ( 0xD000<=address && address<0xE000 && (cRSID_C64.RAMbank[1]&3) ) {
+ if (0xD400 <= address && address < 0xD419) return &cRSID_C64.IObankWR[address]; //emulate bitfading aka SID-read of last written reg (e.g. Lift Off ROR $D400,x)
+ return &cRSID_C64.IObankRD[address];
+ }
+ else if ( (address<0xC000 && (cRSID_C64.RAMbank[1]&3)==3)
+ || (0xE000<=address && (cRSID_C64.RAMbank[1]&2)) ) return &cRSID_C64.ROMbanks[address];
+ return &cRSID_C64.RAMbank[address];
+}
+
+static inline unsigned char* cRSID_getMemReadPtrC64 (cRSID_C64instance* C64, register unsigned short address) {
+ if (address<0xA000) return &C64->RAMbank[address];
+ else if ( 0xD000<=address && address<0xE000 && (C64->RAMbank[1]&3) ) {
+ if (0xD400 <= address && address < 0xD419) return &cRSID_C64.IObankWR[address]; //emulate peculiar SID-read (e.g. Lift Off)
+ return &C64->IObankRD[address];
+ }
+ else if ( (address<0xC000 && (C64->RAMbank[1]&3)==3)
+ || (0xE000<=address && (C64->RAMbank[1]&2)) ) return &C64->ROMbanks[address];
+ return &C64->RAMbank[address];
+}
+
+
+static inline unsigned char* cRSID_getMemWritePtr (register unsigned short address) {
+ //cRSID_C64instance* const C64 = &cRSID_C64; //for faster (?) operation we use a global object as memory
+ if (address<0xD000 || 0xE000<=address) return &cRSID_C64.RAMbank[address];
+ else if ( cRSID_C64.RAMbank[1]&3 ) { //handle SID-mirrors! (CJ in the USA workaround (writing above $d420, except SID2/SID3))
+ if (0xD420 <= address && address < 0xD800) { //CIA/VIC mirrors needed?
+ if ( !(cRSID_C64.PSIDdigiMode && 0xD418 <= address && address < 0xD500)
+ && !(cRSID_C64.SID[2].BaseAddress <= address && address < cRSID_C64.SID[2].BaseAddress+0x20)
+ && !(cRSID_C64.SID[3].BaseAddress <= address && address < cRSID_C64.SID[3].BaseAddress+0x20) ) {
+ return &cRSID_C64.IObankWR[ 0xD400 + (address&0x1F) ]; //write to $D400..D41F if not in SID2/SID3 address-space
+ }
+ else return &cRSID_C64.IObankWR[address];
+ }
+ else return &cRSID_C64.IObankWR[address];
+ }
+ return &cRSID_C64.RAMbank[address];
+}
+
+
+static inline unsigned char* cRSID_getMemWritePtrC64 (cRSID_C64instance* C64, register unsigned short address) {
+ if (address<0xD000 || 0xE000<=address) return &C64->RAMbank[address];
+ else if ( C64->RAMbank[1]&3 ) { //handle SID-mirrors! (CJ in the USA workaround (writing above $d420, except SID2/SID3/PSIDdigi))
+ if (0xD420 <= address && address < 0xD800) { //CIA/VIC mirrors needed?
+ if ( !(cRSID_C64.PSIDdigiMode && 0xD418 <= address && address < 0xD500)
+ && !(C64->SID[2].BaseAddress <= address && address < C64->SID[2].BaseAddress+0x20)
+ && !(C64->SID[3].BaseAddress <= address && address < C64->SID[3].BaseAddress+0x20) ) {
+ return &C64->IObankWR[ 0xD400 + (address&0x1F) ]; //write to $D400..D41F if not in SID2/SID3 address-space
+ }
+ else return &C64->IObankWR[address];
+ }
+ else return &C64->IObankWR[address];
+ }
+ return &C64->RAMbank[address];
+}
+
+
+static inline unsigned char cRSID_readMem (register unsigned short address) {
+ return *cRSID_getMemReadPtr(address);
+}
+
+static inline unsigned char cRSID_readMemC64 (cRSID_C64instance* C64, register unsigned short address) {
+ return *cRSID_getMemReadPtrC64(C64,address);
+}
+
+
+static inline void cRSID_writeMem (register unsigned short address, register unsigned char data) {
+ *cRSID_getMemWritePtr(address)=data;
+}
+
+static inline void cRSID_writeMemC64 (cRSID_C64instance* C64, register unsigned short address, register unsigned char data) {
+ *cRSID_getMemWritePtrC64(C64,address)=data;
+}
+
+
+void cRSID_setROMcontent (cRSID_C64instance* C64) { //fill KERNAL/BASIC-ROM areas with content needed for SID-playback
+ int i;
+ static const unsigned char ROM_IRQreturnCode[9] = {0xAD,0x0D,0xDC,0x68,0xA8,0x68,0xAA,0x68,0x40}; //CIA1-acknowledge IRQ-return
+ static const unsigned char ROM_NMIstartCode[5] = {0x78,0x6c,0x18,0x03,0x40}; //SEI and jmp($0318)
+ static const unsigned char ROM_IRQBRKstartCode[19] = { //Full IRQ-return (handling BRK with the same RAM vector as IRQ)
+ 0x48,0x8A,0x48,0x98,0x48,0xBA,0xBD,0x04,0x01,0x29,0x10,0xEA,0xEA,0xEA,0xEA,0xEA,0x6C,0x14,0x03
+ };
+
+ for (i=0xA000; i<0x10000; ++i) C64->ROMbanks[i] = 0x60; //RTS (at least return if some unsupported call is made to ROM)
+ for (i=0xEA31; i<0xEA7E; ++i) C64->ROMbanks[i] = 0xEA; //NOP (full IRQ-return leading to simple IRQ-return without other tasks)
+ for (i=0; i<9; ++i) C64->ROMbanks [0xEA7E + i] = ROM_IRQreturnCode[i];
+ for (i=0; i<4; ++i) C64->ROMbanks [0xFE43 + i] = ROM_NMIstartCode[i];
+ for (i=0; i<19; ++i) C64->ROMbanks[0xFF48 + i] = ROM_IRQBRKstartCode[i];
+
+ C64->ROMbanks[0xFFFB] = 0xFE; C64->ROMbanks[0xFFFA] = 0x43; //ROM NMI-vector
+ C64->ROMbanks[0xFFFF] = 0xFF; C64->ROMbanks[0xFFFE] = 0x48; //ROM IRQ-vector
+
+ //copy KERNAL & BASIC ROM contents into the RAM under them? (So PSIDs that don't select bank correctly will work better.)
+ for (i=0xA000; i<0x10000; ++i) C64->RAMbank[i]=C64->ROMbanks[i];
+}
+
+
+void cRSID_initMem (cRSID_C64instance* C64) { //set default values that normally KERNEL ensures after startup/reset (only SID-playback related)
+ static int i;
+
+ //data required by both PSID and RSID (according to HVSC SID_file_format.txt):
+ cRSID_writeMemC64( C64, 0x02A6, C64->VideoStandard ); //$02A6 should be pre-set to: 0:NTSC / 1:PAL
+ cRSID_writeMemC64( C64, 0x0001, 0x37 ); //initialize bank-reg. (ROM-banks and IO enabled)
+
+ //if (C64->ROMbanks[0xE000]==0) { //wasn't a KERNAL-ROM loaded? (e.g. PSID)
+ cRSID_writeMemC64( C64, 0x00CB, 0x40 ); //Some tunes might check for keypress here (e.g. Master Blaster Intro)
+ //if(C64->RealSIDmode) {
+ cRSID_writeMemC64( C64, 0x0315, 0xEA ); cRSID_writeMemC64( C64, 0x0314, 0x31 ); //IRQ
+ cRSID_writeMemC64( C64, 0x0319, 0xEA/*0xFE*/ ); cRSID_writeMemC64( C64, 0x0318, 0x81/*0x47*/ ); //NMI
+ //}
+
+ for (i=0xD000; i<0xD7FF; ++i) C64->IObankRD[i] = C64->IObankWR[i] = 0; //initialize the whole IO area for a known base-state
+ if(C64->RealSIDmode) {C64->IObankWR[0xD012] = 0x37; C64->IObankWR[0xD011] = 0x8B;} //else C64->IObankWR[0xD012] = 0;
+ //C64->IObankWR[0xD019] = 0; //PSID: rasterrow: any value <= $FF, IRQ:enable later if there is VIC-timingsource
+
+ C64->IObankRD[0xDC00]=0x10; C64->IObankRD[0xDC01]=0xFF; //Imitate CIA1 keyboard/joy port, some tunes check if buttons are not pressed
+ if (C64->VideoStandard) { C64->IObankWR[0xDC04]=0x24; C64->IObankWR[0xDC05]=0x40; } //initialize CIAs
+ else { C64->IObankWR[0xDC04]=0x95; C64->IObankWR[0xDC05]=0x42; }
+ if(C64->RealSIDmode) C64->IObankWR[0xDC0D] = 0x81; //Reset-default, but for PSID CIA1 TimerA IRQ should be enabled anyway if SID is CIA-timed
+ C64->IObankWR[0xDC0E] = 0x01; //some tunes (and PSID doc) expect already running CIA (Reset-default)
+ C64->IObankWR[0xDC0F] = 0x00; //All counters other than CIA1 TimerA should be disabled and set to 0xFF for PSID:
+ C64->IObankWR[0xDD04] = C64->IObankWR[0xDD05] = 0xFF; //C64->IObankWR[0xDD0E] = C64->IObank[0xDD0F] = 0x00;
+ //}
+
+}
+
diff --git a/lib/rbcodec/codecs/cRSID/C64/SID.c b/lib/rbcodec/codecs/cRSID/C64/SID.c
new file mode 100644
index 0000000000..22b07c15da
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/C64/SID.c
@@ -0,0 +1,276 @@
+
+//cRSID SID emulation engine
+
+
+void cRSID_createSIDchip (cRSID_C64instance* C64, cRSID_SIDinstance* SID, unsigned short model, unsigned short baseaddress) {
+ SID->C64 = C64;
+ SID->ChipModel = model;
+ if( baseaddress>=0xD400 && (baseaddress<0xD800 || (0xDE00<=baseaddress && baseaddress<=0xDFE0)) ) { //check valid address, avoid Color-RAM
+ SID->BaseAddress = baseaddress; SID->BasePtr = &C64->IObankWR[baseaddress];
+ }
+ else { SID->BaseAddress=0x0000; SID->BasePtr = NULL; }
+ cRSID_initSIDchip(SID);
+}
+
+
+void cRSID_initSIDchip (cRSID_SIDinstance* SID) {
+ static unsigned char Channel;
+ for (Channel = 0; Channel < 21; Channel+=7) {
+ SID->ADSRstate[Channel] = 0; SID->RateCounter[Channel] = 0;
+ SID->EnvelopeCounter[Channel] = 0; SID->ExponentCounter[Channel] = 0;
+ SID->PhaseAccu[Channel] = 0; SID->PrevPhaseAccu[Channel] = 0;
+ SID->NoiseLFSR[Channel] = 0x7FFFFF;
+ SID->PrevWavGenOut[Channel] = 0; SID->PrevWavData[Channel] = 0;
+ }
+ SID->SyncSourceMSBrise = 0; SID->RingSourceMSB = 0;
+ SID->PrevLowPass = SID->PrevBandPass = SID->PrevVolume = 0;
+}
+
+
+void cRSID_emulateADSRs (cRSID_SIDinstance *SID, char cycles) {
+
+ enum ADSRstateBits { GATE_BITVAL=0x01, ATTACK_BITVAL=0x80, DECAYSUSTAIN_BITVAL=0x40, HOLDZEROn_BITVAL=0x10 };
+
+ static const short ADSRprescalePeriods[16] = {
+ 9, 32, 63, 95, 149, 220, 267, 313, 392, 977, 1954, 3126, 3907, 11720, 19532, 31251
+ };
+ static const unsigned char ADSRexponentPeriods[256] = {
+ 1, 30, 30, 30, 30, 30, 30, 16, 16, 16, 16, 16, 16, 16, 16,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, //pos0:1 pos6:30 pos14:16 pos26:8
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, //pos54:4 //pos93:2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+ };
+
+ static unsigned char Channel, PrevGate, AD, SR;
+ static unsigned short PrescalePeriod;
+ static unsigned char *ChannelPtr, *ADSRstatePtr, *EnvelopeCounterPtr, *ExponentCounterPtr;
+ static unsigned short *RateCounterPtr;
+
+
+ for (Channel=0; Channel<21; Channel+=7) {
+
+ ChannelPtr=&SID->BasePtr[Channel]; AD=ChannelPtr[5]; SR=ChannelPtr[6];
+ ADSRstatePtr = &(SID->ADSRstate[Channel]);
+ RateCounterPtr = &(SID->RateCounter[Channel]);
+ EnvelopeCounterPtr = &(SID->EnvelopeCounter[Channel]);
+ ExponentCounterPtr = &(SID->ExponentCounter[Channel]);
+
+ PrevGate = (*ADSRstatePtr & GATE_BITVAL);
+ if ( PrevGate != (ChannelPtr[4] & GATE_BITVAL) ) { //gatebit-change?
+ if (PrevGate) *ADSRstatePtr &= ~ (GATE_BITVAL | ATTACK_BITVAL | DECAYSUSTAIN_BITVAL); //falling edge
+ else *ADSRstatePtr = (GATE_BITVAL | ATTACK_BITVAL | DECAYSUSTAIN_BITVAL | HOLDZEROn_BITVAL); //rising edge
+ }
+
+ if (*ADSRstatePtr & ATTACK_BITVAL) PrescalePeriod = ADSRprescalePeriods[ AD >> 4 ];
+ else if (*ADSRstatePtr & DECAYSUSTAIN_BITVAL) PrescalePeriod = ADSRprescalePeriods[ AD & 0x0F ];
+ else PrescalePeriod = ADSRprescalePeriods[ SR & 0x0F ];
+
+ *RateCounterPtr += cycles; if (*RateCounterPtr >= 0x8000) *RateCounterPtr -= 0x8000; //*RateCounterPtr &= 0x7FFF; //can wrap around (ADSR delay-bug: short 1st frame)
+
+ if (PrescalePeriod <= *RateCounterPtr && *RateCounterPtr < PrescalePeriod+cycles) { //ratecounter shot (matches rateperiod) (in genuine SID ratecounter is LFSR)
+ *RateCounterPtr -= PrescalePeriod; //reset rate-counter on period-match
+ if ( (*ADSRstatePtr & ATTACK_BITVAL) || ++(*ExponentCounterPtr) == ADSRexponentPeriods[*EnvelopeCounterPtr] ) {
+ *ExponentCounterPtr = 0;
+ if (*ADSRstatePtr & HOLDZEROn_BITVAL) {
+ if (*ADSRstatePtr & ATTACK_BITVAL) {
+ ++(*EnvelopeCounterPtr);
+ if (*EnvelopeCounterPtr==0xFF) *ADSRstatePtr &= ~ATTACK_BITVAL;
+ }
+ else if ( !(*ADSRstatePtr & DECAYSUSTAIN_BITVAL) || *EnvelopeCounterPtr != (SR&0xF0)+(SR>>4) ) {
+ --(*EnvelopeCounterPtr); //resid adds 1 cycle delay, we omit that mechanism here
+ if (*EnvelopeCounterPtr==0) *ADSRstatePtr &= ~HOLDZEROn_BITVAL;
+ }}}}}
+
+}
+
+
+
+int cRSID_emulateWaves (cRSID_SIDinstance *SID) {
+
+ enum SIDspecs { CHANNELS=3+1, VOLUME_MAX=0xF, D418_DIGI_VOLUME=2 }; //digi-channel is counted too
+ enum WaveFormBits { NOISE_BITVAL=0x80, PULSE_BITVAL=0x40, SAW_BITVAL=0x20, TRI_BITVAL=0x10 };
+ enum ControlBits { TEST_BITVAL=0x08, RING_BITVAL=0x04, SYNC_BITVAL=0x02, GATE_BITVAL=0x01 };
+ enum FilterBits { OFF3_BITVAL=0x80, HIGHPASS_BITVAL=0x40, BANDPASS_BITVAL=0x20, LOWPASS_BITVAL=0x10 };
+
+ #include "SID.h"
+ static const unsigned char FilterSwitchVal[] = {1,1,1,1,1,1,1,2,2,2,2,2,2,2,4};
+
+ static char MainVolume;
+ static unsigned char Channel, WF, TestBit, Envelope, FilterSwitchReso, VolumeBand;
+ static unsigned int Utmp, PhaseAccuStep, MSB, WavGenOut, PW;
+ static int Tmp, Feedback, Steepness, PulsePeak;
+ static int FilterInput, Cutoff, Resonance, FilterOutput, NonFilted, Output;
+ static unsigned char *ChannelPtr;
+ static int *PhaseAccuPtr;
+
+
+ inline unsigned short combinedWF( const unsigned char* WFarray, unsigned short oscval) {
+ static unsigned char Pitch;
+ static unsigned short Filt;
+ if (SID->ChipModel==6581 && WFarray!=PulseTriangle) oscval &= 0x7FFF;
+ Pitch = ChannelPtr[1] ? ChannelPtr[1] : 1; //avoid division by zero
+ Filt = 0x7777 + (0x8888/Pitch);
+ SID->PrevWavData[Channel] = ( WFarray[oscval>>4]*Filt + SID->PrevWavData[Channel]*(0xFFFF-Filt) ) >> 16;
+ return SID->PrevWavData[Channel] << 8;
+ }
+
+
+ FilterInput = NonFilted = 0;
+ FilterSwitchReso = SID->BasePtr[0x17]; VolumeBand=SID->BasePtr[0x18];
+
+
+ //Waveform-generator //(phase accumulator and waveform-selector)
+
+
+ for (Channel=0; Channel<21; Channel+=7) {
+ ChannelPtr=&(SID->BasePtr[Channel]);
+
+ WF = ChannelPtr[4]; TestBit = ( (WF & TEST_BITVAL) != 0 );
+ PhaseAccuPtr = &(SID->PhaseAccu[Channel]);
+
+
+ PhaseAccuStep = ( (ChannelPtr[1]<<8) + ChannelPtr[0] ) * SID->C64->SampleClockRatio;
+ if (TestBit || ((WF & SYNC_BITVAL) && SID->SyncSourceMSBrise)) *PhaseAccuPtr = 0;
+ else { //stepping phase-accumulator (oscillator)
+ *PhaseAccuPtr += PhaseAccuStep;
+ if (*PhaseAccuPtr >= 0x10000000) *PhaseAccuPtr -= 0x10000000;
+ }
+ *PhaseAccuPtr &= 0xFFFFFFF;
+ MSB = *PhaseAccuPtr & 0x8000000;
+ SID->SyncSourceMSBrise = (MSB > (SID->PrevPhaseAccu[Channel] & 0x8000000)) ? 1 : 0;
+
+
+ if (WF & NOISE_BITVAL) { //noise waveform
+ Tmp = SID->NoiseLFSR[Channel]; //clock LFSR all time if clockrate exceeds observable at given samplerate (last term):
+ if ( ((*PhaseAccuPtr & 0x1000000) != (SID->PrevPhaseAccu[Channel] & 0x1000000)) || PhaseAccuStep >= 0x1000000 ) {
+ Feedback = ( (Tmp & 0x400000) ^ ((Tmp & 0x20000) << 5) ) != 0;
+ Tmp = ( (Tmp << 1) | Feedback|TestBit ) & 0x7FFFFF; //TEST-bit turns all bits in noise LFSR to 1 (on real SID slowly, in approx. 8000 microseconds ~ 300 samples)
+ SID->NoiseLFSR[Channel] = Tmp;
+ } //we simply zero output when other waveform is mixed with noise. On real SID LFSR continuously gets filled by zero and locks up. ($C1 waveform with pw<8 can keep it for a while.)
+ WavGenOut = (WF & 0x70) ? 0 : ((Tmp & 0x100000) >> 5) | ((Tmp & 0x40000) >> 4) | ((Tmp & 0x4000) >> 1) | ((Tmp & 0x800) << 1)
+ | ((Tmp & 0x200) << 2) | ((Tmp & 0x20) << 5) | ((Tmp & 0x04) << 7) | ((Tmp & 0x01) << 8);
+ }
+
+ else if (WF & PULSE_BITVAL) { //simple pulse
+ PW = ( ((ChannelPtr[3]&0xF) << 8) + ChannelPtr[2] ) << 4; //PW=0000..FFF0 from SID-register
+ Utmp = (int) (PhaseAccuStep >> 13); if (0 < PW && PW < Utmp) PW = Utmp; //Too thin pulsewidth? Correct...
+ Utmp ^= 0xFFFF; if (PW > Utmp) PW = Utmp; //Too thin pulsewidth? Correct it to a value representable at the current samplerate
+ Utmp = *PhaseAccuPtr >> 12;
+
+ if ( (WF&0xF0) == PULSE_BITVAL ) { //simple pulse, most often used waveform, make it sound as clean as possible (by making it trapezoid)
+ Steepness = (PhaseAccuStep>=4096) ? 0xFFFFFFF/PhaseAccuStep : 0xFFFF; //rising/falling-edge steepness (add/sub at samples)
+ if (TestBit) WavGenOut = 0xFFFF;
+ else if (Utmp<PW) { //rising edge (interpolation)
+ PulsePeak = (0xFFFF-PW) * Steepness; //very thin pulses don't make a full swing between 0 and max but make a little spike
+ if (PulsePeak>0xFFFF) PulsePeak=0xFFFF; //but adequately thick trapezoid pulses reach the maximum level
+ Tmp = PulsePeak - (PW-Utmp)*Steepness; //draw the slope from the peak
+ WavGenOut = (Tmp<0)? 0:Tmp; //but stop at 0-level
+ }
+ else { //falling edge (interpolation)
+ PulsePeak = PW*Steepness; //very thin pulses don't make a full swing between 0 and max but make a little spike
+ if (PulsePeak>0xFFFF) PulsePeak=0xFFFF; //adequately thick trapezoid pulses reach the maximum level
+ Tmp = (0xFFFF-Utmp)*Steepness - PulsePeak; //draw the slope from the peak
+ WavGenOut = (Tmp>=0)? 0xFFFF:Tmp; //but stop at max-level
+ }}
+
+ else { //combined pulse
+ WavGenOut = (Utmp >= PW || TestBit) ? 0xFFFF:0;
+ if (WF & TRI_BITVAL) {
+ if (WF & SAW_BITVAL) { //pulse+saw+triangle (waveform nearly identical to tri+saw)
+ if (WavGenOut) WavGenOut = combinedWF( PulseSawTriangle, Utmp);
+ }
+ else { //pulse+triangle
+ Tmp = *PhaseAccuPtr ^ ( (WF&RING_BITVAL)? SID->RingSourceMSB : 0 );
+ if (WavGenOut) WavGenOut = combinedWF( PulseTriangle, Tmp >> 12);
+ }}
+ else if (WF & SAW_BITVAL) { //pulse+saw
+ if(WavGenOut) WavGenOut = combinedWF( PulseSawtooth, Utmp);
+ }}
+ }
+
+ else if (WF & SAW_BITVAL) { //sawtooth
+ WavGenOut = *PhaseAccuPtr >> 12; //saw (this row would be enough for simple but aliased-at-high-pitch saw)
+ if (WF & TRI_BITVAL) WavGenOut = combinedWF( SawTriangle, WavGenOut); //saw+triangle
+ else { //simple cleaned (bandlimited) saw
+ Steepness = (PhaseAccuStep>>4)/288; if(Steepness==0) Steepness=1; //avoid division by zero in next steps
+ WavGenOut += (WavGenOut * Steepness) >> 16; //1st half (rising edge) of asymmetric triangle-like saw waveform
+ if (WavGenOut>0xFFFF) WavGenOut = 0xFFFF - ( ((WavGenOut-0x10000)<<16) / Steepness ); //2nd half (falling edge, reciprocal steepness)
+ }}
+
+ else if (WF & TRI_BITVAL) { //triangle (this waveform has no harsh edges, so it doesn't suffer from strong aliasing at high pitches)
+ Tmp = *PhaseAccuPtr ^ ( WF&RING_BITVAL? SID->RingSourceMSB : 0 );
+ WavGenOut = ( Tmp ^ (Tmp&0x8000000? 0xFFFFFFF:0) ) >> 11;
+ }
+
+
+ WavGenOut &= 0xFFFF;
+ if (WF&0xF0) SID->PrevWavGenOut[Channel] = WavGenOut; //emulate waveform 00 floating wave-DAC (utilized by SounDemon digis)
+ else WavGenOut = SID->PrevWavGenOut[Channel]; //(on real SID waveform00 decays, we just simply keep the value to avoid clicks)
+ SID->PrevPhaseAccu[Channel] = *PhaseAccuPtr;
+ SID->RingSourceMSB = MSB;
+
+ //routing the channel signal to either the filter or the unfiltered master output depending on filter-switch SID-registers
+ Envelope = SID->ChipModel==8580 ? SID->EnvelopeCounter[Channel] : ADSR_DAC_6581[SID->EnvelopeCounter[Channel]];
+ if (FilterSwitchReso & FilterSwitchVal[Channel]) {
+ FilterInput += ( ((int)WavGenOut-0x8000) * Envelope ) >> 8;
+ }
+ else if ( Channel!=14 || !(VolumeBand & OFF3_BITVAL) ) {
+ NonFilted += ( ((int)WavGenOut-0x8000) * Envelope ) >> 8;
+ }
+
+ }
+ //update readable SID1-registers (some SID tunes might use 3rd channel ENV3/OSC3 value as control)
+ SID->C64->IObankRD[SID->BaseAddress+0x1B] = WavGenOut>>8; //OSC3, ENV3 (some players rely on it, unfortunately even for timing)
+ SID->C64->IObankRD[SID->BaseAddress+0x1C] = SID->EnvelopeCounter[14]; //Envelope
+
+
+ //Filter
+
+
+ Cutoff = (SID->BasePtr[0x16] << 3) + (SID->BasePtr[0x15] & 7);
+ Resonance = FilterSwitchReso >> 4;
+ if (SID->ChipModel == 8580) {
+ Cutoff = CutoffMul8580_44100Hz[Cutoff];
+ Resonance = Resonances8580[Resonance];
+ }
+ else { //6581
+ Cutoff += (FilterInput*105)>>16; if (Cutoff>0x7FF) Cutoff=0x7FF; else if (Cutoff<0) Cutoff=0; //MOSFET-VCR control-voltage-modulation
+ Cutoff = CutoffMul6581_44100Hz[Cutoff]; //(resistance-modulation aka 6581 filter distortion) emulation
+ Resonance = Resonances6581[Resonance];
+ }
+
+ FilterOutput=0;
+ Tmp = FilterInput + ((SID->PrevBandPass * Resonance)>>12) + SID->PrevLowPass;
+ if (VolumeBand & HIGHPASS_BITVAL) FilterOutput -= Tmp;
+ Tmp = SID->PrevBandPass - ( (Tmp * Cutoff) >> 12 );
+ SID->PrevBandPass = Tmp;
+ if (VolumeBand & BANDPASS_BITVAL) FilterOutput -= Tmp;
+ Tmp = SID->PrevLowPass + ( (Tmp * Cutoff) >> 12 );
+ SID->PrevLowPass = Tmp;
+ if (VolumeBand & LOWPASS_BITVAL) FilterOutput += Tmp;
+
+
+ //Output stage
+ //For $D418 volume-register digi playback: an AC / DC separation for $D418 value at low (20Hz or so) cutoff-frequency,
+ //sending AC (highpass) value to a 4th 'digi' channel mixed to the master output, and set ONLY the DC (lowpass) value to the volume-control.
+ //This solved 2 issues: Thanks to the lowpass filtering of the volume-control, SID tunes where digi is played together with normal SID channels,
+ //won't sound distorted anymore, and the volume-clicks disappear when setting SID-volume. (This is useful for fade-in/out tunes like Hades Nebula, where clicking ruins the intro.)
+ if (SID->C64->RealSIDmode) {
+ Tmp = (signed int) ( (VolumeBand&0xF) << 12 );
+ NonFilted += (Tmp - SID->PrevVolume) * D418_DIGI_VOLUME; //highpass is digi, adding it to output must be before digifilter-code
+ SID->PrevVolume += (Tmp - SID->PrevVolume) >> 10; //arithmetic shift amount determines digi lowpass-frequency
+ MainVolume = SID->PrevVolume >> 12; //lowpass is main volume
+ }
+ else MainVolume = VolumeBand & 0xF;
+
+ Output = ((NonFilted+FilterOutput) * MainVolume) / ( (CHANNELS*VOLUME_MAX) + SID->C64->Attenuation );
+
+ return Output; // master output
+
+}
+
diff --git a/lib/rbcodec/codecs/cRSID/C64/SID.h b/lib/rbcodec/codecs/cRSID/C64/SID.h
new file mode 100644
index 0000000000..3e0e866171
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/C64/SID.h
@@ -0,0 +1,824 @@
+
+//SID-tables: combined waveform,etc. (Keep them static because they're included locally inside the wave-generator function.)
+
+
+static const unsigned char ADSR_DAC_6581[] = {
+ 0x00,0x02,0x03,0x04,0x05,0x06,0x07,0x09,0x09,0x0B,0x0B,0x0D,0x0D,0x0F,0x10,0x12,
+ 0x11,0x13,0x14,0x15,0x16,0x17,0x18,0x1A,0x1A,0x1C,0x1C,0x1E,0x1E,0x20,0x21,0x23, //used at output of ADSR envelope generator
+ 0x21,0x23,0x24,0x25,0x26,0x27,0x28,0x2A,0x2A,0x2C,0x2C,0x2E,0x2E,0x30,0x31,0x33, //(not used for wave-generator because of 8bit-only resolution)
+ 0x32,0x34,0x35,0x36,0x37,0x38,0x39,0x3B,0x3B,0x3D,0x3D,0x3F,0x3F,0x41,0x42,0x44,
+ 0x40,0x42,0x42,0x44,0x44,0x46,0x47,0x49,0x49,0x4A,0x4B,0x4D,0x4D,0x4F,0x50,0x52,
+ 0x51,0x53,0x53,0x55,0x55,0x57,0x58,0x5A,0x5A,0x5B,0x5C,0x5E,0x5E,0x60,0x61,0x63,
+ 0x61,0x62,0x63,0x65,0x65,0x67,0x68,0x6A,0x69,0x6B,0x6C,0x6E,0x6E,0x70,0x71,0x73,
+ 0x72,0x73,0x74,0x76,0x76,0x78,0x79,0x7B,0x7A,0x7C,0x7D,0x7F,0x7F,0x81,0x82,0x84,
+ 0x7B,0x7D,0x7E,0x80,0x80,0x82,0x83,0x85,0x84,0x86,0x87,0x89,0x89,0x8B,0x8C,0x8D,
+ 0x8C,0x8E,0x8F,0x91,0x91,0x93,0x94,0x96,0x95,0x97,0x98,0x9A,0x9A,0x9C,0x9D,0x9E,
+ 0x9C,0x9E,0x9F,0xA1,0xA1,0xA3,0xA4,0xA5,0xA5,0xA7,0xA8,0xAA,0xAA,0xAC,0xAC,0xAE,
+ 0xAD,0xAF,0xB0,0xB2,0xB2,0xB4,0xB5,0xB6,0xB6,0xB8,0xB9,0xBB,0xBB,0xBD,0xBD,0xBF,
+ 0xBB,0xBD,0xBE,0xC0,0xC0,0xC2,0xC2,0xC4,0xC4,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,
+ 0xCC,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDE,
+ 0xDC,0xDE,0xDF,0xE1,0xE1,0xE3,0xE3,0xE5,0xE5,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xEE,
+ 0xED,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFF
+};
+
+
+static const unsigned short Resonances8580[] = { //generated by curvegen.c
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0x16A0,0x14BF,0x1306,0x1172,0x1000,0x0EAC,0x0D74,0x0C56,0x0B50,0x0A5F,0x0983,0x08B9,0x0800,0x0756,0x06BA,0x062B
+ //0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE8, 0xD5, 0xC5, 0xB3, 0xA4, 0x97, 0x8A, 0x80, 0x77, 0x6E, 0x66 <- calculated then refined manually to sound best
+};
+
+static const unsigned short Resonances6581[] = { //generated by curvegen.c
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0x168F,0x168F,0x168F,0x168F,0x168F,0x168F,0x1555,0x1249,0x1000,0x0E38,0x0CCC,0x0BA2,0x0AAA,0x09D8,0x0924,0x0888
+ //0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xF9, 0xF6, 0xF2, 0xEC, 0xE4, 0xCD, 0xBA, 0xAB, 0x9E, 0x92, 0x86 <- calculated then refined manually to sound best
+};
+
+
+static const unsigned short CutoffMul8580_44100Hz[] = { //generated by curvegen.c
+0x006,0x00A,0x00D,0x011,0x014,0x018,0x01B,0x01F,0x022,0x026,0x029,0x02D,0x030,0x034,0x037,0x03B,
+0x03E,0x041,0x045,0x048,0x04C,0x04F,0x053,0x056,0x059,0x05D,0x060,0x064,0x067,0x06B,0x06E,0x071,
+0x075,0x078,0x07C,0x07F,0x082,0x086,0x089,0x08D,0x090,0x093,0x097,0x09A,0x09D,0x0A1,0x0A4,0x0A7,
+0x0AB,0x0AE,0x0B2,0x0B5,0x0B8,0x0BC,0x0BF,0x0C2,0x0C6,0x0C9,0x0CC,0x0D0,0x0D3,0x0D6,0x0D9,0x0DD,
+0x0E0,0x0E3,0x0E7,0x0EA,0x0ED,0x0F1,0x0F4,0x0F7,0x0FA,0x0FE,0x101,0x104,0x108,0x10B,0x10E,0x111,
+0x115,0x118,0x11B,0x11E,0x122,0x125,0x128,0x12B,0x12F,0x132,0x135,0x138,0x13C,0x13F,0x142,0x145,
+0x149,0x14C,0x14F,0x152,0x155,0x159,0x15C,0x15F,0x162,0x165,0x169,0x16C,0x16F,0x172,0x175,0x178,
+0x17C,0x17F,0x182,0x185,0x188,0x18B,0x18F,0x192,0x195,0x198,0x19B,0x19E,0x1A2,0x1A5,0x1A8,0x1AB,
+0x1AE,0x1B1,0x1B4,0x1B7,0x1BB,0x1BE,0x1C1,0x1C4,0x1C7,0x1CA,0x1CD,0x1D0,0x1D3,0x1D7,0x1DA,0x1DD,
+0x1E0,0x1E3,0x1E6,0x1E9,0x1EC,0x1EF,0x1F2,0x1F5,0x1F9,0x1FC,0x1FF,0x202,0x205,0x208,0x20B,0x20E,
+0x211,0x214,0x217,0x21A,0x21D,0x220,0x223,0x226,0x229,0x22C,0x22F,0x232,0x235,0x238,0x23B,0x23E,
+0x241,0x244,0x247,0x24A,0x24D,0x250,0x253,0x256,0x259,0x25C,0x25F,0x262,0x265,0x268,0x26B,0x26E,
+0x271,0x274,0x277,0x27A,0x27D,0x280,0x283,0x286,0x289,0x28C,0x28F,0x292,0x295,0x297,0x29A,0x29D,
+0x2A0,0x2A3,0x2A6,0x2A9,0x2AC,0x2AF,0x2B2,0x2B5,0x2B8,0x2BB,0x2BD,0x2C0,0x2C3,0x2C6,0x2C9,0x2CC,
+0x2CF,0x2D2,0x2D5,0x2D7,0x2DA,0x2DD,0x2E0,0x2E3,0x2E6,0x2E9,0x2EB,0x2EE,0x2F1,0x2F4,0x2F7,0x2FA,
+0x2FD,0x2FF,0x302,0x305,0x308,0x30B,0x30E,0x310,0x313,0x316,0x319,0x31C,0x31F,0x321,0x324,0x327,
+0x32A,0x32D,0x32F,0x332,0x335,0x338,0x33B,0x33D,0x340,0x343,0x346,0x349,0x34B,0x34E,0x351,0x354,
+0x356,0x359,0x35C,0x35F,0x362,0x364,0x367,0x36A,0x36D,0x36F,0x372,0x375,0x378,0x37A,0x37D,0x380,
+0x382,0x385,0x388,0x38B,0x38D,0x390,0x393,0x396,0x398,0x39B,0x39E,0x3A0,0x3A3,0x3A6,0x3A8,0x3AB,
+0x3AE,0x3B1,0x3B3,0x3B6,0x3B9,0x3BB,0x3BE,0x3C1,0x3C3,0x3C6,0x3C9,0x3CB,0x3CE,0x3D1,0x3D3,0x3D6,
+0x3D9,0x3DB,0x3DE,0x3E1,0x3E3,0x3E6,0x3E9,0x3EB,0x3EE,0x3F1,0x3F3,0x3F6,0x3F8,0x3FB,0x3FE,0x400,
+0x403,0x406,0x408,0x40B,0x40D,0x410,0x413,0x415,0x418,0x41A,0x41D,0x420,0x422,0x425,0x427,0x42A,
+0x42D,0x42F,0x432,0x434,0x437,0x439,0x43C,0x43F,0x441,0x444,0x446,0x449,0x44B,0x44E,0x451,0x453,
+0x456,0x458,0x45B,0x45D,0x460,0x462,0x465,0x467,0x46A,0x46D,0x46F,0x472,0x474,0x477,0x479,0x47C,
+0x47E,0x481,0x483,0x486,0x488,0x48B,0x48D,0x490,0x492,0x495,0x497,0x49A,0x49C,0x49F,0x4A1,0x4A4,
+0x4A6,0x4A9,0x4AB,0x4AE,0x4B0,0x4B3,0x4B5,0x4B8,0x4BA,0x4BC,0x4BF,0x4C1,0x4C4,0x4C6,0x4C9,0x4CB,
+0x4CE,0x4D0,0x4D3,0x4D5,0x4D7,0x4DA,0x4DC,0x4DF,0x4E1,0x4E4,0x4E6,0x4E8,0x4EB,0x4ED,0x4F0,0x4F2,
+0x4F5,0x4F7,0x4F9,0x4FC,0x4FE,0x501,0x503,0x505,0x508,0x50A,0x50D,0x50F,0x511,0x514,0x516,0x519,
+0x51B,0x51D,0x520,0x522,0x524,0x527,0x529,0x52C,0x52E,0x530,0x533,0x535,0x537,0x53A,0x53C,0x53E,
+0x541,0x543,0x546,0x548,0x54A,0x54D,0x54F,0x551,0x554,0x556,0x558,0x55B,0x55D,0x55F,0x562,0x564,
+0x566,0x568,0x56B,0x56D,0x56F,0x572,0x574,0x576,0x579,0x57B,0x57D,0x580,0x582,0x584,0x586,0x589,
+0x58B,0x58D,0x590,0x592,0x594,0x596,0x599,0x59B,0x59D,0x5A0,0x5A2,0x5A4,0x5A6,0x5A9,0x5AB,0x5AD,
+0x5AF,0x5B2,0x5B4,0x5B6,0x5B8,0x5BB,0x5BD,0x5BF,0x5C1,0x5C4,0x5C6,0x5C8,0x5CA,0x5CD,0x5CF,0x5D1,
+0x5D3,0x5D5,0x5D8,0x5DA,0x5DC,0x5DE,0x5E1,0x5E3,0x5E5,0x5E7,0x5E9,0x5EC,0x5EE,0x5F0,0x5F2,0x5F4,
+0x5F7,0x5F9,0x5FB,0x5FD,0x5FF,0x602,0x604,0x606,0x608,0x60A,0x60C,0x60F,0x611,0x613,0x615,0x617,
+0x619,0x61C,0x61E,0x620,0x622,0x624,0x626,0x629,0x62B,0x62D,0x62F,0x631,0x633,0x635,0x638,0x63A,
+0x63C,0x63E,0x640,0x642,0x644,0x646,0x649,0x64B,0x64D,0x64F,0x651,0x653,0x655,0x657,0x65A,0x65C,
+0x65E,0x660,0x662,0x664,0x666,0x668,0x66A,0x66C,0x66F,0x671,0x673,0x675,0x677,0x679,0x67B,0x67D,
+0x67F,0x681,0x683,0x685,0x688,0x68A,0x68C,0x68E,0x690,0x692,0x694,0x696,0x698,0x69A,0x69C,0x69E,
+0x6A0,0x6A2,0x6A4,0x6A6,0x6A8,0x6AB,0x6AD,0x6AF,0x6B1,0x6B3,0x6B5,0x6B7,0x6B9,0x6BB,0x6BD,0x6BF,
+0x6C1,0x6C3,0x6C5,0x6C7,0x6C9,0x6CB,0x6CD,0x6CF,0x6D1,0x6D3,0x6D5,0x6D7,0x6D9,0x6DB,0x6DD,0x6DF,
+0x6E1,0x6E3,0x6E5,0x6E7,0x6E9,0x6EB,0x6ED,0x6EF,0x6F1,0x6F3,0x6F5,0x6F7,0x6F9,0x6FB,0x6FD,0x6FF,
+0x701,0x703,0x705,0x707,0x709,0x70B,0x70C,0x70E,0x710,0x712,0x714,0x716,0x718,0x71A,0x71C,0x71E,
+0x720,0x722,0x724,0x726,0x728,0x72A,0x72C,0x72E,0x72F,0x731,0x733,0x735,0x737,0x739,0x73B,0x73D,
+0x73F,0x741,0x743,0x745,0x746,0x748,0x74A,0x74C,0x74E,0x750,0x752,0x754,0x756,0x758,0x759,0x75B,
+0x75D,0x75F,0x761,0x763,0x765,0x767,0x769,0x76A,0x76C,0x76E,0x770,0x772,0x774,0x776,0x778,0x779,
+0x77B,0x77D,0x77F,0x781,0x783,0x785,0x786,0x788,0x78A,0x78C,0x78E,0x790,0x791,0x793,0x795,0x797,
+0x799,0x79B,0x79D,0x79E,0x7A0,0x7A2,0x7A4,0x7A6,0x7A7,0x7A9,0x7AB,0x7AD,0x7AF,0x7B1,0x7B2,0x7B4,
+0x7B6,0x7B8,0x7BA,0x7BB,0x7BD,0x7BF,0x7C1,0x7C3,0x7C4,0x7C6,0x7C8,0x7CA,0x7CC,0x7CD,0x7CF,0x7D1,
+0x7D3,0x7D5,0x7D6,0x7D8,0x7DA,0x7DC,0x7DE,0x7DF,0x7E1,0x7E3,0x7E5,0x7E6,0x7E8,0x7EA,0x7EC,0x7ED,
+0x7EF,0x7F1,0x7F3,0x7F5,0x7F6,0x7F8,0x7FA,0x7FC,0x7FD,0x7FF,0x801,0x803,0x804,0x806,0x808,0x80A,
+0x80B,0x80D,0x80F,0x810,0x812,0x814,0x816,0x817,0x819,0x81B,0x81D,0x81E,0x820,0x822,0x823,0x825,
+0x827,0x829,0x82A,0x82C,0x82E,0x82F,0x831,0x833,0x835,0x836,0x838,0x83A,0x83B,0x83D,0x83F,0x841,
+0x842,0x844,0x846,0x847,0x849,0x84B,0x84C,0x84E,0x850,0x851,0x853,0x855,0x856,0x858,0x85A,0x85B,
+0x85D,0x85F,0x860,0x862,0x864,0x865,0x867,0x869,0x86A,0x86C,0x86E,0x86F,0x871,0x873,0x874,0x876,
+0x878,0x879,0x87B,0x87D,0x87E,0x880,0x881,0x883,0x885,0x886,0x888,0x88A,0x88B,0x88D,0x88F,0x890,
+0x892,0x893,0x895,0x897,0x898,0x89A,0x89C,0x89D,0x89F,0x8A0,0x8A2,0x8A4,0x8A5,0x8A7,0x8A8,0x8AA,
+0x8AC,0x8AD,0x8AF,0x8B0,0x8B2,0x8B4,0x8B5,0x8B7,0x8B8,0x8BA,0x8BC,0x8BD,0x8BF,0x8C0,0x8C2,0x8C4,
+0x8C5,0x8C7,0x8C8,0x8CA,0x8CB,0x8CD,0x8CF,0x8D0,0x8D2,0x8D3,0x8D5,0x8D6,0x8D8,0x8DA,0x8DB,0x8DD,
+0x8DE,0x8E0,0x8E1,0x8E3,0x8E4,0x8E6,0x8E8,0x8E9,0x8EB,0x8EC,0x8EE,0x8EF,0x8F1,0x8F2,0x8F4,0x8F5,
+0x8F7,0x8F9,0x8FA,0x8FC,0x8FD,0x8FF,0x900,0x902,0x903,0x905,0x906,0x908,0x909,0x90B,0x90C,0x90E,
+0x90F,0x911,0x912,0x914,0x916,0x917,0x919,0x91A,0x91C,0x91D,0x91F,0x920,0x922,0x923,0x925,0x926,
+0x928,0x929,0x92B,0x92C,0x92E,0x92F,0x931,0x932,0x934,0x935,0x936,0x938,0x939,0x93B,0x93C,0x93E,
+0x93F,0x941,0x942,0x944,0x945,0x947,0x948,0x94A,0x94B,0x94D,0x94E,0x950,0x951,0x952,0x954,0x955,
+0x957,0x958,0x95A,0x95B,0x95D,0x95E,0x960,0x961,0x962,0x964,0x965,0x967,0x968,0x96A,0x96B,0x96D,
+0x96E,0x96F,0x971,0x972,0x974,0x975,0x977,0x978,0x979,0x97B,0x97C,0x97E,0x97F,0x981,0x982,0x983,
+0x985,0x986,0x988,0x989,0x98A,0x98C,0x98D,0x98F,0x990,0x992,0x993,0x994,0x996,0x997,0x999,0x99A,
+0x99B,0x99D,0x99E,0x9A0,0x9A1,0x9A2,0x9A4,0x9A5,0x9A6,0x9A8,0x9A9,0x9AB,0x9AC,0x9AD,0x9AF,0x9B0,
+0x9B2,0x9B3,0x9B4,0x9B6,0x9B7,0x9B8,0x9BA,0x9BB,0x9BD,0x9BE,0x9BF,0x9C1,0x9C2,0x9C3,0x9C5,0x9C6,
+0x9C7,0x9C9,0x9CA,0x9CC,0x9CD,0x9CE,0x9D0,0x9D1,0x9D2,0x9D4,0x9D5,0x9D6,0x9D8,0x9D9,0x9DA,0x9DC,
+0x9DD,0x9DE,0x9E0,0x9E1,0x9E2,0x9E4,0x9E5,0x9E6,0x9E8,0x9E9,0x9EA,0x9EC,0x9ED,0x9EE,0x9F0,0x9F1,
+0x9F2,0x9F4,0x9F5,0x9F6,0x9F8,0x9F9,0x9FA,0x9FC,0x9FD,0x9FE,0xA00,0xA01,0xA02,0xA04,0xA05,0xA06,
+0xA07,0xA09,0xA0A,0xA0B,0xA0D,0xA0E,0xA0F,0xA11,0xA12,0xA13,0xA14,0xA16,0xA17,0xA18,0xA1A,0xA1B,
+0xA1C,0xA1D,0xA1F,0xA20,0xA21,0xA23,0xA24,0xA25,0xA26,0xA28,0xA29,0xA2A,0xA2C,0xA2D,0xA2E,0xA2F,
+0xA31,0xA32,0xA33,0xA34,0xA36,0xA37,0xA38,0xA3A,0xA3B,0xA3C,0xA3D,0xA3F,0xA40,0xA41,0xA42,0xA44,
+0xA45,0xA46,0xA47,0xA49,0xA4A,0xA4B,0xA4C,0xA4E,0xA4F,0xA50,0xA51,0xA53,0xA54,0xA55,0xA56,0xA58,
+0xA59,0xA5A,0xA5B,0xA5C,0xA5E,0xA5F,0xA60,0xA61,0xA63,0xA64,0xA65,0xA66,0xA67,0xA69,0xA6A,0xA6B,
+0xA6C,0xA6E,0xA6F,0xA70,0xA71,0xA72,0xA74,0xA75,0xA76,0xA77,0xA79,0xA7A,0xA7B,0xA7C,0xA7D,0xA7F,
+0xA80,0xA81,0xA82,0xA83,0xA85,0xA86,0xA87,0xA88,0xA89,0xA8B,0xA8C,0xA8D,0xA8E,0xA8F,0xA91,0xA92,
+0xA93,0xA94,0xA95,0xA96,0xA98,0xA99,0xA9A,0xA9B,0xA9C,0xA9E,0xA9F,0xAA0,0xAA1,0xAA2,0xAA3,0xAA5,
+0xAA6,0xAA7,0xAA8,0xAA9,0xAAA,0xAAC,0xAAD,0xAAE,0xAAF,0xAB0,0xAB1,0xAB3,0xAB4,0xAB5,0xAB6,0xAB7,
+0xAB8,0xAB9,0xABB,0xABC,0xABD,0xABE,0xABF,0xAC0,0xAC2,0xAC3,0xAC4,0xAC5,0xAC6,0xAC7,0xAC8,0xACA,
+0xACB,0xACC,0xACD,0xACE,0xACF,0xAD0,0xAD1,0xAD3,0xAD4,0xAD5,0xAD6,0xAD7,0xAD8,0xAD9,0xADB,0xADC,
+0xADD,0xADE,0xADF,0xAE0,0xAE1,0xAE2,0xAE3,0xAE5,0xAE6,0xAE7,0xAE8,0xAE9,0xAEA,0xAEB,0xAEC,0xAEE,
+0xAEF,0xAF0,0xAF1,0xAF2,0xAF3,0xAF4,0xAF5,0xAF6,0xAF7,0xAF9,0xAFA,0xAFB,0xAFC,0xAFD,0xAFE,0xAFF,
+0xB00,0xB01,0xB02,0xB04,0xB05,0xB06,0xB07,0xB08,0xB09,0xB0A,0xB0B,0xB0C,0xB0D,0xB0E,0xB0F,0xB11,
+0xB12,0xB13,0xB14,0xB15,0xB16,0xB17,0xB18,0xB19,0xB1A,0xB1B,0xB1C,0xB1D,0xB1E,0xB20,0xB21,0xB22,
+0xB23,0xB24,0xB25,0xB26,0xB27,0xB28,0xB29,0xB2A,0xB2B,0xB2C,0xB2D,0xB2E,0xB2F,0xB30,0xB32,0xB33,
+0xB34,0xB35,0xB36,0xB37,0xB38,0xB39,0xB3A,0xB3B,0xB3C,0xB3D,0xB3E,0xB3F,0xB40,0xB41,0xB42,0xB43,
+0xB44,0xB45,0xB46,0xB47,0xB48,0xB49,0xB4B,0xB4C,0xB4D,0xB4E,0xB4F,0xB50,0xB51,0xB52,0xB53,0xB54,
+0xB55,0xB56,0xB57,0xB58,0xB59,0xB5A,0xB5B,0xB5C,0xB5D,0xB5E,0xB5F,0xB60,0xB61,0xB62,0xB63,0xB64,
+0xB65,0xB66,0xB67,0xB68,0xB69,0xB6A,0xB6B,0xB6C,0xB6D,0xB6E,0xB6F,0xB70,0xB71,0xB72,0xB73,0xB74,
+0xB75,0xB76,0xB77,0xB78,0xB79,0xB7A,0xB7B,0xB7C,0xB7D,0xB7E,0xB7F,0xB80,0xB81,0xB82,0xB83,0xB84,
+0xB85,0xB86,0xB87,0xB88,0xB89,0xB8A,0xB8B,0xB8C,0xB8D,0xB8E,0xB8F,0xB8F,0xB90,0xB91,0xB92,0xB93,
+0xB94,0xB95,0xB96,0xB97,0xB98,0xB99,0xB9A,0xB9B,0xB9C,0xB9D,0xB9E,0xB9F,0xBA0,0xBA1,0xBA2,0xBA3,
+0xBA4,0xBA5,0xBA6,0xBA7,0xBA7,0xBA8,0xBA9,0xBAA,0xBAB,0xBAC,0xBAD,0xBAE,0xBAF,0xBB0,0xBB1,0xBB2,
+0xBB3,0xBB4,0xBB5,0xBB6,0xBB7,0xBB8,0xBB8,0xBB9,0xBBA,0xBBB,0xBBC,0xBBD,0xBBE,0xBBF,0xBC0,0xBC1,
+0xBC2,0xBC3,0xBC4,0xBC5,0xBC5,0xBC6,0xBC7,0xBC8,0xBC9,0xBCA,0xBCB,0xBCC,0xBCD,0xBCE,0xBCF,0xBD0,
+0xBD1,0xBD1,0xBD2,0xBD3,0xBD4,0xBD5,0xBD6,0xBD7,0xBD8,0xBD9,0xBDA,0xBDB,0xBDB,0xBDC,0xBDD,0xBDE,
+0xBDF,0xBE0,0xBE1,0xBE2,0xBE3,0xBE4,0xBE4,0xBE5,0xBE6,0xBE7,0xBE8,0xBE9,0xBEA,0xBEB,0xBEC,0xBED,
+0xBED,0xBEE,0xBEF,0xBF0,0xBF1,0xBF2,0xBF3,0xBF4,0xBF5,0xBF5,0xBF6,0xBF7,0xBF8,0xBF9,0xBFA,0xBFB,
+0xBFC,0xBFC,0xBFD,0xBFE,0xBFF,0xC00,0xC01,0xC02,0xC03,0xC03,0xC04,0xC05,0xC06,0xC07,0xC08,0xC09,
+0xC0A,0xC0A,0xC0B,0xC0C,0xC0D,0xC0E,0xC0F,0xC10,0xC10,0xC11,0xC12,0xC13,0xC14,0xC15,0xC16,0xC16,
+0xC17,0xC18,0xC19,0xC1A,0xC1B,0xC1C,0xC1C,0xC1D,0xC1E,0xC1F,0xC20,0xC21,0xC21,0xC22,0xC23,0xC24,
+0xC25,0xC26,0xC27,0xC27,0xC28,0xC29,0xC2A,0xC2B,0xC2C,0xC2C,0xC2D,0xC2E,0xC2F,0xC30,0xC31,0xC31,
+0xC32,0xC33,0xC34,0xC35,0xC36,0xC36,0xC37,0xC38,0xC39,0xC3A,0xC3B,0xC3B,0xC3C,0xC3D,0xC3E,0xC3F,
+0xC3F,0xC40,0xC41,0xC42,0xC43,0xC44,0xC44,0xC45,0xC46,0xC47,0xC48,0xC48,0xC49,0xC4A,0xC4B,0xC4C,
+0xC4D,0xC4D,0xC4E,0xC4F,0xC50,0xC51,0xC51,0xC52,0xC53,0xC54,0xC55,0xC55,0xC56,0xC57,0xC58,0xC59,
+0xC59,0xC5A,0xC5B,0xC5C,0xC5D,0xC5D,0xC5E,0xC5F,0xC60,0xC61,0xC61,0xC62,0xC63,0xC64,0xC64,0xC65,
+0xC66,0xC67,0xC68,0xC68,0xC69,0xC6A,0xC6B,0xC6C,0xC6C,0xC6D,0xC6E,0xC6F,0xC6F,0xC70,0xC71,0xC72,
+0xC73,0xC73,0xC74,0xC75,0xC76,0xC76,0xC77,0xC78,0xC79,0xC7A,0xC7A,0xC7B,0xC7C,0xC7D,0xC7D,0xC7E,
+0xC7F,0xC80,0xC80,0xC81,0xC82,0xC83,0xC83,0xC84,0xC85,0xC86,0xC87,0xC87,0xC88,0xC89,0xC8A,0xC8A,
+0xC8B,0xC8C,0xC8D,0xC8D,0xC8E,0xC8F,0xC90,0xC90,0xC91,0xC92,0xC93,0xC93,0xC94,0xC95,0xC96,0xC96,
+0xC97,0xC98,0xC99,0xC99,0xC9A,0xC9B,0xC9C,0xC9C,0xC9D,0xC9E,0xC9F,0xC9F,0xCA0,0xCA1,0xCA1,0xCA2,
+0xCA3,0xCA4,0xCA4,0xCA5,0xCA6,0xCA7,0xCA7,0xCA8,0xCA9,0xCAA,0xCAA,0xCAB,0xCAC,0xCAC,0xCAD,0xCAE,
+0xCAF,0xCAF,0xCB0,0xCB1,0xCB2,0xCB2,0xCB3,0xCB4,0xCB4,0xCB5,0xCB6,0xCB7,0xCB7,0xCB8,0xCB9,0xCB9,
+0xCBA,0xCBB,0xCBC,0xCBC,0xCBD,0xCBE,0xCBE,0xCBF,0xCC0,0xCC1,0xCC1,0xCC2,0xCC3,0xCC3,0xCC4,0xCC5,
+0xCC6,0xCC6,0xCC7,0xCC8,0xCC8,0xCC9,0xCCA,0xCCA,0xCCB,0xCCC,0xCCD,0xCCD,0xCCE,0xCCF,0xCCF,0xCD0,
+0xCD1,0xCD1,0xCD2,0xCD3,0xCD4,0xCD4,0xCD5,0xCD6,0xCD6,0xCD7,0xCD8,0xCD8,0xCD9,0xCDA,0xCDA,0xCDB,
+0xCDC,0xCDC,0xCDD,0xCDE,0xCDF,0xCDF,0xCE0,0xCE1,0xCE1,0xCE2,0xCE3,0xCE3,0xCE4,0xCE5,0xCE5,0xCE6,
+0xCE7,0xCE7,0xCE8,0xCE9,0xCE9,0xCEA,0xCEB,0xCEB,0xCEC,0xCED,0xCED,0xCEE,0xCEF,0xCEF,0xCF0,0xCF1,
+0xCF1,0xCF2,0xCF3,0xCF3,0xCF4,0xCF5,0xCF5,0xCF6,0xCF7,0xCF7,0xCF8,0xCF9,0xCF9,0xCFA,0xCFB,0xCFB,
+0xCFC,0xCFD,0xCFD,0xCFE,0xCFF,0xCFF,0xD00,0xD01,0xD01,0xD02,0xD03,0xD03,0xD04,0xD05,0xD05,0xD06,
+0xD07,0xD07,0xD08,0xD09,0xD09,0xD0A,0xD0A,0xD0B,0xD0C,0xD0C,0xD0D,0xD0E,0xD0E,0xD0F,0xD10,0xD10,
+0xD11,0xD12,0xD12,0xD13,0xD13,0xD14,0xD15,0xD15,0xD16,0xD17,0xD17,0xD18,0xD19,0xD19,0xD1A,0xD1A,
+0xD1B,0xD1C,0xD1C,0xD1D,0xD1E,0xD1E,0xD1F,0xD1F,0xD20,0xD21,0xD21,0xD22,0xD23,0xD23,0xD24,0xD25,
+0xD25,0xD26,0xD26,0xD27,0xD28,0xD28,0xD29,0xD29,0xD2A,0xD2B,0xD2B,0xD2C,0xD2D,0xD2D,0xD2E,0xD2E,
+0xD2F,0xD30,0xD30,0xD31,0xD32,0xD32,0xD33,0xD33,0xD34,0xD35,0xD35,0xD36,0xD36,0xD37,0xD38,0xD38
+};
+
+static const unsigned short CutoffMul6581_44100Hz[] = { //generated by curvegen.c
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,0x081,
+0x081,0x086,0x08B,0x08F,0x094,0x099,0x09D,0x0A2,0x0A6,0x0AB,0x0B0,0x0B4,0x0B9,0x0BE,0x0C2,0x0C7,
+0x0CB,0x0D0,0x0D5,0x0D9,0x0DE,0x0E2,0x0E7,0x0EB,0x0F0,0x0F5,0x0F9,0x0FE,0x102,0x107,0x10B,0x110,
+0x114,0x119,0x11D,0x122,0x126,0x12B,0x12F,0x134,0x138,0x13D,0x141,0x146,0x14A,0x14F,0x153,0x157,
+0x15C,0x160,0x165,0x169,0x16E,0x172,0x176,0x17B,0x17F,0x183,0x188,0x18C,0x191,0x195,0x199,0x19E,
+0x1A2,0x1A6,0x1AB,0x1AF,0x1B3,0x1B8,0x1BC,0x1C0,0x1C5,0x1C9,0x1CD,0x1D2,0x1D6,0x1DA,0x1DE,0x1E3,
+0x1E7,0x1EB,0x1EF,0x1F4,0x1F8,0x1FC,0x200,0x205,0x209,0x20D,0x211,0x215,0x21A,0x21E,0x222,0x226,
+0x22A,0x22F,0x233,0x237,0x23B,0x23F,0x243,0x248,0x24C,0x250,0x254,0x258,0x25C,0x260,0x265,0x269,
+0x26D,0x271,0x275,0x279,0x27D,0x281,0x285,0x289,0x28D,0x292,0x296,0x29A,0x29E,0x2A2,0x2A6,0x2AA,
+0x2AE,0x2B2,0x2B6,0x2BA,0x2BE,0x2C2,0x2C6,0x2CA,0x2CE,0x2D2,0x2D6,0x2DA,0x2DE,0x2E2,0x2E6,0x2EA,
+0x2EE,0x2F2,0x2F6,0x2FA,0x2FD,0x301,0x305,0x309,0x30D,0x311,0x315,0x319,0x31D,0x321,0x325,0x328,
+0x32C,0x330,0x334,0x338,0x33C,0x340,0x344,0x347,0x34B,0x34F,0x353,0x357,0x35B,0x35E,0x362,0x366,
+0x36A,0x36E,0x371,0x375,0x379,0x37D,0x381,0x384,0x388,0x38C,0x390,0x393,0x397,0x39B,0x39F,0x3A2,
+0x3A6,0x3AA,0x3AE,0x3B1,0x3B5,0x3B9,0x3BD,0x3C0,0x3C4,0x3C8,0x3CB,0x3CF,0x3D3,0x3D6,0x3DA,0x3DE,
+0x3E1,0x3E5,0x3E9,0x3EC,0x3F0,0x3F4,0x3F7,0x3FB,0x3FF,0x402,0x406,0x409,0x40D,0x411,0x414,0x418,
+0x41B,0x41F,0x423,0x426,0x42A,0x42D,0x431,0x435,0x438,0x43C,0x43F,0x443,0x446,0x44A,0x44D,0x451,
+0x455,0x458,0x45C,0x45F,0x463,0x466,0x46A,0x46D,0x471,0x474,0x478,0x47B,0x47F,0x482,0x486,0x489,
+0x48C,0x490,0x493,0x497,0x49A,0x49E,0x4A1,0x4A5,0x4A8,0x4AB,0x4AF,0x4B2,0x4B6,0x4B9,0x4BD,0x4C0,
+0x4C3,0x4C7,0x4CA,0x4CE,0x4D1,0x4D4,0x4D8,0x4DB,0x4DE,0x4E2,0x4E5,0x4E8,0x4EC,0x4EF,0x4F3,0x4F6,
+0x4F9,0x4FD,0x500,0x503,0x507,0x50A,0x50D,0x510,0x514,0x517,0x51A,0x51E,0x521,0x524,0x528,0x52B,
+0x52E,0x531,0x535,0x538,0x53B,0x53E,0x542,0x545,0x548,0x54B,0x54F,0x552,0x555,0x558,0x55B,0x55F,
+0x562,0x565,0x568,0x56C,0x56F,0x572,0x575,0x578,0x57B,0x57F,0x582,0x585,0x588,0x58B,0x58F,0x592,
+0x595,0x598,0x59B,0x59E,0x5A1,0x5A5,0x5A8,0x5AB,0x5AE,0x5B1,0x5B4,0x5B7,0x5BA,0x5BD,0x5C1,0x5C4,
+0x5C7,0x5CA,0x5CD,0x5D0,0x5D3,0x5D6,0x5D9,0x5DC,0x5DF,0x5E2,0x5E5,0x5E9,0x5EC,0x5EF,0x5F2,0x5F5,
+0x5F8,0x5FB,0x5FE,0x601,0x604,0x607,0x60A,0x60D,0x610,0x613,0x616,0x619,0x61C,0x61F,0x622,0x625,
+0x628,0x62B,0x62E,0x631,0x634,0x637,0x63A,0x63D,0x640,0x643,0x645,0x648,0x64B,0x64E,0x651,0x654,
+0x657,0x65A,0x65D,0x660,0x663,0x666,0x669,0x66B,0x66E,0x671,0x674,0x677,0x67A,0x67D,0x680,0x682,
+0x685,0x688,0x68B,0x68E,0x691,0x694,0x696,0x699,0x69C,0x69F,0x6A2,0x6A5,0x6A7,0x6AA,0x6AD,0x6B0,
+0x6B3,0x6B6,0x6B8,0x6BB,0x6BE,0x6C1,0x6C4,0x6C6,0x6C9,0x6CC,0x6CF,0x6D2,0x6D4,0x6D7,0x6DA,0x6DD,
+0x6DF,0x6E2,0x6E5,0x6E8,0x6EA,0x6ED,0x6F0,0x6F3,0x6F5,0x6F8,0x6FB,0x6FE,0x700,0x703,0x706,0x708,
+0x70B,0x70E,0x711,0x713,0x716,0x719,0x71B,0x71E,0x721,0x723,0x726,0x729,0x72B,0x72E,0x731,0x733,
+0x736,0x739,0x73B,0x73E,0x741,0x743,0x746,0x749,0x74B,0x74E,0x750,0x753,0x756,0x758,0x75B,0x75E,
+0x760,0x763,0x765,0x768,0x76B,0x76D,0x770,0x772,0x775,0x778,0x77A,0x77D,0x77F,0x782,0x784,0x787,
+0x78A,0x78C,0x78F,0x791,0x794,0x796,0x799,0x79B,0x79E,0x7A0,0x7A3,0x7A5,0x7A8,0x7AB,0x7AD,0x7B0,
+0x7B2,0x7B5,0x7B7,0x7BA,0x7BC,0x7BF,0x7C1,0x7C4,0x7C6,0x7C9,0x7CB,0x7CE,0x7D0,0x7D2,0x7D5,0x7D7,
+0x7DA,0x7DC,0x7DF,0x7E1,0x7E4,0x7E6,0x7E9,0x7EB,0x7ED,0x7F0,0x7F2,0x7F5,0x7F7,0x7FA,0x7FC,0x7FF,
+0x801,0x803,0x806,0x808,0x80B,0x80D,0x80F,0x812,0x814,0x817,0x819,0x81B,0x81E,0x820,0x823,0x825,
+0x827,0x82A,0x82C,0x82E,0x831,0x833,0x835,0x838,0x83A,0x83D,0x83F,0x841,0x844,0x846,0x848,0x84B,
+0x84D,0x84F,0x852,0x854,0x856,0x858,0x85B,0x85D,0x85F,0x862,0x864,0x866,0x869,0x86B,0x86D,0x86F,
+0x872,0x874,0x876,0x879,0x87B,0x87D,0x87F,0x882,0x884,0x886,0x888,0x88B,0x88D,0x88F,0x892,0x894,
+0x896,0x898,0x89A,0x89D,0x89F,0x8A1,0x8A3,0x8A6,0x8A8,0x8AA,0x8AC,0x8AE,0x8B1,0x8B3,0x8B5,0x8B7,
+0x8BA,0x8BC,0x8BE,0x8C0,0x8C2,0x8C4,0x8C7,0x8C9,0x8CB,0x8CD,0x8CF,0x8D2,0x8D4,0x8D6,0x8D8,0x8DA,
+0x8DC,0x8DF,0x8E1,0x8E3,0x8E5,0x8E7,0x8E9,0x8EB,0x8EE,0x8F0,0x8F2,0x8F4,0x8F6,0x8F8,0x8FA,0x8FC,
+0x8FF,0x901,0x903,0x905,0x907,0x909,0x90B,0x90D,0x90F,0x912,0x914,0x916,0x918,0x91A,0x91C,0x91E,
+0x920,0x922,0x924,0x926,0x928,0x92B,0x92D,0x92F,0x931,0x933,0x935,0x937,0x939,0x93B,0x93D,0x93F,
+0x941,0x943,0x945,0x947,0x949,0x94B,0x94D,0x94F,0x951,0x953,0x955,0x957,0x959,0x95B,0x95D,0x95F,
+0x961,0x963,0x965,0x967,0x969,0x96B,0x96D,0x96F,0x971,0x973,0x975,0x977,0x979,0x97B,0x97D,0x97F,
+0x981,0x983,0x985,0x987,0x989,0x98B,0x98D,0x98F,0x991,0x993,0x995,0x997,0x999,0x99B,0x99C,0x99E,
+0x9A0,0x9A2,0x9A4,0x9A6,0x9A8,0x9AA,0x9AC,0x9AE,0x9B0,0x9B2,0x9B3,0x9B5,0x9B7,0x9B9,0x9BB,0x9BD,
+0x9BF,0x9C1,0x9C3,0x9C5,0x9C6,0x9C8,0x9CA,0x9CC,0x9CE,0x9D0,0x9D2,0x9D4,0x9D5,0x9D7,0x9D9,0x9DB,
+0x9DD,0x9DF,0x9E1,0x9E2,0x9E4,0x9E6,0x9E8,0x9EA,0x9EC,0x9ED,0x9EF,0x9F1,0x9F3,0x9F5,0x9F7,0x9F8,
+0x9FA,0x9FC,0x9FE,0xA00,0xA02,0xA03,0xA05,0xA07,0xA09,0xA0B,0xA0C,0xA0E,0xA10,0xA12,0xA14,0xA15,
+0xA17,0xA19,0xA1B,0xA1C,0xA1E,0xA20,0xA22,0xA24,0xA25,0xA27,0xA29,0xA2B,0xA2C,0xA2E,0xA30,0xA32,
+0xA33,0xA35,0xA37,0xA39,0xA3A,0xA3C,0xA3E,0xA40,0xA41,0xA43,0xA45,0xA47,0xA48,0xA4A,0xA4C,0xA4E,
+0xA4F,0xA51,0xA53,0xA54,0xA56,0xA58,0xA5A,0xA5B,0xA5D,0xA5F,0xA60,0xA62,0xA64,0xA65,0xA67,0xA69,
+0xA6B,0xA6C,0xA6E,0xA70,0xA71,0xA73,0xA75,0xA76,0xA78,0xA7A,0xA7B,0xA7D,0xA7F,0xA80,0xA82,0xA84,
+0xA85,0xA87,0xA89,0xA8A,0xA8C,0xA8E,0xA8F,0xA91,0xA92,0xA94,0xA96,0xA97,0xA99,0xA9B,0xA9C,0xA9E,
+0xAA0,0xAA1,0xAA3,0xAA4,0xAA6,0xAA8,0xAA9,0xAAB,0xAAC,0xAAE,0xAB0,0xAB1,0xAB3,0xAB5,0xAB6,0xAB8,
+0xAB9,0xABB,0xABC,0xABE,0xAC0,0xAC1,0xAC3,0xAC4,0xAC6,0xAC8,0xAC9,0xACB,0xACC,0xACE,0xACF,0xAD1,
+0xAD3,0xAD4,0xAD6,0xAD7,0xAD9,0xADA,0xADC,0xADE,0xADF,0xAE1,0xAE2,0xAE4,0xAE5,0xAE7,0xAE8,0xAEA,
+0xAEB,0xAED,0xAEE,0xAF0,0xAF2,0xAF3,0xAF5,0xAF6,0xAF8,0xAF9,0xAFB,0xAFC,0xAFE,0xAFF,0xB01,0xB02,
+0xB04,0xB05,0xB07,0xB08,0xB0A,0xB0B,0xB0D,0xB0E,0xB10,0xB11,0xB13,0xB14,0xB16,0xB17,0xB19,0xB1A,
+0xB1C,0xB1D,0xB1F,0xB20,0xB22,0xB23,0xB24,0xB26,0xB27,0xB29,0xB2A,0xB2C,0xB2D,0xB2F,0xB30,0xB32,
+0xB33,0xB35,0xB36,0xB37,0xB39,0xB3A,0xB3C,0xB3D,0xB3F,0xB40,0xB42,0xB43,0xB44,0xB46,0xB47,0xB49,
+0xB4A,0xB4C,0xB4D,0xB4E,0xB50,0xB51,0xB53,0xB54,0xB55,0xB57,0xB58,0xB5A,0xB5B,0xB5C,0xB5E,0xB5F,
+0xB61,0xB62,0xB63,0xB65,0xB66,0xB68,0xB69,0xB6A,0xB6C,0xB6D,0xB6F,0xB70,0xB71,0xB73,0xB74,0xB75,
+0xB77,0xB78,0xB7A,0xB7B,0xB7C,0xB7E,0xB7F,0xB80,0xB82,0xB83,0xB84,0xB86,0xB87,0xB89,0xB8A,0xB8B,
+0xB8D,0xB8E,0xB8F,0xB91,0xB92,0xB93,0xB95,0xB96,0xB97,0xB99,0xB9A,0xB9B,0xB9D,0xB9E,0xB9F,0xBA1,
+0xBA2,0xBA3,0xBA5,0xBA6,0xBA7,0xBA8,0xBAA,0xBAB,0xBAC,0xBAE,0xBAF,0xBB0,0xBB2,0xBB3,0xBB4,0xBB6,
+0xBB7,0xBB8,0xBB9,0xBBB,0xBBC,0xBBD,0xBBF,0xBC0,0xBC1,0xBC2,0xBC4,0xBC5,0xBC6,0xBC8,0xBC9,0xBCA,
+0xBCB,0xBCD,0xBCE,0xBCF,0xBD0,0xBD2,0xBD3,0xBD4,0xBD5,0xBD7,0xBD8,0xBD9,0xBDB,0xBDC,0xBDD,0xBDE,
+0xBE0,0xBE1,0xBE2,0xBE3,0xBE4,0xBE6,0xBE7,0xBE8,0xBE9,0xBEB,0xBEC,0xBED,0xBEE,0xBF0,0xBF1,0xBF2,
+0xBF3,0xBF5,0xBF6,0xBF7,0xBF8,0xBF9,0xBFB,0xBFC,0xBFD,0xBFE,0xBFF,0xC01,0xC02,0xC03,0xC04,0xC05,
+0xC07,0xC08,0xC09,0xC0A,0xC0B,0xC0D,0xC0E,0xC0F,0xC10,0xC11,0xC13,0xC14,0xC15,0xC16,0xC17,0xC19,
+0xC1A,0xC1B,0xC1C,0xC1D,0xC1E,0xC20,0xC21,0xC22,0xC23,0xC24,0xC25,0xC27,0xC28,0xC29,0xC2A,0xC2B,
+0xC2C,0xC2E,0xC2F,0xC30,0xC31,0xC32,0xC33,0xC34,0xC36,0xC37,0xC38,0xC39,0xC3A,0xC3B,0xC3C,0xC3E,
+0xC3F,0xC40,0xC41,0xC42,0xC43,0xC44,0xC46,0xC47,0xC48,0xC49,0xC4A,0xC4B,0xC4C,0xC4D,0xC4F,0xC50,
+0xC51,0xC52,0xC53,0xC54,0xC55,0xC56,0xC57,0xC59,0xC5A,0xC5B,0xC5C,0xC5D,0xC5E,0xC5F,0xC60,0xC61,
+0xC62,0xC63,0xC65,0xC66,0xC67,0xC68,0xC69,0xC6A,0xC6B,0xC6C,0xC6D,0xC6E,0xC6F,0xC71,0xC72,0xC73,
+0xC74,0xC75,0xC76,0xC77,0xC78,0xC79,0xC7A,0xC7B,0xC7C,0xC7D,0xC7E,0xC7F,0xC81,0xC82,0xC83,0xC84,
+0xC85,0xC86,0xC87,0xC88,0xC89,0xC8A,0xC8B,0xC8C,0xC8D,0xC8E,0xC8F,0xC90,0xC91,0xC92,0xC93,0xC94,
+0xC95,0xC96,0xC97,0xC99,0xC9A,0xC9B,0xC9C,0xC9D,0xC9E,0xC9F,0xCA0,0xCA1,0xCA2,0xCA3,0xCA4,0xCA5,
+0xCA6,0xCA7,0xCA8,0xCA9,0xCAA,0xCAB,0xCAC,0xCAD,0xCAE,0xCAF,0xCB0,0xCB1,0xCB2,0xCB3,0xCB4,0xCB5,
+0xCB6,0xCB7,0xCB8,0xCB9,0xCBA,0xCBB,0xCBC,0xCBD,0xCBE,0xCBF,0xCC0,0xCC1,0xCC2,0xCC3,0xCC4,0xCC5,
+0xCC6,0xCC7,0xCC8,0xCC9,0xCCA,0xCCA,0xCCB,0xCCC,0xCCD,0xCCE,0xCCF,0xCD0,0xCD1,0xCD2,0xCD3,0xCD4,
+0xCD5,0xCD6,0xCD7,0xCD8,0xCD9,0xCDA,0xCDB,0xCDC,0xCDD,0xCDE,0xCDF,0xCE0,0xCE0,0xCE1,0xCE2,0xCE3,
+0xCE4,0xCE5,0xCE6,0xCE7,0xCE8,0xCE9,0xCEA,0xCEB,0xCEC,0xCED,0xCEE,0xCEF,0xCEF,0xCF0,0xCF1,0xCF2,
+0xCF3,0xCF4,0xCF5,0xCF6,0xCF7,0xCF8,0xCF9,0xCFA,0xCFA,0xCFB,0xCFC,0xCFD,0xCFE,0xCFF,0xD00,0xD01,
+0xD02,0xD03,0xD04,0xD04,0xD05,0xD06,0xD07,0xD08,0xD09,0xD0A,0xD0B,0xD0C,0xD0D,0xD0D,0xD0E,0xD0F,
+0xD10,0xD11,0xD12,0xD13,0xD14,0xD15,0xD15,0xD16,0xD17,0xD18,0xD19,0xD1A,0xD1B,0xD1C,0xD1C,0xD1D,
+0xD1E,0xD1F,0xD20,0xD21,0xD22,0xD23,0xD23,0xD24,0xD25,0xD26,0xD27,0xD28,0xD29,0xD29,0xD2A,0xD2B,
+0xD2C,0xD2D,0xD2E,0xD2F,0xD2F,0xD30,0xD31,0xD32,0xD33,0xD34,0xD34,0xD35,0xD36,0xD37,0xD38,0xD39,
+0xD3A,0xD3A,0xD3B,0xD3C,0xD3D,0xD3E,0xD3F,0xD3F,0xD40,0xD41,0xD42,0xD43,0xD44,0xD44,0xD45,0xD46,
+0xD47,0xD48,0xD48,0xD49,0xD4A,0xD4B,0xD4C,0xD4D,0xD4D,0xD4E,0xD4F,0xD50,0xD51,0xD51,0xD52,0xD53,
+0xD54,0xD55,0xD55,0xD56,0xD57,0xD58,0xD59,0xD5A,0xD5A,0xD5B,0xD5C,0xD5D,0xD5D,0xD5E,0xD5F,0xD60,
+0xD61,0xD61,0xD62,0xD63,0xD64,0xD65,0xD65,0xD66,0xD67,0xD68,0xD69,0xD69,0xD6A,0xD6B,0xD6C,0xD6C,
+0xD6D,0xD6E,0xD6F,0xD70,0xD70,0xD71,0xD72,0xD73,0xD73,0xD74,0xD75,0xD76,0xD77,0xD77,0xD78,0xD79,
+0xD7A,0xD7A,0xD7B,0xD7C,0xD7D,0xD7D,0xD7E,0xD7F,0xD80,0xD80,0xD81,0xD82,0xD83,0xD83,0xD84,0xD85,
+0xD86,0xD86,0xD87,0xD88,0xD89,0xD89,0xD8A,0xD8B,0xD8C,0xD8C,0xD8D,0xD8E,0xD8F,0xD8F,0xD90,0xD91,
+0xD92,0xD92,0xD93,0xD94,0xD94,0xD95,0xD96,0xD97,0xD97,0xD98,0xD99,0xD9A,0xD9A,0xD9B,0xD9C,0xD9C,
+0xD9D,0xD9E,0xD9F,0xD9F,0xDA0,0xDA1,0xDA1,0xDA2,0xDA3,0xDA4,0xDA4,0xDA5,0xDA6,0xDA6,0xDA7,0xDA8,
+0xDA9,0xDA9,0xDAA,0xDAB,0xDAB,0xDAC,0xDAD,0xDAE,0xDAE,0xDAF,0xDB0,0xDB0,0xDB1,0xDB2,0xDB2,0xDB3,
+0xDB4,0xDB5,0xDB5,0xDB6,0xDB7,0xDB7,0xDB8,0xDB9,0xDB9,0xDBA,0xDBB,0xDBB,0xDBC,0xDBD,0xDBD,0xDBE,
+0xDBF,0xDC0,0xDC0,0xDC1,0xDC2,0xDC2,0xDC3,0xDC4,0xDC4,0xDC5,0xDC6,0xDC6,0xDC7,0xDC8,0xDC8,0xDC9,
+0xDCA,0xDCA,0xDCB,0xDCC,0xDCC,0xDCD,0xDCE,0xDCE,0xDCF,0xDD0,0xDD0,0xDD1,0xDD2,0xDD2,0xDD3,0xDD4,
+0xDD4,0xDD5,0xDD6,0xDD6,0xDD7,0xDD8,0xDD8,0xDD9,0xDD9,0xDDA,0xDDB,0xDDB,0xDDC,0xDDD,0xDDD,0xDDE,
+0xDDF,0xDDF,0xDE0,0xDE1,0xDE1,0xDE2,0xDE2,0xDE3,0xDE4,0xDE4,0xDE5,0xDE6,0xDE6,0xDE7,0xDE8,0xDE8,
+0xDE9,0xDE9,0xDEA,0xDEB,0xDEB,0xDEC,0xDED,0xDED,0xDEE,0xDEE,0xDEF,0xDF0,0xDF0,0xDF1,0xDF2,0xDF2,
+0xDF3,0xDF3,0xDF4,0xDF5,0xDF5,0xDF6,0xDF7,0xDF7,0xDF8,0xDF8,0xDF9,0xDFA,0xDFA,0xDFB,0xDFB,0xDFC,
+0xDFD,0xDFD,0xDFE,0xDFE,0xDFF,0xE00,0xE00,0xE01,0xE02,0xE02,0xE03,0xE03,0xE04,0xE05,0xE05,0xE06,
+0xE06,0xE07,0xE08,0xE08,0xE09,0xE09,0xE0A,0xE0A,0xE0B,0xE0C,0xE0C,0xE0D,0xE0D,0xE0E,0xE0F,0xE0F,
+0xE10,0xE10,0xE11,0xE12,0xE12,0xE13,0xE13,0xE14,0xE14,0xE15,0xE16,0xE16,0xE17,0xE17,0xE18,0xE18,
+0xE19,0xE1A,0xE1A,0xE1B,0xE1B,0xE1C,0xE1C,0xE1D,0xE1E,0xE1E,0xE1F,0xE1F,0xE20,0xE20,0xE21,0xE22,
+0xE22,0xE23,0xE23,0xE24,0xE24,0xE25,0xE26,0xE26,0xE27,0xE27,0xE28,0xE28,0xE29,0xE29,0xE2A,0xE2B,
+0xE2B,0xE2C,0xE2C,0xE2D,0xE2D,0xE2E,0xE2E,0xE2F,0xE30,0xE30,0xE31,0xE31,0xE32,0xE32,0xE33,0xE33,
+0xE34,0xE34,0xE35,0xE36,0xE36,0xE37,0xE37,0xE38,0xE38,0xE39,0xE39,0xE3A,0xE3A,0xE3B,0xE3B,0xE3C,
+0xE3C,0xE3D,0xE3E,0xE3E,0xE3F,0xE3F,0xE40,0xE40,0xE41,0xE41,0xE42,0xE42,0xE43,0xE43,0xE44,0xE44
+};
+
+
+static const unsigned char SawTriangle [] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0x0F,0x0F,0x0F,0x0F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1E,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0x0F,0x0F,0x0F,0x1F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3E,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0x0F,0x0F,0x0F,0x0F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1E,0x1E,0x1F,0x1F,0x1F,0x1F,0x3F,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0x0F,0x0F,0x1F,0x1F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x83,0x83,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x87,0x87,0x87,0x8F,
+ 0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0xE0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE3,0xE3,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF1,
+ 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,
+ 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+static const unsigned char PulseTriangle [] = { //can be substituted by PulseSaw with mirroring the upper half (like with triangle-waveform)
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x3C,0x3F,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x5E,0x5F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x40,0x60,0x60,0x6F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x60,0x40,0x40,0x60,0x60,0x60,0x60,0x70,0x77,
+ 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x60,0x60,0x40,0x40,0x40,0x60,0x60,0x60,0x60,0x70,0x60,0x60,0x60,0x70,0x70,0x70,0x78,0x7B,
+ 0x60,0x60,0x60,0x70,0x60,0x70,0x70,0x70,0x70,0x70,0x70,0x78,0x78,0x78,0x78,0x7C,0x78,0x78,0x78,0x7C,0x78,0x7C,0x7C,0x7E,0x7C,0x7E,0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x8E,0x9F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xAF,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xA0,0xA0,0xA0,0xA0,0xB7,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xA0,0x80,0x80,0x80,0x80,0x80,0x80,0xA0,0xA0,0xA0,0xA0,0xA0,0xB0,0xA0,0xB0,0xB0,0xBB,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xB0,0xB0,0xA0,0xB0,0xB0,0xB8,0xB0,0xB8,0xB8,0xBC,0xB0,0xB8,0xB8,0xB8,0xB8,0xBC,0xBC,0xBE,0xBC,0xBC,0xBE,0xBF,0xBE,0xBF,0xBF,0xBF,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0x80,0x80,0x80,0xC0,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xCF,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0xC0,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD7,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD0,0xD0,0xD9,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD0,0xC0,0xD0,0xD0,0xD0,0xD0,0xD8,0xD8,0xDC,0xD0,0xD0,0xD8,0xD8,0xD8,0xDC,0xDC,0xDE,0xDC,0xDC,0xDE,0xDF,0xDE,0xDF,0xDF,0xDF,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xE0,0xE0,0xE0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE7,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE8,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE8,0xEC,0xE0,0xE0,0xE0,0xE8,0xE8,0xE8,0xEC,0xEE,0xEC,0xEC,0xEC,0xEE,0xEE,0xEF,0xEF,0xEF,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF4,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF4,0xF0,0xF4,0xF4,0xF6,0xF6,0xF7,0xF7,0xF7,
+ 0xF0,0xF0,0xF0,0xF8,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFA,0xFA,0xFB,0xFB,0xFB,
+ 0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFC,0xFD,0xFD,0xFD,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,
+ 0xFB,0xFB,0xFB,0xFA,0xFA,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF7,0xF7,0xF7,0xF6,0xF6,0xF4,0xF4,0xF0,0xF4,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF4,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0xE0,0xF0,0xF0,0xF0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xEF,0xEF,0xEF,0xEE,0xEE,0xEC,0xEC,0xE8,0xEE,0xEC,0xE8,0xE8,0xE8,0xE0,0xE0,0xE0,0xEC,0xE8,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE8,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE7,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0xC0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xDF,0xDF,0xDF,0xDE,0xDF,0xDE,0xDC,0xDC,0xDE,0xDC,0xDC,0xD8,0xD8,0xD8,0xD0,0xD0,0xDC,0xD8,0xD8,0xD0,0xD0,0xD0,0xD0,0xC0,0xD0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xD9,0xD0,0xD0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xD7,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,
+ 0xCF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0xC0,0x80,0x80,0x80,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0xBF,0xBF,0xBF,0xBE,0xBF,0xBE,0xBC,0xBC,0xBE,0xBC,0xBC,0xB8,0xB8,0xB8,0xB8,0xB0,0xBC,0xB8,0xB8,0xB0,0xB8,0xB0,0xB0,0xB0,0xB0,0xB0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xBB,0xB0,0xB0,0xA0,0xB0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0x80,0x80,0x80,0x80,0x80,0xA0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0xB7,0xB0,0xA0,0xA0,0xA0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0xAF,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x80,0x00,0x00,0x00,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9F,0x9E,0x88,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,
+ 0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x7F,0x7F,0x7F,0x7F,0x7F,0x7E,0x7E,0x7C,0x7E,0x7C,0x7C,0x78,0x7C,0x78,0x78,0x78,0x7C,0x78,0x78,0x78,0x78,0x70,0x70,0x70,0x78,0x70,0x70,0x60,0x70,0x60,0x60,0x60,
+ 0x7B,0x78,0x70,0x70,0x70,0x60,0x60,0x60,0x70,0x60,0x60,0x60,0x60,0x40,0x40,0x40,0x60,0x60,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x00,0x00,0x00,
+ 0x77,0x70,0x60,0x60,0x60,0x60,0x40,0x40,0x60,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x6F,0x64,0x60,0x40,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5F,0x5E,0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x3F,0x3F,0x3E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+static const unsigned char PulseSawtooth [] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x1F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x0C,0x1C,0x3F,0x1E,0x3F,0x3F,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x5F,0x0C,0x5F,0x5F,0x5F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x40,0x40,0x6F,0x40,0x6F,0x6F,0x6F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x61,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x70,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x70,0x40,0x60,0x60,0x77,0x60,0x77,0x77,0x77,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x40,0x40,0x60,0x40,0x60,0x60,0x79,
+ 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x40,0x40,0x60,0x60,0x60,0x60,0x78,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x60,0x70,0x70,0x78,0x70,0x79,0x7B,0x7B,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x70,0x60,0x60,0x60,0x70,0x60,0x70,0x70,0x7C,0x60,0x70,0x70,0x70,0x70,0x70,0x70,0x7C,0x70,0x78,0x78,0x7C,0x78,0x7C,0x7C,0x7D,
+ 0x70,0x78,0x78,0x78,0x78,0x78,0x78,0x7C,0x78,0x7C,0x7C,0x7E,0x7C,0x7E,0x7E,0x7E,0x7C,0x7C,0x7C,0x7E,0x7E,0x7F,0x7F,0x7F,0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0xFF,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x8D,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x8E,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x8F,0x80,0x80,0x80,0x9F,0x80,0x9F,0x9F,0x9F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x87,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x83,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x81,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x87,0x80,0x80,0x80,0x87,0x80,0x8F,0xAF,0xAF,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,
+ 0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xA0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xA0,0x80,0x80,0x80,0xA0,0x80,0xA3,0xB7,0xB7,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xB1,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xB0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xB0,0x80,0xA0,0xA0,0xB0,0xA0,0xB8,0xB9,0xBB,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xA0,0x80,0x80,0x80,0xA0,0x80,0xA0,0xA0,0xB8,0x80,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xB8,0xA0,0xB0,0xB0,0xB8,0xB0,0xBC,0xBC,0xBD,
+ 0xA0,0xB0,0xB0,0xB0,0xB0,0xB8,0xB8,0xBC,0xB0,0xB8,0xB8,0xBC,0xB8,0xBC,0xBE,0xBE,0xB8,0xBC,0xBC,0xBE,0xBC,0xBE,0xBE,0xBF,0xBE,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC7,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC3,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x80,0x80,0xC0,0x80,0xC0,0xC0,0xC1,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC7,0xC0,0xC0,0xC0,0xC7,0xC0,0xCF,0xCF,0xCF,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC3,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x80,0x80,0xC0,0x80,0xC0,0xC0,0xC0,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC1,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC1,0xC7,0xD7,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD0,0xC0,0xC0,0xC0,0xD0,0xC0,0xD0,0xD8,0xDB,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD8,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD8,0xC0,0xC0,0xC0,0xD8,0xD0,0xD8,0xD8,0xDD,
+ 0xC0,0xC0,0xC0,0xD0,0xC0,0xD0,0xD0,0xDC,0xD0,0xD8,0xD8,0xDC,0xD8,0xDC,0xDC,0xDE,0xD8,0xDC,0xDC,0xDE,0xDC,0xDE,0xDE,0xDF,0xDE,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE3,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xC0,0xC0,0xE0,0xC0,0xE0,0xE0,0xE1,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE1,0xE3,0xE7,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xC0,0xC0,0xE0,0xC0,0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xE0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xEB,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE8,0xE0,0xE8,0xE8,0xED,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xEC,0xE0,0xE0,0xE0,0xEC,0xE8,0xEC,0xEC,0xEE,0xE8,0xE8,0xE8,0xEC,0xEC,0xEE,0xEE,0xEF,0xEC,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,0xE0,0xE0,0xE0,0xF0,0xE0,0xF0,0xF0,0xF0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF3,
+ 0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF5,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF4,0xF4,0xF6,0xF0,0xF0,0xF0,0xF4,0xF0,0xF4,0xF6,0xF7,0xF4,0xF6,0xF6,0xF7,0xF7,0xF7,0xF7,0xF7,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF8,0xF0,0xF0,0xF0,0xF0,0xF0,0xF8,0xF8,0xF8,0xF0,0xF0,0xF0,0xF8,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF9,
+ 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFA,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFB,0xF8,0xFA,0xFA,0xFB,0xFB,0xFB,0xFB,0xFB,
+ 0xF8,0xF8,0xF8,0xFC,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFD,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFD,
+ 0xFC,0xFC,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+static const unsigned char PulseSawTriangle [] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x70,0x60,0x20,0x70,0x70,0x70,0x70,0x70,0x78,0x78,0x78,0x7C,0x7C,0x7E,0x7E,0x7F,0x7F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1E,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x8C,0x9F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x00,0x00,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xCF,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
+ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE0,0xC0,0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE3,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,
+ 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
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 @@
+
+//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
+ //}
+}
+
diff --git a/lib/rbcodec/codecs/cRSID/README.txt b/lib/rbcodec/codecs/cRSID/README.txt
new file mode 100644
index 0000000000..3a806b65ed
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/README.txt
@@ -0,0 +1,39 @@
+ cRSID by Hermit (Mihaly Horvath) - Year 2022
+ --------------------------------------------
+
+This is a serious integer-only update (rewrite) to my cSID and cSID-light
+commandline SID-players, aiming for an ongoing inclusion into RockBox,
+as per a request by Ninja earlier at CSDb. He will do the integration.
+
+The name now contains the 'R' because now a RealSID-like environment-mode
+(CIA, VIC, IRQ, NMI) is supported more-or-less ('RealSIDmode' in source).
+There are still many RSID tunes that are not played properly, mainly
+the tricky ones which use DC04 or DD0C as jump-addresses or RTI placeholders,
+like for example 'Hi Fi Sky', and other modern digi tunes.
+I don't feel like debugging these complex tunes now...
+PSID-only playback has improved a lot since cSID-light-1.1,
+and now many PlaySID-digis are supported as well if that still matters.
+
+The CPU and ADSR went through serious timing improvements,
+it's now can be called cycle-exact, and hardrestarts and delaybugs are now
+simulated well, no missed notes, whatever.
+
+This release also contains shared and static library forms for better
+inclusion in other SID-playback projects (like FlexSID for example).
+I completely eliminated global variables and definitions, except a
+'cRSID_c64' instance which is for faster access of struct members.
+(Emulated C64 memory accesses are made to this for faster operation.)
+
+More info (the API for the library) is seen in the 'libcRSID.h' file.
+
+It has been tried already on a SanDisk RockBox device and tunes not
+containing digis are already played on it fine. Tunes with 2SID/3SID or
+digis however are too much for the player (38MHz..192MHz ARM) at this form.
+So maybe the code will be optimized by eliminating overheads of structs,
+pointers, optimizing function-calls, inlining, and by other possible means.
+
+Hopefully in the near future the outdated TinySID engine will be replaced
+in the RockBox source-tree...
+
+License is still WTF: Do what the fuck you want with this code, but
+ it would be nice mentioning me as the original author.
diff --git a/lib/rbcodec/codecs/cRSID/host/audio.c b/lib/rbcodec/codecs/cRSID/host/audio.c
new file mode 100644
index 0000000000..2e06279113
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/host/audio.c
@@ -0,0 +1,62 @@
+
+#ifdef CRSID_PLATFORM_PC
+
+#include <SDL/SDL.h>
+
+
+void cRSID_soundCallback(void* userdata, unsigned char *buf, int len) {
+ cRSID_generateSound( (cRSID_C64instance*)userdata, buf, len );
+}
+
+
+void* cRSID_initSound(cRSID_C64instance* C64, unsigned short samplerate, unsigned short buflen) {
+ static SDL_AudioSpec soundspec;
+ if ( SDL_Init(SDL_INIT_AUDIO) < 0 ) {
+ fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); return NULL;
+ }
+ soundspec.freq=samplerate; soundspec.channels=1; soundspec.format=AUDIO_S16;
+ soundspec.samples=buflen; soundspec.userdata=C64; soundspec.callback=cRSID_soundCallback;
+ if ( SDL_OpenAudio(&soundspec, NULL) < 0 ) {
+ fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); return NULL;
+ }
+ return (void*)&soundspec;
+}
+
+
+void cRSID_closeSound (void) {
+ SDL_PauseAudio(1); SDL_CloseAudio();
+}
+
+
+void cRSID_startSound (void) {
+ SDL_PauseAudio(0);
+}
+
+
+void cRSID_stopSound (void) {
+ SDL_PauseAudio(1);
+}
+
+
+void cRSID_generateSound(cRSID_C64instance* C64instance, unsigned char *buf, unsigned short len) {
+ static unsigned short i;
+ static int Output;
+ for(i=0;i<len;i+=2) {
+ Output=cRSID_generateSample(C64instance); //cRSID_emulateC64(C64instance);
+ //if (Output>=32767) Output=32767; else if (Output<=-32768) Output=-32768; //saturation logic on overflow
+ buf[i]=Output&0xFF; buf[i+1]=Output>>8;
+ }
+}
+
+
+#endif
+
+
+static inline signed short cRSID_generateSample (cRSID_C64instance* C64) { //call this from custom buffer-filler
+ static int Output;
+ Output=cRSID_emulateC64(C64);
+ if (C64->PSIDdigiMode) Output += cRSID_playPSIDdigi(C64);
+ if (Output>=32767) Output=32767; else if (Output<=-32768) Output=-32768; //saturation logic on overflow
+ return (signed short) Output;
+}
+
diff --git a/lib/rbcodec/codecs/cRSID/host/file.c b/lib/rbcodec/codecs/cRSID/host/file.c
new file mode 100644
index 0000000000..c87f37ebb4
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/host/file.c
@@ -0,0 +1,60 @@
+
+
+#ifdef CRSID_PLATFORM_PC
+
+int cRSID_loadSIDfile (unsigned char* SIDfileData, char* filename, int maxlen) {
+ static signed short Data;
+ static signed int SizeCnt;
+ static FILE *SIDfile;
+
+ if ( (SIDfile=fopen(filename,"rb")) == NULL ) return CRSID_ERROR_LOAD;
+
+ SizeCnt=0;
+
+ while ( (Data=fgetc(SIDfile)) != EOF ) {
+ if (SizeCnt >= maxlen) return CRSID_ERROR_LOAD;
+ SIDfileData[SizeCnt] = Data; SizeCnt++;
+ }
+
+ fclose(SIDfile);
+ return SizeCnt;
+}
+
+#endif
+
+
+cRSID_SIDheader* cRSID_processSIDfile(cRSID_C64instance* C64, unsigned char* filedata, int filesize) {
+ int i;
+ unsigned short SIDdataOffset;
+ cRSID_SIDheader* SIDheader;
+ static const char MagicStringPSID[]="PSID";
+ //static const char MagicStringRSID[]="RSID";
+
+ C64->SIDheader = SIDheader = (cRSID_SIDheader*) filedata;
+
+ for (i=0x0000; i < 0xA000; ++i) C64->RAMbank[i]=0; //fresh start (maybe some bugged SIDs want 0 at certain RAM-locations)
+ for (i=0xC000; i < 0xD000; ++i) C64->RAMbank[i]=0;
+
+ if ( SIDheader->MagicString[0] != 'P' && SIDheader->MagicString[0] != 'R' ) return NULL;
+ for (i=1; i < (int)(sizeof(MagicStringPSID)-1); ++i) { if (SIDheader->MagicString[i] != MagicStringPSID[i]) return NULL; }
+ C64->RealSIDmode = ( SIDheader->MagicString[0] == 'R' );
+
+ if (SIDheader->LoadAddressH==0 && SIDheader->LoadAddressH==0) { //load-address taken from first 2 bytes of the C64 PRG
+ C64->LoadAddress = (filedata[SIDheader->HeaderSize+1]<<8) + (filedata[SIDheader->HeaderSize+0]);
+ SIDdataOffset = SIDheader->HeaderSize+2;
+ }
+ else { //load-adress taken from SID-header
+ C64->LoadAddress = (SIDheader->LoadAddressH<<8) + (SIDheader->LoadAddressL);
+ SIDdataOffset = SIDheader->HeaderSize;
+ }
+
+ for (i=SIDdataOffset; i<filesize; ++i) C64->RAMbank [ C64->LoadAddress + (i-SIDdataOffset) ] = filedata[i];
+
+ i = C64->LoadAddress + (filesize-SIDdataOffset);
+ C64->EndAddress = (i<0x10000) ? i : 0xFFFF;
+
+ C64->PSIDdigiMode = ( !C64->RealSIDmode && (SIDheader->ModelFormatStandard & 2) );
+
+ return C64->SIDheader;
+}
+
diff --git a/lib/rbcodec/codecs/cRSID/libcRSID.c b/lib/rbcodec/codecs/cRSID/libcRSID.c
new file mode 100644
index 0000000000..f7ef713e12
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/libcRSID.c
@@ -0,0 +1,134 @@
+// cRSID lightweight (integer-only) RealSID library (with API-calls) by Hermit (Mihaly Horvath), Year 2022
+// License: WTF - do what the fuck you want with the code, but please mention me as the original author
+
+#include <stdlib.h>
+//#include <stdint.h>
+#ifdef CRSID_PLATFORM_PC
+ #include <stdio.h>
+#endif
+
+#include "libcRSID.h"
+
+#include "C64/C64.c"
+#include "host/file.c"
+#include "host/audio.c"
+
+
+cRSID_C64instance* cRSID_init (unsigned short samplerate, unsigned short buflen) {
+ static cRSID_C64instance* C64 = &cRSID_C64;
+
+ C64 = cRSID_createC64 (C64, samplerate);
+#ifdef CRSID_PLATFORM_PC
+ if ( cRSID_initSound (C64, samplerate,buflen) == NULL) return NULL;
+#else
+ if (buflen) return C64; //this is here just to eliminate unused 'buflen' variable warning
+#endif
+
+ return C64;
+}
+
+
+void cRSID_initSIDtune (cRSID_C64instance* C64, cRSID_SIDheader* SIDheader, char subtune) { //subtune: 1..255
+ static const unsigned char PowersOf2[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
+ unsigned int InitTimeout=10000000; //allowed instructions, value should be selected to allow for long-running memory-copiers in init-routines (e.g. Synth Sample)
+
+ if (subtune==0) subtune = 1;
+ else if (subtune > SIDheader->SubtuneAmount) subtune = SIDheader->SubtuneAmount;
+ C64->SubTune = subtune;
+
+ cRSID_setC64(C64); cRSID_initC64(C64); //cRSID_writeMemC64(C64,0xD418,0xF); //set C64 hardware and init (reset) it
+
+ //determine init-address:
+ C64->InitAddress = ((SIDheader->InitAddressH)<<8) + (SIDheader->InitAddressL); //get info from BASIC-startupcode for some tunes
+ if (C64->RAMbank[1] == 0x37) { //are there SIDs with routine under IO area? some PSIDs don't set bank-registers themselves
+ if ( (0xA000 <= C64->InitAddress && C64->InitAddress < 0xC000)
+ || (C64->LoadAddress < 0xC000 && C64->EndAddress >= 0xA000) ) C64->RAMbank[1] = 0x36;
+ else if (C64->InitAddress >= 0xE000 || C64->EndAddress >=0xE000) C64->RAMbank[1] = 0x35;
+ }
+ cRSID_initCPU( &C64->CPU, C64->InitAddress ); //prepare init-routine call
+ C64->CPU.A = subtune - 1;
+
+ if (!C64->RealSIDmode) {
+ //call init-routine:
+ for (InitTimeout=10000000; InitTimeout>0; InitTimeout--) { if ( cRSID_emulateCPU()>=0xFE ) break; } //give error when timed out?
+ }
+
+ //determine timing-source, if CIA, replace FrameCycles previouisly set to VIC-timing
+ if (subtune>32) C64->TimerSource = C64->SIDheader->SubtuneTimeSources[0] & 0x80; //subtunes above 32 should use subtune32's timing
+ else C64->TimerSource = C64->SIDheader->SubtuneTimeSources[(32-subtune)>>3] & PowersOf2[(subtune-1)&7];
+ if (C64->TimerSource || C64->IObankWR[0xDC05]!=0x40 || C64->IObankWR[0xDC04]!=0x24) { //CIA1-timing (probably multispeed tune)
+ C64->FrameCycles = ( ( C64->IObankWR[0xDC04] + (C64->IObankWR[0xDC05]<<8) ) ); //<< 4) / C64->ClockRatio;
+ C64->TimerSource = 1; //if init-routine changed DC04 or DC05, assume CIA-timing
+ }
+
+ //determine playaddress:
+ C64->PlayAddress = (SIDheader->PlayAddressH<<8) + SIDheader->PlayAddressL;
+ if (C64->PlayAddress) { //normal play-address called with JSR
+ if (C64->RAMbank[1] == 0x37) { //are there SIDs with routine under IO area?
+ if (0xA000 <= C64->PlayAddress && C64->PlayAddress < 0xC000) C64->RAMbank[1] = 0x36;
+ }
+ else if (C64->PlayAddress >= 0xE000) C64->RAMbank[1] = 0x35; //player under KERNAL (e.g. Crystal Kingdom Dizzy)
+ }
+ else { //IRQ-playaddress for multispeed-tunes set by init-routine (some tunes turn off KERNAL ROM but doesn't set IRQ-vector!)
+ C64->PlayAddress = (C64->RAMbank[1] & 3) < 2 ? cRSID_readMemC64(C64,0xFFFE) + (cRSID_readMemC64(C64,0xFFFF)<<8) //for PSID
+ : cRSID_readMemC64(C64,0x314) + (cRSID_readMemC64(C64,0x315)<<8);
+ if (C64->PlayAddress==0) { //if 0, still try with RSID-mode fallback
+ cRSID_initCPU( &C64->CPU, C64->PlayAddress ); //point CPU to play-routine
+ C64->Finished=1; C64->Returned=1; return;
+ }
+ }
+
+ if (!C64->RealSIDmode) { //prepare (PSID) play-routine playback:
+ cRSID_initCPU( &C64->CPU, C64->PlayAddress ); //point CPU to play-routine
+ C64->FrameCycleCnt=0; C64->Finished=1; C64->SampleCycleCnt=0; //C64->CIAisSet=0;
+ }
+ else { C64->Finished=0; C64->Returned=0; }
+
+}
+
+
+#ifdef CRSID_PLATFORM_PC
+
+
+char cRSID_playSIDfile(cRSID_C64instance* C64, char* filename, char subtune) {
+ static cRSID_SIDheader* SIDheader;
+
+ SIDheader = cRSID_loadSIDtune(C64,filename);
+ if (SIDheader==NULL) return CRSID_ERROR_LOAD;
+
+ cRSID_initSIDtune (C64 , SIDheader , subtune);
+ cRSID_playSIDtune ();
+
+ return CRSID_STATUS_OK;
+}
+
+
+cRSID_SIDheader* cRSID_loadSIDtune(cRSID_C64instance* C64, char* filename) {
+ enum SIDspecs { CRSID_FILESIZE_MAX = 100000 };
+ int FileSize;
+ static unsigned char SIDfileData [CRSID_FILESIZE_MAX]; //use memset?
+
+ FileSize = cRSID_loadSIDfile( SIDfileData, filename, CRSID_FILESIZE_MAX);
+ if ( FileSize == CRSID_ERROR_LOAD ) return NULL;
+
+ return cRSID_processSIDfile ( C64, SIDfileData, FileSize );
+}
+
+
+void cRSID_close() {
+ cRSID_closeSound();
+}
+
+
+void cRSID_playSIDtune (void) {
+ cRSID_startSound();
+}
+
+
+void cRSID_pauseSIDtune (void) {
+ cRSID_stopSound();
+}
+
+
+#endif
+
diff --git a/lib/rbcodec/codecs/cRSID/libcRSID.h b/lib/rbcodec/codecs/cRSID/libcRSID.h
new file mode 100644
index 0000000000..23c8dbcd28
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/libcRSID.h
@@ -0,0 +1,221 @@
+// cRSID lightweight RealSID (integer-only) library-header (with API-calls) by Hermit (Mihaly Horvath)
+
+#ifndef LIBCRSID_HEADER
+#define LIBCRSID_HEADER //used to prevent double inclusion of this header-file
+
+
+enum cRSID_Specifications { CRSID_SIDCOUNT_MAX=3, CRSID_CIACOUNT=2 };
+enum cRSID_StatusCodes { CRSID_STATUS_OK=0, CRSID_ERROR_INIT=-1, CRSID_ERROR_LOAD=-2 };
+
+
+typedef struct cRSID_SIDheader cRSID_SIDheader;
+typedef struct cRSID_C64instance cRSID_C64instance;
+typedef struct cRSID_CPUinstance cRSID_CPUinstance;
+typedef struct cRSID_SIDinstance cRSID_SIDinstance;
+typedef struct cRSID_CIAinstance cRSID_CIAinstance;
+typedef struct cRSID_VICinstance cRSID_VICinstance;
+
+
+cRSID_C64instance cRSID_C64; //the only global object (for faster & simpler access than with struct-pointers, in some places)
+
+
+// Main API functions (mainly in libcRSID.c)
+cRSID_C64instance* cRSID_init (unsigned short samplerate, unsigned short buflen); //init emulation objects and sound
+#ifdef CRSID_PLATFORM_PC
+char cRSID_playSIDfile (cRSID_C64instance* C64, char* filename, char subtune); //simple single-call SID playback
+cRSID_SIDheader* cRSID_loadSIDtune (cRSID_C64instance* C64, char* filename); //load and process SID-filedata to C64 memory
+void cRSID_playSIDtune (void); //start/continue playback (enable playing audio-buffer)
+void cRSID_pauseSIDtune (void); //pause playback (enable playing audio-buffer)
+void cRSID_close (void); //close sound etc.
+#endif
+cRSID_SIDheader* cRSID_processSIDfile (cRSID_C64instance* C64, unsigned char* filedata, int filesize); //in host/file.c, copy SID-data to C64 memory
+void cRSID_initSIDtune (cRSID_C64instance* C64, cRSID_SIDheader* SIDheader, char subtune); //init tune/subtune
+static inline signed short cRSID_generateSample (cRSID_C64instance* C64); //in host/audio.c, calculate a single sample
+
+
+//Internal functions
+
+// C64/C64.c
+cRSID_C64instance* cRSID_createC64 (cRSID_C64instance* C64, unsigned short samplerate);
+void cRSID_setC64 (cRSID_C64instance* C64); //configure hardware (SIDs) for SID-tune
+void cRSID_initC64 (cRSID_C64instance* C64); //hard-reset
+int cRSID_emulateC64 (cRSID_C64instance* C64);
+static inline short cRSID_playPSIDdigi (cRSID_C64instance* C64);
+// C64/MEM.c
+static inline unsigned char* cRSID_getMemReadPtr (register unsigned short address); //for global cSID_C64 fast-access
+static inline unsigned char* cRSID_getMemReadPtrC64 (cRSID_C64instance* C64, register unsigned short address); //maybe slower
+static inline unsigned char* cRSID_getMemWritePtr (register unsigned short address); //for global cSID_C64 fast-access
+static inline unsigned char* cRSID_getMemWritePtrC64 (cRSID_C64instance* C64, register unsigned short address); //maybe slower
+static inline unsigned char cRSID_readMem (register unsigned short address); //for global cSID_C64 fast-access
+static inline unsigned char cRSID_readMemC64 (cRSID_C64instance* C64, register unsigned short address); //maybe slower
+static inline void cRSID_writeMem (register unsigned short address, register unsigned char data); //for global cSID_C64 fast-access
+static inline void cRSID_writeMemC64 (cRSID_C64instance* C64, register unsigned short address, register unsigned char data); //maybe slower
+void cRSID_setROMcontent (cRSID_C64instance* C64); //KERNAL, BASIC
+void cRSID_initMem (cRSID_C64instance* C64);
+// C64/CPU.c
+void cRSID_initCPU (cRSID_CPUinstance* CPU, unsigned short mempos);
+unsigned char cRSID_emulateCPU (void); //direct instances inside for hopefully faster operation
+static inline char cRSID_handleCPUinterrupts (cRSID_CPUinstance* CPU);
+// C64/SID.c
+void cRSID_createSIDchip (cRSID_C64instance* C64, cRSID_SIDinstance* SID, unsigned short model, unsigned short baseaddress);
+void cRSID_initSIDchip (cRSID_SIDinstance* SID);
+void cRSID_emulateADSRs (cRSID_SIDinstance *SID, char cycles);
+int cRSID_emulateWaves (cRSID_SIDinstance* SID);
+// C64/CIA.c
+void cRSID_createCIAchip (cRSID_C64instance* C64, cRSID_CIAinstance* CIA, unsigned short baseaddress);
+void cRSID_initCIAchip (cRSID_CIAinstance* CIA);
+static inline char cRSID_emulateCIA (cRSID_CIAinstance* CIA, char cycles);
+static inline void cRSID_writeCIAIRQmask (cRSID_CIAinstance* CIA, unsigned char value);
+static inline void cRSID_acknowledgeCIAIRQ (cRSID_CIAinstance* CIA);
+// C64/VIC.c
+void cRSID_createVICchip (cRSID_C64instance* C64, cRSID_VICinstance* VIC, unsigned short baseaddress);
+void cRSID_initVICchip (cRSID_VICinstance* VIC);
+static inline char cRSID_emulateVIC (cRSID_VICinstance* VIC, char cycles);
+static inline void cRSID_acknowledgeVICrasterIRQ (cRSID_VICinstance* VIC);
+
+// host/file.c
+#ifdef CRSID_PLATFORM_PC
+int cRSID_loadSIDfile (unsigned char* SIDfileData, char* filename, int maxlen); //load SID-file to a memory location (and return size)
+#endif
+// host/audio.c
+#ifdef CRSID_PLATFORM_PC
+void* cRSID_initSound (cRSID_C64instance* C64, unsigned short samplerate, unsigned short buflen);
+void cRSID_startSound (void);
+void cRSID_stopSound (void);
+void cRSID_closeSound (void);
+void cRSID_generateSound (cRSID_C64instance* C64, unsigned char* buf, unsigned short len);
+#endif
+
+
+struct cRSID_SIDheader { //Offset: default/info:
+ unsigned char MagicString[4]; //$00 - "PSID" or "RSID" (RSID must provide Reset-circumstances & CIA/VIC-interrupts)
+ unsigned char VersionH00; //$04
+ unsigned char Version; //$05 - 1 for PSID v1, 2..4 for PSID v2..4 or RSID v2..4 (3/4 has 2SID/3SID support)
+ unsigned char HeaderSizeH00; //$06
+ unsigned char HeaderSize; //$07 - $76 for v1, $7C for v2..4
+ unsigned char LoadAddressH,LoadAddressL; //$08 - if 0 it's a PRG and its loadaddress is used (RSID: 0, PRG-loadaddress>=$07E8)
+ unsigned char InitAddressH,InitAddressL; //$0A - if 0 it's taken from load-address (but should be set) (RSID: don't point to ROM, 0 if BASICflag set)
+ unsigned char PlayAddressH,PlayAddressL; //$0C - if 0 play-routine-call is set by the initializer (always true for RSID)
+ unsigned char SubtuneAmountH00; //$0E
+ unsigned char SubtuneAmount; //$0F - 1..256
+ unsigned char DefaultSubtuneH00; //$10
+ unsigned char DefaultSubtune; //$11 - 1..256 (optional, defaults to 1)
+ unsigned char SubtuneTimeSources[4]; //$12 - 0:Vsync / 1:CIA1 (for PSID) (LSB is subtune1, MSB above 32) , always 0 for RSID
+ char Title[32]; //$16 - strings are using 1252 codepage
+ char Author[32]; //$36
+ char ReleaseInfo[32]; //$56
+ //SID v2 additions: (if SID2/SID3 model is set to unknown, they're set to the same model as SID1)
+ unsigned char ModelFormatStandardH; //$76 - bit9&8/7&6/5&4: SID3/2/1 model (00:?,01:6581,10:8580,11:both), bit3&2:VideoStandard..
+ unsigned char ModelFormatStandard; //$77 ..(01:PAL,10:NTSC,11:both), bit1:(0:C64,1:PlaySIDsamples/RSID_BASICflag), bit0:(0:builtin-player,1:MUS)
+ unsigned char RelocStartPage; //$78 - v2NG specific, if 0 the SID doesn't write outside its data-range, if $FF there's no place for driver
+ unsigned char RelocFreePages; //$79 - size of area from RelocStartPage for driver-relocation (RSID: must not contain ROM or 0..$3FF)
+ unsigned char SID2baseAddress; //$7A - (SID2BASE-$d000)/16 //SIDv3-relevant, only $42..$FE values are valid ($d420..$DFE0), else no SID2
+ unsigned char SID3baseAddress; //$7B - (SID3BASE-$d000)/16 //SIDv4-relevant, only $42..$FE values are valid ($d420..$DFE0), else no SID3
+}; //music-program follows right after the header
+
+
+struct cRSID_CPUinstance {
+ cRSID_C64instance* C64; //reference to the containing C64
+ unsigned int PC;
+ short int A, SP;
+ unsigned char X, Y, ST; //STATUS-flags: N V - B D I Z C
+ unsigned char PrevNMI; //used for NMI leading edge detection
+};
+
+
+struct cRSID_SIDinstance {
+ //SID-chip data:
+ cRSID_C64instance* C64; //reference to the containing C64
+ unsigned short ChipModel; //values: 8580 / 6581
+ unsigned short BaseAddress; //SID-baseaddress location in C64-memory (IO)
+ unsigned char* BasePtr; //SID-baseaddress location in host's memory
+ //ADSR-related:
+ unsigned char ADSRstate[15];
+ unsigned short RateCounter[15];
+ unsigned char EnvelopeCounter[15];
+ unsigned char ExponentCounter[15];
+ //Wave-related:
+ int PhaseAccu[15]; //28bit precision instead of 24bit
+ int PrevPhaseAccu[15]; //(integerized ClockRatio fractionals, WebSID has similar solution)
+ unsigned char SyncSourceMSBrise;
+ unsigned int RingSourceMSB;
+ unsigned int NoiseLFSR[15];
+ unsigned int PrevWavGenOut[15];
+ unsigned char PrevWavData[15];
+ //Filter-related:
+ int PrevLowPass;
+ int PrevBandPass;
+ //Output-stage:
+ signed int PrevVolume; //lowpass-filtered version of Volume-band register
+};
+
+
+struct cRSID_CIAinstance {
+ cRSID_C64instance* C64; //reference to the containing C64
+ char ChipModel; //old or new CIA? (have 1 cycle difference in cases)
+ unsigned short BaseAddress; //CIA-baseaddress location in C64-memory (IO)
+ unsigned char* BasePtrWR; //CIA-baseaddress location in host's memory for writing
+ unsigned char* BasePtrRD; //CIA-baseaddress location in host's memory for reading
+};
+
+
+struct cRSID_VICinstance {
+ cRSID_C64instance* C64; //reference to the containing C64
+ char ChipModel; //(timing differences between models?)
+ unsigned short BaseAddress; //VIC-baseaddress location in C64-memory (IO)
+ unsigned char* BasePtrWR; //VIC-baseaddress location in host's memory for writing
+ unsigned char* BasePtrRD; //VIC-baseaddress location in host's memory for reading
+ unsigned short RasterLines;
+ unsigned char RasterRowCycles;
+ unsigned char RowCycleCnt;
+};
+
+
+struct cRSID_C64instance {
+ //platform-related:
+ unsigned short SampleRate;
+ //C64-machine related:
+ unsigned char VideoStandard; //0:NTSC, 1:PAL (based on the SID-header field)
+ unsigned int CPUfrequency;
+ unsigned short SampleClockRatio; //ratio of CPU-clock and samplerate
+ //SID-file related:
+ union {
+ cRSID_SIDheader* SIDheader;
+ char* SIDfileData;
+ };
+ unsigned short Attenuation;
+ char RealSIDmode;
+ char PSIDdigiMode;
+ unsigned char SubTune;
+ unsigned short LoadAddress;
+ unsigned short InitAddress;
+ unsigned short PlayAddress;
+ unsigned short EndAddress;
+ char TimerSource; //for current subtune, 0:VIC, 1:CIA (as in SID-header)
+ //PSID-playback related:
+ //char CIAisSet; //for dynamic CIA setting from player-routine (RealSID substitution)
+ int FrameCycles;
+ int FrameCycleCnt; //this is a substitution in PSID-mode for CIA/VIC counters
+ short PrevRasterLine;
+ short SampleCycleCnt;
+ short TenthSecondCnt;
+ char Finished;
+ char Returned;
+ unsigned char IRQ; //collected IRQ line from devices
+ unsigned char NMI; //collected NMI line from devices
+
+ //Hardware-elements:
+ cRSID_CPUinstance CPU;
+ cRSID_SIDinstance SID[CRSID_SIDCOUNT_MAX+1];
+ cRSID_CIAinstance CIA[CRSID_CIACOUNT+1];
+ cRSID_VICinstance VIC;
+ //Overlapping system memories, which one is read/written in an address region depends on CPU-port bankselect-bits)
+ //Address $00 and $01 - data-direction and data-register of port built into CPU (used as bank-selection) (overriding RAM on C64)
+ unsigned char RAMbank[0x10100]; //$0000..$FFFF RAM (and RAM under IO/ROM/CPUport)
+ unsigned char IObankWR[0x10100]; //$D000..$DFFF IO-RAM (registers) to write (VIC/SID/CIA/ColorRAM/IOexpansion)
+ unsigned char IObankRD[0x10100]; //$D000..$DFFF IO-RAM (registers) to read from (VIC/SID/CIA/ColorRAM/IOexpansion)
+ unsigned char ROMbanks[0x10100]; //$1000..$1FFF/$9000..$9FFF (CHARGEN), $A000..$BFFF (BASIC), $E000..$FFFF (KERNAL)
+};
+
+
+#endif //LIBCRSID_HEADER