diff --git a/MCUME_teensy41/teensy800/AudioPlaySystem.cpp b/MCUME_teensy41/teensy800/AudioPlaySystem.cpp new file mode 100644 index 0000000..68b7e19 --- /dev/null +++ b/MCUME_teensy41/teensy800/AudioPlaySystem.cpp @@ -0,0 +1,361 @@ +#include "emuapi.h" + +#ifdef HAS_SND + +#include "AudioPlaySystem.h" +#include +#define SAMPLERATE AUDIO_SAMPLE_RATE_EXACT +#define CLOCKFREQ 985248 + +#ifndef CUSTOM_SND +PROGMEM static const short square[]={ +32767,32767,32767,32767, +32767,32767,32767,32767, +32767,32767,32767,32767, +32767,32767,32767,32767, +32767,32767,32767,32767, +32767,32767,32767,32767, +32767,32767,32767,32767, +32767,32767,32767,32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767, +}; + +PROGMEM const short noise[] { +-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767, +-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,32767,-32767, +-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767, +-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,32767,32767,-32767, +-32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,-32767,32767,32767,-32767, +-32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,-32767,-32767, +32767,-32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767,-32767, +32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,-32767,32767,32767,-32767,32767,-32767,32767,-32767,-32767, +32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, +32767,-32767,32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,32767,-32767,32767,-32767,-32767, +}; + +#define NOISEBSIZE 0x100 + +typedef struct +{ + unsigned int spos; + unsigned int sinc; + unsigned int vol; +} Channel; + +static Channel chan[6] = { + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0} }; + +#endif + +volatile bool playing = false; + + +static void snd_Reset(void) +{ +#ifndef CUSTOM_SND + chan[0].vol = 0; + chan[1].vol = 0; + chan[2].vol = 0; + chan[3].vol = 0; + chan[4].vol = 0; + chan[5].vol = 0; + chan[0].sinc = 0; + chan[1].sinc = 0; + chan[2].sinc = 0; + chan[3].sinc = 0; + chan[4].sinc = 0; + chan[5].sinc = 0; +#endif +} + + +#ifdef CUSTOM_SND +extern "C" { +void SND_Process(void *sndbuffer, int sndn); +} +#endif + + +FASTRUN void AudioPlaySystem::snd_Mixer(short * stream, int len ) +{ + if (playing) + { +#ifdef CUSTOM_SND + SND_Process((void*)stream, len); +#else + int i; + long s; + len = len >> 1; + short v0=chan[0].vol; + short v1=chan[1].vol; + short v2=chan[2].vol; + short v3=chan[3].vol; + short v4=chan[4].vol; + short v5=chan[5].vol; + for (i=0;i>8)&0x3f])>>11); + s+=((v1*square[(chan[1].spos>>8)&0x3f])>>11); + s+=((v2*square[(chan[2].spos>>8)&0x3f])>>11); + s+=((v3*noise[(chan[3].spos>>8)&(NOISEBSIZE-1)])>>11); + s+=((v4*noise[(chan[4].spos>>8)&(NOISEBSIZE-1)])>>11); + s+=((v5*noise[(chan[5].spos>>8)&(NOISEBSIZE-1)])>>11); + *stream++ = (short)(s); + *stream++ = (short)(s); + chan[0].spos += chan[0].sinc; + chan[1].spos += chan[1].sinc; + chan[2].spos += chan[2].sinc; + chan[3].spos += chan[3].sinc; + chan[4].spos += chan[4].sinc; + chan[5].spos += chan[5].sinc; + } +#endif + } +} + +void AudioPlaySystem::begin(void) +{ + this->reset(); +} + +void AudioPlaySystem::start(void) +{ + playing = true; +} + +void AudioPlaySystem::setSampleParameters(float clockfreq, float samplerate) { +} + +void AudioPlaySystem::reset(void) +{ + snd_Reset(); +} + +void AudioPlaySystem::stop(void) +{ + //__disable_irq(); + playing = false; + //__enable_irq(); +} + +bool AudioPlaySystem::isPlaying(void) +{ + return playing; +} + + + +void AudioPlaySystem::sound(int C, int F, int V) { +#ifndef CUSTOM_SND + if (C < 6) { + chan[C].vol = V; + chan[C].sinc = F>>1; + } +#endif +} + +void AudioPlaySystem::step(void) { +} + + +#ifndef HAS_T4_VGA +/******************************************************************* + Experimental I2S interrupt based sound driver for PCM51xx !!! +*******************************************************************/ + +FLASHMEM static void set_audioClock(int nfact, int32_t nmult, uint32_t ndiv, bool force) // sets PLL4 +{ + if (!force && (CCM_ANALOG_PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_ENABLE)) return; + + CCM_ANALOG_PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_BYPASS | CCM_ANALOG_PLL_AUDIO_ENABLE + | CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2) // 2: 1/4; 1: 1/2; 0: 1/1 + | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(nfact); + + CCM_ANALOG_PLL_AUDIO_NUM = nmult & CCM_ANALOG_PLL_AUDIO_NUM_MASK; + CCM_ANALOG_PLL_AUDIO_DENOM = ndiv & CCM_ANALOG_PLL_AUDIO_DENOM_MASK; + + CCM_ANALOG_PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_POWERDOWN;//Switch on PLL + while (!(CCM_ANALOG_PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK)) {}; //Wait for pll-lock + + const int div_post_pll = 1; // other values: 2,4 + CCM_ANALOG_MISC2 &= ~(CCM_ANALOG_MISC2_DIV_MSB | CCM_ANALOG_MISC2_DIV_LSB); + if(div_post_pll>1) CCM_ANALOG_MISC2 |= CCM_ANALOG_MISC2_DIV_LSB; + if(div_post_pll>3) CCM_ANALOG_MISC2 |= CCM_ANALOG_MISC2_DIV_MSB; + + CCM_ANALOG_PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS;//Disable Bypass +} + +#define AUDIO_SAMPLE_RATE_EXACT 11025.0 //44117.64706 //11025.0 //22050.0 //44117.64706 //31778.0 + +FLASHMEM static void config_sai1() +{ + CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON); + double fs = AUDIO_SAMPLE_RATE_EXACT; + // PLL between 27*24 = 648MHz und 54*24=1296MHz + int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4 + int n2 = 1 + (24000000 * 27) / (fs * 256 * n1); + double C = (fs * 256 * n1 * n2) / 24000000; + int c0 = C; + int c2 = 10000; + int c1 = C * c2 - (c0 * c2); + + set_audioClock(c0, c1, c2, true); + // clear SAI1_CLK register locations + CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK)) + | CCM_CSCMR1_SAI1_CLK_SEL(2); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4 + + n1 = n1 / 2; //Double Speed for TDM + + CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK)) + | CCM_CS1CDR_SAI1_CLK_PRED(n1 - 1) // &0x07 + | CCM_CS1CDR_SAI1_CLK_PODF(n2 - 1); // &0x3f + + IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK)) + | (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0)); //Select MCLK + + + // configure transmitter + int rsync = 0; + int tsync = 1; + + I2S1_TMR = 0; + I2S1_TCR1 = I2S_TCR1_RFW(1); + I2S1_TCR2 = I2S_TCR2_SYNC(tsync) | I2S_TCR2_BCP // sync=0; tx is async; + | (I2S_TCR2_BCD | I2S_TCR2_DIV((1)) | I2S_TCR2_MSEL(1)); + I2S1_TCR3 = I2S_TCR3_TCE; + I2S1_TCR4 = I2S_TCR4_FRSZ((2-1)) | I2S_TCR4_SYWD((32-1)) | I2S_TCR4_MF + | I2S_TCR4_FSD | I2S_TCR4_FSE | I2S_TCR4_FSP; + I2S1_TCR5 = I2S_TCR5_WNW((32-1)) | I2S_TCR5_W0W((32-1)) | I2S_TCR5_FBT((32-1)); + + + I2S1_RMR = 0; + I2S1_RCR1 = I2S_RCR1_RFW(1); + I2S1_RCR2 = I2S_RCR2_SYNC(rsync) | I2S_RCR2_BCP // sync=0; rx is async; + | (I2S_RCR2_BCD | I2S_RCR2_DIV((1)) | I2S_RCR2_MSEL(1)); + I2S1_RCR3 = I2S_RCR3_RCE; + I2S1_RCR4 = I2S_RCR4_FRSZ((2-1)) | I2S_RCR4_SYWD((32-1)) | I2S_RCR4_MF + | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD; + I2S1_RCR5 = I2S_RCR5_WNW((32-1)) | I2S_RCR5_W0W((32-1)) | I2S_RCR5_FBT((32-1)); + + //CORE_PIN23_CONFIG = 3; // MCLK + CORE_PIN21_CONFIG = 3; // RX_BCLK + CORE_PIN20_CONFIG = 3; // RX_SYNC + CORE_PIN7_CONFIG = 3; // TX_DATA0 + I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE; + I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */; +} + + + +//DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx[1024]; + +static bool fillfirsthalf = true; +static uint16_t cnt = 0; +static uint16_t sampleBufferSize = 0; + +static void (*fillsamples)(short * stream, int len) = nullptr; + +static uint32_t * i2s_tx_buffer __attribute__((aligned(32))); +static uint16_t * i2s_tx_buffer16; +static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2); + + +FASTRUN void AudioPlaySystem::AUDIO_isr() { + + *txreg = i2s_tx_buffer16[cnt]; + cnt = cnt + 1; + cnt = cnt & (sampleBufferSize*2-1); + + if (cnt == 0) { + fillfirsthalf = false; + NVIC_SET_PENDING(IRQ_SOFTWARE); + } + else if (cnt == sampleBufferSize) { + fillfirsthalf = true; + NVIC_SET_PENDING(IRQ_SOFTWARE); + } +/* + I2S1_TDR0 = i2s_tx_buffer[cnt]; + cnt = cnt + 1; + cnt = cnt & (sampleBufferSize-1); + if (cnt == 0) { + fillfirsthalf = false; + NVIC_SET_PENDING(IRQ_SOFTWARE); + } + else if (cnt == sampleBufferSize/2) { + fillfirsthalf = true; + NVIC_SET_PENDING(IRQ_SOFTWARE); + } +*/ +} + +FASTRUN void AudioPlaySystem::SOFTWARE_isr() { + //Serial.println("x"); + if (fillfirsthalf) { + fillsamples((short *)i2s_tx_buffer, sampleBufferSize); + arm_dcache_flush_delete((void*)i2s_tx_buffer, (sampleBufferSize/2)*sizeof(uint32_t)); + } + else { + fillsamples((short *)&i2s_tx_buffer[sampleBufferSize/2], sampleBufferSize); + arm_dcache_flush_delete((void*)&i2s_tx_buffer[sampleBufferSize/2], (sampleBufferSize/2)*sizeof(uint32_t)); + } +} + +// display VGA image +FLASHMEM void AudioPlaySystem::begin_audio(int samplesize, void (*callback)(short * stream, int len)) +{ + fillsamples = callback; + i2s_tx_buffer = (uint32_t*)malloc(samplesize*sizeof(uint32_t)); //&i2s_tx[0]; + + if (i2s_tx_buffer == NULL) { + Serial.println("could not allocate audio samples"); + return; + } + memset((void*)i2s_tx_buffer,0, samplesize*sizeof(uint32_t)); + arm_dcache_flush_delete((void*)i2s_tx_buffer, samplesize*sizeof(uint32_t)); + i2s_tx_buffer16 = (uint16_t*)i2s_tx_buffer; + + sampleBufferSize = samplesize; + + config_sai1(); + attachInterruptVector(IRQ_SAI1, AUDIO_isr); + NVIC_ENABLE_IRQ(IRQ_SAI1); + NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority + NVIC_SET_PRIORITY(IRQ_SAI1, 127); + attachInterruptVector(IRQ_SOFTWARE, SOFTWARE_isr); + NVIC_SET_PRIORITY(IRQ_SOFTWARE, 208); + NVIC_ENABLE_IRQ(IRQ_SOFTWARE); + + I2S1_TCSR |= 1<<8; // start generating TX FIFO interrupts + + Serial.print("Audio sample buffer = "); + Serial.println(samplesize); +} + +FLASHMEM void AudioPlaySystem::end_audio() +{ + if (i2s_tx_buffer != NULL) { + free(i2s_tx_buffer); + } +} + +#endif +#endif diff --git a/MCUME_teensy41/teensy800/AudioPlaySystem.h b/MCUME_teensy41/teensy800/AudioPlaySystem.h new file mode 100644 index 0000000..fb22cdc --- /dev/null +++ b/MCUME_teensy41/teensy800/AudioPlaySystem.h @@ -0,0 +1,34 @@ +#ifndef audioplaysystem_h_ +#define audioplaysystem_h_ + +#ifdef HAS_SND + +#include "platform_config.h" + +class AudioPlaySystem +{ +public: + AudioPlaySystem(void) { }; + void begin(void); + void setSampleParameters(float clockfreq, float samplerate); + void reset(void); + void start(void); + void stop(void); + bool isPlaying(void); + void sound(int C, int F, int V); + void buzz(int size, int val); + void step(void); + static void snd_Mixer(short * stream, int len ); +#ifndef HAS_T4_VGA + void begin_audio(int samplesize, void (*callback)(short * stream, int len)); + void end_audio(); + static void AUDIO_isr(void); + static void SOFTWARE_isr(void); +#endif + +}; + + +#endif + +#endif diff --git a/MCUME_teensy41/teensy800/akey.h b/MCUME_teensy41/teensy800/akey.h new file mode 100644 index 0000000..06e4939 --- /dev/null +++ b/MCUME_teensy41/teensy800/akey.h @@ -0,0 +1,239 @@ +#ifndef AKEY_H_ +#define AKEY_H_ +/* akey.h: Atari key codes */ + +/* INPUT_key_code values */ +#define AKEY_NONE -1 + +/* Special key codes. */ +#define AKEY_WARMSTART -2 +#define AKEY_COLDSTART -3 +#define AKEY_EXIT -4 +#define AKEY_BREAK -5 +#define AKEY_UI -7 +#define AKEY_SCREENSHOT -8 +#define AKEY_SCREENSHOT_INTERLACE -9 +#define AKEY_START -10 +#define AKEY_SELECT -11 +#define AKEY_OPTION -12 +#define AKEY_PBI_BB_MENU -13 +#define AKEY_CX85_1 -14 +#define AKEY_CX85_2 -15 +#define AKEY_CX85_3 -16 +#define AKEY_CX85_4 -17 +#define AKEY_CX85_5 -18 +#define AKEY_CX85_6 -19 +#define AKEY_CX85_7 -20 +#define AKEY_CX85_8 -21 +#define AKEY_CX85_9 -22 +#define AKEY_CX85_0 -23 +#define AKEY_CX85_PERIOD -24 +#define AKEY_CX85_MINUS -25 +#define AKEY_CX85_PLUS_ENTER -26 +#define AKEY_CX85_ESCAPE -27 +#define AKEY_CX85_NO -28 +#define AKEY_CX85_DELETE -29 +#define AKEY_CX85_YES -30 +#define AKEY_TURBO -31 +#ifdef USE_UI_BASIC_ONSCREEN_KEYBOARD +#define AKEY_KEYB -32 +#endif +#ifdef DIRECTX + /* special menu directives */ + #define AKEY32_MENU_SAVE_CONFIG -107 + #define AKEY32_UI_MOUSE_CLICK -108 +#endif + +#define AKEY_SHFT 0x40 +#define AKEY_CTRL 0x80 +#define AKEY_SHFTCTRL 0xc0 + +#define AKEY_0 0x32 +#define AKEY_1 0x1f +#define AKEY_2 0x1e +#define AKEY_3 0x1a +#define AKEY_4 0x18 +#define AKEY_5 0x1d +#define AKEY_6 0x1b +#define AKEY_7 0x33 +#define AKEY_8 0x35 +#define AKEY_9 0x30 + +#define AKEY_CTRL_0 (AKEY_CTRL | AKEY_0) +#define AKEY_CTRL_1 (AKEY_CTRL | AKEY_1) +#define AKEY_CTRL_2 (AKEY_CTRL | AKEY_2) +#define AKEY_CTRL_3 (AKEY_CTRL | AKEY_3) +#define AKEY_CTRL_4 (AKEY_CTRL | AKEY_4) +#define AKEY_CTRL_5 (AKEY_CTRL | AKEY_5) +#define AKEY_CTRL_6 (AKEY_CTRL | AKEY_6) +#define AKEY_CTRL_7 (AKEY_CTRL | AKEY_7) +#define AKEY_CTRL_8 (AKEY_CTRL | AKEY_8) +#define AKEY_CTRL_9 (AKEY_CTRL | AKEY_9) + +#define AKEY_a 0x3f +#define AKEY_b 0x15 +#define AKEY_c 0x12 +#define AKEY_d 0x3a +#define AKEY_e 0x2a +#define AKEY_f 0x38 +#define AKEY_g 0x3d +#define AKEY_h 0x39 +#define AKEY_i 0x0d +#define AKEY_j 0x01 +#define AKEY_k 0x05 +#define AKEY_l 0x00 +#define AKEY_m 0x25 +#define AKEY_n 0x23 +#define AKEY_o 0x08 +#define AKEY_p 0x0a +#define AKEY_q 0x2f +#define AKEY_r 0x28 +#define AKEY_s 0x3e +#define AKEY_t 0x2d +#define AKEY_u 0x0b +#define AKEY_v 0x10 +#define AKEY_w 0x2e +#define AKEY_x 0x16 +#define AKEY_y 0x2b +#define AKEY_z 0x17 + +#define AKEY_A (AKEY_SHFT | AKEY_a) +#define AKEY_B (AKEY_SHFT | AKEY_b) +#define AKEY_C (AKEY_SHFT | AKEY_c) +#define AKEY_D (AKEY_SHFT | AKEY_d) +#define AKEY_E (AKEY_SHFT | AKEY_e) +#define AKEY_F (AKEY_SHFT | AKEY_f) +#define AKEY_G (AKEY_SHFT | AKEY_g) +#define AKEY_H (AKEY_SHFT | AKEY_h) +#define AKEY_I (AKEY_SHFT | AKEY_i) +#define AKEY_J (AKEY_SHFT | AKEY_j) +#define AKEY_K (AKEY_SHFT | AKEY_k) +#define AKEY_L (AKEY_SHFT | AKEY_l) +#define AKEY_M (AKEY_SHFT | AKEY_m) +#define AKEY_N (AKEY_SHFT | AKEY_n) +#define AKEY_O (AKEY_SHFT | AKEY_o) +#define AKEY_P (AKEY_SHFT | AKEY_p) +#define AKEY_Q (AKEY_SHFT | AKEY_q) +#define AKEY_R (AKEY_SHFT | AKEY_r) +#define AKEY_S (AKEY_SHFT | AKEY_s) +#define AKEY_T (AKEY_SHFT | AKEY_t) +#define AKEY_U (AKEY_SHFT | AKEY_u) +#define AKEY_V (AKEY_SHFT | AKEY_v) +#define AKEY_W (AKEY_SHFT | AKEY_w) +#define AKEY_X (AKEY_SHFT | AKEY_x) +#define AKEY_Y (AKEY_SHFT | AKEY_y) +#define AKEY_Z (AKEY_SHFT | AKEY_z) + +#define AKEY_CTRL_a (AKEY_CTRL | AKEY_a) +#define AKEY_CTRL_b (AKEY_CTRL | AKEY_b) +#define AKEY_CTRL_c (AKEY_CTRL | AKEY_c) +#define AKEY_CTRL_d (AKEY_CTRL | AKEY_d) +#define AKEY_CTRL_e (AKEY_CTRL | AKEY_e) +#define AKEY_CTRL_f (AKEY_CTRL | AKEY_f) +#define AKEY_CTRL_g (AKEY_CTRL | AKEY_g) +#define AKEY_CTRL_h (AKEY_CTRL | AKEY_h) +#define AKEY_CTRL_i (AKEY_CTRL | AKEY_i) +#define AKEY_CTRL_j (AKEY_CTRL | AKEY_j) +#define AKEY_CTRL_k (AKEY_CTRL | AKEY_k) +#define AKEY_CTRL_l (AKEY_CTRL | AKEY_l) +#define AKEY_CTRL_m (AKEY_CTRL | AKEY_m) +#define AKEY_CTRL_n (AKEY_CTRL | AKEY_n) +#define AKEY_CTRL_o (AKEY_CTRL | AKEY_o) +#define AKEY_CTRL_p (AKEY_CTRL | AKEY_p) +#define AKEY_CTRL_q (AKEY_CTRL | AKEY_q) +#define AKEY_CTRL_r (AKEY_CTRL | AKEY_r) +#define AKEY_CTRL_s (AKEY_CTRL | AKEY_s) +#define AKEY_CTRL_t (AKEY_CTRL | AKEY_t) +#define AKEY_CTRL_u (AKEY_CTRL | AKEY_u) +#define AKEY_CTRL_v (AKEY_CTRL | AKEY_v) +#define AKEY_CTRL_w (AKEY_CTRL | AKEY_w) +#define AKEY_CTRL_x (AKEY_CTRL | AKEY_x) +#define AKEY_CTRL_y (AKEY_CTRL | AKEY_y) +#define AKEY_CTRL_z (AKEY_CTRL | AKEY_z) + +#define AKEY_CTRL_A (AKEY_CTRL | AKEY_A) +#define AKEY_CTRL_B (AKEY_CTRL | AKEY_B) +#define AKEY_CTRL_C (AKEY_CTRL | AKEY_C) +#define AKEY_CTRL_D (AKEY_CTRL | AKEY_D) +#define AKEY_CTRL_E (AKEY_CTRL | AKEY_E) +#define AKEY_CTRL_F (AKEY_CTRL | AKEY_F) +#define AKEY_CTRL_G (AKEY_CTRL | AKEY_G) +#define AKEY_CTRL_H (AKEY_CTRL | AKEY_H) +#define AKEY_CTRL_I (AKEY_CTRL | AKEY_I) +#define AKEY_CTRL_J (AKEY_CTRL | AKEY_J) +#define AKEY_CTRL_K (AKEY_CTRL | AKEY_K) +#define AKEY_CTRL_L (AKEY_CTRL | AKEY_L) +#define AKEY_CTRL_M (AKEY_CTRL | AKEY_M) +#define AKEY_CTRL_N (AKEY_CTRL | AKEY_N) +#define AKEY_CTRL_O (AKEY_CTRL | AKEY_O) +#define AKEY_CTRL_P (AKEY_CTRL | AKEY_P) +#define AKEY_CTRL_Q (AKEY_CTRL | AKEY_Q) +#define AKEY_CTRL_R (AKEY_CTRL | AKEY_R) +#define AKEY_CTRL_S (AKEY_CTRL | AKEY_S) +#define AKEY_CTRL_T (AKEY_CTRL | AKEY_T) +#define AKEY_CTRL_U (AKEY_CTRL | AKEY_U) +#define AKEY_CTRL_V (AKEY_CTRL | AKEY_V) +#define AKEY_CTRL_W (AKEY_CTRL | AKEY_W) +#define AKEY_CTRL_X (AKEY_CTRL | AKEY_X) +#define AKEY_CTRL_Y (AKEY_CTRL | AKEY_Y) +#define AKEY_CTRL_Z (AKEY_CTRL | AKEY_Z) + +#define AKEY_HELP 0x11 +#define AKEY_DOWN 0x8f +#define AKEY_LEFT 0x86 +#define AKEY_RIGHT 0x87 +#define AKEY_UP 0x8e +#define AKEY_BACKSPACE 0x34 +#define AKEY_DELETE_CHAR 0xb4 +#define AKEY_DELETE_LINE 0x74 +#define AKEY_INSERT_CHAR 0xb7 +#define AKEY_INSERT_LINE 0x77 +#define AKEY_ESCAPE 0x1c +#define AKEY_ATARI 0x27 +#define AKEY_CAPSLOCK 0x7c +#define AKEY_CAPSTOGGLE 0x3c +#define AKEY_TAB 0x2c +#define AKEY_SETTAB 0x6c +#define AKEY_CLRTAB 0xac +#define AKEY_RETURN 0x0c +#define AKEY_SPACE 0x21 +#define AKEY_EXCLAMATION 0x5f +#define AKEY_DBLQUOTE 0x5e +#define AKEY_HASH 0x5a +#define AKEY_DOLLAR 0x58 +#define AKEY_PERCENT 0x5d +#define AKEY_AMPERSAND 0x5b +#define AKEY_QUOTE 0x73 +#define AKEY_AT 0x75 +#define AKEY_PARENLEFT 0x70 +#define AKEY_PARENRIGHT 0x72 +#define AKEY_LESS 0x36 +#define AKEY_GREATER 0x37 +#define AKEY_EQUAL 0x0f +#define AKEY_QUESTION 0x66 +#define AKEY_MINUS 0x0e +#define AKEY_PLUS 0x06 +#define AKEY_ASTERISK 0x07 +#define AKEY_SLASH 0x26 +#define AKEY_COLON 0x42 +#define AKEY_SEMICOLON 0x02 +#define AKEY_COMMA 0x20 +#define AKEY_FULLSTOP 0x22 +#define AKEY_UNDERSCORE 0x4e +#define AKEY_BRACKETLEFT 0x60 +#define AKEY_BRACKETRIGHT 0x62 +#define AKEY_CIRCUMFLEX 0x47 +#define AKEY_BACKSLASH 0x46 +#define AKEY_BAR 0x4f +#define AKEY_CLEAR (AKEY_SHFT | AKEY_LESS) +#define AKEY_CARET (AKEY_SHFT | AKEY_ASTERISK) +#define AKEY_F1 0x03 +#define AKEY_F2 0x04 +#define AKEY_F3 0x13 +#define AKEY_F4 0x14 + +/* Following keys cannot be read with both shift and control pressed: + J K L ; + * Z X C V B F1 F2 F3 F4 HELP */ + + +#endif /* AKEY_H_ */ diff --git a/MCUME_teensy41/teensy800/antic.c b/MCUME_teensy41/teensy800/antic.c new file mode 100644 index 0000000..542f5fa --- /dev/null +++ b/MCUME_teensy41/teensy800/antic.c @@ -0,0 +1,4150 @@ +/* + * antic.c - ANTIC chip emulation + * + * Copyright (C) 1995-1998 David Firth + * Copyright (C) 1998-2008 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Atari800 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include + +#include "antic.h" +#include "cpu.h" +#include "gtia.h" +#include "memory.h" +#include "pokey.h" + +#ifdef NEW_CYCLE_EXACT +#include "cycle_map.h" +#endif + + +UWORD Screen_atari[ATARI_WIDTH / 2]; // = NULL; +#define scrn_line 0 //(ATARI_WIDTH / 2) + +#define DRAWLINE() \ + if ( (ANTIC_ypos > 8) && (ANTIC_ypos < 248)) { \ + emu_DrawLine((unsigned char *)&Screen_atari[32/sizeof(Screen_atari[0])], 320, 240, ANTIC_ypos-8); \ + } + + +#define LCHOP 3 /* do not build leftmost 0..3 characters in wide mode */ +#define RCHOP 3 /* do not build rightmost 0..3 characters in wide mode */ + +int ANTIC_break_ypos = 999; +#if !defined(BASIC) && !defined(CURSES_BASIC) +static int gtia_bug_active = FALSE; /* The GTIA bug mode is active */ +#endif +#ifdef NEW_CYCLE_EXACT +static void draw_partial_scanline(int l,int r); +static void update_scanline_chbase(void); +static void update_scanline_invert(void); +static void update_scanline_blank(void); +const int *ANTIC_cpu2antic_ptr; +const int *ANTIC_antic2cpu_ptr; +int ANTIC_delayed_wsync = 0; +static int dmactl_changed = 0; +static UBYTE delayed_DMACTL; +static int draw_antic_ptr_changed = 0; +static UBYTE need_load; +static int dmactl_bug_chdata; +#endif /* NEW_CYCLE_EXACT */ +#ifndef NO_SIMPLE_PAL_BLENDING +int ANTIC_pal_blending = 0; +#endif /* NO_SIMPLE_PAL_BLENDING */ + +/* Video memory access is hidden behind these macros. It allows to track dirty video memory + to improve video system performance */ +#ifdef DIRTYRECT + +static UWORD *scratchUWordPtr; +static UWORD scratchUWord; +static ULONG *scratchULongPtr; +static ULONG scratchULong; +static UBYTE *scratchUBytePtr; +static UBYTE scratchUByte; + + +#ifdef NODIRTYCOMPARE + +#define WRITE_VIDEO(ptr, val) \ + do { \ + scratchUWordPtr = (ptr); \ + Screen_dirty[((ULONG) scratchUWordPtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchUWordPtr = (val); \ + } while (0) +#define WRITE_VIDEO_LONG(ptr, val) \ + do { \ + scratchULongPtr = (ptr); \ + Screen_dirty[((ULONG) scratchULongPtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchULongPtr = (val); \ + } while (0) +#define WRITE_VIDEO_BYTE(ptr, val) \ + do { \ + scratchUBytePtr = (ptr); \ + Screen_dirty[((ULONG) scratchUBytePtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchUBytePtr = (val); \ + } while (0) +#define FILL_VIDEO(ptr, val, size) \ + do { \ + scratchUBytePtr = (UBYTE*) (ptr); \ + scratchULong = (ULONG) (size); \ + memset(Screen_dirty + (((ULONG) scratchUBytePtr - (ULONG) Screen_atari) >> 3), 1, scratchULong >> 3); \ + memset(scratchUBytePtr, (val), scratchULong); \ + } while (0) + +#else /* NODIRTYCOMPARE not defined: */ + +#define WRITE_VIDEO(ptr, val) \ + do { \ + scratchUWordPtr = (ptr); \ + scratchUWord = (val); \ + if (*scratchUWordPtr != scratchUWord) { \ + Screen_dirty[((ULONG) scratchUWordPtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchUWordPtr = scratchUWord; \ + } \ + } while (0) +#ifndef WORDS_UNALIGNED_OK +#define WRITE_VIDEO_LONG(ptr, val) \ + do { \ + scratchULongPtr = (ptr); \ + scratchULong = (val); \ + if (*scratchULongPtr != scratchULong) { \ + Screen_dirty[((ULONG) scratchULongPtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchULongPtr = scratchULong; \ + } \ + } while (0) +#else +#define WRITE_VIDEO_LONG(ptr, val) \ + do { \ + scratchULongPtr = (ptr); \ + scratchULong = (val); \ + if (*scratchULongPtr != scratchULong) { \ + Screen_dirty[((ULONG) scratchULongPtr - (ULONG) Screen_atari) >> 3] = 1; \ + Screen_dirty[((ULONG) scratchULongPtr - (ULONG) Screen_atari + 2) >> 3] = 1; \ + *scratchULongPtr = scratchULong; \ + } \ + } while (0) +#endif +#define WRITE_VIDEO_BYTE(ptr, val) \ + do { \ + scratchUBytePtr = (ptr); \ + scratchUByte = (val); \ + if (*scratchUBytePtr != scratchUByte) { \ + Screen_dirty[((ULONG) scratchUBytePtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchUBytePtr = scratchUByte; \ + } \ + } while (0) +static UBYTE *scratchFillLimit; +#define FILL_VIDEO(ptr, val, size) \ + do { \ + scratchUBytePtr = (UBYTE *) (ptr); \ + scratchUByte = (UBYTE) (val); \ + scratchFillLimit = scratchUBytePtr + (size); \ + for (; scratchUBytePtr < scratchFillLimit; scratchUBytePtr++) { \ + if (*scratchUBytePtr != scratchUByte) { \ + Screen_dirty[((ULONG) scratchUBytePtr - (ULONG) Screen_atari) >> 3] = 1; \ + *scratchUBytePtr = scratchUByte; \ + } \ + } \ + } while (0) + +#endif /* NODIRTYCOMPARE */ + +#else /* DIRTYRECT not defined: */ + +#define WRITE_VIDEO(ptr, val) (*(ptr) = val) +#define WRITE_VIDEO_LONG(ptr, val) (*(ptr) = val) +#define WRITE_VIDEO_BYTE(ptr, val) (*(ptr) = val) +#define FILL_VIDEO(ptr, val, size) memset(ptr, val, size) + +#endif /* DIRTYRECT */ + +#define READ_VIDEO_LONG(ptr) (*(ptr)) + +void ANTIC_VideoMemset(UBYTE *ptr, UBYTE val, ULONG size) +{ + FILL_VIDEO(ptr, val, size); +} + +void ANTIC_VideoPutByte(UBYTE *ptr, UBYTE val) +{ + WRITE_VIDEO_BYTE(ptr, val); +} + + +/* Memory access helpers----------------------------------------------------- */ +/* Some optimizations result in unaligned 32-bit accesses. These macros have + been introduced for machines that don't allow unaligned memory accesses. */ + +#ifdef DIRTYRECT +/* STAT_UNALIGNED_WORDS doesn't work with DIRTYRECT */ +#define WRITE_VIDEO_LONG_UNALIGNED WRITE_VIDEO_LONG +#else +#define WRITE_VIDEO_LONG_UNALIGNED(ptr, val) UNALIGNED_PUT_LONG((ptr), (val), Screen_atari_write_long_stat) +#endif + +#ifdef WORDS_UNALIGNED_OK +#define IS_ZERO_ULONG(x) (! UNALIGNED_GET_LONG(x, pm_scanline_read_long_stat)) +#define DO_GTIA_BYTE(p, l, x) { \ + WRITE_VIDEO_LONG_UNALIGNED((ULONG *) (p), (l)[(x) >> 4]); \ + WRITE_VIDEO_LONG_UNALIGNED((ULONG *) (p) + 1, (l)[(x) & 0xf]); \ + } +#else /* WORDS_UNALIGNED_OK */ +#define IS_ZERO_ULONG(x) (!((const UBYTE *)(x))[0] && !((const UBYTE *)(x))[1] && !((const UBYTE *)(x))[2] && !((const UBYTE *)(x))[3]) +#define DO_GTIA_BYTE(p, l, x) { \ + WRITE_VIDEO((UWORD *) (p), (UWORD) ((l)[(x) >> 4])); \ + WRITE_VIDEO((UWORD *) (p) + 1, (UWORD) ((l)[(x) >> 4])); \ + WRITE_VIDEO((UWORD *) (p) + 2, (UWORD) ((l)[(x) & 0xf])); \ + WRITE_VIDEO((UWORD *) (p) + 3, (UWORD) ((l)[(x) & 0xf])); \ + } +#endif /* WORDS_UNALIGNED_OK */ + +/* ANTIC Registers --------------------------------------------------------- */ + +UBYTE ANTIC_DMACTL; +UBYTE ANTIC_CHACTL; +UWORD ANTIC_dlist; +UBYTE ANTIC_HSCROL; +UBYTE ANTIC_VSCROL; +UBYTE ANTIC_PMBASE; +UBYTE ANTIC_CHBASE; +UBYTE ANTIC_NMIEN; +UBYTE ANTIC_NMIST; + +/* ANTIC Memory ------------------------------------------------------------ */ + +#if !defined(BASIC) && !defined(CURSES_BASIC) +static UBYTE antic_memory[52]; +#define ANTIC_margin 4 +/* It's number of bytes in antic_memory, which are never loaded, but may be + read in wide playfield mode. These bytes are uninitialized, because on + real computer there's some kind of 'garbage'. Possibly 1 is enough, but + 4 bytes surely won't cause negative indexes. :) */ + +/* Screen ----------------------------------------------------------------- + Define screen as ULONG to ensure that it is Longword aligned. + This allows special optimisations under certain conditions. + ------------------------------------------------------------------------ */ + +static UWORD *scrn_ptr; +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + +/* Separate access to XE extended memory ----------------------------------- */ +/* It's available in 130 XE and 320 KB Compy Shop. + Note: during ANTIC access to extended memory in Compy Shop Self Test + is disabled. It is unknown if this is true for real 130 XE. If not, + then some extra code has to be added to: + - check if selftest_enabled is set + - check if the address is in range 0x5000..0x57ff + - if both conditions are true, then access memory instead of ANTIC_xe_ptr */ + +/* Pointer to 16 KB seen by ANTIC in 0x4000-0x7fff. + If it's the same what the CPU sees (and what's in MEMORY_mem[0x4000..0x7fff], + then NULL. */ +const UBYTE *ANTIC_xe_ptr = NULL; + +/* ANTIC Timing -------------------------------------------------------------- + +NOTE: this information was written before NEW_CYCLE_EXACT was introduced! + +I've introduced global variable ANTIC_xpos, which contains current number of cycle +in a line. This simplifies ANTIC/CPU timing much. The CPU_GO() function which +emulates CPU is now void and is called with ANTIC_xpos limit, below which CPU can go. + +All strange variables holding 'unused cycles', 'DMA cycles', 'allocated cycles' +etc. are removed. Simply whenever ANTIC fetches a byte, it takes single cycle, +which can be done now with ANTIC_xpos++. There's only one exception: in text modes +2-5 ANTIC takes more bytes than cycles, because it does less than ANTIC_DMAR refresh +cycles. + +Now emulation is really screenline-oriented. We do ANTIC_ypos++ after a line, +not inside it. + +This simplified diagram shows when what is done in a line: + +MDPPPPDD..............(------R/S/F------).......... +^ ^ ^ ^ ^ ^ ^ ^ ---> time/xpos +0 | NMIST_C NMI_C SCR_C WSYNC_C|LINE_C +VSCON_C VSCOF_C + +M - fetch Missiles +D - fetch DL +P - fetch Players +S - fetch Screen +F - fetch Font (in text modes) +R - refresh Memory (ANTIC_DMAR cycles) + +Only Memory Refresh happens in every line, other tasks are optional. + +Below are exact diagrams for some non-scrolled modes: + 11111111111111 + 11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111 +012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 + /--------------------------narrow------------------------------\ + /----------------------------------normal--------------------------------------\ + /-------------------------------------------wide--------------------------------------------\ + +blank line: +MDPPPPDD.................R...R...R...R...R...R...R...R...R........................................................ + +mode 8,9: +MDPPPPDD....S.......S....R..SR...R..SR...R..SR...R..SR...R..S.......S.......S.......S.......S.......S............. + +mode a,b,c: +MDPPPPDD....S...S...S...SR..SR..SR..SR..SR..SR..SR..SR..SR..S...S...S...S...S...S...S...S...S...S...S...S......... + +mode d,e,f: +MDPPPPDD....S.S.S.S.S.S.SRS.SRS.SRS.SRS.SRS.SRS.SRS.SRS.SRS.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S......... + +Notes: +* At the beginning of a line fetched are: + - a byte of Missiles + - a byte of DL (instruction) + - four bytes of Players + - two bytes of DL argument (jump or screen address) + The emulator, however, fetches them all continuously. + +* Refresh cycles and Screen/Font fetches have been tested for some modes (see above). + This is for making the emulator more accurate, able to change colour registers, + sprite positions or GTIA modes during scanline. These modes are the most commonly used + with those effects. + Currently this isn't implemented, and all R/S/F cycles are fetched continuously in *all* modes + (however, right number of cycles is taken in every mode, basing on screen width and HSCROL). + +There are a few constants representing following events: + +* VSCON_C - in first VSC line dctr is loaded with VSCROL + +* ANTIC_NMIST_C - NMIST is updated (set to 0x9f on DLI, set to 0x5f on VBLKI) + +* ANTIC_NMI_C - If NMIEN permits, NMI interrupt is generated + +* SCR_C - We draw whole line of screen. On a real computer you can change + ANTIC/GTIA registers while displaying screen, however this emulator + isn't that accurate. + +* ANTIC_WSYNC_C - ANTIC holds CPU until this moment, when WSYNC is written + +* VSCOF_C - in last VSC line dctr is compared with VSCROL + +* ANTIC_LINE_C - simply end of line (this used to be called CPUL) + +All constants are determined by tests on real Atari computer. It is assumed, +that ANTIC registers are read with LDA, LDX, LDY and written with STA, STX, +STY, all in absolute addressing mode. All these instructions last 4 cycles +and perform read/write operation in last cycle. The CPU emulation should +correctly emulate WSYNC and add cycles for current instruction BEFORE +executing it. That's why VSCOF_C > ANTIC_LINE_C is correct. + +How WSYNC is now implemented: + +* On writing WSYNC: + - if ANTIC_xpos <= ANTIC_WSYNC_C && ANTIC_xpos_limit >= ANTIC_WSYNC_C, + we only change ANTIC_xpos to ANTIC_WSYNC_C - that's all + - otherwise we set ANTIC_wsync_halt and change ANTIC_xpos to ANTIC_xpos_limit causing CPU_GO() + to return + +* At the beginning of CPU_GO() (CPU emulation), when ANTIC_wsync_halt is set: + - if ANTIC_xpos_limit < ANTIC_WSYNC_C we return + - else we set ANTIC_xpos to ANTIC_WSYNC_C, reset ANTIC_wsync_halt and emulate some cycles + +We don't emulate ANTIC_NMIST_C, ANTIC_NMI_C and SCR_C if it is unnecessary. +These are all cases: + +* Common overscreen line + Nothing happens except that ANTIC gets ANTIC_DMAR cycles: + ANTIC_xpos += ANTIC_DMAR; GOEOL; + +* First overscreen line - start of vertical blank + - CPU goes until ANTIC_NMIST_C + - ANTIC sets NMIST to 0x5f + if (ANTIC_NMIEN & 0x40) { + - CPU goes until ANTIC_NMI_C + - ANTIC forces NMI + } + - ANTIC gets ANTIC_DMAR cycles + - CPU goes until ANTIC_LINE_C + +* Screen line without DLI + - ANTIC fetches DL and P/MG + - CPU goes until SCR_C + - ANTIC draws whole line fetching Screen/Font and refreshing memory + - CPU goes until ANTIC_LINE_C + +* Screen line with DLI + - ANTIC fetches DL and P/MG + - CPU goes until ANTIC_NMIST_C + - ANTIC sets NMIST to 0x9f + if (ANTIC_NMIEN & 0x80) { + - CPU goes until ANTIC_NMI_C + - ANTIC forces NMI + } + - CPU goes until SCR_C + - ANTIC draws line with ANTIC_DMAR + - CPU goes until ANTIC_LINE_C + + -------------------------------------------------------------------------- */ + +#define VSCON_C 1 +#define SCR_C 28 +#define VSCOF_C 112 + +unsigned int ANTIC_screenline_cpu_clock = 0; + +#ifdef NEW_CYCLE_EXACT +#define UPDATE_DMACTL do{if (dmactl_changed) { \ + dmactl_changed = 0; \ + ANTIC_PutByte(ANTIC_OFFSET_DMACTL, delayed_DMACTL); \ + } \ + if (draw_antic_ptr_changed) { \ + draw_antic_ptr_changed = 0; \ + draw_antic_ptr = saved_draw_antic_ptr; \ + }}while(0) +#else +#define UPDATE_DMACTL do{}while(0) +#endif /* NEW_CYCLE_EXACT */ +#define UPDATE_GTIA_BUG /* update GTIA if it was in bug mode */\ + do{if(gtia_bug_active) {\ + /* restore draw_antic_ptr for multi-line modes*/\ + draw_antic_ptr = draw_antic_table[GTIA_PRIOR >> 6][anticmode];\ + gtia_bug_active = FALSE;\ + }}while(0) +#define GOEOL_CYCLE_EXACT CPU_GO(ANTIC_antic2cpu_ptr[ANTIC_LINE_C]); \ + ANTIC_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; \ + ANTIC_xpos -= ANTIC_LINE_C; \ + ANTIC_screenline_cpu_clock += ANTIC_LINE_C; \ + DRAWLINE();ANTIC_ypos++; \ + GTIA_UpdatePmplColls(); +#define GOEOL CPU_GO(ANTIC_LINE_C); ANTIC_xpos -= ANTIC_LINE_C; ANTIC_screenline_cpu_clock += ANTIC_LINE_C; UPDATE_DMACTL; DRAWLINE();ANTIC_ypos++; UPDATE_GTIA_BUG +#define OVERSCREEN_LINE ANTIC_xpos += ANTIC_DMAR; GOEOL + +int ANTIC_xpos = 0; +int ANTIC_xpos_limit; +int ANTIC_wsync_halt = FALSE; + +int ANTIC_ypos; /* Line number - lines 8..247 are on screen */ + +/* Timing in first line of modes 2-5 +In these modes ANTIC takes more bytes than cycles. Despite this, it would be +possible that SCR_C + cycles_taken > ANTIC_WSYNC_C. To avoid this we must take some +cycles before SCR_C. before_cycles contains number of them, while extra_cycles +contains difference between bytes taken and cycles taken plus before_cycles. */ + +#define BEFORE_CYCLES (SCR_C - 28) +/* It's number of cycles taken before SCR_C for not scrolled, narrow playfield. + It wasn't tested, but should be ok. ;) */ + +/* Light pen support ------------------------------------------------------- */ + +static UBYTE PENH; +static UBYTE PENV; +UBYTE ANTIC_PENH_input = 0x00; +UBYTE ANTIC_PENV_input = 0xff; + +#ifndef BASIC + +/* Internal ANTIC registers ------------------------------------------------ */ + +static UWORD screenaddr; /* Screen Pointer */ +static UBYTE IR; /* Instruction Register */ +static UBYTE anticmode; /* Antic mode */ +static UBYTE dctr; /* Delta Counter */ +static UBYTE lastline; /* dctr limit */ +static UBYTE need_dl; /* boolean: fetch DL next line */ +static UBYTE vscrol_off; /* boolean: displaying line ending VSC */ + +#endif + +#if !defined(BASIC) && !defined(CURSES_BASIC) + +/* Pre-computed values for improved performance ---------------------------- */ + +#define NORMAL0 0 /* modes 2,3,4,5,0xd,0xe,0xf */ +#define NORMAL1 1 /* modes 6,7,0xa,0xb,0xc */ +#define NORMAL2 2 /* modes 8,9 */ +#define SCROLL0 3 /* modes 2,3,4,5,0xd,0xe,0xf with HSC */ +#define SCROLL1 4 /* modes 6,7,0xa,0xb,0xc with HSC */ +#define SCROLL2 5 /* modes 8,9 with HSC */ +static int md; /* current mode NORMAL0..SCROLL2 */ +/* tables for modes NORMAL0..SCROLL2 */ +static int chars_read[6]; +static int chars_displayed[6]; +static int x_min[6]; +static int ch_offset[6]; +static int load_cycles[6]; +static int font_cycles[6]; +static int before_cycles[6]; +static int extra_cycles[6]; + +/* border parameters for current display width */ +static int left_border_chars; +static int right_border_start; +#ifdef NEW_CYCLE_EXACT +static int left_border_start = LCHOP * 4; +static int right_border_end = (48 - RCHOP) * 4; +#define LBORDER_START left_border_start +#define RBORDER_END right_border_end +#else +#define LBORDER_START (LCHOP * 4) +#define RBORDER_END ((48 - RCHOP) * 4) +#endif /* NEW_CYCLE_EXACT */ + +/* set with CHBASE *and* CHACTL - bits 0..2 set if flip on */ +static UWORD chbase_20; /* CHBASE for 20 character mode */ + +/* set with CHACTL */ +static UBYTE invert_mask; +static int blank_mask; + +/* A scanline of AN0 and AN1 signals as transmitted from ANTIC to GTIA. + In every byte, bit 0 is AN0 and bit 1 is AN1 */ +static UBYTE an_scanline[ATARI_WIDTH / 2 + 8]; + +/* lookup tables */ +static UBYTE blank_lookup[256]; +static UWORD lookup2[256]; +ULONG ANTIC_lookup_gtia9[16]; +ULONG ANTIC_lookup_gtia11[16]; +static UBYTE playfield_lookup[257]; +static UBYTE mode_e_an_lookup[256]; + +/* Colour lookup table + This single table replaces 4 previously used: cl_word, cur_prior, + prior_table and pf_colls. It should be treated as a two-dimensional table, + with playfield colours in rows and PMG colours in columns: + no_PMG PM0 PM1 PM01 PM2 PM3 PM23 PM023 PM123 PM0123 PM25 PM35 PM235 colls ... ... + BAK + ... + HI2 + HI3 + PF0 + PF1 + PF2 + PF3 + The table contains word value (lsb = msb) of colour to be drawn. + The table is being updated taking current PRIOR setting into consideration. + '...' represent two unused columns and single unused row. + HI2 and HI3 are used only if colour_translation_table is being used. + They're colours of hi-res pixels on PF2 and PF3 respectively (PF2 is + default background for hi-res, PF3 is PM5). + Columns PM023, PM123 and PM0123 are used when PRIOR & 0xf equals any + of 5,7,0xc,0xd,0xe,0xf. The columns represent PM0, PM1 and PM01 respectively + covered by PM2 and/or PM3. This is to handle black colour on PF2 and PF3. + Columns PM25, PM35 and PM235 are used when PRIOR & 0x1f equals any + of 0x10,0x1a,0x1c,0x1e. The columns represent PM2, PM3 and PM23 + respectively covered by PM5. This to handle colour on PF0 and PF1: + PF3 if (PRIOR & 0x1f) == 0x10, PF0 or PF1 otherwise. + Additional column 'colls' holds collisions of playfields with PMG. */ + +UWORD ANTIC_cl[128]; + +#define C_PM0 0x01 +#define C_PM1 0x02 +#define C_PM01 0x03 +#define C_PM2 0x04 +#define C_PM3 0x05 +#define C_PM23 0x06 +#define C_PM023 0x07 +#define C_PM123 0x08 +#define C_PM0123 0x09 +#define C_PM25 0x0a +#define C_PM35 0x0b +#define C_PM235 0x0c +#define C_COLLS 0x0d +#define C_BAK 0x00 +#define C_HI2 0x20 +#define C_HI3 0x30 +#define C_PF0 0x40 +#define C_PF1 0x50 +#define C_PF2 0x60 +#define C_PF3 0x70 +#define C_BLACK (C_PF3 | C_PM25) + +/* these are byte-offsets in the table, so left shift for indexing word table + has been avoided */ +#define COLOUR(x) (*(UWORD *) ((UBYTE *) ANTIC_cl + (x) )) +#define L_PM0 (2 * C_PM0) +#define L_PM1 (2 * C_PM1) +#define L_PM01 (2 * C_PM01) +#define L_PM2 (2 * C_PM2) +#define L_PM3 (2 * C_PM3) +#define L_PM23 (2 * C_PM23) +#define L_PM023 (2 * C_PM023) +#define L_PM123 (2 * C_PM123) +#define L_PM0123 (2 * C_PM0123) +#define L_PM25 (2 * C_PM25) +#define L_PM35 (2 * C_PM35) +#define L_PM235 (2 * C_PM235) +#define L_COLLS (2 * C_COLLS) +#define L_BAK (2 * C_BAK) +#define L_HI2 (2 * C_HI2) +#define L_HI3 (2 * C_HI3) +#define L_PF0 (2 * C_PF0) +#define L_PF1 (2 * C_PF1) +#define L_PF2 (2 * C_PF2) +#define L_PF3 (2 * C_PF3) +#define L_BLACK (2 * C_BLACK) + +/* Blank areas optimizations + Routines for most graphics modes take advantage of fact, that often + large areas of screen are background colour. If it is possible, 8 pixels + of background are drawn at once - with two longs or four words, if + the platform doesn't allow unaligned long access. + Artifacting also uses unaligned long access if it's supported. */ + +#ifdef WORDS_UNALIGNED_OK + +#define INIT_BACKGROUND_6 ULONG background = ANTIC_cl[C_PF2] | (((ULONG) ANTIC_cl[C_PF2]) << 16); +#define INIT_BACKGROUND_8 ULONG background = ANTIC_lookup_gtia9[0]; +#define DRAW_BACKGROUND(colreg) { \ + WRITE_VIDEO_LONG_UNALIGNED((ULONG *) ptr, background); \ + WRITE_VIDEO_LONG_UNALIGNED(((ULONG *) ptr) + 1, background); \ + ptr += 4; \ + } +#define DRAW_ARTIF { \ + WRITE_VIDEO_LONG_UNALIGNED((ULONG *) ptr, art_curtable[(UBYTE) (screendata_tally >> 10)]); \ + WRITE_VIDEO_LONG_UNALIGNED(((ULONG *) ptr) + 1, art_curtable[(UBYTE) (screendata_tally >> 6)]); \ + ptr += 4; \ + } + +#else + +#define INIT_BACKGROUND_6 +#define INIT_BACKGROUND_8 +#define DRAW_BACKGROUND(colreg) {\ + WRITE_VIDEO(ptr, ANTIC_cl[colreg]); \ + WRITE_VIDEO(ptr + 1, ANTIC_cl[colreg]); \ + WRITE_VIDEO(ptr + 2, ANTIC_cl[colreg]); \ + WRITE_VIDEO(ptr + 3, ANTIC_cl[colreg]); \ + ptr += 4;\ + } +#define DRAW_ARTIF {\ + WRITE_VIDEO(ptr++, ((UWORD *) art_curtable)[(screendata_tally & 0x03fc00) >> 9]); \ + WRITE_VIDEO(ptr++, ((UWORD *) art_curtable)[((screendata_tally & 0x03fc00) >> 9) + 1]); \ + WRITE_VIDEO(ptr++, ((UWORD *) art_curtable)[(screendata_tally & 0x003fc0) >> 5]); \ + WRITE_VIDEO(ptr++, ((UWORD *) art_curtable)[((screendata_tally & 0x003fc0) >> 5) + 1]); \ + } + +#endif /* WORDS_UNALIGNED_OK */ + +#define DRAW_ARTIF_NEW {\ + WRITE_VIDEO(ptr++, art_lookup_new[(screendata_tally & 0x03f000) >> 12]); \ + WRITE_VIDEO(ptr++, art_lookup_new[(screendata_tally & 0x00fc00) >> 10]); \ + WRITE_VIDEO(ptr++, art_lookup_new[(screendata_tally & 0x003f00) >> 8]); \ + WRITE_VIDEO(ptr++, art_lookup_new[(screendata_tally & 0x000fc0) >> 6]); \ + } + +/* Hi-res modes optimizations + Now hi-res modes are drawn with words, not bytes. Endianess defaults + to little-endian. WORDS_BIGENDIAN should be defined when compiling on + a big-endian machine. */ + +#ifdef WORDS_BIGENDIAN +#define BYTE0_MASK 0xff00 +#define BYTE1_MASK 0x00ff +#define HIRES_MASK_01 0xfff0 +#define HIRES_MASK_10 0xf0ff +#define HIRES_LUM_01 0x000f +#define HIRES_LUM_10 0x0f00 +#else +#define BYTE0_MASK 0x00ff +#define BYTE1_MASK 0xff00 +#define HIRES_MASK_01 0xf0ff +#define HIRES_MASK_10 0xfff0 +#define HIRES_LUM_01 0x0f00 +#define HIRES_LUM_10 0x000f +#endif + +static UWORD hires_lookup_n[128]; +static UWORD hires_lookup_m[128]; +#define hires_norm(x) hires_lookup_n[(x) >> 1] +#define hires_mask(x) hires_lookup_m[(x) >> 1] + +#ifndef USE_COLOUR_TRANSLATION_TABLE +int ANTIC_artif_new = FALSE; /* New type of artifacting */ +UWORD ANTIC_hires_lookup_l[128]; /* accessed in gtia.c */ +#define hires_lum(x) ANTIC_hires_lookup_l[(x) >> 1] +#endif + +/* Player/Missile Graphics ------------------------------------------------- */ + +#define PF0PM (*(UBYTE *) &ANTIC_cl[C_PF0 | C_COLLS]) +#define PF1PM (*(UBYTE *) &ANTIC_cl[C_PF1 | C_COLLS]) +#define PF2PM (*(UBYTE *) &ANTIC_cl[C_PF2 | C_COLLS]) +#define PF3PM (*(UBYTE *) &ANTIC_cl[C_PF3 | C_COLLS]) +#define PF_COLLS(x) (((UBYTE *) &ANTIC_cl)[(x) + L_COLLS]) + +static int singleline; +int ANTIC_player_dma_enabled; +int ANTIC_player_gra_enabled; +int ANTIC_missile_dma_enabled; +int ANTIC_missile_gra_enabled; +int ANTIC_player_flickering; +int ANTIC_missile_flickering; + +static UWORD pmbase_s; +static UWORD pmbase_d; + +/* PMG lookup tables */ +static UBYTE pm_lookup_table[20][256]; +/* current PMG lookup table */ +static const UBYTE *pm_lookup_ptr; + +#define PL_00 0 /* 0x00,0x01,0x02,0x03,0x04,0x06,0x08,0x09,0x0a,0x0b */ +#define PL_05 1 /* 0x05,0x07,0x0c,0x0d,0x0e,0x0f */ +#define PL_10 2 /* 0x10,0x1a */ +#define PL_11 3 /* 0x11,0x18,0x19 */ +#define PL_12 4 /* 0x12 */ +#define PL_13 5 /* 0x13,0x1b */ +#define PL_14 6 /* 0x14,0x16 */ +#define PL_15 7 /* 0x15,0x17,0x1d,0x1f */ +#define PL_1c 8 /* 0x1c */ +#define PL_1e 9 /* 0x1e */ +#define PL_20 10 /* 0x20,0x21,0x22,0x23,0x24,0x26,0x28,0x29,0x2a,0x2b */ +#define PL_25 11 /* 0x25,0x27,0x2c,0x2d,0x2e,0x2f */ +#define PL_30 12 /* 0x30,0x3a */ +#define PL_31 13 /* 0x31,0x38,0x39 */ +#define PL_32 14 /* 0x32 */ +#define PL_33 15 /* 0x33,0x3b */ +#define PL_34 16 /* 0x34,0x36 */ +#define PL_35 17 /* 0x35,0x37,0x3d,0x3f */ +#define PL_3c 18 /* 0x3c */ +#define PL_3e 19 /* 0x3e */ + +static const UBYTE prior_to_pm_lookup[64] = { + PL_00, PL_00, PL_00, PL_00, PL_00, PL_05, PL_00, PL_05, + PL_00, PL_00, PL_00, PL_00, PL_05, PL_05, PL_05, PL_05, + PL_10, PL_11, PL_12, PL_13, PL_14, PL_15, PL_14, PL_15, + PL_11, PL_11, PL_10, PL_13, PL_1c, PL_15, PL_1e, PL_15, + PL_20, PL_20, PL_20, PL_20, PL_20, PL_25, PL_20, PL_25, + PL_20, PL_20, PL_20, PL_20, PL_25, PL_25, PL_25, PL_25, + PL_30, PL_31, PL_32, PL_33, PL_34, PL_35, PL_34, PL_35, + PL_31, PL_31, PL_30, PL_33, PL_3c, PL_35, PL_3e, PL_35 +}; + +static void init_pm_lookup(void) +{ + static const UBYTE pm_lookup_template[10][16] = { + /* PL_20 */ + { L_BAK, L_PM0, L_PM1, L_PM01, L_PM2, L_PM0, L_PM1, L_PM01, + L_PM3, L_PM0, L_PM1, L_PM01, L_PM23, L_PM0, L_PM1, L_PM01 }, + /* PL_25 */ + { L_BAK, L_PM0, L_PM1, L_PM01, L_PM2, L_PM023, L_PM123, L_PM0123, + L_PM3, L_PM023, L_PM123, L_PM0123, L_PM23, L_PM023, L_PM123, L_PM0123 }, + /* PL_30 */ + { L_PF3, L_PM0, L_PM1, L_PM01, L_PM25, L_PM0, L_PM1, L_PM01, + L_PM35, L_PM0, L_PM1, L_PM01, L_PM235, L_PM0, L_PM1, L_PM01 }, + /* PL_31 */ + { L_PF3, L_PM0, L_PM1, L_PM01, L_PM2, L_PM0, L_PM1, L_PM01, + L_PM3, L_PM0, L_PM1, L_PM01, L_PM23, L_PM0, L_PM1, L_PM01 }, + /* PL_32 */ + { L_PF3, L_PM0, L_PM1, L_PM01, L_PF3, L_PM0, L_PM1, L_PM01, + L_PF3, L_PM0, L_PM1, L_PM01, L_PF3, L_PM0, L_PM1, L_PM01 }, + /* PL_33 */ + { L_PF3, L_PM0, L_PM1, L_PM01, L_BLACK, L_PM0, L_PM1, L_PM01, + L_BLACK, L_PM0, L_PM1, L_PM01, L_BLACK, L_PM0, L_PM1, L_PM01 }, + /* PL_34 */ + { L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, + L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, L_PF3, L_PF3 }, + /* PL_35 */ + { L_PF3, L_PF3, L_PF3, L_PF3, L_BLACK, L_BLACK, L_BLACK, L_BLACK, + L_BLACK, L_BLACK, L_BLACK, L_BLACK, L_BLACK, L_BLACK, L_BLACK, L_BLACK }, + /* PL_3c */ + { L_PF3, L_PF3, L_PF3, L_PF3, L_PM25, L_PM25, L_PM25, L_PM25, + L_PM25, L_PM25, L_PM25, L_PM25, L_PM25, L_PM25, L_PM25, L_PM25 }, + /* PL_3e */ + { L_PF3, L_PF3, L_PF3, L_PF3, L_PM25, L_BLACK, L_BLACK, L_BLACK, + L_PM25, L_BLACK, L_BLACK, L_BLACK, L_PM25, L_BLACK, L_BLACK, L_BLACK } + }; + + static const UBYTE multi_to_normal[] = { + L_BAK, + L_PM0, L_PM1, L_PM0, + L_PM2, L_PM3, L_PM2, + L_PM023, L_PM123, L_PM023, + L_PM25, L_PM35, L_PM25 + }; + + int i; + int j; + UBYTE temp; + + for (i = 0; i <= 1; i++) + for (j = 0; j <= 255; j++) { + pm_lookup_table[i + 10][j] = temp = pm_lookup_template[i][(j & 0xf) | (j >> 4)]; + pm_lookup_table[i][j] = temp <= L_PM235 ? multi_to_normal[temp >> 1] : temp; + } + for (; i <= 9; i++) { + for (j = 0; j <= 15; j++) { + pm_lookup_table[i + 10][j] = temp = pm_lookup_template[i < 7 ? 0 : 1][j]; + pm_lookup_table[i][j] = temp <= L_PM235 ? multi_to_normal[temp >> 1] : temp; + } + for (; j <= 255; j++) { + pm_lookup_table[i + 10][j] = temp = pm_lookup_template[i][j & 0xf]; + pm_lookup_table[i][j] = temp <= L_PM235 ? multi_to_normal[temp >> 1] : temp; + } + } +} + +static const UBYTE hold_missiles_tab[16] = { + 0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f, + 0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff}; + +static void pmg_dma(void) +{ + /* VDELAY bit set == GTIA ignores PMG DMA in even lines */ + if (ANTIC_player_dma_enabled) { + if (ANTIC_player_gra_enabled) { + const UBYTE *base; + if (singleline) { + if (ANTIC_xe_ptr != NULL && pmbase_s < 0x8000 && pmbase_s >= 0x4000) + base = ANTIC_xe_ptr + pmbase_s - 0x4000 + ANTIC_ypos; + else + base = memory + pmbase_s + ANTIC_ypos; + if (ANTIC_ypos & 1) { + GTIA_GRAFP0 = base[0x400]; + GTIA_GRAFP1 = base[0x500]; + GTIA_GRAFP2 = base[0x600]; + GTIA_GRAFP3 = base[0x700]; + } + else { + if ((GTIA_VDELAY & 0x10) == 0) + GTIA_GRAFP0 = base[0x400]; + if ((GTIA_VDELAY & 0x20) == 0) + GTIA_GRAFP1 = base[0x500]; + if ((GTIA_VDELAY & 0x40) == 0) + GTIA_GRAFP2 = base[0x600]; + if ((GTIA_VDELAY & 0x80) == 0) + GTIA_GRAFP3 = base[0x700]; + } + } + else { + if (ANTIC_xe_ptr != NULL && pmbase_d < 0x8000 && pmbase_d >= 0x4000) + base = ANTIC_xe_ptr + (pmbase_d - 0x4000) + (ANTIC_ypos >> 1); + else + base = memory + pmbase_d + (ANTIC_ypos >> 1); + if (ANTIC_ypos & 1) { + GTIA_GRAFP0 = base[0x200]; + GTIA_GRAFP1 = base[0x280]; + GTIA_GRAFP2 = base[0x300]; + GTIA_GRAFP3 = base[0x380]; + } + else { + if ((GTIA_VDELAY & 0x10) == 0) + GTIA_GRAFP0 = base[0x200]; + if ((GTIA_VDELAY & 0x20) == 0) + GTIA_GRAFP1 = base[0x280]; + if ((GTIA_VDELAY & 0x40) == 0) + GTIA_GRAFP2 = base[0x300]; + if ((GTIA_VDELAY & 0x80) == 0) + GTIA_GRAFP3 = base[0x380]; + } + } + } + ANTIC_xpos += 4; + } + if (ANTIC_missile_dma_enabled) { + if (ANTIC_missile_gra_enabled) { + UBYTE data; + if (ANTIC_xe_ptr != NULL && pmbase_s < 0x8000 && pmbase_s >= 0x4000) + data = ANTIC_xe_ptr[singleline ? pmbase_s + ANTIC_ypos + 0x300 - 0x4000 : pmbase_d + (ANTIC_ypos >> 1) + 0x180 - 0x4000]; + else + data = MEMORY_dGetByte(singleline ? pmbase_s + ANTIC_ypos + 0x300 : pmbase_d + (ANTIC_ypos >> 1) + 0x180); + /* in odd lines load all missiles, in even only those, for which VDELAY bit is zero */ + GTIA_GRAFM = ANTIC_ypos & 1 ? data : ((GTIA_GRAFM ^ data) & hold_missiles_tab[GTIA_VDELAY & 0xf]) ^ data; + } + ANTIC_xpos++; + } +} + +/* Artifacting ------------------------------------------------------------ */ + +int ANTIC_artif_mode; + +static UWORD art_lookup_new[64]; +static UWORD art_colour1_new; +static UWORD art_colour2_new; + +static ULONG art_lookup_normal[256]; +static ULONG art_lookup_reverse[256]; +static ULONG art_bkmask_normal[256]; +static ULONG art_lummask_normal[256]; +static ULONG art_bkmask_reverse[256]; +static ULONG art_lummask_reverse[256]; + +static ULONG *art_curtable = art_lookup_normal; +static ULONG *art_curbkmask = art_bkmask_normal; +static ULONG *art_curlummask = art_lummask_normal; + +static UWORD art_normal_colpf1_save; +static UWORD art_normal_colpf2_save; +static UWORD art_reverse_colpf1_save; +static UWORD art_reverse_colpf2_save; + +static void setup_art_colours(void) +{ + static UWORD *art_colpf1_save = &art_normal_colpf1_save; + static UWORD *art_colpf2_save = &art_normal_colpf2_save; + UWORD curlum = ANTIC_cl[C_PF1] & 0x0f0f; + + if (curlum != *art_colpf1_save || ANTIC_cl[C_PF2] != *art_colpf2_save) { + if (curlum < (ANTIC_cl[C_PF2] & 0x0f0f)) { + art_colpf1_save = &art_reverse_colpf1_save; + art_colpf2_save = &art_reverse_colpf2_save; + art_curtable = art_lookup_reverse; + art_curlummask = art_lummask_reverse; + art_curbkmask = art_bkmask_reverse; + } + else { + art_colpf1_save = &art_normal_colpf1_save; + art_colpf2_save = &art_normal_colpf2_save; + art_curtable = art_lookup_normal; + art_curlummask = art_lummask_normal; + art_curbkmask = art_bkmask_normal; + } + if (curlum ^ *art_colpf1_save) { + int i; + ULONG new_colour = curlum ^ *art_colpf1_save; + new_colour |= new_colour << 16; + *art_colpf1_save = curlum; + for (i = 0; i <= 255; i++) + art_curtable[i] ^= art_curlummask[i] & new_colour; + } + if (ANTIC_cl[C_PF2] ^ *art_colpf2_save) { + int i; + ULONG new_colour = ANTIC_cl[C_PF2] ^ *art_colpf2_save; + new_colour |= new_colour << 16; + *art_colpf2_save = ANTIC_cl[C_PF2]; + for (i = 0; i <= 255; i++) + art_curtable[i] ^= art_curbkmask[i] & new_colour; + } + + } +} + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + +/* Initialization ---------------------------------------------------------- */ + +int ANTIC_Initialise(void) +{ +#if !defined(BASIC) && !defined(CURSES_BASIC) +#if SKIP + int i, j; + + for (i = j = 1; i < *argc; i++) { + int i_a = (i + 1 < *argc); /* is argument available? */ + int a_m = FALSE; /* error, argument missing! */ + + if (strcmp(argv[i], "-artif") == 0) { + if (i_a) { + ANTIC_artif_mode = Util_sscandec(argv[++i]); + if (ANTIC_artif_mode < 0 || ANTIC_artif_mode > 4) { + Log_print("Invalid artifacting mode, using default."); + ANTIC_artif_mode = 0; + } + } + else a_m = TRUE; + } + else { + if (strcmp(argv[i], "-help") == 0) { + Log_print("\t-artif Set artifacting mode 0-4 (0 = disable)"); + } + argv[j++] = argv[i]; + } + + if (a_m) { + Log_print("Missing argument for '%s'", argv[i]); + return FALSE; + } + } + *argc = j; +#endif + ANTIC_UpdateArtifacting(); + + playfield_lookup[0x00] = L_BAK; + playfield_lookup[0x40] = L_PF0; + playfield_lookup[0x80] = L_PF1; + playfield_lookup[0xc0] = L_PF2; + playfield_lookup[0x100] = L_PF3; + blank_lookup[0x80] = blank_lookup[0xa0] = blank_lookup[0xc0] = blank_lookup[0xe0] = 0x00; + hires_mask(0x00) = 0xffff; +#ifdef USE_COLOUR_TRANSLATION_TABLE + hires_mask(0x40) = BYTE0_MASK; + hires_mask(0x80) = BYTE1_MASK; + hires_mask(0xc0) = 0; +#else + hires_mask(0x40) = HIRES_MASK_01; + hires_mask(0x80) = HIRES_MASK_10; + hires_mask(0xc0) = 0xf0f0; + hires_lum(0x00) = hires_lum(0x40) = hires_lum(0x80) = hires_lum(0xc0) = 0; +#endif + init_pm_lookup(); + mode_e_an_lookup[0] = 0; + mode_e_an_lookup[1] = mode_e_an_lookup[4] = mode_e_an_lookup[0x10] = mode_e_an_lookup[0x40] = 0; + mode_e_an_lookup[2] = mode_e_an_lookup[8] = mode_e_an_lookup[0x20] = mode_e_an_lookup[0x80] = 1; + mode_e_an_lookup[3] = mode_e_an_lookup[12] = mode_e_an_lookup[0x30] = mode_e_an_lookup[0xc0] = 2; +#ifdef NEW_CYCLE_EXACT + CYCLE_MAP_Create(); + ANTIC_cpu2antic_ptr = &CYCLE_MAP_cpu2antic[0]; + ANTIC_antic2cpu_ptr = &CYCLE_MAP_antic2cpu[0]; +#endif /* NEW_CYCLE_EXACT */ + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + + return TRUE; +} + +void ANTIC_Reset(void) +{ + ANTIC_NMIEN = 0x00; + ANTIC_NMIST = 0x1f; + ANTIC_PutByte(ANTIC_OFFSET_DMACTL, 0); +} + +#if !defined(BASIC) && !defined(CURSES_BASIC) + +/* Border ------------------------------------------------------------------ */ + +#define DO_BORDER_1 {\ + if (IS_ZERO_ULONG(pm_scanline_ptr)) {\ + ULONG *l_ptr = (ULONG *) ptr;\ + WRITE_VIDEO_LONG(l_ptr++, background); \ + WRITE_VIDEO_LONG(l_ptr++, background); \ + ptr = (UWORD *) l_ptr;\ + pm_scanline_ptr += 4;\ + }\ + else {\ + int k = 4;\ + do + +#define DO_BORDER DO_BORDER_1\ + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[*pm_scanline_ptr++]));\ + while (--k);\ + }\ +} + +#define DO_GTIA10_BORDER DO_BORDER_1\ + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[*pm_scanline_ptr++ | 1]));\ + while (--k);\ + }\ +} + +static void do_border(void) +{ + int kk; + UWORD *ptr = &scrn_ptr[LBORDER_START]; + const UBYTE *pm_scanline_ptr = >IA_pm_scanline[LBORDER_START]; + ULONG background = ANTIC_lookup_gtia9[0]; + /* left border */ + for (kk = left_border_chars; kk; kk--) + DO_BORDER + /* right border */ + ptr = &scrn_ptr[right_border_start]; + pm_scanline_ptr = >IA_pm_scanline[right_border_start]; + while (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]) + DO_BORDER +} + +static void do_border_gtia10(void) +{ + int kk; + UWORD *ptr = &scrn_ptr[LBORDER_START]; + const UBYTE *pm_scanline_ptr = >IA_pm_scanline[LBORDER_START]; + ULONG background = ANTIC_cl[C_PM0] | (ANTIC_cl[C_PM0] << 16); + /* left border */ + for (kk = left_border_chars; kk; kk--) + DO_GTIA10_BORDER + WRITE_VIDEO(ptr, COLOUR(pm_lookup_ptr[*pm_scanline_ptr | 1])); /* one extra pixel, because of the right shift of gtia10*/ + /* right border */ + pm_scanline_ptr = >IA_pm_scanline[right_border_start]; + if (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]) { + ptr = &scrn_ptr[right_border_start + 1]; /*start one pixel further right because of the right shift of gtia10*/ + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[pm_scanline_ptr[1] | 1])); + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[pm_scanline_ptr[2] | 1])); + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[pm_scanline_ptr[3] | 1])); + pm_scanline_ptr += 4; + while (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]) + DO_GTIA10_BORDER + } +} + +static void do_border_gtia11(void) +{ + int kk; + UWORD *ptr = &scrn_ptr[LBORDER_START]; + const UBYTE *pm_scanline_ptr = >IA_pm_scanline[LBORDER_START]; + ULONG background = ANTIC_lookup_gtia11[0]; +#ifdef USE_COLOUR_TRANSLATION_TABLE + ANTIC_cl[C_PF3] = colour_translation_table[GTIA_COLPF3 & 0xf0]; +#else + ANTIC_cl[C_PF3] &= 0xf0f0; +#endif + ANTIC_cl[C_BAK] = (UWORD) background; + /* left border */ + for (kk = left_border_chars; kk; kk--) + DO_BORDER + /* right border */ + ptr = &scrn_ptr[right_border_start]; + pm_scanline_ptr = >IA_pm_scanline[right_border_start]; + while (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]) + DO_BORDER + GTIA_COLOUR_TO_WORD(ANTIC_cl[C_PF3],GTIA_COLPF3) + GTIA_COLOUR_TO_WORD(ANTIC_cl[C_BAK],GTIA_COLBK) +} + +static void draw_antic_0(void) +{ + UWORD *ptr = scrn_ptr + LBORDER_START; + if (GTIA_pm_dirty) { + const UBYTE *pm_scanline_ptr = >IA_pm_scanline[LBORDER_START]; + ULONG background = ANTIC_lookup_gtia9[0]; + do + DO_BORDER + while (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]); + } + else + FILL_VIDEO(ptr, ANTIC_cl[C_BAK], (RBORDER_END - LBORDER_START) * 2); +} + +static void draw_antic_0_gtia10(void) +{ + UWORD *ptr = scrn_ptr + LBORDER_START; + if (GTIA_pm_dirty) { + const UBYTE *pm_scanline_ptr = >IA_pm_scanline[LBORDER_START]; + ULONG background = ANTIC_cl[C_PM0] | (ANTIC_cl[C_PM0] << 16); + do + DO_GTIA10_BORDER + while (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]); + } + else + FILL_VIDEO(ptr, ANTIC_cl[C_PM0], (RBORDER_END - LBORDER_START) * 2); +} + +static void draw_antic_0_gtia11(void) +{ + UWORD *ptr = scrn_ptr + LBORDER_START; + if (GTIA_pm_dirty) { + const UBYTE *pm_scanline_ptr = >IA_pm_scanline[LBORDER_START]; + ULONG background = ANTIC_lookup_gtia11[0]; +#ifdef USE_COLOUR_TRANSLATION_TABLE + ANTIC_cl[C_PF3] = colour_translation_table[GTIA_COLPF3 & 0xf0]; +#else + ANTIC_cl[C_PF3] &= 0xf0f0; +#endif + ANTIC_cl[C_BAK] = (UWORD) background; + do + DO_BORDER + while (pm_scanline_ptr < >IA_pm_scanline[RBORDER_END]); + GTIA_COLOUR_TO_WORD(ANTIC_cl[C_PF3],GTIA_COLPF3) + GTIA_COLOUR_TO_WORD(ANTIC_cl[C_BAK],GTIA_COLBK) + } + else + FILL_VIDEO(ptr, ANTIC_lookup_gtia11[0], (RBORDER_END - LBORDER_START) * 2); +} + +/* ANTIC modes ------------------------------------------------------------- */ + +static const UBYTE gtia_10_lookup[] = +{L_BAK, L_BAK, L_BAK, L_BAK, L_PF0, L_PF1, L_PF2, L_PF3, + L_BAK, L_BAK, L_BAK, L_BAK, L_PF0, L_PF1, L_PF2, L_PF3}; +static const UBYTE gtia_10_pm[] = +{1, 2, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static void draw_an_gtia9(const ULONG *t_pm_scanline_ptr) +{ + int i = ((const UBYTE *) t_pm_scanline_ptr - GTIA_pm_scanline) & ~1; + while (i < right_border_start) { + UWORD *ptr = scrn_ptr + i; + int pixel = (an_scanline[i] << 2) + an_scanline[i + 1]; + UBYTE pm_reg; + WRITE_VIDEO_LONG((ULONG *) ptr, ANTIC_lookup_gtia9[pixel]); + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + pm_reg = pm_lookup_ptr[pm_reg]; + if (pm_reg == L_PF3) { +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[pixel | GTIA_COLPF3]); +#else + WRITE_VIDEO(ptr, pixel | (pixel << 8) | ANTIC_cl[C_PF3]); +#endif + } + else { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + i++; + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + pm_reg = pm_lookup_ptr[pm_reg]; + if (pm_reg == L_PF3) { +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr + 1, colour_translation_table[pixel | GTIA_COLPF3]); +#else + WRITE_VIDEO(ptr + 1, pixel | (pixel << 8) | ANTIC_cl[C_PF3]); +#endif + } + else { + WRITE_VIDEO(ptr + 1, COLOUR(pm_reg)); + } + } + i++; + } + do_border(); +} + +static void draw_an_gtia10(const ULONG *t_pm_scanline_ptr) +{ + int i = ((const UBYTE *) t_pm_scanline_ptr - GTIA_pm_scanline) | 1; + UWORD lookup_gtia10[16]; + lookup_gtia10[0] = ANTIC_cl[C_PM0]; + lookup_gtia10[1] = ANTIC_cl[C_PM1]; + lookup_gtia10[2] = ANTIC_cl[C_PM2]; + lookup_gtia10[3] = ANTIC_cl[C_PM3]; + lookup_gtia10[12] = lookup_gtia10[4] = ANTIC_cl[C_PF0]; + lookup_gtia10[13] = lookup_gtia10[5] = ANTIC_cl[C_PF1]; + lookup_gtia10[14] = lookup_gtia10[6] = ANTIC_cl[C_PF2]; + lookup_gtia10[15] = lookup_gtia10[7] = ANTIC_cl[C_PF3]; + lookup_gtia10[8] = lookup_gtia10[9] = lookup_gtia10[10] = lookup_gtia10[11] = ANTIC_cl[C_BAK]; + while (i < right_border_start) { + UWORD *ptr = scrn_ptr + i; + int pixel = (an_scanline[i - 1] << 2) + an_scanline[i]; + UBYTE pm_reg; + int colreg; + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + colreg = gtia_10_lookup[pixel]; + PF_COLLS(colreg) |= pm_reg; + pm_reg |= gtia_10_pm[pixel]; + WRITE_VIDEO(ptr, COLOUR(pm_lookup_ptr[pm_reg] | colreg)); + } + else { + WRITE_VIDEO(ptr, lookup_gtia10[pixel]); + } + i++; + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + colreg = gtia_10_lookup[pixel]; + PF_COLLS(colreg) |= pm_reg; + pm_reg |= gtia_10_pm[pixel]; + WRITE_VIDEO(ptr + 1, COLOUR(pm_lookup_ptr[pm_reg] | colreg)); + } + else { + WRITE_VIDEO(ptr + 1, lookup_gtia10[pixel]); + } + i++; + } + do_border_gtia10(); +} + +static void draw_an_gtia11(const ULONG *t_pm_scanline_ptr) +{ + int i = ((const UBYTE *) t_pm_scanline_ptr - GTIA_pm_scanline) & ~1; + while (i < right_border_start) { + UWORD *ptr = scrn_ptr + i; + int pixel = (an_scanline[i] << 2) + an_scanline[i + 1]; + UBYTE pm_reg; + WRITE_VIDEO_LONG((ULONG *) ptr, ANTIC_lookup_gtia11[pixel]); + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + pm_reg = pm_lookup_ptr[pm_reg]; + if (pm_reg == L_PF3) { +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[pixel ? pixel | GTIA_COLPF3 : GTIA_COLPF3 & 0xf0]); +#else + WRITE_VIDEO(ptr, pixel ? (pixel << 4) | (pixel << 12) | ANTIC_cl[C_PF3] : ANTIC_cl[C_PF3] & 0xf0f0); +#endif + } + else { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + i++; + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + pm_reg = pm_lookup_ptr[pm_reg]; + if (pm_reg == L_PF3) { +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr + 1, colour_translation_table[pixel ? pixel | GTIA_COLPF3 : GTIA_COLPF3 & 0xf0]); +#else + WRITE_VIDEO(ptr + 1, pixel ? (pixel << 4) | (pixel << 12) | ANTIC_cl[C_PF3] : ANTIC_cl[C_PF3] & 0xf0f0); +#endif + } + else { + WRITE_VIDEO(ptr + 1, COLOUR(pm_reg)); + } + } + i++; + } + do_border_gtia11(); +} + +static void draw_an_gtia_bug(const ULONG *t_pm_scanline_ptr) +{ + static const UBYTE gtia_bug_colreg[] = {L_PF0, L_PF1, L_PF2, L_PF3}; + UWORD lookup_gtia_bug[16]; + int i; + lookup_gtia_bug[0] = ANTIC_cl[C_PF0]; + lookup_gtia_bug[1] = ANTIC_cl[C_PF1]; + lookup_gtia_bug[2] = ANTIC_cl[C_PF2]; + lookup_gtia_bug[3] = ANTIC_cl[C_PF3]; + i = ((const UBYTE *) t_pm_scanline_ptr - GTIA_pm_scanline); + while (i < right_border_start) { + UWORD *ptr = scrn_ptr + i; + int pixel = an_scanline[i]; + UBYTE pm_reg; + int colreg; + pm_reg = GTIA_pm_scanline[i]; + if (pm_reg) { + colreg = gtia_bug_colreg[pixel]; + PF_COLLS(colreg) |= pm_reg; + WRITE_VIDEO(ptr, COLOUR(pm_lookup_ptr[pm_reg] | colreg)); + } + else { + WRITE_VIDEO(ptr, lookup_gtia_bug[pixel]); + } + i++; + } + do_border(); +} + +#define DEFINE_DRAW_AN(anticmode) \ + static void draw_antic_ ## anticmode ## _gtia9 (int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr)\ + {\ + prepare_an_antic_ ## anticmode (nchars, antic_memptr, t_pm_scanline_ptr);\ + draw_an_gtia9(t_pm_scanline_ptr);\ + }\ + static void draw_antic_ ## anticmode ## _gtia10 (int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr)\ + {\ + prepare_an_antic_ ## anticmode (nchars, antic_memptr, t_pm_scanline_ptr);\ + draw_an_gtia10(t_pm_scanline_ptr);\ + }\ + static void draw_antic_ ## anticmode ## _gtia11 (int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr)\ + {\ + prepare_an_antic_ ## anticmode (nchars, antic_memptr, t_pm_scanline_ptr);\ + draw_an_gtia11(t_pm_scanline_ptr);\ + } + +#define CHAR_LOOP_BEGIN do { +#define CHAR_LOOP_END } while (--nchars); + +#define DO_PMG_LORES PF_COLLS(colreg) |= pm_pixel = *c_pm_scanline_ptr++;\ + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[pm_pixel] | colreg)); + +#ifdef ALTERNATE_LOOP_COUNTERS /* speeds-up pmg in hires a bit or not? try it :) */ +#define FOUR_LOOP_BEGIN(data) data |= 0x800000; do { /* data becomes negative after four data <<= 2 */ +#define FOUR_LOOP_END(data) } while (data >= 0); +#else +#define FOUR_LOOP_BEGIN(data) int k = 4; do { +#define FOUR_LOOP_END(data) } while (--k); +#endif + +#ifdef USE_COLOUR_TRANSLATION_TABLE + +#define INIT_HIRES hires_norm(0x00) = ANTIC_cl[C_PF2];\ + hires_norm(0x40) = hires_norm(0x10) = hires_norm(0x04) = (ANTIC_cl[C_PF2] & BYTE0_MASK) | (ANTIC_cl[C_HI2] & BYTE1_MASK);\ + hires_norm(0x80) = hires_norm(0x20) = hires_norm(0x08) = (ANTIC_cl[C_HI2] & BYTE0_MASK) | (ANTIC_cl[C_PF2] & BYTE1_MASK);\ + hires_norm(0xc0) = hires_norm(0x30) = hires_norm(0x0c) = ANTIC_cl[C_HI2]; + +#define DO_PMG_HIRES(data) {\ + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr;\ + int pm_pixel;\ + int mask;\ + FOUR_LOOP_BEGIN(data)\ + pm_pixel = *c_pm_scanline_ptr++;\ + if (data & 0xc0)\ + PF2PM |= pm_pixel;\ + mask = hires_mask(data & 0xc0);\ + pm_pixel = pm_lookup_ptr[pm_pixel] | L_PF2;\ + WRITE_VIDEO(ptr++, (COLOUR(pm_pixel) & mask) | (COLOUR(pm_pixel + (L_HI2 - L_PF2)) & ~mask));\ + data <<= 2;\ + FOUR_LOOP_END(data)\ +} + +#else /* USE_COLOUR_TRANSLATION_TABLE */ + +#define INIT_HIRES hires_norm(0x00) = ANTIC_cl[C_PF2];\ + hires_norm(0x40) = hires_norm(0x10) = hires_norm(0x04) = (ANTIC_cl[C_PF2] & HIRES_MASK_01) | hires_lum(0x40);\ + hires_norm(0x80) = hires_norm(0x20) = hires_norm(0x08) = (ANTIC_cl[C_PF2] & HIRES_MASK_10) | hires_lum(0x80);\ + hires_norm(0xc0) = hires_norm(0x30) = hires_norm(0x0c) = (ANTIC_cl[C_PF2] & 0xf0f0) | hires_lum(0xc0); + +#define INIT_ARTIF_NEW art_lookup_new[0] = art_lookup_new[1] = art_lookup_new[2] = art_lookup_new[3] = \ + art_lookup_new[16] = art_lookup_new[17] = art_lookup_new[18] = art_lookup_new[19] = \ + art_lookup_new[32] = art_lookup_new[33] = art_lookup_new[34] = art_lookup_new[35] = \ + art_lookup_new[48] = art_lookup_new[49] = art_lookup_new[50] = art_lookup_new[51] = ANTIC_cl[C_PF2];\ + art_lookup_new[7] = art_lookup_new[23] = art_lookup_new[39] = art_lookup_new[55] = (ANTIC_cl[C_PF2] & HIRES_MASK_01) | hires_lum(0x40);\ + art_lookup_new[56] = art_lookup_new[57] = art_lookup_new[58] = art_lookup_new[59] = (ANTIC_cl[C_PF2] & HIRES_MASK_10) | hires_lum(0x80);\ + art_lookup_new[12] = art_lookup_new[13] = art_lookup_new[14] = art_lookup_new[15] = \ + art_lookup_new[28] = art_lookup_new[29] = art_lookup_new[30] = art_lookup_new[31] = \ + art_lookup_new[44] = art_lookup_new[45] = art_lookup_new[46] = art_lookup_new[47] = \ + art_lookup_new[60] = art_lookup_new[61] = art_lookup_new[62] = art_lookup_new[63] = (ANTIC_cl[C_PF2] & 0xf0f0) | hires_lum(0xc0);\ + if ((ANTIC_cl[C_PF2] & 0x0F00) != (ANTIC_cl[C_PF1] & 0x0F00)) { \ + art_lookup_new[4] = art_lookup_new[5] = art_lookup_new[36] = art_lookup_new[37] = \ + art_lookup_new[52] = art_lookup_new[53 ]= ((art_colour1_new & BYTE1_MASK & ~(HIRES_LUM_01))) | hires_lum(0x40) | (ANTIC_cl[C_PF2] & BYTE0_MASK);\ + art_lookup_new[20] = art_lookup_new[21] = (art_colour1_new & 0xf0f0) | hires_lum(0xc0);\ + art_lookup_new[8] = art_lookup_new[9] = art_lookup_new[11] = art_lookup_new[40] = \ + art_lookup_new[43] = ((art_colour2_new & BYTE0_MASK & ~(HIRES_LUM_10))) | hires_lum(0x80) | (ANTIC_cl[C_PF2] & BYTE1_MASK);\ + art_lookup_new[10] = art_lookup_new[41] = art_lookup_new[42] = (art_colour2_new & 0xf0f0) | hires_lum(0xc0);\ + }\ + else {\ + art_lookup_new[4] = art_lookup_new[5] = art_lookup_new[36] = art_lookup_new[37] = \ + art_lookup_new[52] = art_lookup_new[53 ]= art_lookup_new[20] = art_lookup_new[21] = \ + art_lookup_new[8] = art_lookup_new[9] = art_lookup_new[11] = art_lookup_new[40] = \ + art_lookup_new[43] = art_lookup_new[10] = art_lookup_new[41] = art_lookup_new[42] = ANTIC_cl[C_PF2];\ + }\ + art_lookup_new[6] = art_lookup_new[22] = art_lookup_new[38] = art_lookup_new[54] = (ANTIC_cl[C_PF2] & HIRES_MASK_01) | hires_lum(0x40);\ + art_lookup_new[24] = art_lookup_new[25] = art_lookup_new[26] = art_lookup_new[27] = (ANTIC_cl[C_PF2] & HIRES_MASK_10) | hires_lum(0x80); + +#define DO_PMG_HIRES(data) {\ + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr;\ + int pm_pixel;\ + FOUR_LOOP_BEGIN(data)\ + pm_pixel = *c_pm_scanline_ptr++;\ + if (data & 0xc0)\ + PF2PM |= pm_pixel;\ + WRITE_VIDEO(ptr++, (COLOUR(pm_lookup_ptr[pm_pixel] | L_PF2) & hires_mask(data & 0xc0)) | hires_lum(data & 0xc0));\ + data <<= 2;\ + FOUR_LOOP_END(data)\ +} + +#define DO_PMG_HIRES_NEW(data, tally) {\ + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr;\ + int pm_pixel;\ + FOUR_LOOP_BEGIN(data)\ + pm_pixel = *c_pm_scanline_ptr++;\ + if (pm_pixel) \ + WRITE_VIDEO(ptr++, (COLOUR(pm_lookup_ptr[pm_pixel] | L_PF2)));\ + else\ + WRITE_VIDEO(ptr++, art_lookup_new[(tally & 0xfc0000) >> 18]); \ + data <<= 2;\ + tally <<= 6;\ + FOUR_LOOP_END(data)\ +} + +#endif /* USE_COLOUR_TRANSLATION_TABLE */ + +#ifdef NEW_CYCLE_EXACT +#define ADD_FONT_CYCLES +#else +#define ADD_FONT_CYCLES ANTIC_xpos += font_cycles[md] +#endif + +#ifdef PAGED_MEM + +#define INIT_ANTIC_2 int t_chbase = (dctr ^ chbase_20) & 0xfc07;\ + ADD_FONT_CYCLES;\ + blank_lookup[0x60] = (anticmode == 2 || dctr & 0xe) ? 0xff : 0;\ + blank_lookup[0x00] = blank_lookup[0x20] = blank_lookup[0x40] = (dctr & 0xe) == 8 ? 0 : 0xff; + +#define GET_CHDATA_ANTIC_2 chdata = (screendata & invert_mask) ? 0xff : 0;\ + if (blank_lookup[screendata & blank_mask])\ + chdata ^= MEMORY_dGetByte(t_chbase + ((UWORD) (screendata & 0x7f) << 3)); + +#else /* PAGED_MEM */ + +#define INIT_ANTIC_2 const UBYTE *chptr;\ + if (ANTIC_xe_ptr != NULL && chbase_20 < 0x8000 && chbase_20 >= 0x4000)\ + chptr = ANTIC_xe_ptr + ((dctr ^ chbase_20) & 0x3c07);\ + else\ + chptr = MEMORY_mem + ((dctr ^ chbase_20) & 0xfc07);\ + ADD_FONT_CYCLES;\ + blank_lookup[0x60] = (anticmode == 2 || dctr & 0xe) ? 0xff : 0;\ + blank_lookup[0x00] = blank_lookup[0x20] = blank_lookup[0x40] = (dctr & 0xe) == 8 ? 0 : 0xff; + +#define GET_CHDATA_ANTIC_2 chdata = (screendata & invert_mask) ? 0xff : 0;\ + if (blank_lookup[screendata & blank_mask])\ + chdata ^= chptr[(screendata & 0x7f) << 3]; + +#endif /* PAGED_MEM */ + +static void draw_antic_2(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_BACKGROUND_6 + INIT_ANTIC_2 + INIT_HIRES + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int chdata; + + GET_CHDATA_ANTIC_2 + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + if (chdata) { + WRITE_VIDEO(ptr++, hires_norm(chdata & 0xc0)); + WRITE_VIDEO(ptr++, hires_norm(chdata & 0x30)); + WRITE_VIDEO(ptr++, hires_norm(chdata & 0x0c)); + WRITE_VIDEO(ptr++, hires_norm((chdata & 0x03) << 2)); + } + else + DRAW_BACKGROUND(C_PF2) + } + else + DO_PMG_HIRES(chdata) + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +#ifdef NEW_CYCLE_EXACT +static void draw_antic_2_dmactl_bug(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_BACKGROUND_6 + INIT_ANTIC_2 + (void)chptr; /* suppress GCC -Wunused-but-set-variable warning */ + INIT_HIRES + + CHAR_LOOP_BEGIN + /* UBYTE screendata = *antic_memptr++; */ + +/* In this glitched mode, the output depends on the MSB of the last char */ +/* drawn in the previous line, and invert_mask. It seems to reveal that */ +/* ANTIC has a latch that is set by the MSB of the char that controls an */ +/* invert gate. */ +/* When this gate was set on the last line and the next line is glitched */ +/* it remains set and the whole line appears inverted */ +/* We'll use this modeline to draw antic f glitched as well, and set */ +/* dmactl_bug_chdata to 0 */ + int chdata = (dmactl_bug_chdata & invert_mask) ? 0xff : 0; + /* GET_CHDATA_ANTIC_2 */ + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + + if (chdata) { + WRITE_VIDEO(ptr++, hires_norm(chdata & 0xc0)); + WRITE_VIDEO(ptr++, hires_norm(chdata & 0x30)); + WRITE_VIDEO(ptr++, hires_norm(chdata & 0x0c)); + WRITE_VIDEO(ptr++, hires_norm((chdata & 0x03) << 2)); + } + else + DRAW_BACKGROUND(C_PF2) + } + else + DO_PMG_HIRES(chdata) + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} +#endif + +static void draw_antic_2_artif(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + ULONG screendata_tally; + INIT_ANTIC_2 + { + UBYTE screendata = *antic_memptr++; + UBYTE chdata; + GET_CHDATA_ANTIC_2 + screendata_tally = chdata; + } + setup_art_colours(); + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + ULONG chdata; + + GET_CHDATA_ANTIC_2 + screendata_tally <<= 8; + screendata_tally |= chdata; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + DRAW_ARTIF + else { + chdata = screendata_tally >> 8; + DO_PMG_HIRES(chdata) + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +#ifndef USE_COLOUR_TRANSLATION_TABLE +static void draw_antic_2_artif_new(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + ULONG screendata_tally; + ULONG pmtally; + UBYTE screendata = *antic_memptr++; + UBYTE chdata; + INIT_ANTIC_2 + INIT_ARTIF_NEW + GET_CHDATA_ANTIC_2 + screendata_tally = chdata; + setup_art_colours(); + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + ULONG chdata; + + GET_CHDATA_ANTIC_2 + screendata_tally <<= 8; + screendata_tally |= chdata; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + DRAW_ARTIF_NEW + else { + chdata = screendata_tally >> 8; + pmtally = ((screendata_tally & 0x03f000) << 6) | + ((screendata_tally & 0x00fc00) << 2) | + ((screendata_tally & 0x003f00) >> 2) | + ((screendata_tally & 0x000fc0) >> 6); + DO_PMG_HIRES_NEW(chdata,pmtally) + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} +#endif + +static void prepare_an_antic_2(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); +#ifdef PAGED_MEM + int t_chbase = (dctr ^ chbase_20) & 0xfc07; +#else + const UBYTE *chptr; + if (ANTIC_xe_ptr != NULL && chbase_20 < 0x8000 && chbase_20 >= 0x4000) + chptr = ANTIC_xe_ptr + ((dctr ^ chbase_20) & 0x3c07); + else + chptr = MEMORY_mem + ((dctr ^ chbase_20) & 0xfc07); +#endif + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int chdata; + GET_CHDATA_ANTIC_2 + *an_ptr++ = chdata >> 6; + *an_ptr++ = (chdata >> 4) & 3; + *an_ptr++ = (chdata >> 2) & 3; + *an_ptr++ = chdata & 3; + CHAR_LOOP_END +} + +static void draw_antic_2_gtia9(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_ANTIC_2 + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_2(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia9(t_pm_scanline_ptr); + return; + } + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int chdata; + + GET_CHDATA_ANTIC_2 + WRITE_VIDEO_LONG((ULONG *) ptr, ANTIC_lookup_gtia9[chdata >> 4]); + WRITE_VIDEO_LONG((ULONG *) ptr + 1, ANTIC_lookup_gtia9[chdata & 0xf]); + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + ptr += 4; + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int k = 4; + UBYTE pm_reg; + do { + pm_reg = pm_lookup_ptr[*c_pm_scanline_ptr++]; + if (pm_reg) { + if (pm_reg == L_PF3) { + UBYTE tmp = k > 2 ? chdata >> 4 : chdata & 0xf; +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[tmp | GTIA_COLPF3]); +#else + WRITE_VIDEO(ptr, tmp | ((UWORD)tmp << 8) | ANTIC_cl[C_PF3]); +#endif + } + else + { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + ptr++; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +static void draw_antic_2_gtia10(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ +#ifdef WORDS_UNALIGNED_OK + ULONG lookup_gtia10[16]; +#else + UWORD lookup_gtia10[16]; +#endif + INIT_ANTIC_2 + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_2(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia10(t_pm_scanline_ptr); + return; + } + +#ifdef WORDS_UNALIGNED_OK + lookup_gtia10[0] = ANTIC_cl[C_PM0] | (ANTIC_cl[C_PM0] << 16); + lookup_gtia10[1] = ANTIC_cl[C_PM1] | (ANTIC_cl[C_PM1] << 16); + lookup_gtia10[2] = ANTIC_cl[C_PM2] | (ANTIC_cl[C_PM2] << 16); + lookup_gtia10[3] = ANTIC_cl[C_PM3] | (ANTIC_cl[C_PM3] << 16); + lookup_gtia10[12] = lookup_gtia10[4] = ANTIC_cl[C_PF0] | (ANTIC_cl[C_PF0] << 16); + lookup_gtia10[13] = lookup_gtia10[5] = ANTIC_cl[C_PF1] | (ANTIC_cl[C_PF1] << 16); + lookup_gtia10[14] = lookup_gtia10[6] = ANTIC_cl[C_PF2] | (ANTIC_cl[C_PF2] << 16); + lookup_gtia10[15] = lookup_gtia10[7] = ANTIC_cl[C_PF3] | (ANTIC_cl[C_PF3] << 16); + lookup_gtia10[8] = lookup_gtia10[9] = lookup_gtia10[10] = lookup_gtia10[11] = ANTIC_lookup_gtia9[0]; +#else + lookup_gtia10[0] = ANTIC_cl[C_PM0]; + lookup_gtia10[1] = ANTIC_cl[C_PM1]; + lookup_gtia10[2] = ANTIC_cl[C_PM2]; + lookup_gtia10[3] = ANTIC_cl[C_PM3]; + lookup_gtia10[12] = lookup_gtia10[4] = ANTIC_cl[C_PF0]; + lookup_gtia10[13] = lookup_gtia10[5] = ANTIC_cl[C_PF1]; + lookup_gtia10[14] = lookup_gtia10[6] = ANTIC_cl[C_PF2]; + lookup_gtia10[15] = lookup_gtia10[7] = ANTIC_cl[C_PF3]; + lookup_gtia10[8] = lookup_gtia10[9] = lookup_gtia10[10] = lookup_gtia10[11] = ANTIC_cl[C_BAK]; +#endif + ptr++; + t_pm_scanline_ptr = (const ULONG *) (((const UBYTE *) t_pm_scanline_ptr) + 1); + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int chdata; + + GET_CHDATA_ANTIC_2 + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + DO_GTIA_BYTE(ptr, lookup_gtia10, chdata) + ptr += 4; + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + UBYTE t_screendata = chdata >> 4; + do { + colreg = gtia_10_lookup[t_screendata]; + PF_COLLS(colreg) |= pm_pixel = *c_pm_scanline_ptr++; + pm_pixel |= gtia_10_pm[t_screendata]; + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[pm_pixel] | colreg)); + if (k == 3) + t_screendata = chdata & 0x0f; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border_gtia10(); +} + +static void draw_antic_2_gtia11(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_ANTIC_2 + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_2(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia11(t_pm_scanline_ptr); + return; + } + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int chdata; + + GET_CHDATA_ANTIC_2 + WRITE_VIDEO_LONG((ULONG *) ptr, ANTIC_lookup_gtia11[chdata >> 4]); + WRITE_VIDEO_LONG((ULONG *) ptr + 1, ANTIC_lookup_gtia11[chdata & 0xf]); + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + ptr += 4; + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int k = 4; + UBYTE pm_reg; + do { + pm_reg = pm_lookup_ptr[*c_pm_scanline_ptr++]; + if (pm_reg) { + if (pm_reg == L_PF3) { + UBYTE tmp = k > 2 ? chdata & 0xf0 : chdata << 4; +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[tmp ? tmp | GTIA_COLPF3 : GTIA_COLPF3 & 0xf0]); +#else + WRITE_VIDEO(ptr, tmp ? tmp | ((UWORD)tmp << 8) | ANTIC_cl[C_PF3] : ANTIC_cl[C_PF3] & 0xf0f0); +#endif + } + else + { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + ptr++; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border_gtia11(); +} + +static void draw_antic_2_gtia_bug(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + prepare_an_antic_2(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia_bug(t_pm_scanline_ptr); + return; +} + +static void draw_antic_4(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_BACKGROUND_8 +#ifdef PAGED_MEM + UWORD t_chbase = ((anticmode == 4 ? dctr : dctr >> 1) ^ chbase_20) & 0xfc07; +#else + const UBYTE *chptr; + if (ANTIC_xe_ptr != NULL && chbase_20 < 0x8000 && chbase_20 >= 0x4000) + chptr = ANTIC_xe_ptr + (((anticmode == 4 ? dctr : dctr >> 1) ^ chbase_20) & 0x3c07); + else + chptr = MEMORY_mem + (((anticmode == 4 ? dctr : dctr >> 1) ^ chbase_20) & 0xfc07); +#endif + + ADD_FONT_CYCLES; + lookup2[0x0f] = lookup2[0x00] = ANTIC_cl[C_BAK]; + lookup2[0x4f] = lookup2[0x1f] = lookup2[0x13] = + lookup2[0x40] = lookup2[0x10] = lookup2[0x04] = lookup2[0x01] = ANTIC_cl[C_PF0]; + lookup2[0x8f] = lookup2[0x2f] = lookup2[0x17] = lookup2[0x11] = + lookup2[0x80] = lookup2[0x20] = lookup2[0x08] = lookup2[0x02] = ANTIC_cl[C_PF1]; + lookup2[0xc0] = lookup2[0x30] = lookup2[0x0c] = lookup2[0x03] = ANTIC_cl[C_PF2]; + lookup2[0xcf] = lookup2[0x3f] = lookup2[0x1b] = lookup2[0x12] = ANTIC_cl[C_PF3]; + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + const UWORD *lookup; + UBYTE chdata; + if (screendata & 0x80) + lookup = lookup2 + 0xf; + else + lookup = lookup2; +#ifdef PAGED_MEM + chdata = MEMORY_dGetByte(t_chbase + ((UWORD) (screendata & 0x7f) << 3)); +#else + chdata = chptr[(screendata & 0x7f) << 3]; +#endif + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + if (chdata) { + WRITE_VIDEO(ptr++, lookup[chdata & 0xc0]); + WRITE_VIDEO(ptr++, lookup[chdata & 0x30]); + WRITE_VIDEO(ptr++, lookup[chdata & 0x0c]); + WRITE_VIDEO(ptr++, lookup[chdata & 0x03]); + } + else + DRAW_BACKGROUND(C_BAK) + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + playfield_lookup[0xc0] = screendata & 0x80 ? L_PF3 : L_PF2; + do { + colreg = playfield_lookup[chdata & 0xc0]; + DO_PMG_LORES + chdata <<= 2; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + playfield_lookup[0xc0] = L_PF2; + do_border(); +} + +static void prepare_an_antic_4(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); +#ifdef PAGED_MEM + UWORD t_chbase = ((anticmode == 4 ? dctr : dctr >> 1) ^ chbase_20) & 0xfc07; +#else + const UBYTE *chptr; + if (ANTIC_xe_ptr != NULL && chbase_20 < 0x8000 && chbase_20 >= 0x4000) + chptr = ANTIC_xe_ptr + (((anticmode == 4 ? dctr : dctr >> 1) ^ chbase_20) & 0x3c07); + else + chptr = MEMORY_mem + (((anticmode == 4 ? dctr : dctr >> 1) ^ chbase_20) & 0xfc07); +#endif + + ADD_FONT_CYCLES; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + UBYTE an; + UBYTE chdata; +#ifdef PAGED_MEM + chdata = MEMORY_dGetByte(t_chbase + ((UWORD) (screendata & 0x7f) << 3)); +#else + chdata = chptr[(screendata & 0x7f) << 3]; +#endif + an = mode_e_an_lookup[chdata & 0xc0]; + *an_ptr++ = (an == 2 && screendata & 0x80) ? 3 : an; + an = mode_e_an_lookup[chdata & 0x30]; + *an_ptr++ = (an == 2 && screendata & 0x80) ? 3 : an; + an = mode_e_an_lookup[chdata & 0x0c]; + *an_ptr++ = (an == 2 && screendata & 0x80) ? 3 : an; + an = mode_e_an_lookup[chdata & 0x03]; + *an_ptr++ = (an == 2 && screendata & 0x80) ? 3 : an; + CHAR_LOOP_END +} + +DEFINE_DRAW_AN(4) + +static void draw_antic_6(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ +#ifdef PAGED_MEM + UWORD t_chbase = (anticmode == 6 ? dctr & 7 : dctr >> 1) ^ chbase_20; +#else + const UBYTE *chptr; + if (ANTIC_xe_ptr != NULL && chbase_20 < 0x8000 && chbase_20 >= 0x4000) + chptr = ANTIC_xe_ptr + (((anticmode == 6 ? dctr & 7 : dctr >> 1) ^ chbase_20) - 0x4000); + else + chptr = MEMORY_mem + ((anticmode == 6 ? dctr & 7 : dctr >> 1) ^ chbase_20); +#endif + + ADD_FONT_CYCLES; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + UBYTE chdata; + UWORD colour; + int kk = 2; + colour = COLOUR((playfield_lookup + 0x40)[screendata & 0xc0]); +#ifdef PAGED_MEM + chdata = MEMORY_dGetByte(t_chbase + ((UWORD) (screendata & 0x3f) << 3)); +#else + chdata = chptr[(screendata & 0x3f) << 3]; +#endif + do { + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + if (chdata & 0xf0) { + if (chdata & 0x80) { + WRITE_VIDEO(ptr++, colour); + } + else { + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + } + if (chdata & 0x40) { + WRITE_VIDEO(ptr++, colour); + } + else { + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + } + if (chdata & 0x20) { + WRITE_VIDEO(ptr++, colour); + } + else { + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + } + if (chdata & 0x10) { + WRITE_VIDEO(ptr++, colour); + } + else { + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + } + } + else { + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + WRITE_VIDEO(ptr++, ANTIC_cl[C_BAK]); + } + chdata <<= 4; + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + UBYTE setcol = (playfield_lookup + 0x40)[screendata & 0xc0]; + int colreg; + int k = 4; + do { + colreg = chdata & 0x80 ? setcol : L_BAK; + DO_PMG_LORES + chdata <<= 1; + } while (--k); + + } + t_pm_scanline_ptr++; + } while (--kk); + CHAR_LOOP_END + do_border(); +} + +static void prepare_an_antic_6(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); +#ifdef PAGED_MEM + UWORD t_chbase = (anticmode == 6 ? dctr & 7 : dctr >> 1) ^ chbase_20; +#else + const UBYTE *chptr; + if (ANTIC_xe_ptr != NULL && chbase_20 < 0x8000 && chbase_20 >= 0x4000) + chptr = ANTIC_xe_ptr + (((anticmode == 6 ? dctr & 7 : dctr >> 1) ^ chbase_20) - 0x4000); + else + chptr = MEMORY_mem + ((anticmode == 6 ? dctr & 7 : dctr >> 1) ^ chbase_20); +#endif + + ADD_FONT_CYCLES; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + UBYTE an = screendata >> 6; + UBYTE chdata; +#ifdef PAGED_MEM + chdata = MEMORY_dGetByte(t_chbase + ((UWORD) (screendata & 0x3f) << 3)); +#else + chdata = chptr[(screendata & 0x3f) << 3]; +#endif + *an_ptr++ = chdata & 0x80 ? an : 0; + *an_ptr++ = chdata & 0x40 ? an : 0; + *an_ptr++ = chdata & 0x20 ? an : 0; + *an_ptr++ = chdata & 0x10 ? an : 0; + *an_ptr++ = chdata & 0x08 ? an : 0; + *an_ptr++ = chdata & 0x04 ? an : 0; + *an_ptr++ = chdata & 0x02 ? an : 0; + *an_ptr++ = chdata & 0x01 ? an : 0; + CHAR_LOOP_END +} + +DEFINE_DRAW_AN(6) + +static void draw_antic_8(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + lookup2[0x00] = ANTIC_cl[C_BAK]; + lookup2[0x40] = ANTIC_cl[C_PF0]; + lookup2[0x80] = ANTIC_cl[C_PF1]; + lookup2[0xc0] = ANTIC_cl[C_PF2]; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int kk = 4; + do { + if ((const UBYTE *) t_pm_scanline_ptr >= GTIA_pm_scanline + 4 * (48 - RCHOP)) + break; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + UWORD data = lookup2[screendata & 0xc0]; + WRITE_VIDEO(ptr++, data); + WRITE_VIDEO(ptr++, data); + WRITE_VIDEO(ptr++, data); + WRITE_VIDEO(ptr++, data); + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg = playfield_lookup[screendata & 0xc0]; + int k = 4; + do { + DO_PMG_LORES + } while (--k); + } + screendata <<= 2; + t_pm_scanline_ptr++; + } while (--kk); + CHAR_LOOP_END + do_border(); +} + +static void prepare_an_antic_8(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int kk = 4; + do { + UBYTE data = mode_e_an_lookup[screendata & 0xc0]; + *an_ptr++ = data; + *an_ptr++ = data; + *an_ptr++ = data; + *an_ptr++ = data; + screendata <<= 2; + } while (--kk); + CHAR_LOOP_END +} + +DEFINE_DRAW_AN(8) + +static void draw_antic_9(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + lookup2[0x00] = ANTIC_cl[C_BAK]; + lookup2[0x80] = lookup2[0x40] = ANTIC_cl[C_PF0]; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int kk = 4; + do { + if ((const UBYTE *) t_pm_scanline_ptr >= GTIA_pm_scanline + 4 * (48 - RCHOP)) + break; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + WRITE_VIDEO(ptr++, lookup2[screendata & 0x80]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x80]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x40]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x40]); + screendata <<= 2; + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + do { + colreg = (screendata & 0x80) ? L_PF0 : L_BAK; + DO_PMG_LORES + if (k & 0x01) + screendata <<= 1; + } while (--k); + } + t_pm_scanline_ptr++; + } while (--kk); + CHAR_LOOP_END + do_border(); +} + +/* ANTIC modes 9, b and c use BAK and PF0 colours only so they're not visible in GTIA modes */ + +static void draw_antic_9_gtia9(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + draw_antic_0(); +} + +static void draw_antic_9_gtia10(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + draw_antic_0_gtia10(); +} + +static void draw_antic_9_gtia11(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + draw_antic_0_gtia11(); +} + +static void draw_antic_a(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + lookup2[0x00] = ANTIC_cl[C_BAK]; + lookup2[0x40] = lookup2[0x10] = ANTIC_cl[C_PF0]; + lookup2[0x80] = lookup2[0x20] = ANTIC_cl[C_PF1]; + lookup2[0xc0] = lookup2[0x30] = ANTIC_cl[C_PF2]; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int kk = 2; + do { + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + WRITE_VIDEO(ptr++, lookup2[screendata & 0xc0]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0xc0]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x30]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x30]); + screendata <<= 4; + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + do { + colreg = playfield_lookup[screendata & 0xc0]; + DO_PMG_LORES + if (k & 0x01) + screendata <<= 2; + } while (--k); + } + t_pm_scanline_ptr++; + } while (--kk); + CHAR_LOOP_END + do_border(); +} + +static void prepare_an_antic_a(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + UBYTE data = mode_e_an_lookup[screendata & 0xc0]; + *an_ptr++ = data; + *an_ptr++ = data; + data = mode_e_an_lookup[screendata & 0x30]; + *an_ptr++ = data; + *an_ptr++ = data; + data = mode_e_an_lookup[screendata & 0x0c]; + *an_ptr++ = data; + *an_ptr++ = data; + data = mode_e_an_lookup[screendata & 0x03]; + *an_ptr++ = data; + *an_ptr++ = data; + CHAR_LOOP_END +} + +DEFINE_DRAW_AN(a) + +static void draw_antic_c(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + lookup2[0x00] = ANTIC_cl[C_BAK]; + lookup2[0x80] = lookup2[0x40] = lookup2[0x20] = lookup2[0x10] = ANTIC_cl[C_PF0]; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + int kk = 2; + do { + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + WRITE_VIDEO(ptr++, lookup2[screendata & 0x80]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x40]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x20]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x10]); + screendata <<= 4; + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + do { + colreg = (screendata & 0x80) ? L_PF0 : L_BAK; + DO_PMG_LORES + screendata <<= 1; + } while (--k); + } + t_pm_scanline_ptr++; + } while (--kk); + CHAR_LOOP_END + do_border(); +} + +static void draw_antic_e(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_BACKGROUND_8 + lookup2[0x00] = ANTIC_cl[C_BAK]; + lookup2[0x40] = lookup2[0x10] = lookup2[0x04] = lookup2[0x01] = ANTIC_cl[C_PF0]; + lookup2[0x80] = lookup2[0x20] = lookup2[0x08] = lookup2[0x02] = ANTIC_cl[C_PF1]; + lookup2[0xc0] = lookup2[0x30] = lookup2[0x0c] = lookup2[0x03] = ANTIC_cl[C_PF2]; + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + if (screendata) { + WRITE_VIDEO(ptr++, lookup2[screendata & 0xc0]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x30]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x0c]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x03]); + } + else + DRAW_BACKGROUND(C_BAK) + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + do { + colreg = playfield_lookup[screendata & 0xc0]; + DO_PMG_LORES + screendata <<= 2; + } while (--k); + + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +static void prepare_an_antic_e(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + *an_ptr++ = mode_e_an_lookup[screendata & 0xc0]; + *an_ptr++ = mode_e_an_lookup[screendata & 0x30]; + *an_ptr++ = mode_e_an_lookup[screendata & 0x0c]; + *an_ptr++ = mode_e_an_lookup[screendata & 0x03]; + CHAR_LOOP_END +} + +static void draw_antic_e_gtia9(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + ULONG lookup[16]; + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_e(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia9(t_pm_scanline_ptr); + return; + } + lookup[0] = lookup[1] = lookup[4] = lookup[5] = ANTIC_lookup_gtia9[0]; + lookup[2] = lookup[6] = ANTIC_lookup_gtia9[1]; + lookup[3] = lookup[7] = ANTIC_lookup_gtia9[2]; + lookup[8] = lookup[9] = ANTIC_lookup_gtia9[4]; + lookup[10] = ANTIC_lookup_gtia9[5]; + lookup[11] = ANTIC_lookup_gtia9[6]; + lookup[12] = lookup[13] = ANTIC_lookup_gtia9[8]; + lookup[14] = ANTIC_lookup_gtia9[9]; + lookup[15] = ANTIC_lookup_gtia9[10]; + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + WRITE_VIDEO_LONG((ULONG *) ptr, lookup[screendata >> 4]); + WRITE_VIDEO_LONG((ULONG *) ptr + 1, lookup[screendata & 0xf]); + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + ptr += 4; + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int k = 4; + UBYTE pm_reg; + do { + pm_reg = pm_lookup_ptr[*c_pm_scanline_ptr++]; + if (pm_reg) { + if (pm_reg == L_PF3) { + UBYTE tmp = k > 2 ? screendata >> 4 : screendata & 0xf; +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[tmp | GTIA_COLPF3]); +#else + WRITE_VIDEO(ptr, tmp | ((UWORD)tmp << 8) | ANTIC_cl[C_PF3]); +#endif + } + else + { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + ptr++; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +static void draw_antic_e_gtia10 (int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + prepare_an_antic_e(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia10(t_pm_scanline_ptr); +} +static void draw_antic_e_gtia11 (int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + prepare_an_antic_e(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia11(t_pm_scanline_ptr); +} + +static void draw_antic_f(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + INIT_BACKGROUND_6 + INIT_HIRES + + CHAR_LOOP_BEGIN + int screendata = *antic_memptr++; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + if (screendata) { + WRITE_VIDEO(ptr++, hires_norm(screendata & 0xc0)); + WRITE_VIDEO(ptr++, hires_norm(screendata & 0x30)); + WRITE_VIDEO(ptr++, hires_norm(screendata & 0x0c)); + WRITE_VIDEO(ptr++, hires_norm((screendata & 0x03) << 2)); + } + else + DRAW_BACKGROUND(C_PF2) + } + else + DO_PMG_HIRES(screendata) + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +static void draw_antic_f_artif(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + ULONG screendata_tally = *antic_memptr++; + + setup_art_colours(); + CHAR_LOOP_BEGIN + int screendata = *antic_memptr++; + screendata_tally <<= 8; + screendata_tally |= screendata; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + DRAW_ARTIF + else { + screendata = antic_memptr[-2]; + DO_PMG_HIRES(screendata) + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +#ifndef USE_COLOUR_TRANSLATION_TABLE +static void draw_antic_f_artif_new(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + ULONG pmtally; + ULONG screendata_tally = *antic_memptr++; + INIT_ARTIF_NEW + + setup_art_colours(); + CHAR_LOOP_BEGIN + int screendata = *antic_memptr++; + screendata_tally <<= 8; + screendata_tally |= screendata; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + DRAW_ARTIF_NEW + else { + screendata = antic_memptr[-2]; + pmtally = ((screendata_tally & 0x03f000) << 6) | + ((screendata_tally & 0x00fc00) << 2) | + ((screendata_tally & 0x003f00) >> 2) | + ((screendata_tally & 0x000fc0) >> 6); + DO_PMG_HIRES_NEW(screendata,pmtally) + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} +#endif + +static void prepare_an_antic_f(int nchars, const UBYTE *antic_memptr, const ULONG *t_pm_scanline_ptr) +{ + UBYTE *an_ptr = (UBYTE *) t_pm_scanline_ptr + (an_scanline - GTIA_pm_scanline); + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + *an_ptr++ = screendata >> 6; + *an_ptr++ = (screendata >> 4) & 3; + *an_ptr++ = (screendata >> 2) & 3; + *an_ptr++ = screendata & 3; + CHAR_LOOP_END +} + +static void draw_antic_f_gtia9(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_f(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia9(t_pm_scanline_ptr); + return; + } + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + WRITE_VIDEO_LONG((ULONG *) ptr, ANTIC_lookup_gtia9[screendata >> 4]); + WRITE_VIDEO_LONG((ULONG *) ptr + 1, ANTIC_lookup_gtia9[screendata & 0xf]); + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + ptr += 4; + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int k = 4; + UBYTE pm_reg; + do { + pm_reg = pm_lookup_ptr[*c_pm_scanline_ptr++]; + if (pm_reg) { + if (pm_reg == L_PF3) { + UBYTE tmp = k > 2 ? screendata >> 4 : screendata & 0xf; +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[tmp | GTIA_COLPF3]); +#else + WRITE_VIDEO(ptr, tmp | ((UWORD)tmp << 8) | ANTIC_cl[C_PF3]); +#endif + } + else { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + ptr++; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +static void draw_antic_f_gtia10(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ +#ifdef WORDS_UNALIGNED_OK + ULONG lookup_gtia10[16]; +#else + UWORD lookup_gtia10[16]; +#endif + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_f(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia10(t_pm_scanline_ptr); + return; + } +#ifdef WORDS_UNALIGNED_OK + lookup_gtia10[0] = ANTIC_cl[C_PM0] | (ANTIC_cl[C_PM0] << 16); + lookup_gtia10[1] = ANTIC_cl[C_PM1] | (ANTIC_cl[C_PM1] << 16); + lookup_gtia10[2] = ANTIC_cl[C_PM2] | (ANTIC_cl[C_PM2] << 16); + lookup_gtia10[3] = ANTIC_cl[C_PM3] | (ANTIC_cl[C_PM3] << 16); + lookup_gtia10[12] = lookup_gtia10[4] = ANTIC_cl[C_PF0] | (ANTIC_cl[C_PF0] << 16); + lookup_gtia10[13] = lookup_gtia10[5] = ANTIC_cl[C_PF1] | (ANTIC_cl[C_PF1] << 16); + lookup_gtia10[14] = lookup_gtia10[6] = ANTIC_cl[C_PF2] | (ANTIC_cl[C_PF2] << 16); + lookup_gtia10[15] = lookup_gtia10[7] = ANTIC_cl[C_PF3] | (ANTIC_cl[C_PF3] << 16); + lookup_gtia10[8] = lookup_gtia10[9] = lookup_gtia10[10] = lookup_gtia10[11] = ANTIC_lookup_gtia9[0]; +#else + lookup_gtia10[0] = ANTIC_cl[C_PM0]; + lookup_gtia10[1] = ANTIC_cl[C_PM1]; + lookup_gtia10[2] = ANTIC_cl[C_PM2]; + lookup_gtia10[3] = ANTIC_cl[C_PM3]; + lookup_gtia10[12] = lookup_gtia10[4] = ANTIC_cl[C_PF0]; + lookup_gtia10[13] = lookup_gtia10[5] = ANTIC_cl[C_PF1]; + lookup_gtia10[14] = lookup_gtia10[6] = ANTIC_cl[C_PF2]; + lookup_gtia10[15] = lookup_gtia10[7] = ANTIC_cl[C_PF3]; + lookup_gtia10[8] = lookup_gtia10[9] = lookup_gtia10[10] = lookup_gtia10[11] = ANTIC_cl[C_BAK]; +#endif + ptr++; + t_pm_scanline_ptr = (const ULONG *) (((const UBYTE *) t_pm_scanline_ptr) + 1); + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + DO_GTIA_BYTE(ptr, lookup_gtia10, screendata) + ptr += 4; + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + UBYTE t_screendata = screendata >> 4; + do { + colreg = gtia_10_lookup[t_screendata]; + PF_COLLS(colreg) |= pm_pixel = *c_pm_scanline_ptr++; /*playfield colours can generate collisions*/ + pm_pixel |= gtia_10_pm[t_screendata]; /*but player colours don't*/ + WRITE_VIDEO(ptr++, COLOUR(pm_lookup_ptr[pm_pixel] | colreg)); /*although they mix with the real players*/ + if (k == 3) + t_screendata = screendata & 0x0f; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border_gtia10(); +} + +static void draw_antic_f_gtia11(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + if ((unsigned long) ptr & 2) { /* HSCROL & 1 */ + prepare_an_antic_f(nchars, antic_memptr, t_pm_scanline_ptr); + draw_an_gtia11(t_pm_scanline_ptr); + return; + } + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + WRITE_VIDEO_LONG((ULONG *) ptr, ANTIC_lookup_gtia11[screendata >> 4]); + WRITE_VIDEO_LONG((ULONG *) ptr + 1, ANTIC_lookup_gtia11[screendata & 0xf]); + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) + ptr += 4; + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int k = 4; + UBYTE pm_reg; + do { + pm_reg = pm_lookup_ptr[*c_pm_scanline_ptr++]; + if (pm_reg) { + if (pm_reg == L_PF3) { + UBYTE tmp = k > 2 ? screendata & 0xf0 : screendata << 4; +#ifdef USE_COLOUR_TRANSLATION_TABLE + WRITE_VIDEO(ptr, colour_translation_table[tmp ? tmp | GTIA_COLPF3 : GTIA_COLPF3 & 0xf0]); +#else + WRITE_VIDEO(ptr, tmp ? tmp | ((UWORD)tmp << 8) | ANTIC_cl[C_PF3] : ANTIC_cl[C_PF3] & 0xf0f0); +#endif + } + else + { + WRITE_VIDEO(ptr, COLOUR(pm_reg)); + } + } + ptr++; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border_gtia11(); +} + +/* GTIA-switch-to-mode-00 bug +If while drawing line in hi-res mode PRIOR is changed from 0x40..0xff to +0x00..0x3f, GTIA doesn't back to hi-res, but starts generating mode similar +to ANTIC's 0xe, but with colours PF0, PF1, PF2, PF3. */ + +/* Technical explaination by perrym: + * in gtia.pdf there is a flip-flop at page 40, drawing location C3 with + * what looks like W and A on the gates + * This is set by AN2=0 AN1=1 AN0=1 durning HBLANK + * The middle input to the lower NOR gate is the inverted signal !NRM(?) + * (NRM means NORMAL?) which arrives from the top left of the page. + * This signal is defined on page 38, positions C2/B2 + * where there is a NOR gate pointing downwards with 00 written to the + * right of its output. + * !NRM is the condition that PRIOR is not set to b7=0,b6=0. + * When PRIOR is not set to NRM, the flip-flip is always reset, + * which seems necessary for the proper operation of the GTIA modes. + * If PRIOR is reset to NRM then the flip-flop remains reset, and + * since ANTIC data in hi-res modes is sent as PF0-PF3, this data is used + * by GTIA directly.*/ + +static void draw_antic_f_gtia_bug(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + lookup2[0x00] = ANTIC_cl[C_PF0]; + lookup2[0x40] = lookup2[0x10] = lookup2[0x04] = lookup2[0x01] = ANTIC_cl[C_PF1]; + lookup2[0x80] = lookup2[0x20] = lookup2[0x08] = lookup2[0x02] = ANTIC_cl[C_PF2]; + lookup2[0xc0] = lookup2[0x30] = lookup2[0x0c] = lookup2[0x03] = ANTIC_cl[C_PF3]; + + CHAR_LOOP_BEGIN + UBYTE screendata = *antic_memptr++; + if (IS_ZERO_ULONG(t_pm_scanline_ptr)) { + WRITE_VIDEO(ptr++, lookup2[screendata & 0xc0]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x30]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x0c]); + WRITE_VIDEO(ptr++, lookup2[screendata & 0x03]); + } + else { + const UBYTE *c_pm_scanline_ptr = (const UBYTE *) t_pm_scanline_ptr; + int pm_pixel; + int colreg; + int k = 4; + do { + colreg = (playfield_lookup + 0x40)[screendata & 0xc0]; + DO_PMG_LORES + screendata <<= 2; + } while (--k); + } + t_pm_scanline_ptr++; + CHAR_LOOP_END + do_border(); +} + +/* pointer to a function that draws a single line of graphics */ +typedef void (*draw_antic_function)(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr); + +/* tables for all GTIA and ANTIC modes */ +static draw_antic_function draw_antic_table[4][16] = { +/* normal */ + { NULL, NULL, draw_antic_2, draw_antic_2, + draw_antic_4, draw_antic_4, draw_antic_6, draw_antic_6, + draw_antic_8, draw_antic_9, draw_antic_a, draw_antic_c, + draw_antic_c, draw_antic_e, draw_antic_e, draw_antic_f}, +/* GTIA 9 */ + { NULL, NULL, draw_antic_2_gtia9, draw_antic_2_gtia9, + draw_antic_4_gtia9, draw_antic_4_gtia9, draw_antic_6_gtia9, draw_antic_6_gtia9, + draw_antic_8_gtia9, draw_antic_9_gtia9, draw_antic_a_gtia9, draw_antic_9_gtia9, + draw_antic_9_gtia9, draw_antic_e_gtia9, draw_antic_e_gtia9, draw_antic_f_gtia9}, +/* GTIA 10 */ + { NULL, NULL, draw_antic_2_gtia10, draw_antic_2_gtia10, + draw_antic_4_gtia10, draw_antic_4_gtia10, draw_antic_6_gtia10, draw_antic_6_gtia10, + draw_antic_8_gtia10, draw_antic_9_gtia10, draw_antic_a_gtia10, draw_antic_9_gtia10, + draw_antic_9_gtia10, draw_antic_e_gtia10, draw_antic_e_gtia10, draw_antic_f_gtia10}, +/* GTIA 11 */ + { NULL, NULL, draw_antic_2_gtia11, draw_antic_2_gtia11, + draw_antic_4_gtia11, draw_antic_4_gtia11, draw_antic_6_gtia11, draw_antic_6_gtia11, + draw_antic_8_gtia11, draw_antic_9_gtia11, draw_antic_a_gtia11, draw_antic_9_gtia11, + draw_antic_9_gtia11, draw_antic_e_gtia11, draw_antic_e_gtia11, draw_antic_f_gtia11}}; + +/* pointer to current GTIA/ANTIC mode routine */ +static draw_antic_function draw_antic_ptr = draw_antic_8; +#ifdef NEW_CYCLE_EXACT +static draw_antic_function saved_draw_antic_ptr; +#endif +/* pointer to current GTIA mode blank drawing routine */ +static void (*draw_antic_0_ptr)(void) = draw_antic_0; + +#ifdef NEW_CYCLE_EXACT +/* wrapper for antic_0, for dmactl bugs */ +static void draw_antic_0_dmactl_bug(int nchars, const UBYTE *antic_memptr, UWORD *ptr, const ULONG *t_pm_scanline_ptr) +{ + draw_antic_0_ptr(); +} +#endif + +/* Artifacting ------------------------------------------------------------ */ + +void ANTIC_UpdateArtifacting(void) +{ +#define ART_BROWN 0 +#define ART_BLUE 1 +#define ART_DARK_BROWN 2 +#define ART_DARK_BLUE 3 +#define ART_BRIGHT_BROWN 4 +#define ART_BRIGHT_BLUE 5 +#define ART_RED 6 +#define ART_GREEN 7 + static const UBYTE art_colour_table[4][8] = { + { 0x88, 0x14, 0x88, 0x14, 0x8f, 0x1f, 0xbb, 0x5f }, /* brownblue */ + { 0x14, 0x88, 0x14, 0x88, 0x1f, 0x8f, 0x5f, 0xbb }, /* bluebrown */ + { 0xd6, 0x46, 0xd6, 0x46, 0xdf, 0x4a, 0x4f, 0xac }, /* redgreen */ + { 0x46, 0xd6, 0x46, 0xd6, 0x4a, 0xdf, 0xac, 0x4f } /* greenred */ + }; + + int i; + int j; + int c; + const UBYTE *art_colours; + UBYTE q; + UBYTE art_white; + + if (ANTIC_artif_mode == 0) { + draw_antic_table[0][2] = draw_antic_table[0][3] = draw_antic_2; + draw_antic_table[0][0xf] = draw_antic_f; + return; + } + +#ifndef USE_COLOUR_TRANSLATION_TABLE + if (ANTIC_artif_new) { + static UWORD new_art_colour_table[4][2] = { + {0x4040, 0x8080}, + {0x8080, 0x4040}, + {0x8080, 0xd0d0}, + {0xd0d0, 0x8080} + }; + draw_antic_table[0][2] = draw_antic_table[0][3] = draw_antic_2_artif_new; + draw_antic_table[0][0xf] = draw_antic_f_artif_new; + art_colour1_new = new_art_colour_table[ANTIC_artif_mode - 1][0]; + art_colour2_new = new_art_colour_table[ANTIC_artif_mode - 1][1]; + } + else +#endif + { + draw_antic_table[0][2] = draw_antic_table[0][3] = draw_antic_2_artif; + draw_antic_table[0][0xf] = draw_antic_f_artif; + } + + art_colours = (ANTIC_artif_mode <= 4 ? art_colour_table[ANTIC_artif_mode - 1] : art_colour_table[2]); + + art_reverse_colpf1_save = art_normal_colpf1_save = ANTIC_cl[C_PF1] & 0x0f0f; + art_reverse_colpf2_save = art_normal_colpf2_save = ANTIC_cl[C_PF2]; + art_white = (ANTIC_cl[C_PF2] & 0xf0) | (ANTIC_cl[C_PF1] & 0x0f); + + for (i = 0; i <= 255; i++) { + art_bkmask_normal[i] = 0; + art_lummask_normal[i] = 0; + art_bkmask_reverse[255 - i] = 0; + art_lummask_reverse[255 - i] = 0; + + for (j = 0; j <= 3; j++) { + q = i << j; + if (!(q & 0x20)) { + if ((q & 0xf8) == 0x50) + c = ART_BLUE; /* 01010 */ + else if ((q & 0xf8) == 0xD8) + c = ART_DARK_BLUE; /* 11011 */ + else { /* xx0xx */ + ((UBYTE *) art_lookup_normal)[(i << 2) + j] = GTIA_COLPF2; + ((UBYTE *) art_lookup_reverse)[((255 - i) << 2) + j] = art_white; + ((UBYTE *) art_bkmask_normal)[(i << 2) + j] = 0xff; + ((UBYTE *) art_lummask_reverse)[((255 - i) << 2) + j] = 0x0f; + ((UBYTE *) art_bkmask_reverse)[((255 - i) << 2) + j] = 0xf0; + continue; + } + } + else if (q & 0x40) { + if (q & 0x10) + goto colpf1_pixel; /* x111x */ + else if (q & 0x80) { + if (q & 0x08) + c = ART_BRIGHT_BROWN; /* 11101 */ + else + goto colpf1_pixel; /* 11100 */ + } + else + c = ART_GREEN; /* 0110x */ + } + else if (q & 0x10) { + if (q & 0x08) { + if (q & 0x80) + c = ART_BRIGHT_BROWN; /* 00111 */ + else + goto colpf1_pixel; /* 10111 */ + } + else + c = ART_RED; /* x0110 */ + } + else + c = ART_BROWN; /* x010x */ + + ((UBYTE *) art_lookup_reverse)[((255 - i) << 2) + j] = + ((UBYTE *) art_lookup_normal)[(i << 2) + j] = art_colours[(j & 1) ^ c]; + continue; + + colpf1_pixel: + ((UBYTE *) art_lookup_normal)[(i << 2) + j] = art_white; + ((UBYTE *) art_lookup_reverse)[((255 - i) << 2) + j] = GTIA_COLPF2; + ((UBYTE *) art_bkmask_reverse)[((255 - i) << 2) + j] = 0xff; + ((UBYTE *) art_lummask_normal)[(i << 2) + j] = 0x0f; + ((UBYTE *) art_bkmask_normal)[(i << 2) + j] = 0xf0; + } + } +} + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + +/* Display List ------------------------------------------------------------ */ + +UBYTE ANTIC_GetDLByte(UWORD *paddr) +{ + int addr = *paddr; + UBYTE result; + if (ANTIC_xe_ptr != NULL && addr < 0x8000 && addr >= 0x4000) + result = ANTIC_xe_ptr[addr - 0x4000]; + else + result = MEMORY_GetByte((UWORD) addr); + addr++; + if ((addr & 0x3FF) == 0) + addr -= 0x400; + *paddr = (UWORD) addr; + return result; +} + +UWORD ANTIC_GetDLWord(UWORD *paddr) +{ + UBYTE lsb = ANTIC_GetDLByte(paddr); +#if !defined(BASIC) && !defined(CURSES_BASIC) + if (ANTIC_player_flickering && ((GTIA_VDELAY & 0x80) == 0 || ANTIC_ypos & 1)) + GTIA_GRAFP3 = lsb; +#endif + return (ANTIC_GetDLByte(paddr) << 8) + lsb; +} + +#if !defined(BASIC) && !defined(CURSES_BASIC) + +/* Real ANTIC doesn't fetch beginning bytes in HSC + nor screen+47 in wide playfield. This function does. */ +static void antic_load(void) +{ +#ifdef PAGED_MEM + UBYTE *antic_memptr = antic_memory + ANTIC_margin; + UWORD new_screenaddr = screenaddr + chars_read[md]; + if ((screenaddr ^ new_screenaddr) & 0xf000) { + do + *antic_memptr++ = MEMORY_dGetByte(screenaddr++); + while (screenaddr & 0xfff); + screenaddr -= 0x1000; + new_screenaddr -= 0x1000; + } + while (screenaddr < new_screenaddr) + *antic_memptr++ = MEMORY_dGetByte(screenaddr++); +#else + UWORD new_screenaddr = screenaddr + chars_read[md]; + if ((screenaddr ^ new_screenaddr) & 0xf000) { + int bytes = (-screenaddr) & 0xfff; + if (ANTIC_xe_ptr != NULL && screenaddr < 0x8000 && screenaddr >= 0x4000) { + memcpy(antic_memory + ANTIC_margin, ANTIC_xe_ptr + (screenaddr - 0x4000), bytes); + if (new_screenaddr & 0xfff) + memcpy(antic_memory + ANTIC_margin + bytes, ANTIC_xe_ptr + (screenaddr + bytes - 0x5000), new_screenaddr & 0xfff); + } + else if ((screenaddr & 0xf000) == 0xd000) { + MEMORY_CopyFromMem(screenaddr, antic_memory + ANTIC_margin, bytes); + if (new_screenaddr & 0xfff) + MEMORY_CopyFromMem((UWORD) (screenaddr + bytes - 0x1000), antic_memory + ANTIC_margin + bytes, new_screenaddr & 0xfff); + } + else { + MEMORY_dCopyFromMem(screenaddr, antic_memory + ANTIC_margin, bytes); + if (new_screenaddr & 0xfff) + MEMORY_dCopyFromMem(screenaddr + bytes - 0x1000, antic_memory + ANTIC_margin + bytes, new_screenaddr & 0xfff); + } + screenaddr = new_screenaddr - 0x1000; + } + else { + if (ANTIC_xe_ptr != NULL && screenaddr < 0x8000 && screenaddr >= 0x4000) + memcpy(antic_memory + ANTIC_margin, ANTIC_xe_ptr + (screenaddr - 0x4000), chars_read[md]); + else if ((screenaddr & 0xf000) == 0xd000) + MEMORY_CopyFromMem(screenaddr, antic_memory + ANTIC_margin, chars_read[md]); + else + MEMORY_dCopyFromMem(screenaddr, antic_memory + ANTIC_margin, chars_read[md]); + screenaddr = new_screenaddr; + } +#endif +} + +#ifdef NEW_CYCLE_EXACT +int ANTIC_cur_screen_pos = ANTIC_NOT_DRAWING; +#endif + +#ifdef USE_CURSES +static int scanlines_to_curses_display = 0; +#endif + +/* This function emulates one frame drawing screen at Screen_atari */ +void ANTIC_Frame(int draw_display) +{ + static const UBYTE mode_type[32] = { + NORMAL0, NORMAL0, NORMAL0, NORMAL0, NORMAL0, NORMAL0, NORMAL1, NORMAL1, + NORMAL2, NORMAL2, NORMAL1, NORMAL1, NORMAL1, NORMAL0, NORMAL0, NORMAL0, + SCROLL0, SCROLL0, SCROLL0, SCROLL0, SCROLL0, SCROLL0, SCROLL1, SCROLL1, + SCROLL2, SCROLL2, SCROLL1, SCROLL1, SCROLL1, SCROLL0, SCROLL0, SCROLL0 + }; + static const UBYTE normal_lastline[16] = + { 0, 0, 7, 9, 7, 15, 7, 15, 7, 3, 3, 1, 0, 1, 0, 0 }; + UBYTE vscrol_flag = FALSE; + UBYTE no_jvb = TRUE; +#ifndef NEW_CYCLE_EXACT + UBYTE need_load; +#endif + +#ifdef NEW_CYCLE_EXACT + int cpu2antic_index; +#endif /* NEW_CYCLE_EXACT */ + + ANTIC_ypos = 0; + do { + POKEY_Scanline(); /* check and generate IRQ */ + OVERSCREEN_LINE; + } while (ANTIC_ypos < 8); + + scrn_ptr = (UWORD *) Screen_atari; +#ifdef NEW_CYCLE_EXACT + ANTIC_cur_screen_pos = ANTIC_NOT_DRAWING; +#endif + need_dl = TRUE; + do { +#ifdef SKIP + if ((INPUT_mouse_mode == INPUT_MOUSE_PEN || INPUT_mouse_mode == INPUT_MOUSE_GUN) && (ANTIC_ypos >> 1 == ANTIC_PENV_input)) { + PENH = ANTIC_PENH_input; + PENV = ANTIC_PENV_input; + if (GTIA_GRACTL & 4) + GTIA_TRIG_latch[INPUT_mouse_port] = 0; + } +#endif + POKEY_Scanline(); /* check and generate IRQ */ + pmg_dma(); + +#ifdef USE_CURSES + if (--scanlines_to_curses_display == 0) + curses_display_line(anticmode, antic_memory + ANTIC_margin); +#endif + + need_load = FALSE; + if (need_dl) { + if (ANTIC_DMACTL & 0x20) { + IR = ANTIC_GetDLByte(&ANTIC_dlist); + anticmode = IR & 0xf; + ANTIC_xpos++; + /* PMG flickering :-) */ + if (ANTIC_missile_flickering) + GTIA_GRAFM = ANTIC_ypos & 1 ? IR : ((GTIA_GRAFM ^ IR) & hold_missiles_tab[GTIA_VDELAY & 0xf]) ^ IR; + if (ANTIC_player_flickering) + { + UBYTE hold = ANTIC_ypos & 1 ? 0 : GTIA_VDELAY; + if ((hold & 0x10) == 0) + GTIA_GRAFP0 = MEMORY_dGetByte((UWORD) (CPU_regPC - ANTIC_xpos + 8)); + if ((hold & 0x20) == 0) + GTIA_GRAFP1 = MEMORY_dGetByte((UWORD) (CPU_regPC - ANTIC_xpos + 9)); + if ((hold & 0x40) == 0) + GTIA_GRAFP2 = MEMORY_dGetByte((UWORD) (CPU_regPC - ANTIC_xpos + 10)); + if ((hold & 0x80) == 0) + GTIA_GRAFP3 = MEMORY_dGetByte((UWORD) (CPU_regPC - ANTIC_xpos + 11)); + } + } + else + IR &= 0x7f; /* repeat last instruction, but don't generate DLI */ + + dctr = 0; + need_dl = FALSE; + vscrol_off = FALSE; + + switch (anticmode) { + case 0x00: + lastline = (IR >> 4) & 7; + if (vscrol_flag) { + lastline = ANTIC_VSCROL; + vscrol_flag = FALSE; + vscrol_off = TRUE; + } + break; + case 0x01: + lastline = 0; + if (IR & 0x40 && ANTIC_DMACTL & 0x20) { + ANTIC_dlist = ANTIC_GetDLWord(&ANTIC_dlist); + ANTIC_xpos += 2; + no_jvb = FALSE; + } + else + if (vscrol_flag) { + lastline = ANTIC_VSCROL; + vscrol_flag = FALSE; + vscrol_off = TRUE; + } + break; + default: + lastline = normal_lastline[anticmode]; + if (IR & 0x20) { + if (!vscrol_flag) { + CPU_GO(VSCON_C); + dctr = ANTIC_VSCROL; + vscrol_flag = TRUE; + } + } + else if (vscrol_flag) { + lastline = ANTIC_VSCROL; + vscrol_flag = FALSE; + vscrol_off = TRUE; + } + if (IR & 0x40 && ANTIC_DMACTL & 0x20) { + screenaddr = ANTIC_GetDLWord(&ANTIC_dlist); + ANTIC_xpos += 2; + } + md = mode_type[IR & 0x1f]; + need_load = TRUE; + draw_antic_ptr = draw_antic_table[GTIA_PRIOR >> 6][anticmode]; + break; + } + } +#ifdef NEW_CYCLE_EXACT + cpu2antic_index = 0; + if (anticmode < 2 || (ANTIC_DMACTL & 3) == 0 || + (anticmode >= 8 && !need_load)) { + cpu2antic_index = 0; + } + else { +/* TODO: use a cleaner lookup table here */ + if (!(IR & 0x10) && ((ANTIC_DMACTL & 3) == 1)) + cpu2antic_index = 1; + else if ((!(IR &0x10) && ((ANTIC_DMACTL & 3) == 2)) || + ((IR & 0x10) && ((ANTIC_DMACTL & 3) == 1))) { + cpu2antic_index = 2; + } + else + cpu2antic_index = 10; + if (IR & 0x10) { + cpu2antic_index += (ANTIC_HSCROL >> 1); + } + if (anticmode >=2 && anticmode <=7 && !need_load) + cpu2antic_index += 17; + if (anticmode ==6 || anticmode ==7) + cpu2antic_index += 17 * 2; + else if (anticmode==8 || anticmode == 9) + cpu2antic_index += 17 * 6; + else if (anticmode >=0xa && anticmode <=0xc) + cpu2antic_index += 17 * 5; + else if (anticmode >=0x0d) + cpu2antic_index += 17 * 4; + } + ANTIC_cpu2antic_ptr = &CYCLE_MAP_cpu2antic[CYCLE_MAP_SIZE * cpu2antic_index]; + ANTIC_antic2cpu_ptr = &CYCLE_MAP_antic2cpu[CYCLE_MAP_SIZE * cpu2antic_index]; +#endif /* NEW_CYCLE_EXACT */ + + if ((IR & 0x4f) == 1 && (ANTIC_DMACTL & 0x20)) { + ANTIC_dlist = ANTIC_GetDLWord(&ANTIC_dlist); + ANTIC_xpos += 2; + } + +#ifdef NEW_CYCLE_EXACT + /* begin drawing here */ + if (draw_display) { + ANTIC_cur_screen_pos = LBORDER_START; + ANTIC_xpos = ANTIC_antic2cpu_ptr[ANTIC_xpos]; /* convert antic to cpu(need for WSYNC) */ + if (dctr == lastline) { + if (no_jvb) + need_dl = TRUE; + if (IR & 0x80) { + CPU_GO(ANTIC_antic2cpu_ptr[ANTIC_NMIST_C]); + ANTIC_NMIST = 0x9f; + if (ANTIC_NMIEN & 0x80) { + CPU_GO(ANTIC_antic2cpu_ptr[ANTIC_NMI_C]); + CPU_NMI(); + } + } + } + } + else /* force this to be within an else if NEW_CYCLE_EXACT */ +#endif /* NEW_CYCLE_EXACT */ + if (dctr == lastline) { + if (no_jvb) + need_dl = TRUE; + if (IR & 0x80) { + CPU_GO(ANTIC_NMIST_C); + ANTIC_NMIST = 0x9f; + if (ANTIC_NMIEN & 0x80) { + CPU_GO(ANTIC_NMI_C); + CPU_NMI(); + } + } + } + if (!draw_display) { + ANTIC_xpos += ANTIC_DMAR; + if (anticmode < 2 || (ANTIC_DMACTL & 3) == 0) { + GOEOL; + if (no_jvb) { + dctr++; + dctr &= 0xf; + } + continue; + } + if (need_load) { + ANTIC_xpos += load_cycles[md]; + if (anticmode <= 5) /* extra cycles in font modes */ + ANTIC_xpos += before_cycles[md] - extra_cycles[md]; + } + if (anticmode < 8) + ANTIC_xpos += font_cycles[md]; + GOEOL; + dctr++; + dctr &= 0xf; + continue; + } +#ifndef NO_YPOS_BREAK_FLICKER +#define YPOS_BREAK_FLICKER do{if (ANTIC_ypos == ANTIC_break_ypos - 1000) {\ + static int toggle;\ + if (toggle == 1) {\ + FILL_VIDEO(scrn_ptr + LBORDER_START, 0x0f0f, (RBORDER_END - LBORDER_START) * 2);\ + }\ + toggle = !toggle;\ + }}while(0) +#else +#define YPOS_BREAK_FLICKER do{}while(0) +#endif /* NO_YPOS_BREAK_FLICKER */ + +#ifdef NEW_CYCLE_EXACT + GTIA_NewPmScanline(); + if (anticmode < 2 || (ANTIC_DMACTL & 3) == 0) { + GOEOL_CYCLE_EXACT; + draw_partial_scanline(ANTIC_cur_screen_pos, RBORDER_END); + UPDATE_DMACTL; + UPDATE_GTIA_BUG; + ANTIC_cur_screen_pos = ANTIC_NOT_DRAWING; + YPOS_BREAK_FLICKER; + scrn_ptr += Screen_WIDTH / 2; + if (no_jvb) { + dctr++; + dctr &= 0xf; + } + continue; + } + + GOEOL_CYCLE_EXACT; + draw_partial_scanline(ANTIC_cur_screen_pos, RBORDER_END); + UPDATE_DMACTL; + UPDATE_GTIA_BUG; + ANTIC_cur_screen_pos = ANTIC_NOT_DRAWING; + +#else /* NEW_CYCLE_EXACT not defined */ + if (need_load && anticmode <= 5 && ANTIC_DMACTL & 3) + ANTIC_xpos += before_cycles[md]; + + CPU_GO(SCR_C); + GTIA_NewPmScanline(); + + ANTIC_xpos += ANTIC_DMAR; + + if (anticmode < 2 || (ANTIC_DMACTL & 3) == 0) { + draw_antic_0_ptr(); + GOEOL; + YPOS_BREAK_FLICKER; + scrn_ptr += scrn_line; + if (no_jvb) { + dctr++; + dctr &= 0xf; + } + continue; + } + + if (need_load) { + antic_load(); +#ifdef USE_CURSES + /* Normally, we would call curses_display_line here, + and not use scanlines_to_curses_display at all. + That would however cause incorrect color of the "MEMORY" + menu item in Self Test - it isn't set properly + in the first scanline. We therefore postpone + curses_display_line call to the next scanline. */ + scanlines_to_curses_display = 1; +#endif + ANTIC_xpos += load_cycles[md]; + if (anticmode <= 5) /* extra cycles in font modes */ + ANTIC_xpos -= extra_cycles[md]; + } + + draw_antic_ptr(chars_displayed[md], + antic_memory + ANTIC_margin + ch_offset[md], + scrn_ptr + x_min[md], + (ULONG *) >IA_pm_scanline[x_min[md]]); + + GOEOL; +#endif /* NEW_CYCLE_EXACT */ + YPOS_BREAK_FLICKER; + scrn_ptr += scrn_line; + dctr++; + dctr &= 0xf; + } while (ANTIC_ypos < (ATARI_HEIGHT + 8)); + + emu_DrawVsync(); + +#ifndef NO_SIMPLE_PAL_BLENDING + /* Simple PAL blending, using only the base 256 color palette. */ + if (ANTIC_pal_blending) + { + int ypos = ANTIC_ypos - 1; + /* Start at the last screen line (248). */ + ULONG *ptr = (ULONG *) (scrn_ptr - 4 * RCHOP); + do { + int k = 2 * (48 - LCHOP - RCHOP); + do { + /* For each grayscale pixel (colors $00..$0f) blend it with + chrominance of a pixel from the previous line. */ + ULONG pix = READ_VIDEO_LONG(--ptr); + ULONG mask = 0xf0f0f0f0; + /* Take advantage of the fact that chrominance can change only + every two pixels. This way we may test only two pixels in a + quadruplet instead of four. */ + if (pix & 0x0000f0f0) + /* Two LSBs are non-grayscale */ + mask &= 0xf0f00000; + if (pix & 0xf0f00000) + /* Two MSBs are non-grayscale */ + mask &= 0x0000f0f0; + + WRITE_VIDEO_LONG(ptr, (READ_VIDEO_LONG(ptr - ATARI_WIDTH / 4) & mask) | pix); + } while (--k); + ptr -= 2 * (LCHOP + RCHOP); /* Move one line up */ + } while (--ypos > 8); /* Stop after line 9 */ + + } +#endif /* NO_SIMPLE_PAL_BLENDING */ + +/* TODO: cycle-exact overscreen lines */ + POKEY_Scanline(); /* check and generate IRQ */ + CPU_GO(ANTIC_NMIST_C); + ANTIC_NMIST = 0x5f; /* Set VBLANK */ + if (ANTIC_NMIEN & 0x40) { + CPU_GO(ANTIC_NMI_C); + CPU_NMI(); + } + ANTIC_xpos += ANTIC_DMAR; + GOEOL; + + do { + POKEY_Scanline(); /* check and generate IRQ */ + OVERSCREEN_LINE; + } while (ANTIC_ypos < max_ypos); + ANTIC_ypos = 0; /* just for monitor.c */ +} + +#ifdef NEW_CYCLE_EXACT + +/* update the scanline from the last changed position to the current +position, when a change was made to a display register during drawing */ +void ANTIC_UpdateScanline(void) +{ + int actual_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; + int oldpos = ANTIC_cur_screen_pos; + ANTIC_cur_screen_pos = actual_xpos * 2 - 37; + draw_partial_scanline(oldpos, ANTIC_cur_screen_pos); +} + +/* prior needs a different adjustment and could generate small glitches +between mode changes */ +/* TODO: support glitches between mode changes (tiny areas that are neither +the new mode nor the old mode, which occur between mode changes */ +void ANTIC_UpdateScanlinePrior(UBYTE byte) +{ + int actual_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; + int prior_mode_adj = 2; + int oldpos = ANTIC_cur_screen_pos; + ANTIC_cur_screen_pos = actual_xpos * 2 - 37 + prior_mode_adj; + draw_partial_scanline(oldpos, ANTIC_cur_screen_pos); +} + +/* chbase needs a different adjustment */ +void update_scanline_chbase(void) +{ + int actual_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; + int hscrol_adj = (IR & 0x10) ? ANTIC_HSCROL : 0; + int hscrollsb_adj = (hscrol_adj & 1); + int oldpos = ANTIC_cur_screen_pos; + int fontfetch_adj; + /* antic fetches character font data every 2 or 4 cycles */ + /* we want to delay the change until the next fetch */ + /* empirically determined: */ + if (anticmode >= 2 && anticmode <= 5) { + fontfetch_adj = (((hscrol_adj >>1) - actual_xpos + 0) & 1) * 2 + 9; + } + else if (anticmode == 6 || anticmode == 7) { + fontfetch_adj = (((hscrol_adj >> 1) - actual_xpos + 2) & 3) * 2 + 9; + } + else { + fontfetch_adj = 0; + } + ANTIC_cur_screen_pos = actual_xpos * 2 - 37 + hscrollsb_adj + fontfetch_adj; + draw_partial_scanline(oldpos, ANTIC_cur_screen_pos); +} + +/* chactl invert needs a different adjustment */ +void update_scanline_invert(void) +{ + int actual_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; + int hscrol_adj = (IR & 0x10) ? ANTIC_HSCROL : 0; + int hscrollsb_adj = (hscrol_adj & 1); + int oldpos = ANTIC_cur_screen_pos; + + /* empirically determined: adjustment of 4 */ + ANTIC_cur_screen_pos = actual_xpos * 2 - 37 + hscrollsb_adj + 4; + draw_partial_scanline(oldpos, ANTIC_cur_screen_pos); +} + +/* chactl blank needs a different adjustment */ +void update_scanline_blank(void) +{ + int actual_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; + int hscrol_adj = (IR & 0x10) ? ANTIC_HSCROL : 0; + int hscrollsb_adj = (hscrol_adj & 1); + int oldpos = ANTIC_cur_screen_pos; + + /* empirically determined: adjustment of 7 */ + ANTIC_cur_screen_pos = actual_xpos * 2 - 37 + hscrollsb_adj + 7; + draw_partial_scanline(oldpos, ANTIC_cur_screen_pos); +} + +static void set_dmactl_bug(void){ + need_load = FALSE; + saved_draw_antic_ptr = draw_antic_ptr; + draw_antic_ptr_changed = 1; + if (anticmode == 2 || anticmode == 3 || anticmode == 0xf) { + draw_antic_ptr = draw_antic_2_dmactl_bug; + dmactl_bug_chdata = (anticmode == 0xf) ? 0 : antic_memory[ANTIC_margin + chars_read[md] - 1]; + } + else { + draw_antic_ptr = draw_antic_0_dmactl_bug; + } +} + +/* draw a partial scanline between point l and point r */ +/* l is the left hand word, r is the point one past the right-most word to draw */ +void draw_partial_scanline(int l, int r) +{ + /* lborder_chars: save left border chars,we restore it after */ + /* it is the number of 8pixel 'chars' in the left border */ + int lborder_chars = left_border_chars; + + /* rborder_start: save right border start, we restore it after */ + /* it is the start of the right border, in words */ + int rborder_start = right_border_start; + + /* lborder_start: start of the left border, in words */ + int lborder_start = LCHOP * 4; + /* end of the left border, in words */ + int lborder_end = LCHOP * 4 + left_border_chars * 4; + /* end of the right border, in words */ + int rborder_end = (48 - RCHOP) * 4; + /* flag: if true, don't show playfield. used if the partial scanline */ + /* does not include the playfield */ + int dont_display_playfield = 0; + /* offset of the left most drawable 8 pixel pf block */ + /* int l_pfchar = (lborder_end - x_min[md]) / 4; */ + int l_pfchar = 0; + /* offset of the right most drawable 8 pixel pf plock, *plus one* */ + int r_pfchar = 0; + /* buffer to save 0,1,2 or 3 words of the left hand portion of an 8pixel */ + /* 'char' which is going to be erased by the left hand side of the */ + /* left most 8pixel 'char' in the partial scanline and must be saved */ + /* and restored later */ + UWORD sv_buf[4]; + /* buffer to save 0 or 1 (modes 6,7,a,b,c) ,or , (0,1,2 or 3) (modes 8,9) */ + /* 8pixel 'chars' of playfield which is going to be erased by the left */ + /* hand most 8pixel 'char's of the 2(modes 67abc) or 4(modes 89) 8pixel */ + /* 'char'-sized blocks that these modes must draw. */ + UWORD sv_buf2[4 * 4]; /* for modes 6,7,8,9,a,b,c */ + /* start,size of the above buffers */ + int sv_bufstart = 0; + int sv_bufsize = 0; + int sv_bufstart2 = 0; + int sv_bufsize2 = 0; + /* number of 8,16,32pixel chars to draw in the playfield */ + int nchars = 0; + /* adjustment to ch_index , it is the number of 8,16,32pixel chars */ + /* that we do not draw on the left hand side that would usually be drawn */ + /* for this mode */ + int ch_adj = 0; + /* adjustment to x_min to skip over the left side */ + int x_min_adj = 0; + /* it's the offset of the left most drawable 8pixel pfblock which is */ + /* rounded *down* to the nearest factor of (2:mode 67abc,4:mode 89) */ + /* if it is divided by (2:mode 67abc,4:mode 89) it will give the */ + /* offset of the left most drawable (16,32)pixel 'char' */ + int l_pfactual = 0; + /* it is the offset of the right most drawable 8pixel pf block which is */ + /* rounded *up* to the nearest factor of (2,4), *plus one* */ + /* so that r_pfactual-l_pfactual / (2,4) = number of 16,32 pixel 'chars' */ + /* to be drawn */ + int r_pfactual = 0; + /* it is the offset of the 8pixel block aligned with pf which overlaps */ + /* the left border. We need this for modes 6-c, because in these modes */ + /* the code will save 8pixel blocks to the left of l_pfchar and */ + /* >= l_pfactual, which will result in portions of the left border */ + /* being saved on some occasions which should not be, unless we */ + /* use this variable to alter the number of chars saved */ + /* int l_borderpfchar=0; */ + + r_pfchar = chars_displayed[md]; + if (md == NORMAL1 || md == SCROLL1) { /* modes 6,7,a,b,c */ + r_pfchar *= 2; + } + else if (md == NORMAL2 || md == SCROLL2) { /* modes 8,9 */ + r_pfchar *= 4; + } + if (anticmode < 2 || (ANTIC_DMACTL & 3) == 0) { + lborder_end = rborder_end; + dont_display_playfield = 1; + } + if (l > rborder_end) + l = rborder_end; + if (r > rborder_end) + r = rborder_end; + if (l < lborder_start) + l = lborder_start; + if (r < lborder_start) + r = lborder_start; + if (l >= r) + return; + if (l < lborder_end) { + /* left point is within left border */ + sv_bufstart = (l & (~3)); /* high order bits give buffer start */ + sv_bufsize = l - sv_bufstart; + left_border_start = sv_bufstart; + left_border_chars = lborder_chars - (sv_bufstart - lborder_start) / 4; + if (l > x_min[md]) { + /* special case for modes 56789abc */ + /* position buffer within the reference frame */ + /* of the playfield if that */ + /* results in more pixels being saved in the buffer */ + /* needed because for modes 5789abc the overlapping part */ + /* can be more than 1 8pixel char and we only save the left */ + /* hand most 8pixel chars in the code in the later section */ + /* further down, so there is a possibility that the 8pixels */ + /* which are saved within the reference frame of the border */ + /* are not enough to ensure that everything gets saved */ + l_pfchar = (l - x_min[md]) / 4; + if (((l - x_min[md]) & 3) > sv_bufsize) { + sv_bufsize = ((l - x_min[md]) & 3); + sv_bufstart = l - sv_bufsize; + } + } + } + else if (l >= rborder_start) { + sv_bufstart = (l & (~3)); /* high order bits give buffer start */ + sv_bufsize = l - sv_bufstart; + right_border_start = sv_bufstart; + dont_display_playfield = 1; /* don't display the playfield */ + } + else { /*within screen */ + sv_bufsize = ((l - x_min[md]) & 3); /* low bits have buf size */ + sv_bufstart = l - sv_bufsize; /* difference gives start */ + l_pfchar = (sv_bufstart - x_min[md]) / 4; + left_border_chars = 0; /* don't display left border */ + } + memcpy(sv_buf, scrn_ptr + sv_bufstart, sv_bufsize * sizeof(UWORD)); /* save part of screen */ + + if (r <= lborder_end) { + /* right_end_char = (r + 3) / 4; */ + left_border_chars = (r + 3) / 4 - sv_bufstart / 4; + /* everything must be within the left border */ + dont_display_playfield = 1; /* don't display the playfield */ + } + else { /* right point is past start of playfield */ + /* now load ANTIC data: needed for ANTIC glitches */ + if (need_load) { + antic_load(); +#ifdef USE_CURSES + /* Normally, we would call curses_display_line here, + and not use scanlines_to_curses_display at all. + That would however cause incorrect color of the "MEMORY" + menu item in Self Test - it isn't set properly + in the first scanline. We therefore postpone + curses_display_line call to the next scanline. */ + scanlines_to_curses_display = 1; +#endif + need_load = FALSE; + } + + if (r > rborder_start) { + right_border_end = ((r + 3) & (~3)); /* round up to nearest 8pixel */ + } + else { + r_pfchar = (r - x_min[md] + 3) / 4; /* round up to nearest 8pixel */ + } + } + if (dont_display_playfield) { + nchars = 0; + x_min_adj = 0; + ch_adj = 0; + } + else if (md == NORMAL1 || md == SCROLL1) { /* modes 6,7,a,b,c */ + l_pfactual = (l_pfchar & (~1)); /* round down to nearest 16pixel */ + sv_bufsize2 = (l_pfchar - l_pfactual) * 4; + sv_bufstart2 = x_min[md] + l_pfactual * 4; + r_pfactual = ((r_pfchar + 1) & (~1)); /* round up to nearest 16pixel */ + nchars = (r_pfactual - l_pfactual) / 2; + x_min_adj = l_pfactual * 4; + ch_adj = l_pfactual / 2; + } + else if (md == NORMAL2 || md == SCROLL2) { /* modes 8,9 */ + l_pfactual = (l_pfchar & (~3)); + sv_bufsize2 = (l_pfchar - l_pfactual) * 4; + sv_bufstart2 = x_min[md] + l_pfactual * 4; + r_pfactual = ((r_pfchar + 3) & (~3)); + nchars = (r_pfactual - l_pfactual) / 4; + x_min_adj = l_pfactual * 4; + ch_adj = l_pfactual / 4; + } + else { + nchars = r_pfchar - l_pfchar; + x_min_adj = l_pfchar * 4; + ch_adj = l_pfchar; + } + memcpy(sv_buf2, scrn_ptr + sv_bufstart2, sv_bufsize2 * sizeof(UWORD)); /* save part of screen */ + + if (dont_display_playfield) { +/* the idea here is to use draw_antic_0_ptr() to draw just the border only, since */ +/* we can't set nchars=0. draw_antic_0_ptr will work if left_border_start and */ +/* right_border_end are set correctly */ + if (anticmode < 2 || (ANTIC_DMACTL & 3) == 0 || r <= lborder_end) { + right_border_end = left_border_start + left_border_chars * 4; + } + else if (l >= rborder_start) { + left_border_start = right_border_start; + } + draw_antic_0_ptr(); + } + else { + draw_antic_ptr(nchars, /* chars_displayed[md], */ + antic_memory + ANTIC_margin + ch_offset[md] + ch_adj, + scrn_ptr + x_min[md] + x_min_adj, + (ULONG *) >IA_pm_scanline[x_min[md] + x_min_adj]); + } + memcpy(scrn_ptr + sv_bufstart2, sv_buf2, sv_bufsize2 * sizeof(UWORD)); /* restore screen */ + memcpy(scrn_ptr + sv_bufstart, sv_buf, sv_bufsize * sizeof(UWORD)); /* restore screen */ + + /* restore border global variables */ + left_border_chars=lborder_chars; + right_border_start=rborder_start; + left_border_start = LCHOP * 4; + right_border_end = (48-RCHOP) *4; +} +#endif /* NEW_CYCLE_EXACT */ + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + +/* ANTIC registers --------------------------------------------------------- */ + +UBYTE ANTIC_GetByte(UWORD addr, int no_side_effects) +{ + switch (addr & 0xf) { + case ANTIC_OFFSET_VCOUNT: + if (ANTIC_XPOS < ANTIC_LINE_C) + return ANTIC_ypos >> 1; + if (ANTIC_ypos + 1 < max_ypos) + return (ANTIC_ypos + 1) >> 1; + return 0; + case ANTIC_OFFSET_PENH: + return PENH; + case ANTIC_OFFSET_PENV: + return PENV; + case ANTIC_OFFSET_NMIST: + return ANTIC_NMIST; + default: + return 0xff; + } +} + +#if !defined(BASIC) && !defined(CURSES_BASIC) + +/* GTIA calls it on write to PRIOR */ +void ANTIC_SetPrior(UBYTE byte) +{ + if ((byte ^ GTIA_PRIOR) & 0x0f) { +#ifdef USE_COLOUR_TRANSLATION_TABLE + UBYTE col = 0; + UBYTE col2 = 0; + UBYTE hi; + UBYTE hi2; + if ((byte & 3) == 0) { + col = GTIA_COLPF0; + col2 = GTIA_COLPF1; + } + if ((byte & 0xc) == 0) { + ANTIC_cl[C_PF0 | C_PM0] = colour_translation_table[col | GTIA_COLPM0]; + ANTIC_cl[C_PF0 | C_PM1] = colour_translation_table[col | GTIA_COLPM1]; + ANTIC_cl[C_PF0 | C_PM01] = colour_translation_table[col | GTIA_COLPM0 | GTIA_COLPM1]; + ANTIC_cl[C_PF1 | C_PM0] = colour_translation_table[col2 | GTIA_COLPM0]; + ANTIC_cl[C_PF1 | C_PM1] = colour_translation_table[col2 | GTIA_COLPM1]; + ANTIC_cl[C_PF1 | C_PM01] = colour_translation_table[col2 | GTIA_COLPM0 | GTIA_COLPM1]; + } + else { + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF0 | C_PM1] = ANTIC_cl[C_PF0 | C_PM0] = colour_translation_table[col]; + ANTIC_cl[C_PF1 | C_PM01] = ANTIC_cl[C_PF1 | C_PM1] = ANTIC_cl[C_PF1 | C_PM0] = colour_translation_table[col2]; + } + if (byte & 4) { + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PF2 | C_PM0] = ANTIC_cl[C_PF2]; + ANTIC_cl[C_PF3 | C_PM01] = ANTIC_cl[C_PF3 | C_PM1] = ANTIC_cl[C_PF3 | C_PM0] = ANTIC_cl[C_PF3]; + ANTIC_cl[C_HI2 | C_PM01] = ANTIC_cl[C_HI2 | C_PM1] = ANTIC_cl[C_HI2 | C_PM0] = ANTIC_cl[C_HI2]; + } + else { + ANTIC_cl[C_PF3 | C_PM0] = ANTIC_cl[C_PF2 | C_PM0] = ANTIC_cl[C_PM0]; + ANTIC_cl[C_PF3 | C_PM1] = ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PM1]; + ANTIC_cl[C_PF3 | C_PM01] = ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PM01]; + ANTIC_cl[C_HI2 | C_PM0] = colour_translation_table[(GTIA_COLPM0 & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM1] = colour_translation_table[(GTIA_COLPM1 & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM01] = colour_translation_table[((GTIA_COLPM0 | GTIA_COLPM1) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + } + col = col2 = 0; + hi = hi2 = GTIA_COLPF1 & 0xf; + ANTIC_cl[C_BLACK - C_PF2 + C_HI2] = colour_translation_table[hi]; + if ((byte & 9) == 0) { + col = GTIA_COLPF2; + col2 = GTIA_COLPF3; + hi |= col & 0xf0; + hi2 |= col2 & 0xf0; + } + if ((byte & 6) == 0) { + ANTIC_cl[C_PF2 | C_PM2] = colour_translation_table[col | GTIA_COLPM2]; + ANTIC_cl[C_PF2 | C_PM3] = colour_translation_table[col | GTIA_COLPM3]; + ANTIC_cl[C_PF2 | C_PM23] = colour_translation_table[col | GTIA_COLPM2 | GTIA_COLPM3]; + ANTIC_cl[C_PF3 | C_PM2] = colour_translation_table[col2 | GTIA_COLPM2]; + ANTIC_cl[C_PF3 | C_PM3] = colour_translation_table[col2 | GTIA_COLPM3]; + ANTIC_cl[C_PF3 | C_PM23] = colour_translation_table[col2 | GTIA_COLPM2 | GTIA_COLPM3]; + ANTIC_cl[C_HI2 | C_PM2] = colour_translation_table[hi | (GTIA_COLPM2 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM3] = colour_translation_table[hi | (GTIA_COLPM3 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM23] = colour_translation_table[hi | ((GTIA_COLPM2 | GTIA_COLPM3) & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM25] = colour_translation_table[hi2 | (GTIA_COLPM2 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM35] = colour_translation_table[hi2 | (GTIA_COLPM3 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM235] = colour_translation_table[hi2 | ((GTIA_COLPM2 | GTIA_COLPM3) & 0xf0)]; + } + else { + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF2 | C_PM3] = ANTIC_cl[C_PF2 | C_PM2] = colour_translation_table[col]; + ANTIC_cl[C_PF3 | C_PM23] = ANTIC_cl[C_PF3 | C_PM3] = ANTIC_cl[C_PF3 | C_PM2] = colour_translation_table[col2]; + ANTIC_cl[C_HI2 | C_PM23] = ANTIC_cl[C_HI2 | C_PM3] = ANTIC_cl[C_HI2 | C_PM2] = colour_translation_table[hi]; + } +#else /* USE_COLOUR_TRANSLATION_TABLE */ + UWORD cword = 0; + UWORD cword2 = 0; + if ((byte & 3) == 0) { + cword = ANTIC_cl[C_PF0]; + cword2 = ANTIC_cl[C_PF1]; + } + if ((byte & 0xc) == 0) { + ANTIC_cl[C_PF0 | C_PM0] = cword | ANTIC_cl[C_PM0]; + ANTIC_cl[C_PF0 | C_PM1] = cword | ANTIC_cl[C_PM1]; + ANTIC_cl[C_PF0 | C_PM01] = cword | ANTIC_cl[C_PM01]; + ANTIC_cl[C_PF1 | C_PM0] = cword2 | ANTIC_cl[C_PM0]; + ANTIC_cl[C_PF1 | C_PM1] = cword2 | ANTIC_cl[C_PM1]; + ANTIC_cl[C_PF1 | C_PM01] = cword2 | ANTIC_cl[C_PM01]; + } + else { + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF0 | C_PM1] = ANTIC_cl[C_PF0 | C_PM0] = cword; + ANTIC_cl[C_PF1 | C_PM01] = ANTIC_cl[C_PF1 | C_PM1] = ANTIC_cl[C_PF1 | C_PM0] = cword2; + } + if (byte & 4) { + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PF2 | C_PM0] = ANTIC_cl[C_PF2]; + ANTIC_cl[C_PF3 | C_PM01] = ANTIC_cl[C_PF3 | C_PM1] = ANTIC_cl[C_PF3 | C_PM0] = ANTIC_cl[C_PF3]; + } + else { + ANTIC_cl[C_PF3 | C_PM0] = ANTIC_cl[C_PF2 | C_PM0] = ANTIC_cl[C_PM0]; + ANTIC_cl[C_PF3 | C_PM1] = ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PM1]; + ANTIC_cl[C_PF3 | C_PM01] = ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PM01]; + } + cword = cword2 = 0; + if ((byte & 9) == 0) { + cword = ANTIC_cl[C_PF2]; + cword2 = ANTIC_cl[C_PF3]; + } + if ((byte & 6) == 0) { + ANTIC_cl[C_PF2 | C_PM2] = cword | ANTIC_cl[C_PM2]; + ANTIC_cl[C_PF2 | C_PM3] = cword | ANTIC_cl[C_PM3]; + ANTIC_cl[C_PF2 | C_PM23] = cword | ANTIC_cl[C_PM23]; + ANTIC_cl[C_PF3 | C_PM2] = cword2 | ANTIC_cl[C_PM2]; + ANTIC_cl[C_PF3 | C_PM3] = cword2 | ANTIC_cl[C_PM3]; + ANTIC_cl[C_PF3 | C_PM23] = cword2 | ANTIC_cl[C_PM23]; + } + else { + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF2 | C_PM3] = ANTIC_cl[C_PF2 | C_PM2] = cword; + ANTIC_cl[C_PF3 | C_PM23] = ANTIC_cl[C_PF3 | C_PM3] = ANTIC_cl[C_PF3 | C_PM2] = cword2; + } +#endif /* USE_COLOUR_TRANSLATION_TABLE */ + if (byte & 1) { + ANTIC_cl[C_PF1 | C_PM2] = ANTIC_cl[C_PF0 | C_PM2] = ANTIC_cl[C_PM2]; + ANTIC_cl[C_PF1 | C_PM3] = ANTIC_cl[C_PF0 | C_PM3] = ANTIC_cl[C_PM3]; + ANTIC_cl[C_PF1 | C_PM23] = ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PM23]; + } + else { + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF0 | C_PM3] = ANTIC_cl[C_PF0 | C_PM2] = ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM23] = ANTIC_cl[C_PF1 | C_PM3] = ANTIC_cl[C_PF1 | C_PM2] = ANTIC_cl[C_PF1]; + } + if ((byte & 0xf) == 0xc) { + ANTIC_cl[C_PF0 | C_PM0123] = ANTIC_cl[C_PF0 | C_PM123] = ANTIC_cl[C_PF0 | C_PM023] = ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM0123] = ANTIC_cl[C_PF1 | C_PM123] = ANTIC_cl[C_PF1 | C_PM023] = ANTIC_cl[C_PF1]; + } + else + ANTIC_cl[C_PF0 | C_PM0123] = ANTIC_cl[C_PF0 | C_PM123] = ANTIC_cl[C_PF0 | C_PM023] = + ANTIC_cl[C_PF1 | C_PM0123] = ANTIC_cl[C_PF1 | C_PM123] = ANTIC_cl[C_PF1 | C_PM023] = GTIA_COLOUR_BLACK; + if (byte & 0xf) { + ANTIC_cl[C_PF0 | C_PM25] = ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM25] = ANTIC_cl[C_PF1]; + ANTIC_cl[C_PF3 | C_PM25] = ANTIC_cl[C_PF2 | C_PM25] = ANTIC_cl[C_PM25] = GTIA_COLOUR_BLACK; + } + else { + ANTIC_cl[C_PF0 | C_PM235] = ANTIC_cl[C_PF0 | C_PM35] = ANTIC_cl[C_PF0 | C_PM25] = + ANTIC_cl[C_PF1 | C_PM235] = ANTIC_cl[C_PF1 | C_PM35] = ANTIC_cl[C_PF1 | C_PM25] = ANTIC_cl[C_PF3]; + ANTIC_cl[C_PF3 | C_PM25] = ANTIC_cl[C_PF2 | C_PM25] = ANTIC_cl[C_PM25] = ANTIC_cl[C_PF3 | C_PM2]; + ANTIC_cl[C_PF3 | C_PM35] = ANTIC_cl[C_PF2 | C_PM35] = ANTIC_cl[C_PM35] = ANTIC_cl[C_PF3 | C_PM3]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23]; + } + } + pm_lookup_ptr = pm_lookup_table[prior_to_pm_lookup[byte & 0x3f]]; + draw_antic_0_ptr = byte < 0x80 ? draw_antic_0 : byte < 0xc0 ? draw_antic_0_gtia10 : draw_antic_0_gtia11; + if (byte < 0x40 && (GTIA_PRIOR >= 0x40 || gtia_bug_active) && (anticmode == 2 || anticmode == 3 || anticmode == 0xf) && ANTIC_XPOS >= ((ANTIC_DMACTL & 3) == 3 ? 16 : 18)) { + /* A GTIA Mode was active, and no longer is. An ANTIC hi-res mode is being used. GTIA is no longer set in hi-res mode */ + if (anticmode == 2 || anticmode == 3) draw_antic_ptr = draw_antic_2_gtia_bug; + else if (anticmode == 0xf) draw_antic_ptr = draw_antic_f_gtia_bug; + gtia_bug_active = TRUE; + } + else + draw_antic_ptr = draw_antic_table[byte >> 6][anticmode]; +} + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + +void ANTIC_PutByte(UWORD addr, UBYTE byte) +{ + switch (addr & 0xf) { + case ANTIC_OFFSET_DLISTL: + ANTIC_dlist = (ANTIC_dlist & 0xff00) | byte; + break; + case ANTIC_OFFSET_DLISTH: + ANTIC_dlist = (ANTIC_dlist & 0x00ff) | (byte << 8); + break; + case ANTIC_OFFSET_DMACTL: +/* TODO: make this truly cycle-exact, update cpu2antic and antic2cpu, +add support for wider->narrow glitches including the interesting mode 6 +glitch */ +#ifdef NEW_CYCLE_EXACT + dmactl_changed=0; + /* has DMACTL width changed? */ + if ((byte & 3) != (ANTIC_DMACTL & 3) ){ + /* DMACTL width changed from 0 */ + if ((ANTIC_DMACTL & 3) == 0) { + int glitch_cycle = (3 + 32) - 8*(byte & 3); + int x = ANTIC_XPOS; + if((IR & 0x10) && ((byte & 3) != 3)){ + /*adjust for narrow or std HSCROL*/ + glitch_cycle -= 8; + } + /*ANTIC doesn't fetch and display data if the*/ + /*DMACTL width changes from zero after this */ + /*cycle. Instead, it displays a blank scan */ + /*line for modes other than 23F and for 23F */ + /*it displays a glitched line after the change*/ + if(x >= glitch_cycle){ + if(ANTIC_DRAWING_SCREEN){ + ANTIC_UpdateScanline(); + set_dmactl_bug(); + } + } + else { + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } + } + } + /* DMACTL width changed to 0 */ + else if ((byte & 3)==0) { + /* TODO: this is not 100% correct */ + if (ANTIC_DRAWING_SCREEN) { + int actual_xpos = ANTIC_cpu2antic_ptr[ANTIC_xpos]; + int antic_limit = ANTIC_cpu2antic_ptr[ANTIC_xpos_limit]; + ANTIC_UpdateScanline(); + /*fix for a minor glitch in fasteddie*/ + /*don't steal cycles after DMACTL off*/ + ANTIC_cpu2antic_ptr = &CYCLE_MAP_cpu2antic[0]; + ANTIC_antic2cpu_ptr = &CYCLE_MAP_antic2cpu[0]; + ANTIC_xpos = ANTIC_antic2cpu_ptr[actual_xpos]; + ANTIC_xpos_limit = ANTIC_antic2cpu_ptr[antic_limit]; + } + /* DMACTL width has changed and not to 0 and not from 0 */ + } + else { + /* DMACTL width has increased and no HSCROL */ + if (((byte & 3) > (ANTIC_DMACTL & 3)) && !(IR & 0x10)) { + int x; /* the change cycle */ + int left_glitch_cycle = 0; + int right_glitch_cycle = 0; + x = ANTIC_XPOS; + if (((ANTIC_DMACTL & 3) == 2) && ((byte & 3) == 3)) { /* Normal->Wide */ + left_glitch_cycle = 11; + right_glitch_cycle = 18; + } + else if (((ANTIC_DMACTL & 3) == 1) && ((byte & 3) == 3)) { /* Narrow->Wide */ + left_glitch_cycle = 11; + right_glitch_cycle = 26; + } + else if (((ANTIC_DMACTL & 3) == 1) && ((byte & 3) == 2)) { /* Narrow->Normal */ + left_glitch_cycle = 19; + right_glitch_cycle = 27; + } + /* change occurs during drawing of line */ + /* delay change till next line */ + if (x > right_glitch_cycle) { + dmactl_changed = 1; + delayed_DMACTL = byte; + break; + /* change occurs during 'glitch' region */ + } + else if (x >= left_glitch_cycle && x <= right_glitch_cycle && anticmode > 1) { + set_dmactl_bug(); + } + } + else { + /* DMACTL width has decreased or HSCROL */ + /* TODO: this is not 100% correct */ + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } + } + } + } +#endif /* NEW_CYCLE_EXACT */ + ANTIC_DMACTL = byte; +#if defined(BASIC) || defined(CURSES_BASIC) + break; +#else + switch (byte & 0x03) { + case 0x00: + /* no antic_load when screen off */ + /* chars_read[NORMAL0] = 0; + chars_read[NORMAL1] = 0; + chars_read[NORMAL2] = 0; + chars_read[SCROLL0] = 0; + chars_read[SCROLL1] = 0; + chars_read[SCROLL2] = 0; */ + /* no draw_antic_* when screen off */ + /* chars_displayed[NORMAL0] = 0; + chars_displayed[NORMAL1] = 0; + chars_displayed[NORMAL2] = 0; + chars_displayed[SCROLL0] = 0; + chars_displayed[SCROLL1] = 0; + chars_displayed[SCROLL2] = 0; + x_min[NORMAL0] = 0; + x_min[NORMAL1] = 0; + x_min[NORMAL2] = 0; + x_min[SCROLL0] = 0; + x_min[SCROLL1] = 0; + x_min[SCROLL2] = 0; + ch_offset[NORMAL0] = 0; + ch_offset[NORMAL1] = 0; + ch_offset[NORMAL2] = 0; + ch_offset[SCROLL0] = 0; + ch_offset[SCROLL1] = 0; + ch_offset[SCROLL2] = 0; */ + /* no borders when screen off, only background */ + /* left_border_chars = 48 - LCHOP - RCHOP; + right_border_start = 0; */ + break; + case 0x01: + chars_read[NORMAL0] = 32; + chars_read[NORMAL1] = 16; + chars_read[NORMAL2] = 8; + chars_read[SCROLL0] = 40; + chars_read[SCROLL1] = 20; + chars_read[SCROLL2] = 10; + chars_displayed[NORMAL0] = 32; + chars_displayed[NORMAL1] = 16; + chars_displayed[NORMAL2] = 8; + x_min[NORMAL0] = 32; + x_min[NORMAL1] = 32; + x_min[NORMAL2] = 32; + ch_offset[NORMAL0] = 0; + ch_offset[NORMAL1] = 0; + ch_offset[NORMAL2] = 0; + font_cycles[NORMAL0] = load_cycles[NORMAL0] = 32; + font_cycles[NORMAL1] = load_cycles[NORMAL1] = 16; + load_cycles[NORMAL2] = 8; + before_cycles[NORMAL0] = BEFORE_CYCLES; + before_cycles[SCROLL0] = BEFORE_CYCLES + 8; + extra_cycles[NORMAL0] = 7 + BEFORE_CYCLES; + extra_cycles[SCROLL0] = 8 + BEFORE_CYCLES + 8; + left_border_chars = 8 - LCHOP; + right_border_start = (ATARI_WIDTH - 64) / 2; + break; + case 0x02: + chars_read[NORMAL0] = 40; + chars_read[NORMAL1] = 20; + chars_read[NORMAL2] = 10; + chars_read[SCROLL0] = 48; + chars_read[SCROLL1] = 24; + chars_read[SCROLL2] = 12; + chars_displayed[NORMAL0] = 40; + chars_displayed[NORMAL1] = 20; + chars_displayed[NORMAL2] = 10; + x_min[NORMAL0] = 16; + x_min[NORMAL1] = 16; + x_min[NORMAL2] = 16; + ch_offset[NORMAL0] = 0; + ch_offset[NORMAL1] = 0; + ch_offset[NORMAL2] = 0; + font_cycles[NORMAL0] = load_cycles[NORMAL0] = 40; + font_cycles[NORMAL1] = load_cycles[NORMAL1] = 20; + load_cycles[NORMAL2] = 10; + before_cycles[NORMAL0] = BEFORE_CYCLES + 8; + before_cycles[SCROLL0] = BEFORE_CYCLES + 16; + extra_cycles[NORMAL0] = 8 + BEFORE_CYCLES + 8; + extra_cycles[SCROLL0] = 7 + BEFORE_CYCLES + 16; + left_border_chars = 4 - LCHOP; + right_border_start = (ATARI_WIDTH - 32) / 2; + break; + case 0x03: + chars_read[NORMAL0] = 48; + chars_read[NORMAL1] = 24; + chars_read[NORMAL2] = 12; + chars_read[SCROLL0] = 48; + chars_read[SCROLL1] = 24; + chars_read[SCROLL2] = 12; + chars_displayed[NORMAL0] = 42; + chars_displayed[NORMAL1] = 22; + chars_displayed[NORMAL2] = 12; + x_min[NORMAL0] = 12; + x_min[NORMAL1] = 8; + x_min[NORMAL2] = 0; + ch_offset[NORMAL0] = 3; + ch_offset[NORMAL1] = 1; + ch_offset[NORMAL2] = 0; + font_cycles[NORMAL0] = load_cycles[NORMAL0] = 47; + font_cycles[NORMAL1] = load_cycles[NORMAL1] = 24; + load_cycles[NORMAL2] = 12; + before_cycles[NORMAL0] = BEFORE_CYCLES + 16; + before_cycles[SCROLL0] = BEFORE_CYCLES + 16; + extra_cycles[NORMAL0] = 7 + BEFORE_CYCLES + 16; + extra_cycles[SCROLL0] = 7 + BEFORE_CYCLES + 16; + left_border_chars = 3 - LCHOP; + right_border_start = (ATARI_WIDTH - 8) / 2; + break; + } + + ANTIC_missile_dma_enabled = (byte & 0x0c); /* no player dma without missile */ + ANTIC_player_dma_enabled = (byte & 0x08); + singleline = (byte & 0x10); + ANTIC_player_flickering = ((ANTIC_player_dma_enabled | ANTIC_player_gra_enabled) == 0x02); + ANTIC_missile_flickering = ((ANTIC_missile_dma_enabled | ANTIC_missile_gra_enabled) == 0x01); + + byte = ANTIC_HSCROL; /* update horizontal scroll data */ +/* ******* FALLTHROUGH ******* */ + case ANTIC_OFFSET_HSCROL: +/* TODO: make this truely cycle exact, and update cpu2antic and antic2cpu */ +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + ANTIC_HSCROL = byte &= 0x0f; + if (ANTIC_DMACTL & 3) { + chars_displayed[SCROLL0] = chars_displayed[NORMAL0]; + ch_offset[SCROLL0] = 4 - (byte >> 2); + x_min[SCROLL0] = x_min[NORMAL0]; + if (byte & 3) { + x_min[SCROLL0] += (byte & 3) - 4; + chars_displayed[SCROLL0]++; + ch_offset[SCROLL0]--; + } + chars_displayed[SCROLL2] = chars_displayed[NORMAL2]; + if ((ANTIC_DMACTL & 3) == 3) { /* wide playfield */ + ch_offset[SCROLL0]--; + if (byte == 4 || byte == 12) + chars_displayed[SCROLL1] = 21; + else + chars_displayed[SCROLL1] = 22; + if (byte <= 4) { + x_min[SCROLL1] = byte + 8; + ch_offset[SCROLL1] = 1; + } + else if (byte <= 12) { + x_min[SCROLL1] = byte; + ch_offset[SCROLL1] = 0; + } + else { + x_min[SCROLL1] = byte - 8; + ch_offset[SCROLL1] = -1; + } + /* technically, the part below is wrong */ + /* scrolling in mode 8,9 with HSCROL=13,14,15 */ + /* will set x_min=13,14,15 > 4*LCHOP = 12 */ + /* so that nothing is drawn on the far left side */ + /* of the screen. We could fix this, but only */ + /* by setting x_min to be negative. */ + x_min[SCROLL2] = byte; + ch_offset[SCROLL2] = 0; + } + else { + chars_displayed[SCROLL1] = chars_displayed[NORMAL1]; + ch_offset[SCROLL1] = 2 - (byte >> 3); + x_min[SCROLL1] = x_min[NORMAL0]; + if (byte) { + if (byte & 7) { + x_min[SCROLL1] += (byte & 7) - 8; + chars_displayed[SCROLL1]++; + ch_offset[SCROLL1]--; + } + x_min[SCROLL2] = x_min[NORMAL2] + byte - 16; + chars_displayed[SCROLL2]++; + ch_offset[SCROLL2] = 0; + } + else { + x_min[SCROLL2] = x_min[NORMAL2]; + ch_offset[SCROLL2] = 1; + } + } + + if (ANTIC_DMACTL & 2) { /* normal & wide playfield */ + load_cycles[SCROLL0] = 47 - (byte >> 2); + font_cycles[SCROLL0] = (47 * 4 + 1 - byte) >> 2; + load_cycles[SCROLL1] = (24 * 8 + 3 - byte) >> 3; + font_cycles[SCROLL1] = (24 * 8 + 1 - byte) >> 3; + load_cycles[SCROLL2] = byte < 0xc ? 12 : 11; + } + else { /* narrow playfield */ + font_cycles[SCROLL0] = load_cycles[SCROLL0] = 40; + font_cycles[SCROLL1] = load_cycles[SCROLL1] = 20; + load_cycles[SCROLL2] = 16; + } + } + break; + case ANTIC_OFFSET_VSCROL: + ANTIC_VSCROL = byte & 0x0f; + if (vscrol_off) { + lastline = ANTIC_VSCROL; + if (ANTIC_XPOS < VSCOF_C) + need_dl = dctr == lastline; + } + break; + case ANTIC_OFFSET_PMBASE: + ANTIC_PMBASE = byte; + pmbase_d = (byte & 0xfc) << 8; + pmbase_s = pmbase_d & 0xf8ff; + break; + case ANTIC_OFFSET_CHACTL: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + update_scanline_invert(); + } +#endif + invert_mask = byte & 2 ? 0x80 : 0; +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + update_scanline_blank(); + } +#endif + blank_mask = byte & 1 ? 0xe0 : 0x60; + if ((ANTIC_CHACTL ^ byte) & 4) { +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + /* timing for flip is the same as chbase */ + update_scanline_chbase(); + } +#endif + chbase_20 ^= 7; + } + ANTIC_CHACTL = byte; + break; + case ANTIC_OFFSET_CHBASE: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + update_scanline_chbase(); + } +#endif + ANTIC_CHBASE = byte; + chbase_20 = (byte & 0xfe) << 8; + if (ANTIC_CHACTL & 4) + chbase_20 ^= 7; + break; +#endif /* defined(BASIC) || defined(CURSES_BASIC) */ + case ANTIC_OFFSET_WSYNC: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + if (ANTIC_xpos <= ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C] && ANTIC_xpos_limit >= ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C]) + if (ANTIC_cpu2antic_ptr[ANTIC_xpos + 1] == ANTIC_cpu2antic_ptr[ANTIC_xpos] + 1) { + /* antic does not steal the current cycle */ +/* note that if ANTIC_WSYNC_C is a stolen cycle, then ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C+1]-1 corresponds +to the last cpu cycle < ANTIC_WSYNC_C. Then the cpu will see this cycle if WSYNC +is not delayed, since it really occurred one cycle after the STA WSYNC. But if +WSYNC is "delayed" then ANTIC_xpos is the next cpu cycle after ANTIC_WSYNC_C (which was stolen +), so it is one greater than the above value. EG if ANTIC_WSYNC_C=10 and is stolen +(and let us say cycle 9,11 are also stolen, and 8,12 are not), then in the first +case we have ANTIC_cpu2antic_ptr[ANTIC_WSYNC_C+1]-1 = 8 and in the 2nd =12 */ + ANTIC_xpos = ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C + 1] - 1; + } + else { + ANTIC_xpos = ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C + 1]; + } + else { + ANTIC_wsync_halt = TRUE; + ANTIC_xpos = ANTIC_xpos_limit; + if (ANTIC_cpu2antic_ptr[ANTIC_xpos + 1] == ANTIC_cpu2antic_ptr[ANTIC_xpos] + 1) { + /* antic does not steal the current cycle */ + ANTIC_delayed_wsync = 0; + } + else { + ANTIC_delayed_wsync = 1; + } + } + } + else { + ANTIC_delayed_wsync = 0; +#endif /* NEW_CYCLE_EXACT */ + if (ANTIC_xpos <= ANTIC_WSYNC_C && ANTIC_xpos_limit >= ANTIC_WSYNC_C) + ANTIC_xpos = ANTIC_WSYNC_C; + else { + ANTIC_wsync_halt = TRUE; + ANTIC_xpos = ANTIC_xpos_limit; + } +#ifdef NEW_CYCLE_EXACT + } +#endif /* NEW_CYCLE_EXACT */ + break; + case ANTIC_OFFSET_NMIEN: + ANTIC_NMIEN = byte; + break; + case ANTIC_OFFSET_NMIRES: + ANTIC_NMIST = 0x1f; + break; + default: + break; + } +} + +/* State ------------------------------------------------------------------- */ + +#ifndef BASIC + +void ANTIC_StateSave(void) +{ + StateSav_SaveUBYTE(&ANTIC_DMACTL, 1); + StateSav_SaveUBYTE(&ANTIC_CHACTL, 1); + StateSav_SaveUBYTE(&ANTIC_HSCROL, 1); + StateSav_SaveUBYTE(&ANTIC_VSCROL, 1); + StateSav_SaveUBYTE(&ANTIC_PMBASE, 1); + StateSav_SaveUBYTE(&ANTIC_CHBASE, 1); + StateSav_SaveUBYTE(&ANTIC_NMIEN, 1); + StateSav_SaveUBYTE(&ANTIC_NMIST, 1); + StateSav_SaveUBYTE(&IR, 1); + StateSav_SaveUBYTE(&anticmode, 1); + StateSav_SaveUBYTE(&dctr, 1); + StateSav_SaveUBYTE(&lastline, 1); + StateSav_SaveUBYTE(&need_dl, 1); + StateSav_SaveUBYTE(&vscrol_off, 1); + + StateSav_SaveUWORD(&ANTIC_dlist, 1); + StateSav_SaveUWORD(&screenaddr, 1); + + StateSav_SaveINT(&ANTIC_xpos, 1); + StateSav_SaveINT(&ANTIC_xpos_limit, 1); + StateSav_SaveINT(&ANTIC_ypos, 1); +} + +void ANTIC_StateRead(void) +{ + StateSav_ReadUBYTE(&ANTIC_DMACTL, 1); + StateSav_ReadUBYTE(&ANTIC_CHACTL, 1); + StateSav_ReadUBYTE(&ANTIC_HSCROL, 1); + StateSav_ReadUBYTE(&ANTIC_VSCROL, 1); + StateSav_ReadUBYTE(&ANTIC_PMBASE, 1); + StateSav_ReadUBYTE(&ANTIC_CHBASE, 1); + StateSav_ReadUBYTE(&ANTIC_NMIEN, 1); + StateSav_ReadUBYTE(&ANTIC_NMIST, 1); + StateSav_ReadUBYTE(&IR, 1); + StateSav_ReadUBYTE(&anticmode, 1); + StateSav_ReadUBYTE(&dctr, 1); + StateSav_ReadUBYTE(&lastline, 1); + StateSav_ReadUBYTE(&need_dl, 1); + StateSav_ReadUBYTE(&vscrol_off, 1); + + StateSav_ReadUWORD(&ANTIC_dlist, 1); + StateSav_ReadUWORD(&screenaddr, 1); + + StateSav_ReadINT(&ANTIC_xpos, 1); + StateSav_ReadINT(&ANTIC_xpos_limit, 1); + StateSav_ReadINT(&ANTIC_ypos, 1); + + ANTIC_PutByte(ANTIC_OFFSET_DMACTL, ANTIC_DMACTL); + ANTIC_PutByte(ANTIC_OFFSET_CHACTL, ANTIC_CHACTL); + ANTIC_PutByte(ANTIC_OFFSET_PMBASE, ANTIC_PMBASE); + ANTIC_PutByte(ANTIC_OFFSET_CHBASE, ANTIC_CHBASE); +} + +#endif /* BASIC */ diff --git a/MCUME_teensy41/teensy800/antic.h b/MCUME_teensy41/teensy800/antic.h new file mode 100644 index 0000000..0a89e66 --- /dev/null +++ b/MCUME_teensy41/teensy800/antic.h @@ -0,0 +1,136 @@ +#ifndef ANTIC_H_ +#define ANTIC_H_ + +#include "atari.h" +/* + * Offset to registers in custom relative to start of antic memory addresses. + */ + +#define ANTIC_OFFSET_DMACTL 0x00 +#define ANTIC_OFFSET_CHACTL 0x01 +#define ANTIC_OFFSET_DLISTL 0x02 +#define ANTIC_OFFSET_DLISTH 0x03 +#define ANTIC_OFFSET_HSCROL 0x04 +#define ANTIC_OFFSET_VSCROL 0x05 +#define ANTIC_OFFSET_PMBASE 0x07 +#define ANTIC_OFFSET_CHBASE 0x09 +#define ANTIC_OFFSET_WSYNC 0x0a +#define ANTIC_OFFSET_VCOUNT 0x0b +#define ANTIC_OFFSET_PENH 0x0c +#define ANTIC_OFFSET_PENV 0x0d +#define ANTIC_OFFSET_NMIEN 0x0e +#define ANTIC_OFFSET_NMIRES 0x0f +#define ANTIC_OFFSET_NMIST 0x0f + +extern UBYTE ANTIC_CHACTL; +extern UBYTE ANTIC_CHBASE; +extern UWORD ANTIC_dlist; +extern UBYTE ANTIC_DMACTL; +extern UBYTE ANTIC_HSCROL; +extern UBYTE ANTIC_NMIEN; +extern UBYTE ANTIC_NMIST; +extern UBYTE ANTIC_PMBASE; +extern UBYTE ANTIC_VSCROL; + +extern int ANTIC_break_ypos; +extern int ANTIC_ypos; +extern int ANTIC_wsync_halt; + +/* Current clock cycle in a scanline. + Normally 0 <= ANTIC_xpos && ANTIC_xpos < ANTIC_LINE_C, but in some cases ANTIC_xpos >= ANTIC_LINE_C, + which means that we are already in line (ypos + 1). */ +extern int ANTIC_xpos; + +/* ANTIC_xpos limit for the currently running 6502 emulation. */ +extern int ANTIC_xpos_limit; + +/* Main clock value at the beginning of the current scanline. */ +extern unsigned int ANTIC_screenline_cpu_clock; + +/* Current main clock value. */ +#define ANTIC_CPU_CLOCK (ANTIC_screenline_cpu_clock + ANTIC_XPOS) + +#define ANTIC_NMIST_C 6 +#define ANTIC_NMI_C 12 + +/* Number of cycles per scanline. */ +#define ANTIC_LINE_C 114 + +/* STA WSYNC resumes here. */ +#define ANTIC_WSYNC_C 106 + +/* Number of memory refresh cycles per scanline. + In the first scanline of a font mode there are actually less than ANTIC_DMAR + memory refresh cycles. */ +#define ANTIC_DMAR 9 + +extern int ANTIC_artif_mode; +extern int ANTIC_artif_new; + +extern UBYTE ANTIC_PENH_input; +extern UBYTE ANTIC_PENV_input; + +int ANTIC_Initialise(void); +void ANTIC_Reset(void); +void ANTIC_Frame(int draw_display); +UBYTE ANTIC_GetByte(UWORD addr, int no_side_effects); +void ANTIC_PutByte(UWORD addr, UBYTE byte); + +UBYTE ANTIC_GetDLByte(UWORD *paddr); +UWORD ANTIC_GetDLWord(UWORD *paddr); + +/* always call ANTIC_UpdateArtifacting after changing ANTIC_artif_mode */ +void ANTIC_UpdateArtifacting(void); + +/* Video memory access */ +void ANTIC_VideoMemset(UBYTE *ptr, UBYTE val, ULONG size); +void ANTIC_VideoPutByte(UBYTE *ptr, UBYTE val); + +/* GTIA calls it on a write to PRIOR */ +void ANTIC_SetPrior(UBYTE prior); + +/* Saved states */ +void ANTIC_StateSave(void); +void ANTIC_StateRead(void); + +/* Pointer to 16 KB seen by ANTIC in 0x4000-0x7fff. + If it's the same what the CPU sees (and what's in memory[0x4000..0x7fff], + then NULL. */ +extern const UBYTE *ANTIC_xe_ptr; + +/* PM graphics for GTIA */ +extern int ANTIC_player_dma_enabled; +extern int ANTIC_missile_dma_enabled; +extern int ANTIC_player_gra_enabled; +extern int ANTIC_missile_gra_enabled; +extern int ANTIC_player_flickering; +extern int ANTIC_missile_flickering; + +/* ANTIC colour lookup tables, used by GTIA */ +extern UWORD ANTIC_cl[128]; +extern ULONG ANTIC_lookup_gtia9[16]; +extern ULONG ANTIC_lookup_gtia11[16]; +extern UWORD ANTIC_hires_lookup_l[128]; + +#ifdef NEW_CYCLE_EXACT +#define ANTIC_NOT_DRAWING -999 +#define ANTIC_DRAWING_SCREEN (ANTIC_cur_screen_pos!=ANTIC_NOT_DRAWING) +extern int ANTIC_delayed_wsync; +extern int ANTIC_cur_screen_pos; +extern const int *ANTIC_cpu2antic_ptr; +extern const int *ANTIC_antic2cpu_ptr; +void ANTIC_UpdateScanline(void); +void ANTIC_UpdateScanlinePrior(UBYTE byte); + +#define ANTIC_XPOS ( ANTIC_DRAWING_SCREEN ? ANTIC_cpu2antic_ptr[ANTIC_xpos] : ANTIC_xpos ) +#else +#define ANTIC_XPOS ANTIC_xpos +#endif /* NEW_CYCLE_EXACT */ + +#ifndef NO_SIMPLE_PAL_BLENDING +/* Set to 1 to enable simplified emulation of PAL blending, that uses only + the standard 8-bit palette. */ +extern int ANTIC_pal_blending; +#endif /* NO_SIMPLE_PAL_BLENDING */ + +#endif /* ANTIC_H_ */ diff --git a/MCUME_teensy41/teensy800/atari.h b/MCUME_teensy41/teensy800/atari.h new file mode 100644 index 0000000..14891ca --- /dev/null +++ b/MCUME_teensy41/teensy800/atari.h @@ -0,0 +1,102 @@ +#ifndef __ATARI__ +#define __ATARI__ + +// define globals +#define MEMORY_SIZE 0xC000 //0x10000 + +#define ATARI_WIDTH 384 +#define ATARI_HEIGHT 240 +#define TV_PAL 312 +#define TV_NTSC 262 + +//#define DIRTYRECT 1 +//#define WORDS_UNALIGNED_OK 1 +//#define ALTERNATE_LOOP_COUNTERS 1 +//#define NEW_CYCLE_EXACT 1 +//#define USE_CURSES 1 +//#define WORDS_BIGENDIAN 1 +//#define SYNCHRONIZED_SOUND 1 +#define CLIP_SOUND 1 +#define STEREO_SOUND 1 +#define POKEYSND_SIGNED_SAMPLES 1 +#define PAGED_MEM 1 +#define SOUND 1 +#define NO_SIMPLE_PAL_BLENDING 1 + +#define max_ypos tv_mode + +extern int tv_mode; +extern unsigned char INPUT_key_consol; + +enum ESCAPE { + ESC_SIOV, +/* + * These are special device escape codes required by the Basic version + */ + ESC_E_OPEN, + ESC_E_CLOSE, + ESC_E_READ, + ESC_E_WRITE, + ESC_E_STATUS, + ESC_E_SPECIAL, + + ESC_K_OPEN, + ESC_K_CLOSE, + ESC_K_READ, + ESC_K_WRITE, + ESC_K_STATUS, + ESC_K_SPECIAL, +/* + * These are Escape codes for the normal device handlers. + * Some are never used and some are only sometimes used. + */ + + ESC_PHOPEN = 0xb0, + ESC_PHCLOS = 0xb1, + ESC_PHREAD = 0xb2, + ESC_PHWRIT = 0xb3, + ESC_PHSTAT = 0xb4, + ESC_PHSPEC = 0xb5, + ESC_PHINIT = 0xb6, + + ESC_HHOPEN = 0xc0, + ESC_HHCLOS = 0xc1, + ESC_HHREAD = 0xc2, + ESC_HHWRIT = 0xc3, + ESC_HHSTAT = 0xc4, + ESC_HHSPEC = 0xc5, + ESC_HHINIT = 0xc6, + ESC_BREAK = 0xff +}; + +#ifndef _TYPEDEF_H +#define _TYPEDEF_H + +//data types +#define UBYTE unsigned char +#define UWORD unsigned short +#define ULONG unsigned int + +#define SBYTE signed char +#define SWORD signed short +#define SLONG signed int + +#define int8 char +#define int16 short +#define int32 int + +#define uint8 unsigned int8 +#define uint16 unsigned int16 +#define uint32 unsigned int32 +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#endif + + + +#endif diff --git a/MCUME_teensy41/teensy800/atari800.c b/MCUME_teensy41/teensy800/atari800.c new file mode 100644 index 0000000..3e661e4 --- /dev/null +++ b/MCUME_teensy41/teensy800/atari800.c @@ -0,0 +1,564 @@ +#include "atari800.h" +#include +#include "memory.h" +#include "cpu.h" +#include "atari.h" +#include "akey.h" +#include "pokey.h" +#include +//#include "romatariosa.h" +#include "romatariosb.h" +//#include "romatarixl.h" +#include "antic.h" +#include "gtia.h" +#include "pia.h" +#include "colours.h" +#include "emuapi.h" +#if HAS_SND +#include "pokeysnd.h" +#endif + + +// Controllers +typedef struct +{ + // All values are 1 or 0, or perhaps not... + int left; + int right; + int up; + int down; + int trig; + +} CONTROLLER; + + +// global variables +EXTMEM static unsigned char MemPool[8*1024*1024]; +unsigned char * memory=&MemPool[0]; +int tv_mode = TV_PAL; +UBYTE INPUT_key_consol; + + +// local variables +static CONTROLLER cont1, cont2; +static int INPUT_key_code = AKEY_NONE; +static int INPUT_key_shift = 0; + +/* MEMORY MAP INDEX (0 is invalid) +* 0-3FFF RAM (read/write) +* 4000-7FFF RAM (read/write) +* 8000-9FFF BASIC right CART 8K +* A000-BFFF BASIC left CART 8K +* D000-D0FF GTIA regs +* D200-D2FF POKEY regs +* D300-D3FF PIA regs +* D400-D4FF ANTIC regs +* D800-FFFF OS ROM (ro) +* E000 I/O expansion +*/ + + +// memory CPU read (load) handler +uint8 Atari_GetByte(uint16 addr) +{ + if (addr < MEMORY_SIZE) { // MAPPER_RAM + return(memory[addr]); + } + else if ( (addr >= 0xD000) && (addr < 0xD100) ) { // MAPPER_GTIA + return GTIA_GetByte(addr,1); + } + else if ( (addr >= 0xD200) && (addr < 0xD300) ) { // MAPPER_POKEY + return POKEY_GetByte(addr,1); + } + else if ( (addr >= 0xD300) && (addr < 0xD400) ) { // MAPPER_PIA + return PIA_GetByte(addr); + } + else if ( (addr >= 0xD400) && (addr < 0xD500) ) { // MAPPER_ANTIC + return ANTIC_GetByte(addr,1); + } + else if ((addr >= 0xD800) && (addr < 0x10000)) { // MAPPER_ROM (bios) + //return(memory[addr]); + return(romos[addr-0xD800]); + } + + //case MAPPER_IOEXP: // I/O exp read + // return IOEXPread(addr); + + return 0xff; +} + +// memory CPU write (store) handler +void Atari_PutByte(uint16 addr, uint8 byte) +{ + if (addr < 0x8000) { // MAPPER_RAM + memory[addr] = byte; + } + else if (addr < 0xC000) { // MAPPER_ROM + } + else if ( (addr >= 0xD000) && (addr < 0xD100) ) { // MAPPER_GTIA + GTIA_PutByte(addr, byte); + } + else if ( (addr >= 0xD200) && (addr < 0xD300) ) { // MAPPER_POKEY + POKEY_PutByte(addr, byte); + } + else if ( (addr >= 0xD300) && (addr < 0xD400) ) { // MAPPER_PIA + PIA_PutByte(addr, byte); + } + else if ( (addr >= 0xD400) && (addr < 0xD500) ) { // MAPPER_ANTIC + ANTIC_PutByte(addr, byte); + } + + //case MAPPER_IOEXP: // I/O exp write + // IOEXPwrite(addr, byte); +} + + +static void INPUT_Frame(void) +{ + int i; + static int last_key_code = AKEY_NONE; + static int last_key_break = 0; + + if (cont1.trig) GTIA_TRIG[0]=0; else GTIA_TRIG[0]=1; + + + i = (INPUT_key_code == AKEY_BREAK); + if (i && !last_key_break) { + if (POKEY_IRQEN & 0x80) { + POKEY_IRQST &= ~0x80; + CPU_GenerateIRQ(); + } + } + last_key_break = i; + POKEY_SKSTAT |= 0xc; + if (INPUT_key_shift) + POKEY_SKSTAT &= ~8; + + if (INPUT_key_code < 0) { + //if (CASSETTE_press_space) { + // INPUT_key_code = AKEY_SPACE; + // CASSETTE_press_space = 0; + //} + //else { + last_key_code = AKEY_NONE; + //} + } + if ((INPUT_key_code&~0x17) == AKEY_SHFTCTRL) { + INPUT_key_code = AKEY_NONE; + } + if (INPUT_key_code >= 0) { +//emu_printi(INPUT_key_code); + POKEY_SKSTAT &= ~4; + if ((INPUT_key_code ^ last_key_code) & ~AKEY_SHFTCTRL) { + /* ignore if only shift or control has changed its state */ + last_key_code = INPUT_key_code; + POKEY_KBCODE = (UBYTE) INPUT_key_code; + if (POKEY_IRQEN & 0x40) { + if (POKEY_IRQST & 0x40) { + POKEY_IRQST &= ~0x40; + CPU_GenerateIRQ(); + } + else { + /* keyboard over-run */ + POKEY_SKSTAT &= ~0x40; + /* assert(CPU_IRQ != 0); */ + } + } + } + } +} + +// check keyboard and set kbcode on VBI (not for A800) +void INPUT_Scanline(void) +{ +// if (cont1.trig) GTIA_TRIG[0]=0; else GTIA_TRIG[0]=1; +} + + +static void load_CART(char * cartname) +{ + int flen = emu_FileSize(cartname); + int f = emu_FileOpen(cartname, "r+b"); + if (flen < 16384) { + //emu_FileRead(&memory[0xA000], flen, f); + emu_printf("8k"); + for(int i=0; i +/* 0x3F */ 102, // ? +/* 0x40 */ 117, // @ +/* 0x41 */ INV_KEY, // A +/* 0x42 */ INV_KEY, // B +/* 0x43 */ INV_KEY, // C +/* 0x44 */ INV_KEY, // D +/* 0x45 */ INV_KEY, // E +/* 0x46 */ INV_KEY, // F +/* 0x47 */ INV_KEY, // G +/* 0x48 */ INV_KEY, // H +/* 0x49 */ INV_KEY, // I +/* 0x4A */ INV_KEY, // J +/* 0x4B */ INV_KEY, // K +/* 0x4C */ INV_KEY, // L +/* 0x4D */ INV_KEY, // M +/* 0x4E */ INV_KEY, // N +/* 0x4F */ INV_KEY, // O +/* 0x50 */ INV_KEY, // P +/* 0x51 */ INV_KEY, // Q +/* 0x52 */ INV_KEY, // R +/* 0x53 */ INV_KEY, // S +/* 0x54 */ INV_KEY, // T +/* 0x55 */ INV_KEY, // U +/* 0x56 */ INV_KEY, // V +/* 0x57 */ INV_KEY, // W +/* 0x58 */ INV_KEY, // X +/* 0x59 */ INV_KEY, // Y +/* 0x5A */ INV_KEY, // Z +/* 0x5B */ INV_KEY, // square bracket open +/* 0x5C */ INV_KEY, // backslach +/* 0x5D */ INV_KEY, // square braquet close +/* 0x5E */ INV_KEY, // ^ circonflex +/* 0x5F */ INV_KEY, // _ undescore +/* 0x60 */ INV_KEY, // `backquote +/* 0x61 */ 0x3F, // a +/* 0x62 */ 0x15, // b +/* 0x63 */ 0x12, // c +/* 0x64 */ 0x3A, // d +/* 0x65 */ 0x2A, // e +/* 0x66 */ 0x38, // f +/* 0x67 */ 0x3D, // g +/* 0x68 */ 0x39, // h +/* 0x69 */ 0x0D, // i +/* 0x6A */ 0x01, // j +/* 0x6B */ 0x05, // k +/* 0x6C */ 0x00, // l +/* 0x6D */ 0x25, // m +/* 0x6E */ 0x23, // n +/* 0x6F */ 0x08, // o +/* 0x70 */ 0x0A, // p +/* 0x71 */ 0x2F, // q +/* 0x72 */ 0x28, // r +/* 0x73 */ 0x3E, // s +/* 0x74 */ 0x2D, // t +/* 0x75 */ 0x0B, // u +/* 0x76 */ 0x10, // v +/* 0x77 */ 0x2E, // w +/* 0x78 */ 0x15, // x +/* 0x79 */ 0x2B, // y +/* 0x7A */ 0x17, // z +/* 0x7B */ INV_KEY, // curly bracket open +/* 0x7C */ INV_KEY, // or +/* 0x7D */ INV_KEY, // curly bracket close +/* 0x7E */ INV_KEY, // tilt +/* 0x7F */ 0x34, // backspace + +/* 0xC0 */ INV_KEY, +/* 0xC1 */ INV_KEY, +/* 0xC2 */ INV_KEY, // F1 +/* 0xC3 */ INV_KEY, // F2 +/* 0xC4 */ INV_KEY, // F3 +/* 0xC5 */ INV_KEY, // F4 +/* 0xC6 */ INV_KEY, // F5 +/* 0xC7 */ INV_KEY, // F6 +/* 0xC8 */ INV_KEY, // F7 +/* 0xC9 */ INV_KEY, // F8 +/* 0xCA */ INV_KEY, // F9 +/* 0xCB */ INV_KEY, // F10 +/* 0xCC */ INV_KEY, +/* 0xCD */ INV_KEY, +/* 0xCE */ INV_KEY, +/* 0xCF */ INV_KEY, +/* 0xD0 */ INV_KEY, +/* 0xD1 */ INV_KEY, +/* 0xD2 */ INV_KEY, +/* 0xD3 */ INV_KEY, +/* 0xD4 */ INV_KEY, // DEL +/* 0xD5 */ INV_KEY, +/* 0xD6 */ INV_KEY, +/* 0xD7 */ INV_KEY, // U +/* 0xD8 */ INV_KEY, // L +/* 0xD9 */ INV_KEY, // R +/* 0xDA */ INV_KEY, // D +/* 0xDB */ INV_KEY, +/* 0xDC */ INV_KEY, +/* 0xDD */ INV_KEY, +/* 0xDE */ INV_KEY, +/* 0xDF */ INV_KEY +}; + + +static int ik; // joypad key +static int ihk; // I2C keyboard key +static int iusbhk; // USB keyboard key +static int prevhk; // previous keyboard key + +void emu_KeyboardOnDown(int keymodifer, int key) { + int keyCode = -1; //INV_KEY; + if ((key >=0xc0) && (key <=0xdf)) { + keyCode = ((key-0xc0) & 0x1f) + 0x80; + } + else { + keyCode = key & 0x7f; + } + + //emu_printh(key); + //emu_printh(keyCode); + + if (keyCode != -1) { + iusbhk = keyCode; + } +} + +void emu_KeyboardOnUp(int keymodifer, int key) { + iusbhk = 0; +} + +void at8_Input(int click) { + ik = emu_GetPad(); + ihk = emu_ReadI2CKeyboard(); +} + +void at8_Init(void) +{ + int i; + + // Palette + for (i = 0; i < PALETTE_SIZE; i++) + { + emu_SetPaletteEntry(R32(colourtable[i]), G32(colourtable[i]), B32(colourtable[i]), i); + } + +#if HAS_SND + emu_sndInit(); + POKEYSND_Init(POKEYSND_FREQ_17_APPROX, 44100, 1, POKEYSND_BIT16); +#endif + + emu_printf("Allocating RAM"); + if (memory == NULL) memory = emu_Malloc(MEMORY_SIZE); + + Initialise(); +} + + + +void at8_Step(void) +{ + int k = ik; + int hk = ihk; + if (iusbhk) hk = iusbhk; + + CONTROLLER * which; + + if (k & 0x8000) which=&cont2; + else which=&cont1; + + // Start + if (k & MASK_KEY_USER1) + INPUT_key_consol &= ~0x01; + else + INPUT_key_consol |= 0x01; + + // Select + if (k & MASK_KEY_USER2) + INPUT_key_consol &= ~0x02; + else + INPUT_key_consol |= 0x02; + + // OPTION + if (k & MASK_KEY_USER3) + INPUT_key_consol &= ~0x04; + else + INPUT_key_consol |= 0x04; + + if (hk != 0) { + int key = keyboardAsciiConv[hk]; + if (key != INV_KEY) INPUT_key_code = key; + } + else { + INPUT_key_code = AKEY_NONE; + } + + // Keyboard + INPUT_Frame(); + + // Joystick side button, trigger and directions + if (k & MASK_JOY2_BTN) + which->trig = 1; + else + which->trig = 0; + if (k & MASK_JOY2_DOWN) + which->down = 1; + else + which->down = 0; + if (k & MASK_JOY2_UP) + which->up = 1; + else + which->up = 0; + if (k & MASK_JOY2_RIGHT) + which->left = 1; + else + which->left = 0; + if (k & MASK_JOY2_LEFT) + which->right = 1; + else + which->right = 0; + + GTIA_Frame(); + ANTIC_Frame(1); + emu_DrawVsync(); + POKEY_Frame(); +} + + + +void at8_Start(char * cartname) +{ + load_CART(cartname); + + emu_printf("antic"); + ANTIC_Initialise(); + emu_printf("gtia"); + GTIA_Initialise(); + emu_printf("pia"); + PIA_Initialise(); + emu_printf("pokey"); + POKEY_Initialise(); + PORTA = 0x00; + ANTIC_NMIEN = 0x00; + ANTIC_NMIST = 0x00; + memory[0x244] = 1; + GTIA_TRIG[0]=1; + GTIA_TRIG[1]=1; + GTIA_TRIG[2]=1; + GTIA_TRIG[3]=1; + emu_printf("6502 reset"); + CPU_Reset(); + + emu_printf("init done"); +} diff --git a/MCUME_teensy41/teensy800/atari800.h b/MCUME_teensy41/teensy800/atari800.h new file mode 100644 index 0000000..35f4820 --- /dev/null +++ b/MCUME_teensy41/teensy800/atari800.h @@ -0,0 +1,4 @@ +extern void at8_Init(void); +extern void at8_Step(void); +extern void at8_Start(char * filename); +extern void at8_Input(int click); diff --git a/MCUME_teensy41/teensy800/colours.h b/MCUME_teensy41/teensy800/colours.h new file mode 100644 index 0000000..a31db53 --- /dev/null +++ b/MCUME_teensy41/teensy800/colours.h @@ -0,0 +1,68 @@ +const unsigned int colourtable[256] = +{ + 0x0, 0x1c1c1c, 0x393939, 0x595959, + 0x797979, 0x929292, 0xababab, 0xbcbcbc, + 0xcdcdcd, 0xd9d9d9, 0xe6e6e6, 0xececec, + 0xf2f2f2, 0xf8f8f8, 0xffffff, 0xffffff, + 0x391701, 0x5e2304, 0x833008, 0xa54716, + 0xc85f24, 0xe37820, 0xff911d, 0xffab1d, + 0xffc51d, 0xffce34, 0xffd84c, 0xffe651, + 0xfff456, 0xfff977, 0xffff98, 0xffff98, + 0x451904, 0x721e11, 0x9f241e, 0xb33a20, + 0xc85122, 0xe36920, 0xff811e, 0xff8c25, + 0xff982c, 0xffae38, 0xffc545, 0xffc559, + 0xffc66d, 0xffd587, 0xffe4a1, 0xffe4a1, + 0x4a1704, 0x7e1a0d, 0xb21d17, 0xc82119, + 0xdf251c, 0xec3b38, 0xfa5255, 0xfc6161, + 0xff706e, 0xff7f7e, 0xff8f8f, 0xff9d9e, + 0xffabad, 0xffb9bd, 0xffc7ce, 0xffc7ce, + 0x50568, 0x3b136d, 0x712272, 0x8b2a8c, + 0xa532a6, 0xb938ba, 0xcd3ecf, 0xdb47dd, + 0xea51eb, 0xf45ff5, 0xfe6dff, 0xfe7afd, + 0xff87fb, 0xff95fd, 0xffa4ff, 0xffa4ff, + 0x280479, 0x400984, 0x590f90, 0x70249d, + 0x8839aa, 0xa441c3, 0xc04adc, 0xd054ed, + 0xe05eff, 0xe96dff, 0xf27cff, 0xf88aff, + 0xff98ff, 0xfea1ff, 0xfeabff, 0xfeabff, + 0x35088a, 0x420aad, 0x500cd0, 0x6428d0, + 0x7945d0, 0x8d4bd4, 0xa251d9, 0xb058ec, + 0xbe60ff, 0xc56bff, 0xcc77ff, 0xd183ff, + 0xd790ff, 0xdb9dff, 0xdfaaff, 0xdfaaff, + 0x51e81, 0x626a5, 0x82fca, 0x263dd4, + 0x444cde, 0x4f5aee, 0x5a68ff, 0x6575ff, + 0x7183ff, 0x8091ff, 0x90a0ff, 0x97a9ff, + 0x9fb2ff, 0xafbeff, 0xc0cbff, 0xc0cbff, + 0xc048b, 0x2218a0, 0x382db5, 0x483ec7, + 0x584fda, 0x6159ec, 0x6b64ff, 0x7a74ff, + 0x8a84ff, 0x918eff, 0x9998ff, 0xa5a3ff, + 0xb1aeff, 0xb8b8ff, 0xc0c2ff, 0xc0c2ff, + 0x1d295a, 0x1d3876, 0x1d4892, 0x1c5cac, + 0x1c71c6, 0x3286cf, 0x489bd9, 0x4ea8ec, + 0x55b6ff, 0x70c7ff, 0x8cd8ff, 0x93dbff, + 0x9bdfff, 0xafe4ff, 0xc3e9ff, 0xc3e9ff, + 0x2f4302, 0x395202, 0x446103, 0x417a12, + 0x3e9421, 0x4a9f2e, 0x57ab3b, 0x5cbd55, + 0x61d070, 0x69e27a, 0x72f584, 0x7cfa8d, + 0x87ff97, 0x9affa6, 0xadffb6, 0xadffb6, + 0xa4108, 0xd540a, 0x10680d, 0x137d0f, + 0x169212, 0x19a514, 0x1cb917, 0x1ec919, + 0x21d91b, 0x47e42d, 0x6ef040, 0x78f74d, + 0x83ff5b, 0x9aff7a, 0xb2ff9a, 0xb2ff9a, + 0x4410b, 0x5530e, 0x66611, 0x77714, + 0x88817, 0x99b1a, 0xbaf1d, 0x48c41f, + 0x86d922, 0x8fe924, 0x99f927, 0xa8fc41, + 0xb7ff5b, 0xc9ff6e, 0xdcff81, 0xdcff81, + 0x2350f, 0x73f15, 0xc4a1c, 0x2d5f1e, + 0x4f7420, 0x598324, 0x649228, 0x82a12e, + 0xa1b034, 0xa9c13a, 0xb2d241, 0xc4d945, + 0xd6e149, 0xe4f04e, 0xf2ff53, 0xf2ff53, + 0x263001, 0x243803, 0x234005, 0x51541b, + 0x806931, 0x978135, 0xaf993a, 0xc2a73e, + 0xd5b543, 0xdbc03d, 0xe1cb38, 0xe2d836, + 0xe3e534, 0xeff258, 0xfbff7d, 0xfbff7d, + 0x401a02, 0x581f05, 0x702408, 0x8d3a13, + 0xab511f, 0xb56427, 0xbf7730, 0xd0853a, + 0xe19344, 0xeda04e, 0xf9ad58, 0xfcb75c, + 0xffc160, 0xffc671, 0xffcb83, 0xffcb83, +}; + diff --git a/MCUME_teensy41/teensy800/cpu.c b/MCUME_teensy41/teensy800/cpu.c new file mode 100644 index 0000000..cc73b28 --- /dev/null +++ b/MCUME_teensy41/teensy800/cpu.c @@ -0,0 +1,2444 @@ +/* + * cpu.c - 6502 CPU emulation + * + * Copyright (C) 1995-1998 David Firth + * Copyright (C) 1998-2005 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Atari800 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + Configuration symbols + ===================== + + Define CPU65C02 if you don't want 6502 JMP() bug emulation. + Define CYCLES_PER_OPCODE to update ANTIC_xpos in each opcode's emulation. + Define MONITOR_BREAK if you want code breakpoints and execution history. + Define MONITOR_BREAKPOINTS if you want user-defined breakpoints. + Define MONITOR_PROFILE if you want 6502 opcode profiling. + Define MONITOR_TRACE if you want the code to be disassembled while it is executed. + Define NO_GOTO if you compile with GCC, but want switch() rather than goto *. + Define NO_V_FLAG_VARIABLE to don't use local (static) variable V for the V flag. + Define PC_PTR to emulate 6502 Program Counter using UBYTE *. + Define PREFETCH_CODE to always fetch 2 bytes after the opcode. + Define WRAP_64K to correctly emulate instructions that wrap at 64K. + Define WRAP_ZPAGE to prevent incorrect access to the address 0x0100 in zeropage + indirect mode. + + + Limitations & Known bugs + ======================== + + There is no emulation of the bug in the BRK instruction executed simultaneously + with another interrupt. + + The 6502 emulation ignores memory attributes for instruction fetch. + This is because the instruction must come from either RAM or ROM. + A program that executes instructions from within hardware addresses will fail + since there is never any usable code there. + + The 6502 emulation also ignores memory attributes for accesses to page 0 and page 1. + */ + + +#ifdef SKIP +#include "config.h" +#include +#include /* exit() */ + +#include "cpu.h" +#ifdef ASAP /* external project, see http://asap.sf.net */ +#include "asap_internal.h" +#else +#include "antic.h" +#include "atari.h" +#include "esc.h" +#include "memory.h" +#include "monitor.h" +#ifndef BASIC +#include "statesav.h" +#ifndef __PLUS +#include "ui.h" +#endif +#endif /* BASIC */ +#endif /* ASAP */ +#else + +#include +#include /* exit() */ +#include "cpu.h" +#include "antic.h" +#include "memory.h" + +#define ESC_Run(x) + +#endif + + +/* For Atari Basic loader */ +void (*CPU_rts_handler)(void) = NULL; + +/* 6502 instruction profiling */ +#ifdef MONITOR_PROFILE +int CPU_instruction_count[256]; +#endif + +/* Execution history */ +#ifdef MONITOR_BREAK +UWORD CPU_remember_PC[CPU_REMEMBER_PC_STEPS]; +UBYTE CPU_remember_op[CPU_REMEMBER_PC_STEPS][3]; +unsigned int CPU_remember_PC_curpos = 0; +int CPU_remember_xpos[CPU_REMEMBER_PC_STEPS]; +UWORD CPU_remember_JMP[CPU_REMEMBER_JMP_STEPS]; +unsigned int CPU_remember_jmp_curpos = 0; +#define INC_RET_NESTING MONITOR_ret_nesting++ +#else /* MONITOR_BREAK */ +#define INC_RET_NESTING +#endif /* MONITOR_BREAK */ + +UBYTE CPU_cim_encountered = FALSE; +UBYTE CPU_IRQ; + +#ifdef FALCON_CPUASM + +#if defined(PAGED_MEM) || defined(PAGED_ATTRIB) +#error cpu_m68k.asm cannot work with paged memory/attributes +#endif + +#if defined(MONITOR_BREAKPOINTS) +#error cpu_m68k.asm does not support user-defined breakpoints +#endif + +#if defined(MONITOR_TRACE) +#error cpu_m68k.asm does not support disassembling the code while it is executed +#endif + +#else /* FALCON_CPUASM */ + +/* Windows headers define it */ +#undef ABSOLUTE + +#ifndef __GNUC__ +#define NO_GOTO +#endif + +/* #define CYCLES_PER_OPCODE */ + +/* #define MONITOR_PROFILE */ + +/* #define NO_V_FLAG_VARIABLE */ + +/* If PC_PTR is defined, local PC is "const UBYTE *", otherwise it's UWORD. */ +/* #define PC_PTR */ + +/* If PREFETCH_CODE is defined, 2 bytes after the opcode are always fetched. */ +/* #define PREFETCH_CODE */ + + +/* 6502 stack handling */ +#define PL MEMORY_dGetByte(0x0100 + ++S) +#define PH(x) MEMORY_dPutByte(0x0100 + S--, x) +#define PHW(x) PH((x) >> 8); PH((x) & 0xff) + +/* 6502 code fetching */ +#ifdef PC_PTR +#define GET_PC() (PC - MEMORY_mem) +#define SET_PC(newpc) (PC = MEMORY_mem + (newpc)) +#define PHPC { UWORD tmp = PC - MEMORY_mem; PHW(tmp); } +#define GET_CODE_BYTE() (*PC++) +#define PEEK_CODE_BYTE() (*PC) +#if !defined(WORDS_BIGENDIAN) && defined(WORDS_UNALIGNED_OK) +#define PEEK_CODE_WORD() (*(const UWORD *) PC) +#else +#define PEEK_CODE_WORD() (*PC + (PC[1] << 8)) +#endif +#else /* PC_PTR */ +#define GET_PC() PC +#define SET_PC(newpc) (PC = (newpc)) +#define PHPC PHW(PC) +#define GET_CODE_BYTE() MEMORY_dGetByte(PC++) +#define PEEK_CODE_BYTE() MEMORY_dGetByte(PC) +#define PEEK_CODE_WORD() MEMORY_dGetWord(PC) +#endif /* PC_PTR */ + +/* Cycle-exact Read-Modify-Write instructions. + RMW instructions: ASL, LSR, ROL, ROR, INC, DEC + (+ some undocumented) write to the specified address + *twice*: first the unmodified value, then the modified value. + This can be observed only with some hardware registers. */ +/* XXX: we do this only for GTIA, because NEW_CYCLE_EXACT does not correctly + emulate INC $D400 (and INC $D40A wasn't tested) */ +#ifdef NEW_CYCLE_EXACT +#ifndef PAGED_ATTRIB +#define RMW_GetByte(x, addr) \ + if (MEMORY_attrib[addr] == MEMORY_HARDWARE) { \ + x = MEMORY_HwGetByte(addr, FALSE); \ + if ((addr & 0xef00) == 0xc000) { \ + ANTIC_xpos--; \ + MEMORY_HwPutByte(addr, x); \ + ANTIC_xpos++; \ + } \ + } else \ + x = MEMORY_dGetByte(addr); +#else /* PAGED_ATTRIB */ +#define RMW_GetByte(x, addr) \ + x = MEMORY_GetByte(addr); \ + if ((addr & 0xef00) == 0xc000) { \ + ANTIC_xpos--; \ + MEMORY_PutByte(addr, x); \ + ANTIC_xpos++; \ + } +#endif /* PAGED_ATTRIB */ +#else /* NEW_CYCLE_EXACT */ +/* Don't emulate the first write */ +#define RMW_GetByte(x, addr) x = MEMORY_GetByte(addr); +#endif /* NEW_CYCLE_EXACT */ + +/* 6502 registers. */ +UWORD CPU_regPC; +UBYTE CPU_regA; +UBYTE CPU_regX; +UBYTE CPU_regY; +UBYTE CPU_regP; /* Processor Status Byte (Partial) */ +UBYTE CPU_regS; + +/* Transfer 6502 registers between global variables and local variables inside CPU_GO() */ +#define UPDATE_GLOBAL_REGS CPU_regPC = GET_PC(); CPU_regS = S; CPU_regA = A; CPU_regX = X; CPU_regY = Y +#define UPDATE_LOCAL_REGS SET_PC(CPU_regPC); S = CPU_regS; A = CPU_regA; X = CPU_regX; Y = CPU_regY + +/* 6502 flags local to this module */ +static UBYTE N; /* bit7 set => N flag set */ +#ifndef NO_V_FLAG_VARIABLE +static UBYTE V; /* non-zero => V flag set */ +#endif +static UBYTE Z; /* zero => Z flag set */ +static UBYTE C; /* must be 0 or 1 */ +/* B, D, I are always in CPU_regP */ + +void CPU_GetStatus(void) +{ +#ifndef NO_V_FLAG_VARIABLE + CPU_regP = (N & 0x80) + (V ? 0x40 : 0) + (CPU_regP & 0x3c) + ((Z == 0) ? 0x02 : 0) + C; +#else + CPU_regP = (N & 0x80) + (CPU_regP & 0x7c) + ((Z == 0) ? 0x02 : 0) + C; +#endif +} + +void CPU_PutStatus(void) +{ + N = CPU_regP; +#ifndef NO_V_FLAG_VARIABLE + V = (CPU_regP & 0x40); +#endif + Z = (CPU_regP & 0x02) ^ 0x02; + C = (CPU_regP & 0x01); +} + +/* Addressing modes */ +#ifdef WRAP_ZPAGE +#define zGetWord(x) (MEMORY_dGetByte(x) + (MEMORY_dGetByte((UBYTE) ((x) + 1)) << 8)) +#else +#define zGetWord(x) MEMORY_dGetWord(x) +#endif +#ifdef PREFETCH_CODE +#if defined(WORDS_BIGENDIAN) || !defined(WORDS_UNALIGNED_OK) +#warning PREFETCH_CODE is efficient only on little-endian machines with WORDS_UNALIGNED_OK +#endif +#define OP_BYTE ((UBYTE) addr) +#define OP_WORD addr +#define IMMEDIATE (PC++, (UBYTE) addr) +#define ABSOLUTE PC += 2 +#define ZPAGE PC++; addr &= 0xff +#define ABSOLUTE_X addr += X; PC += 2 +#define ABSOLUTE_Y addr += Y; PC += 2 +#define INDIRECT_X PC++; addr = (UBYTE) (addr + X); addr = zGetWord(addr) +#define INDIRECT_Y PC++; addr &= 0xff; addr = zGetWord(addr) + Y +#define ZPAGE_X PC++; addr = (UBYTE) (addr + X) +#define ZPAGE_Y PC++; addr = (UBYTE) (addr + Y) +#else /* PREFETCH_CODE */ +#define OP_BYTE PEEK_CODE_BYTE() +#define OP_WORD PEEK_CODE_WORD() +#define IMMEDIATE GET_CODE_BYTE() +#define ABSOLUTE addr = PEEK_CODE_WORD(); PC += 2 +#define ZPAGE addr = GET_CODE_BYTE() +#define ABSOLUTE_X addr = PEEK_CODE_WORD() + X; PC += 2 +#define ABSOLUTE_Y addr = PEEK_CODE_WORD() + Y; PC += 2 +#define INDIRECT_X addr = (UBYTE) (GET_CODE_BYTE() + X); addr = zGetWord(addr) +#define INDIRECT_Y addr = GET_CODE_BYTE(); addr = zGetWord(addr) + Y +#define ZPAGE_X addr = (UBYTE) (GET_CODE_BYTE() + X) +#define ZPAGE_Y addr = (UBYTE) (GET_CODE_BYTE() + Y) +#endif /* PREFETCH_CODE */ + +/* Instructions */ +#define AND(t_data) Z = N = A &= t_data +#define CMP(t_data) data = t_data; Z = N = A - data; C = (A >= data) +#define CPX(t_data) data = t_data; Z = N = X - data; C = (X >= data) +#define CPY(t_data) data = t_data; Z = N = Y - data; C = (Y >= data) +#define EOR(t_data) Z = N = A ^= t_data +#define LDA(t_data) Z = N = A = t_data +#define LDX(t_data) Z = N = X = t_data +#define LDY(t_data) Z = N = Y = t_data +#define ORA(t_data) Z = N = A |= t_data +#ifndef NO_V_FLAG_VARIABLE +#define PHP(x) data = (N & 0x80) + (V ? 0x40 : 0) + (CPU_regP & (x)) + ((Z == 0) ? 0x02 : 0) + C; PH(data) +#define PHPB0 PHP(0x2c) /* push flags with B flag clear (NMI, IRQ) */ +#define PHPB1 PHP(0x3c) /* push flags with B flag set (PHP, BRK) */ +#define PLP data = PL; N = data; V = (data & 0x40); Z = (data & 0x02) ^ 0x02; C = (data & 0x01); CPU_regP = (data & 0x0c) + 0x30 +#else /* NO_V_FLAG_VARIABLE */ +#define PHP(x) data = (N & 0x80) + (CPU_regP & (x)) + ((Z == 0) ? 0x02 : 0) + C; PH(data) +#define PHPB0 PHP(0x6c) /* push flags with B flag clear (NMI, IRQ) */ +#define PHPB1 PHP(0x7c) /* push flags with B flag set (PHP, BRK) */ +#define PLP data = PL; N = data; Z = (data & 0x02) ^ 0x02; C = (data & 0x01); CPU_regP = (data & 0x4c) + 0x30 +#endif /* NO_V_FLAG_VARIABLE */ +/* 1 or 2 extra cycles for conditional jumps */ +#if 0 +/* old, less efficient version */ +#define BRANCH(cond) \ + if (cond) { \ + SWORD sdata = (SBYTE) GET_CODE_BYTE(); \ + if ((sdata + (UBYTE) GET_PC()) & 0xff00) \ + ANTIC_xpos++; \ + ANTIC_xpos++; \ + PC += sdata; \ + DONE \ + } \ + PC++; \ + DONE +#else +#define BRANCH(cond) \ + if (cond) { \ + addr = (UWORD) (SBYTE) IMMEDIATE; \ + addr += GET_PC(); \ + if ((addr ^ GET_PC()) & 0xff00) \ + ANTIC_xpos++; \ + ANTIC_xpos++; \ + SET_PC(addr); \ + DONE \ + } \ + PC++; \ + DONE +#endif + +/* 1 extra cycle for X (or Y) index overflow */ +#define NCYCLES_X if ((UBYTE) addr < X) ANTIC_xpos++ +#define NCYCLES_Y if ((UBYTE) addr < Y) ANTIC_xpos++ + +/* Triggers a Non-Maskable Interrupt */ +void CPU_NMI(void) +{ + UBYTE S = CPU_regS; + UBYTE data; + + PHW(CPU_regPC); + PHPB0; + CPU_SetI; + CPU_regPC = MEMORY_dGetWordAligned(0xfffa); + CPU_regS = S; + ANTIC_xpos += 7; /* handling an interrupt by 6502 takes 7 cycles */ + INC_RET_NESTING; +} + +/* Check pending IRQ, helps in (not only) Lucasfilm games */ +#define CPUCHECKIRQ \ + if (CPU_IRQ && !(CPU_regP & CPU_I_FLAG) && ANTIC_xpos < ANTIC_xpos_limit) { \ + PHPC; \ + PHPB0; \ + CPU_SetI; \ + SET_PC(MEMORY_dGetWordAligned(0xfffe)); \ + ANTIC_xpos += 7; \ + INC_RET_NESTING; \ + } + +/* Enter monitor */ +#ifdef __PLUS +#define ENTER_MONITOR Atari800_Exit(TRUE) +#else +#ifdef SKIP +#define ENTER_MONITOR if (!Atari800_Exit(TRUE)) exit(0) +#else +#define ENTER_MONITOR exit(0) +#endif +#endif +#define DO_BREAK \ + UPDATE_GLOBAL_REGS; \ + CPU_GetStatus(); \ + ENTER_MONITOR; \ + CPU_PutStatus(); \ + UPDATE_LOCAL_REGS; + + +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ +static const int cycles[256] = +{ + 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, /* 0x */ + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 1x */ + 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, /* 2x */ + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 3x */ + + 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, /* 4x */ + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 5x */ + 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, /* 6x */ + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 7x */ + + 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* 8x */ + 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, /* 9x */ + 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* Ax */ + 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, /* Bx */ + + 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* Cx */ + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* Dx */ + 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* Ex */ + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 /* Fx */ +}; + +/* 6502 emulation routine */ +#ifndef NO_GOTO +__extension__ /* suppress -ansi -pedantic warnings */ +#endif +void CPU_GO(int limit) +{ +#ifdef NO_GOTO +#define OPCODE_ALIAS(code) case 0x##code: +#define DONE break; +#else +#define OPCODE_ALIAS(code) opcode_##code: +#define DONE goto next; + static const void *opcode[256] = + { + &&opcode_00, &&opcode_01, &&opcode_02, &&opcode_03, + &&opcode_04, &&opcode_05, &&opcode_06, &&opcode_07, + &&opcode_08, &&opcode_09, &&opcode_0a, &&opcode_0b, + &&opcode_0c, &&opcode_0d, &&opcode_0e, &&opcode_0f, + + &&opcode_10, &&opcode_11, &&opcode_12, &&opcode_13, + &&opcode_14, &&opcode_15, &&opcode_16, &&opcode_17, + &&opcode_18, &&opcode_19, &&opcode_1a, &&opcode_1b, + &&opcode_1c, &&opcode_1d, &&opcode_1e, &&opcode_1f, + + &&opcode_20, &&opcode_21, &&opcode_22, &&opcode_23, + &&opcode_24, &&opcode_25, &&opcode_26, &&opcode_27, + &&opcode_28, &&opcode_29, &&opcode_2a, &&opcode_2b, + &&opcode_2c, &&opcode_2d, &&opcode_2e, &&opcode_2f, + + &&opcode_30, &&opcode_31, &&opcode_32, &&opcode_33, + &&opcode_34, &&opcode_35, &&opcode_36, &&opcode_37, + &&opcode_38, &&opcode_39, &&opcode_3a, &&opcode_3b, + &&opcode_3c, &&opcode_3d, &&opcode_3e, &&opcode_3f, + + &&opcode_40, &&opcode_41, &&opcode_42, &&opcode_43, + &&opcode_44, &&opcode_45, &&opcode_46, &&opcode_47, + &&opcode_48, &&opcode_49, &&opcode_4a, &&opcode_4b, + &&opcode_4c, &&opcode_4d, &&opcode_4e, &&opcode_4f, + + &&opcode_50, &&opcode_51, &&opcode_52, &&opcode_53, + &&opcode_54, &&opcode_55, &&opcode_56, &&opcode_57, + &&opcode_58, &&opcode_59, &&opcode_5a, &&opcode_5b, + &&opcode_5c, &&opcode_5d, &&opcode_5e, &&opcode_5f, + + &&opcode_60, &&opcode_61, &&opcode_62, &&opcode_63, + &&opcode_64, &&opcode_65, &&opcode_66, &&opcode_67, + &&opcode_68, &&opcode_69, &&opcode_6a, &&opcode_6b, + &&opcode_6c, &&opcode_6d, &&opcode_6e, &&opcode_6f, + + &&opcode_70, &&opcode_71, &&opcode_72, &&opcode_73, + &&opcode_74, &&opcode_75, &&opcode_76, &&opcode_77, + &&opcode_78, &&opcode_79, &&opcode_7a, &&opcode_7b, + &&opcode_7c, &&opcode_7d, &&opcode_7e, &&opcode_7f, + + &&opcode_80, &&opcode_81, &&opcode_82, &&opcode_83, + &&opcode_84, &&opcode_85, &&opcode_86, &&opcode_87, + &&opcode_88, &&opcode_89, &&opcode_8a, &&opcode_8b, + &&opcode_8c, &&opcode_8d, &&opcode_8e, &&opcode_8f, + + &&opcode_90, &&opcode_91, &&opcode_92, &&opcode_93, + &&opcode_94, &&opcode_95, &&opcode_96, &&opcode_97, + &&opcode_98, &&opcode_99, &&opcode_9a, &&opcode_9b, + &&opcode_9c, &&opcode_9d, &&opcode_9e, &&opcode_9f, + + &&opcode_a0, &&opcode_a1, &&opcode_a2, &&opcode_a3, + &&opcode_a4, &&opcode_a5, &&opcode_a6, &&opcode_a7, + &&opcode_a8, &&opcode_a9, &&opcode_aa, &&opcode_ab, + &&opcode_ac, &&opcode_ad, &&opcode_ae, &&opcode_af, + + &&opcode_b0, &&opcode_b1, &&opcode_b2, &&opcode_b3, + &&opcode_b4, &&opcode_b5, &&opcode_b6, &&opcode_b7, + &&opcode_b8, &&opcode_b9, &&opcode_ba, &&opcode_bb, + &&opcode_bc, &&opcode_bd, &&opcode_be, &&opcode_bf, + + &&opcode_c0, &&opcode_c1, &&opcode_c2, &&opcode_c3, + &&opcode_c4, &&opcode_c5, &&opcode_c6, &&opcode_c7, + &&opcode_c8, &&opcode_c9, &&opcode_ca, &&opcode_cb, + &&opcode_cc, &&opcode_cd, &&opcode_ce, &&opcode_cf, + + &&opcode_d0, &&opcode_d1, &&opcode_d2, &&opcode_d3, + &&opcode_d4, &&opcode_d5, &&opcode_d6, &&opcode_d7, + &&opcode_d8, &&opcode_d9, &&opcode_da, &&opcode_db, + &&opcode_dc, &&opcode_dd, &&opcode_de, &&opcode_df, + + &&opcode_e0, &&opcode_e1, &&opcode_e2, &&opcode_e3, + &&opcode_e4, &&opcode_e5, &&opcode_e6, &&opcode_e7, + &&opcode_e8, &&opcode_e9, &&opcode_ea, &&opcode_eb, + &&opcode_ec, &&opcode_ed, &&opcode_ee, &&opcode_ef, + + &&opcode_f0, &&opcode_f1, &&opcode_f2, &&opcode_f3, + &&opcode_f4, &&opcode_f5, &&opcode_f6, &&opcode_f7, + &&opcode_f8, &&opcode_f9, &&opcode_fa, &&opcode_fb, + &&opcode_fc, &&opcode_fd, &&opcode_fe, &&opcode_ff, + }; +#endif /* NO_GOTO */ + +#ifdef CYCLES_PER_OPCODE +#define OPCODE(code) OPCODE_ALIAS(code) ANTIC_xpos += cycles[0x##code]; +#else +#define OPCODE(code) OPCODE_ALIAS(code) +#endif + +#ifdef PC_PTR + const UBYTE *PC; +#else + UWORD PC; +#endif + UBYTE A; + UBYTE X; + UBYTE Y; + UBYTE S; + + UWORD addr; + UBYTE data; +#define insn data + +/* + This used to be in the main loop but has been removed to improve + execution speed. It does not seem to have any adverse effect on + the emulation for two reasons: + + 1. NMI's will can only be raised in antic.c - there is + no way an NMI can be generated whilst in this routine. + + 2. The timing of the IRQs are not that critical. */ + + if (ANTIC_wsync_halt) { + +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { +/* if ANTIC_WSYNC_C is a stolen cycle, ANTIC_antic2cpu_ptr will convert that to the nearest + cpu cycle before that cycle. The CPU will see this cycle, if WSYNC is not + delayed. (Actually this cycle is the first cycle of the instruction after + STA WSYNC, which was really executed one cycle after STA WSYNC because + of an internal antic delay ). ANTIC_delayed_wsync is added to this cycle to form + the limit in the case that WSYNC is not early (does not allow this extra cycle) */ + + if (limit < ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C] + ANTIC_delayed_wsync) + return; + ANTIC_xpos = ANTIC_antic2cpu_ptr[ANTIC_WSYNC_C] + ANTIC_delayed_wsync; + } + else { + if (limit < (ANTIC_WSYNC_C + ANTIC_delayed_wsync)) + return; + ANTIC_xpos = ANTIC_WSYNC_C; + } + ANTIC_delayed_wsync = 0; + +#else /* NEW_CYCLE_EXACT */ + + if (limit < ANTIC_WSYNC_C) + return; + ANTIC_xpos = ANTIC_WSYNC_C; + +#endif /* NEW_CYCLE_EXACT */ + + ANTIC_wsync_halt = 0; + } + ANTIC_xpos_limit = limit; /* needed for WSYNC store inside ANTIC */ + + UPDATE_LOCAL_REGS; + + CPUCHECKIRQ; + + while (ANTIC_xpos < ANTIC_xpos_limit) { +#ifdef MONITOR_PROFILE + int old_xpos = ANTIC_xpos; + UWORD old_PC = GET_PC(); +#endif + + +#ifdef MONITOR_BREAKPOINTS + breakpoint_return: +#endif + +#ifdef PC_PTR + /* must handle 64k wrapping */ + if (PC >= MEMORY_mem + 0xfffe) { + if (PC >= MEMORY_mem + 0x10000) + PC -= 0x10000; + else { + /* the opcode is before 0x10000, but the operand is past */ +#ifdef WORDS_UNALIGNED_OK + *(UWORD *) (MEMORY_mem + 0x10000) = *(UWORD *) MEMORY_mem; +#else + MEMORY_mem[0x10000] = MEMORY_mem[0]; + MEMORY_mem[0x10001] = MEMORY_mem[1]; +#endif /* WORDS_UNALIGNED_OK */ + } + } +#endif /* PC_PTR */ + +#ifdef MONITOR_TRACE + if (MONITOR_trace_file != NULL) { + MONITOR_ShowState(MONITOR_trace_file, GET_PC(), A, X, Y, S, + (N & 0x80) ? 'N' : '-', +#ifndef NO_V_FLAG_VARIABLE + V ? 'V' : '-', +#else + (CPU_regP & CPU_V_FLAG) ? 'V' : '-', +#endif + (Z == 0) ? 'Z' : '-', + (C != 0) ? 'C' : '-'); + } +#endif + +#ifdef MONITOR_BREAK + CPU_remember_PC[CPU_remember_PC_curpos] = GET_PC(); + CPU_remember_op[CPU_remember_PC_curpos][0] = MEMORY_dGetByte(GET_PC()); + CPU_remember_op[CPU_remember_PC_curpos][1] = MEMORY_dGetByte(GET_PC()+1); + CPU_remember_op[CPU_remember_PC_curpos][2] = MEMORY_dGetByte(GET_PC()+2); +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) + CPU_remember_xpos[CPU_remember_PC_curpos] = ANTIC_cpu2antic_ptr[ANTIC_xpos] + (ANTIC_ypos << 8); + else +#endif + CPU_remember_xpos[CPU_remember_PC_curpos] = ANTIC_xpos + (ANTIC_ypos << 8); + CPU_remember_PC_curpos = (CPU_remember_PC_curpos + 1) % CPU_REMEMBER_PC_STEPS; + + if (MONITOR_break_addr == GET_PC() || ANTIC_break_ypos == ANTIC_ypos) { + DO_BREAK; + } +#endif /* MONITOR_BREAK */ + +#if defined(WRAP_64K) && !defined(PC_PTR) + MEMORY_mem[0x10000] = MEMORY_mem[0]; +#endif + + insn = GET_CODE_BYTE(); + +#ifdef MONITOR_BREAKPOINTS +#ifdef MONITOR_BREAK + if (MONITOR_breakpoint_table_size > 0 && MONITOR_breakpoints_enabled && !MONITOR_break_step) +#else + if (MONITOR_breakpoint_table_size > 0 && MONITOR_breakpoints_enabled) +#endif + { + UBYTE optype = MONITOR_optype6502[insn]; + int i; + switch (optype >> 4) { + case 1: + addr = PEEK_CODE_WORD(); + break; + case 2: + addr = PEEK_CODE_BYTE(); + break; + case 3: + addr = PEEK_CODE_WORD() + X; + break; + case 4: + addr = PEEK_CODE_WORD() + Y; + break; + case 5: + addr = (UBYTE) (PEEK_CODE_BYTE() + X); + addr = zGetWord(addr); + break; + case 6: + addr = PEEK_CODE_BYTE(); + addr = zGetWord(addr) + Y; + break; + case 7: + addr = (UBYTE) (PEEK_CODE_BYTE() + X); + break; + case 8: + addr = (UBYTE) (PEEK_CODE_BYTE() + Y); + break; + /* XXX: case 13 */ + default: + addr = 0; + break; + } + for (i = 0; i < MONITOR_breakpoint_table_size; i++) { + int cond; + int value, m_addr; + if (!MONITOR_breakpoint_table[i].enabled) + continue; /* skip */ + cond = MONITOR_breakpoint_table[i].condition; + if (cond == MONITOR_BREAKPOINT_OR) + break; /* fire */ + value = MONITOR_breakpoint_table[i].value; + m_addr = MONITOR_breakpoint_table[i].m_addr; + if (cond == MONITOR_BREAKPOINT_FLAG_CLEAR) { + switch (value) { + case CPU_N_FLAG: + if ((N & 0x80) == 0) + continue; + break; +#ifndef NO_V_FLAG_VARIABLE + case CPU_V_FLAG: + if (V == 0) + continue; + break; +#endif + case CPU_Z_FLAG: + if (Z != 0) + continue; + break; + case CPU_C_FLAG: + if (C == 0) + continue; + break; + default: + if ((CPU_regP & value) == 0) + continue; + break; + } + } + else if (cond == MONITOR_BREAKPOINT_FLAG_SET) { + switch (value) { + case CPU_N_FLAG: + if ((N & 0x80) != 0) + continue; + break; +#ifndef NO_V_FLAG_VARIABLE + case CPU_V_FLAG: + if (V != 0) + continue; + break; +#endif + case CPU_Z_FLAG: + if (Z == 0) + continue; + break; + case CPU_C_FLAG: + if (C != 0) + continue; + break; + default: + if ((CPU_regP & value) != 0) + continue; + break; + } + } + else { + int val; + switch (cond >> 3) { + case MONITOR_BREAKPOINT_PC >> 3: + val = GET_PC() - 1; + break; + case MONITOR_BREAKPOINT_A >> 3: + val = A; + break; + case MONITOR_BREAKPOINT_X >> 3: + val = X; + break; + case MONITOR_BREAKPOINT_Y >> 3: + val = Y; + break; + case MONITOR_BREAKPOINT_S >> 3: + val = S; + break; + case MONITOR_BREAKPOINT_READ >> 3: + if ((optype & 4) == 0) + goto cond_failed; + val = addr; + break; + case MONITOR_BREAKPOINT_WRITE >> 3: + if ((optype & 8) == 0) + goto cond_failed; + val = addr; + break; + case MONITOR_BREAKPOINT_ACCESS >> 3: + if ((optype & 12) == 0) + goto cond_failed; + val = addr; + break; + case MONITOR_BREAKPOINT_MEMORY >> 3: + val = MEMORY_SafeGetByte(m_addr); + break; + default: + /* shouldn't happen */ + continue; + } + if ((cond & MONITOR_BREAKPOINT_LESS) != 0 && val < value) + continue; + if ((cond & MONITOR_BREAKPOINT_EQUAL) != 0 && val == value) + continue; + if ((cond & MONITOR_BREAKPOINT_GREATER) != 0 && val > value) + continue; + cond_failed: + ; + } + /* a condition failed */ + /* quickly skip AND-connected conditions */ + do { + if (++i >= MONITOR_breakpoint_table_size) + goto no_breakpoint; + } while (MONITOR_breakpoint_table[i].condition != MONITOR_BREAKPOINT_OR || !MONITOR_breakpoint_table[i].enabled); + } + /* fire breakpoint */ + PC--; + DO_BREAK; + goto breakpoint_return; + no_breakpoint: + ; + } +#endif /* MONITOR_BREAKPOINTS */ + +#ifndef CYCLES_PER_OPCODE + ANTIC_xpos += cycles[insn]; +#endif + +#ifdef MONITOR_PROFILE + CPU_instruction_count[insn]++; + MONITOR_coverage[old_PC = PC - 1].count++; + MONITOR_coverage_insns++; +#endif + +#ifdef PREFETCH_CODE + addr = PEEK_CODE_WORD(); +#endif + +#ifdef NO_GOTO + switch (insn) { +#else + goto *opcode[insn]; +#endif + + OPCODE(00) /* BRK */ +#ifdef MONITOR_BREAK + if (MONITOR_break_brk) { + DO_BREAK; + } + else +#endif + { + PC++; + PHPC; + PHPB1; + CPU_SetI; + SET_PC(MEMORY_dGetWordAligned(0xfffe)); + INC_RET_NESTING; + } + DONE + + OPCODE(01) /* ORA (ab,x) */ + INDIRECT_X; + ORA(MEMORY_GetByte(addr)); + DONE + + OPCODE(03) /* ASO (ab,x) [unofficial - ASL then ORA with Acc] */ + INDIRECT_X; + + aso: + RMW_GetByte(data, addr); + C = (data & 0x80) ? 1 : 0; + data <<= 1; + MEMORY_PutByte(addr, data); + Z = N = A |= data; + DONE + + OPCODE_ALIAS(04) /* NOP ab [unofficial - skip byte] */ + OPCODE_ALIAS(44) + OPCODE(64) + PC++; + DONE + + OPCODE_ALIAS(14) /* NOP ab,x [unofficial - skip byte] */ + OPCODE_ALIAS(34) + OPCODE_ALIAS(54) + OPCODE_ALIAS(74) + OPCODE_ALIAS(d4) + OPCODE(f4) + PC++; + DONE + + OPCODE_ALIAS(80) /* NOP #ab [unofficial - skip byte] */ + OPCODE_ALIAS(82) + OPCODE_ALIAS(89) + OPCODE_ALIAS(c2) + OPCODE(e2) + PC++; + DONE + + OPCODE(05) /* ORA ab */ + ZPAGE; + ORA(MEMORY_dGetByte(addr)); + DONE + + OPCODE(06) /* ASL ab */ + ZPAGE; + data = MEMORY_dGetByte(addr); + C = (data & 0x80) ? 1 : 0; + Z = N = data << 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(07) /* ASO ab [unofficial - ASL then ORA with Acc] */ + ZPAGE; + + aso_zpage: + data = MEMORY_dGetByte(addr); + C = (data & 0x80) ? 1 : 0; + data <<= 1; + MEMORY_dPutByte(addr, data); + Z = N = A |= data; + DONE + + OPCODE(08) /* PHP */ + PHPB1; + DONE + + OPCODE(09) /* ORA #ab */ + ORA(IMMEDIATE); + DONE + + OPCODE(0a) /* ASL */ + C = (A & 0x80) ? 1 : 0; + Z = N = A <<= 1; + DONE + + OPCODE_ALIAS(0b) /* ANC #ab [unofficial - AND then copy N to C (Fox) */ + OPCODE(2b) + AND(IMMEDIATE); + C = N >= 0x80; + DONE + + OPCODE(0c) /* NOP abcd [unofficial - skip word] */ + PC += 2; + DONE + + OPCODE(0d) /* ORA abcd */ + ABSOLUTE; + ORA(MEMORY_GetByte(addr)); + DONE + + OPCODE(0e) /* ASL abcd */ + ABSOLUTE; + RMW_GetByte(data, addr); + C = (data & 0x80) ? 1 : 0; + Z = N = data << 1; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(0f) /* ASO abcd [unofficial - ASL then ORA with Acc] */ + ABSOLUTE; + goto aso; + + OPCODE(10) /* BPL */ + BRANCH(!(N & 0x80)) + + OPCODE(11) /* ORA (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + ORA(MEMORY_GetByte(addr)); + DONE + + OPCODE(13) /* ASO (ab),y [unofficial - ASL then ORA with Acc] */ + INDIRECT_Y; + goto aso; + + OPCODE(15) /* ORA ab,x */ + ZPAGE_X; + ORA(MEMORY_dGetByte(addr)); + DONE + + OPCODE(16) /* ASL ab,x */ + ZPAGE_X; + data = MEMORY_dGetByte(addr); + C = (data & 0x80) ? 1 : 0; + Z = N = data << 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(17) /* ASO ab,x [unofficial - ASL then ORA with Acc] */ + ZPAGE_X; + goto aso_zpage; + + OPCODE(18) /* CLC */ + C = 0; + DONE + + OPCODE(19) /* ORA abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + ORA(MEMORY_GetByte(addr)); + DONE + + OPCODE(1b) /* ASO abcd,y [unofficial - ASL then ORA with Acc] */ + ABSOLUTE_Y; + goto aso; + + OPCODE_ALIAS(1c) /* NOP abcd,x [unofficial - skip word] */ + OPCODE_ALIAS(3c) + OPCODE_ALIAS(5c) + OPCODE_ALIAS(7c) + OPCODE_ALIAS(dc) + OPCODE(fc) + if (OP_BYTE + X >= 0x100) + ANTIC_xpos++; + PC += 2; + DONE + + OPCODE(1d) /* ORA abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + ORA(MEMORY_GetByte(addr)); + DONE + + OPCODE(1e) /* ASL abcd,x */ + ABSOLUTE_X; + RMW_GetByte(data, addr); + C = (data & 0x80) ? 1 : 0; + Z = N = data << 1; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(1f) /* ASO abcd,x [unofficial - ASL then ORA with Acc] */ + ABSOLUTE_X; + goto aso; + + OPCODE(20) /* JSR abcd */ + { + UWORD retaddr = GET_PC() + 1; +#ifdef MONITOR_BREAK + CPU_remember_JMP[CPU_remember_jmp_curpos] = GET_PC() - 1; + CPU_remember_jmp_curpos = (CPU_remember_jmp_curpos + 1) % CPU_REMEMBER_JMP_STEPS; + MONITOR_ret_nesting++; +#endif + PHW(retaddr); + } + SET_PC(OP_WORD); + DONE + + OPCODE(21) /* AND (ab,x) */ + INDIRECT_X; + AND(MEMORY_GetByte(addr)); + DONE + + OPCODE(23) /* RLA (ab,x) [unofficial - ROL Mem, then AND with A] */ + INDIRECT_X; + + rla: + RMW_GetByte(data, addr); + if (C) { + C = (data & 0x80) ? 1 : 0; + data = (data << 1) + 1; + } + else { + C = (data & 0x80) ? 1 : 0; + data = (data << 1); + } + MEMORY_PutByte(addr, data); + Z = N = A &= data; + DONE + + OPCODE(24) /* BIT ab */ + ZPAGE; + N = MEMORY_dGetByte(addr); +#ifndef NO_V_FLAG_VARIABLE + V = N & 0x40; +#else + CPU_regP = (CPU_regP & 0xbf) + (N & 0x40); +#endif + Z = (A & N); + DONE + + OPCODE(25) /* AND ab */ + ZPAGE; + AND(MEMORY_dGetByte(addr)); + DONE + + OPCODE(26) /* ROL ab */ + ZPAGE; + data = MEMORY_dGetByte(addr); + Z = N = (data << 1) + C; + C = (data & 0x80) ? 1 : 0; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(27) /* RLA ab [unofficial - ROL Mem, then AND with A] */ + ZPAGE; + + rla_zpage: + data = MEMORY_dGetByte(addr); + if (C) { + C = (data & 0x80) ? 1 : 0; + data = (data << 1) + 1; + } + else { + C = (data & 0x80) ? 1 : 0; + data = (data << 1); + } + MEMORY_dPutByte(addr, data); + Z = N = A &= data; + DONE + + OPCODE(28) /* PLP */ + PLP; + CPUCHECKIRQ; + DONE + + OPCODE(29) /* AND #ab */ + AND(IMMEDIATE); + DONE + + OPCODE(2a) /* ROL */ + Z = N = (A << 1) + C; + C = (A & 0x80) ? 1 : 0; + A = Z; + DONE + + OPCODE(2c) /* BIT abcd */ + ABSOLUTE; + N = MEMORY_GetByte(addr); +#ifndef NO_V_FLAG_VARIABLE + V = N & 0x40; +#else + CPU_regP = (CPU_regP & 0xbf) + (N & 0x40); +#endif + Z = (A & N); + DONE + + OPCODE(2d) /* AND abcd */ + ABSOLUTE; + AND(MEMORY_GetByte(addr)); + DONE + + OPCODE(2e) /* ROL abcd */ + ABSOLUTE; + RMW_GetByte(data, addr); + Z = N = (data << 1) + C; + C = (data & 0x80) ? 1 : 0; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(2f) /* RLA abcd [unofficial - ROL Mem, then AND with A] */ + ABSOLUTE; + goto rla; + + OPCODE(30) /* BMI */ + BRANCH(N & 0x80) + + OPCODE(31) /* AND (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + AND(MEMORY_GetByte(addr)); + DONE + + OPCODE(33) /* RLA (ab),y [unofficial - ROL Mem, then AND with A] */ + INDIRECT_Y; + goto rla; + + OPCODE(35) /* AND ab,x */ + ZPAGE_X; + AND(MEMORY_dGetByte(addr)); + DONE + + OPCODE(36) /* ROL ab,x */ + ZPAGE_X; + data = MEMORY_dGetByte(addr); + Z = N = (data << 1) + C; + C = (data & 0x80) ? 1 : 0; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(37) /* RLA ab,x [unofficial - ROL Mem, then AND with A] */ + ZPAGE_X; + goto rla_zpage; + + OPCODE(38) /* SEC */ + C = 1; + DONE + + OPCODE(39) /* AND abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + AND(MEMORY_GetByte(addr)); + DONE + + OPCODE(3b) /* RLA abcd,y [unofficial - ROL Mem, then AND with A] */ + ABSOLUTE_Y; + goto rla; + + OPCODE(3d) /* AND abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + AND(MEMORY_GetByte(addr)); + DONE + + OPCODE(3e) /* ROL abcd,x */ + ABSOLUTE_X; + RMW_GetByte(data, addr); + Z = N = (data << 1) + C; + C = (data & 0x80) ? 1 : 0; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(3f) /* RLA abcd,x [unofficial - ROL Mem, then AND with A] */ + ABSOLUTE_X; + goto rla; + + OPCODE(40) /* RTI */ + PLP; + data = PL; + SET_PC((PL << 8) + data); + CPUCHECKIRQ; +#ifdef MONITOR_BREAK + if (MONITOR_break_ret && --MONITOR_ret_nesting <= 0) + MONITOR_break_step = TRUE; +#endif + DONE + + OPCODE(41) /* EOR (ab,x) */ + INDIRECT_X; + EOR(MEMORY_GetByte(addr)); + DONE + + OPCODE(43) /* LSE (ab,x) [unofficial - LSR then EOR result with A] */ + INDIRECT_X; + + lse: + RMW_GetByte(data, addr); + C = data & 1; + data >>= 1; + MEMORY_PutByte(addr, data); + Z = N = A ^= data; + DONE + + OPCODE(45) /* EOR ab */ + ZPAGE; + EOR(MEMORY_dGetByte(addr)); + DONE + + OPCODE(46) /* LSR ab */ + ZPAGE; + data = MEMORY_dGetByte(addr); + C = data & 1; + Z = data >> 1; + N = 0; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(47) /* LSE ab [unofficial - LSR then EOR result with A] */ + ZPAGE; + + lse_zpage: + data = MEMORY_dGetByte(addr); + C = data & 1; + data >>= 1; + MEMORY_dPutByte(addr, data); + Z = N = A ^= data; + DONE + + OPCODE(48) /* PHA */ + PH(A); + DONE + + OPCODE(49) /* EOR #ab */ + EOR(IMMEDIATE); + DONE + + OPCODE(4a) /* LSR */ + C = A & 1; + Z = N = A >>= 1; + DONE + + OPCODE(4b) /* ALR #ab [unofficial - Acc AND Data, LSR result] */ + data = A & IMMEDIATE; + C = data & 1; + Z = N = A = (data >> 1); + DONE + + OPCODE(4c) /* JMP abcd */ +#ifdef MONITOR_BREAK + CPU_remember_JMP[CPU_remember_jmp_curpos] = GET_PC() - 1; + CPU_remember_jmp_curpos = (CPU_remember_jmp_curpos + 1) % CPU_REMEMBER_JMP_STEPS; +#endif + SET_PC(OP_WORD); + DONE + + OPCODE(4d) /* EOR abcd */ + ABSOLUTE; + EOR(MEMORY_GetByte(addr)); + DONE + + OPCODE(4e) /* LSR abcd */ + ABSOLUTE; + RMW_GetByte(data, addr); + C = data & 1; + Z = data >> 1; + N = 0; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(4f) /* LSE abcd [unofficial - LSR then EOR result with A] */ + ABSOLUTE; + goto lse; + + OPCODE(50) /* BVC */ +#ifndef NO_V_FLAG_VARIABLE + BRANCH(!V) +#else + BRANCH(!(CPU_regP & 0x40)) +#endif + + OPCODE(51) /* EOR (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + EOR(MEMORY_GetByte(addr)); + DONE + + OPCODE(53) /* LSE (ab),y [unofficial - LSR then EOR result with A] */ + INDIRECT_Y; + goto lse; + + OPCODE(55) /* EOR ab,x */ + ZPAGE_X; + EOR(MEMORY_dGetByte(addr)); + DONE + + OPCODE(56) /* LSR ab,x */ + ZPAGE_X; + data = MEMORY_dGetByte(addr); + C = data & 1; + Z = data >> 1; + N = 0; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(57) /* LSE ab,x [unofficial - LSR then EOR result with A] */ + ZPAGE_X; + goto lse_zpage; + + OPCODE(58) /* CLI */ + CPU_ClrI; + CPUCHECKIRQ; + DONE + + OPCODE(59) /* EOR abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + EOR(MEMORY_GetByte(addr)); + DONE + + OPCODE(5b) /* LSE abcd,y [unofficial - LSR then EOR result with A] */ + ABSOLUTE_Y; + goto lse; + + OPCODE(5d) /* EOR abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + EOR(MEMORY_GetByte(addr)); + DONE + + OPCODE(5e) /* LSR abcd,x */ + ABSOLUTE_X; + RMW_GetByte(data, addr); + C = data & 1; + Z = data >> 1; + N = 0; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(5f) /* LSE abcd,x [unofficial - LSR then EOR result with A] */ + ABSOLUTE_X; + goto lse; + + OPCODE(60) /* RTS */ + data = PL; + SET_PC((PL << 8) + data + 1); +#ifdef MONITOR_BREAK + if (MONITOR_break_ret && --MONITOR_ret_nesting <= 0) + MONITOR_break_step = TRUE; +#endif + if (CPU_rts_handler != NULL) { + CPU_rts_handler(); + CPU_rts_handler = NULL; + } + DONE + + OPCODE(61) /* ADC (ab,x) */ + INDIRECT_X; + data = MEMORY_GetByte(addr); + goto adc; + + OPCODE(63) /* RRA (ab,x) [unofficial - ROR Mem, then ADC to Acc] */ + INDIRECT_X; + + rra: + RMW_GetByte(data, addr); + if (C) { + C = data & 1; + data = (data >> 1) + 0x80; + } + else { + C = data & 1; + data >>= 1; + } + MEMORY_PutByte(addr, data); + goto adc; + + OPCODE(65) /* ADC ab */ + ZPAGE; + data = MEMORY_dGetByte(addr); + goto adc; + + OPCODE(66) /* ROR ab */ + ZPAGE; + data = MEMORY_dGetByte(addr); + Z = N = (C << 7) + (data >> 1); + C = data & 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(67) /* RRA ab [unofficial - ROR Mem, then ADC to Acc] */ + ZPAGE; + + rra_zpage: + data = MEMORY_dGetByte(addr); + if (C) { + C = data & 1; + data = (data >> 1) + 0x80; + } + else { + C = data & 1; + data >>= 1; + } + MEMORY_dPutByte(addr, data); + goto adc; + + OPCODE(68) /* PLA */ + Z = N = A = PL; + DONE + + OPCODE(69) /* ADC #ab */ + data = IMMEDIATE; + goto adc; + + OPCODE(6a) /* ROR */ + Z = N = (C << 7) + (A >> 1); + C = A & 1; + A = Z; + DONE + + OPCODE(6b) /* ARR #ab [unofficial - Acc AND Data, ROR result] */ + /* It does some 'BCD fixup' if D flag is set */ + /* MPC 05/24/00 */ + data = A & IMMEDIATE; + if (CPU_regP & CPU_D_FLAG) { + UBYTE temp = (data >> 1) + (C << 7); + Z = N = temp; +#ifndef NO_V_FLAG_VARIABLE + V = ((temp ^ data) & 0x40); +#else + CPU_regP = (CPU_regP & 0xbf) + ((temp ^ data) & 0x40); +#endif + if ((data & 0x0F) + (data & 0x01) > 5) + temp = (temp & 0xF0) + ((temp + 0x6) & 0x0F); + if (data + (data & 0x10) >= 0x60) { + temp += 0x60; + C = 1; + } + else + C = 0; + A = (UBYTE) temp; + } + else { + Z = N = A = (data >> 1) + (C << 7); + C = data >> 7; +#ifndef NO_V_FLAG_VARIABLE + V = C ^ ((A >> 5) & 1); +#else + CPU_regP = (CPU_regP & 0xbf) + ((A ^ data) & 0x40); +#endif + } + DONE + + OPCODE(6c) /* JMP (abcd) */ +#ifdef MONITOR_BREAK + CPU_remember_JMP[CPU_remember_jmp_curpos] = GET_PC() - 1; + CPU_remember_jmp_curpos = (CPU_remember_jmp_curpos + 1) % CPU_REMEMBER_JMP_STEPS; +#endif + ABSOLUTE; +#ifdef CPU65C02 + /* XXX: if ((UBYTE) addr == 0xff) ANTIC_xpos++; */ + SET_PC(MEMORY_dGetWord(addr)); +#else + /* original 6502 had a bug in JMP (addr) when addr crossed page boundary */ + if ((UBYTE) addr == 0xff) + SET_PC((MEMORY_dGetByte(addr - 0xff) << 8) + MEMORY_dGetByte(addr)); + else + SET_PC(MEMORY_dGetWord(addr)); +#endif + DONE + + OPCODE(6d) /* ADC abcd */ + ABSOLUTE; + data = MEMORY_GetByte(addr); + goto adc; + + OPCODE(6e) /* ROR abcd */ + ABSOLUTE; + RMW_GetByte(data, addr); + Z = N = (C << 7) + (data >> 1); + C = data & 1; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(6f) /* RRA abcd [unofficial - ROR Mem, then ADC to Acc] */ + ABSOLUTE; + goto rra; + + OPCODE(70) /* BVS */ +#ifndef NO_V_FLAG_VARIABLE + BRANCH(V) +#else + BRANCH(CPU_regP & 0x40) +#endif + + OPCODE(71) /* ADC (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + data = MEMORY_GetByte(addr); + goto adc; + + OPCODE(73) /* RRA (ab),y [unofficial - ROR Mem, then ADC to Acc] */ + INDIRECT_Y; + goto rra; + + OPCODE(75) /* ADC ab,x */ + ZPAGE_X; + data = MEMORY_dGetByte(addr); + goto adc; + + OPCODE(76) /* ROR ab,x */ + ZPAGE_X; + data = MEMORY_dGetByte(addr); + Z = N = (C << 7) + (data >> 1); + C = data & 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(77) /* RRA ab,x [unofficial - ROR Mem, then ADC to Acc] */ + ZPAGE_X; + goto rra_zpage; + + OPCODE(78) /* SEI */ + CPU_SetI; + DONE + + OPCODE(79) /* ADC abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + data = MEMORY_GetByte(addr); + goto adc; + + OPCODE(7b) /* RRA abcd,y [unofficial - ROR Mem, then ADC to Acc] */ + ABSOLUTE_Y; + goto rra; + + OPCODE(7d) /* ADC abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + data = MEMORY_GetByte(addr); + goto adc; + + OPCODE(7e) /* ROR abcd,x */ + ABSOLUTE_X; + RMW_GetByte(data, addr); + Z = N = (C << 7) + (data >> 1); + C = data & 1; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(7f) /* RRA abcd,x [unofficial - ROR Mem, then ADC to Acc] */ + ABSOLUTE_X; + goto rra; + + OPCODE(81) /* STA (ab,x) */ + INDIRECT_X; + MEMORY_PutByte(addr, A); + DONE + + /* AXS doesn't change flags and SAX is better name for it (Fox) */ + OPCODE(83) /* SAX (ab,x) [unofficial - Store result A AND X */ + INDIRECT_X; + data = A & X; + MEMORY_PutByte(addr, data); + DONE + + OPCODE(84) /* STY ab */ + ZPAGE; + MEMORY_dPutByte(addr, Y); + DONE + + OPCODE(85) /* STA ab */ + ZPAGE; + MEMORY_dPutByte(addr, A); + DONE + + OPCODE(86) /* STX ab */ + ZPAGE; + MEMORY_dPutByte(addr, X); + DONE + + OPCODE(87) /* SAX ab [unofficial - Store result A AND X] */ + ZPAGE; + data = A & X; + MEMORY_dPutByte(addr, data); + DONE + + OPCODE(88) /* DEY */ + Z = N = --Y; + DONE + + OPCODE(8a) /* TXA */ + Z = N = A = X; + DONE + + OPCODE(8b) /* ANE #ab [unofficial - A AND X AND (Mem OR $EF) to Acc] (Fox) */ + data = IMMEDIATE; + Z = N = A & X & data; + A &= X & (data | 0xef); + DONE + + OPCODE(8c) /* STY abcd */ + ABSOLUTE; + MEMORY_PutByte(addr, Y); + DONE + + OPCODE(8d) /* STA abcd */ + ABSOLUTE; + MEMORY_PutByte(addr, A); + DONE + + OPCODE(8e) /* STX abcd */ + ABSOLUTE; + MEMORY_PutByte(addr, X); + DONE + + OPCODE(8f) /* SAX abcd [unofficial - Store result A AND X] */ + ABSOLUTE; + data = A & X; + MEMORY_PutByte(addr, data); + DONE + + OPCODE(90) /* BCC */ + BRANCH(!C) + + OPCODE(91) /* STA (ab),y */ + INDIRECT_Y; + MEMORY_PutByte(addr, A); + DONE + + OPCODE(93) /* SHA (ab),y [unofficial, UNSTABLE - Store A AND X AND (H+1) ?] (Fox) */ + /* It seems previous memory value is important - also in 9f */ + ZPAGE; + addr = zGetWord(addr); + data = A & X & ((addr >> 8) + 1); + if ((addr & 0xff) + Y > 0xff) { /* if it crosses a page */ + MEMORY_PutByte(((addr + Y) & 0xff) | (data << 8), data); + } + else { + MEMORY_PutByte(addr + Y, data); + } + DONE + + OPCODE(94) /* STY ab,x */ + ZPAGE_X; + MEMORY_dPutByte(addr, Y); + DONE + + OPCODE(95) /* STA ab,x */ + ZPAGE_X; + MEMORY_dPutByte(addr, A); + DONE + + OPCODE(96) /* STX ab,y */ + ZPAGE_Y; + MEMORY_PutByte(addr, X); + DONE + + OPCODE(97) /* SAX ab,y [unofficial - Store result A AND X] */ + ZPAGE_Y; + data = A & X; + MEMORY_dPutByte(addr, data); + DONE + + OPCODE(98) /* TYA */ + Z = N = A = Y; + DONE + + OPCODE(99) /* STA abcd,y */ + ABSOLUTE_Y; + MEMORY_PutByte(addr, A); + DONE + + OPCODE(9a) /* TXS */ + S = X; + DONE + + OPCODE(9b) /* SHS abcd,y [unofficial, UNSTABLE] (Fox) */ + /* Transfer A AND X to S, then store S AND (H+1)] */ + /* S seems to be stable, only memory values vary */ + ABSOLUTE; + S = A & X; + data = S & ((addr >> 8) + 1); + if ((addr & 0xff) + Y > 0xff) { /* if it crosses a page */ + MEMORY_PutByte(((addr + Y) & 0xff) | (data << 8), data); + } + else { + MEMORY_PutByte(addr + Y, data); + } + DONE + + OPCODE(9c) /* SHY abcd,x [unofficial - Store Y and (H+1)] (Fox) */ + /* Seems to be stable */ + ABSOLUTE; + /* MPC 05/24/00 */ + data = Y & ((UBYTE) ((addr >> 8) + 1)); + if ((addr & 0xff) + X > 0xff) { /* if it crosses a page */ + MEMORY_PutByte(((addr + X) & 0xff) | (data << 8), data); + } + else { + MEMORY_PutByte(addr + X, data); + } + DONE + + OPCODE(9d) /* STA abcd,x */ + ABSOLUTE_X; + MEMORY_PutByte(addr, A); + DONE + + OPCODE(9e) /* SHX abcd,y [unofficial - Store X and (H+1)] (Fox) */ + /* Seems to be stable */ + ABSOLUTE; + /* MPC 05/24/00 */ + data = X & ((UBYTE) ((addr >> 8) + 1)); + if ((addr & 0xff) + Y > 0xff) { /* if it crosses a page */ + MEMORY_PutByte(((addr + Y) & 0xff) | (data << 8), data); + } + else { + MEMORY_PutByte(addr + Y, data); + } + DONE + + OPCODE(9f) /* SHA abcd,y [unofficial, UNSTABLE - Store A AND X AND (H+1) ?] (Fox) */ + ABSOLUTE; + data = A & X & ((addr >> 8) + 1); + if ((addr & 0xff) + Y > 0xff) { /* if it crosses a page */ + MEMORY_PutByte(((addr + Y) & 0xff) | (data << 8), data); + } + else { + MEMORY_PutByte(addr + Y, data); + } + DONE + + OPCODE(a0) /* LDY #ab */ + LDY(IMMEDIATE); + DONE + + OPCODE(a1) /* LDA (ab,x) */ + INDIRECT_X; + LDA(MEMORY_GetByte(addr)); + DONE + + OPCODE(a2) /* LDX #ab */ + LDX(IMMEDIATE); + DONE + + OPCODE(a3) /* LAX (ab,x) [unofficial] */ + INDIRECT_X; + Z = N = X = A = MEMORY_GetByte(addr); + DONE + + OPCODE(a4) /* LDY ab */ + ZPAGE; + LDY(MEMORY_dGetByte(addr)); + DONE + + OPCODE(a5) /* LDA ab */ + ZPAGE; + LDA(MEMORY_dGetByte(addr)); + DONE + + OPCODE(a6) /* LDX ab */ + ZPAGE; + LDX(MEMORY_dGetByte(addr)); + DONE + + OPCODE(a7) /* LAX ab [unofficial] */ + ZPAGE; + Z = N = X = A = MEMORY_GetByte(addr); + DONE + + OPCODE(a8) /* TAY */ + Z = N = Y = A; + DONE + + OPCODE(a9) /* LDA #ab */ + LDA(IMMEDIATE); + DONE + + OPCODE(aa) /* TAX */ + Z = N = X = A; + DONE + + OPCODE(ab) /* ANX #ab [unofficial - AND #ab, then TAX] */ + Z = N = X = A &= IMMEDIATE; + DONE + + OPCODE(ac) /* LDY abcd */ + ABSOLUTE; + LDY(MEMORY_GetByte(addr)); + DONE + + OPCODE(ad) /* LDA abcd */ + ABSOLUTE; + LDA(MEMORY_GetByte(addr)); + DONE + + OPCODE(ae) /* LDX abcd */ + ABSOLUTE; + LDX(MEMORY_GetByte(addr)); + DONE + + OPCODE(af) /* LAX abcd [unofficial] */ + ABSOLUTE; + Z = N = X = A = MEMORY_GetByte(addr); + DONE + + OPCODE(b0) /* BCS */ + BRANCH(C) + + OPCODE(b1) /* LDA (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + LDA(MEMORY_GetByte(addr)); + DONE + + OPCODE(b3) /* LAX (ab),y [unofficial] */ + INDIRECT_Y; + NCYCLES_Y; + Z = N = X = A = MEMORY_GetByte(addr); + DONE + + OPCODE(b4) /* LDY ab,x */ + ZPAGE_X; + LDY(MEMORY_dGetByte(addr)); + DONE + + OPCODE(b5) /* LDA ab,x */ + ZPAGE_X; + LDA(MEMORY_dGetByte(addr)); + DONE + + OPCODE(b6) /* LDX ab,y */ + ZPAGE_Y; + LDX(MEMORY_GetByte(addr)); + DONE + + OPCODE(b7) /* LAX ab,y [unofficial] */ + ZPAGE_Y; + Z = N = X = A = MEMORY_GetByte(addr); + DONE + + OPCODE(b8) /* CLV */ +#ifndef NO_V_FLAG_VARIABLE + V = 0; +#else + CPU_ClrV; +#endif + DONE + + OPCODE(b9) /* LDA abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + LDA(MEMORY_GetByte(addr)); + DONE + + OPCODE(ba) /* TSX */ + Z = N = X = S; + DONE + +/* AXA [unofficial - original decode by R.Sterba and R.Petruzela 15.1.1998 :-)] + AXA - this is our new imaginative name for instruction with opcode hex BB. + AXA - Store Mem AND #$FD to Acc and X, then set stackpoint to value (Acc - 4) + It's cool! :-) + LAS - this is better name for this :) (Fox) + It simply ANDs stack pointer with Mem, then transfers result to A and X + */ + + OPCODE(bb) /* LAS abcd,y [unofficial - AND S with Mem, transfer to A and X (Fox) */ + ABSOLUTE_Y; + NCYCLES_Y; + Z = N = A = X = S &= MEMORY_GetByte(addr); + DONE + + OPCODE(bc) /* LDY abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + LDY(MEMORY_GetByte(addr)); + DONE + + OPCODE(bd) /* LDA abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + LDA(MEMORY_GetByte(addr)); + DONE + + OPCODE(be) /* LDX abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + LDX(MEMORY_GetByte(addr)); + DONE + + OPCODE(bf) /* LAX abcd,y [unofficial] */ + ABSOLUTE_Y; + NCYCLES_Y; + Z = N = X = A = MEMORY_GetByte(addr); + DONE + + OPCODE(c0) /* CPY #ab */ + CPY(IMMEDIATE); + DONE + + OPCODE(c1) /* CMP (ab,x) */ + INDIRECT_X; + CMP(MEMORY_GetByte(addr)); + DONE + + OPCODE(c3) /* DCM (ab,x) [unofficial - DEC Mem then CMP with Acc] */ + INDIRECT_X; + + dcm: + RMW_GetByte(data, addr); + data--; + MEMORY_PutByte(addr, data); + CMP(data); + DONE + + OPCODE(c4) /* CPY ab */ + ZPAGE; + CPY(MEMORY_dGetByte(addr)); + DONE + + OPCODE(c5) /* CMP ab */ + ZPAGE; + CMP(MEMORY_dGetByte(addr)); + DONE + + OPCODE(c6) /* DEC ab */ + ZPAGE; + Z = N = MEMORY_dGetByte(addr) - 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(c7) /* DCM ab [unofficial - DEC Mem then CMP with Acc] */ + ZPAGE; + + dcm_zpage: + data = MEMORY_dGetByte(addr) - 1; + MEMORY_dPutByte(addr, data); + CMP(data); + DONE + + OPCODE(c8) /* INY */ + Z = N = ++Y; + DONE + + OPCODE(c9) /* CMP #ab */ + CMP(IMMEDIATE); + DONE + + OPCODE(ca) /* DEX */ + Z = N = --X; + DONE + + OPCODE(cb) /* SBX #ab [unofficial - store ((A AND X) - Mem) in X] (Fox) */ + X &= A; + data = IMMEDIATE; + C = X >= data; + /* MPC 05/24/00 */ + Z = N = X -= data; + DONE + + OPCODE(cc) /* CPY abcd */ + ABSOLUTE; + CPY(MEMORY_GetByte(addr)); + DONE + + OPCODE(cd) /* CMP abcd */ + ABSOLUTE; + CMP(MEMORY_GetByte(addr)); + DONE + + OPCODE(ce) /* DEC abcd */ + ABSOLUTE; + RMW_GetByte(Z, addr); + N = --Z; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(cf) /* DCM abcd [unofficial - DEC Mem then CMP with Acc] */ + ABSOLUTE; + goto dcm; + + OPCODE(d0) /* BNE */ + BRANCH(Z) + + OPCODE(d1) /* CMP (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + CMP(MEMORY_GetByte(addr)); + DONE + + OPCODE(d3) /* DCM (ab),y [unofficial - DEC Mem then CMP with Acc] */ + INDIRECT_Y; + goto dcm; + + OPCODE(d5) /* CMP ab,x */ + ZPAGE_X; + CMP(MEMORY_dGetByte(addr)); + DONE + + OPCODE(d6) /* DEC ab,x */ + ZPAGE_X; + Z = N = MEMORY_dGetByte(addr) - 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(d7) /* DCM ab,x [unofficial - DEC Mem then CMP with Acc] */ + ZPAGE_X; + goto dcm_zpage; + + OPCODE(d8) /* CLD */ + CPU_ClrD; + DONE + + OPCODE(d9) /* CMP abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + CMP(MEMORY_GetByte(addr)); + DONE + + OPCODE(db) /* DCM abcd,y [unofficial - DEC Mem then CMP with Acc] */ + ABSOLUTE_Y; + goto dcm; + + OPCODE(dd) /* CMP abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + CMP(MEMORY_GetByte(addr)); + DONE + + OPCODE(de) /* DEC abcd,x */ + ABSOLUTE_X; + RMW_GetByte(Z, addr); + N = --Z; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(df) /* DCM abcd,x [unofficial - DEC Mem then CMP with Acc] */ + ABSOLUTE_X; + goto dcm; + + OPCODE(e0) /* CPX #ab */ + CPX(IMMEDIATE); + DONE + + OPCODE(e1) /* SBC (ab,x) */ + INDIRECT_X; + data = MEMORY_GetByte(addr); + goto sbc; + + OPCODE(e3) /* INS (ab,x) [unofficial - INC Mem then SBC with Acc] */ + INDIRECT_X; + + ins: + RMW_GetByte(data, addr); + ++data; + MEMORY_PutByte(addr, data); + goto sbc; + + OPCODE(e4) /* CPX ab */ + ZPAGE; + CPX(MEMORY_dGetByte(addr)); + DONE + + OPCODE(e5) /* SBC ab */ + ZPAGE; + data = MEMORY_dGetByte(addr); + goto sbc; + + OPCODE(e6) /* INC ab */ + ZPAGE; + Z = N = MEMORY_dGetByte(addr) + 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(e7) /* INS ab [unofficial - INC Mem then SBC with Acc] */ + ZPAGE; + + ins_zpage: + data = MEMORY_dGetByte(addr) + 1; + MEMORY_dPutByte(addr, data); + goto sbc; + + OPCODE(e8) /* INX */ + Z = N = ++X; + DONE + + OPCODE_ALIAS(e9) /* SBC #ab */ + OPCODE(eb) /* SBC #ab [unofficial] */ + data = IMMEDIATE; + goto sbc; + + OPCODE_ALIAS(ea) /* NOP */ + OPCODE_ALIAS(1a) /* NOP [unofficial] */ + OPCODE_ALIAS(3a) + OPCODE_ALIAS(5a) + OPCODE_ALIAS(7a) + OPCODE_ALIAS(da) + OPCODE(fa) + DONE + + OPCODE(ec) /* CPX abcd */ + ABSOLUTE; + CPX(MEMORY_GetByte(addr)); + DONE + + OPCODE(ed) /* SBC abcd */ + ABSOLUTE; + data = MEMORY_GetByte(addr); + goto sbc; + + OPCODE(ee) /* INC abcd */ + ABSOLUTE; + RMW_GetByte(Z, addr); + N = ++Z; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(ef) /* INS abcd [unofficial - INC Mem then SBC with Acc] */ + ABSOLUTE; + goto ins; + + OPCODE(f0) /* BEQ */ + BRANCH(!Z) + + OPCODE(f1) /* SBC (ab),y */ + INDIRECT_Y; + NCYCLES_Y; + data = MEMORY_GetByte(addr); + goto sbc; + + OPCODE(f3) /* INS (ab),y [unofficial - INC Mem then SBC with Acc] */ + INDIRECT_Y; + goto ins; + + OPCODE(f5) /* SBC ab,x */ + ZPAGE_X; + data = MEMORY_dGetByte(addr); + goto sbc; + + OPCODE(f6) /* INC ab,x */ + ZPAGE_X; + Z = N = MEMORY_dGetByte(addr) + 1; + MEMORY_dPutByte(addr, Z); + DONE + + OPCODE(f7) /* INS ab,x [unofficial - INC Mem then SBC with Acc] */ + ZPAGE_X; + goto ins_zpage; + + OPCODE(f8) /* SED */ + CPU_SetD; + DONE + + OPCODE(f9) /* SBC abcd,y */ + ABSOLUTE_Y; + NCYCLES_Y; + data = MEMORY_GetByte(addr); + goto sbc; + + OPCODE(fb) /* INS abcd,y [unofficial - INC Mem then SBC with Acc] */ + ABSOLUTE_Y; + goto ins; + + OPCODE(fd) /* SBC abcd,x */ + ABSOLUTE_X; + NCYCLES_X; + data = MEMORY_GetByte(addr); + goto sbc; + + OPCODE(fe) /* INC abcd,x */ + ABSOLUTE_X; + RMW_GetByte(Z, addr); + N = ++Z; + MEMORY_PutByte(addr, Z); + DONE + + OPCODE(ff) /* INS abcd,x [unofficial - INC Mem then SBC with Acc] */ + ABSOLUTE_X; + goto ins; + +#ifdef ASAP + + OPCODE_ALIAS(d2) + OPCODE_ALIAS(f2) + +#else + + OPCODE(d2) /* ESCRTS #ab (CIM) - on Atari is here instruction CIM [unofficial] !RS! */ + data = IMMEDIATE; + UPDATE_GLOBAL_REGS; + CPU_GetStatus(); + ESC_Run(data); + CPU_PutStatus(); + UPDATE_LOCAL_REGS; + data = PL; + SET_PC((PL << 8) + data + 1); +#ifdef MONITOR_BREAK + if (MONITOR_break_ret && --MONITOR_ret_nesting <= 0) + MONITOR_break_step = TRUE; +#endif + DONE + + OPCODE(f2) /* ESC #ab (CIM) - on Atari is here instruction CIM [unofficial] !RS! */ + /* OPCODE(ff: ESC #ab - opcode FF is now used for INS [unofficial] instruction !RS! */ + data = IMMEDIATE; + UPDATE_GLOBAL_REGS; + CPU_GetStatus(); + ESC_Run(data); + CPU_PutStatus(); + UPDATE_LOCAL_REGS; + DONE + +#endif /* ASAP */ + + OPCODE_ALIAS(02) /* CIM [unofficial - crash intermediate] */ + OPCODE_ALIAS(12) + OPCODE_ALIAS(22) + OPCODE_ALIAS(32) + OPCODE_ALIAS(42) + OPCODE_ALIAS(52) + OPCODE_ALIAS(62) + OPCODE_ALIAS(72) + OPCODE_ALIAS(92) + OPCODE(b2) + +#ifdef ASAP + + ASAP_CIM(); + DONE + +#else + + /* OPCODE(d2) Used for ESCRTS #ab (CIM) */ + /* OPCODE(f2) Used for ESC #ab (CIM) */ + PC--; + UPDATE_GLOBAL_REGS; + CPU_GetStatus(); + +#ifdef CRASH_MENU + UI_crash_address = GET_PC(); + UI_crash_afterCIM = GET_PC() + 1; + UI_crash_code = insn; + UI_Run(); +#else + CPU_cim_encountered = TRUE; + ENTER_MONITOR; +#endif /* CRASH_MENU */ + + CPU_PutStatus(); + UPDATE_LOCAL_REGS; + DONE + +#endif /* ASAP */ + +/* ---------------------------------------------- */ +/* ADC and SBC routines */ + + adc: + if (!(CPU_regP & CPU_D_FLAG)) { + /* Binary mode */ + unsigned int tmp; + tmp = A + data + C; + C = tmp > 0xff; + /* C = tmp >> 8; */ +#ifndef NO_V_FLAG_VARIABLE + V = !((A ^ data) & 0x80) && ((data ^ tmp) & 0x80); +#else + CPU_ClrV; + if (!((A ^ data) & 0x80) && ((data ^ tmp) & 0x80)) + CPU_SetV; +#endif + Z = N = A = (UBYTE) tmp; + } + else { + /* Decimal mode */ + unsigned int tmp; + tmp = (A & 0x0f) + (data & 0x0f) + C; + if (tmp >= 0x0a) + tmp = ((tmp + 0x06) & 0x0f) + 0x10; + tmp += (A & 0xf0) + (data & 0xf0); + + Z = A + data + C; + N = (UBYTE) tmp; +#ifndef NO_V_FLAG_VARIABLE + V = !((A ^ data) & 0x80) && ((data ^ tmp) & 0x80); +#else + CPU_ClrV; + if (!((A ^ data) & 0x80) && ((data ^ tmp) & 0x80)) + CPU_SetV; +#endif + + if (tmp >= 0xa0) + tmp += 0x60; + C = tmp > 0xff; + A = (UBYTE) tmp; + } + DONE + + sbc: + if (!(CPU_regP & CPU_D_FLAG)) { + /* Binary mode */ + unsigned int tmp; + /* tmp = A - data - !C; */ + tmp = A - data - 1 + C; + C = tmp < 0x100; +#ifndef NO_V_FLAG_VARIABLE + V = ((A ^ data) & 0x80) && ((A ^ tmp) & 0x80); +#else + CPU_ClrV; + if (((A ^ data) & 0x80) && ((A ^ tmp) & 0x80)) + CPU_SetV; +#endif + Z = N = A = (UBYTE) tmp; + } + else { + /* Decimal mode */ + unsigned int tmp; + tmp = (A & 0x0f) - (data & 0x0f) - 1 + C; + if (tmp & 0x10) + tmp = ((tmp - 0x06) & 0x0f) - 0x10; + tmp += (A & 0xf0) - (data & 0xf0); + if (tmp & 0x100) + tmp -= 0x60; + + Z = N = A - data - 1 + C; +#ifndef NO_V_FLAG_VARIABLE + V = ((A ^ data) & 0x80) && ((A ^ Z) & 0x80); +#else + CPU_ClrV; + if (((A ^ data) & 0x80) && ((A ^ Z) & 0x80)) + CPU_SetV; +#endif + C = ((unsigned int) (A - data - 1 + C)) <= 0xff; + + A = tmp; + } + DONE + +#ifdef NO_GOTO + } +#else + next: +#endif + +#ifdef MONITOR_PROFILE + { + int cyc = ANTIC_xpos - old_xpos; + MONITOR_coverage[old_PC].cycles += cyc; + MONITOR_coverage_cycles += cyc; + } +#endif + +#ifdef MONITOR_BREAK + if (MONITOR_break_step) { + DO_BREAK; + } +#endif + /* This "continue" does nothing here. + But it is necessary because, if we're not using NO_GOTO nor MONITOR_BREAK, + gcc can complain: "error: label at end of compound statement". */ + continue; + } + + UPDATE_GLOBAL_REGS; +} + +#endif /* FALCON_CPUASM */ + +void CPU_Reset(void) +{ +#ifdef MONITOR_PROFILE + memset(CPU_instruction_count, 0, sizeof(CPU_instruction_count)); +#endif + + CPU_IRQ = 0; + + CPU_regP = 0x34; /* The unused bit is always 1, I flag set! */ + CPU_PutStatus(); /* Make sure flags are all updated */ + CPU_regS = 0xff; + CPU_regPC = MEMORY_dGetWordAligned(0xfffc); +} + +#if !defined(BASIC) && !defined(ASAP) + +void CPU_StateSave(UBYTE SaveVerbose) +{ + StateSav_SaveUBYTE(&CPU_regA, 1); + + CPU_GetStatus(); /* Make sure flags are all updated */ + StateSav_SaveUBYTE(&CPU_regP, 1); + + StateSav_SaveUBYTE(&CPU_regS, 1); + StateSav_SaveUBYTE(&CPU_regX, 1); + StateSav_SaveUBYTE(&CPU_regY, 1); + StateSav_SaveUBYTE(&CPU_IRQ, 1); + + MEMORY_StateSave(SaveVerbose); + + StateSav_SaveUWORD(&CPU_regPC, 1); +} + +void CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion) +{ + StateSav_ReadUBYTE(&CPU_regA, 1); + + StateSav_ReadUBYTE(&CPU_regP, 1); + CPU_PutStatus(); /* Make sure flags are all updated */ + + StateSav_ReadUBYTE(&CPU_regS, 1); + StateSav_ReadUBYTE(&CPU_regX, 1); + StateSav_ReadUBYTE(&CPU_regY, 1); + StateSav_ReadUBYTE(&CPU_IRQ, 1); + + MEMORY_StateRead(SaveVerbose, StateVersion); + + StateSav_ReadUWORD(&CPU_regPC, 1); +} + +#endif diff --git a/MCUME_teensy41/teensy800/cpu.h b/MCUME_teensy41/teensy800/cpu.h new file mode 100644 index 0000000..3ee25e6 --- /dev/null +++ b/MCUME_teensy41/teensy800/cpu.h @@ -0,0 +1,65 @@ +#ifndef CPU_H_ +#define CPU_H_ + +#include "atari.h" + +#define CPU_N_FLAG 0x80 +#define CPU_V_FLAG 0x40 +#define CPU_B_FLAG 0x10 +#define CPU_D_FLAG 0x08 +#define CPU_I_FLAG 0x04 +#define CPU_Z_FLAG 0x02 +#define CPU_C_FLAG 0x01 + +void CPU_GetStatus(void); +void CPU_PutStatus(void); +void CPU_Reset(void); +void CPU_StateSave(UBYTE SaveVerbose); +void CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion); +void CPU_NMI(void); +void CPU_GO(int limit); +#define CPU_GenerateIRQ() (CPU_IRQ = 1) + +extern UWORD CPU_regPC; +extern UBYTE CPU_regA; +extern UBYTE CPU_regP; +extern UBYTE CPU_regS; +extern UBYTE CPU_regY; +extern UBYTE CPU_regX; + +#define CPU_SetN CPU_regP |= CPU_N_FLAG +#define CPU_ClrN CPU_regP &= (~CPU_N_FLAG) +#define CPU_SetV CPU_regP |= CPU_V_FLAG +#define CPU_ClrV CPU_regP &= (~CPU_V_FLAG) +#define CPU_SetB CPU_regP |= CPU_B_FLAG +#define CPU_ClrB CPU_regP &= (~CPU_B_FLAG) +#define CPU_SetD CPU_regP |= CPU_D_FLAG +#define CPU_ClrD CPU_regP &= (~CPU_D_FLAG) +#define CPU_SetI CPU_regP |= CPU_I_FLAG +#define CPU_ClrI CPU_regP &= (~CPU_I_FLAG) +#define CPU_SetZ CPU_regP |= CPU_Z_FLAG +#define CPU_ClrZ CPU_regP &= (~CPU_Z_FLAG) +#define CPU_SetC CPU_regP |= CPU_C_FLAG +#define CPU_ClrC CPU_regP &= (~CPU_C_FLAG) + +extern UBYTE CPU_IRQ; + +extern void (*CPU_rts_handler)(void); + +extern UBYTE CPU_cim_encountered; + +#define CPU_REMEMBER_PC_STEPS 64 +extern UWORD CPU_remember_PC[CPU_REMEMBER_PC_STEPS]; +extern UBYTE CPU_remember_op[CPU_REMEMBER_PC_STEPS][3]; +extern unsigned int CPU_remember_PC_curpos; +extern int CPU_remember_xpos[CPU_REMEMBER_PC_STEPS]; + +#define CPU_REMEMBER_JMP_STEPS 16 +extern UWORD CPU_remember_JMP[CPU_REMEMBER_JMP_STEPS]; +extern unsigned int CPU_remember_jmp_curpos; + +#ifdef MONITOR_PROFILE +extern int CPU_instruction_count[256]; +#endif + +#endif /* CPU_H_ */ diff --git a/MCUME_teensy41/teensy800/crc32.c b/MCUME_teensy41/teensy800/crc32.c new file mode 100644 index 0000000..d22e223 --- /dev/null +++ b/MCUME_teensy41/teensy800/crc32.c @@ -0,0 +1,86 @@ +/* CRC32.C -- Calculates 32bit CRC checksum + */ +// modified main() (see crc32.orig) to get calc_crc32() function +// JH 2002 + +#include +#include + +const unsigned long crc32_table[256] = { /* lookup table */ +0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, +0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, +0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, +0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, +0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, +0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, +0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, +0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, +0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, +0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, +0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, +0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, +0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, +0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, +0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, +0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, +0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, +0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, +0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, +0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, +0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, +0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, +0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, +0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, +0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, +0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, +0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, +0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, +0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, +0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, +0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, +0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, +0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, +0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, +0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, +0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, +0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, +0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, +0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, +0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, +0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, +0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, +0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; + +unsigned long calc_crc32(unsigned char *buf, int buflen) +{ + // buf is pointer to input buffer (data to crc) + // buflen is length of input buffer + + unsigned long crc; /* CRC value */ + //size_t j; /* buffer positions*/ + int j; /* buffer positions*/ + int k; /* generic integer */ + +#ifdef DEBUG + printf("32bit Cyclic Redudancy Check\n"); +#endif + + crc = 0xFFFFFFFF; /* preconditioning sets non zero value */ + + /* loop through the buffer and calculate CRC */ + for(j=0; j> 8) & 0x00FFFFFFL) ^ crc32_table[k]; + } + + crc=~crc; /* postconditioning */ + + /* print results */ +#ifdef DEBUG + printf("CRC32 is %08lX\n", crc); +#endif + + return crc; +} + + diff --git a/MCUME_teensy41/teensy800/emuapi.cpp b/MCUME_teensy41/teensy800/emuapi.cpp new file mode 100644 index 0000000..eb4be06 --- /dev/null +++ b/MCUME_teensy41/teensy800/emuapi.cpp @@ -0,0 +1,1731 @@ +#define KEYMAP_PRESENT 1 + +extern "C" { + #include "emuapi.h" + #include "iopins.h" +} + +#ifdef HAS_T4_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif + +#ifdef HAS_USBKEY +#include "USBHost_t36.h" // Read this header first for key info +USBHost myusb; +USBHub hub1(myusb); +KeyboardController keyboard1(myusb); +USBHIDParser hid1(myusb); +MouseController mouse1(myusb); +MIDIDevice midi1(myusb); +#endif + +static bool emu_writeConfig(void); +static bool emu_readConfig(void); +static bool emu_eraseConfig(void); + +static bool mouseDetected = false; +static bool keyboardDetected = false; +static uint8_t usbnavpad=0; + +#include +static File file; + +#define MAX_FILES 64 +#define AUTORUN_FILENAME "autorun.txt" + +#define MAX_FILENAME_SIZE 24 +#define MAX_MENULINES 9 +#define TEXT_HEIGHT 16 +#define TEXT_WIDTH 8 +#define MENU_FILE_XOFFSET (2*TEXT_WIDTH) +#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) +#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) +#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) +#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40) +#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT) +#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH) +#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET) + +#define MENU_TFT_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) +#define MENU_TFT_YOFFSET (MENU_VBAR_YOFFSET+32) +#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) +#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) + +extern TFT_T_DMA tft; + +static int nbFiles=0; +static int curFile=0; +static int topFile=0; +static char selection[MAX_FILENAME_PATH]=""; +static char second_selection[MAX_FILENAME_PATH]=""; +static char files[MAX_FILES][MAX_FILENAME_SIZE]; +static char selected_filename[MAX_FILENAME_SIZE]=""; +static char second_selected_filename[MAX_FILENAME_SIZE]=""; +static bool menuRedraw=true; +static bool autorun=false; + +static const unsigned short * keys; +#ifdef TEECOMPUTER +static unsigned char keymatrix[6]; +static int keymatrix_hitrow=-1; +static uint32_t keypress_t_ms=0; +static uint32_t last_t_ms=0; +static uint32_t hundred_ms_cnt=0; +static bool ledflash_toggle=false; +#endif +static bool key_extmode=false; +static bool key_sh=false; +static bool key_fn=false; + +static boolean joySwapped = false; +static uint16_t bLastState; +#ifdef PIN_JOY2_A1X +static int xRef; +static int yRef; +#endif +static bool menuOn=true; + + +/******************************** + * Generic output and malloc +********************************/ +void emu_printf(const char * text) +{ + Serial.println(text); +} + +void emu_printf(int val) +{ + Serial.println(val); +} + +void emu_printi(int val) +{ + Serial.println(val); +} + +void emu_printh(int val) +{ + Serial.println(val,HEX); +} + +static int malbufpt = 0; +static char malbuf[EXTRA_HEAP]; + +void * emu_Malloc(unsigned int size) +{ + void * retval = malloc(size); + if (!retval) { + emu_printf("failled to allocate"); + emu_printf(size); + emu_printf("fallback"); + if ( (malbufpt+size) < sizeof(malbuf) ) { + retval = (void *)&malbuf[malbufpt]; + malbufpt += size; + } + else { + emu_printf("failure to allocate"); + } + } + else { + emu_printf("could allocate dynamic "); + emu_printf(size); + } + + return retval; +} + +void * emu_MallocI(unsigned int size) +{ + void * retval = NULL; + + if ( (malbufpt+size) < sizeof(malbuf) ) { + retval = (void *)&malbuf[malbufpt]; + malbufpt += size; + emu_printf("could allocate static "); + emu_printf(size); + } + else { + emu_printf("failure to allocate"); + } + + return retval; +} +void emu_Free(void * pt) +{ + free(pt); +} + +/******************************** + * Input and keyboard +********************************/ +#ifdef PIN_JOY2_A1X +int emu_ReadAnalogJoyX(int min, int max) +{ + int val = analogRead(PIN_JOY2_A1X); +#if INVX + val = 4095 - val; +#endif + val = val-xRef; + val = ((val*140)/100); + if ( (val > -512) && (val < 512) ) val = 0; + val = val+2048; + return (val*(max-min))/4096; +} +#endif + +#ifdef PIN_JOY2_A2Y +int emu_ReadAnalogJoyY(int min, int max) +{ + int val = analogRead(PIN_JOY2_A2Y); +#if INVY + val = 4095 - val; +#endif + val = val-yRef; + val = ((val*120)/100); + if ( (val > -512) && (val < 512) ) val = 0; + //val = (val*(max-min))/4096; + val = val+2048; + //return val+(max-min)/2; + return (val*(max-min))/4096; +} +#endif + +static uint16_t readAnalogJoystick(void) +{ + uint16_t joysval = 0; + +#ifdef PIN_JOY2_A1X + int xReading = emu_ReadAnalogJoyX(0,256); + if (xReading > 128) joysval |= MASK_JOY2_LEFT; + else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; + + int yReading = emu_ReadAnalogJoyY(0,256); + if (yReading < 128) joysval |= MASK_JOY2_UP; + else if (yReading > 128) joysval |= MASK_JOY2_DOWN; +#endif + +#ifdef PIN_JOY2_BTN + joysval |= (digitalRead(PIN_JOY2_BTN) == HIGH ? 0 : MASK_JOY2_BTN); +#endif + return (joysval); +} + + +int emu_SwapJoysticks(int statusOnly) { + if (!statusOnly) { + if (joySwapped) { + joySwapped = false; + } + else { + joySwapped = true; + } + } + return(joySwapped?1:0); +} + +int emu_GetPad(void) +{ + return(bLastState/*|((joySwapped?1:0)<<7)*/); +} + +int emu_ReadKeys(void) +{ + uint16_t retval; + uint16_t j1 = readAnalogJoystick(); + uint16_t j2 = 0; + + // Second joystick +#ifdef PIN_JOY1_1 + if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_UP; +#endif +#ifdef PIN_JOY1_2 + if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_DOWN; +#endif +#ifdef PIN_JOY1_3 + if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_RIGHT; +#endif +#ifdef PIN_JOY1_4 + if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_LEFT; +#endif +#ifdef PIN_JOY1_BTN + if ( digitalRead(PIN_JOY1_BTN) == LOW ) j2 |= MASK_JOY2_BTN; +#endif + if (joySwapped) { + retval = ((j1 << 8) | j2); + } + else { + retval = ((j2 << 8) | j1); + } + + if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP; + if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN; + if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT; + if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT; + if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN; + if (usbnavpad & MASK_KEY_USER1) retval |= MASK_KEY_USER1; + if (usbnavpad & MASK_KEY_USER2) retval |= MASK_KEY_USER2; + +#ifdef PIN_KEY_USER1 + if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1; +#endif +#ifdef PIN_KEY_USER2 + if ( digitalRead(PIN_KEY_USER2) == LOW ) retval |= MASK_KEY_USER2; +#endif +#ifdef PIN_KEY_USER3 + if ( digitalRead(PIN_KEY_USER3) == LOW ) retval |= MASK_KEY_USER3; +#endif +#ifdef PIN_KEY_USER4 + if ( digitalRead(PIN_KEY_USER4) == LOW ) retval |= MASK_KEY_USER4; +#endif + +#ifdef TEECOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={KCOLOUT1,KCOLOUT2,KCOLOUT3,KCOLOUT4,KCOLOUT5,KCOLOUT6}; + for (int i=0;i<6;i++){ + pinMode(cols[i],OUTPUT); + digitalWrite(cols[i], 0); + row=0; + row |= (digitalRead(KROWIN1) ? 0 : 0x01); + row |= (digitalRead(KROWIN2) ? 0 : 0x02); + row |= (digitalRead(KROWIN3) ? 0 : 0x04); + row |= (digitalRead(KROWIN4) ? 0 : 0x08); + row |= (digitalRead(KROWIN5) ? 0 : 0x10); + row |= (digitalRead(KROWIN6) ? 0 : 0x20); + row |= (digitalRead(KROWIN7) ? 0 : 0x40); + digitalWrite(cols[i], 1); + pinMode(cols[i],INPUT_DISABLE); + keymatrix[i]=row; + } + + bool fn_pressed=false; + if ( keymatrix[5] & 0x08 ) {fn_pressed=true; keymatrix[5] &= ~0x08;}; + + bool sh_pressed=false; + if ( keymatrix[5] & 0x10 ) {sh_pressed=true; keymatrix[5] &= ~0x10;}; + + for (int i=0;i<6;i++){ + row = keymatrix[i]; + if (row) keymatrix_hitrow=i; + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x40 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x20 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x20 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x40 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x1 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x02 ) retval |= MASK_JOY2_BTN; + + // Handle LED flash + uint32_t time_ms=millis(); + if ((time_ms-last_t_ms) > 100) { + last_t_ms = time_ms; + if (ledflash_toggle == false) { + ledflash_toggle = true; + } + else { + ledflash_toggle = false; + } + } + + if ( sh_pressed ) { + key_sh = true; + } + else { + key_sh = false; + if ( fn_pressed ) { + if (key_fn == false) + { + // Release to Press transition + if (hundred_ms_cnt == 0) { + keypress_t_ms=time_ms; + hundred_ms_cnt += 1; // 1 + } + else { + hundred_ms_cnt += 1; // 2 + if (hundred_ms_cnt >= 2) + { + hundred_ms_cnt = 0; + if ( (time_ms-keypress_t_ms) < 500) + { + if (key_extmode == false) + { + key_extmode = true; + } + else + { + key_extmode = false; + } + } + } + } + } + else { + // Keep press + if (hundred_ms_cnt == 1) { + if ((millis()-keypress_t_ms) > 1000) + { + if (key_extmode == false) + { + key_extmode = true; + } + else + { + key_extmode = false; + } + hundred_ms_cnt = 0; + } + } + } + key_fn = true; + } + else { + key_fn = false; + } + } + + // Handle LED + if (key_extmode == true) { + digitalWrite(KLED, (ledflash_toggle?1:0)); + } + else { + if ( (key_fn == true) || (key_sh == true) ) { + digitalWrite(KLED, 1); + } + else { + digitalWrite(KLED, 0); + } + } + + if ( key_fn ) retval |= MASK_KEY_USER2; + if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; + + if ( (key_fn) && (key_sh) ) +#else + if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) + || (retval & MASK_KEY_USER4 ) ) +#endif + { +// Reset procedure T3.X and T4.0 by Frank Boesing !! +#if defined(__IMXRT1052__) || defined(__IMXRT1062__) + uint32_t tmp = SNVS_LPCR; // save control register + + SNVS_LPSR |= 1; + + // disable alarm + SNVS_LPCR &= ~0x02; + while (SNVS_LPCR & 0x02); + + __disable_irq(); + //get Time: + uint32_t lsb, msb; + do { + msb = SNVS_LPSRTCMR; + lsb = SNVS_LPSRTCLR; + } while ( (SNVS_LPSRTCLR != lsb) | (SNVS_LPSRTCMR != msb) ); + uint32_t secs = (msb << 17) | (lsb >> 15); + + //set alarm + secs += 2; + SNVS_LPTAR = secs; + while (SNVS_LPTAR != secs); + + SNVS_LPCR = tmp | 0x02; // restore control register and set alarm + while (!(SNVS_LPCR & 0x02)); + + SNVS_LPCR |= (1 << 6); // turn off power + while (1) asm("wfi"); +#else + *(volatile uint32_t *)0xE000ED0C = 0x5FA0004; + while (true) { + ; + } +#endif + } + + return (retval); +} + +unsigned short emu_DebounceLocalKeys(void) +{ + uint16_t bCurState = emu_ReadKeys(); + uint16_t bClick = bCurState & ~bLastState; + bLastState = bCurState; + + return (bClick); +} + +int emu_ReadI2CKeyboard(void) { + int retval=0; +#ifdef TEECOMPUTER + if (key_extmode) { + if (key_fn) { + keys = (const unsigned short *)key_map5; // fn-extra + } + else if (key_sh) { + keys = (const unsigned short *)key_map4; // shift-functionkeys + } + else { + keys = (const unsigned short *)key_map3; // def-digitkeys + } + } + else { + if (key_fn) { + keys = (const unsigned short *)key_map2; // fn-shiftothers + } + else if (key_sh) { + keys = (const unsigned short *)key_map1; // shift-uppercase + } + else { + keys = (const unsigned short *)key_map0; // def-lowercase + } + } + + + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (unsigned int i=0; i= 128) { + midiDataCnt = 0; + midiLastCmd = value; + switch (value & 0xF0) { + case 128: // 0x80 + midiCmdNbParam = 2; + //Serial.print("note off: "); + //Serial.println(value&0xf); + break; + case 144: //0x90 + midiCmdNbParam = 2; + //Serial.print("note on: "); + //Serial.println(value&0xf); + break; + case 160: //0xA0 + midiCmdNbParam = 2; + //Serial.print("aftertouch: "); // rare + //Serial.println(value&0xf); + break; + case 176: //0xB0 + midiCmdNbParam = 2; + //Serial.print("continuous controller: "); + //Serial.println(value&0xf); + break; + case 192: //0xC0 + midiCmdNbParam = 1; + //Serial.print("patch change: "); //some + //Serial.println(value&0xf); + break; + case 208: //0xD0 + midiCmdNbParam = 1; + Serial.print("channel pressure: "); + Serial.println(value&0xf); + break; + case 224: //0xE0 + midiCmdNbParam = 2; + //Serial.print("pitch bend: "); + //Serial.println(value&0xf); + break; + case 240: //0xF0 + // non-musical commands + switch (value) { + case 0xF0: + //Serial.println("NI: System Exclusive"); + break; + case 0xF1: + //Serial.println("NI: System Common - MIDI Time Code Quarter Frame"); + break; + case 0xF2: + midiCmdNbParam = 2; + break; + case 0xF3: + //Serial.println("NI: System Common - Song Select"); + break; + case 0xF6: + //Serial.println("NI: System Common - Tune Request"); + break; + case 0xF8: + //Serial.println("System Real Time - Timing Clock"); + midi1.sendRealTime(value, 0); + break; + case 0xFA: + //Serial.println("System Real Time - Start"); + midi1.sendRealTime(value, 0); + break; + case 0xFB: + //Serial.println("System Real Time - Continue"); + midi1.sendRealTime(value, 0); + break; + case 0xFC: + //Serial.println("System Real Time - Stop"); + midi1.sendRealTime(value, 0); + break; + case 0xFE: + //Serial.println("System Real Time - Active Sensing"); + midi1.sendRealTime(value, 0); + break; + case 0xFF: + //Serial.println("System Real Time - System Reset"); + midi1.sendRealTime(value, 0); + break; + } + //SystemExclusive = 0xF0, // System Exclusive + //TimeCodeQuarterFrame = 0xF1, // System Common - MIDI Time Code Quarter Frame + //SongPosition = 0xF2, // System Common - Song Position Pointer + //SongSelect = 0xF3, // System Common - Song Select + //TuneRequest = 0xF6, // System Common - Tune Request + //Clock = 0xF8, // System Real Time - Timing Clock + //Start = 0xFA, // System Real Time - Start + //Continue = 0xFB, // System Real Time - Continue + //Stop = 0xFC, // System Real Time - Stop + //ActiveSensing = 0xFE, // System Real Time - Active Sensing + //SystemReset = 0xFF, // System Real Time - System Reset + break; + default: + Serial.print("??: "); + Serial.println(value&0xf); + break; + } + } + else { + if (midiDataCnt<16) midiBuffer[midiDataCnt++] = value ; + if ( (midiLastCmd & 0xF0) == 240) { + if (midiLastCmd == 0xF2) { + if (midiDataCnt == midiCmdNbParam) { + //Serial.println("System Common - Song Position Pointer"); + midi1.sendSongPosition(((int)midiBuffer[1]<<7)+(int)midiBuffer[0], 0); + } + } + else { + Serial.println(value); + } + } + else if (midiDataCnt == midiCmdNbParam) { + unsigned char chan = (midiLastCmd&0xf)+1; + //Serial.print("ch "); + //Serial.println(chan); + switch (midiLastCmd & 0xF0) { + case 128: //0x80 + //Serial.print("note off: "); + midi1.sendNoteOff(midiBuffer[0], midiBuffer[1], chan); + break; + case 144: //0x90 + //Serial.print("note on: "); + midi1.sendNoteOn(midiBuffer[0], midiBuffer[1], chan); + break; + case 160: //0xA0 + //Serial.print("aftertouch: "); + midi1.sendPolyPressure(midiBuffer[0], midiBuffer[1], chan); + break; + case 176: //0xB0 + //Serial.print("continuous controller: "); + midi1.sendControlChange(midiBuffer[0], midiBuffer[1], chan); + break; + case 192: //0xC0 + //Serial.print("patch change: "); + midi1.sendProgramChange(midiBuffer[0], chan); + break; + case 208: //0xD0 + //Serial.print("channel pressure: "); + midi1.sendAfterTouch(midiBuffer[0], chan); + break; + case 224: //0xE0 + //Serial.print("pitch bend: "); + midi1.sendPitchBend((((int)midiBuffer[1]<<7)+(int)midiBuffer[0])-8192, chan); + break; + default: + Serial.print("??: "); + break; + } + } + } +#endif +} + +/******************************** + * Menu file loader UI +********************************/ +static int readNbFiles(void) { + int totalFiles = 0; + + File entry; + file = SD.open(selection); + while ( (true) && (totalFiles=0) { + menuRedraw=true; + curFile -= 9; + } else if (curFile!=0) { + menuRedraw=true; + curFile--; + } + } + else if ( (bClick & MASK_JOY2_DOWN) || (bClick & MASK_JOY1_DOWN) ) { + if ((curFile<(nbFiles-1)) && (nbFiles)) { + curFile++; + menuRedraw=true; + } + } + else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { + if ((curFile<(nbFiles-9)) && (nbFiles)) { + curFile += 9; + menuRedraw=true; + } + else if ((curFile<(nbFiles-1)) && (nbFiles)) { + curFile++; + menuRedraw=true; + } + } + + if (menuRedraw && nbFiles) { + int fileIndex = 0; + tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR); +// if (curFile <= (MAX_MENULINES/2-1)) topFile=0; +// else topFile=curFile-(MAX_MENULINES/2); + if (curFile <= (MAX_MENULINES-1)) topFile=0; + else topFile=curFile-(MAX_MENULINES/2); + + //Serial.print("curfile: "); + //Serial.println(curFile); + //Serial.print("topFile: "); + //Serial.println(topFile); + + int i=0; + while (i=nbFiles) { + // no more files + break; + } + char * filename = &files[fileIndex][0]; + if (fileIndex >= topFile) { + if ((i+topFile) < nbFiles ) { + if ((i+topFile)==curFile) { + tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); + strcpy(selected_filename,filename); + } + else { + tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true); + } + } + i++; + } + fileIndex++; + } + + +// tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); + tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, "FLOPPY2:", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); + tft.drawRectNoDma(120,MENU_JOYS_YOFFSET+8, MENU_FILE_W, 8, RGBVAL16(0x00,0x00,0x00)); + tft.drawTextNoDma(120,MENU_JOYS_YOFFSET+8, second_selected_filename, RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), false); + menuRedraw=false; + } + + return (action); +} + +bool menuActive(void) +{ + return (menuOn); +} + +void toggleMenu(bool on) { + if (on) { + menuOn=true; + backgroundMenu(); + } else { + menuOn = false; + } +} + +char * menuSelection(void) +{ + return (selection); +} + +char * menuSecondSelection(void) +{ + return (second_selection); +} + + +/******************************** + * OSKB handling +********************************/ +static bool oskbOn = false; +static int cxpos = 0; +static int cypos = 0; +static uint16_t oskbBLastState = 0; +#define OSKBHEIGHT 4 +#define OSKBXOFF 16 +#define OSKBYOFF 0 + +static void lineOSKB(int xoff, bool bottom, char * str, int row) +{ + char c[4] = {' ',0,' ',0}; + const char * cpt = str; + int i=0; + int fb_width,fb_height; + tft.get_frame_buffer_size(&fb_width, &fb_height); + int ypos = (bottom?(fb_height-2*8):0); + int line = row + (bottom?2:0); + while ((c[1] = *cpt++)) + { + uint16_t bg; + if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); + else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff); + if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); + tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); + i++; + } +} + +static int linelenOSKB() { + if (cypos == 0) return strlen(keylables_map0_0); + else if (cypos == 1) return strlen(keylables_map0_1); + else if (cypos == 2) return strlen(keylables_map0_2); + else return strlen(keylables_map0_3); +} + +static void drawOSKB() { + if (key_extmode) { + if (key_fn) { + lineOSKB(16,false, keylables_map5_0, 0); + lineOSKB(8, false, keylables_map5_1, 1); + lineOSKB(0, true, keylables_map5_2, 0); + lineOSKB(96,true, keylables_map5_3, 1); + } + else if (key_sh) { + lineOSKB(16,false, keylables_map4_0, 0); + lineOSKB(8, false, keylables_map4_1, 1); + lineOSKB(0, true, keylables_map4_2, 0); + lineOSKB(96,true, keylables_map4_3, 1); + } + else { + lineOSKB(16,false, keylables_map3_0, 0); + lineOSKB(8, false, keylables_map3_1, 1); + lineOSKB(0, true, keylables_map3_2, 0); + lineOSKB(96,true, keylables_map3_3, 1); + } + } + else { + if (key_fn) { + lineOSKB(16,false, keylables_map2_0, 0); + lineOSKB(8, false, keylables_map2_1, 1); + lineOSKB(0, true, keylables_map2_2, 0); + lineOSKB(96,true, keylables_map2_3, 1); + } + else if (key_sh) { + lineOSKB(16,false, keylables_map1_0, 0); + lineOSKB(8, false, keylables_map1_1, 1); + lineOSKB(0, true, keylables_map1_2, 0); + lineOSKB(96,true, keylables_map1_3, 1); + } + else { + lineOSKB(16,false, keylables_map0_0, 0); + lineOSKB(8, false, keylables_map0_1, 1); + lineOSKB(0, true, keylables_map0_2, 0); + lineOSKB(96,true, keylables_map0_3, 1); + } + } +} + +int handleOSKB(void) { + int retval = 0; + if (oskbOn) { + uint16_t bClick = bLastState & ~oskbBLastState; + oskbBLastState = bLastState; + bool updated = true; + if (bClick & MASK_KEY_USER1) + { + } + else if (bClick & MASK_JOY2_RIGHT) + { + cxpos++; + if (cxpos >= linelenOSKB()) cxpos = 0; + } + else if (bClick & MASK_JOY2_LEFT) + { + cxpos--; + if (cxpos < 0) cxpos = linelenOSKB()-1; + } + else if (bClick & MASK_JOY2_DOWN) + { + cypos++; + if (cypos >= OSKBHEIGHT) cypos = 0; + if (cxpos >= linelenOSKB()) cxpos = linelenOSKB()-1; + } + else if (bClick & MASK_JOY2_UP) + { + cypos--; + if (cypos < 0) cypos = OSKBHEIGHT-1; + if (cxpos >= linelenOSKB()) cxpos = linelenOSKB()-1; + } + else if (oskbBLastState & MASK_JOY2_BTN) + { + //if (retval) { toggleOSKB(false); updated=false; }; + } + else { + updated=false; + } + /*if (updated)*/ drawOSKB(); + } + return retval; +} + +void toggleOSKB(bool forceon) { + if (forceon) { + oskbOn = true; + drawOSKB(); + } + else { + if (oskbOn) { + oskbOn = false; + } + else { + oskbOn = true; + drawOSKB(); + } + } +} + + + +/******************************** + * File IO +********************************/ +static File file_handlers[NB_FILE_HANDLER]; + +static void FileHandlersInit(void) { + for (int i=0; i= 0) { + if ((file_handlers[handler] = SD.open(filepath, O_READ))) { + // emu_printi(handler+1); + retval = handler+1; + } + else { + file_handlers[handler] = file; + emu_printf("FileOpen failed"); + } + } + return (retval); +#endif +} + +int emu_FileRead(void * buf, int size, int handler) +{ +// emu_printf("FileRead"); +// emu_printi(handler); +#ifdef HCFH + return (file.read(buf, size)); +#else + return (getFileHandler(handler).read(buf, size)); +#endif +} + +int emu_FileGetc(int handler) { +// emu_printf("FileGetc"); +// emu_printi(handler); +#ifdef HCFH + unsigned char c; + int retval = file.read(&c, 1); + if (retval != 1) { + emu_printf("emu_FileGetc failed"); + } + return (int)c; +#else + unsigned char c; + int retval = getFileHandler(handler).read(&c, 1); + if (retval != 1) { + emu_printf("emu_FileGetc failed"); + } + return (int)c; +#endif +} + +int emu_FileSeek(int handler, int seek, int origin) +{ +// emu_printf("FileSeek"); +// emu_printi(handler); +// emu_printi(seek); +#ifdef HCFH + file.seek(seek); + return (seek); +#else + getFileHandler(handler).seek(seek); + return (seek); +#endif +} + +int emu_FileTell(int handler) { +// emu_printf("FileTell"); +// emu_printi(handler); +#ifdef HCFH + return (50); +#else + File file = getFileHandler(handler); + return (emu_FileSize((char*)file.name())); +#endif +} + + +void emu_FileClose(int handler) +{ +// emu_printf("FileClose"); +// emu_printi(handler); +#ifdef HCFH + file.close(); +#else + getFileHandler(handler).close(); + file_handlers[handler-1] = file; +#endif +} + + +static File lofile; + +unsigned int emu_FileSize(const char * filepath) +{ + unsigned int filesize=0; + emu_printf(filepath); + if ((lofile = SD.open(filepath, O_READ))) + { + emu_printf("filesize is..."); + filesize = lofile.size(); + emu_printf(filesize); + lofile.close(); + } + return(filesize); +} + +unsigned int emu_LoadFile(const char * filepath, void * buf, int size) +{ + unsigned int filesize = 0; + emu_printf("LoadFile..."); + emu_printf(filepath); + if ((lofile = SD.open(filepath, O_READ))) + { + filesize = lofile.size(); + emu_printf(filesize); + if ((unsigned int)size >= filesize) + { + if (lofile.read(buf, filesize) != filesize) + { + emu_printf("File read failed"); + } + } + lofile.close(); + } + return(filesize); +} + +unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek) +{ + unsigned int filesize = 0; + emu_printf("LoadFileSeek..."); + emu_printf(filepath); + if ((lofile = SD.open(filepath, O_READ))) + { + lofile.seek(seek); + emu_printf(size); + if (lofile.read(buf, size) != (unsigned int)size) { + emu_printf("File read failed"); + } + lofile.close(); + } + return(filesize); +} + +static bool emu_writeConfig(void) +{ + bool retval = false; + if ((lofile = SD.open(ROMSDIR "/" AUTORUN_FILENAME, O_CREAT | O_WRITE))) + { + if (lofile.write(selection, strlen(selection)) != strlen(selection)) { + emu_printf("Config write failed"); + } + else { + retval = true; + } + lofile.close(); + } + return retval; +} + +static bool emu_readConfig(void) +{ + bool retval = false; + + if ((lofile = SD.open(ROMSDIR "/" AUTORUN_FILENAME, O_READ))) + { + unsigned int filesize = lofile.size(); + unsigned int sizeread = lofile.read(selection, filesize); + if (sizeread != filesize) { + emu_printf("Config read failed"); + } + else { + if (sizeread == filesize) + { + selection[filesize]=0; + retval = true; + } + } + lofile.close(); + } + return retval; +} + +static bool emu_eraseConfig(void) +{ + SD.remove (ROMSDIR "/" AUTORUN_FILENAME); +} + +/******************************** + * File IO compatibility +********************************/ +#ifdef HAS_EXTFF + +#include "ff.h" + +typedef struct { + File f; + int offset; + int size; + int used; +} FileDesc; + +typedef int * FIL; + + + +#define NO_MMAP_HANDLES 32 + +static FileDesc fds[NO_MMAP_HANDLES]; +static int nextHandle=0; + +static void freeHandle(int h) { + fds[h].used = 0; +} + + +static int getFreeHandle() { + int n=NO_MMAP_HANDLES; + while (fds[nextHandle].used!=0 && n!=0) { + nextHandle++; + if (nextHandle==NO_MMAP_HANDLES) nextHandle=0; + n-1; + } + if (n==0) { + emu_printf("getFreeHandle error"); + return; + } + + int r=nextHandle; + fds[r].used = 1; + nextHandle++; + if (nextHandle==NO_MMAP_HANDLES) nextHandle=0; + + return r; +} + +FRESULT f_open (FIL* fp, const char * path, unsigned char mode) +{ + emu_printf("fopen"); + emu_printf((char*)path); + int i=getFreeHandle(); + emu_printf(i); + fds[i].f = SD.open(path, O_READ); + *fp = i; + if (fds[i].f) { + fds[i].size = fds[i].f.size(); + emu_printi(fds[i].size); + return(FR_OK); + } + emu_printf("error"); + freeHandle(fds[i].f); + return(FR_NO_FILE); +} + +FRESULT f_close (FIL* fp) +{ + int i = *fp; + emu_printf("fclose"); + emu_printi(i); + fds[i].f.close(); + freeHandle(i); + return(FR_OK); +} + +FRESULT f_read (FIL* fp, void* buff, unsigned int btr, unsigned int * br) +{ + int i = *fp; + + if (btr < 64738) { + int nr = fds[i].f.read(buff, btr); + //emu_printf("fread"); + //emu_printi(btr); + //emu_printi(nr); + *br = nr; + if (nr <= 0) + return(FR_DISK_ERR); + else + return(FR_OK); + } + + unsigned char buffer[256]; + + int remaining = btr; + int byteread = 0; + int retval=0; + + while (remaining>0) { + if (remaining < 256) + retval = fds[i].f.read(buffer, remaining); + else + retval = fds[i].f.read(buffer, 256); + if (retval>0) { + memcpy(buff,buffer,retval); + buff += retval; + byteread += retval; + remaining -= retval; + } + else { + break; + } + } + *br = byteread; + //emu_printi(byteread); + if (byteread <= 0) + return(FR_DISK_ERR); + else + return(FR_OK); +} + +FRESULT f_readn (FIL* fp, void* buff, unsigned int btr, unsigned int * br) +{ + return(f_read (fp, buff, btr, br)); +} + +FRESULT f_write (FIL* fp, const void* buff, unsigned int btw, unsigned int * bw) +{ + return(FR_OK); +} +FRESULT f_writen (FIL* fp, const void* buff, unsigned int btw, unsigned int * bw) +{ + return(FR_OK); +} +FRESULT f_lseek (FIL* fp, unsigned long ofs) +{ + int i = *fp; + //emu_printf("fseek"); + //emu_printi(ofs); + fds[i].f.seek(ofs); + return(FR_OK); +} + + +FRESULT f_unlink (const char * path) +{ + return(FR_OK); +} +FRESULT f_rename (const char * path_old, const char * path_new) +{ + return(FR_OK); +} +FRESULT f_stat (const char * path, FILINFO* fno) +{ + return(FR_OK); +} + +unsigned long f_tell (FIL * fp) +{ + int i = *fp; + emu_printf("ftell"); + return(fds[i].size); + //return(fds[i].f.ftell()); +} + +unsigned long f_size (FIL * fp) +{ + int i = *fp; + emu_printf("fsize"); + emu_printi(fds[i].size); + return(fds[i].size); +} + +FRESULT f_mkdir (const char* path) +{ + return(FR_OK); +} +#endif + + +/******************************** + * Initialization +********************************/ +void emu_init(void) +{ + Serial.begin(115200); + +#ifdef HAS_USBKEY + myusb.begin(); + keyboard1.attachPress(OnPress); + keyboard1.attachRelease(OnRelease); +#endif + + while (!SD.begin(SD_CS)) + { + Serial.println("SD begin failed, retrying..."); + delay(1000); + } + strcpy(selection,ROMSDIR); + + FileHandlersInit(); + + nbFiles = readNbFiles(); + + Serial.print("SD initialized, files found: "); + Serial.println(nbFiles); + + emu_InitJoysticks(); +#ifdef SWAP_JOYSTICK + joySwapped = true; +#else + joySwapped = false; +#endif + +#ifdef TEECOMPUTER +#ifndef HAS_T4_VGA + tft.flipscreen(false); +#endif +#endif + int keypressed = emu_ReadKeys(); + if (keypressed & MASK_JOY2_DOWN) { + tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); + tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); + emu_eraseConfig(); + delay(1000); + } + else { + if (emu_readConfig()) { + autorun = true; + } + } + + toggleMenu(true); +} + + +void emu_start(void) +{ + usbnavpad = 0; +} diff --git a/MCUME_teensy41/teensy800/emuapi.h b/MCUME_teensy41/teensy800/emuapi.h new file mode 100644 index 0000000..1e2327c --- /dev/null +++ b/MCUME_teensy41/teensy800/emuapi.h @@ -0,0 +1,214 @@ +#ifndef EMUAPI_H +#define EMUAPI_H + +#include "platform_config.h" + +#define CUSTOM_SND 1 +//#define TIMER_REND 1 +#define EXTRA_HEAP 0x10 + +// Title: < > +#define TITLE " Atari 800 Emulator" +#define ROMSDIR "800" + +#define emu_Init(ROM) {at8_Init(); at8_Start(ROM);} +#define emu_Step(x) {at8_Step();} +#define emu_Input(x) {at8_Input(x);} + +#define MAX_FILENAME_PATH 64 +#define NB_FILE_HANDLER 4 +#define PALETTE_SIZE 256 +#define VID_FRAME_SKIP 0x0 +#define TFT_VBUFFER_YCROP 0 +#define SINGLELINE_RENDERING 1 + +#define R32(rgb) ((rgb>>16)&0xff) +#define G32(rgb) ((rgb>>8)&0xff) +#define B32(rgb) (rgb & 0xff) + +#define ACTION_NONE 0 +#define ACTION_MAXKBDVAL 16 +#define ACTION_EXITKBD 128 +#define ACTION_RUN1 129 +#define ACTION_RUN2 130 +#define ACTION_RUN3 131 + +#ifdef KEYMAP_PRESENT + +#define keylables_map0_0 (char *)"qwertyuiop\x1a" +#define keylables_map0_1 (char *)" asdfghjkl\x19" +#define keylables_map0_2 (char *)" zxcvbnm,.;/" +#define keylables_map0_3 (char *)" +\x10-" +const unsigned short key_map0[] = { + 'q','w','e','r','t','y','u','i','o','p',127, //lowecase + 0,'a','s','d','f','g','h','j','k','l',10, + 0,'z','x','c','v','b','n','m',',','.',';','/', + 0,0,0,0, + 0,'+',' ','-' + }; + +#define keylables_map1_0 (char *)" \x1a" +#define keylables_map1_1 (char *)" \x19" +#define keylables_map1_2 (char *)" <>:?" +#define keylables_map1_3 (char *)" =\x10 " +const unsigned short key_map1[] = { + '1','2','3','4','5','6','7','8','9','0',127, // digit keys + 0, 0,0,0,0,0,0,0,0,0,10, + 0, 0,0,0,0,0,0,0,'<','>',':','?', + 154,152,151,153, //U L R D + 0,'=',' ',0 + }; + +#define keylables_map2_0 (char *)"!\"#$%^&*()@" +#define keylables_map2_1 (char *)" \x19" +#define keylables_map2_2 (char *)" <>:?" +#define keylables_map2_3 (char *)" =\x10 " +const unsigned short key_map2[] = { + '!','"','#','$','%','^','&','*','(',')','@', // shiftothers + 9, 0,0,0,0,0,0,0,0,0,10, + 0, 0,0,0,0,0,0,0,'<','>',':','?', + 154,152,151,153, //U L R D + 0,'=',' ',0 + }; + +#define keylables_map3_0 (char *)"1234567890 " +#define keylables_map3_1 (char *)" " +#define keylables_map3_2 (char *)" " +#define keylables_map3_3 (char *)" " + +const unsigned short key_map3[] = { + '1','2','3','4','5','6','7','8','9','0',0, // digit keys + 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0,0,0,0,0,0,0,0,0,0,0, + 154,152,151,153, //U L R D + 0,0,' ',0 + }; + +#define keylables_map4_0 (char *)" " +#define keylables_map4_1 (char *)" " +#define keylables_map4_2 (char *)" " +#define keylables_map4_3 (char *)" " + +const unsigned short key_map4[] = { + 0,0,0,0,0,0,0,0,0,0,0, // function keys + 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0,0,0,0,0,0,0,0,0,0,0, + 154,152,151,153, //U L R D + 0,0,' ',0 + }; + +#define keylables_map5_0 (char *)" " +#define keylables_map5_1 (char *)" " +#define keylables_map5_2 (char *)" " +#define keylables_map5_3 (char *)" " + +const unsigned short key_map5[] = { + 0,0,0,0,0,0,0,0,0,0,0, // extra keys + 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0,0,0,0,0,0,0,0,0,0,0, + 154,152,151,153, //U L R D + 0,0,' ',0 + }; + +const unsigned short matkeys[] = { + 0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1 + 0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2 + 0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3 + 0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN + 0x510,0x010,0x110,0x310, // row 4 + }; + +#endif + + +#define MASK_JOY2_RIGHT 0x0001 +#define MASK_JOY2_LEFT 0x0002 +#define MASK_JOY2_UP 0x0004 +#define MASK_JOY2_DOWN 0x0008 +#define MASK_JOY2_BTN 0x0010 +#define MASK_KEY_USER1 0x0020 +#define MASK_KEY_USER2 0x0040 +#define MASK_KEY_USER3 0x0080 +#define MASK_JOY1_RIGHT 0x0100 +#define MASK_JOY1_LEFT 0x0200 +#define MASK_JOY1_UP 0x0400 +#define MASK_JOY1_DOWN 0x0800 +#define MASK_JOY1_BTN 0x1000 +#define MASK_KEY_USER4 0x2000 + + +#ifdef __cplusplus +extern "C" { +#else +#define bool unsigned char +#endif + +extern void emu_init(void); +extern void emu_start(void); +extern void emu_printf(const char * text); +extern void emu_printi(int val); +extern void emu_printh(int val); +extern void * emu_Malloc(unsigned int size); +extern void * emu_MallocI(unsigned int size); +extern void emu_Free(void * pt); + +extern int emu_FileOpen(const char * filepath, const char * mode); +extern int emu_FileRead(void * buf, int size, int handler); +extern int emu_FileGetc(int handler); +extern int emu_FileSeek(int handler, int seek, int origin); +extern int emu_FileTell(int handler); +extern void emu_FileClose(int handler); + +extern unsigned int emu_FileSize(const char * filepath); +extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size); +extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); + +extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); +extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); +extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line); +extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); +extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); +extern void emu_CopyLine(int width, int height, int ysrc, int ydst); +extern void emu_DrawVsync(void); +extern int emu_FrameSkip(void); +extern void * emu_LineBuffer(int line); +extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); + +extern bool menuActive(void); +extern char * menuSelection(void); +extern char * menuSecondSelection(void); +extern void toggleMenu(bool on); +extern int handleMenu(unsigned short bClick); + +extern int handleOSKB(void); +extern void toggleOSKB(bool forceon); + +extern void emu_InitJoysticks(void); +extern int emu_SwapJoysticks(int statusOnly); +extern unsigned short emu_DebounceLocalKeys(void); +extern int emu_ReadKeys(void); +extern int emu_GetPad(void); +extern int emu_GetMouse(int *x, int *y, int *buts); +extern int emu_MouseDetected(void); +extern int emu_KeyboardDetected(void); +extern int emu_ReadAnalogJoyX(int min, int max); +extern int emu_ReadAnalogJoyY(int min, int max); +extern int emu_ReadI2CKeyboard(void); +extern unsigned char emu_ReadI2CKeyboard2(int row); +extern void emu_KeyboardOnUp(int keymodifer, int key); +extern void emu_KeyboardOnDown(int keymodifer, int key); +extern void emu_MidiOnDataReceived(unsigned char data); + +extern void emu_sndPlaySound(int chan, int volume, int freq); +extern void emu_sndPlayBuzz(int size, int val); +extern void emu_sndInit(); +extern void emu_resetus(void); +extern int emu_us(void); + +extern int emu_setKeymap(int index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/MCUME_teensy41/teensy800/font8x8.h b/MCUME_teensy41/teensy800/font8x8.h new file mode 100644 index 0000000..a0913e4 --- /dev/null +++ b/MCUME_teensy41/teensy800/font8x8.h @@ -0,0 +1,148 @@ + +// Font: c64_lower.64c + +PROGMEM const unsigned char font8x8[128][8] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + + { 0x7f, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7f, 0x00 }, // Space // 0x10 + { 0x00, 0x27, 0x31, 0x27, 0x21, 0x71, 0x00, 0x00 }, // F1 // 0x11 + { 0x00, 0x77, 0x41, 0x77, 0x11, 0x71, 0x00, 0x00 }, // F2 + { 0x00, 0x77, 0x41, 0x77, 0x41, 0x71, 0x00, 0x00 }, // F3 + { 0x00, 0x17, 0x51, 0x77, 0x41, 0x41, 0x00, 0x00 }, // F4 + { 0x00, 0x77, 0x11, 0x77, 0x41, 0x71, 0x00, 0x00 }, // F5 + { 0x00, 0x77, 0x11, 0x77, 0x51, 0x71, 0x00, 0x00 }, // F6 + { 0x00, 0x77, 0x41, 0x47, 0x41, 0x41, 0x00, 0x00 }, // F7 + { 0x00, 0x77, 0x51, 0x77, 0x51, 0x71, 0x00, 0x00 }, // F8 // 0x18 + { 0x00, 0x00, 0x20, 0x24, 0x3e, 0x04, 0x00, 0x00 }, // Return // 0x19 + { 0x00, 0x59, 0x4b, 0x5b, 0x4b, 0xd9, 0x00, 0x00 }, // Del // 0x1A + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (//) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; + + diff --git a/MCUME_teensy41/teensy800/gtia.c b/MCUME_teensy41/teensy800/gtia.c new file mode 100644 index 0000000..1d3612c --- /dev/null +++ b/MCUME_teensy41/teensy800/gtia.c @@ -0,0 +1,1330 @@ +/* + * gtia.c - GTIA chip emulation + * + * Copyright (C) 1995-1998 David Firth + * Copyright (C) 1998-2015 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Atari800 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include "antic.h" +#include "gtia.h" + +/* GTIA Registers ---------------------------------------------------------- */ + +UBYTE GTIA_M0PL; +UBYTE GTIA_M1PL; +UBYTE GTIA_M2PL; +UBYTE GTIA_M3PL; +UBYTE GTIA_P0PL; +UBYTE GTIA_P1PL; +UBYTE GTIA_P2PL; +UBYTE GTIA_P3PL; +UBYTE GTIA_HPOSP0; +UBYTE GTIA_HPOSP1; +UBYTE GTIA_HPOSP2; +UBYTE GTIA_HPOSP3; +UBYTE GTIA_HPOSM0; +UBYTE GTIA_HPOSM1; +UBYTE GTIA_HPOSM2; +UBYTE GTIA_HPOSM3; +UBYTE GTIA_SIZEP0; +UBYTE GTIA_SIZEP1; +UBYTE GTIA_SIZEP2; +UBYTE GTIA_SIZEP3; +UBYTE GTIA_SIZEM; +UBYTE GTIA_GRAFP0; +UBYTE GTIA_GRAFP1; +UBYTE GTIA_GRAFP2; +UBYTE GTIA_GRAFP3; +UBYTE GTIA_GRAFM; +UBYTE GTIA_COLPM0; +UBYTE GTIA_COLPM1; +UBYTE GTIA_COLPM2; +UBYTE GTIA_COLPM3; +UBYTE GTIA_COLPF0; +UBYTE GTIA_COLPF1; +UBYTE GTIA_COLPF2; +UBYTE GTIA_COLPF3; +UBYTE GTIA_COLBK; +UBYTE GTIA_PRIOR; +UBYTE GTIA_VDELAY; +UBYTE GTIA_GRACTL; + +/* Internal GTIA state ----------------------------------------------------- */ + +int GTIA_speaker; +int GTIA_consol_override = 0; +static UBYTE consol; +UBYTE consol_mask; +UBYTE GTIA_TRIG[4]; +UBYTE GTIA_TRIG_latch[4]; + +#if defined(BASIC) || defined(CURSES_BASIC) + +static UBYTE PF0PM = 0; +static UBYTE PF1PM = 0; +static UBYTE PF2PM = 0; +static UBYTE PF3PM = 0; +#define GTIA_collisions_mask_missile_playfield 0 +#define GTIA_collisions_mask_player_playfield 0 +#define GTIA_collisions_mask_missile_player 0 +#define GTIA_collisions_mask_player_player 0 + +#else /* defined(BASIC) || defined(CURSES_BASIC) */ + +void set_prior(UBYTE byte); /* in antic.c */ + +/* Player/Missile stuff ---------------------------------------------------- */ + +/* change to 0x00 to disable collisions */ +UBYTE GTIA_collisions_mask_missile_playfield = 0x0f; +UBYTE GTIA_collisions_mask_player_playfield = 0x0f; +UBYTE GTIA_collisions_mask_missile_player = 0x0f; +UBYTE GTIA_collisions_mask_player_player = 0x0f; + +#ifdef NEW_CYCLE_EXACT +/* temporary collision registers for the current scanline only */ +UBYTE P1PL_T; +UBYTE P2PL_T; +UBYTE P3PL_T; +UBYTE M0PL_T; +UBYTE M1PL_T; +UBYTE M2PL_T; +UBYTE M3PL_T; +/* If partial collisions have been generated during a scanline, this + * is the position of the up-to-date collision point , otherwise it is 0 + */ +int collision_curpos; +/* if hitclr has been written to during a scanline, this is the position + * within pm_scaline at which it was written to, and collisions should + * only be generated from this point on, otherwise it is 0 + */ +int hitclr_pos; +#else +#define P1PL_T GTIA_P1PL +#define P2PL_T GTIA_P2PL +#define P3PL_T GTIA_P3PL +#define M0PL_T GTIA_M0PL +#define M1PL_T GTIA_M1PL +#define M2PL_T GTIA_M2PL +#define M3PL_T GTIA_M3PL +#endif /* NEW_CYCLE_EXACT */ + +static UBYTE *hposp_ptr[4]; +static UBYTE *hposm_ptr[4]; +static ULONG hposp_mask[4]; + +static ULONG grafp_lookup[4][256]; +static ULONG *grafp_ptr[4]; +static int global_sizem[4]; + +static const int PM_Width[4] = {1, 2, 1, 4}; + +/* Meaning of bits in GTIA_pm_scanline: +bit 0 - Player 0 +bit 1 - Player 1 +bit 2 - Player 2 +bit 3 - Player 3 +bit 4 - Missile 0 +bit 5 - Missile 1 +bit 6 - Missile 2 +bit 7 - Missile 3 +*/ + +UBYTE GTIA_pm_scanline[ATARI_WIDTH / 2 + 8]; /* there's a byte for every *pair* of pixels */ +int GTIA_pm_dirty = TRUE; + +#define C_PM0 0x01 +#define C_PM1 0x02 +#define C_PM01 0x03 +#define C_PM2 0x04 +#define C_PM3 0x05 +#define C_PM23 0x06 +#define C_PM023 0x07 +#define C_PM123 0x08 +#define C_PM0123 0x09 +#define C_PM25 0x0a +#define C_PM35 0x0b +#define C_PM235 0x0c +#define C_COLLS 0x0d +#define C_BAK 0x00 +#define C_HI2 0x20 +#define C_HI3 0x30 +#define C_PF0 0x40 +#define C_PF1 0x50 +#define C_PF2 0x60 +#define C_PF3 0x70 + +#define PF0PM (*(UBYTE *) &ANTIC_cl[C_PF0 | C_COLLS]) +#define PF1PM (*(UBYTE *) &ANTIC_cl[C_PF1 | C_COLLS]) +#define PF2PM (*(UBYTE *) &ANTIC_cl[C_PF2 | C_COLLS]) +#define PF3PM (*(UBYTE *) &ANTIC_cl[C_PF3 | C_COLLS]) + +/* Colours ----------------------------------------------------------------- */ + +#ifdef USE_COLOUR_TRANSLATION_TABLE +UWORD colour_translation_table[256]; +#endif /* USE_COLOUR_TRANSLATION_TABLE */ + +static void setup_gtia9_11(void) { + int i; +#ifdef USE_COLOUR_TRANSLATION_TABLE + UWORD temp; + temp = colour_translation_table[GTIA_COLBK & 0xf0]; + ANTIC_lookup_gtia11[0] = ((ULONG) temp << 16) + temp; + for (i = 1; i < 16; i++) { + temp = colour_translation_table[GTIA_COLBK | i]; + ANTIC_lookup_gtia9[i] = ((ULONG) temp << 16) + temp; + temp = colour_translation_table[GTIA_COLBK | (i << 4)]; + ANTIC_lookup_gtia11[i] = ((ULONG) temp << 16) + temp; + } +#else + ULONG count9 = 0; + ULONG count11 = 0; + ANTIC_lookup_gtia11[0] = ANTIC_lookup_gtia9[0] & 0xf0f0f0f0; + for (i = 1; i < 16; i++) { + ANTIC_lookup_gtia9[i] = ANTIC_lookup_gtia9[0] | (count9 += 0x01010101); + ANTIC_lookup_gtia11[i] = ANTIC_lookup_gtia9[0] | (count11 += 0x10101010); + } +#endif +} + +#endif /* defined(BASIC) || defined(CURSES_BASIC) */ + +/* Initialization ---------------------------------------------------------- */ + +int GTIA_Initialise(void) +{ +#if !defined(BASIC) && !defined(CURSES_BASIC) + int i; + for (i = 0; i < 256; i++) { + int tmp = i + 0x100; + ULONG grafp1 = 0; + ULONG grafp2 = 0; + ULONG grafp4 = 0; + do { + grafp1 <<= 1; + grafp2 <<= 2; + grafp4 <<= 4; + if (tmp & 1) { + grafp1++; + grafp2 += 3; + grafp4 += 15; + } + tmp >>= 1; + } while (tmp != 1); + grafp_lookup[2][i] = grafp_lookup[0][i] = grafp1; + grafp_lookup[1][i] = grafp2; + grafp_lookup[3][i] = grafp4; + } + memset(ANTIC_cl, GTIA_COLOUR_BLACK, sizeof(ANTIC_cl)); + for (i = 0; i < 32; i++) + GTIA_PutByte((UWORD) i, 0); +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + + return TRUE; +} + +#ifdef NEW_CYCLE_EXACT + +/* generate updated PxPL and MxPL for part of a scanline */ +/* slow, but should be called rarely */ +static void generate_partial_pmpl_colls(int l, int r) +{ + int i; + if (r < 0 || l >= (int) sizeof(GTIA_pm_scanline) / (int) sizeof(GTIA_pm_scanline[0])) + return; + if (r >= (int) sizeof(GTIA_pm_scanline) / (int) sizeof(GTIA_pm_scanline[0])) { + r = (int) sizeof(GTIA_pm_scanline) / (int) sizeof(GTIA_pm_scanline[0]); + } + if (l < 0) + l = 0; + + for (i = l; i <= r; i++) { + UBYTE p = GTIA_pm_scanline[i]; +/* It is possible that some bits are set in PxPL/MxPL here, which would + * not otherwise be set ever in GTIA_NewPmScanline. This is because the + * player collisions are always generated in order in GTIA_NewPmScanline. + * However this does not cause any problem because we never use those bits + * of PxPL/MxPL in the collision reading code. + */ + GTIA_P1PL |= (p & (1 << 1)) ? p : 0; + GTIA_P2PL |= (p & (1 << 2)) ? p : 0; + GTIA_P3PL |= (p & (1 << 3)) ? p : 0; + GTIA_M0PL |= (p & (0x10 << 0)) ? p : 0; + GTIA_M1PL |= (p & (0x10 << 1)) ? p : 0; + GTIA_M2PL |= (p & (0x10 << 2)) ? p : 0; + GTIA_M3PL |= (p & (0x10 << 3)) ? p : 0; + } + +} + +/* update pm->pl collisions for a partial scanline */ +static void update_partial_pmpl_colls(void) +{ + int l = collision_curpos; + int r = ANTIC_XPOS * 2 - 37; + generate_partial_pmpl_colls(l, r); + collision_curpos = r; +} + +/* update pm-> pl collisions at the end of a scanline */ +void GTIA_UpdatePmplColls(void) +{ + if (hitclr_pos != 0){ + generate_partial_pmpl_colls(hitclr_pos, + sizeof(GTIA_pm_scanline) / sizeof(GTIA_pm_scanline[0]) - 1); +/* If hitclr was written to, then only part of GTIA_pm_scanline should be used + * for collisions */ + + } + else { +/* otherwise the whole of pm_scaline can be used for collisions. This will + * update the collision registers based on the generated collisions for the + * current line */ + GTIA_P1PL |= P1PL_T; + GTIA_P2PL |= P2PL_T; + GTIA_P3PL |= P3PL_T; + GTIA_M0PL |= M0PL_T; + GTIA_M1PL |= M1PL_T; + GTIA_M2PL |= M2PL_T; + GTIA_M3PL |= M3PL_T; + } + collision_curpos = 0; + hitclr_pos = 0; +} + +#else +#define update_partial_pmpl_colls() +#endif /* NEW_CYCLE_EXACT */ + +/* Prepare PMG scanline ---------------------------------------------------- */ + +#if !defined(BASIC) && !defined(CURSES_BASIC) + +void GTIA_NewPmScanline(void) +{ +#ifdef NEW_CYCLE_EXACT +/* reset temporary pm->pl collisions */ + P1PL_T = P2PL_T = P3PL_T = 0; + M0PL_T = M1PL_T = M2PL_T = M3PL_T = 0; +#endif /* NEW_CYCLE_EXACT */ +/* Clear if necessary */ + if (GTIA_pm_dirty) { + memset(GTIA_pm_scanline, 0, ATARI_WIDTH / 2); + GTIA_pm_dirty = FALSE; + } + +/* Draw Players */ + +#define DO_PLAYER(n) if (GTIA_GRAFP##n) { \ + ULONG grafp = grafp_ptr[n][GTIA_GRAFP##n] & hposp_mask[n]; \ + if (grafp) { \ + UBYTE *ptr = hposp_ptr[n]; \ + GTIA_pm_dirty = TRUE; \ + do { \ + if (grafp & 1) \ + P##n##PL_T |= *ptr |= 1 << n; \ + ptr++; \ + grafp >>= 1; \ + } while (grafp); \ + } \ +} + + /* optimized DO_PLAYER(0): GTIA_pm_scanline is clear and P0PL is unused */ + if (GTIA_GRAFP0) { + ULONG grafp = grafp_ptr[0][GTIA_GRAFP0] & hposp_mask[0]; + if (grafp) { + UBYTE *ptr = hposp_ptr[0]; + GTIA_pm_dirty = TRUE; + do { + if (grafp & 1) + *ptr = 1; + ptr++; + grafp >>= 1; + } while (grafp); + } + } + + DO_PLAYER(1) + DO_PLAYER(2) + DO_PLAYER(3) + +/* Draw Missiles */ + +#define DO_MISSILE(n,p,m,r,l) if (GTIA_GRAFM & m) { \ + int j = global_sizem[n]; \ + UBYTE *ptr = hposm_ptr[n]; \ + if (GTIA_GRAFM & r) { \ + if (GTIA_GRAFM & l) \ + j <<= 1; \ + } \ + else \ + ptr += j; \ + if (ptr < GTIA_pm_scanline + 2) { \ + j += ptr - GTIA_pm_scanline - 2; \ + ptr = GTIA_pm_scanline + 2; \ + } \ + else if (ptr + j > GTIA_pm_scanline + ATARI_WIDTH / 2 - 2) \ + j = GTIA_pm_scanline + ATARI_WIDTH / 2 - 2 - ptr; \ + if (j > 0) \ + do \ + M##n##PL_T |= *ptr++ |= p; \ + while (--j); \ +} + + if (GTIA_GRAFM) { + GTIA_pm_dirty = TRUE; + DO_MISSILE(3, 0x80, 0xc0, 0x80, 0x40) + DO_MISSILE(2, 0x40, 0x30, 0x20, 0x10) + DO_MISSILE(1, 0x20, 0x0c, 0x08, 0x04) + DO_MISSILE(0, 0x10, 0x03, 0x02, 0x01) + } +} + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + +/* GTIA registers ---------------------------------------------------------- */ + +void GTIA_Frame(void) +{ +#ifdef BASIC + consol = 0xf; +#else + consol = INPUT_key_consol | 0x08; +#endif + + if (GTIA_GRACTL & 4) { + GTIA_TRIG_latch[0] &= GTIA_TRIG[0]; + GTIA_TRIG_latch[1] &= GTIA_TRIG[1]; + GTIA_TRIG_latch[2] &= GTIA_TRIG[2]; + GTIA_TRIG_latch[3] &= GTIA_TRIG[3]; + } +} + +UBYTE GTIA_GetByte(UWORD addr, int no_side_effects) +{ + switch (addr & 0x1f) { + case GTIA_OFFSET_M0PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x10) >> 4) + + ((PF1PM & 0x10) >> 3) + + ((PF2PM & 0x10) >> 2) + + ((PF3PM & 0x10) >> 1)) & GTIA_collisions_mask_missile_playfield; + case GTIA_OFFSET_M1PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x20) >> 5) + + ((PF1PM & 0x20) >> 4) + + ((PF2PM & 0x20) >> 3) + + ((PF3PM & 0x20) >> 2)) & GTIA_collisions_mask_missile_playfield; + case GTIA_OFFSET_M2PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x40) >> 6) + + ((PF1PM & 0x40) >> 5) + + ((PF2PM & 0x40) >> 4) + + ((PF3PM & 0x40) >> 3)) & GTIA_collisions_mask_missile_playfield; + case GTIA_OFFSET_M3PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x80) >> 7) + + ((PF1PM & 0x80) >> 6) + + ((PF2PM & 0x80) >> 5) + + ((PF3PM & 0x80) >> 4)) & GTIA_collisions_mask_missile_playfield; + case GTIA_OFFSET_P0PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return ((PF0PM & 0x01) + + ((PF1PM & 0x01) << 1) + + ((PF2PM & 0x01) << 2) + + ((PF3PM & 0x01) << 3)) & GTIA_collisions_mask_player_playfield; + case GTIA_OFFSET_P1PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x02) >> 1) + + (PF1PM & 0x02) + + ((PF2PM & 0x02) << 1) + + ((PF3PM & 0x02) << 2)) & GTIA_collisions_mask_player_playfield; + case GTIA_OFFSET_P2PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x04) >> 2) + + ((PF1PM & 0x04) >> 1) + + (PF2PM & 0x04) + + ((PF3PM & 0x04) << 1)) & GTIA_collisions_mask_player_playfield; + case GTIA_OFFSET_P3PF: +#ifdef NEW_CYCLE_EXACT + if (ANTIC_DRAWING_SCREEN) { + ANTIC_UpdateScanline(); + } +#endif + return (((PF0PM & 0x08) >> 3) + + ((PF1PM & 0x08) >> 2) + + ((PF2PM & 0x08) >> 1) + + (PF3PM & 0x08)) & GTIA_collisions_mask_player_playfield; + case GTIA_OFFSET_M0PL: + update_partial_pmpl_colls(); + return GTIA_M0PL & GTIA_collisions_mask_missile_player; + case GTIA_OFFSET_M1PL: + update_partial_pmpl_colls(); + return GTIA_M1PL & GTIA_collisions_mask_missile_player; + case GTIA_OFFSET_M2PL: + update_partial_pmpl_colls(); + return GTIA_M2PL & GTIA_collisions_mask_missile_player; + case GTIA_OFFSET_M3PL: + update_partial_pmpl_colls(); + return GTIA_M3PL & GTIA_collisions_mask_missile_player; + case GTIA_OFFSET_P0PL: + update_partial_pmpl_colls(); + return (((GTIA_P1PL & 0x01) << 1) /* mask in player 1 */ + + ((GTIA_P2PL & 0x01) << 2) /* mask in player 2 */ + + ((GTIA_P3PL & 0x01) << 3)) /* mask in player 3 */ + & GTIA_collisions_mask_player_player; + case GTIA_OFFSET_P1PL: + update_partial_pmpl_colls(); + return ((GTIA_P1PL & 0x01) /* mask in player 0 */ + + ((GTIA_P2PL & 0x02) << 1) /* mask in player 2 */ + + ((GTIA_P3PL & 0x02) << 2)) /* mask in player 3 */ + & GTIA_collisions_mask_player_player; + case GTIA_OFFSET_P2PL: + update_partial_pmpl_colls(); + return ((GTIA_P2PL & 0x03) /* mask in player 0 and 1 */ + + ((GTIA_P3PL & 0x04) << 1)) /* mask in player 3 */ + & GTIA_collisions_mask_player_player; + case GTIA_OFFSET_P3PL: + update_partial_pmpl_colls(); + return (GTIA_P3PL & 0x07) /* mask in player 0,1, and 2 */ + & GTIA_collisions_mask_player_player; + case GTIA_OFFSET_TRIG0: + return GTIA_TRIG[0] & GTIA_TRIG_latch[0]; + case GTIA_OFFSET_TRIG1: + return GTIA_TRIG[1] & GTIA_TRIG_latch[1]; + case GTIA_OFFSET_TRIG2: + return GTIA_TRIG[2] & GTIA_TRIG_latch[2]; + case GTIA_OFFSET_TRIG3: + return GTIA_TRIG[3] & GTIA_TRIG_latch[3]; + case GTIA_OFFSET_PAL: + return (tv_mode == TV_PAL) ? 0x01 : 0x0f; + case GTIA_OFFSET_CONSOL: + { + UBYTE byte = consol & consol_mask; +#if SKIP + if (!no_side_effects && GTIA_consol_override > 0) { + /* Check if we're called from outside OS. This avoids sending + console keystrokes to diagnostic cartridges. */ + if (CPU_regPC < 0xc000) + /* Not from OS. Disable console override. */ + GTIA_consol_override = 0; + else { + --GTIA_consol_override; + if (Atari800_builtin_basic && Atari800_disable_basic && !BINLOAD_loading_basic) + /* Only for XL/XE - hold Option during reboot. */ + byte &= ~INPUT_CONSOL_OPTION; + if (CASSETTE_hold_start && Atari800_machine_type != Atari800_MACHINE_5200) { + /* Only for the computers - hold Start during reboot. */ + byte &= ~INPUT_CONSOL_START; + if (GTIA_consol_override == 0) { + /* press Space after Start to start cassette boot. */ + CASSETTE_press_space = 1; + CASSETTE_hold_start = CASSETTE_hold_start_on_reboot; + } + } + } + } +#endif + return byte; + } + default: + break; + } + + return 0xf; +} + +void GTIA_PutByte(UWORD addr, UBYTE byte) +{ +#if !defined(BASIC) && !defined(CURSES_BASIC) + UWORD cword; + UWORD cword2; + +#ifdef NEW_CYCLE_EXACT + int x; /* the cycle-exact update position in GTIA_pm_scanline */ + if (ANTIC_DRAWING_SCREEN) { + if ((addr & 0x1f) != GTIA_PRIOR) { + ANTIC_UpdateScanline(); + } else { + ANTIC_UpdateScanlinePrior(byte); + } + } +#define UPDATE_PM_CYCLE_EXACT if(ANTIC_DRAWING_SCREEN) GTIA_NewPmScanline(); +#else +#define UPDATE_PM_CYCLE_EXACT +#endif + +#endif /* !defined(BASIC) && !defined(CURSES_BASIC) */ + + switch (addr & 0x1f) { + case GTIA_OFFSET_CONSOL: + GTIA_speaker = !(byte & 0x08); +#ifdef CONSOLE_SOUND + POKEYSND_UpdateConsol(1); +#endif + consol_mask = (~byte) & 0x0f; + break; + +#if defined(BASIC) || defined(CURSES_BASIC) + + /* We use these for Antic modes 6, 7 on Curses */ + case GTIA_OFFSET_COLPF0: + GTIA_COLPF0 = byte; + break; + case GTIA_OFFSET_COLPF1: + GTIA_COLPF1 = byte; + break; + case GTIA_OFFSET_COLPF2: + GTIA_COLPF2 = byte; + break; + case GTIA_OFFSET_COLPF3: + GTIA_COLPF3 = byte; + break; + +#else + +#ifdef USE_COLOUR_TRANSLATION_TABLE + case GTIA_OFFSET_COLBK: + GTIA_COLBK = byte &= 0xfe; + ANTIC_cl[C_BAK] = cword = colour_translation_table[byte]; + if (cword != (UWORD) (ANTIC_lookup_gtia9[0]) ) { + ANTIC_lookup_gtia9[0] = cword + (cword << 16); + if (GTIA_PRIOR & 0x40) + setup_gtia9_11(); + } + break; + case GTIA_OFFSET_COLPF0: + GTIA_COLPF0 = byte &= 0xfe; + ANTIC_cl[C_PF0] = cword = GTIA_colour_translation_table[byte]; + if ((GTIA_PRIOR & 1) == 0) { + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF0 | C_PM3] = ANTIC_cl[C_PF0 | C_PM2] = cword; + if ((GTIA_PRIOR & 3) == 0) { + if (GTIA_PRIOR & 0xf) { + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF0 | C_PM1] = ANTIC_cl[C_PF0 | C_PM0] = cword; + if ((GTIA_PRIOR & 0xf) == 0xc) + ANTIC_cl[C_PF0 | C_PM0123] = ANTIC_cl[C_PF0 | C_PM123] = ANTIC_cl[C_PF0 | C_PM023] = cword; + } + else { + ANTIC_cl[C_PF0 | C_PM0] = colour_translation_table[byte | GTIA_COLPM0]; + ANTIC_cl[C_PF0 | C_PM1] = colour_translation_table[byte | GTIA_COLPM1]; + ANTIC_cl[C_PF0 | C_PM01] = colour_translation_table[byte | GTIA_COLPM0 | GTIA_COLPM1]; + } + } + if ((GTIA_PRIOR & 0xf) >= 0xa) + ANTIC_cl[C_PF0 | C_PM25] = cword; + } + break; + case GTIA_OFFSET_COLPF1: + GTIA_COLPF1 = byte &= 0xfe; + ANTIC_cl[C_PF1] = cword = GTIA_colour_translation_table[byte]; + if ((GTIA_PRIOR & 1) == 0) { + ANTIC_cl[C_PF1 | C_PM23] = ANTIC_cl[C_PF1 | C_PM3] = ANTIC_cl[C_PF1 | C_PM2] = cword; + if ((GTIA_PRIOR & 3) == 0) { + if (GTIA_PRIOR & 0xf) { + ANTIC_cl[C_PF1 | C_PM01] = ANTIC_cl[C_PF1 | C_PM1] = ANTIC_cl[C_PF1 | C_PM0] = cword; + if ((GTIA_PRIOR & 0xf) == 0xc) + ANTIC_cl[C_PF1 | C_PM0123] = ANTIC_cl[C_PF1 | C_PM123] = ANTIC_cl[C_PF1 | C_PM023] = cword; + } + else { + ANTIC_cl[C_PF1 | C_PM0] = colour_translation_table[byte | GTIA_COLPM0]; + ANTIC_cl[C_PF1 | C_PM1] = colour_translation_table[byte | GTIA_COLPM1]; + ANTIC_cl[C_PF1 | C_PM01] = colour_translation_table[byte | GTIA_COLPM0 | GTIA_COLPM1]; + } + } + } + { + UBYTE byte2 = (GTIA_COLPF2 & 0xf0) + (byte & 0xf); + ANTIC_cl[C_HI2] = cword = colour_translation_table[byte2]; + ANTIC_cl[C_HI3] = colour_translation_table[(GTIA_COLPF3 & 0xf0) | (byte & 0xf)]; + if (GTIA_PRIOR & 4) + ANTIC_cl[C_HI2 | C_PM01] = ANTIC_cl[C_HI2 | C_PM1] = ANTIC_cl[C_HI2 | C_PM0] = cword; + if ((GTIA_PRIOR & 9) == 0) { + if (GTIA_PRIOR & 0xf) + ANTIC_cl[C_HI2 | C_PM23] = ANTIC_cl[C_HI2 | C_PM3] = ANTIC_cl[C_HI2 | C_PM2] = cword; + else { + ANTIC_cl[C_HI2 | C_PM2] = colour_translation_table[byte2 | (GTIA_COLPM2 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM3] = colour_translation_table[byte2 | (GTIA_COLPM3 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM23] = colour_translation_table[byte2 | ((GTIA_COLPM2 | GTIA_COLPM3) & 0xf0)]; + } + } + } + break; + case GTIA_OFFSET_COLPF2: + GTIA_COLPF2 = byte &= 0xfe; + ANTIC_cl[C_PF2] = cword = GTIA_colour_translation_table[byte]; + { + UBYTE byte2 = (byte & 0xf0) + (GTIA_COLPF1 & 0xf); + ANTIC_cl[C_HI2] = cword2 = colour_translation_table[byte2]; + if (GTIA_PRIOR & 4) { + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PF2 | C_PM0] = cword; + ANTIC_cl[C_HI2 | C_PM01] = ANTIC_cl[C_HI2 | C_PM1] = ANTIC_cl[C_HI2 | C_PM0] = cword2; + } + if ((GTIA_PRIOR & 9) == 0) { + if (GTIA_PRIOR & 0xf) { + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF2 | C_PM3] = ANTIC_cl[C_PF2 | C_PM2] = cword; + ANTIC_cl[C_HI2 | C_PM23] = ANTIC_cl[C_HI2 | C_PM3] = ANTIC_cl[C_HI2 | C_PM2] = cword2; + } + else { + ANTIC_cl[C_PF2 | C_PM2] = colour_translation_table[byte | GTIA_COLPM2]; + ANTIC_cl[C_PF2 | C_PM3] = colour_translation_table[byte | GTIA_COLPM3]; + ANTIC_cl[C_PF2 | C_PM23] = colour_translation_table[byte | GTIA_COLPM2 | GTIA_COLPM3]; + ANTIC_cl[C_HI2 | C_PM2] = colour_translation_table[byte2 | (GTIA_COLPM2 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM3] = colour_translation_table[byte2 | (GTIA_COLPM3 & 0xf0)]; + ANTIC_cl[C_HI2 | C_PM23] = colour_translation_table[byte2 | ((GTIA_COLPM2 | GTIA_COLPM3) & 0xf0)]; + } + } + } + break; + case GTIA_OFFSET_COLPF3: + GTIA_COLPF3 = byte &= 0xfe; + ANTIC_cl[C_PF3] = cword = colour_translation_table[byte]; + ANTIC_cl[C_HI3] = cword2 = colour_translation_table[(byte & 0xf0) | (GTIA_COLPF1 & 0xf)]; + if (GTIA_PRIOR & 4) + ANTIC_cl[C_PF3 | C_PM01] = ANTIC_cl[C_PF3 | C_PM1] = ANTIC_cl[C_PF3 | C_PM0] = cword; + if ((GTIA_PRIOR & 9) == 0) { + if (GTIA_PRIOR & 0xf) + ANTIC_cl[C_PF3 | C_PM23] = ANTIC_cl[C_PF3 | C_PM3] = ANTIC_cl[C_PF3 | C_PM2] = cword; + else { + ANTIC_cl[C_PF3 | C_PM25] = ANTIC_cl[C_PF2 | C_PM25] = ANTIC_cl[C_PM25] = ANTIC_cl[C_PF3 | C_PM2] = colour_translation_table[byte | GTIA_COLPM2]; + ANTIC_cl[C_PF3 | C_PM35] = ANTIC_cl[C_PF2 | C_PM35] = ANTIC_cl[C_PM35] = ANTIC_cl[C_PF3 | C_PM3] = colour_translation_table[byte | GTIA_COLPM3]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23] = colour_translation_table[byte | GTIA_COLPM2 | GTIA_COLPM3]; + ANTIC_cl[C_PF0 | C_PM235] = ANTIC_cl[C_PF0 | C_PM35] = ANTIC_cl[C_PF0 | C_PM25] = + ANTIC_cl[C_PF1 | C_PM235] = ANTIC_cl[C_PF1 | C_PM35] = ANTIC_cl[C_PF1 | C_PM25] = cword; + } + } + break; + case GTIA_OFFSET_COLPM0: + GTIA_COLPM0 = byte &= 0xfe; + ANTIC_cl[C_PM023] = ANTIC_cl[C_PM0] = cword = colour_translation_table[byte]; + { + UBYTE byte2 = byte | GTIA_COLPM1; + ANTIC_cl[C_PM0123] = ANTIC_cl[C_PM01] = cword2 = colour_translation_table[byte2]; + if ((GTIA_PRIOR & 4) == 0) { + ANTIC_cl[C_PF2 | C_PM0] = ANTIC_cl[C_PF3 | C_PM0] = cword; + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF3 | C_PM01] = cword2; + ANTIC_cl[C_HI2 | C_PM0] = colour_translation_table[(byte & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM01] = colour_translation_table[(byte2 & 0xf0) | (GTIA_COLPF1 & 0xf)]; + if ((GTIA_PRIOR & 0xc) == 0) { + if (GTIA_PRIOR & 3) { + ANTIC_cl[C_PF0 | C_PM0] = ANTIC_cl[C_PF1 | C_PM0] = cword; + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF1 | C_PM01] = cword2; + } + else { + ANTIC_cl[C_PF0 | C_PM0] = colour_translation_table[byte | GTIA_COLPF0]; + ANTIC_cl[C_PF1 | C_PM0] = colour_translation_table[byte | GTIA_COLPF1]; + ANTIC_cl[C_PF0 | C_PM01] = colour_translation_table[byte2 | GTIA_COLPF0]; + ANTIC_cl[C_PF1 | C_PM01] = colour_translation_table[byte2 | GTIA_COLPF1]; + } + } + } + } + break; + case GTIA_OFFSET_COLPM1: + GTIA_COLPM1 = byte &= 0xfe; + ANTIC_cl[C_PM123] = ANTIC_cl[C_PM1] = cword = colour_translation_table[byte]; + { + UBYTE byte2 = byte | GTIA_COLPM0; + ANTIC_cl[C_PM0123] = ANTIC_cl[C_PM01] = cword2 = colour_translation_table[byte2]; + if ((GTIA_PRIOR & 4) == 0) { + ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PF3 | C_PM1] = cword; + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF3 | C_PM01] = cword2; + ANTIC_cl[C_HI2 | C_PM1] = colour_translation_table[(byte & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM01] = colour_translation_table[(byte2 & 0xf0) | (GTIA_COLPF1 & 0xf)]; + if ((GTIA_PRIOR & 0xc) == 0) { + if (GTIA_PRIOR & 3) { + ANTIC_cl[C_PF0 | C_PM1] = ANTIC_cl[C_PF1 | C_PM1] = cword; + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF1 | C_PM01] = cword2; + } + else { + ANTIC_cl[C_PF0 | C_PM1] = colour_translation_table[byte | GTIA_COLPF0]; + ANTIC_cl[C_PF1 | C_PM1] = colour_translation_table[byte | GTIA_COLPF1]; + ANTIC_cl[C_PF0 | C_PM01] = colour_translation_table[byte2 | GTIA_COLPF0]; + ANTIC_cl[C_PF1 | C_PM01] = colour_translation_table[byte2 | GTIA_COLPF1]; + } + } + } + } + break; + case GTIA_OFFSET_COLPM2: + GTIA_COLPM2 = byte &= 0xfe; + ANTIC_cl[C_PM2] = cword = colour_translation_table[byte]; + { + UBYTE byte2 = byte | GTIA_COLPM3; + ANTIC_cl[C_PM23] = cword2 = colour_translation_table[byte2]; + if (GTIA_PRIOR & 1) { + ANTIC_cl[C_PF0 | C_PM2] = ANTIC_cl[C_PF1 | C_PM2] = cword; + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF1 | C_PM23] = cword2; + } + if ((GTIA_PRIOR & 6) == 0) { + if (GTIA_PRIOR & 9) { + ANTIC_cl[C_PF2 | C_PM2] = ANTIC_cl[C_PF3 | C_PM2] = cword; + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF3 | C_PM23] = cword2; + ANTIC_cl[C_HI2 | C_PM2] = colour_translation_table[(byte & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM23] = colour_translation_table[(byte2 & 0xf0) | (GTIA_COLPF1 & 0xf)]; + } + else { + ANTIC_cl[C_PF2 | C_PM2] = colour_translation_table[byte | GTIA_COLPF2]; + ANTIC_cl[C_PF3 | C_PM25] = ANTIC_cl[C_PF2 | C_PM25] = ANTIC_cl[C_PM25] = ANTIC_cl[C_PF3 | C_PM2] = colour_translation_table[byte | GTIA_COLPF3]; + ANTIC_cl[C_PF2 | C_PM23] = colour_translation_table[byte2 | GTIA_COLPF2]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23] = colour_translation_table[byte2 | GTIA_COLPF3]; + ANTIC_cl[C_HI2 | C_PM2] = colour_translation_table[((byte | GTIA_COLPF2) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM25] = colour_translation_table[((byte | GTIA_COLPF3) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM23] = colour_translation_table[((byte2 | GTIA_COLPF2) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM235] = colour_translation_table[((byte2 | GTIA_COLPF3) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + } + } + } + break; + case GTIA_OFFSET_COLPM3: + GTIA_COLPM3 = byte &= 0xfe; + ANTIC_cl[C_PM3] = cword = colour_translation_table[byte]; + { + UBYTE byte2 = byte | GTIA_COLPM2; + ANTIC_cl[C_PM23] = cword2 = colour_translation_table[byte2]; + if (GTIA_PRIOR & 1) { + ANTIC_cl[C_PF0 | C_PM3] = ANTIC_cl[C_PF1 | C_PM3] = cword; + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF1 | C_PM23] = cword2; + } + if ((GTIA_PRIOR & 6) == 0) { + if (GTIA_PRIOR & 9) { + ANTIC_cl[C_PF2 | C_PM3] = ANTIC_cl[C_PF3 | C_PM3] = cword; + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF3 | C_PM23] = cword2; + } + else { + ANTIC_cl[C_PF2 | C_PM3] = colour_translation_table[byte | GTIA_COLPF2]; + ANTIC_cl[C_PF3 | C_PM35] = ANTIC_cl[C_PF2 | C_PM35] = ANTIC_cl[C_PM35] = ANTIC_cl[C_PF3 | C_PM3] = colour_translation_table[byte | GTIA_COLPF3]; + ANTIC_cl[C_PF2 | C_PM23] = colour_translation_table[byte2 | GTIA_COLPF2]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23] = colour_translation_table[byte2 | GTIA_COLPF3]; + ANTIC_cl[C_HI2 | C_PM3] = colour_translation_table[((byte | GTIA_COLPF2) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + ANTIC_cl[C_HI2 | C_PM23] = colour_translation_table[((byte2 | GTIA_COLPF2) & 0xf0) | (GTIA_COLPF1 & 0xf)]; + } + } + } + break; +#else /* USE_COLOUR_TRANSLATION_TABLE */ + case GTIA_OFFSET_COLBK: + GTIA_COLBK = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_BAK] = cword; + if (cword != (UWORD) (ANTIC_lookup_gtia9[0]) ) { + ANTIC_lookup_gtia9[0] = cword + (cword << 16); + if (GTIA_PRIOR & 0x40) + setup_gtia9_11(); + } + break; + case GTIA_OFFSET_COLPF0: + GTIA_COLPF0 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PF0] = cword; + if ((GTIA_PRIOR & 1) == 0) { + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF0 | C_PM3] = ANTIC_cl[C_PF0 | C_PM2] = cword; + if ((GTIA_PRIOR & 3) == 0) { + if (GTIA_PRIOR & 0xf) { + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF0 | C_PM1] = ANTIC_cl[C_PF0 | C_PM0] = cword; + if ((GTIA_PRIOR & 0xf) == 0xc) + ANTIC_cl[C_PF0 | C_PM0123] = ANTIC_cl[C_PF0 | C_PM123] = ANTIC_cl[C_PF0 | C_PM023] = cword; + } + else + ANTIC_cl[C_PF0 | C_PM01] = (ANTIC_cl[C_PF0 | C_PM0] = cword | ANTIC_cl[C_PM0]) | (ANTIC_cl[C_PF0 | C_PM1] = cword | ANTIC_cl[C_PM1]); + } + if ((GTIA_PRIOR & 0xf) >= 0xa) + ANTIC_cl[C_PF0 | C_PM25] = cword; + } + break; + case GTIA_OFFSET_COLPF1: + GTIA_COLPF1 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PF1] = cword; + if ((GTIA_PRIOR & 1) == 0) { + ANTIC_cl[C_PF1 | C_PM23] = ANTIC_cl[C_PF1 | C_PM3] = ANTIC_cl[C_PF1 | C_PM2] = cword; + if ((GTIA_PRIOR & 3) == 0) { + if (GTIA_PRIOR & 0xf) { + ANTIC_cl[C_PF1 | C_PM01] = ANTIC_cl[C_PF1 | C_PM1] = ANTIC_cl[C_PF1 | C_PM0] = cword; + if ((GTIA_PRIOR & 0xf) == 0xc) + ANTIC_cl[C_PF1 | C_PM0123] = ANTIC_cl[C_PF1 | C_PM123] = ANTIC_cl[C_PF1 | C_PM023] = cword; + } + else + ANTIC_cl[C_PF1 | C_PM01] = (ANTIC_cl[C_PF1 | C_PM0] = cword | ANTIC_cl[C_PM0]) | (ANTIC_cl[C_PF1 | C_PM1] = cword | ANTIC_cl[C_PM1]); + } + } + ((UBYTE *)ANTIC_hires_lookup_l)[0x80] = ((UBYTE *)ANTIC_hires_lookup_l)[0x41] = (UBYTE) + (ANTIC_hires_lookup_l[0x60] = cword & 0xf0f); + break; + case GTIA_OFFSET_COLPF2: + GTIA_COLPF2 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PF2] = cword; + if (GTIA_PRIOR & 4) + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PF2 | C_PM0] = cword; + if ((GTIA_PRIOR & 9) == 0) { + if (GTIA_PRIOR & 0xf) + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF2 | C_PM3] = ANTIC_cl[C_PF2 | C_PM2] = cword; + else + ANTIC_cl[C_PF2 | C_PM23] = (ANTIC_cl[C_PF2 | C_PM2] = cword | ANTIC_cl[C_PM2]) | (ANTIC_cl[C_PF2 | C_PM3] = cword | ANTIC_cl[C_PM3]); + } + break; + case GTIA_OFFSET_COLPF3: + GTIA_COLPF3 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PF3] = cword; + if (GTIA_PRIOR & 4) + ANTIC_cl[C_PF3 | C_PM01] = ANTIC_cl[C_PF3 | C_PM1] = ANTIC_cl[C_PF3 | C_PM0] = cword; + if ((GTIA_PRIOR & 9) == 0) { + if (GTIA_PRIOR & 0xf) + ANTIC_cl[C_PF3 | C_PM23] = ANTIC_cl[C_PF3 | C_PM3] = ANTIC_cl[C_PF3 | C_PM2] = cword; + else { + ANTIC_cl[C_PF3 | C_PM25] = ANTIC_cl[C_PF2 | C_PM25] = ANTIC_cl[C_PM25] = ANTIC_cl[C_PF3 | C_PM2] = cword | ANTIC_cl[C_PM2]; + ANTIC_cl[C_PF3 | C_PM35] = ANTIC_cl[C_PF2 | C_PM35] = ANTIC_cl[C_PM35] = ANTIC_cl[C_PF3 | C_PM3] = cword | ANTIC_cl[C_PM3]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23] = ANTIC_cl[C_PF3 | C_PM2] | ANTIC_cl[C_PF3 | C_PM3]; + ANTIC_cl[C_PF0 | C_PM235] = ANTIC_cl[C_PF0 | C_PM35] = ANTIC_cl[C_PF0 | C_PM25] = + ANTIC_cl[C_PF1 | C_PM235] = ANTIC_cl[C_PF1 | C_PM35] = ANTIC_cl[C_PF1 | C_PM25] = cword; + } + } + break; + case GTIA_OFFSET_COLPM0: + GTIA_COLPM0 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PM023] = ANTIC_cl[C_PM0] = cword; + ANTIC_cl[C_PM0123] = ANTIC_cl[C_PM01] = cword2 = cword | ANTIC_cl[C_PM1]; + if ((GTIA_PRIOR & 4) == 0) { + ANTIC_cl[C_PF2 | C_PM0] = ANTIC_cl[C_PF3 | C_PM0] = cword; + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF3 | C_PM01] = cword2; + if ((GTIA_PRIOR & 0xc) == 0) { + if (GTIA_PRIOR & 3) { + ANTIC_cl[C_PF0 | C_PM0] = ANTIC_cl[C_PF1 | C_PM0] = cword; + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF1 | C_PM01] = cword2; + } + else { + ANTIC_cl[C_PF0 | C_PM0] = cword | ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM0] = cword | ANTIC_cl[C_PF1]; + ANTIC_cl[C_PF0 | C_PM01] = cword2 | ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM01] = cword2 | ANTIC_cl[C_PF1]; + } + } + } + break; + case GTIA_OFFSET_COLPM1: + GTIA_COLPM1 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PM123] = ANTIC_cl[C_PM1] = cword; + ANTIC_cl[C_PM0123] = ANTIC_cl[C_PM01] = cword2 = cword | ANTIC_cl[C_PM0]; + if ((GTIA_PRIOR & 4) == 0) { + ANTIC_cl[C_PF2 | C_PM1] = ANTIC_cl[C_PF3 | C_PM1] = cword; + ANTIC_cl[C_PF2 | C_PM01] = ANTIC_cl[C_PF3 | C_PM01] = cword2; + if ((GTIA_PRIOR & 0xc) == 0) { + if (GTIA_PRIOR & 3) { + ANTIC_cl[C_PF0 | C_PM1] = ANTIC_cl[C_PF1 | C_PM1] = cword; + ANTIC_cl[C_PF0 | C_PM01] = ANTIC_cl[C_PF1 | C_PM01] = cword2; + } + else { + ANTIC_cl[C_PF0 | C_PM1] = cword | ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM1] = cword | ANTIC_cl[C_PF1]; + ANTIC_cl[C_PF0 | C_PM01] = cword2 | ANTIC_cl[C_PF0]; + ANTIC_cl[C_PF1 | C_PM01] = cword2 | ANTIC_cl[C_PF1]; + } + } + } + break; + case GTIA_OFFSET_COLPM2: + GTIA_COLPM2 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PM2] = cword; + ANTIC_cl[C_PM23] = cword2 = cword | ANTIC_cl[C_PM3]; + if (GTIA_PRIOR & 1) { + ANTIC_cl[C_PF0 | C_PM2] = ANTIC_cl[C_PF1 | C_PM2] = cword; + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF1 | C_PM23] = cword2; + } + if ((GTIA_PRIOR & 6) == 0) { + if (GTIA_PRIOR & 9) { + ANTIC_cl[C_PF2 | C_PM2] = ANTIC_cl[C_PF3 | C_PM2] = cword; + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF3 | C_PM23] = cword2; + } + else { + ANTIC_cl[C_PF2 | C_PM2] = cword | ANTIC_cl[C_PF2]; + ANTIC_cl[C_PF3 | C_PM25] = ANTIC_cl[C_PF2 | C_PM25] = ANTIC_cl[C_PM25] = ANTIC_cl[C_PF3 | C_PM2] = cword | ANTIC_cl[C_PF3]; + ANTIC_cl[C_PF2 | C_PM23] = cword2 | ANTIC_cl[C_PF2]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23] = cword2 | ANTIC_cl[C_PF3]; + } + } + break; + case GTIA_OFFSET_COLPM3: + GTIA_COLPM3 = byte &= 0xfe; + GTIA_COLOUR_TO_WORD(cword,byte); + ANTIC_cl[C_PM3] = cword; + ANTIC_cl[C_PM23] = cword2 = cword | ANTIC_cl[C_PM2]; + if (GTIA_PRIOR & 1) { + ANTIC_cl[C_PF0 | C_PM3] = ANTIC_cl[C_PF1 | C_PM3] = cword; + ANTIC_cl[C_PF0 | C_PM23] = ANTIC_cl[C_PF1 | C_PM23] = cword2; + } + if ((GTIA_PRIOR & 6) == 0) { + if (GTIA_PRIOR & 9) { + ANTIC_cl[C_PF2 | C_PM3] = ANTIC_cl[C_PF3 | C_PM3] = cword; + ANTIC_cl[C_PF2 | C_PM23] = ANTIC_cl[C_PF3 | C_PM23] = cword2; + } + else { + ANTIC_cl[C_PF2 | C_PM3] = cword | ANTIC_cl[C_PF2]; + ANTIC_cl[C_PF3 | C_PM35] = ANTIC_cl[C_PF2 | C_PM35] = ANTIC_cl[C_PM35] = ANTIC_cl[C_PF3 | C_PM3] = cword | ANTIC_cl[C_PF3]; + ANTIC_cl[C_PF2 | C_PM23] = cword2 | ANTIC_cl[C_PF2]; + ANTIC_cl[C_PF3 | C_PM235] = ANTIC_cl[C_PF2 | C_PM235] = ANTIC_cl[C_PM235] = ANTIC_cl[C_PF3 | C_PM23] = cword2 | ANTIC_cl[C_PF3]; + } + } + break; +#endif /* USE_COLOUR_TRANSLATION_TABLE */ + case GTIA_OFFSET_GRAFM: + GTIA_GRAFM = byte; + UPDATE_PM_CYCLE_EXACT + break; + +#ifdef NEW_CYCLE_EXACT +#define CYCLE_EXACT_GRAFP(n) x = ANTIC_XPOS * 2 - 3;\ + if (GTIA_HPOSP##n >= x) {\ + /* hpos right of x */\ + /* redraw */ \ + UPDATE_PM_CYCLE_EXACT\ + } +#else +#define CYCLE_EXACT_GRAFP(n) +#endif /* NEW_CYCLE_EXACT */ + +#define DO_GRAFP(n) case GTIA_OFFSET_GRAFP##n:\ + GTIA_GRAFP##n = byte;\ + CYCLE_EXACT_GRAFP(n);\ + break; + + DO_GRAFP(0) + DO_GRAFP(1) + DO_GRAFP(2) + DO_GRAFP(3) + + case GTIA_OFFSET_HITCLR: + GTIA_M0PL = GTIA_M1PL = GTIA_M2PL = GTIA_M3PL = 0; + GTIA_P0PL = GTIA_P1PL = GTIA_P2PL = GTIA_P3PL = 0; + PF0PM = PF1PM = PF2PM = PF3PM = 0; +#ifdef NEW_CYCLE_EXACT + hitclr_pos = ANTIC_XPOS * 2 - 37; + collision_curpos = hitclr_pos; +#endif + break; +/* TODO: cycle-exact missile HPOS, GRAF, SIZE */ +/* this is only an approximation */ + case GTIA_OFFSET_HPOSM0: + GTIA_HPOSM0 = byte; + hposm_ptr[0] = GTIA_pm_scanline + byte - 0x20; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_HPOSM1: + GTIA_HPOSM1 = byte; + hposm_ptr[1] = GTIA_pm_scanline + byte - 0x20; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_HPOSM2: + GTIA_HPOSM2 = byte; + hposm_ptr[2] = GTIA_pm_scanline + byte - 0x20; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_HPOSM3: + GTIA_HPOSM3 = byte; + hposm_ptr[3] = GTIA_pm_scanline + byte - 0x20; + UPDATE_PM_CYCLE_EXACT + break; + +#ifdef NEW_CYCLE_EXACT +#define CYCLE_EXACT_HPOSP(n) x = ANTIC_XPOS * 2 - 1;\ + if (GTIA_HPOSP##n < x && byte < x) {\ + /* case 1: both left of x */\ + /* do nothing */\ + }\ + else if (GTIA_HPOSP##n >= x && byte >= x ) {\ + /* case 2: both right of x */\ + /* redraw, clearing first */\ + UPDATE_PM_CYCLE_EXACT\ + }\ + else if (GTIA_HPOSP##n = x) {\ + /* case 3: new value is right, old value is left */\ + /* redraw without clearing first */\ + /* note: a hack, we can get away with it unless another change occurs */\ + /* before the original copy that wasn't erased due to changing */\ + /* GTIA_pm_dirty is drawn */\ + GTIA_pm_dirty = FALSE;\ + UPDATE_PM_CYCLE_EXACT\ + GTIA_pm_dirty = TRUE; /* can't trust that it was reset correctly */\ + }\ + else {\ + /* case 4: new value is left, old value is right */\ + /* remove old player and don't draw the new one */\ + UBYTE save_graf = GTIA_GRAFP##n;\ + GTIA_GRAFP##n = 0;\ + UPDATE_PM_CYCLE_EXACT\ + GTIA_GRAFP##n = save_graf;\ + } +#else +#define CYCLE_EXACT_HPOSP(n) +#endif /* NEW_CYCLE_EXACT */ +#define DO_HPOSP(n) case GTIA_OFFSET_HPOSP##n: \ + hposp_ptr[n] = GTIA_pm_scanline + byte - 0x20; \ + if (byte >= 0x22) { \ + if (byte > 0xbe) { \ + if (byte >= 0xde) \ + hposp_mask[n] = 0; \ + else \ + hposp_mask[n] = 0xffffffff >> (byte - 0xbe); \ + } \ + else \ + hposp_mask[n] = 0xffffffff; \ + } \ + else if (byte > 2) \ + hposp_mask[n] = 0xffffffff << (0x22 - byte); \ + else \ + hposp_mask[n] = 0; \ + CYCLE_EXACT_HPOSP(n)\ + GTIA_HPOSP##n = byte; \ + break; + + DO_HPOSP(0) + DO_HPOSP(1) + DO_HPOSP(2) + DO_HPOSP(3) + +/* TODO: cycle-exact size changes */ +/* this is only an approximation */ + case GTIA_OFFSET_SIZEM: + GTIA_SIZEM = byte; + global_sizem[0] = PM_Width[byte & 0x03]; + global_sizem[1] = PM_Width[(byte & 0x0c) >> 2]; + global_sizem[2] = PM_Width[(byte & 0x30) >> 4]; + global_sizem[3] = PM_Width[(byte & 0xc0) >> 6]; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_SIZEP0: + GTIA_SIZEP0 = byte; + grafp_ptr[0] = grafp_lookup[byte & 3]; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_SIZEP1: + GTIA_SIZEP1 = byte; + grafp_ptr[1] = grafp_lookup[byte & 3]; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_SIZEP2: + GTIA_SIZEP2 = byte; + grafp_ptr[2] = grafp_lookup[byte & 3]; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_SIZEP3: + GTIA_SIZEP3 = byte; + grafp_ptr[3] = grafp_lookup[byte & 3]; + UPDATE_PM_CYCLE_EXACT + break; + case GTIA_OFFSET_PRIOR: + ANTIC_SetPrior(byte); + GTIA_PRIOR = byte; + if (byte & 0x40) + setup_gtia9_11(); + break; + case GTIA_OFFSET_VDELAY: + GTIA_VDELAY = byte; + break; + case GTIA_OFFSET_GRACTL: + GTIA_GRACTL = byte; + ANTIC_missile_gra_enabled = (byte & 0x01); + ANTIC_player_gra_enabled = (byte & 0x02); + ANTIC_player_flickering = ((ANTIC_player_dma_enabled | ANTIC_player_gra_enabled) == 0x02); + ANTIC_missile_flickering = ((ANTIC_missile_dma_enabled | ANTIC_missile_gra_enabled) == 0x01); + if ((byte & 4) == 0) + GTIA_TRIG_latch[0] = GTIA_TRIG_latch[1] = GTIA_TRIG_latch[2] = GTIA_TRIG_latch[3] = 1; + break; + +#endif /* defined(BASIC) || defined(CURSES_BASIC) */ + } +} + +/* State ------------------------------------------------------------------- */ + +#ifndef BASIC + +void GTIA_StateSave(void) +{ + int next_console_value = 7; + + StateSav_SaveUBYTE(>IA_HPOSP0, 1); + StateSav_SaveUBYTE(>IA_HPOSP1, 1); + StateSav_SaveUBYTE(>IA_HPOSP2, 1); + StateSav_SaveUBYTE(>IA_HPOSP3, 1); + StateSav_SaveUBYTE(>IA_HPOSM0, 1); + StateSav_SaveUBYTE(>IA_HPOSM1, 1); + StateSav_SaveUBYTE(>IA_HPOSM2, 1); + StateSav_SaveUBYTE(>IA_HPOSM3, 1); + StateSav_SaveUBYTE(&PF0PM, 1); + StateSav_SaveUBYTE(&PF1PM, 1); + StateSav_SaveUBYTE(&PF2PM, 1); + StateSav_SaveUBYTE(&PF3PM, 1); + StateSav_SaveUBYTE(>IA_M0PL, 1); + StateSav_SaveUBYTE(>IA_M1PL, 1); + StateSav_SaveUBYTE(>IA_M2PL, 1); + StateSav_SaveUBYTE(>IA_M3PL, 1); + StateSav_SaveUBYTE(>IA_P0PL, 1); + StateSav_SaveUBYTE(>IA_P1PL, 1); + StateSav_SaveUBYTE(>IA_P2PL, 1); + StateSav_SaveUBYTE(>IA_P3PL, 1); + StateSav_SaveUBYTE(>IA_SIZEP0, 1); + StateSav_SaveUBYTE(>IA_SIZEP1, 1); + StateSav_SaveUBYTE(>IA_SIZEP2, 1); + StateSav_SaveUBYTE(>IA_SIZEP3, 1); + StateSav_SaveUBYTE(>IA_SIZEM, 1); + StateSav_SaveUBYTE(>IA_GRAFP0, 1); + StateSav_SaveUBYTE(>IA_GRAFP1, 1); + StateSav_SaveUBYTE(>IA_GRAFP2, 1); + StateSav_SaveUBYTE(>IA_GRAFP3, 1); + StateSav_SaveUBYTE(>IA_GRAFM, 1); + StateSav_SaveUBYTE(>IA_COLPM0, 1); + StateSav_SaveUBYTE(>IA_COLPM1, 1); + StateSav_SaveUBYTE(>IA_COLPM2, 1); + StateSav_SaveUBYTE(>IA_COLPM3, 1); + StateSav_SaveUBYTE(>IA_COLPF0, 1); + StateSav_SaveUBYTE(>IA_COLPF1, 1); + StateSav_SaveUBYTE(>IA_COLPF2, 1); + StateSav_SaveUBYTE(>IA_COLPF3, 1); + StateSav_SaveUBYTE(>IA_COLBK, 1); + StateSav_SaveUBYTE(>IA_PRIOR, 1); + StateSav_SaveUBYTE(>IA_VDELAY, 1); + StateSav_SaveUBYTE(>IA_GRACTL, 1); + + StateSav_SaveUBYTE(&consol_mask, 1); + StateSav_SaveINT(>IA_speaker, 1); + StateSav_SaveINT(&next_console_value, 1); + StateSav_SaveUBYTE(GTIA_TRIG_latch, 4); +} + +void GTIA_StateRead(UBYTE version) +{ + int next_console_value; /* ignored */ + + StateSav_ReadUBYTE(>IA_HPOSP0, 1); + StateSav_ReadUBYTE(>IA_HPOSP1, 1); + StateSav_ReadUBYTE(>IA_HPOSP2, 1); + StateSav_ReadUBYTE(>IA_HPOSP3, 1); + StateSav_ReadUBYTE(>IA_HPOSM0, 1); + StateSav_ReadUBYTE(>IA_HPOSM1, 1); + StateSav_ReadUBYTE(>IA_HPOSM2, 1); + StateSav_ReadUBYTE(>IA_HPOSM3, 1); + StateSav_ReadUBYTE(&PF0PM, 1); + StateSav_ReadUBYTE(&PF1PM, 1); + StateSav_ReadUBYTE(&PF2PM, 1); + StateSav_ReadUBYTE(&PF3PM, 1); + StateSav_ReadUBYTE(>IA_M0PL, 1); + StateSav_ReadUBYTE(>IA_M1PL, 1); + StateSav_ReadUBYTE(>IA_M2PL, 1); + StateSav_ReadUBYTE(>IA_M3PL, 1); + StateSav_ReadUBYTE(>IA_P0PL, 1); + StateSav_ReadUBYTE(>IA_P1PL, 1); + StateSav_ReadUBYTE(>IA_P2PL, 1); + StateSav_ReadUBYTE(>IA_P3PL, 1); + StateSav_ReadUBYTE(>IA_SIZEP0, 1); + StateSav_ReadUBYTE(>IA_SIZEP1, 1); + StateSav_ReadUBYTE(>IA_SIZEP2, 1); + StateSav_ReadUBYTE(>IA_SIZEP3, 1); + StateSav_ReadUBYTE(>IA_SIZEM, 1); + StateSav_ReadUBYTE(>IA_GRAFP0, 1); + StateSav_ReadUBYTE(>IA_GRAFP1, 1); + StateSav_ReadUBYTE(>IA_GRAFP2, 1); + StateSav_ReadUBYTE(>IA_GRAFP3, 1); + StateSav_ReadUBYTE(>IA_GRAFM, 1); + StateSav_ReadUBYTE(>IA_COLPM0, 1); + StateSav_ReadUBYTE(>IA_COLPM1, 1); + StateSav_ReadUBYTE(>IA_COLPM2, 1); + StateSav_ReadUBYTE(>IA_COLPM3, 1); + StateSav_ReadUBYTE(>IA_COLPF0, 1); + StateSav_ReadUBYTE(>IA_COLPF1, 1); + StateSav_ReadUBYTE(>IA_COLPF2, 1); + StateSav_ReadUBYTE(>IA_COLPF3, 1); + StateSav_ReadUBYTE(>IA_COLBK, 1); + StateSav_ReadUBYTE(>IA_PRIOR, 1); + StateSav_ReadUBYTE(>IA_VDELAY, 1); + StateSav_ReadUBYTE(>IA_GRACTL, 1); + + StateSav_ReadUBYTE(&consol_mask, 1); + StateSav_ReadINT(>IA_speaker, 1); + StateSav_ReadINT(&next_console_value, 1); + if (version >= 7) + StateSav_ReadUBYTE(GTIA_TRIG_latch, 4); + + GTIA_PutByte(GTIA_OFFSET_HPOSP0, GTIA_HPOSP0); + GTIA_PutByte(GTIA_OFFSET_HPOSP1, GTIA_HPOSP1); + GTIA_PutByte(GTIA_OFFSET_HPOSP2, GTIA_HPOSP2); + GTIA_PutByte(GTIA_OFFSET_HPOSP3, GTIA_HPOSP3); + GTIA_PutByte(GTIA_OFFSET_HPOSM0, GTIA_HPOSM0); + GTIA_PutByte(GTIA_OFFSET_HPOSM1, GTIA_HPOSM1); + GTIA_PutByte(GTIA_OFFSET_HPOSM2, GTIA_HPOSM2); + GTIA_PutByte(GTIA_OFFSET_HPOSM3, GTIA_HPOSM3); + GTIA_PutByte(GTIA_OFFSET_SIZEP0, GTIA_SIZEP0); + GTIA_PutByte(GTIA_OFFSET_SIZEP1, GTIA_SIZEP1); + GTIA_PutByte(GTIA_OFFSET_SIZEP2, GTIA_SIZEP2); + GTIA_PutByte(GTIA_OFFSET_SIZEP3, GTIA_SIZEP3); + GTIA_PutByte(GTIA_OFFSET_SIZEM, GTIA_SIZEM); + GTIA_PutByte(GTIA_OFFSET_GRAFP0, GTIA_GRAFP0); + GTIA_PutByte(GTIA_OFFSET_GRAFP1, GTIA_GRAFP1); + GTIA_PutByte(GTIA_OFFSET_GRAFP2, GTIA_GRAFP2); + GTIA_PutByte(GTIA_OFFSET_GRAFP3, GTIA_GRAFP3); + GTIA_PutByte(GTIA_OFFSET_GRAFM, GTIA_GRAFM); + GTIA_PutByte(GTIA_OFFSET_COLPM0, GTIA_COLPM0); + GTIA_PutByte(GTIA_OFFSET_COLPM1, GTIA_COLPM1); + GTIA_PutByte(GTIA_OFFSET_COLPM2, GTIA_COLPM2); + GTIA_PutByte(GTIA_OFFSET_COLPM3, GTIA_COLPM3); + GTIA_PutByte(GTIA_OFFSET_COLPF0, GTIA_COLPF0); + GTIA_PutByte(GTIA_OFFSET_COLPF1, GTIA_COLPF1); + GTIA_PutByte(GTIA_OFFSET_COLPF2, GTIA_COLPF2); + GTIA_PutByte(GTIA_OFFSET_COLPF3, GTIA_COLPF3); + GTIA_PutByte(GTIA_OFFSET_COLBK, GTIA_COLBK); + GTIA_PutByte(GTIA_OFFSET_PRIOR, GTIA_PRIOR); + GTIA_PutByte(GTIA_OFFSET_GRACTL, GTIA_GRACTL); +} + +#endif /* BASIC */ diff --git a/MCUME_teensy41/teensy800/gtia.h b/MCUME_teensy41/teensy800/gtia.h new file mode 100644 index 0000000..865c4ae --- /dev/null +++ b/MCUME_teensy41/teensy800/gtia.h @@ -0,0 +1,136 @@ +#ifndef GTIA_H_ +#define GTIA_H_ + + +#define GTIA_OFFSET_HPOSP0 0x00 +#define GTIA_OFFSET_M0PF 0x00 +#define GTIA_OFFSET_HPOSP1 0x01 +#define GTIA_OFFSET_M1PF 0x01 +#define GTIA_OFFSET_HPOSP2 0x02 +#define GTIA_OFFSET_M2PF 0x02 +#define GTIA_OFFSET_HPOSP3 0x03 +#define GTIA_OFFSET_M3PF 0x03 +#define GTIA_OFFSET_HPOSM0 0x04 +#define GTIA_OFFSET_P0PF 0x04 +#define GTIA_OFFSET_HPOSM1 0x05 +#define GTIA_OFFSET_P1PF 0x05 +#define GTIA_OFFSET_HPOSM2 0x06 +#define GTIA_OFFSET_P2PF 0x06 +#define GTIA_OFFSET_HPOSM3 0x07 +#define GTIA_OFFSET_P3PF 0x07 +#define GTIA_OFFSET_SIZEP0 0x08 +#define GTIA_OFFSET_M0PL 0x08 +#define GTIA_OFFSET_SIZEP1 0x09 +#define GTIA_OFFSET_M1PL 0x09 +#define GTIA_OFFSET_SIZEP2 0x0a +#define GTIA_OFFSET_M2PL 0x0a +#define GTIA_OFFSET_SIZEP3 0x0b +#define GTIA_OFFSET_M3PL 0x0b +#define GTIA_OFFSET_SIZEM 0x0c +#define GTIA_OFFSET_P0PL 0x0c +#define GTIA_OFFSET_GRAFP0 0x0d +#define GTIA_OFFSET_P1PL 0x0d +#define GTIA_OFFSET_GRAFP1 0x0e +#define GTIA_OFFSET_P2PL 0x0e +#define GTIA_OFFSET_GRAFP2 0x0f +#define GTIA_OFFSET_P3PL 0x0f +#define GTIA_OFFSET_GRAFP3 0x10 +#define GTIA_OFFSET_TRIG0 0x10 +#define GTIA_OFFSET_GRAFM 0x11 +#define GTIA_OFFSET_TRIG1 0x11 +#define GTIA_OFFSET_COLPM0 0x12 +#define GTIA_OFFSET_TRIG2 0x12 +#define GTIA_OFFSET_COLPM1 0x13 +#define GTIA_OFFSET_TRIG3 0x13 +#define GTIA_OFFSET_COLPM2 0x14 +#define GTIA_OFFSET_PAL 0x14 +#define GTIA_OFFSET_COLPM3 0x15 +#define GTIA_OFFSET_COLPF0 0x16 +#define GTIA_OFFSET_COLPF1 0x17 +#define GTIA_OFFSET_COLPF2 0x18 +#define GTIA_OFFSET_COLPF3 0x19 +#define GTIA_OFFSET_COLBK 0x1a +#define GTIA_OFFSET_PRIOR 0x1b +#define GTIA_OFFSET_VDELAY 0x1c +#define GTIA_OFFSET_GRACTL 0x1d +#define GTIA_OFFSET_HITCLR 0x1e +#define GTIA_OFFSET_CONSOL 0x1f + +extern UBYTE GTIA_GRAFM; +extern UBYTE GTIA_GRAFP0; +extern UBYTE GTIA_GRAFP1; +extern UBYTE GTIA_GRAFP2; +extern UBYTE GTIA_GRAFP3; +extern UBYTE GTIA_HPOSP0; +extern UBYTE GTIA_HPOSP1; +extern UBYTE GTIA_HPOSP2; +extern UBYTE GTIA_HPOSP3; +extern UBYTE GTIA_HPOSM0; +extern UBYTE GTIA_HPOSM1; +extern UBYTE GTIA_HPOSM2; +extern UBYTE GTIA_HPOSM3; +extern UBYTE GTIA_SIZEP0; +extern UBYTE GTIA_SIZEP1; +extern UBYTE GTIA_SIZEP2; +extern UBYTE GTIA_SIZEP3; +extern UBYTE GTIA_SIZEM; +extern UBYTE GTIA_COLPM0; +extern UBYTE GTIA_COLPM1; +extern UBYTE GTIA_COLPM2; +extern UBYTE GTIA_COLPM3; +extern UBYTE GTIA_COLPF0; +extern UBYTE GTIA_COLPF1; +extern UBYTE GTIA_COLPF2; +extern UBYTE GTIA_COLPF3; +extern UBYTE GTIA_COLBK; +extern UBYTE GTIA_GRACTL; +extern UBYTE GTIA_M0PL; +extern UBYTE GTIA_M1PL; +extern UBYTE GTIA_M2PL; +extern UBYTE GTIA_M3PL; +extern UBYTE GTIA_P0PL; +extern UBYTE GTIA_P1PL; +extern UBYTE GTIA_P2PL; +extern UBYTE GTIA_P3PL; +extern UBYTE GTIA_PRIOR; +extern UBYTE GTIA_VDELAY; + +#ifdef USE_COLOUR_TRANSLATION_TABLE + +extern UWORD GTIA_colour_translation_table[256]; +#define GTIA_COLOUR_BLACK GTIA_colour_translation_table[0] +#define GTIA_COLOUR_TO_WORD(dest,src) dest = GTIA_colour_translation_table[src]; + +#else + +#define GTIA_COLOUR_BLACK 0 +#define GTIA_COLOUR_TO_WORD(dest,src) dest = (((UWORD) (src)) << 8) | (src); + +#endif /* USE_COLOUR_TRANSLATION_TABLE */ + +extern UBYTE GTIA_pm_scanline[ATARI_WIDTH / 2 + 8]; /* there's a byte for every *pair* of pixels */ +extern int GTIA_pm_dirty; + +extern UBYTE GTIA_collisions_mask_missile_playfield; +extern UBYTE GTIA_collisions_mask_player_playfield; +extern UBYTE GTIA_collisions_mask_missile_player; +extern UBYTE GTIA_collisions_mask_player_player; + +extern UBYTE GTIA_TRIG[4]; +extern UBYTE GTIA_TRIG_latch[4]; + +extern int GTIA_consol_override; +extern int GTIA_speaker; + +int GTIA_Initialise(void); +void GTIA_Frame(void); +void GTIA_NewPmScanline(void); +UBYTE GTIA_GetByte(UWORD addr, int no_side_effects); +void GTIA_PutByte(UWORD addr, UBYTE byte); +void GTIA_StateSave(void); +void GTIA_StateRead(UBYTE version); + +#ifdef NEW_CYCLE_EXACT +void GTIA_UpdatePmplColls(void); +#endif +#endif /* GTIA_H_ */ diff --git a/MCUME_teensy41/teensy800/iopins.h b/MCUME_teensy41/teensy800/iopins.h new file mode 100644 index 0000000..24bcda2 --- /dev/null +++ b/MCUME_teensy41/teensy800/iopins.h @@ -0,0 +1,124 @@ +#ifndef IOPINS_H +#define IOPINS_H + +#include "platform_config.h" + +#ifdef TEECOMPUTER + +// Teecomputer layout + +// VGA +// R 3 2K +// R 4 1K +// R 33 500 +// G 11 2K +// G 13 1K +// G 2 500 +// B 10 820 +// B 12 390 +// HSYNC 15 82 +// VSYNC 8 82 + +// Display +#define TFT_SCLK 27 +#define TFT_MOSI 26 +#define TFT_MISO 255 +#define TFT_TOUCH_CS 255 +#define TFT_TOUCH_INT 255 +#define TFT_DC 23 +#define TFT_CS 22 // 255 for LORES ST7789 (NO CS) +#define TFT_RST 255 // 255 for ILI/ST if connected to 3.3V or 24 if really needed + + +// SD +#define SD_CS BUILTIN_SDCARD + +// Audio +#define AUDIO_I2S_DIN 7 +#define AUDIO_I2S_BCK 21 +#define AUDIO_I2S_LCK 20 + +// Keyboard matrix +#define KLED 14 +//Cols (out) +//pico 1,2,3,4,5,14 +//teen 16,6,24,25,28,31 +#define KCOLOUT1 16 +#define KCOLOUT2 6 +#define KCOLOUT3 24 +#define KCOLOUT4 25 +#define KCOLOUT5 28 +#define KCOLOUT6 31 +//Rows (in) +//pico 9,8,6,15,7,22 +//teen 19,18,17,5,29,30,32 //5,6,16,17,18,19 +#define KROWIN1 19 +#define KROWIN2 18 +#define KROWIN3 17 +#define KROWIN4 5 +#define KROWIN5 29 +#define KROWIN6 30 +#define KROWIN7 32 + +#define PIN_KEY_USER1 41 +#define PIN_KEY_USER2 40 + +// Second joystick (external) +#define PIN_JOY1_BTN 34 +#define PIN_JOY1_1 35 // UP +#define PIN_JOY1_2 36 // DOWN +#define PIN_JOY1_3 38 // RIGHT +#define PIN_JOY1_4 37 // LEFT + +#else + +// Original Layout +#define TFT_SCLK 13 +#define TFT_MOSI 11 +#define TFT_MISO 12 +#define TFT_TOUCH_CS 255 +#define TFT_TOUCH_INT 255 +#define TFT_DC 9 +#define TFT_CS 22 // 255 for LORES ST7789 (NO CS) +#define TFT_RST 23 // 255 for ILI/ST if connected to 3.3V + +// SD +#define SD_CS BUILTIN_SDCARD + +// I2C keyboard +#define I2C_SCL_IO 19 +#define I2C_SDA_IO 18 + +// Analog joystick (primary) for JOY2 and 5 extra buttons +#ifdef HAS_T4_VGA +#define PIN_JOY2_A1X A3 +#define PIN_JOY2_A2Y A2 +#define PIN_JOY2_BTN 14 +#define PIN_KEY_USER1 22 +#define PIN_KEY_USER2 23 + +// Second joystick +#define PIN_JOY1_BTN 34 +#define PIN_JOY1_1 35 // UP +#define PIN_JOY1_2 36 // DOWN +#define PIN_JOY1_3 38 // RIGHT +#define PIN_JOY1_4 37 // LEFT + +#else +#define PIN_JOY2_A1X A1 +#define PIN_JOY2_A2Y A2 +#define PIN_JOY2_BTN 17 +#define PIN_KEY_USER1 3 //34 +#define PIN_KEY_USER2 4 //35 + +// Second joystick +#define PIN_JOY1_BTN 2 +#define PIN_JOY1_1 14 // UP +#define PIN_JOY1_2 7 // DOWN +#define PIN_JOY1_3 6 // RIGHT +#define PIN_JOY1_4 5 // LEFT +#endif + +#endif + +#endif diff --git a/MCUME_teensy41/teensy800/memory.h b/MCUME_teensy41/teensy800/memory.h new file mode 100644 index 0000000..1945156 --- /dev/null +++ b/MCUME_teensy41/teensy800/memory.h @@ -0,0 +1,18 @@ +#ifndef __MEMORY__ +#define __MEMORY__ + +extern unsigned char * memory; + +#define MEMORY_GetByte(addr) (Atari_GetByte(addr)) +#define MEMORY_PutByte(addr,byte) Atari_PutByte(addr,byte) + +#define MEMORY_dGetByte(addr) (Atari_GetByte(addr)) +#define MEMORY_dPutByte(addr,byte) Atari_PutByte(addr,byte) +#define MEMORY_dGetWord(x) (Atari_GetByte(x) | (Atari_GetByte((x) + 1) << 8)) +#define MEMORY_dPutWord(x,y) (Atari_PutByte(x,(UBYTE) (y)) , Atari_PutByte(x + 1,(UBYTE) ((y) >> 8)) +/* faster versions of dGetWord and dPutWord for even addresses */ +/* TODO: guarantee that memory is UWORD-aligned and use UWORD access */ +#define MEMORY_dGetWordAligned(x) MEMORY_dGetWord(x) +#define MEMORY_dPutWordAligned(x,y) MEMORY_dPutWord(x,y) + +#endif diff --git a/MCUME_teensy41/teensy800/noise.h b/MCUME_teensy41/teensy800/noise.h new file mode 100644 index 0000000..c93ac89 --- /dev/null +++ b/MCUME_teensy41/teensy800/noise.h @@ -0,0 +1,1059 @@ +const UBYTE POKEY_poly9_lookup[] = { +255,127,63,31,15,135,195,225,240,120,188,222,239,119,59,29, +14,135,67,161,208,104,52,154,205,102,179,217,108,182,219,237, +246,123,189,94,47,23,11,133,194,225,112,56,156,206,103,51, +25,12,134,67,33,144,72,36,18,137,68,162,81,168,212,234, +117,186,93,174,215,235,245,122,61,158,79,39,147,73,164,210, +233,116,58,157,206,231,115,57,28,14,7,3,129,192,224,112, +184,220,238,119,187,93,46,151,203,229,242,121,188,94,175,87, +43,149,74,165,82,41,20,10,5,2,129,64,160,80,168,84, +170,85,170,213,234,245,250,125,190,95,175,215,107,181,90,45, +22,11,5,130,193,96,176,216,236,118,187,221,110,183,219,109, +182,91,173,214,107,53,26,13,6,131,65,160,208,232,116,186, +221,238,247,251,125,62,31,143,199,227,241,120,60,158,207,103, +179,89,44,150,203,101,178,89,172,214,235,117,58,29,142,199, +99,177,88,44,22,139,69,162,209,232,244,250,253,254,127,191, +95,47,151,75,165,210,105,52,26,141,70,163,81,40,148,202, +101,50,25,140,198,99,49,24,12,6,3,1,128,192,96,48, +152,204,102,51,153,76,166,83,169,212,106,53,154,77,38,147, +201,228,242,249,252,126,191,223,111,183,91,45,150,75,37,146, +73,36,146,201,100,178,217,236,246,251,253,126,63,159,79,167, +211,105,180,90,173,86,43,21,10,133,66,161,80,40,20,138, +69,34,145,200,228,114,185,220,110,55,155,77,166,211,233,244, +122,189,222,111,55,27,13,134,195,97,176,88,172,86,171,85, +42,149,202,229,114,57,156,78,39,19,9,132,194,97,48,24, +140,70,35,17,8,132,66,33,16,8,4,2,1,0,128,64, +32,16,136,68,34,17,136,196,98,49,152,76,38,19,137,196, +226,113,184,92,174,87,171,213,106,181,218,109,54,27,141,198, +227,113,56,28,142,71,35,145,72,164,82,169,84,42,21,138, +197,98,177,216,108,54,155,205,230,243,249,124,62,159,207,231, +243,121,60,30,143,71,163,209,104,180,218,237,118,59,157,78, +167,83,41,148,74,37,18,9,4,130,65,32,144,200,100,50, +153,204,230,115,185,92,46,23,139,197,226,241,248,124,190,223, +239,247,123,61,30,15,7,131,193,224,240,248,252,254,255,}; +const UBYTE POKEY_poly17_lookup[] = { +255,1,224,3,254,231,131,241,31,28,254,217,99,142,33,4, +1,24,130,17,28,226,25,90,146,145,61,250,216,123,12,48, +24,227,1,216,131,141,223,227,130,233,157,13,226,59,122,212, +179,149,60,226,90,106,16,210,1,185,147,73,190,119,7,152, +142,217,133,238,227,227,249,89,108,118,190,11,199,103,242,233, +123,109,32,220,130,149,93,242,158,11,132,87,112,170,71,46, +107,238,48,210,66,137,17,10,130,52,76,170,60,158,154,149, +108,226,255,58,80,118,197,187,54,28,174,217,198,222,97,160, +197,26,39,68,12,76,216,28,125,232,125,14,28,220,249,37, +172,137,194,59,57,228,49,214,0,161,17,88,162,149,30,194, +28,72,184,20,59,152,245,105,116,149,191,211,68,234,45,10, +249,132,189,209,96,174,39,38,45,158,184,181,42,192,87,252, +106,87,163,155,252,254,22,146,12,237,201,68,223,125,99,204, +0,148,65,49,151,17,55,82,77,113,142,5,68,75,60,82, +91,17,163,19,124,230,159,50,22,6,77,220,94,85,232,47, +46,189,142,145,5,122,171,67,108,67,238,98,242,227,219,121, +42,84,22,205,253,70,148,201,177,143,152,151,72,166,245,22, +132,108,192,223,124,114,222,3,129,23,122,142,19,36,102,42, +106,246,178,195,94,107,8,80,16,165,113,80,228,229,150,165, +116,1,254,226,211,251,26,88,180,245,51,212,36,229,27,116, +118,143,27,166,86,38,200,206,124,81,238,71,162,171,254,189, +34,80,71,213,218,7,200,143,108,215,175,83,101,242,236,43, +103,37,152,200,185,13,168,155,234,158,59,132,52,64,106,36, +146,106,141,3,34,39,54,44,175,170,244,31,22,94,205,105, +6,181,92,161,172,136,211,41,58,241,103,157,25,163,2,108, +197,142,102,117,155,93,239,78,48,153,243,11,88,151,197,119, +247,152,97,40,69,2,174,228,22,167,92,132,252,192,246,237, +50,245,54,133,62,226,94,42,24,214,81,177,182,9,246,115, +211,208,171,28,157,232,179,239,156,17,32,34,98,102,162,234, +238,59,99,68,128,140,200,145,141,250,179,202,204,89,5,230, +106,98,243,242,201,122,63,2,93,212,255,85,160,174,170,247, +47,16,93,241,175,29,133,106,162,243,126,8,122,176,243,91, +88,50,149,55,83,92,99,141,16,18,0,37,80,72,37,196, +8,4,81,24,39,65,92,70,221,88,55,196,45,84,25,61, +227,73,88,23,197,127,118,152,107,137,65,10,39,100,12,14, +248,156,63,192,124,76,62,124,191,15,133,79,242,187,91,204, +114,180,162,67,127,115,201,113,142,4,84,73,61,70,25,24, +179,1,125,211,205,123,39,128,76,200,29,76,250,60,59,202, +213,200,38,253,159,5,102,107,122,112,243,215,153,50,26,198, +85,208,174,77,135,239,246,177,242,72,106,53,130,73,156,87, +65,186,38,31,191,207,133,195,51,187,212,61,116,56,111,131, +232,142,63,229,44,4,27,184,183,11,212,87,213,250,7,138, +175,236,149,135,82,39,208,76,109,77,12,94,248,57,111,128, +216,136,60,217,234,31,43,142,180,84,34,140,134,112,5,182, +106,199,163,178,109,190,61,167,8,196,81,148,230,65,211,183, +219,212,250,4,186,169,239,169,65,73,23,230,79,50,187,215, +13,114,59,83,69,243,190,9,230,115,242,192,235,61,9,232, +146,254,204,50,181,54,1,126,226,219,122,26,82,21,241,59, +93,164,255,178,208,110,76,27,44,247,42,65,71,246,234,67, +235,51,232,228,158,39,68,13,92,218,29,105,170,116,30,14, +221,204,119,229,184,68,58,45,167,40,196,19,180,102,3,251, +182,153,246,90,66,144,128,41,153,193,43,63,165,45,144,89, +185,38,25,223,195,131,187,191,140,180,81,114,134,131,52,79, +154,58,157,166,83,119,210,201,57,15,128,30,232,188,30,146, +28,237,232,84,159,92,247,204,33,133,17,18,2,5,84,74, +13,64,26,36,117,26,77,229,206,36,209,91,31,66,31,112, +63,23,13,255,234,81,203,22,250,140,59,161,100,8,79,224, +154,110,220,27,5,102,106,106,114,242,195,219,59,10,212,84, +229,252,4,182,105,247,165,177,81,120,38,151,62,199,14,98, +61,18,89,181,231,17,209,50,143,150,118,68,170,44,158,187, +133,44,195,107,58,113,103,149,152,163,8,205,193,134,239,245, +129,244,75,86,243,153,121,170,84,30,76,253,76,53,205,185, +6,24,141,225,2,237,213,132,230,97,211,245,251,84,184,44, +187,235,205,9,7,99,62,32,127,178,217,255,78,16,153,177, +43,216,213,237,118,181,186,193,110,111,43,104,212,150,197,116, +199,158,98,20,131,25,158,210,21,248,170,95,175,74,244,209, +247,222,0,176,1,123,179,193,125,95,12,123,168,113,74,68, +208,140,109,193,205,94,119,200,105,12,21,72,171,36,28,139, +137,142,251,165,168,193,75,63,99,77,16,158,193,37,223,185, +35,72,197,196,198,229,209,213,254,70,146,169,189,137,224,27, +127,198,153,16,58,128,119,120,104,119,166,137,214,123,16,240, +33,255,177,225,120,77,38,254,174,19,103,86,168,41,202,241, +136,108,217,79,79,107,42,112,86,135,217,150,222,196,240,133, +190,227,70,169,25,200,178,188,174,146,119,92,40,61,130,89, +156,118,81,250,7,139,191,238,148,147,16,46,192,94,108,120, +94,23,201,191,110,148,155,145,46,202,255,104,112,215,151,211, +22,202,140,88,145,164,107,243,225,249,93,44,126,186,91,207, +66,178,161,127,185,104,249,71,141,91,162,146,110,204,27,36, +118,42,75,230,242,226,202,107,41,65,64,134,228,68,135,253, +214,148,224,32,207,179,162,76,143,109,198,189,80,112,164,167, +50,101,54,172,175,162,117,31,28,255,201,97,143,53,70,8, +8,144,16,41,176,80,107,20,144,41,185,193,105,31,37,111, +184,88,251,4,185,153,233,170,125,143,12,214,121,49,228,33, +214,33,177,81,121,54,149,63,211,76,107,45,0,88,128,181, +88,224,180,142,130,53,93,184,63,139,204,222,117,224,236,14, +55,109,189,12,177,9,249,131,205,223,103,194,233,24,93,224, +191,62,148,62,193,110,110,59,106,213,130,135,125,215,140,99, +33,209,80,175,84,20,236,233,70,189,89,225,166,172,135,35, +55,53,61,185,233,233,77,13,79,234,58,122,214,147,145,62, +202,222,120,48,246,3,211,55,219,220,123,4,176,8,235,161, +200,201,13,79,235,42,120,215,135,211,55,218,204,121,5,164, +74,226,177,218,200,56,29,162,27,254,214,147,144,46,200,223, +108,114,255,19,193,54,238,142,50,53,54,9,255,226,209,219, +30,90,156,113,33,244,0,231,113,208,228,237,23,165,126,160, +250,234,90,123,0,241,16,237,240,212,174,68,23,253,255,5, +160,11,250,183,139,212,95,84,250,13,43,171,228,28,7,72, +142,116,84,174,77,134,255,244,176,230,10,99,37,144,72,169, +5,8,139,160,30,171,140,156,209,32,174,163,102,45,27,232, +183,174,132,23,113,62,5,47,250,252,59,70,20,200,169,12, +153,137,171,171,237,141,5,67,59,50,85,55,223,157,99,2, +225,20,140,232,144,223,216,50,156,166,81,87,214,203,17,139, +146,62,204,190,116,54,142,143,228,87,183,218,197,232,7,175, +255,164,176,67,90,35,129,84,74,12,80,24,37,97,88,68, +245,220,37,228,9,86,115,153,113,43,84,20,237,249,68,188, +77,163,175,188,149,34,2,103,116,136,111,232,89,78,86,248, +41,111,161,200,200,29,77,234,62,58,222,151,193,54,239,158, +48,52,34,75,246,242,195,218,43,8,213,64,167,245,20,164, +104,194,247,248,96,254,39,131,125,222,28,113,40,101,2,236, +196,150,229,116,133,190,226,86,171,24,220,240,181,190,128,118, +105,122,116,179,223,157,98,18,227,21,152,170,153,207,202,51, +169,244,24,102,80,202,5,200,139,44,223,171,3,109,215,172, +99,99,241,208,237,124,21,174,203,230,251,115,200,96,156,7, +65,31,118,95,27,11,135,102,102,171,122,252,50,215,22,195, +28,74,152,16,57,176,113,123,84,177,189,185,224,120,79,6, +250,172,59,227,68,136,13,200,155,44,254,187,67,76,67,172, +66,114,161,243,120,104,118,182,139,215,111,82,249,49,237,176, +212,42,4,23,120,175,7,36,79,186,58,223,134,211,53,250, +200,123,45,32,88,194,149,216,162,156,143,192,23,253,254,21, +162,10,238,245,130,196,77,85,207,95,98,154,98,29,19,11, +151,102,71,187,58,221,166,215,55,210,76,105,13,4,90,168, +49,74,192,144,140,232,145,207,218,51,136,228,88,71,196,202, +36,217,219,15,74,191,96,117,151,157,247,66,192,129,156,203, +128,155,185,174,152,215,72,34,181,22,1,60,194,91,56,50, +83,87,211,155,27,142,214,116,224,238,46,51,111,149,136,163, +41,221,129,167,123,245,160,229,27,117,102,141,26,178,20,47, +216,220,125,100,188,14,147,45,255,169,97,73,85,198,207,112, +147,214,79,80,155,21,111,218,120,57,102,17,218,131,137,159, +235,134,185,149,40,162,115,126,0,251,176,249,250,92,58,28, +183,73,245,199,149,211,18,138,132,92,193,172,78,179,169,253, +137,100,91,127,67,201,18,190,196,55,245,60,37,42,232,214, +190,64,118,229,187,116,60,46,155,238,223,35,130,101,92,13, +109,202,124,88,126,85,171,31,172,254,178,210,78,72,25,4, +115,56,97,99,244,128,231,121,81,228,231,182,161,118,41,122, +240,243,223,24,50,16,103,81,216,39,205,157,70,82,169,49, +72,224,148,142,192,21,221,250,23,138,142,252,213,166,198,39, +241,93,61,110,153,74,155,33,47,177,76,169,13,136,155,168, +190,187,198,28,65,40,6,50,44,167,42,228,23,182,78,135, +233,150,189,244,48,230,2,226,37,154,233,173,13,129,11,186, +183,15,148,95,209,170,15,175,239,164,145,83,26,2,21,84, +107,29,0,59,176,117,59,92,181,237,177,197,56,7,2,46, +228,30,38,92,142,93,196,254,100,178,239,159,33,38,33,94, +160,185,218,216,56,60,178,91,223,66,147,177,63,152,252,249, +102,156,11,129,7,122,175,3,100,71,190,106,215,163,147,125, +254,28,51,8,229,64,196,197,212,199,212,195,148,203,144,155, +152,190,216,246,220,34,148,7,81,31,87,79,91,42,19,102, +71,186,42,223,167,195,117,219,92,123,12,49,8,225,0,204, +193,132,207,241,131,220,207,68,211,189,123,192,240,140,46,241, +79,29,75,139,34,62,167,15,180,95,147,138,143,237,199,165, +211,113,186,68,63,125,173,45,128,89,152,54,89,254,87,131, +154,174,220,151,196,102,229,155,116,126,14,27,172,247,34,192, +71,252,75,71,227,186,104,254,55,131,92,206,92,80,188,101, +35,253,148,181,112,96,230,166,162,103,63,57,237,161,196,9, +21,67,27,50,23,23,95,223,75,3,163,54,44,174,186,246, +30,2,28,196,121,20,180,105,243,229,185,85,40,46,178,126, +143,10,182,117,55,156,173,225,65,221,87,199,218,34,152,199, +73,19,167,87,52,234,203,106,59,99,69,144,142,201,133,207, +243,163,216,205,108,87,175,91,228,242,230,138,99,45,17,72, +163,164,12,131,41,158,177,37,56,201,227,174,41,199,33,146, +97,61,21,41,187,224,125,31,12,255,232,113,207,20,210,8, +41,129,64,10,37,68,8,12,208,24,45,224,88,78,84,216, +45,109,137,76,218,61,105,232,84,158,76,245,205,53,199,24, +2,16,4,97,24,68,113,156,37,97,89,84,247,221,49,166, +0,70,97,152,68,121,29,37,107,248,80,255,84,177,188,169, +226,121,91,68,243,188,41,226,113,218,68,249,29,45,234,248, +90,94,80,185,53,41,248,208,255,92,48,188,163,67,125,83, +205,115,166,128,70,105,25,68,115,188,33,99,113,208,229,253, +21,164,106,226,243,250,72,122,53,163,89,220,118,213,186,7, +14,239,236,16,215,80,163,148,12,224,25,94,210,153,57,170, +208,94,76,120,28,55,73,253,70,149,217,179,142,140,213,65, +182,231,23,177,62,137,238,250,115,202,64,152,5,105,155,100, +127,63,9,237,194,244,201,118,255,26,81,36,231,58,96,118, +166,139,246,127,18,216,165,237,145,197,122,39,130,108,204,31, +100,126,46,27,238,215,162,130,111,253,9,101,67,252,66,215, +241,179,220,172,116,19,222,199,193,147,191,222,148,240,32,238, +163,226,109,27,109,231,172,0,83,49,179,81,125,118,157,59, +131,68,78,109,72,92,84,253,125,37,172,136,210,57,56,240, +115,223,16,179,16,109,240,220,47,68,29,92,251,13,41,139, +224,30,47,204,156,84,112,172,39,34,109,150,188,229,34,229, +23,180,110,131,235,190,57,230,16,194,0,136,129,8,139,161, +14,169,141,136,147,41,190,177,103,24,73,161,134,40,133,3, +50,39,23,60,239,139,96,31,55,79,157,74,147,161,63,185, +236,185,71,8,11,160,22,42,140,150,112,36,166,42,230,55, +178,76,175,109,132,157,208,50,140,166,112,71,150,234,133,139, +179,47,156,157,225,34,237,151,164,102,35,251,244,185,118,24, +106,145,194,11,57,135,1,22,99,29,16,59,145,101,123,125, +33,237,144,212,104,36,151,58,135,6,102,109,26,124,245,175, +21,5,122,170,83,110,66,250,32,251,243,201,120,31,6,95, +252,123,71,128,138,168,157,139,130,63,253,172,53,3,88,134, +213,84,230,204,2,181,85,49,190,129,103,123,121,97,229,148, +132,96,1,215,114,131,210,46,72,223,100,243,255,25,96,50, +230,7,178,47,159,173,231,33,209,81,191,86,21,248,171,79, +173,75,224,147,254,206,18,177,52,41,250,240,251,94,24,56, +177,99,89,81,167,215,52,226,74,106,49,194,65,152,7,73, +159,102,87,187,27,205,230,246,163,210,109,120,93,39,207,188, +82,82,128,161,24,201,160,158,171,132,29,209,42,15,167,110, +164,155,242,30,10,156,212,113,180,164,35,115,117,177,253,185, +100,56,79,131,170,174,191,167,4,5,89,154,23,77,254,126, +19,202,135,232,135,175,247,37,176,73,251,39,137,221,202,22, +249,188,61,162,88,206,84,208,172,109,131,237,222,53,224,104, +78,55,232,237,14,53,77,185,14,153,141,235,163,233,221,13, +102,123,122,81,227,151,184,166,26,231,68,128,141,216,147,140, +238,241,195,220,75,4,211,56,43,194,116,200,110,124,27,79, +199,234,34,251,247,137,112,27,86,87,217,59,15,132,94,224, +184,78,154,57,173,160,80,75,20,210,9,57,131,65,30,103, +77,24,30,209,45,127,169,105,200,85,204,110,116,155,95,207, +74,50,177,119,25,120,179,199,29,83,10,3,36,70,42,40, +214,50,129,118,106,74,114,176,227,91,121,34,213,22,199,92, +66,156,64,49,149,49,51,80,101,245,156,37,96,73,86,246, +201,115,175,16,84,96,173,22,48,44,163,106,236,19,230,70, +162,169,222,185,32,120,195,199,250,35,202,229,200,69,205,95, +102,218,106,25,67,3,178,38,15,191,238,149,131,18,47,212, +28,101,104,76,22,252,237,39,165,29,144,58,137,230,122,99, +194,224,136,79,233,11,108,215,174,67,103,243,248,105,110,53, +138,201,140,95,225,170,108,159,47,199,45,82,121,49,229,49, +212,32,165,19,112,38,135,62,230,30,34,28,134,89,148,246, +65,242,167,155,245,110,4,155,184,191,138,212,93,116,254,15, +3,47,246,60,35,74,228,208,198,204,65,133,215,114,130,194, +44,73,203,38,250,239,11,97,7,180,78,131,169,158,185,164, +56,195,66,170,33,78,161,136,200,153,13,234,187,106,220,19, +133,118,98,202,98,184,67,75,51,162,69,30,111,205,8,22, +113,61,53,41,249,192,253,93,36,254,170,83,111,82,248,33, +239,177,192,104,13,7,106,174,50,118,6,139,188,222,146,144, +44,232,219,110,90,123,1,225,18,236,228,150,167,84,5,252, +202,87,233,58,124,182,159,151,70,70,233,24,92,240,189,63, +128,124,200,126,124,58,95,135,203,182,251,214,152,32,56,195, +67,186,35,79,181,202,193,137,31,235,142,56,149,34,3,119, +118,137,123,170,80,94,68,249,28,61,232,249,78,28,89,169, +39,40,205,130,182,109,182,189,183,0,100,65,222,102,209,219, +31,74,158,112,53,182,9,247,99,209,209,191,94,148,248,161, +238,169,67,105,19,228,103,182,169,247,41,112,81,247,215,145, +178,10,206,245,192,228,205,23,231,94,32,184,194,91,57,34, +81,86,199,217,18,158,196,117,213,188,103,2,233,148,156,224, +48,207,146,178,12,174,249,198,156,65,32,135,50,38,6,46, +236,158,54,84,46,77,142,126,244,186,71,14,107,172,16,82, +0,161,16,72,160,148,10,128,21,88,170,21,14,202,188,88, +242,148,171,144,93,248,62,31,142,223,228,242,231,154,97,44, +5,10,170,180,30,130,28,204,248,20,190,200,247,237,48,213, +50,135,22,102,76,10,60,212,59,21,36,107,250,112,251,86, +153,56,187,194,93,89,46,87,46,75,238,114,242,194,203,57, +11,192,22,236,236,22,183,92,165,236,128,215,121,50,212,39, +213,29,119,74,73,0,150,96,37,151,56,167,2,100,69,158, +110,213,139,23,111,222,56,49,98,65,210,166,201,215,239,82, +241,176,237,186,117,46,12,158,248,181,174,128,87,121,58,85, +39,223,188,115,66,192,128,140,201,129,143,251,167,136,197,73, +23,231,95,48,186,195,79,123,43,65,68,198,236,64,215,245, +243,212,168,36,27,251,135,137,151,107,150,177,53,56,232,243, +238,8,83,33,179,112,109,54,188,175,131,101,95,61,107,201, +64,158,101,101,157,28,243,8,105,129,196,74,37,193,88,14, +84,92,109,109,12,28,216,185,45,168,217,202,30,121,172,53, +2,72,132,212,64,164,197,18,167,84,4,236,200,86,253,120, +117,166,141,150,115,20,160,41,218,241,169,124,153,110,219,107, +11,97,6,164,76,130,189,220,176,180,42,194,119,248,104,127, +39,137,220,218,20,248,168,127,171,72,220,85,229,254,36,178, +107,223,33,163,113,92,36,253,154,85,108,110,62,58,223,135, +195,55,251,220,57,36,48,74,195,160,138,235,173,9,193,3, +190,231,7,177,31,153,174,219,231,202,97,137,85,74,14,112, +28,39,73,220,86,213,248,39,142,173,196,17,149,114,3,210, +38,201,223,110,82,251,17,233,178,252,174,22,55,92,173,109, +128,221,216,54,220,174,85,7,222,238,81,195,150,234,132,155, +177,46,136,223,232,50,255,150,145,52,106,202,114,184,98,91, +115,131,209,30,78,220,88,53,228,41,86,49,185,241,105,124, +21,175,219,228,250,103,138,105,140,21,64,42,36,22,42,141, +134,114,37,178,104,239,39,160,77,154,63,205,172,86,51,152, +229,105,85,133,255,242,208,234,12,27,169,167,40,197,3,182, +103,23,185,191,137,228,91,119,194,201,24,31,192,63,124,188, +63,131,76,206,125,64,252,68,183,253,181,164,32,67,115,178, +193,127,127,8,121,128,245,88,100,244,142,7,101,95,60,123, +203,65,138,39,108,141,14,242,61,59,200,245,204,36,213,27, +23,70,79,120,26,87,69,251,62,25,238,211,226,138,107,173, +1,64,3,180,70,3,185,150,25,180,114,67,210,162,137,223, +235,2,249,149,173,242,113,250,68,187,61,173,168,208,91,28, +114,25,115,3,209,22,207,220,82,148,224,33,223,177,163,88, +205,100,214,175,81,69,246,238,3,227,55,184,236,187,103,12, +9,136,146,56,172,178,114,78,2,184,132,59,177,100,41,95, +160,187,250,220,58,20,54,73,255,102,145,219,155,10,158,245, +101,180,141,179,35,92,133,237,210,245,248,100,190,47,135,45, +214,57,49,96,97,214,164,225,83,253,114,213,178,135,30,231, +76,0,157,208,51,156,164,113,83,212,227,149,153,178,26,206, +212,208,164,236,131,231,127,49,232,225,206,45,65,73,22,246, +77,51,175,149,4,98,41,82,112,161,247,56,96,114,230,131, +242,47,26,253,229,165,149,17,50,2,71,116,202,79,104,27, +102,87,186,11,207,231,226,225,219,125,106,92,18,157,245,99, +212,129,181,91,208,178,141,190,243,70,136,9,136,147,40,174, +179,102,12,11,168,150,58,132,54,96,110,38,186,238,159,35, +6,37,92,136,61,200,248,28,62,216,255,77,32,159,178,23, +30,206,221,64,182,229,55,181,60,161,106,232,83,238,66,242, +161,251,249,104,124,23,143,223,230,210,227,152,73,168,23,42, +142,182,116,38,142,174,244,23,150,78,197,201,22,255,220,49, +164,32,66,99,176,192,107,61,1,105,146,244,109,54,189,191, +129,100,75,127,98,217,82,159,80,55,212,45,117,9,125,194, +221,88,54,212,47,85,13,127,234,89,74,22,240,45,63,169, +237,136,85,73,62,118,31,27,143,199,102,227,251,120,120,118, +151,155,151,78,198,249,16,252,224,247,191,16,116,96,239,54, +176,110,139,107,174,49,70,0,136,128,24,137,160,26,235,132, +152,129,40,139,227,46,41,207,160,146,107,156,17,33,50,96, +103,182,168,231,43,113,69,181,222,129,160,11,251,167,137,213, +75,22,243,29,57,170,209,78,78,121,8,117,64,237,84,148, +236,225,199,189,83,64,162,164,14,163,45,156,153,161,42,233, +199,172,67,99,179,240,109,62,61,175,137,196,91,53,226,73, +90,55,193,125,94,28,121,169,101,8,77,192,158,108,244,159, +23,70,78,104,24,86,81,185,55,9,252,210,215,216,34,156, +135,65,23,247,95,17,170,131,110,239,43,96,85,150,207,213, +195,150,235,148,153,176,58,202,214,248,32,254,163,195,125,91, +76,115,172,33,66,97,144,196,105,21,133,123,178,208,111,92, +25,45,227,104,72,87,228,235,118,185,122,217,98,159,51,7, +20,78,201,8,30,241,45,61,137,233,138,125,205,44,86,59, +25,229,99,244,129,247,123,80,240,165,191,177,100,40,79,162, +186,238,158,51,4,36,72,202,52,216,234,29,11,138,182,124, +166,158,166,84,7,220,206,85,193,190,110,150,187,149,44,226, +123,122,80,243,149,185,178,88,238,84,146,140,237,193,197,223, +119,194,200,8,29,193,43,62,181,47,145,77,251,47,9,205, +194,182,233,246,189,50,80,102,197,154,38,92,143,77,198,255, +112,240,230,143,51,39,20,12,233,136,92,217,44,127,171,73, +204,87,228,234,102,187,123,205,32,150,35,21,21,123,155,65, +47,119,44,41,202,240,152,110,216,91,13,98,58,98,87,178, +139,223,239,66,241,145,253,250,84,186,12,191,233,229,141,21, +67,26,34,21,22,75,157,66,19,177,55,25,252,243,199,152, +3,8,135,96,6,167,124,132,190,224,118,175,26,244,116,167, +158,164,116,3,222,230,209,211,158,74,148,209,49,190,128,119, +121,120,117,167,157,148,114,0,226,32,202,227,168,73,203,39, +234,237,10,117,69,189,94,145,168,171,235,237,9,69,67,190, +98,87,179,155,221,238,86,179,152,237,232,85,143,94,246,216, +99,140,1,0,3,48,6,3,60,198,27,48,54,3,95,246, +219,83,138,2,60,197,43,54,53,63,153,237,235,101,137,93, +202,30,120,188,55,3,92,198,221,80,182,196,39,245,29,53, +106,201,66,190,97,103,181,152,225,40,77,131,174,238,183,163, +84,13,124,218,95,73,42,54,54,15,159,238,215,163,146,109, +252,29,39,74,236,80,214,196,225,149,157,242,18,202,132,216, +129,172,203,227,171,121,205,36,214,43,17,69,115,190,1,103, +115,248,97,239,53,128,104,136,87,104,42,118,54,139,223,238, +82,243,144,233,184,93,170,30,190,220,183,196,36,197,27,54, +86,15,89,142,87,100,234,110,58,123,199,129,146,43,156,149, +97,50,229,55,180,44,163,107,252,17,231,82,224,160,206,171, +33,77,145,142,203,165,203,241,139,92,223,76,115,173,49,64, +96,132,134,96,5,151,122,135,130,38,109,159,44,247,43,81, +69,247,254,1,226,35,250,229,171,117,13,60,218,219,9,42, +179,102,13,27,170,151,46,198,63,112,124,39,143,188,214,18, +128,36,72,203,36,218,235,9,73,131,166,110,167,171,244,29, +54,90,207,65,130,167,124,133,174,226,119,187,88,253,100,181, +159,145,38,74,239,96,208,199,221,83,134,194,36,201,219,46, +90,255,65,225,151,188,230,18,227,20,136,168,152,219,136,58, +185,230,25,83,2,131,52,78,138,56,156,178,17,126,194,219, +56,58,210,87,217,58,31,134,95,244,250,71,138,43,172,149, +2,2,37,84,8,45,192,88,12,116,88,111,69,136,14,248, +157,47,194,125,88,124,117,175,29,132,122,160,242,106,74,115, +160,225,90,109,96,220,6,213,93,119,206,9,0,19,48,39, +19,124,231,143,48,23,18,15,213,78,71,233,26,124,244,191, +23,4,110,232,90,126,80,251,21,169,186,248,254,30,18,28, +229,105,84,149,253,243,196,168,5,11,187,166,29,151,74,135, +225,22,173,252,144,246,72,98,181,146,65,60,71,11,58,182, +23,23,94,207,73,2,183,116,37,190,168,247,43,80,85,245, +255,21,160,42,234,247,170,64,95,117,235,93,8,62,240,127, +31,8,191,224,117,159,28,247,72,97,133,148,66,0,129,16, +10,128,20,72,168,20,26,136,181,72,224,149,158,194,20,201, +184,30,154,156,253,224,244,143,22,119,92,41,45,128,88,136, +52,88,234,21,138,138,188,221,162,150,47,212,29,117,106,77, +2,190,228,55,183,28,165,104,192,215,252,98,214,163,145,93, +250,30,27,140,247,96,224,199,190,99,70,161,152,200,184,29, +170,154,254,220,50,148,38,65,95,118,219,91,11,2,54,100, +47,62,188,191,131,68,79,125,74,93,64,191,116,53,190,137, +231,107,113,193,245,222,4,240,9,127,227,201,88,31,68,127, +124,57,111,129,200,138,61,205,168,22,59,156,181,97,112,197, +183,246,4,162,41,222,177,161,120,201,102,254,43,67,101,210, +236,105,71,165,218,224,184,79,138,59,172,180,18,66,4,192, +8,12,209,8,47,225,76,12,93,200,63,108,188,30,147,12, +239,233,64,221,85,231,222,32,176,67,91,51,131,85,94,78, +89,8,55,96,109,22,188,237,163,229,29,21,106,139,98,62, +35,79,180,218,195,136,11,169,135,40,135,35,54,37,63,184, +253,171,68,29,93,235,15,40,159,162,23,63,222,157,97,34, +229,22,164,108,130,255,252,48,246,2,195,53,218,200,57,13, +160,26,234,148,154,128,60,201,234,62,59,206,149,192,34,173, +151,32,38,35,126,164,187,242,92,42,28,150,89,181,230,1, +211,51,155,212,127,84,184,45,171,233,204,29,69,106,46,50, +126,135,139,182,127,150,152,165,104,193,199,254,99,194,225,152, +77,232,31,46,222,190,81,102,198,170,32,95,179,139,221,207, +70,243,185,121,232,116,158,14,213,77,119,239,25,64,50,164, +39,50,109,183,172,165,3,113,23,149,127,211,200,43,45,133, +8,130,49,28,160,57,218,208,185,60,184,250,219,74,26,49, +37,49,88,225,165,156,129,32,11,243,38,137,223,234,18,251, +148,185,176,120,234,86,186,8,255,225,225,221,29,102,90,106, +17,194,3,184,135,11,183,103,21,153,187,139,204,223,101,226, +237,26,117,100,173,30,176,60,171,202,252,89,102,214,170,1, +79,243,170,73,207,103,226,233,90,125,96,253,22,149,124,227, +206,40,17,67,19,178,7,31,255,207,1,131,51,62,132,63, +240,124,47,14,188,220,179,132,44,193,75,62,115,79,17,138, +131,44,207,171,34,125,151,141,247,99,208,193,189,95,128,186, +168,254,187,66,92,65,173,86,48,168,227,106,105,67,228,194, +230,233,83,237,114,244,162,199,63,115,76,33,140,128,16,9, +176,18,75,148,210,1,184,131,75,191,99,69,145,158,203,132, +219,177,170,200,223,109,98,253,18,213,116,231,158,32,52,3, +91,182,211,87,218,10,25,133,99,50,225,119,188,40,243,99, +217,81,175,86,52,232,235,110,57,75,193,130,174,237,135,165, +87,49,186,193,111,127,41,105,192,212,204,100,213,159,87,70, +202,40,24,211,1,187,179,77,188,95,131,138,174,253,135,132, +71,113,155,85,111,94,56,57,227,65,216,7,205,223,102,210, +235,25,73,162,182,46,134,63,244,60,39,10,236,212,150,196, +100,197,159,118,86,138,9,140,211,32,170,227,110,41,75,224, +146,238,204,19,165,118,32,234,226,250,107,74,113,128,229,88, +69,228,206,38,241,95,29,106,155,98,31,51,15,149,78,195, +169,26,249,164,189,147,64,46,101,14,44,220,154,21,108,234, +126,58,90,215,193,179,191,156,180,112,98,198,162,160,79,187, +43,205,133,198,99,177,209,121,62,20,63,217,237,111,37,137, +216,154,28,252,248,119,142,8,148,81,49,182,1,119,115,217, +113,175,20,20,104,169,70,56,9,227,34,232,199,174,99,103, +177,216,233,44,29,139,139,174,255,167,128,69,89,31,71,79, +122,58,83,71,211,186,11,206,247,224,224,207,63,99,76,0, +156,192,49,157,176,51,90,196,241,148,172,224,83,255,82,209, +176,175,154,245,108,36,159,186,151,14,198,125,80,252,101,167, +189,148,48,32,98,98,226,226,234,107,107,97,192,196,204,69, +197,223,118,210,202,9,9,131,34,46,167,46,164,31,178,30, +143,204,214,245,240,228,174,39,39,61,156,185,161,104,201,71, +238,107,98,241,210,205,120,23,134,79,244,219,87,202,10,56, +149,35,19,117,119,157,57,163,64,76,69,204,78,116,217,127, +79,8,26,176,53,59,216,245,237,52,149,58,131,70,110,105, +74,116,208,239,93,1,174,226,118,171,90,252,112,247,150,129, +52,75,218,50,153,246,91,82,146,129,61,219,200,59,45,164, +24,194,16,136,160,24,203,128,154,169,172,153,195,10,43,165, +4,0,9,144,18,9,180,82,67,144,130,9,157,195,3,187, +183,13,180,91,211,130,139,189,207,128,147,57,190,144,119,88, +104,53,134,9,148,83,17,178,3,95,247,203,81,139,22,126, +204,59,36,52,10,203,164,218,227,136,73,137,7,106,175,34, +116,7,159,254,215,130,130,45,221,137,39,107,253,0,245,81, +245,246,133,178,35,94,165,233,208,221,124,118,158,11,133,71, +114,171,83,108,98,254,34,211,119,219,88,59,4,53,88,233, +37,140,137,128,27,185,166,25,215,66,131,177,30,136,188,216, +242,156,42,144,87,89,58,23,7,95,254,91,67,130,162,44, +143,171,166,61,151,8,167,97,84,133,253,210,212,232,36,159, +187,135,12,199,105,18,245,117,181,188,161,98,105,83,228,227, +246,169,114,121,114,213,179,151,28,230,88,66,148,192,33,157, +145,35,26,229,101,148,141,241,3,220,199,197,211,183,218,196, +248,5,174,235,230,185,83,72,34,180,6,3,61,214,25,49, +34,65,86,230,201,82,191,80,117,244,173,55,33,124,128,255, +248,112,254,6,147,61,255,136,113,9,116,82,207,81,130,134, +108,197,143,118,119,154,73,173,71,32,139,242,62,10,222,244, +241,246,140,34,49,87,17,187,147,77,254,127,3,200,134,252, +197,166,231,55,177,124,169,110,184,91,203,2,186,165,47,177, +77,185,15,137,143,234,183,171,212,29,116,122,79,3,170,166, +62,167,14,164,93,146,158,205,228,215,183,210,68,232,13,14, +251,172,57,195,64,138,37,76,137,12,218,185,41,232,209,206, +78,113,137,117,74,76,80,156,101,97,221,20,247,88,97,164, +132,2,33,21,16,43,145,68,107,61,0,121,144,245,121,116, +180,175,147,101,126,45,43,232,212,158,68,116,205,63,102,28, +10,153,132,123,177,224,105,95,37,235,248,88,126,84,187,29, +173,234,240,219,94,90,24,49,33,113,80,229,245,148,164,96, +67,247,242,193,250,47,10,253,196,181,213,48,166,2,102,101, +154,108,253,15,5,79,250,58,91,198,211,176,170,202,255,105, +96,213,150,199,84,195,156,74,144,145,57,186,208,127,92,56, +61,163,73,220,87,197,250,38,154,239,205,1,135,115,54,128, +111,248,89,111,70,184,8,251,161,233,217,77,110,127,42,89, +198,215,240,162,206,175,97,69,149,222,195,128,139,185,143,136, +151,105,182,181,55,16,108,225,206,44,81,75,23,226,15,58, +191,135,5,87,123,27,65,39,246,44,35,107,244,144,231,88, +65,164,198,34,161,87,56,42,211,102,203,123,42,80,86,197, +249,22,156,236,241,199,156,67,0,131,48,14,130,60,204,186, +52,62,138,223,236,114,247,146,193,60,79,138,58,188,182,19, +86,70,201,24,30,208,61,125,168,125,138,92,220,124,117,174, +13,134,123,180,176,99,90,97,161,212,8,36,81,90,7,193, +30,110,220,26,21,100,107,126,48,251,211,201,58,63,134,29, +212,122,5,162,42,238,183,162,68,15,125,206,29,64,58,36, +55,58,205,167,230,37,147,121,191,4,53,89,249,39,141,157, +194,18,169,180,24,226,16,202,128,152,137,168,155,235,142,57, +133,32,2,99,52,128,107,184,81,107,22,176,45,187,233,237, +13,5,75,186,50,95,150,219,149,234,130,251,189,40,240,83, +223,82,147,144,47,216,221,109,102,189,26,209,36,239,187,96, +124,7,143,254,246,146,194,12,73,137,6,122,173,35,96,69, +150,238,197,131,183,127,148,184,161,106,233,67,236,67,230,227, +242,233,122,125,34,221,150,215,84,226,140,10,177,5,57,155, +193,47,127,173,41,192,81,156,102,81,219,23,203,158,122,148, +178,1,126,227,203,120,27,70,87,248,43,79,165,202,224,153, +95,202,26,56,180,51,83,84,227,157,24,178,16,111,208,216, +45,108,153,78,219,41,43,225,68,140,77,192,159,124,246,158, +3,4,71,120,10,87,100,235,126,56,122,211,195,155,59,142, +148,84,96,172,6,50,45,183,40,229,3,244,71,151,251,151, +136,166,121,215,132,227,49,217,240,191,30,148,124,225,238,44, +19,107,151,160,39,59,253,165,165,17,81,50,135,23,118,78, +11,40,150,50,5,54,106,207,34,178,103,31,57,175,129,68, +75,61,66,89,16,183,81,117,246,141,51,35,84,4,237,216, +84,252,108,55,175,157,132,114,33,242,96,235,119,168,104,218, +119,201,120,30,22,93,253,111,5,137,154,186,156,190,208,118, +204,42,52,23,27,159,199,71,243,187,89,236,118,182,138,199, +109,83,237,115,228,160,198,43,49,69,49,158,129,37,91,249, +35,205,149,198,66,161,145,88,170,20,30,200,189,76,176,157, +187,130,92,205,108,86,191,89,229,230,164,131,115,63,16,125, +241,237,61,5,40,138,242,60,42,218,246,217,114,158,2,21, +85,123,31,1,47,242,124,43,78,180,216,227,140,9,129,3, +58,167,7,52,79,155,42,159,167,71,53,219,217,43,14,181, +76,161,141,152,147,8,174,241,70,140,73,128,151,120,166,150, +38,68,15,124,222,31,65,46,102,62,42,223,166,211,119,218, +72,57,5,33,26,224,53,158,136,181,73,240,151,159,214,86, +192,168,12,155,169,175,169,197,9,23,99,31,48,63,147,77, +255,111,1,201,146,190,204,182,245,54,132,46,224,95,62,90, +223,65,163,183,60,164,58,226,86,170,8,222,241,161,252,137, +102,123,123,65,225,150,172,228,19,247,86,129,184,138,218,189, +104,240,215,159,82,22,192,45,92,153,45,235,233,72,93,69, +239,126,48,250,195,203,59,43,196,20,196,104,4,151,120,167, +134,36,69,27,62,215,15,83,47,83,108,99,238,32,210,99, +153,81,43,22,52,109,187,108,189,15,129,15,250,191,11,196, +87,244,234,71,171,59,236,180,150,2,4,69,88,14,85,76, +111,108,24,94,209,169,63,169,236,152,87,72,42,52,22,11, +157,198,83,177,178,73,254,119,131,216,142,92,213,236,103,167, +185,212,56,36,50,106,199,162,162,111,191,41,229,1,212,67, +149,211,19,154,134,93,213,238,71,163,187,252,188,54,18,78, +197,200,6,253,221,37,230,41,82,113,177,245,57,116,48,239, +147,224,46,47,175,172,148,19,16,38,65,94,102,217,90,31, +64,63,116,61,63,137,237,202,117,201,124,94,30,89,173,103, +32,201,210,190,72,246,245,179,212,44,100,27,126,215,139,19, +47,214,60,97,106,100,146,238,205,3,167,119,52,168,235,234, +121,75,68,210,172,105,195,229,218,101,232,77,14,127,236,57, +70,16,136,161,8,201,129,142,235,165,137,209,11,30,247,77, +49,143,145,6,74,173,64,80,133,245,82,196,224,132,143,241, +7,156,207,193,131,191,255,132,176,1,122,163,195,124,75,78, +114,184,99,75,113,130,197,92,71,204,74,52,209,123,31,0, +63,240,125,63,12,189,200,241,141,60,211,74,11,33,6,32, +12,130,56,140,178,48,110,130,250,172,58,243,70,137,25,138, +146,60,236,186,118,30,10,157,196,115,181,176,97,122,101,163, +252,140,54,113,126,5,171,186,252,190,22,22,76,237,76,20, +221,249,39,140,141,192,19,189,246,17,242,2,203,181,202,192, +153,29,234,154,122,156,50,17,118,67,219,50,155,214,95,80, +186,5,47,251,236,57,71,0,138,160,28,139,136,158,249,164, +188,131,66,47,113,76,37,204,136,20,89,184,55,11,220,214, +213,240,166,142,167,101,21,157,251,131,200,143,109,199,173,82, +113,176,229,59,117,36,173,154,240,60,46,154,254,221,34,150, +39,85,29,127,203,73,10,55,100,45,30,184,189,171,192,93, +93,110,95,42,27,230,87,178,138,207,237,67,229,211,244,234, +70,187,57,237,160,212,11,20,87,89,59,7,5,94,234,25, +74,146,176,45,186,249,239,12,17,9,179,34,77,151,238,199, +163,179,125,188,60,179,74,205,65,134,231,116,129,254,234,82, +251,16,249,176,253,186,84,62,76,191,108,181,143,145,7,90, +175,65,68,199,252,66,214,225,177,221,184,54,26,206,213,192, +166,237,151,165,118,33,250,224,251,127,8,120,144,247,89,112, +182,135,23,119,94,9,41,130,112,12,38,120,206,23,224,46, +46,191,174,149,7,82,47,81,76,103,236,8,86,113,185,117, +41,124,144,255,217,96,190,39,7,61,222,153,33,42,225,70, +172,73,194,183,248,228,190,39,6,45,220,152,53,104,232,86, +190,72,247,229,177,213,56,38,18,110,197,138,38,125,159,13, +231,107,112,209,247,223,16,178,0,111,241,200,109,77,13,78, +250,56,123,194,209,152,46,216,223,77,98,191,50,85,54,207, +159,98,22,163,29,156,250,145,234,138,123,173,32,80,67,149, +210,3,152,135,73,151,231,87,177,186,201,238,127,35,200,196, +220,69,228,207,54,243,94,9,40,146,114,13,50,58,199,7, +242,47,27,237,231,164,129,83,59,18,85,117,255,29,33,42, +224,86,174,72,214,245,241,244,172,38,51,127,149,169,179,105, +252,21,167,90,228,240,198,142,97,5,149,90,131,128,14,233, +141,12,211,41,59,225,101,156,13,225,11,124,215,143,83,39, +210,108,105,79,36,218,234,25,75,130,178,44,174,187,230,28, +3,8,134,112,4,166,104,198,183,240,100,174,47,166,61,150, +24,165,96,64,199,244,194,198,233,17,205,242,182,138,198,125, +81,236,103,166,169,214,57,48,112,99,215,176,163,90,237,96, +212,135,213,87,214,202,1,137,147,42,142,183,100,36,143,186, +182,30,134,92,196,252,68,182,237,183,165,52,1,122,162,211, +126,74,90,48,177,115,89,112,183,151,21,118,74,75,32,146, +98,13,19,42,135,38,102,47,58,252,183,135,20,71,88,10, +21,68,107,60,16,123,145,225,59,125,164,189,146,80,44,100, +26,110,213,138,7,109,223,44,115,107,81,192,167,252,133,166, +99,119,177,249,249,108,60,31,139,143,238,247,163,208,77,124, +95,15,75,174,114,118,130,203,188,91,194,146,168,172,155,227, +14,41,141,128,18,41,180,16,99,16,192,33,156,129,33,27, +241,39,157,157,227,2,233,149,140,226,49,219,208,187,28,188, +248,243,206,8,17,1,51,50,69,55,254,141,35,35,117,20, +173,249,192,252,77,38,255,190,17,102,66,234,32,218,227,137, +89,139,6,126,237,43,100,21,158,203,133,203,179,171,220,157, +100,114,239,19,224,38,174,175,166,53,23,24,175,193,68,207, +125,66,220,64,181,213,49,182,0,103,113,216,101,237,29,4, +122,168,115,106,64,210,164,233,211,237,122,117,162,205,158,119, +68,168,12,154,185,173,168,209,75,30,115,13,49,10,193,4, +206,233,0,221,209,167,222,165,224,65,223,119,195,216,10,28, +213,105,55,165,61,144,120,169,102,56,75,195,162,170,239,175, +33,69,17,158,195,5,219,187,11,204,215,228,226,231,187,113, +108,36,158,170,149,15,210,63,89,236,119,166,136,198,121,17, +228,99,246,161,243,121,120,116,183,159,149,102,66,235,48,216, +226,157,27,130,22,108,236,30,54,92,175,77,132,223,240,178, +206,142,113,5,180,74,195,161,154,233,172,29,131,10,174,245, +6,132,77,208,159,93,230,222,34,144,71,89,27,7,71,126, +106,91,98,147,242,15,26,191,197,37,215,57,51,64,101,212, +140,101,65,221,86,215,216,35,140,133,64,3,181,86,1,184, +130,91,189,98,81,211,151,219,150,218,132,248,129,238,235,99, +233,81,204,102,244,139,87,111,90,120,49,231,17,208,34,141, +151,98,6,163,60,140,186,176,126,138,90,188,112,115,214,129, +177,27,216,182,221,182,214,6,192,13,92,219,13,107,171,96, +92,7,205,222,118,208,234,13,11,171,166,60,135,10,166,117, +22,140,237,192,213,221,118,214,138,1,13,211,42,11,231,102, +160,203,250,59,74,212,208,165,252,129,230,107,115,225,241,220, +44,116,27,95,199,203,50,187,214,29,112,58,71,7,250,174, +27,231,70,160,137,218,187,8,252,209,231,222,33,160,65,90, +39,193,92,78,92,88,61,101,41,92,144,189,249,224,252,15, +6,127,252,57,103,0,200,128,156,201,160,159,187,134,28,197, +104,6,183,124,165,174,160,87,59,26,213,101,247,189,49,96, +96,198,166,224,71,191,123,197,160,134,43,181,5,49,27,209, +39,223,189,99,64,193,148,206,192,145,157,250,146,218,140,120, +145,230,75,115,163,209,92,110,92,26,29,229,107,116,145,255, +219,64,186,37,47,185,204,185,5,40,139,226,62,43,206,180, +208,98,140,3,32,7,50,46,135,46,230,63,50,92,167,205, +148,215,80,162,132,14,225,13,28,219,137,43,171,229,12,5, +73,154,54,93,190,95,135,202,166,249,215,140,98,49,211,81, +187,22,29,252,251,71,136,11,168,151,42,134,55,116,44,47, +170,252,158,22,84,108,109,14,60,220,187,5,44,203,234,58, +123,198,145,144,42,136,215,104,34,247,54,129,126,234,90,122, +16,243,17,249,178,221,190,86,22,200,173,76,145,141,251,163, +200,205,77,71,239,122,112,242,199,155,51,14,132,92,192,188, +76,178,189,191,128,116,73,126,118,155,91,143,66,54,225,127, +60,56,251,195,201,27,47,198,60,64,122,36,179,122,205,34, +182,39,23,61,255,137,97,11,117,70,141,88,146,148,109,240, +221,63,70,28,72,185,4,57,153,225,43,125,133,173,210,113, +184,100,59,127,133,169,146,121,188,52,51,90,197,225,150,173, +244,17,246,66,195,177,154,200,188,93,162,158,174,212,23,212, +110,69,139,62,254,158,19,4,102,104,74,118,240,235,95,41, +42,240,86,143,88,150,212,101,244,141,55,99,92,0,189,208, +113,188,36,51,123,213,161,183,57,244,48,231,18,224,36,142, +171,164,29,147,10,143,229,70,165,217,208,190,76,182,253,183, +132,36,65,91,54,211,95,91,10,19,36,103,58,104,247,166, +129,87,123,26,81,37,247,56,97,98,228,130,230,109,19,237, +247,164,160,67,123,51,193,117,222,12,113,9,117,66,205,80, +150,196,101,213,157,119,66,200,0,156,193,33,159,177,39,24, +205,225,134,173,213,1,182,99,87,177,187,217,236,126,55,138, +205,204,87,229,250,100,186,111,143,41,134,49,20,32,41,210, +112,169,118,56,106,211,226,139,123,175,0,84,65,189,86,17, +184,163,75,253,67,197,211,182,202,198,249,17,236,226,246,171, +82,125,112,253,55,133,60,194,90,40,48,82,67,145,146,11, +156,215,65,178,167,31,181,110,129,203,186,59,206,148,208,32, +172,131,98,47,51,108,165,142,160,21,27,154,151,77,246,255, +19,192,38,236,143,38,119,63,25,237,227,228,137,87,107,26, +112,53,183,25,245,98,197,147,182,78,134,249,148,188,224,114, +239,18,240,36,175,187,228,60,7,10,174,244,22,134,76,196, +221,84,246,204,35,165,21,16,42,129,70,106,41,66,112,128, +231,120,65,230,230,162,227,127,57,104,241,198,141,81,3,150, +102,69,155,62,223,142,83,37,242,104,107,103,160,200,202,61, +73,232,22,190,204,183,229,52,133,58,162,86,46,72,222,116, +241,254,13,34,59,246,21,179,26,205,228,214,167,208,69,252, +79,7,235,190,56,246,18,195,20,202,136,24,153,160,59,251, +196,185,21,40,170,242,126,10,90,180,241,115,220,32,181,19, +81,54,199,31,114,30,3,13,214,122,1,226,34,234,231,170, +97,79,53,202,201,8,31,225,47,60,157,171,131,109,223,45, +99,105,80,212,229,245,149,180,98,66,227,176,200,234,61,11, +200,150,252,228,182,167,22,37,124,136,127,232,120,94,22,217, +189,111,128,217,152,62,216,254,93,34,158,166,85,23,222,207, +65,131,183,126,132,186,160,126,171,74,252,81,231,214,160,160, +75,251,35,201,213,206,70,241,153,125,234,92,26,28,245,105, +117,133,189,210,80,168,36,26,235,133,136,131,41,159,161,39, +57,221,161,167,57,213,32,167,51,116,36,175,186,244,62,6, +30,236,253,6,148,77,241,143,29,199,74,34,177,86,9,56, +146,83,29,114,27,83,7,211,62,75,206,114,176,226,75,123, +35,193,84,206,76,80,157,117,99,220,0,181,81,113,182,133, +55,115,92,33,173,144,80,40,36,18,106,133,130,34,45,151, +40,167,35,116,5,191,250,213,170,6,63,253,173,37,1,89, +146,151,93,246,222,3,128,7,120,143,7,102,111,58,120,247, +135,145,23,90,142,81,4,230,104,66,247,240,225,254,45,34, +121,214,149,241,50,204,166,244,7,150,111,213,137,55,107,220, +16,181,112,97,246,164,163,115,125,48,253,179,197,60,71,10, +42,180,22,3,28,198,89,16,182,65,119,247,153,113,42,68, +22,236,237,6,181,93,177,174,137,199,107,51,225,117,156,44, +241,75,93,67,143,114,54,130,79,252,91,71,194,170,40,223, +163,131,125,223,12,115,41,113,64,229,212,132,228,65,215,247, +211,208,170,12,159,233,167,173,149,1,50,35,87,52,235,219, +104,58,119,7,153,158,219,132,250,161,234,233,75,109,67,236, +66,246,225,243,253,56,116,50,207,151,226,6,171,189,140,176, +17,122,130,211,60,106,218,114,153,114,27,82,23,209,63,95, +140,123,160,240,74,78,113,136,101,72,77,68,222,108,113,207, +21,194,10,40,149,2,3,53,86,9,57,130,81,28,102,89, +90,23,193,63,126,156,59,129,100,74,111,96,216,70,221,89, +39,198,44,64,91,52,243,91,89,34,151,54,71,30,106,157, +2,19,53,119,25,121,163,197,28,71,72,10,52,84,43,29, +132,123,176,240,107,94,49,169,241,72,108,85,142,79,228,219, +118,218,74,25,1,35,50,100,39,190,172,183,35,84,5,253, +218,85,232,46,62,191,143,133,71,115,187,81,109,118,188,43, +195,101,218,109,105,77,4,222,232,49,207,144,146,8,172,209, +66,142,97,4,133,88,130,148,76,224,157,30,210,28,105,168, +84,26,12,245,72,101,197,156,70,80,137,53,74,200,16,156, +224,49,223,144,179,24,236,240,214,142,64,21,213,123,23,128, +47,248,221,47,70,61,88,249,37,173,153,192,58,45,166,56, +198,18,160,36,10,235,164,152,195,8,11,161,6,40,141,130, +50,45,182,56,231,2,224,5,158,235,133,137,147,43,158,181, +101,48,205,179,166,12,135,105,150,181,117,48,236,163,230,45, +19,105,183,164,37,19,121,183,133,53,83,88,35,133,20,66, +8,0,16,0,33,16,64,33,148,0,33,17,80,35,149,20, +99,24,64,49,148,33,49,81,113,183,149,53,114,72,99,164, +128,66,41,17,64,35,180,4,35,57,212,49,181,48,97,114, +228,163,246,45,50,121,247,133,177,19,88,166,213,22,198,76, +64,157,84,115,156,33,33,81,80,167,213,20,230,72,66,181, +208,97,188,5,35,59,244,53,183,24,229,96,196,135,244,71, +150,235,149,137,178,59,222,148,241,48,236,162,246,47,18,125, +245,173,53,1,120,130,215,124,98,222,34,145,87,91,26,19, +5,119,122,73,99,166,160,70,43,57,196,49,148,32,33,83, +112,163,215,60,98,90,98,145,210,11,24,151,65,55,247,29, +49,42,193,70,238,105,66,245,208,229,252,5,166,107,246,177, +243,88,104,52,150,11,149,71,83,187,19,77,246,254,3,194, +39,248,205,47,103,45,24,216,177,173,184,209,106,14,51,44, +165,10,224,21,158,202,149,201,178,191,158,148,116,96,238,38, +178,111,159,41,167,33,84,1,189,210,81,184,38,27,255,199, +129,147,59,158,148,117,112,236,39,166,45,150,57,181,32,97, +83,244,227,215,185,50,88,230,213,146,134,76,197,205,86,247, +216,97,172,5,2,43,180,20,35,24,196,113,148,164,97,83, +245,243,213,184,38,26,239,197,128,135,121,151,132,103,113,217, +117,239,28,16,56,161,99,120,65,231,246,160,226,107,123,97, +225,212,140,100,81,223,87,195,154,42,156,151,65,54,231,31, +48,62,131,79,254,123,67,192,130,172,205,131,167,127,181,168, +225,75,125,67,205,82,182,192,103,253,25,101,98,236,2,246, +101,179,253,189,36,48,75,211,162,139,255,239,0,209,17,191, +210,85,248,46,31,175,207,164,211,115,154,64,61,85,41,63, +160,125,154,92,253,108,53,143,153,134,90,165,224,64,207,117, +194,204,72,21,197,123,54,144,111,217,73,47,103,44,8,218, +176,185,250,216,122,28,50,25,247,67,209,147,159,222,214,208, +160,172,139,227,47,57,205,161,134,41,149,1,51,51,85,53, +255,153,97,42,101,6,172,204,146,181,124,160,254,170,82,127, +80,249,53,173,184,208,122,12,50,56,231,3,240,7,159,255, +199,128,131,57,159,128,55,121,252,53,167,24,196,112,132,166, +96,71,183,250,197,170,39,47,189,140,177,1,120,131,199,126, +99,202,96,152,71,73,27,38,87,62,75,207,98,178,227,95, +57,42,209,70,207,121,2,212,68,229,221,20,246,72,99,165, +144,64,40,5,2,42,164,22,34,12,134,120,132,182,96,102, +167,186,228,62,39,14,172,220,146,148,108,224,223,62,82,94, +65,169,22,56,172,179,98,76,3,172,198,50,161,118,40,106, +242,242,203,90,59,0,117,80,237,117,132,172,192,83,189,114, +81,242,135,155,183,78,132,217,144,190,200,246,253,50,212,38, +197,31,118,94,11,9,134,114,36,162,106,238,51,226,68,138, +45,204,153,4,122,169,99,104,65,198,230,224,195,255,123,64, +240,132,175,241,69,188,79,131,171,190,189,166,16,71,80,138, +5,76,203,44,90,251,1,233,147,236,238,55,163,92,140,124, +208,254,77,34,191,182,21,54,74,207,96,146,231,93,17,174, +195,102,235,123,104,112,214,135,209,23,222,206,81,129,182,106, +198,179,176,108,170,127,174,24,214,80,161,180,8,226,49,218, +192,185,29,168,186,250,222,26,16,52,97,123,116,177,255,153, +96,58,103,7,184,142,155,165,110,161,203,248,27,78,214,248, +33,238,161,194,105,25,69,99,190,32,119,51,217,245,239,20, +145,56,171,194,124,73,110,118,186,75,207,99,162,225,94,45, +104,216,86,221,120,55,134,13,212,91,21,226,11,122,183,131, +85,95,94,91,9,35,34,100,6,174,236,150,183,84,36,236, +138,118,125,58,93,167,207,180,211,82,138,0,28,193,41,30, +177,45,185,201,233,15,45,207,168,18,123,148,177,49,120,224, +247,190,0,118,97,251,116,185,126,153,106,155,99,15,49,14, +129,12,202,185,8,248,145,239,218,113,168,100,26,111,197,136, +6,121,157,37,99,121,80,245,245,181,180,32,98,99,242,224, +235,127,41,104,208,214,205,112,151,150,71,84,203,29,74,154, +48,61,178,89,255,70,145,153,187,138,220,221,100,246,175,19, +101,118,172,43,226,117,154,76,253,77,37,207,184,18,90,132, +241,16,236,224,214,175,80,85,244,239,23,161,62,168,254,186, +82,94,64,185,20,57,184,241,107,92,17,173,243,96,232,71, +174,107,230,177,210,72,40,21,2,11,180,86,3,152,134,89, +149,230,67,243,179,217,252,126,22,154,141,237,195,229,219,117, +234,76,26,61,229,41,84,17,189,243,65,248,7,143,255,230, +144,195,24,11,128,22,104,172,22,50,12,167,104,196,151,244, +102,134,171,180,29,178,26,207,196,210,165,248,193,238,111,35, +233,212,156,100,112,207,23,226,14,42,189,134,17,21,114,11, +83,38,195,126,106,90,114,145,243,27,88,182,213,55,214,12, +97,9,84,82,141,113,2,196,68,196,205,84,215,220,99,132, +129,16,11,144,22,73,188,86,19,152,167,73,213,199,215,243, +146,200,172,93,131,142,238,245,131,212,79,84,219,29,107,138, +112,28,38,89,222,87,193,186,46,158,191,197,36,199,59,50, +84,39,221,156,119,64,232,4,158,233,165,141,145,3,26,167, +69,20,207,217,2,158,229,101,149,157,243,2,200,133,204,195, +165,219,241,170,76,159,109,231,173,16,81,48,167,19,116,102, +143,58,182,22,7,92,206,93,64,190,100,55,191,157,165,98, +97,211,244,235,86,185,56,249,226,221,27,6,86,108,105,78, +52,216,235,13,9,139,162,62,175,142,180,85,50,142,135,100, +71,191,122,213,162,135,63,247,12,33,9,208,18,141,244,82, +198,192,128,141,217,131,142,239,229,129,213,91,22,210,13,121, +139,69,78,111,104,88,86,213,249,55,140,172,208,83,156,98, +17,211,19,155,150,95,212,250,5,170,171,238,189,3,64,7, +244,78,7,233,158,60,244,58,71,6,234,172,26,243,4,169, +153,200,186,61,174,152,214,88,32,180,2,67,53,210,73,57, +7,1,30,226,29,26,154,149,109,242,253,59,68,52,204,171, +36,29,155,139,143,239,231,161,209,89,62,86,31,89,175,71, +36,203,250,58,90,214,209,177,190,136,246,121,114,212,163,149, +29,242,26,75,132,210,32,168,195,106,43,99,100,128,206,232, +17,207,210,178,136,238,249,67,204,67,164,195,114,171,82,124, +96,255,54,145,126,203,74,58,49,103,17,216,163,141,157,195, +2,171,181,12,160,25,218,146,153,188,250,210,218,8,56,145, +99,27,113,39,149,28,227,8,72,145,132,107,177,193,121,31, +4,127,248,121,111,4,152,136,185,137,232,155,111,206,57,0, +112,0,231,112,192,230,236,3,231,119,176,232,235,111,41,73, +192,150,236,228,151,183,86,4,232,136,94,249,40,125,131,205, +222,119,192,232,12,31,233,175,44,149,11,147,39,95,189,107, +193,193,158,111,196,153,20,122,136,115,40,96,82,230,193,210, +175,88,213,228,231,183,177,116,40,110,178,250,207,10,51,37, +53,24,233,161,204,137,5,75,187,34,93,151,207,215,227,146, +233,188,29,162,26,238,212,146,132,108,193,207,126,115,202,65, +136,7,104,143,38,118,47,27,236,247,166,128,71,121,27,69, +103,254,40,115,99,209,208,175,92,149,236,227,231,185,81,104, +38,182,46,135,47,246,61,51,72,229,196,132,197,81,151,214, +71,208,139,29,207,202,50,185,246,25,114,18,195,21,218,138, +25,141,226,50,235,214,184,32,122,227,195,248,11,78,247,232, +97,207,53,194,72,8,21,64,43,52,20,43,153,196,123,53, +160,105,218,117,233,124,28,62,217,239,79,33,139,240,30,14, +220,220,117,228,172,6,51,61,181,41,241,65,253,87,133,250, +162,218,239,72,81,133,247,114,192,226,172,11,227,39,184,205, +171,39,45,157,136,179,41,252,145,231,90,97,160,196,10,37, +69,24,14,209,12,111,233,72,92,85,237,127,36,184,202,219, +41,42,241,70,141,89,130,150,108,228,159,54,86,14,73,140, +86,112,168,103,42,105,198,180,192,98,173,19,96,38,166,46, +166,63,182,28,167,72,196,213,212,230,196,131,181,95,144,186, +137,238,251,99,200,65,140,71,96,139,118,126,10,91,164,243, +114,200,98,188,3,67,55,242,77,59,47,133,12,194,57,24, +240,49,255,144,241,56,108,178,254,143,2,55,117,61,61,169, +233,200,93,77,110,126,58,91,199,195,178,171,222,189,96,112, +199,151,242,6,138,173,204,145,133,122,163,194,108,73,79,102, +250,106,91,99,131,240,14,14,253,204,53,197,56,6,18,44, +229,10,100,85,158,79,197,203,54,251,222,25,32,50,98,71, +178,170,207,175,99,101,145,220,235,4,153,153,171,138,253,205, +36,215,59,19,68,103,252,8,119,97,249,84,189,124,177,238, +137,67,43,51,100,37,158,168,181,11,208,23,221,254,87,130, +138,172,221,131,134,111,245,137,117,75,92,82,157,113,35,212, +4,229,89,84,246,205,51,167,20,4,104,136,86,120,40,119, +34,201,214,254,64,242,165,187,241,108,44,31,170,159,174,214, +55,208,108,109,15,44,222,186,17,110,194,250,40,122,243,195, +217,27,14,214,124,97,238,36,146,107,157,1,35,51,116,37, +191,184,245,42,68,23,252,239,7,161,31,184,190,155,198,94, +97,168,68,26,45,229,8,68,81,156,103,65,217,22,223,220, +115,132,160,0,75,177,130,73,157,71,67,187,50,93,182,223, +151,194,6,233,157,12,242,57,123,192,241,156,44,240,91,95, +66,155,48,63,146,93,253,110,21,139,155,174,222,183,192,100, +205,31,102,94,42,25,198,83,176,162,75,255,99,193,209,158, +78,212,217,53,238,136,82,57,48,113,115,213,177,183,24,228, +112,198,134,224,5,159,251,135,136,135,105,151,165,119,49,248, +225,239,61,1,104,130,246,108,34,255,182,145,118,74,74,48, +144,99,25,81,35,151,52,103,26,104,181,134,1,21,83,27, +19,7,87,126,75,75,34,178,102,15,59,174,149,6,66,45, +80,88,37,229,24,68,112,140,39,96,77,22,254,205,35,167, +53,20,40,169,194,120,9,102,114,234,67,234,35,234,229,138, +101,77,29,78,219,40,59,227,69,152,15,201,143,110,247,171, +81,77,118,254,11,67,39,242,108,43,111,164,152,194,24,9, +160,18,106,132,146,32,44,131,106,174,51,102,4,138,168,156, +155,128,62,233,238,60,19,74,135,224,6,175,253,132,180,65, +114,167,147,116,110,14,58,188,183,3,84,71,221,90,23,192, +47,124,157,47,195,109,90,125,97,237,20,148,104,161,199,56, +3,66,38,224,78,46,121,206,21,192,42,44,151,42,135,39, +118,45,59,232,245,142,4,85,89,63,71,13,90,186,17,111, +210,248,41,110,177,202,201,9,15,227,46,40,223,162,147,127, +222,24,49,32,97,82,228,225,214,173,112,81,246,199,147,179, +30,140,252,208,246,204,34,181,23,17,62,195,79,122,59,67, +69,210,174,73,199,231,242,225,250,109,42,125,134,157,212,114, +132,162,32,79,179,170,205,143,103,103,185,88,249,36,189,155, +193,46,111,175,40,212,19,149,118,67,218,34,153,215,75,18, +179,21,61,250,217,107,14,49,12,161,8,200,145,140,234,177, +203,216,27,12,246,120,99,198,160,128,75,185,3,73,151,230, +71,179,187,221,172,118,51,218,197,233,23,173,254,176,242,74, +74,49,128,97,24,69,97,158,36,117,27,93,231,207,48,147, +82,15,80,30,69,109,94,60,121,235,69,136,15,232,159,46, +214,63,81,108,103,174,40,214,51,145,116,107,94,48,185,243, +73,120,23,135,95,246,218,67,136,3,40,135,34,38,39,62, +172,191,162,84,15,92,222,93,97,174,36,22,43,157,132,115, +49,240,97,255,53,161,120,200,118,252,42,87,39,219,252,123, +70,144,136,169,137,201,139,47,239,173,0,81,17,183,83,85, +242,143,27,167,70,36,201,218,62,88,254,85,163,158,172,244, +19,214,70,193,153,30,218,156,121,160,244,10,70,117,216,109, +109,13,12,218,184,57,234,208,218,12,120,153,103,75,121,2, +213,84,231,220,0,180,65,115,183,145,117,122,76,51,172,165, +2,97,21,148,107,145,193,59,63,132,61,208,120,45,38,56, +206,147,160,46,171,239,172,17,67,18,162,5,30,235,141,8, +147,33,63,177,109,185,77,169,15,168,159,170,150,63,212,60, +101,42,108,150,190,197,38,231,63,48,124,163,207,188,83,66, +130,160,12,139,169,142,185,133,40,131,99,62,33,111,176,216, +235,12,25,137,163,42,237,135,164,71,51,187,213,45,118,57, +123,193,225,158,45,228,25,86,82,137,49,10,192,20,204,232, +20,159,216,183,204,164,213,19,150,70,69,217,30,95,204,123, +36,176,74,203,33,138,225,12,13,201,138,62,253,174,21,7, +90,174,81,70,198,232,0,223,241,163,220,141,100,83,255,83, +193,178,174,142,183,101,52,141,187,162,92,143,76,214,253,113, +228,164,134,35,53,21,57,187,193,109,95,45,107,232,80,222, +68,241,157,61,226,88,74,20,208,41,61,129,105,154,117,109, +60,28,187,137,237,203,101,203,125,74,92,80,189,117,33,252, +128,247,121,112,244,167,151,53,118,8,107,160,208,74,12,81, +8,39,96,76,6,252,204,55,229,60,4,58,168,247,42,64, +87,244,235,87,169,58,248,246,159,18,22,68,109,92,28,125, +233,109,12,29,200,187,44,188,155,195,14,107,173,0,80,1, +181,82,65,176,134,11,181,71,17,155,147,15,222,255,65,224, +135,190,231,6,161,29,152,186,153,238,218,115,136,96,24,71, +65,154,38,93,159,79,199,235,50,249,246,157,50,18,70,69, +216,14,93,205,111,102,185,90,217,32,191,179,69,60,79,139, +42,190,183,7,20,79,217,10,31,229,111,52,153,251,139,72, +159,101,103,189,24,241,32,237,147,228,110,39,171,252,156,54, +80,110,69,138,46,252,159,7,70,111,120,88,119,197,185,22, +24,172,241,66,204,65,132,199,112,131,214,110,64,219,52,251, +218,89,40,54,50,79,151,234,135,171,183,45,180,25,243,2, +201,149,206,194,177,153,248,186,94,158,88,181,228,33,215,49, +179,80,109,116,156,47,193,77,94,127,73,105,6,180,76,163, +173,156,145,32,42,227,102,168,75,234,51,234,196,154,37,108, +137,78,250,57,107,192,208,140,108,209,207,95,99,138,96,28, +7,73,158,118,85,186,15,143,239,230,177,211,88,42,20,22, +73,189,70,17,153,179,11,220,215,197,242,167,154,229,108,5, +143,250,182,154,198,92,65,172,70,50,169,247,40,96,83,246, +195,211,187,26,220,244,245,182,132,38,97,95,52,251,219,73, +42,55,38,13,158,250,149,170,130,127,253,40,117,3,221,214, +215,208,162,140,143,225,7,189,223,129,162,43,255,165,161,81, +89,54,215,31,83,14,67,44,66,122,32,243,114,201,114,190, +2,87,117,251,93,41,46,176,94,139,8,158,241,37,188,137, +227,43,121,197,165,214,33,176,65,123,55,129,125,218,92,121, +44,53,10,201,132,222,225,160,205,155,39,78,173,72,208,149, +253,242,212,170,4,31,249,175,13,133,75,178,179,95,156,122, +145,226,11,123,167,129,84,75,28,82,25,49,35,81,84,231, +221,16,182,64,103,245,152,101,104,77,6,254,236,51,231,20, +128,40,136,211,40,42,243,102,137,91,170,18,126,196,187,52, +60,170,219,238,90,115,128,225,24,77,224,158,46,212,31,85, +110,79,42,58,246,23,147,30,207,204,82,181,240,97,254,37, +163,121,220,52,245,58,69,38,238,174,50,119,22,137,189,202, +208,153,60,250,218,91,8,50,48,103,19,248,167,143,181,71, +16,139,145,14,202,189,72,240,149,191,210,84,232,44,30,187, +141,173,195,97,155,117,111,28,24,185,161,105,217,69,239,127, +32,248,194,223,121,34,212,6,197,93,86,222,73,33,135,48, +6,2,44,196,26,36,116,10,79,228,218,102,216,75,13,67, +42,34,118,38,139,254,254,18,210,4,233,153,76,250,61,43, +200,212,220,100,244,143,23,103,94,40,57,194,81,152,38,89, +223,71,195,187,58,220,182,213,54,198,14,96,29,22,91,157, +99,3,241,22,141,252,210,214,200,32,157,147,3,30,231,77, +16,159,209,39,222,173,97,65,213,214,199,208,131,156,207,192, +147,189,254,144,242,8,106,177,194,73,25,7,67,62,98,95, +50,155,215,79,82,187,17,109,242,252,43,70,53,216,233,45, +13,137,138,186,189,174,144,87,88,42,21,6,75,188,82,83, +144,163,25,221,226,151,187,150,28,228,120,70,150,232,165,143, +177,7,24,143,193,6,239,253,0,244,65,247,247,145,240,42, +78,183,232,229,143,53,71,24,10,145,4,107,185,64,121,21, +165,123,240,240,239,30,49,44,161,74,232,17,206,194,176,137, +250,187,74,220,81,165,246,32,226,99,250,97,235,117,136,108, +216,95,77,106,62,50,95,151,203,151,235,150,185,180,56,226, +82,234,0,218,161,169,217,201,46,127,175,9,196,83,180,226, +67,251,51,201,244,222,6,208,13,125,203,77,74,63,96,125, +22,157,253,227,196,137,21,75,154,50,29,182,91,215,194,131, +185,159,136,182,121,246,148,163,16,77,240,158,15,196,95,116, +250,79,11,43,166,52,6,10,172,212,18,132,100,64,207,116, +210,206,73,1,135,114,38,130,110,236,27,102,86,170,9,206, +243,160,232,203,111,107,105,64,212,196,229,213,149,246,66,194, +161,152,201,168,31,171,142,188,213,34,134,39,116,13,63,234, +221,10,22,117,125,61,45,169,200,216,29,108,250,126,27,74, +151,224,39,191,189,165,32,65,83,182,195,87,251,26,89,164, +247,50,192,102,236,11,102,119,186,73,239,103,160,201,218,63, +72,252,84,183,220,165,228,1,215,115,147,208,47,92,157,109, +227,237,24,85,96,175,54,52,46,139,238,254,51,194,68,200, +13,76,219,44,123,235,65,200,7,236,207,38,243,127,25,104, +179,230,13,19,43,151,36,103,59,120,245,167,149,21,114,10, +67,36,194,106,40,83,98,131,242,46,10,255,228,177,215,24, +34,16,70,65,152,6,89,157,103,67,249,18,221,244,247,150, +128,36,73,219,38,219,255,75,64,147,180,111,146,249,189,44, +176,91,219,2,155,181,111,144,217,185,46,152,223,201,34,191, +183,5,52,75,219,34,155,247,79,16,155,145,47,218,253,105, +100,149,158,195,4,203,185,10,216,149,237,242,245,186,68,62, +109,175,44,148,27,145,38,75,255,98,209,211,159,90,150,208, +37,252,137,103,107,121,64,245,212,165,244,1,246,99,211,241, +187,92,188,124,179,206,141,65,3,183,118,5,186,170,223,175, +66,117,209,253,127,4,184,136,251,169,104,217,71,207,123,34, +208,70,205,89,6,214,108,97,207,52,210,74,9,1,2,34, +36,6,42,172,150,50,4,38,104,206,54,240,110,15,43,174, +180,22,2,12,196,88,4,244,72,103,229,152,68,120,13,39, +106,236,18,246,68,163,189,156,176,48,106,194,242,168,106,251, +99,201,81,142,70,116,201,127,110,24,90,145,161,59,249,228, +189,23,0,46,224,94,46,88,222,85,225,190,44,182,59,215, +4,227,57,88,240,181,191,144,116,104,110,54,186,207,143,99, +39,177,92,169,44,152,219,137,42,187,231,13,17,11,147,38, +79,191,106,213,131,151,127,214,152,33,40,193,66,174,97,70, +165,216,192,188,77,162,191,190,148,54,64,110,100,154,110,221, +11,7,103,126,40,123,226,209,218,14,88,157,101,99,253,16, +245,112,229,182,164,38,35,127,180,185,243,72,104,21,134,75, +180,211,83,154,2,29,213,107,23,161,63,184,252,187,70,28, +73,169,6,56,141,163,34,109,151,172,231,35,241,85,189,126, +145,234,139,107,175,33,68,1,156,194,17,153,178,27,222,214, +209,176,174,138,247,109,48,221,179,135,28,199,72,2,181,84, +33,188,128,115,57,112,113,247,149,177,50,72,230,244,130,198, +109,81,205,119,230,136,66,57,17,97,51,244,37,183,57,245, +32,229,19,244,102,135,187,182,28,166,88,198,212,192,164,205, +147,167,94,165,232,192,223,125,98,220,2,149,85,115,158,1, +37,83,120,35,199,52,194,74,40,17,66,3,176,6,11,189, +198,17,145,50,11,214,118,193,250,46,26,255,197,161,151,57, +182,16,103,80,200,37,204,137,4,91,185,35,73,213,198,199, +241,147,220,238,84,147,156,239,192,209,157,126,210,218,9,40, +147,98,15,51,46,133,14,226,61,26,216,181,237,176,213,58, +6,22,108,237,14,52,93,187,15,141,207,226,179,251,220,56, +52,50,75,215,226,131,251,191,8,244,81,247,214,129,176,11, +218,183,201,244,223,22,210,12,105,137,68,90,45,97,72,68, +212,204,101,197,157,86,82,136,33,8,193,0,142,225,4,141, +217,130,158,237,228,149,151,82,6,192,12,76,217,12,127,233, +105,76,21,204,235,36,153,219,139,10,191,229,37,149,25,179, +2,77,213,206,71,225,155,124,254,30,19,12,231,104,64,215, +244,227,214,169,48,89,242,151,155,150,94,196,248,4,190,233, +231,173,17,65,50,166,7,54,111,159,40,183,35,85,21,255, +219,65,170,39,46,173,142,176,21,58,138,215,108,98,255,50, +209,118,207,26,50,20,39,89,220,119,197,184,6,26,173,229, +0,197,81,150,198,69,209,159,95,198,218,32,184,195,75,59, +35,69,20,206,201,0,159,241,39,156,141,225,3,253,215,133, +242,35,218,229,233,85,141,126,242,218,75,8,19,32,39,50, +108,167,174,164,23,51,30,133,109,210,253,121,100,180,142,131, +37,95,185,43,201,197,206,103,225,217,92,126,92,59,13,165, +74,224,145,222,202,16,153,176,59,218,212,249,52,188,170,211, +111,90,121,33,229,16,196,96,132,135,112,7,150,110,197,139, +54,127,158,25,165,98,96,195,246,234,66,251,49,233,240,220, +46,84,31,93,239,79,32,155,242,31,26,158,213,101,246,173, +51,97,116,132,175,240,85,190,78,151,233,183,173,180,17,114, +2,195,52,202,202,56,25,226,19,250,134,155,181,110,128,219, +184,58,218,214,217,48,190,130,87,125,122,93,35,143,180,86, +2,136,132,88,129,164,74,227,161,216,201,44,95,171,11,236, +215,166,194,103,249,89,109,102,188,10,211,37,251,249,105,108, +21,142,203,164,219,243,138,72,157,69,99,191,48,117,50,205, +183,230,4,131,57,158,144,53,120,232,119,174,8,214,113,177, +244,41,118,49,251,209,233,62,61,174,153,198,90,33,160,64, +74,37,192,72,12,85,72,47,100,28,14,217,140,127,225,232, +76,31,109,239,44,16,91,145,163,27,253,230,149,147,18,14, +196,92,68,252,76,55,237,189,4,48,9,243,34,201,215,238, +66,243,177,249,248,124,62,30,159,205,231,231,177,209,120,46, +22,62,205,175,102,53,155,217,175,78,181,201,241,143,28,215, +72,35,165,20,0,40,128,82,40,32,82,98,129,210,42,8, +215,96,163,247,60,32,122,226,211,250,10,90,181,225,113,221, +52,247,26,65,36,198,42,32,87,50,139,215,110,66,251,48, +249,242,221,58,22,22,77,253,78,21,201,187,46,156,159,193, +38,239,191,32,116,3,223,246,211,210,138,8,157,193,35,191, +181,37,48,73,243,166,137,215,107,18,241,53,189,184,241,106, +76,19,172,231,34,225,87,188,106,211,227,155,121,174,20,22, +72,173,68,16,141,241,2,204,197,196,199,245,211,212,234,4, +155,185,175,136,213,73,54,247,31,17,46,195,110,106,123,98, +209,210,143,88,151,196,103,245,153,117,106,76,18,188,229,35, +245,21,181,122,193,226,174,43,231,37,144,73,185,7,9,159, +226,23,187,158,157,228,114,231,146,224,44,15,171,174,188,151, +2,6,101,92,12,125,200,125,76,60,92,187,13,173,203,224, +155,127,206,24,16,48,33,115,112,225,247,188,32,114,99,211, +240,171,94,189,104,241,199,157,83,2,130,36,76,139,44,222, +187,1,108,195,238,106,115,227,209,216,46,92,159,77,231,239, +48,209,114,143,18,54,68,47,124,156,63,193,108,78,63,104, +253,6,149,93,243,142,9,133,67,50,163,87,60,106,219,98, +155,115,15,16,30,193,45,94,185,41,233,193,204,79,101,203, +124,90,94,81,169,55,40,236,146,246,76,34,189,150,17,52, +98,75,114,178,195,95,123,10,81,4,231,120,64,246,228,163, +247,61,48,120,227,199,184,3,74,167,224,68,143,125,198,156, +64,48,133,51,50,68,39,252,140,55,97,124,4,191,248,245, +174,4,23,121,191,5,37,91,248,51,207,148,210,0,168,129, +74,171,33,76,129,140,202,177,137,248,155,78,222,121,33,228, +0,198,97,144,197,121,23,132,111,240,217,127,78,24,24,177, +33,121,209,229,255,53,160,104,202,119,232,104,94,55,201,253, +78,20,217,185,47,136,221,200,54,253,190,21,38,74,238,112, +210,198,201,17,143,210,54,200,238,124,19,206,199,224,131,255, +255,}; diff --git a/MCUME_teensy41/teensy800/pia.c b/MCUME_teensy41/teensy800/pia.c new file mode 100644 index 0000000..9dfd9ce --- /dev/null +++ b/MCUME_teensy41/teensy800/pia.c @@ -0,0 +1,71 @@ +#include + +#include "atari.h" +#include "cpu.h" +#include "pia.h" + +UBYTE PACTL; +UBYTE PBCTL; +UBYTE PORTA; +UBYTE PORTB; + + +static UBYTE PORTA_mask = 0xff; +static UBYTE PORTB_mask = 0xff; + +void PIA_Initialise(void) +{ + PORTA = 0xff; + PORTB = 0xff; +} + +UBYTE PIA_GetByte(UWORD addr) +{ + UBYTE byte; + + addr &= 0x03; + switch (addr) { + case _PACTL: + byte = PACTL; + break; + case _PBCTL: + byte = PBCTL; + break; + case _PORTA: + byte = Atari_PORT(0); + byte &= PORTA_mask; + break; + case _PORTB: + byte = Atari_PORT(1); + byte &= PORTB_mask; + break; + } + + return byte; +} + +int PIA_PutByte(UWORD addr, UBYTE byte) +{ + addr &= 0xff03; + + switch (addr) { + case _PACTL: + PACTL = byte; + break; + case _PBCTL: + PBCTL = byte; + break; + case _PORTA: + if (!(PACTL & 0x04)) + PORTA_mask = ~byte; + break; + case _PORTB: + // if ((byte == 0) && (machine == AtariXL || machine == AtariXE)) + // break; /* special hack for old Atari800 games like is Tapper, for example */ + if (!(PBCTL & 0x04)) + PORTB_mask = ~byte; + break; + } + + return FALSE; +} diff --git a/MCUME_teensy41/teensy800/pia.h b/MCUME_teensy41/teensy800/pia.h new file mode 100644 index 0000000..24080a5 --- /dev/null +++ b/MCUME_teensy41/teensy800/pia.h @@ -0,0 +1,22 @@ +#ifndef __PIA__ +#define __PIA__ + +#include "atari.h" + +#define _PORTA 0x00 +#define _PORTB 0x01 +#define _PACTL 0x02 +#define _PBCTL 0x03 + +extern UBYTE PACTL; +extern UBYTE PBCTL; +extern UBYTE PORTA; +extern UBYTE PORTB; + +extern int xe_bank; + +void PIA_Initialise(void); +UBYTE PIA_GetByte(UWORD addr); +int PIA_PutByte(UWORD addr, UBYTE byte); + +#endif diff --git a/MCUME_teensy41/teensy800/platform_config.h b/MCUME_teensy41/teensy800/platform_config.h new file mode 100644 index 0000000..382d1ff --- /dev/null +++ b/MCUME_teensy41/teensy800/platform_config.h @@ -0,0 +1,39 @@ +#ifndef _PLATFORM_CONFIG_H_ +#define _PLATFORM_CONFIG_H_ + +#define TEECOMPUTER 1 + +#ifdef TEECOMPUTER +//#define ILI9341 1 +//#define ST7789 1 +//#define TFTSPI1 1 +#define HAS_T4_VGA 1 +#define HAS_SND 1 +#define HAS_USBKEY 1 +#define INVX 1 +#else + +#define HAS_T4_VGA 1 +//#define INVX 1 +#define INVY 1 +#define HAS_SND 1 +#define HAS_USBKEY 1 + +#endif + + +//#define ILI9341 1 +//#define ST7789 1 +//#define SWAP_JOYSTICK 1 +//#define LOHRES 1 +//#define ROTATE_SCREEN 1 +//#define EXTERNAL_SD 1 + + +//#define USE_SDFAT 1 +//#define SD_FAT_TYPE 1 +//#define USE_SDFS 1 +//#define SDFSDEV "1:" + + +#endif diff --git a/MCUME_teensy41/teensy800/pokey.c b/MCUME_teensy41/teensy800/pokey.c new file mode 100644 index 0000000..228580c --- /dev/null +++ b/MCUME_teensy41/teensy800/pokey.c @@ -0,0 +1,699 @@ +/* + * pokey.c - POKEY sound chip emulation + * + * Copyright (C) 1995-1998 David Firth + * Copyright (C) 1998-2008 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Atari800 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include "cpu.h" +#include "pokey.h" +#include "gtia.h" +#include "sio.h" +#ifdef SOUND +#include "pokeysnd.h" +#endif +#include "antic.h" + +#ifdef VOICEBOX +#include "voicebox.h" +#include "votraxsnd.h" +#endif + +#ifdef POKEY_UPDATE +void pokey_update(void); +#endif + +UBYTE POKEY_KBCODE; +UBYTE POKEY_SERIN; +UBYTE POKEY_IRQST; +UBYTE POKEY_IRQEN; +UBYTE POKEY_SKSTAT; +UBYTE POKEY_SKCTL; +int POKEY_DELAYED_SERIN_IRQ; +int POKEY_DELAYED_SEROUT_IRQ; +int POKEY_DELAYED_XMTDONE_IRQ; + +/* structures to hold the 9 pokey control bytes */ +UBYTE POKEY_AUDF[4 * POKEY_MAXPOKEYS]; /* AUDFx (D200, D202, D204, D206) */ +UBYTE POKEY_AUDC[4 * POKEY_MAXPOKEYS]; /* AUDCx (D201, D203, D205, D207) */ +UBYTE POKEY_AUDCTL[POKEY_MAXPOKEYS]; /* AUDCTL (D208) */ +int POKEY_DivNIRQ[4], POKEY_DivNMax[4]; +int POKEY_Base_mult[POKEY_MAXPOKEYS]; /* selects either 64Khz or 15Khz clock mult */ + +UBYTE POKEY_POT_input[8] = {228, 228, 228, 228, 228, 228, 228, 228}; +static int pot_scanline; + +#include "noise.h" +//UBYTE POKEY_poly9_lookup[POKEY_POLY9_SIZE]; +//UBYTE POKEY_poly17_lookup[POKEY_POLY17_SIZE]; + +static ULONG random_scanline_counter; + +ULONG POKEY_GetRandomCounter(void) +{ + return random_scanline_counter; +} + +void POKEY_SetRandomCounter(ULONG value) +{ + random_scanline_counter = value; +} + +UBYTE POKEY_GetByte(UWORD addr, int no_side_effects) +{ + UBYTE byte = 0xff; + +#ifdef STEREO_SOUND + if (addr & 0x0010 && POKEYSND_stereo_enabled) + return 0; +#endif + addr &= 0x0f; + if (addr < 8) { + byte = POKEY_POT_input[addr]; + if (byte <= pot_scanline) + return byte; + return pot_scanline; + } + switch (addr) { + case POKEY_OFFSET_ALLPOT: + { + int i; + for (i = 0; i < 8; i++) + if (POKEY_POT_input[i] <= pot_scanline) + byte &= ~(1 << i); /* reset bit if pot value known */ + } + break; + case POKEY_OFFSET_KBCODE: + byte = POKEY_KBCODE; + break; + case POKEY_OFFSET_RANDOM: + if ((POKEY_SKCTL & 0x03) != 0) { + int i = random_scanline_counter + ANTIC_XPOS; + if (POKEY_AUDCTL[0] & POKEY_POLY9) + byte = POKEY_poly9_lookup[i % POKEY_POLY9_SIZE]; + else { + const UBYTE *ptr; + i %= POKEY_POLY17_SIZE; + ptr = POKEY_poly17_lookup + (i >> 3); + i &= 7; + byte = (UBYTE) ((ptr[0] >> i) + (ptr[1] << (8 - i))); + } + } + break; + case POKEY_OFFSET_SERIN: + byte = POKEY_SERIN; +#ifdef DEBUG3 + printf("SERIO: SERIN read, bytevalue %02x\n", POKEY_SERIN); +#endif +#ifdef SERIO_SOUND + POKEYSND_UpdateSerio(0,byte); +#endif + break; + case POKEY_OFFSET_IRQST: + byte = POKEY_IRQST; + break; + case POKEY_OFFSET_SKSTAT: +#if SKIP + byte = POKEY_SKSTAT + (CASSETTE_IOLineStatus() << 4); +#else + byte = POKEY_SKSTAT; +#endif +#ifdef VOICEBOX + if (VOICEBOX_enabled) { + byte = POKEY_SKSTAT + (VOTRAXSND_busy << 4); + } +#endif + break; + } + + return byte; +} + +static void Update_Counter(int chan_mask); + +static int POKEY_siocheck(void) +{ + return (((POKEY_AUDF[POKEY_CHAN3] == 0x28 || POKEY_AUDF[POKEY_CHAN3] == 0x10 + || POKEY_AUDF[POKEY_CHAN3] == 0x08 || POKEY_AUDF[POKEY_CHAN3] == 0x0a) + && POKEY_AUDF[POKEY_CHAN4] == 0x00) /* intelligent peripherals speeds */ + || (POKEY_SKCTL & 0x78) == 0x28) /* cassette save mode */ + && (POKEY_AUDCTL[0] & 0x28) == 0x28; +} + +#ifndef SOUND_GAIN /* sound gain can be pre-defined in the configure/Makefile */ +#define SOUND_GAIN 4 +#endif + +#ifndef SOUND +#define POKEYSND_Update(addr, val, chip, gain) +#else +//#define POKEYSND_Update(addr, val, chip, gain) if (chip == 0) emu_sndPlaySound((chip*4)+addr, gain*16, val*16) +#endif + +void POKEY_PutByte(UWORD addr, UBYTE byte) +{ +#ifdef STEREO_SOUND + addr &= POKEYSND_stereo_enabled ? 0x1f : 0x0f; +#else + addr &= 0x0f; +#endif + switch (addr) { + case POKEY_OFFSET_AUDC1: + POKEY_AUDC[POKEY_CHAN1] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC1, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDC2: + POKEY_AUDC[POKEY_CHAN2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC2, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDC3: + POKEY_AUDC[POKEY_CHAN3] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC3, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDC4: + POKEY_AUDC[POKEY_CHAN4] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC4, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDCTL: + POKEY_AUDCTL[0] = byte; + + /* determine the base multiplier for the 'div by n' calculations */ + if (byte & POKEY_CLOCK_15) + POKEY_Base_mult[0] = POKEY_DIV_15; + else + POKEY_Base_mult[0] = POKEY_DIV_64; + + Update_Counter((1 << POKEY_CHAN1) | (1 << POKEY_CHAN2) | (1 << POKEY_CHAN3) | (1 << POKEY_CHAN4)); + POKEYSND_Update(POKEY_OFFSET_AUDCTL, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF1: + POKEY_AUDF[POKEY_CHAN1] = byte; + Update_Counter((POKEY_AUDCTL[0] & POKEY_CH1_CH2) ? ((1 << POKEY_CHAN2) | (1 << POKEY_CHAN1)) : (1 << POKEY_CHAN1)); + POKEYSND_Update(POKEY_OFFSET_AUDF1, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF2: + POKEY_AUDF[POKEY_CHAN2] = byte; + Update_Counter(1 << POKEY_CHAN2); + POKEYSND_Update(POKEY_OFFSET_AUDF2, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF3: + POKEY_AUDF[POKEY_CHAN3] = byte; + Update_Counter((POKEY_AUDCTL[0] & POKEY_CH3_CH4) ? ((1 << POKEY_CHAN4) | (1 << POKEY_CHAN3)) : (1 << POKEY_CHAN3)); + POKEYSND_Update(POKEY_OFFSET_AUDF3, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF4: + POKEY_AUDF[POKEY_CHAN4] = byte; + Update_Counter(1 << POKEY_CHAN4); + POKEYSND_Update(POKEY_OFFSET_AUDF4, byte, 0, SOUND_GAIN); + break; + case POKEY_OFFSET_IRQEN: + POKEY_IRQEN = byte; +#ifdef DEBUG1 + printf("WR: IRQEN = %x, PC = %x\n", POKEY_IRQEN, PC); +#endif + POKEY_IRQST |= ~byte & 0xf7; /* Reset disabled IRQs except XMTDONE */ +#if SKIP + if ((~POKEY_IRQST & POKEY_IRQEN) == 0 && PBI_IRQ == 0 && PIA_IRQ == 0) +#else + if ((~POKEY_IRQST & POKEY_IRQEN) == 0) +#endif + { + CPU_IRQ = 0; + } + else { + CPU_GenerateIRQ(); + } + break; + case POKEY_OFFSET_SKRES: + POKEY_SKSTAT |= 0xe0; + break; + case POKEY_OFFSET_POTGO: + if (!(POKEY_SKCTL & 4)) + pot_scanline = 0; /* slow pot mode */ + break; + case POKEY_OFFSET_SEROUT: +#ifdef VOICEBOX + VOICEBOX_SEROUTPutByte(byte); +#endif + if ((POKEY_SKCTL & 0x70) == 0x20 && POKEY_siocheck()) + SIO_PutByte(byte); + /* check if cassette 2-tone mode has been enabled */ + if ((POKEY_SKCTL & 0x08) == 0x00) { + /* intelligent device */ + POKEY_DELAYED_SEROUT_IRQ = SIO_SEROUT_INTERVAL; + POKEY_IRQST |= 0x08; + POKEY_DELAYED_XMTDONE_IRQ = SIO_XMTDONE_INTERVAL; + } + else { + /* cassette */ + /* some savers patch the cassette baud rate, so we evaluate it here */ + /* scanlines per second*10 bit*audiofrequency/(1.79 MHz/2) */ + POKEY_DELAYED_SEROUT_IRQ = 312*50*10*(POKEY_AUDF[POKEY_CHAN3] + POKEY_AUDF[POKEY_CHAN4]*0x100)/895000; + /* safety check */ + if (POKEY_DELAYED_SEROUT_IRQ >= 3) { + POKEY_IRQST |= 0x08; + POKEY_DELAYED_XMTDONE_IRQ = 2*POKEY_DELAYED_SEROUT_IRQ - 2; + } + else { + POKEY_DELAYED_SEROUT_IRQ = 0; + POKEY_DELAYED_XMTDONE_IRQ = 0; + } + }; +#ifdef SERIO_SOUND + POKEYSND_UpdateSerio(1, byte); +#endif + break; + case POKEY_OFFSET_STIMER: + POKEY_DivNIRQ[POKEY_CHAN1] = POKEY_DivNMax[POKEY_CHAN1]; + POKEY_DivNIRQ[POKEY_CHAN2] = POKEY_DivNMax[POKEY_CHAN2]; + POKEY_DivNIRQ[POKEY_CHAN4] = POKEY_DivNMax[POKEY_CHAN4]; + POKEYSND_Update(POKEY_OFFSET_STIMER, byte, 0, SOUND_GAIN); +#ifdef DEBUG1 + printf("WR: STIMER = %x\n", byte); +#endif + break; + case POKEY_OFFSET_SKCTL: +#ifdef VOICEBOX + VOICEBOX_SKCTLPutByte(byte); +#endif + POKEY_SKCTL = byte; + POKEYSND_Update(POKEY_OFFSET_SKCTL, byte, 0, SOUND_GAIN); + if (byte & 4) + pot_scanline = 228; /* fast pot mode - return results immediately */ + if ((byte & 0x03) == 0) { + /* POKEY reset. */ + /* Stop serial IO. */ + POKEY_DELAYED_SERIN_IRQ = 0; + POKEY_DELAYED_SEROUT_IRQ = 0; + POKEY_DELAYED_XMTDONE_IRQ = 0; +#if SKIP + CASSETTE_ResetPOKEY(); +#endif + /* TODO other registers should also be reset. */ + } + break; +#ifdef STEREO_SOUND + case POKEY_OFFSET_AUDC1 + POKEY_OFFSET_POKEY2: + POKEY_AUDC[POKEY_CHAN1 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC1, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDC2 + POKEY_OFFSET_POKEY2: + POKEY_AUDC[POKEY_CHAN2 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC2, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDC3 + POKEY_OFFSET_POKEY2: + POKEY_AUDC[POKEY_CHAN3 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC3, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDC4 + POKEY_OFFSET_POKEY2: + POKEY_AUDC[POKEY_CHAN4 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDC4, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDCTL + POKEY_OFFSET_POKEY2: + POKEY_AUDCTL[1] = byte; + /* determine the base multiplier for the 'div by n' calculations */ + if (byte & POKEY_CLOCK_15) + POKEY_Base_mult[1] = POKEY_DIV_15; + else + POKEY_Base_mult[1] = POKEY_DIV_64; + + POKEYSND_Update(POKEY_OFFSET_AUDCTL, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF1 + POKEY_OFFSET_POKEY2: + POKEY_AUDF[POKEY_CHAN1 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDF1, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF2 + POKEY_OFFSET_POKEY2: + POKEY_AUDF[POKEY_CHAN2 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDF2, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF3 + POKEY_OFFSET_POKEY2: + POKEY_AUDF[POKEY_CHAN3 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDF3, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_AUDF4 + POKEY_OFFSET_POKEY2: + POKEY_AUDF[POKEY_CHAN4 + POKEY_CHIP2] = byte; + POKEYSND_Update(POKEY_OFFSET_AUDF4, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_STIMER + POKEY_OFFSET_POKEY2: + POKEYSND_Update(POKEY_OFFSET_STIMER, byte, 1, SOUND_GAIN); + break; + case POKEY_OFFSET_SKCTL + POKEY_OFFSET_POKEY2: + POKEYSND_Update(POKEY_OFFSET_SKCTL, byte, 1, SOUND_GAIN); + break; +#endif + } +} + +int POKEY_Initialise(void) +{ + int i; + ULONG reg; + + /* Initialise Serial Port Interrupts */ + POKEY_DELAYED_SERIN_IRQ = 0; + POKEY_DELAYED_SEROUT_IRQ = 0; + POKEY_DELAYED_XMTDONE_IRQ = 0; + + POKEY_KBCODE = 0xff; + POKEY_SERIN = 0x00; /* or 0xff ? */ + POKEY_IRQST = 0xff; + POKEY_IRQEN = 0x00; + POKEY_SKSTAT = 0xef; + POKEY_SKCTL = 0x00; + + for (i = 0; i < (POKEY_MAXPOKEYS * 4); i++) { + POKEY_AUDC[i] = 0; + POKEY_AUDF[i] = 0; + } + + for (i = 0; i < POKEY_MAXPOKEYS; i++) { + POKEY_AUDCTL[i] = 0; + POKEY_Base_mult[i] = POKEY_DIV_64; + } + + for (i = 0; i < 4; i++) + POKEY_DivNIRQ[i] = POKEY_DivNMax[i] = 0; + + pot_scanline = 0; + +#if SKIP + /* initialise poly9_lookup */ + reg = 0x1ff; + for (i = 0; i < POKEY_POLY9_SIZE; i++) { + reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1); + POKEY_poly9_lookup[i] = (UBYTE) reg; + } + /* initialise poly17_lookup */ + reg = 0x1ffff; + for (i = 0; i < POKEY_POLY17_SIZE; i++) { + reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8); + POKEY_poly17_lookup[i] = (UBYTE) (reg >> 1); + } +#endif + +#ifndef BASIC +#if SKIP + if (INPUT_Playingback()) { + random_scanline_counter = INPUT_PlaybackInt(); + } + else +#endif +#endif + { + random_scanline_counter = +#ifdef HAVE_WINDOWS_H + GetTickCount() % POKEY_POLY17_SIZE; +#elif defined(HAVE_TIME) + time(NULL) % POKEY_POLY17_SIZE; +#else + 0; +#endif + } +#ifndef BASIC +#if SKIP + if (INPUT_Recording()) { + INPUT_RecordInt(random_scanline_counter); + } +#endif +#endif + + return TRUE; +} + +void POKEY_Frame(void) +{ + random_scanline_counter %= (POKEY_AUDCTL[0] & POKEY_POLY9) ? POKEY_POLY9_SIZE : POKEY_POLY17_SIZE; +} + +/*************************************************************************** + ** Generate POKEY Timer IRQs if required ** + ** called on a per-scanline basis, not very precise, but good enough ** + ** for most applications ** + ***************************************************************************/ + +void POKEY_Scanline(void) +{ +#ifdef POKEY_UPDATE + pokey_update(); +#endif + +#ifdef VOL_ONLY_SOUND + POKEYSND_UpdateVolOnly(); +#endif + +#ifndef BASIC + INPUT_Scanline(); /* Handle Amiga and ST mice. */ + /* It's not a part of POKEY emulation, */ + /* but it looks to be the best place to put it. */ +#endif + + /* on nonpatched i/o-operation, enable the cassette timing */ +#if SKIP + if (!ESC_enable_sio_patch) { + if (CASSETTE_AddScanLine()) + POKEY_DELAYED_SERIN_IRQ = 1; + } +#endif + if ((POKEY_SKCTL & 0x03) == 0) + /* Don't process timers when POKEY is in reset mode. */ + return; + + if (pot_scanline < 228) + pot_scanline++; + + random_scanline_counter += ANTIC_LINE_C; + + if (POKEY_DELAYED_SERIN_IRQ > 0) { + if (--POKEY_DELAYED_SERIN_IRQ == 0) { + /* Load a byte to SERIN - even when the IRQ is disabled. */ + POKEY_SERIN = SIO_GetByte(); + if (POKEY_IRQEN & 0x20) { + if (POKEY_IRQST & 0x20) { + POKEY_IRQST &= 0xdf; +#ifdef DEBUG2 + printf("SERIO: SERIN Interrupt triggered, bytevalue %02x\n", POKEY_SERIN); +#endif + } + else { + POKEY_SKSTAT &= 0xdf; +#ifdef DEBUG2 + printf("SERIO: SERIN Interrupt triggered, bytevalue %02x\n", POKEY_SERIN); +#endif + } + CPU_GenerateIRQ(); + } +#ifdef DEBUG2 + else { + printf("SERIO: SERIN Interrupt missed, bytevalue %02x\n", POKEY_SERIN); + } +#endif + } + } + + if (POKEY_DELAYED_SEROUT_IRQ > 0) { + if (--POKEY_DELAYED_SEROUT_IRQ == 0) { + if (POKEY_IRQEN & 0x10) { +#ifdef DEBUG2 + printf("SERIO: SEROUT Interrupt triggered\n"); +#endif + POKEY_IRQST &= 0xef; + CPU_GenerateIRQ(); + } +#ifdef DEBUG2 + else { + printf("SERIO: SEROUT Interrupt missed\n"); + } +#endif + } + } + + if (POKEY_DELAYED_XMTDONE_IRQ > 0) + if (--POKEY_DELAYED_XMTDONE_IRQ == 0) { + POKEY_IRQST &= 0xf7; + if (POKEY_IRQEN & 0x08) { +#ifdef DEBUG2 + printf("SERIO: XMTDONE Interrupt triggered\n"); +#endif + CPU_GenerateIRQ(); + } +#ifdef DEBUG2 + else + printf("SERIO: XMTDONE Interrupt missed\n"); +#endif + } + + if ((POKEY_DivNIRQ[POKEY_CHAN1] -= ANTIC_LINE_C) < 0 ) { + POKEY_DivNIRQ[POKEY_CHAN1] += POKEY_DivNMax[POKEY_CHAN1]; + if (POKEY_IRQEN & 0x01) { + POKEY_IRQST &= 0xfe; + CPU_GenerateIRQ(); + } + } + + if ((POKEY_DivNIRQ[POKEY_CHAN2] -= ANTIC_LINE_C) < 0 ) { + POKEY_DivNIRQ[POKEY_CHAN2] += POKEY_DivNMax[POKEY_CHAN2]; + if (POKEY_IRQEN & 0x02) { + POKEY_IRQST &= 0xfd; + CPU_GenerateIRQ(); + } + } + + if ((POKEY_DivNIRQ[POKEY_CHAN4] -= ANTIC_LINE_C) < 0 ) { + POKEY_DivNIRQ[POKEY_CHAN4] += POKEY_DivNMax[POKEY_CHAN4]; + if (POKEY_IRQEN & 0x04) { + POKEY_IRQST &= 0xfb; + CPU_GenerateIRQ(); + } + } +} + +/*****************************************************************************/ +/* Module: Update_Counter() */ +/* Purpose: To process the latest control values stored in the AUDF, AUDC, */ +/* and AUDCTL registers. It pre-calculates as much information as */ +/* possible for better performance. This routine has been added */ +/* here again as I need the precise frequency for the pokey timers */ +/* again. The pokey emulation is therefore somewhat sub-optimal */ +/* since the actual pokey emulation should grab the frequency values */ +/* directly from here instead of calculating them again. */ +/* */ +/* Author: Ron Fries,Thomas Richter */ +/* Date: March 27, 1998 */ +/* */ +/* Inputs: chan_mask: Channel mask, one bit per channel. */ +/* The channels that need to be updated */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +static void Update_Counter(int chan_mask) +{ + +/************************************************************/ +/* As defined in the manual, the exact Div_n_cnt values are */ +/* different depending on the frequency and resolution: */ +/* 64 kHz or 15 kHz - AUDF + 1 */ +/* 1 MHz, 8-bit - AUDF + 4 */ +/* 1 MHz, 16-bit - AUDF[CHAN1]+256*AUDF[CHAN2] + 7 */ +/************************************************************/ + + /* only reset the channels that have changed */ + + if (chan_mask & (1 << POKEY_CHAN1)) { + /* process channel 1 frequency */ + if (POKEY_AUDCTL[0] & POKEY_CH1_179) + POKEY_DivNMax[POKEY_CHAN1] = POKEY_AUDF[POKEY_CHAN1] + 4; + else + POKEY_DivNMax[POKEY_CHAN1] = (POKEY_AUDF[POKEY_CHAN1] + 1) * POKEY_Base_mult[0]; + if (POKEY_DivNMax[POKEY_CHAN1] < ANTIC_LINE_C) + POKEY_DivNMax[POKEY_CHAN1] = ANTIC_LINE_C; + } + + if (chan_mask & (1 << POKEY_CHAN2)) { + /* process channel 2 frequency */ + if (POKEY_AUDCTL[0] & POKEY_CH1_CH2) { + if (POKEY_AUDCTL[0] & POKEY_CH1_179) + POKEY_DivNMax[POKEY_CHAN2] = POKEY_AUDF[POKEY_CHAN2] * 256 + POKEY_AUDF[POKEY_CHAN1] + 7; + else + POKEY_DivNMax[POKEY_CHAN2] = (POKEY_AUDF[POKEY_CHAN2] * 256 + POKEY_AUDF[POKEY_CHAN1] + 1) * POKEY_Base_mult[0]; + } + else + POKEY_DivNMax[POKEY_CHAN2] = (POKEY_AUDF[POKEY_CHAN2] + 1) * POKEY_Base_mult[0]; + if (POKEY_DivNMax[POKEY_CHAN2] < ANTIC_LINE_C) + POKEY_DivNMax[POKEY_CHAN2] = ANTIC_LINE_C; + } + + if (chan_mask & (1 << POKEY_CHAN4)) { + /* process channel 4 frequency */ + if (POKEY_AUDCTL[0] & POKEY_CH3_CH4) { + if (POKEY_AUDCTL[0] & POKEY_CH3_179) + POKEY_DivNMax[POKEY_CHAN4] = POKEY_AUDF[POKEY_CHAN4] * 256 + POKEY_AUDF[POKEY_CHAN3] + 7; + else + POKEY_DivNMax[POKEY_CHAN4] = (POKEY_AUDF[POKEY_CHAN4] * 256 + POKEY_AUDF[POKEY_CHAN3] + 1) * POKEY_Base_mult[0]; + } + else + POKEY_DivNMax[POKEY_CHAN4] = (POKEY_AUDF[POKEY_CHAN4] + 1) * POKEY_Base_mult[0]; + if (POKEY_DivNMax[POKEY_CHAN4] < ANTIC_LINE_C) + POKEY_DivNMax[POKEY_CHAN4] = ANTIC_LINE_C; + } +} + +#ifndef BASIC + +void POKEY_StateSave(void) +{ + int shift_key = 0; + int keypressed = 0; + + StateSav_SaveUBYTE(&POKEY_KBCODE, 1); + StateSav_SaveUBYTE(&POKEY_IRQST, 1); + StateSav_SaveUBYTE(&POKEY_IRQEN, 1); + StateSav_SaveUBYTE(&POKEY_SKCTL, 1); + + StateSav_SaveINT(&shift_key, 1); + StateSav_SaveINT(&keypressed, 1); + StateSav_SaveINT(&POKEY_DELAYED_SERIN_IRQ, 1); + StateSav_SaveINT(&POKEY_DELAYED_SEROUT_IRQ, 1); + StateSav_SaveINT(&POKEY_DELAYED_XMTDONE_IRQ, 1); + + StateSav_SaveUBYTE(&POKEY_AUDF[0], 4); + StateSav_SaveUBYTE(&POKEY_AUDC[0], 4); + StateSav_SaveUBYTE(&POKEY_AUDCTL[0], 1); + + StateSav_SaveINT(&POKEY_DivNIRQ[0], 4); + StateSav_SaveINT(&POKEY_DivNMax[0], 4); + StateSav_SaveINT(&POKEY_Base_mult[0], 1); +} + +void POKEY_StateRead(void) +{ + int i; + int shift_key; + int keypressed; + + StateSav_ReadUBYTE(&POKEY_KBCODE, 1); + StateSav_ReadUBYTE(&POKEY_IRQST, 1); + StateSav_ReadUBYTE(&POKEY_IRQEN, 1); + StateSav_ReadUBYTE(&POKEY_SKCTL, 1); + + StateSav_ReadINT(&shift_key, 1); + StateSav_ReadINT(&keypressed, 1); + StateSav_ReadINT(&POKEY_DELAYED_SERIN_IRQ, 1); + StateSav_ReadINT(&POKEY_DELAYED_SEROUT_IRQ, 1); + StateSav_ReadINT(&POKEY_DELAYED_XMTDONE_IRQ, 1); + + StateSav_ReadUBYTE(&POKEY_AUDF[0], 4); + StateSav_ReadUBYTE(&POKEY_AUDC[0], 4); + StateSav_ReadUBYTE(&POKEY_AUDCTL[0], 1); + for (i = 0; i < 4; i++) { + POKEY_PutByte((UWORD) (POKEY_OFFSET_AUDF1 + i * 2), POKEY_AUDF[i]); + POKEY_PutByte((UWORD) (POKEY_OFFSET_AUDC1 + i * 2), POKEY_AUDC[i]); + } + POKEY_PutByte(POKEY_OFFSET_AUDCTL, POKEY_AUDCTL[0]); + + StateSav_ReadINT(&POKEY_DivNIRQ[0], 4); + StateSav_ReadINT(&POKEY_DivNMax[0], 4); + StateSav_ReadINT(&POKEY_Base_mult[0], 1); +} + +#endif diff --git a/MCUME_teensy41/teensy800/pokey.h b/MCUME_teensy41/teensy800/pokey.h new file mode 100644 index 0000000..b9a0c29 --- /dev/null +++ b/MCUME_teensy41/teensy800/pokey.h @@ -0,0 +1,120 @@ +#ifndef POKEY_H_ +#define POKEY_H_ + + +#include "atari.h" + + +#define POKEY_OFFSET_AUDF1 0x00 +#define POKEY_OFFSET_AUDC1 0x01 +#define POKEY_OFFSET_AUDF2 0x02 +#define POKEY_OFFSET_AUDC2 0x03 +#define POKEY_OFFSET_AUDF3 0x04 +#define POKEY_OFFSET_AUDC3 0x05 +#define POKEY_OFFSET_AUDF4 0x06 +#define POKEY_OFFSET_AUDC4 0x07 +#define POKEY_OFFSET_AUDCTL 0x08 +#define POKEY_OFFSET_STIMER 0x09 +#define POKEY_OFFSET_SKRES 0x0a +#define POKEY_OFFSET_POTGO 0x0b +#define POKEY_OFFSET_SEROUT 0x0d +#define POKEY_OFFSET_IRQEN 0x0e +#define POKEY_OFFSET_SKCTL 0x0f + +#define POKEY_OFFSET_POT0 0x00 +#define POKEY_OFFSET_POT1 0x01 +#define POKEY_OFFSET_POT2 0x02 +#define POKEY_OFFSET_POT3 0x03 +#define POKEY_OFFSET_POT4 0x04 +#define POKEY_OFFSET_POT5 0x05 +#define POKEY_OFFSET_POT6 0x06 +#define POKEY_OFFSET_POT7 0x07 +#define POKEY_OFFSET_ALLPOT 0x08 +#define POKEY_OFFSET_KBCODE 0x09 +#define POKEY_OFFSET_RANDOM 0x0a +#define POKEY_OFFSET_SERIN 0x0d +#define POKEY_OFFSET_IRQST 0x0e +#define POKEY_OFFSET_SKSTAT 0x0f + +#define POKEY_OFFSET_POKEY2 0x10 /* offset to second pokey chip (STEREO expansion) */ + +#ifndef ASAP + +extern UBYTE POKEY_KBCODE; +extern UBYTE POKEY_IRQST; +extern UBYTE POKEY_IRQEN; +extern UBYTE POKEY_SKSTAT; +extern UBYTE POKEY_SKCTL; +extern int POKEY_DELAYED_SERIN_IRQ; +extern int POKEY_DELAYED_SEROUT_IRQ; +extern int POKEY_DELAYED_XMTDONE_IRQ; + +extern UBYTE POKEY_POT_input[8]; + +ULONG POKEY_GetRandomCounter(void); +void POKEY_SetRandomCounter(ULONG value); +UBYTE POKEY_GetByte(UWORD addr, int no_side_effects); +void POKEY_PutByte(UWORD addr, UBYTE byte); +int POKEY_Initialise(void); +void POKEY_Frame(void); +void POKEY_Scanline(void); +void POKEY_StateSave(void); +void POKEY_StateRead(void); + +#endif + +/* CONSTANT DEFINITIONS */ + +/* definitions for AUDCx (D201, D203, D205, D207) */ +#define POKEY_NOTPOLY5 0x80 /* selects POLY5 or direct CLOCK */ +#define POKEY_POLY4 0x40 /* selects POLY4 or POLY17 */ +#define POKEY_PURETONE 0x20 /* selects POLY4/17 or PURE tone */ +#define POKEY_VOL_ONLY 0x10 /* selects VOLUME OUTPUT ONLY */ +#define POKEY_VOLUME_MASK 0x0f /* volume mask */ + +/* definitions for AUDCTL (D208) */ +#define POKEY_POLY9 0x80 /* selects POLY9 or POLY17 */ +#define POKEY_CH1_179 0x40 /* selects 1.78979 MHz for Ch 1 */ +#define POKEY_CH3_179 0x20 /* selects 1.78979 MHz for Ch 3 */ +#define POKEY_CH1_CH2 0x10 /* clocks channel 1 w/channel 2 */ +#define POKEY_CH3_CH4 0x08 /* clocks channel 3 w/channel 4 */ +#define POKEY_CH1_FILTER 0x04 /* selects channel 1 high pass filter */ +#define POKEY_CH2_FILTER 0x02 /* selects channel 2 high pass filter */ +#define POKEY_CLOCK_15 0x01 /* selects 15.6999kHz or 63.9210kHz */ + +/* for accuracy, the 64kHz and 15kHz clocks are exact divisions of + the 1.79MHz clock */ +#define POKEY_DIV_64 28 /* divisor for 1.79MHz clock to 64 kHz */ +#define POKEY_DIV_15 114 /* divisor for 1.79MHz clock to 15 kHz */ + +/* the size (in entries) of the 4 polynomial tables */ +#define POKEY_POLY4_SIZE 0x000f +#define POKEY_POLY5_SIZE 0x001f +#define POKEY_POLY9_SIZE 511 //0x01ff +#define POKEY_POLY17_SIZE 16385//0x0001ffff + +#define POKEY_MAXPOKEYS 2 /* max number of emulated chips */ + +/* channel/chip definitions */ +#define POKEY_CHAN1 0 +#define POKEY_CHAN2 1 +#define POKEY_CHAN3 2 +#define POKEY_CHAN4 3 +#define POKEY_CHIP1 0 +#define POKEY_CHIP2 4 +#define POKEY_CHIP3 8 +#define POKEY_CHIP4 12 +#define POKEY_SAMPLE 127 + +/* structures to hold the 9 pokey control bytes */ +extern UBYTE POKEY_AUDF[4 * POKEY_MAXPOKEYS]; /* AUDFx (D200, D202, D204, D206) */ +extern UBYTE POKEY_AUDC[4 * POKEY_MAXPOKEYS]; /* AUDCx (D201, D203, D205, D207) */ +extern UBYTE POKEY_AUDCTL[POKEY_MAXPOKEYS]; /* AUDCTL (D208) */ + +extern int POKEY_DivNIRQ[4], POKEY_DivNMax[4]; +extern int POKEY_Base_mult[POKEY_MAXPOKEYS]; /* selects either 64Khz or 15Khz clock mult */ + +extern const UBYTE POKEY_poly9_lookup[POKEY_POLY9_SIZE]; +extern const UBYTE POKEY_poly17_lookup[POKEY_POLY17_SIZE]; + +#endif /* POKEY_H_ */ diff --git a/MCUME_teensy41/teensy800/pokeysnd.c b/MCUME_teensy41/teensy800/pokeysnd.c new file mode 100644 index 0000000..7545f7a --- /dev/null +++ b/MCUME_teensy41/teensy800/pokeysnd.c @@ -0,0 +1,1428 @@ +/* + * pokeysnd.c - POKEY sound chip emulation, v2.4 + * + * Copyright (C) 1996-1998 Ron Fries + * Copyright (C) 1998-2014 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Atari800 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef skip +#include "config.h" +#include +#include + +#ifdef ASAP /* external project, see http://asap.sf.net */ +#include "asap_internal.h" +#else +#include "atari.h" +#ifndef __PLUS +#include "sndsave.h" +#else +#include "sound_win.h" +#endif +#endif +#include "mzpokeysnd.h" +#include "pokeysnd.h" +#if defined(PBI_XLD) || defined (VOICEBOX) +#include "votraxsnd.h" +#endif +#include "antic.h" +#include "gtia.h" +#include "util.h" +#endif + +#include "pokeysnd.h" +#if defined(PBI_XLD) || defined (VOICEBOX) +#include "votraxsnd.h" +#endif +#include "antic.h" +#include "gtia.h" + +#ifdef WORDS_UNALIGNED_OK +# define READ_U32(x) (*(ULONG *) (x)) +# define WRITE_U32(x, d) (*(ULONG *) (x) = (d)) +#else +# ifdef WORDS_BIGENDIAN +# define READ_U32(x) (((*(unsigned char *)(x)) << 24) | ((*((unsigned char *)(x) + 1)) << 16) | \ + ((*((unsigned char *)(x) + 2)) << 8) | ((*((unsigned char *)(x) + 3)))) +# define WRITE_U32(x, d) \ + { \ + ULONG i = d; \ + (*(unsigned char *) (x)) = (((i) >> 24) & 255); \ + (*((unsigned char *) (x) + 1)) = (((i) >> 16) & 255); \ + (*((unsigned char *) (x) + 2)) = (((i) >> 8) & 255); \ + (*((unsigned char *) (x) + 3)) = ((i) & 255); \ + } +# else +# define READ_U32(x) ((*(unsigned char *) (x)) | ((*((unsigned char *) (x) + 1)) << 8) | \ + ((*((unsigned char *) (x) + 2)) << 16) | ((*((unsigned char *) (x) + 3)) << 24)) +# define WRITE_U32(x, d) \ + { \ + ULONG i = d; \ + (*(unsigned char *)(x)) = ((i) & 255); \ + (*((unsigned char *)(x) + 1)) = (((i) >> 8) & 255); \ + (*((unsigned char *)(x) + 2)) = (((i) >> 16) & 255); \ + (*((unsigned char *)(x) + 3)) = (((i) >> 24) & 255); \ + } +# endif +#endif + +/* GLOBAL VARIABLE DEFINITIONS */ + +/* number of pokey chips currently emulated */ +static UBYTE Num_pokeys; + +static UBYTE pokeysnd_AUDV[4 * POKEY_MAXPOKEYS]; /* Channel volume - derived */ + +static UBYTE Outbit[4 * POKEY_MAXPOKEYS]; /* current state of the output (high or low) */ + +static UBYTE Outvol[4 * POKEY_MAXPOKEYS]; /* last output volume for each channel */ + +/* Initialize the bit patterns for the polynomials. */ + +/* The 4bit and 5bit patterns are the identical ones used in the pokey chip. */ +/* Though the patterns could be packed with 8 bits per byte, using only a */ +/* single bit per byte keeps the math simple, which is important for */ +/* efficient processing. */ + +static const UBYTE bit4[POKEY_POLY4_SIZE] = +#ifndef POKEY23_POLY +{1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0}; /* new table invented by Perry */ +#else +{1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}; /* original POKEY 2.3 table */ +#endif + +static const UBYTE bit5[POKEY_POLY5_SIZE] = +#ifndef POKEY23_POLY +{1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0}; +#else +{0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1}; +#endif + +static ULONG P4 = 0, /* Global position pointer for the 4-bit POLY array */ + P5 = 0, /* Global position pointer for the 5-bit POLY array */ + P9 = 0, /* Global position pointer for the 9-bit POLY array */ + P17 = 0; /* Global position pointer for the 17-bit POLY array */ + +static ULONG Div_n_cnt[4 * POKEY_MAXPOKEYS], /* Divide by n counter. one for each channel */ + Div_n_max[4 * POKEY_MAXPOKEYS]; /* Divide by n maximum, one for each channel */ + +static ULONG Samp_n_max, /* Sample max. For accuracy, it is *256 */ + Samp_n_cnt[2]; /* Sample cnt. */ + +#ifdef INTERPOLATE_SOUND +#ifdef CLIP_SOUND +static SWORD last_val = 0; /* last output value */ +#else +static UWORD last_val = 0; +#endif +#ifdef STEREO_SOUND +#ifdef CLIP_SOUND +static SWORD last_val2 = 0; /* last output value */ +#else +static UWORD last_val2 = 0; +#endif +#endif +#endif + +/* Volume only emulations declarations */ +#ifdef VOL_ONLY_SOUND + +int POKEYSND_sampbuf_val[POKEYSND_SAMPBUF_MAX]; /* volume values */ +int POKEYSND_sampbuf_cnt[POKEYSND_SAMPBUF_MAX]; /* relative start time */ +int POKEYSND_sampbuf_ptr = 0; /* pointer to sampbuf */ +int POKEYSND_sampbuf_rptr = 0; /* pointer to read from sampbuf */ +int POKEYSND_sampbuf_last = 0; /* last absolute time */ +int POKEYSND_sampbuf_AUDV[4 * POKEY_MAXPOKEYS]; /* prev. channel volume */ +int POKEYSND_sampbuf_lastval = 0; /* last volume */ +int POKEYSND_sampout; /* last out volume */ +int POKEYSND_samp_freq; +int POKEYSND_samp_consol_val = 0; /* actual value of console sound */ +#ifdef STEREO_SOUND +static int sampbuf_val2[POKEYSND_SAMPBUF_MAX]; /* volume values */ +static int sampbuf_cnt2[POKEYSND_SAMPBUF_MAX]; /* relative start time */ +static int sampbuf_ptr2 = 0; /* pointer to sampbuf */ +static int sampbuf_rptr2 = 0; /* pointer to read from sampbuf */ +static int sampbuf_last2 = 0; /* last absolute time */ +static int sampbuf_lastval2 = 0; /* last volume */ +static int sampout2; /* last out volume */ +#endif +#endif /* VOL_ONLY_SOUND */ + +static ULONG snd_freq17 = POKEYSND_FREQ_17_EXACT; +int POKEYSND_playback_freq = 44100; +UBYTE POKEYSND_num_pokeys = 1; +int POKEYSND_snd_flags = 0; +static int mz_quality = 0; /* default quality for mzpokeysnd */ +#ifdef __PLUS +int mz_clear_regs = 0; +#endif + +int POKEYSND_enable_new_pokey = TRUE; +int POKEYSND_bienias_fix = TRUE; /* when TRUE, high frequencies get emulated: better sound but slower */ +#if defined(__PLUS) && !defined(_WX_) +#define BIENIAS_FIX (g_Sound.nBieniasFix) +#else +#define BIENIAS_FIX POKEYSND_bienias_fix +#endif +#ifndef ASAP +int POKEYSND_stereo_enabled = FALSE; +#endif + +int POKEYSND_volume = 0x100; + +/* multiple sound engine interface */ +static void pokeysnd_process_8(void *sndbuffer, int sndn); +static void pokeysnd_process_16(void *sndbuffer, int sndn); +static void null_pokey_process(void *sndbuffer, int sndn) {} +void (*POKEYSND_Process_ptr)(void *sndbuffer, int sndn) = null_pokey_process; + +static void Update_pokey_sound_rf(UWORD, UBYTE, UBYTE, UBYTE); +static void null_pokey_sound(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) {} +void (*POKEYSND_Update_ptr) (UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) + = null_pokey_sound; + +#ifdef SERIO_SOUND +static void Update_serio_sound_rf(int out, UBYTE data); +static void null_serio_sound(int out, UBYTE data) {} +void (*POKEYSND_UpdateSerio)(int out, UBYTE data) = null_serio_sound; +int POKEYSND_serio_sound_enabled = 1; +#endif + +#ifdef CONSOLE_SOUND +static void Update_consol_sound_rf(int set); +static void null_consol_sound(int set) {} +void (*POKEYSND_UpdateConsol_ptr)(int set) = null_consol_sound; +int POKEYSND_console_sound_enabled = 1; +#endif + +#ifdef VOL_ONLY_SOUND +static void Update_vol_only_sound_rf(void); +static void null_vol_only_sound(void) {} +void (*POKEYSND_UpdateVolOnly)(void) = null_vol_only_sound; +#endif + +#ifdef SYNCHRONIZED_SOUND +UBYTE *POKEYSND_process_buffer = NULL; +unsigned int POKEYSND_process_buffer_length; +unsigned int POKEYSND_process_buffer_fill; +static unsigned int prev_update_tick; + +static void Generate_sync_rf(unsigned int num_ticks); +static void null_generate_sync(unsigned int num_ticks) {} +void (*POKEYSND_GenerateSync)(unsigned int num_ticks) = null_generate_sync; + +static double ticks_per_sample; +static double samp_pos; +static int speaker; +static int const CONSOLE_VOL = 32; +#endif /* SYNCHRONIZED_SOUND */ + +/*****************************************************************************/ +/* In my routines, I treat the sample output as another divide by N counter */ +/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ +/* which has 8 binary digits to the right of the decimal point. I use a two */ +/* byte array to give me a minimum of 40 bits, and then use pointer math to */ +/* reference either the 24.8 whole/fraction combination or the 32-bit whole */ +/* only number. This is mainly used to keep the math simple for */ +/* optimization. See below: */ +/* */ +/* Representation on little-endian machines: */ +/* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx */ +/* fraction whole whole whole whole unused unused unused */ +/* */ +/* Samp_n_cnt[0] gives me a 32-bit int 24 whole bits with 8 fractional bits, */ +/* while (ULONG *)((UBYTE *)(&Samp_n_cnt[0])+1) gives me the 32-bit whole */ +/* number only. */ +/* */ +/* Representation on big-endian machines: */ +/* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx.xxxxxxxx */ +/* unused unused unused whole whole whole whole fraction */ +/* */ +/* Samp_n_cnt[1] gives me a 32-bit int 24 whole bits with 8 fractional bits, */ +/* while (ULONG *)((UBYTE *)(&Samp_n_cnt[0])+3) gives me the 32-bit whole */ +/* number only. */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Module: pokeysnd_init_rf() */ +/* Purpose: to handle the power-up initialization functions */ +/* these functions should only be executed on a cold-restart */ +/* */ +/* Author: Ron Fries */ +/* Date: January 1, 1997 */ +/* */ +/* Inputs: freq17 - the value for the '1.79MHz' Pokey audio clock */ +/* playback_freq - the playback frequency in samples per second */ +/* num_pokeys - specifies the number of pokey chips to be emulated */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +static int pokeysnd_init_rf(ULONG freq17, int playback_freq, + UBYTE num_pokeys, int flags); + +#ifdef VOL_ONLY_SOUND +/* Initialise variables related to volume-only sound. */ +static void init_vol_only(void) +{ + POKEYSND_sampbuf_rptr = POKEYSND_sampbuf_ptr; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; + POKEYSND_sampbuf_lastval = 0; + POKEYSND_samp_consol_val = 0; +#ifdef STEREO_SOUND + sampbuf_rptr2 = sampbuf_ptr2; + sampbuf_last2 = ANTIC_CPU_CLOCK; + sampbuf_lastval2 = 0; +#endif /* STEREO_SOUND */ +} +#endif /* VOL_ONLY_SOUND */ + +int POKEYSND_DoInit(void) +{ +#if SKIP + SndSave_CloseSoundFile(); +#endif + +#ifdef VOL_ONLY_SOUND + init_vol_only(); +#endif /* VOL_ONLY_SOUND */ + +#if SKIP + if (POKEYSND_enable_new_pokey) + return MZPOKEYSND_Init(snd_freq17, POKEYSND_playback_freq, + POKEYSND_num_pokeys, POKEYSND_snd_flags, mz_quality +#ifdef __PLUS + , mz_clear_regs +#endif + ); + else +#endif + return pokeysnd_init_rf(snd_freq17, POKEYSND_playback_freq, + POKEYSND_num_pokeys, POKEYSND_snd_flags); +} + +int POKEYSND_Init(ULONG freq17, int playback_freq, UBYTE num_pokeys, + int flags +#ifdef __PLUS + , int clear_regs +#endif +) +{ + snd_freq17 = freq17; + POKEYSND_playback_freq = playback_freq; + POKEYSND_num_pokeys = num_pokeys; + POKEYSND_snd_flags = flags; +#ifdef __PLUS + mz_clear_regs = clear_regs; +#endif +#ifdef SYNCHRONIZED_SOUND + { + /* A single call to Atari800_Frame may emulate a bit more CPU ticks than the exact number of + ticks per frame (Atari800_tv_mode*114). So we add a few ticks to buffer size just to be safe. */ + unsigned int const surplus_ticks = 10; + double samples_per_frame = (double)POKEYSND_playback_freq/(Atari800_tv_mode == Atari800_TV_PAL ? Atari800_FPS_PAL : Atari800_FPS_NTSC); + unsigned int ticks_per_frame = Atari800_tv_mode*114; + unsigned int max_ticks_per_frame = ticks_per_frame + surplus_ticks; + double ticks_per_sample = (double)ticks_per_frame / samples_per_frame; + POKEYSND_process_buffer_length = POKEYSND_num_pokeys * (unsigned int)ceil((double)max_ticks_per_frame / ticks_per_sample) * ((POKEYSND_snd_flags & POKEYSND_BIT16) ? 2:1); + free(POKEYSND_process_buffer); + POKEYSND_process_buffer = (UBYTE *)Util_malloc(POKEYSND_process_buffer_length); + POKEYSND_process_buffer_fill = 0; + prev_update_tick = ANTIC_CPU_CLOCK; + } +#endif /* SYNCHRONIZED_SOUND */ + +#if defined(PBI_XLD) || defined (VOICEBOX) + VOTRAXSND_Init(playback_freq, num_pokeys, (flags & POKEYSND_BIT16)); +#endif + return POKEYSND_DoInit(); +} + +void POKEYSND_SetMzQuality(int quality) /* specially for win32, perhaps not needed? */ +{ + mz_quality = quality; +} + +void SND_Process(void *sndbuffer, int sndn) +{ + POKEYSND_Process_ptr(sndbuffer, sndn); +#if defined(PBI_XLD) || defined (VOICEBOX) + VOTRAXSND_Process(sndbuffer,sndn); +#endif +#if !defined(__PLUS) && !defined(ASAP) +#if SKIP + SndSave_WriteToSoundFile((const unsigned char *)sndbuffer, sndn); +#endif +#endif +} + +#ifdef SYNCHRONIZED_SOUND +static void Update_synchronized_sound(void) +{ + POKEYSND_GenerateSync(ANTIC_CPU_CLOCK - prev_update_tick); + prev_update_tick = ANTIC_CPU_CLOCK; +} + +int POKEYSND_UpdateProcessBuffer(void) +{ + int sndn; + Update_synchronized_sound(); + sndn = POKEYSND_process_buffer_fill / ((POKEYSND_snd_flags & POKEYSND_BIT16) ? 2 : 1); + POKEYSND_process_buffer_fill = 0; + +#if defined(PBI_XLD) || defined (VOICEBOX) + VOTRAXSND_Process(POKEYSND_process_buffer, sndn); +#endif +#if !defined(__PLUS) && !defined(ASAP) + SndSave_WriteToSoundFile((const unsigned char *)POKEYSND_process_buffer, sndn); +#endif + return sndn; +} +#endif /* SYNCHRONIZED_SOUND */ + +#ifdef SYNCHRONIZED_SOUND +static void init_syncsound(void) +{ + double samples_per_frame = (double)POKEYSND_playback_freq/(Atari800_tv_mode == Atari800_TV_PAL ? Atari800_FPS_PAL : Atari800_FPS_NTSC); + unsigned int ticks_per_frame = Atari800_tv_mode*114; + ticks_per_sample = (double)ticks_per_frame / samples_per_frame; + samp_pos = 0.0; + POKEYSND_GenerateSync = Generate_sync_rf; + speaker = 0; +} +#endif /* SYNCHRONIZED_SOUND */ + +static int pokeysnd_init_rf(ULONG freq17, int playback_freq, + UBYTE num_pokeys, int flags) +{ + UBYTE chan; + + POKEYSND_Update_ptr = Update_pokey_sound_rf; +#ifdef SERIO_SOUND + POKEYSND_UpdateSerio = Update_serio_sound_rf; +#endif +#ifdef CONSOLE_SOUND + POKEYSND_UpdateConsol_ptr = Update_consol_sound_rf; +#endif +#ifdef VOL_ONLY_SOUND + POKEYSND_UpdateVolOnly = Update_vol_only_sound_rf; +#endif + + POKEYSND_Process_ptr = (flags & POKEYSND_BIT16) ? pokeysnd_process_16 : pokeysnd_process_8; + +#ifdef VOL_ONLY_SOUND + POKEYSND_samp_freq = playback_freq; +#endif + + /* start all of the polynomial counters at zero */ + P4 = 0; + P5 = 0; + P9 = 0; + P17 = 0; + + /* calculate the sample 'divide by N' value based on the playback freq. */ + Samp_n_max = ((ULONG) freq17 << 8) / playback_freq; + + Samp_n_cnt[0] = 0; /* initialize all bits of the sample */ + Samp_n_cnt[1] = 0; /* 'divide by N' counter */ + + for (chan = 0; chan < (POKEY_MAXPOKEYS * 4); chan++) { + Outvol[chan] = 0; + Outbit[chan] = 0; + Div_n_cnt[chan] = 0; + Div_n_max[chan] = 0x7fffffffL; + pokeysnd_AUDV[chan] = 0; +#ifdef VOL_ONLY_SOUND + POKEYSND_sampbuf_AUDV[chan] = 0; +#endif + } + + /* set the number of pokey chips currently emulated */ + Num_pokeys = num_pokeys; + +#ifdef SYNCHRONIZED_SOUND + init_syncsound(); +#endif + return 0; /* OK */ +} + + +/*****************************************************************************/ +/* Module: Update_pokey_sound_rf() */ +/* Purpose: To process the latest control values stored in the AUDF, AUDC, */ +/* and AUDCTL registers. It pre-calculates as much information as */ +/* possible for better performance. This routine has not been */ +/* optimized. */ +/* */ +/* Author: Ron Fries */ +/* Date: January 1, 1997 */ +/* */ +/* Inputs: addr - the address of the parameter to be changed */ +/* val - the new value to be placed in the specified address */ +/* gain - specified as an 8-bit fixed point number - use 1 for no */ +/* amplification (output is multiplied by gain) */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +void POKEYSND_Update(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) +{ +#ifdef SYNCHRONIZED_SOUND + Update_synchronized_sound(); +#endif /* SYNCHRONIZED_SOUND */ + POKEYSND_Update_ptr(addr, val, chip, gain); +} + +static void Update_pokey_sound_rf(UWORD addr, UBYTE val, UBYTE chip, + UBYTE gain) +{ + ULONG new_val = 0; + UBYTE chan; + UBYTE chan_mask; + UBYTE chip_offs; + + /* calculate the chip_offs for the channel arrays */ + chip_offs = chip << 2; + + /* determine which address was changed */ + switch (addr & 0x0f) { + case POKEY_OFFSET_AUDF1: + /* POKEY_AUDF[POKEY_CHAN1 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN1; + if (POKEY_AUDCTL[chip] & POKEY_CH1_CH2) /* if ch 1&2 tied together */ + chan_mask |= 1 << POKEY_CHAN2; /* then also change on ch2 */ + break; + case POKEY_OFFSET_AUDC1: + /* POKEY_AUDC[POKEY_CHAN1 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN1 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN1; + break; + case POKEY_OFFSET_AUDF2: + /* POKEY_AUDF[POKEY_CHAN2 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN2; + break; + case POKEY_OFFSET_AUDC2: + /* POKEY_AUDC[POKEY_CHAN2 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN2 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN2; + break; + case POKEY_OFFSET_AUDF3: + /* POKEY_AUDF[POKEY_CHAN3 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN3; + if (POKEY_AUDCTL[chip] & POKEY_CH3_CH4) /* if ch 3&4 tied together */ + chan_mask |= 1 << POKEY_CHAN4; /* then also change on ch4 */ + break; + case POKEY_OFFSET_AUDC3: + /* POKEY_AUDC[POKEY_CHAN3 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN3 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN3; + break; + case POKEY_OFFSET_AUDF4: + /* POKEY_AUDF[POKEY_CHAN4 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN4; + break; + case POKEY_OFFSET_AUDC4: + /* POKEY_AUDC[POKEY_CHAN4 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN4 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN4; + break; + case POKEY_OFFSET_AUDCTL: + /* POKEY_AUDCTL[chip] = val; */ + chan_mask = 15; /* all channels */ + break; + default: + chan_mask = 0; + break; + } + + /************************************************************/ + /* As defined in the manual, the exact Div_n_cnt values are */ + /* different depending on the frequency and resolution: */ + /* 64 kHz or 15 kHz - AUDF + 1 */ + /* 1 MHz, 8-bit - AUDF + 4 */ + /* 1 MHz, 16-bit - POKEY_AUDF[POKEY_CHAN1]+256*POKEY_AUDF[POKEY_CHAN2] + 7 */ + /************************************************************/ + + /* only reset the channels that have changed */ + + if (chan_mask & (1 << POKEY_CHAN1)) { + /* process channel 1 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH1_179) + new_val = POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 4; + else + new_val = (POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN1 + chip_offs]) { + Div_n_max[POKEY_CHAN1 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN1 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN1 + chip_offs] = new_val; + } + } + } + + if (chan_mask & (1 << POKEY_CHAN2)) { + /* process channel 2 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH1_CH2) { + if (POKEY_AUDCTL[chip] & POKEY_CH1_179) + new_val = POKEY_AUDF[POKEY_CHAN2 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 7; + else + new_val = (POKEY_AUDF[POKEY_CHAN2 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 1) * POKEY_Base_mult[chip]; + } + else + new_val = (POKEY_AUDF[POKEY_CHAN2 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN2 + chip_offs]) { + Div_n_max[POKEY_CHAN2 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN2 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN2 + chip_offs] = new_val; + } + } + } + + if (chan_mask & (1 << POKEY_CHAN3)) { + /* process channel 3 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH3_179) + new_val = POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 4; + else + new_val = (POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN3 + chip_offs]) { + Div_n_max[POKEY_CHAN3 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN3 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN3 + chip_offs] = new_val; + } + } + } + + if (chan_mask & (1 << POKEY_CHAN4)) { + /* process channel 4 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH3_CH4) { + if (POKEY_AUDCTL[chip] & POKEY_CH3_179) + new_val = POKEY_AUDF[POKEY_CHAN4 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 7; + else + new_val = (POKEY_AUDF[POKEY_CHAN4 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 1) * POKEY_Base_mult[chip]; + } + else + new_val = (POKEY_AUDF[POKEY_CHAN4 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN4 + chip_offs]) { + Div_n_max[POKEY_CHAN4 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN4 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN4 + chip_offs] = new_val; + } + } + } + + /* if channel is volume only, set current output */ + for (chan = POKEY_CHAN1; chan <= POKEY_CHAN4; chan++) { + if (chan_mask & (1 << chan)) { + +#ifdef VOL_ONLY_SOUND + +#ifdef __PLUS + if (g_Sound.nDigitized) +#endif + if ((POKEY_AUDC[chan + chip_offs] & POKEY_VOL_ONLY)) { + +#ifdef STEREO_SOUND + +#ifdef __PLUS + if (POKEYSND_stereo_enabled && chip & 0x01) +#else + if (chip & 0x01) +#endif + { + sampbuf_lastval2 += pokeysnd_AUDV[chan + chip_offs] + - POKEYSND_sampbuf_AUDV[chan + chip_offs]; + + sampbuf_val2[sampbuf_ptr2] = sampbuf_lastval2; + POKEYSND_sampbuf_AUDV[chan + chip_offs] = pokeysnd_AUDV[chan + chip_offs]; + sampbuf_cnt2[sampbuf_ptr2] = + (ANTIC_CPU_CLOCK - sampbuf_last2) * 128 * POKEYSND_samp_freq / 178979; + sampbuf_last2 = ANTIC_CPU_CLOCK; + sampbuf_ptr2++; + if (sampbuf_ptr2 >= POKEYSND_SAMPBUF_MAX) + sampbuf_ptr2 = 0; + if (sampbuf_ptr2 == sampbuf_rptr2) { + sampbuf_rptr2++; + if (sampbuf_rptr2 >= POKEYSND_SAMPBUF_MAX) + sampbuf_rptr2 = 0; + } + } + else +#endif /* STEREO_SOUND */ + { + POKEYSND_sampbuf_lastval += pokeysnd_AUDV[chan + chip_offs] + -POKEYSND_sampbuf_AUDV[chan + chip_offs]; + + POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; + POKEYSND_sampbuf_AUDV[chan + chip_offs] = pokeysnd_AUDV[chan + chip_offs]; + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = + (ANTIC_CPU_CLOCK - POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; + POKEYSND_sampbuf_ptr++; + if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_ptr = 0; + if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr) { + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + } + } + } + +#endif /* VOL_ONLY_SOUND */ + + /* I've disabled any frequencies that exceed the sampling + frequency. There isn't much point in processing frequencies + that the hardware can't reproduce. I've also disabled + processing if the volume is zero. */ + + /* if the channel is volume only */ + /* or the channel is off (volume == 0) */ + /* or the channel freq is greater than the playback freq */ + if ( (POKEY_AUDC[chan + chip_offs] & POKEY_VOL_ONLY) || + ((POKEY_AUDC[chan + chip_offs] & POKEY_VOLUME_MASK) == 0) + || (!BIENIAS_FIX && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))) + ) { + /* indicate the channel is 'on' */ + Outvol[chan + chip_offs] = 1; + + /* can only ignore channel if filtering off */ + if ((chan == POKEY_CHAN3 && !(POKEY_AUDCTL[chip] & POKEY_CH1_FILTER)) || + (chan == POKEY_CHAN4 && !(POKEY_AUDCTL[chip] & POKEY_CH2_FILTER)) || + (chan == POKEY_CHAN1) || + (chan == POKEY_CHAN2) + || (!BIENIAS_FIX && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))) + ) { + /* and set channel freq to max to reduce processing */ + Div_n_max[chan + chip_offs] = 0x7fffffffL; + Div_n_cnt[chan + chip_offs] = 0x7fffffffL; + } + } + } + } + + /* _enable(); */ /* RSF - removed for portability 31-MAR-97 */ +} + + +/*****************************************************************************/ +/* Module: pokeysnd_process() */ +/* Purpose: To fill the output buffer with the sound output based on the */ +/* pokey chip parameters. */ +/* */ +/* Author: Ron Fries */ +/* Date: January 1, 1997 */ +/* */ +/* Inputs: *buffer - pointer to the buffer where the audio output will */ +/* be placed */ +/* sndn - for mono, size of the playback buffer in samples */ +/* for stereo, size of the playback buffer in left samples */ +/* plus right samples. */ +/* num_pokeys - number of currently active pokeys to process */ +/* */ +/* Outputs: the buffer will be filled with n bytes of audio - no return val */ +/* Also the buffer will be written to disk if Sound recording is ON */ +/* */ +/*****************************************************************************/ + +static void pokeysnd_process_8(void *sndbuffer, int sndn) +{ + register UBYTE *buffer = (UBYTE *) sndbuffer; + register int n = sndn; + + register ULONG *div_n_ptr; + register UBYTE *samp_cnt_w_ptr; + register ULONG event_min; + register UBYTE next_event; +#ifdef CLIP_SOUND + register SWORD cur_val; /* then we have to count as 16-bit signed */ +#ifdef STEREO_SOUND + register SWORD cur_val2; +#endif +#else /* CLIP_SOUND */ + register UBYTE cur_val; /* otherwise we'll simplify as 8-bit unsigned */ +#ifdef STEREO_SOUND + register UBYTE cur_val2; +#endif +#endif /* CLIP_SOUND */ + register UBYTE *out_ptr; + register UBYTE audc; + register UBYTE toggle; + register UBYTE count; + register UBYTE *vol_ptr; + + /* set a pointer to the whole portion of the samp_n_cnt */ +#ifdef WORDS_BIGENDIAN + samp_cnt_w_ptr = ((UBYTE *) (&Samp_n_cnt[0]) + 3); +#else + samp_cnt_w_ptr = ((UBYTE *) (&Samp_n_cnt[0]) + 1); +#endif + + /* set a pointer for optimization */ + out_ptr = Outvol; + vol_ptr = pokeysnd_AUDV; + + /* The current output is pre-determined and then adjusted based on each */ + /* output change for increased performance (less over-all math). */ + /* add the output values of all 4 channels */ + cur_val = POKEYSND_SAMP_MIN; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + cur_val2 = POKEYSND_SAMP_MIN; +#endif /* STEREO_SOUND */ + + count = Num_pokeys; + do { + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + { + count--; + if (count) { + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + } + else + break; + } +#endif /* STEREO_SOUND */ + count--; + } while (count); + +#ifdef SYNCHRONIZED_SOUND + cur_val += speaker; +#endif + + /* loop until the buffer is filled */ + while (n) { + /* Normally the routine would simply decrement the 'div by N' */ + /* counters and react when they reach zero. Since we normally */ + /* won't be processing except once every 80 or so counts, */ + /* I've optimized by finding the smallest count and then */ + /* 'accelerated' time by adjusting all pointers by that amount. */ + + /* find next smallest event (either sample or chan 1-4) */ + next_event = POKEY_SAMPLE; + event_min = READ_U32(samp_cnt_w_ptr); + + div_n_ptr = Div_n_cnt; + + count = 0; + do { + /* Though I could have used a loop here, this is faster */ + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN1 + (count << 2); + } + div_n_ptr++; + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN2 + (count << 2); + } + div_n_ptr++; + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN3 + (count << 2); + } + div_n_ptr++; + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN4 + (count << 2); + } + div_n_ptr++; + + count++; + } while (count < Num_pokeys); + + /* if the next event is a channel change */ + if (next_event != POKEY_SAMPLE) { + /* shift the polynomial counters */ + + count = Num_pokeys; + do { + /* decrement all counters by the smallest count found */ + /* again, no loop for efficiency */ + div_n_ptr--; + *div_n_ptr -= event_min; + div_n_ptr--; + *div_n_ptr -= event_min; + div_n_ptr--; + *div_n_ptr -= event_min; + div_n_ptr--; + *div_n_ptr -= event_min; + + count--; + } while (count); + + + WRITE_U32(samp_cnt_w_ptr, READ_U32(samp_cnt_w_ptr) - event_min); + + /* since the polynomials require a mod (%) function which is + division, I don't adjust the polynomials on the SAMPLE events, + only the CHAN events. I have to keep track of the change, + though. */ + + P4 = (P4 + event_min) % POKEY_POLY4_SIZE; + P5 = (P5 + event_min) % POKEY_POLY5_SIZE; + P9 = (P9 + event_min) % POKEY_POLY9_SIZE; + P17 = (P17 + event_min) % POKEY_POLY17_SIZE; + + /* adjust channel counter */ + Div_n_cnt[next_event] += Div_n_max[next_event]; + + /* get the current AUDC into a register (for optimization) */ + audc = POKEY_AUDC[next_event]; + + /* set a pointer to the current output (for opt...) */ + out_ptr = &Outvol[next_event]; + + /* assume no changes to the output */ + toggle = FALSE; + + /* From here, a good understanding of the hardware is required */ + /* to understand what is happening. I won't be able to provide */ + /* much description to explain it here. */ + + /* if VOLUME only then nothing to process */ + if (!(audc & POKEY_VOL_ONLY)) { + /* if the output is pure or the output is poly5 and the poly5 bit */ + /* is set */ + if ((audc & POKEY_NOTPOLY5) || bit5[P5]) { + /* if the PURETONE bit is set */ + if (audc & POKEY_PURETONE) { + /* then simply toggle the output */ + toggle = TRUE; + } + /* otherwise if POLY4 is selected */ + else if (audc & POKEY_POLY4) { + /* then compare to the poly4 bit */ + toggle = (bit4[P4] == !(*out_ptr)); + } + else { + /* if 9-bit poly is selected on this chip */ + if (POKEY_AUDCTL[next_event >> 2] & POKEY_POLY9) { + /* compare to the poly9 bit */ + toggle = ((POKEY_poly9_lookup[P9] & 1) == !(*out_ptr)); + } + else { + /* otherwise compare to the poly17 bit */ + toggle = (((POKEY_poly17_lookup[P17 >> 3] >> (P17 & 7)) & 1) == !(*out_ptr)); + } + } + } + } + + /* check channel 1 filter (clocked by channel 3) */ + if ( POKEY_AUDCTL[next_event >> 2] & POKEY_CH1_FILTER) { + /* if we're processing channel 3 */ + if ((next_event & 0x03) == POKEY_CHAN3) { + /* check output of channel 1 on same chip */ + if (Outvol[next_event & 0xfd]) { + /* if on, turn it off */ + Outvol[next_event & 0xfd] = 0; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 -= pokeysnd_AUDV[next_event & 0xfd]; + else +#endif /* STEREO_SOUND */ + cur_val -= pokeysnd_AUDV[next_event & 0xfd]; + } + } + } + + /* check channel 2 filter (clocked by channel 4) */ + if ( POKEY_AUDCTL[next_event >> 2] & POKEY_CH2_FILTER) { + /* if we're processing channel 4 */ + if ((next_event & 0x03) == POKEY_CHAN4) { + /* check output of channel 2 on same chip */ + if (Outvol[next_event & 0xfd]) { + /* if on, turn it off */ + Outvol[next_event & 0xfd] = 0; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 -= pokeysnd_AUDV[next_event & 0xfd]; + else +#endif /* STEREO_SOUND */ + cur_val -= pokeysnd_AUDV[next_event & 0xfd]; + } + } + } + + /* if the current output bit has changed */ + if (toggle) { + if (*out_ptr) { + /* remove this channel from the signal */ +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 -= pokeysnd_AUDV[next_event]; + else +#endif /* STEREO_SOUND */ + cur_val -= pokeysnd_AUDV[next_event]; + + /* and turn the output off */ + *out_ptr = 0; + } + else { + /* turn the output on */ + *out_ptr = 1; + + /* and add it to the output signal */ +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 += pokeysnd_AUDV[next_event]; + else +#endif /* STEREO_SOUND */ + cur_val += pokeysnd_AUDV[next_event]; + } + } + } + else { /* otherwise we're processing a sample */ + /* adjust the sample counter - note we're using the 24.8 integer + which includes an 8 bit fraction for accuracy */ + + int iout; +#ifdef STEREO_SOUND + int iout2; +#endif +#ifdef INTERPOLATE_SOUND + if (cur_val != last_val) { + if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */ +#ifdef CLIP_SOUND + iout = (cur_val * (SLONG)(*Samp_n_cnt) + + last_val * (SLONG)(Samp_n_max - *Samp_n_cnt)) + / (SLONG)Samp_n_max; +#else + iout = (cur_val * (*Samp_n_cnt) + + last_val * (Samp_n_max - *Samp_n_cnt)) + / Samp_n_max; +#endif + } + else + iout = cur_val; + last_val = cur_val; + } + else + iout = cur_val; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + if (cur_val2 != last_val2) { + if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */ +#ifdef CLIP_SOUND + iout2 = (cur_val2 * (SLONG)(*Samp_n_cnt) + + last_val2 * (SLONG)(Samp_n_max - *Samp_n_cnt)) + / (SLONG)Samp_n_max; +#else + iout2 = (cur_val2 * (*Samp_n_cnt) + + last_val2 * (Samp_n_max - *Samp_n_cnt)) + / Samp_n_max; +#endif + } + else + iout2 = cur_val2; + last_val2 = cur_val2; + } + else + iout2 = cur_val2; +#endif /* STEREO_SOUND */ +#else /* INTERPOLATE_SOUND */ + iout = cur_val; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + iout2 = cur_val2; +#endif /* STEREO_SOUND */ +#endif /* INTERPOLATE_SOUND */ + +#ifdef VOL_ONLY_SOUND +#ifdef __PLUS + if (g_Sound.nDigitized) +#endif + { + if (POKEYSND_sampbuf_rptr != POKEYSND_sampbuf_ptr) { + int l; + if (POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] > 0) + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] -= 1280; + while ((l = POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr]) <= 0) { + POKEYSND_sampout = POKEYSND_sampbuf_val[POKEYSND_sampbuf_rptr]; + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + if (POKEYSND_sampbuf_rptr != POKEYSND_sampbuf_ptr) + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] += l; + else + break; + } + } + iout += POKEYSND_sampout; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + { + if (sampbuf_rptr2 != sampbuf_ptr2) { + int l; + if (sampbuf_cnt2[sampbuf_rptr2] > 0) + sampbuf_cnt2[sampbuf_rptr2] -= 1280; + while ((l = sampbuf_cnt2[sampbuf_rptr2]) <= 0) { + sampout2 = sampbuf_val2[sampbuf_rptr2]; + sampbuf_rptr2++; + if (sampbuf_rptr2 >= POKEYSND_SAMPBUF_MAX) + sampbuf_rptr2 = 0; + if (sampbuf_rptr2 != sampbuf_ptr2) + sampbuf_cnt2[sampbuf_rptr2] += l; + else + break; + } + } + iout2 += sampout2; + } +#endif /* STEREO_SOUND */ + } +#endif /* VOL_ONLY_SOUND */ + +#ifdef CLIP_SOUND + if (iout > POKEYSND_SAMP_MAX) { /* then check high limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; /* and limit if greater */ + } + else if (iout < POKEYSND_SAMP_MIN) { /* else check low limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; /* and limit if less */ + } + else { /* otherwise use raw value */ + *buffer++ = (UBYTE) iout; + } +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) { + if (iout2 > POKEYSND_SAMP_MAX) + *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; + else if (iout2 < POKEYSND_SAMP_MIN) + *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; + else + *buffer++ = (UBYTE) iout2; + } +#else /* __PLUS */ + if (Num_pokeys > 1) { + if ((POKEYSND_stereo_enabled ? iout2 : iout) > POKEYSND_SAMP_MAX) { /* then check high limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; /* and limit if greater */ + } + else if ((POKEYSND_stereo_enabled ? iout2 : iout) < POKEYSND_SAMP_MIN) { /* else check low limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; /* and limit if less */ + } + else { /* otherwise use raw value */ + *buffer++ = (UBYTE) (POKEYSND_stereo_enabled ? iout2 : iout); + } + } +#endif /* __PLUS */ +#endif /* STEREO_SOUND */ +#else /* CLIP_SOUND */ + *buffer++ = (UBYTE) iout; /* clipping not selected, use value */ +#ifdef STEREO_SOUND + if (Num_pokeys > 1) +#ifdef ASAP + *buffer++ = (UBYTE) iout2; +#else + *buffer++ = (UBYTE) (POKEYSND_stereo_enabled ? iout2 : iout); +#endif +#endif /* STEREO_SOUND */ +#endif /* CLIP_SOUND */ + +#ifdef WORDS_BIGENDIAN + *(Samp_n_cnt + 1) += Samp_n_max; +#else + *Samp_n_cnt += Samp_n_max; +#endif + /* and indicate one less byte in the buffer */ + n--; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + if (Num_pokeys > 1) + n--; +#endif + } + } +#ifdef VOL_ONLY_SOUND +#ifdef __PLUS + if (g_Sound.nDigitized) +#endif + { + if (POKEYSND_sampbuf_rptr == POKEYSND_sampbuf_ptr) + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + if (sampbuf_rptr2 == sampbuf_ptr2) + sampbuf_last2 = ANTIC_CPU_CLOCK; +#endif /* STEREO_SOUND */ + } +#endif /* VOL_ONLY_SOUND */ +} + +#ifdef SERIO_SOUND +static void Update_serio_sound_rf(int out, UBYTE data) +{ +#ifdef VOL_ONLY_SOUND +#ifdef __PLUS + if (g_Sound.nDigitized) { +#endif + int bits, pv, future; + if (!POKEYSND_serio_sound_enabled) return; + + pv = 0; + future = 0; + bits = (data << 1) | 0x200; + while (bits) + { + POKEYSND_sampbuf_lastval -= pv; + pv = (bits & 0x01) * pokeysnd_AUDV[3]; /* FIXME!!! - set volume from AUDV */ + POKEYSND_sampbuf_lastval += pv; + + POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = + (ANTIC_CPU_CLOCK + future-POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK + future; + POKEYSND_sampbuf_ptr++; + if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX ) + POKEYSND_sampbuf_ptr = 0; + if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr ) { + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + } + /* 1789790/19200 = 93 */ + future += 93; /* ~ 19200 bit/s - FIXME!!! set speed form AUDF [2] ??? */ + bits >>= 1; + } + POKEYSND_sampbuf_lastval -= pv; +#ifdef __PLUS + } +#endif +#endif /* VOL_ONLY_SOUND */ +} +#endif /* SERIO_SOUND */ + +void POKEYSND_SetVolume(int vol) +{ + if (vol > 100) + vol = 100; + if (vol < 0) + vol = 0; + + POKEYSND_volume = vol * 0x100 / 100; +} + +static void pokeysnd_process_16(void *sndbuffer, int sndn) +{ + short *buffer = (UWORD *) sndbuffer; + int i; + + pokeysnd_process_8(buffer, sndn); + + for (i = sndn - 1; i >= 0; i--) { +#ifndef POKEYSND_SIGNED_SAMPLES + int smp = ((int) (((UBYTE *) buffer)[i]) - 0x80) * POKEYSND_volume; +#else + int smp = ((int) ((SBYTE *) buffer)[i]) * POKEYSND_volume; +#endif + if (smp > 32767) + smp = 32767; + else if (smp < -32768) + smp = -32768; + + buffer[i] = smp; + } + +} + +#ifdef SYNCHRONIZED_SOUND +static void Generate_sync_rf(unsigned int num_ticks) +{ + double new_samp_pos; + unsigned int ticks; + UBYTE *buffer = POKEYSND_process_buffer + POKEYSND_process_buffer_fill; + UBYTE *buffer_end = POKEYSND_process_buffer + POKEYSND_process_buffer_length; + + for (;;) { + double int_part; + new_samp_pos = samp_pos + ticks_per_sample; + new_samp_pos = modf(new_samp_pos, &int_part); + ticks = (unsigned int)int_part; + if (ticks > num_ticks) { + samp_pos -= num_ticks; + break; + } + if (buffer >= buffer_end) + break; + + samp_pos = new_samp_pos; + num_ticks -= ticks; + + if (POKEYSND_snd_flags & POKEYSND_BIT16) { + pokeysnd_process_16(buffer, POKEYSND_num_pokeys); + buffer += 2 * POKEYSND_num_pokeys; + } + else { + pokeysnd_process_8(buffer, POKEYSND_num_pokeys); + buffer += POKEYSND_num_pokeys; + } + + } + + POKEYSND_process_buffer_fill = buffer - POKEYSND_process_buffer; +} +#endif /* SYNCHRONIZED_SOUND */ + +#ifdef CONSOLE_SOUND +void POKEYSND_UpdateConsol(int set) +{ + if (!POKEYSND_console_sound_enabled) + return; +#ifdef SYNCHRONIZED_SOUND + if (set) + Update_synchronized_sound(); +#endif /* SYNCHRONIZED_SOUND */ + POKEYSND_UpdateConsol_ptr(set); +} + +static void Update_consol_sound_rf(int set) +{ +#ifdef SYNCHRONIZED_SOUND + if (set) + speaker = CONSOLE_VOL * GTIA_speaker; +#elif defined(VOL_ONLY_SOUND) + static int prev_atari_speaker = 0; + static unsigned int prev_cpu_clock = 0; + int d; +#ifdef __PLUS + if (!g_Sound.nDigitized) + return; +#endif + + if (!set && POKEYSND_samp_consol_val == 0) + return; + POKEYSND_sampbuf_lastval -= POKEYSND_samp_consol_val; + if (prev_atari_speaker != GTIA_speaker) { + POKEYSND_samp_consol_val = GTIA_speaker * 8 * 4; /* gain */ + prev_cpu_clock = ANTIC_CPU_CLOCK; + } + else if (!set) { + d = ANTIC_CPU_CLOCK - prev_cpu_clock; + if (d < 114) { + POKEYSND_sampbuf_lastval += POKEYSND_samp_consol_val; + return; + } + while (d >= 114 /* CPUL */) { + POKEYSND_samp_consol_val = POKEYSND_samp_consol_val * 99 / 100; + d -= 114; + } + prev_cpu_clock = ANTIC_CPU_CLOCK - d; + } + POKEYSND_sampbuf_lastval += POKEYSND_samp_consol_val; + prev_atari_speaker = GTIA_speaker; + + POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = + (ANTIC_CPU_CLOCK - POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; + POKEYSND_sampbuf_ptr++; + if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_ptr = 0; + if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr) { + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + } +#endif /* !SYNCHRONIZED_SOUND && VOL_ONLY_SOUND */ +} +#endif /* CONSOLE_SOUND */ + +#ifdef VOL_ONLY_SOUND +static void Update_vol_only_sound_rf(void) +{ +#ifdef CONSOLE_SOUND + POKEYSND_UpdateConsol(0); /* mmm */ +#endif /* CONSOLE_SOUND */ +} +#endif /* VOL_ONLY_SOUND */ diff --git a/MCUME_teensy41/teensy800/pokeysnd.h b/MCUME_teensy41/teensy800/pokeysnd.h new file mode 100644 index 0000000..1ace964 --- /dev/null +++ b/MCUME_teensy41/teensy800/pokeysnd.h @@ -0,0 +1,147 @@ +/*****************************************************************************/ +/* */ +/* Module: POKEY Chip Simulator Includes, V2.3 */ +/* Purpose: To emulate the sound generation hardware of the Atari POKEY chip. */ +/* Author: Ron Fries */ +/* */ +/* Revision History: */ +/* */ +/* 09/22/96 - Ron Fries - Initial Release */ +/* 04/06/97 - Brad Oliver - Some cross-platform modifications. Added */ +/* big/little endian #defines, removed , */ +/* conditional defines for TRUE/FALSE */ +/* 01/19/98 - Ron Fries - Changed signed/unsigned sample support to a */ +/* compile-time option. Defaults to unsigned - */ +/* define SIGNED_SAMPLES to create signed. */ +/* */ +/*****************************************************************************/ +/* */ +/* License Information and Copyright Notice */ +/* ======================================== */ +/* */ +/* PokeySound is Copyright(c) 1996-1998 by Ron Fries */ +/* */ +/* This library is free software; you can redistribute it and/or modify it */ +/* under the terms of version 2 of the GNU Library General Public License */ +/* as published by the Free Software Foundation. */ +/* */ +/* This library is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library */ +/* General Public License for more details. */ +/* To obtain a copy of the GNU Library General Public License, write to the */ +/* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/* */ +/* Any permitted reproduction of these routines, in whole or in part, must */ +/* bear this legend. */ +/* */ +/*****************************************************************************/ + +#ifndef POKEYSND_H_ +#define POKEYSND_H_ + +#include "atari.h" +#include "pokey.h" + +/* CONSTANT DEFINITIONS */ + +/* As an alternative to using the exact frequencies, selecting a playback + frequency that is an exact division of the main clock provides a higher + quality output due to less aliasing. For best results, a value of + 1787520 MHz is used for the main clock. With this value, both the + 64 kHz and 15 kHz clocks are evenly divisible. Selecting a playback + frequency that is also a division of the clock provides the best + results. The best options are FREQ_64 divided by either 2, 3, or 4. + The best selection is based on a trade off between performance and + sound quality. + + Of course, using a main clock frequency that is not exact will affect + the pitch of the output. With these numbers, the pitch will be low + by 0.127%. (More than likely, an actual unit will vary by this much!) */ + +#define POKEYSND_FREQ_17_EXACT 1789790 /* exact 1.79 MHz clock freq */ +#define POKEYSND_FREQ_17_APPROX 1787520 /* approximate 1.79 MHz clock freq */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef POKEYSND_SIGNED_SAMPLES /* if signed output selected */ +#define POKEYSND_SAMP_MAX 255 /* else set unsigned 8-bit clip ranges */ +#define POKEYSND_SAMP_MIN 0 +#define POKEYSND_SAMP_MID 128 +//#define POKEYSND_SAMP_MAX 127 /* then set signed 8-bit clipping ranges */ +//#define POKEYSND_SAMP_MIN -128 +//#define POKEYSND_SAMP_MID 0 +#else +#define POKEYSND_SAMP_MAX 255 /* else set unsigned 8-bit clip ranges */ +#define POKEYSND_SAMP_MIN 0 +#define POKEYSND_SAMP_MID 128 +#endif + +/* init flags */ +#define POKEYSND_BIT16 1 + +extern SLONG POKEYSND_playback_freq; +extern UBYTE POKEYSND_num_pokeys; +extern int POKEYSND_snd_flags; +extern int POKEYSND_volume; + +extern int POKEYSND_enable_new_pokey; +extern int POKEYSND_stereo_enabled; +extern int POKEYSND_serio_sound_enabled; +extern int POKEYSND_console_sound_enabled; +extern int POKEYSND_bienias_fix; + +extern void (*POKEYSND_Process_ptr)(void *sndbuffer, int sndn); +extern void (*POKEYSND_Update_ptr)(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain); +extern void (*POKEYSND_UpdateSerio)(int out, UBYTE data); +extern void (*POKEYSND_UpdateConsol_ptr)(int set); +extern void (*POKEYSND_UpdateVolOnly)(void); + +int POKEYSND_Init(ULONG freq17, int playback_freq, UBYTE num_pokeys, + int flags +#ifdef __PLUS + , int clear_regs +#endif + ); +void POKEYSND_Update(UWORD addr, UBYTE val, UBYTE /*chip*/, UBYTE gain); +void POKEYSND_UpdateConsol(int set); + +/* Fill sndbuffer with sndn samples of audio. Number of bytes written to + sndbuffer is sndn with 8-bit sound, and 2*sndn with 16-bit sound. sndn + must be a multiple of POKEYSND_num_pokeys. */ +void POKEYSND_Process(void *sndbuffer, int sndn); +int POKEYSND_DoInit(void); +void POKEYSND_SetMzQuality(int quality); +void POKEYSND_SetVolume(int vol); + +/* Volume only emulations declarations */ +#ifdef VOL_ONLY_SOUND + +#define POKEYSND_SAMPBUF_MAX 2000 +extern int POKEYSND_sampbuf_val[POKEYSND_SAMPBUF_MAX]; /* volume values */ +extern int POKEYSND_sampbuf_cnt[POKEYSND_SAMPBUF_MAX]; /* relative start time */ +extern int POKEYSND_sampbuf_ptr; /* pointer to sampbuf */ +extern int POKEYSND_sampbuf_rptr; /* pointer to read from sampbuf */ +extern int POKEYSND_sampbuf_last; /* last absolute time */ +extern int POKEYSND_sampbuf_AUDV[4 * POKEY_MAXPOKEYS]; /* prev. channel volume */ +extern int POKEYSND_sampbuf_lastval; /* last volume */ +extern int POKEYSND_sampout; /* last out volume */ +extern int POKEYSND_samp_freq; +extern int POKEYSND_samp_consol_val; /* actual value of console sound */ +#endif /* VOL_ONLY_SOUND */ + +#ifdef SYNCHRONIZED_SOUND +extern UBYTE *POKEYSND_process_buffer; +extern unsigned int POKEYSND_process_buffer_length; +extern unsigned int POKEYSND_process_buffer_fill; +extern void (*POKEYSND_GenerateSync)(unsigned int num_ticks); +int POKEYSND_UpdateProcessBuffer(void); +#endif /* SYNCHRONIZED_SOUND */ + +#ifdef __cplusplus +} + +#endif +#endif /* POKEYSND_H_ */ diff --git a/MCUME_teensy41/teensy800/romatariosa.h b/MCUME_teensy41/teensy800/romatariosa.h new file mode 100644 index 0000000..207cb1a --- /dev/null +++ b/MCUME_teensy41/teensy800/romatariosa.h @@ -0,0 +1,642 @@ +const UBYTE PROGMEM romos[10240] = { +0x20,0xA1,0xDB,0x20,0xBB,0xDB,0xB0,0x39,0xA2,0xED,0xA0,0x04,0x20,0x48,0xDA,0xA2, +0xFF,0x86,0xF1,0x20,0x44,0xDA,0xF0,0x04,0xA9,0xFF,0x85,0xF0,0x20,0x94,0xDB,0xB0, +0x21,0x48,0xA6,0xD5,0xD0,0x11,0x20,0xEB,0xDB,0x68,0x05,0xD9,0x85,0xD9,0xA6,0xF1, +0x30,0xE6,0xE8,0x86,0xF1,0xD0,0xE1,0x68,0xA6,0xF1,0x10,0x02,0xE6,0xED,0x4C,0x18, +0xD8,0x60,0xC9,0x2E,0xF0,0x14,0xC9,0x45,0xF0,0x19,0xA6,0xF0,0xD0,0x68,0xC9,0x2B, +0xF0,0xC6,0xC9,0x2D,0xF0,0x00,0x85,0xEE,0xF0,0xBE,0xA6,0xF1,0x10,0x58,0xE8,0x86, +0xF1,0xF0,0xB5,0xA5,0xF2,0x85,0xEC,0x20,0x94,0xDB,0xB0,0x37,0xAA,0xA5,0xED,0x48, +0x86,0xED,0x20,0x94,0xDB,0xB0,0x17,0x48,0xA5,0xED,0x0A,0x85,0xED,0x0A,0x0A,0x65, +0xED,0x85,0xED,0x68,0x18,0x65,0xED,0x85,0xED,0xA4,0xF2,0x20,0x9D,0xDB,0xA5,0xEF, +0xF0,0x09,0xA5,0xED,0x49,0xFF,0x18,0x69,0x01,0x85,0xED,0x68,0x18,0x65,0xED,0x85, +0xED,0xD0,0x13,0xC9,0x2B,0xF0,0x06,0xC9,0x2D,0xD0,0x07,0x85,0xEF,0x20,0x94,0xDB, +0x90,0xBA,0xA5,0xEC,0x85,0xF2,0xC6,0xF2,0xA5,0xED,0xA6,0xF1,0x30,0x05,0xF0,0x03, +0x38,0xE5,0xF1,0x48,0x2A,0x68,0x6A,0x85,0xED,0x90,0x03,0x20,0xEB,0xDB,0xA5,0xED, +0x18,0x69,0x44,0x85,0xD4,0x20,0x00,0xDC,0xB0,0x0B,0xA6,0xEE,0xF0,0x06,0xA5,0xD4, +0x09,0x80,0x85,0xD4,0x18,0x60,0x20,0x51,0xDA,0xA9,0x30,0x8D,0x7F,0x05,0xA5,0xD4, +0xF0,0x28,0x29,0x7F,0xC9,0x3F,0x90,0x28,0xC9,0x45,0xB0,0x24,0x38,0xE9,0x3F,0x20, +0x70,0xDC,0x20,0xA4,0xDC,0x09,0x80,0x9D,0x80,0x05,0xAD,0x80,0x05,0xC9,0x2E,0xF0, +0x03,0x4C,0x88,0xD9,0x20,0xC1,0xDC,0x4C,0x9C,0xD9,0xA9,0xB0,0x8D,0x80,0x05,0x60, +0xA9,0x01,0x20,0x70,0xDC,0x20,0xA4,0xDC,0xE8,0x86,0xF2,0xA5,0xD4,0x0A,0x38,0xE9, +0x80,0xAE,0x80,0x05,0xE0,0x30,0xF0,0x17,0xAE,0x81,0x05,0xAC,0x82,0x05,0x8E,0x82, +0x05,0x8C,0x81,0x05,0xA6,0xF2,0xE0,0x02,0xD0,0x02,0xE6,0xF2,0x18,0x69,0x01,0x85, +0xED,0xA9,0x45,0xA4,0xF2,0x20,0x9F,0xDC,0x84,0xF2,0xA5,0xED,0x10,0x0B,0xA9,0x00, +0x38,0xE5,0xED,0x85,0xED,0xA9,0x2D,0xD0,0x02,0xA9,0x2B,0x20,0x9F,0xDC,0xA2,0x00, +0xA5,0xED,0x38,0xE9,0x0A,0x90,0x03,0xE8,0xD0,0xF8,0x18,0x69,0x0A,0x48,0x8A,0x20, +0x9D,0xDC,0x68,0x09,0x80,0x20,0x9D,0xDC,0xAD,0x80,0x05,0xC9,0x30,0xD0,0x0D,0x18, +0xA5,0xF3,0x69,0x01,0x85,0xF3,0xA5,0xF4,0x69,0x00,0x85,0xF4,0xA5,0xD4,0x10,0x09, +0x20,0xC1,0xDC,0xA0,0x00,0xA9,0x2D,0x91,0xF3,0x60,0xA5,0xD4,0x85,0xF8,0xA5,0xD5, +0x85,0xF7,0x20,0x44,0xDA,0xF8,0xA0,0x10,0x06,0xF8,0x26,0xF7,0xA2,0x03,0xB5,0xD4, +0x75,0xD4,0x95,0xD4,0xCA,0xD0,0xF7,0x88,0xD0,0xEE,0xD8,0xA9,0x42,0x85,0xD4,0x4C, +0x00,0xDC,0xA9,0x00,0x85,0xF7,0x85,0xF8,0xA5,0xD4,0x30,0x66,0xC9,0x43,0xB0,0x62, +0x38,0xE9,0x40,0x90,0x3F,0x69,0x00,0x0A,0x85,0xF5,0x20,0x5A,0xDA,0xB0,0x53,0xA5, +0xF7,0x85,0xF9,0xA5,0xF8,0x85,0xFA,0x20,0x5A,0xDA,0xB0,0x46,0x20,0x5A,0xDA,0xB0, +0x41,0x18,0xA5,0xF8,0x65,0xFA,0x85,0xF8,0xA5,0xF7,0x65,0xF9,0x85,0xF7,0xB0,0x32, +0x20,0xB9,0xDC,0x18,0x65,0xF8,0x85,0xF8,0xA5,0xF7,0x69,0x00,0xB0,0x24,0x85,0xF7, +0xC6,0xF5,0xD0,0xC6,0x20,0xB9,0xDC,0xC9,0x05,0x90,0x0D,0x18,0xA5,0xF8,0x69,0x01, +0x85,0xF8,0xA5,0xF7,0x69,0x00,0x85,0xF7,0xA5,0xF8,0x85,0xD4,0xA5,0xF7,0x85,0xD5, +0x18,0x60,0x38,0x60,0xA2,0xD4,0xA0,0x06,0xA9,0x00,0x95,0x00,0xE8,0x88,0xD0,0xFA, +0x60,0xA9,0x05,0x85,0xF4,0xA9,0x80,0x85,0xF3,0x60,0x18,0x26,0xF8,0x26,0xF7,0x60, +0xA5,0xE0,0x49,0x80,0x85,0xE0,0xA5,0xE0,0x29,0x7F,0x85,0xF7,0xA5,0xD4,0x29,0x7F, +0x38,0xE5,0xF7,0x10,0x10,0xA2,0x05,0xB5,0xD4,0xB4,0xE0,0x95,0xE0,0x98,0x95,0xD4, +0xCA,0x10,0xF4,0x30,0xE1,0xF0,0x07,0xC9,0x05,0xB0,0x19,0x20,0x3E,0xDC,0xF8,0xA5, +0xD4,0x45,0xE0,0x30,0x1E,0xA2,0x04,0x18,0xB5,0xD5,0x75,0xE1,0x95,0xD5,0xCA,0x10, +0xF7,0xD8,0xB0,0x03,0x4C,0x00,0xDC,0xA9,0x01,0x20,0x3A,0xDC,0xA9,0x01,0x85,0xD5, +0x4C,0x00,0xDC,0xA2,0x04,0x38,0xB5,0xD5,0xF5,0xE1,0x95,0xD5,0xCA,0x10,0xF7,0x90, +0x04,0xD8,0x4C,0x00,0xDC,0xA5,0xD4,0x49,0x80,0x85,0xD4,0x38,0xA2,0x04,0xA9,0x00, +0xF5,0xD5,0x95,0xD5,0xCA,0x10,0xF7,0xD8,0x4C,0x00,0xDC,0xA5,0xD4,0xF0,0x45,0xA5, +0xE0,0xF0,0x3E,0x20,0xCF,0xDC,0x38,0xE9,0x40,0x38,0x65,0xE0,0x30,0x38,0x20,0xE0, +0xDC,0xA5,0xDF,0x29,0x0F,0x85,0xF6,0xC6,0xF6,0x30,0x06,0x20,0x01,0xDD,0x4C,0xF7, +0xDA,0xA5,0xDF,0x4A,0x4A,0x4A,0x4A,0x85,0xF6,0xC6,0xF6,0x30,0x06,0x20,0x05,0xDD, +0x4C,0x09,0xDB,0x20,0x62,0xDC,0xC6,0xF5,0xD0,0xD7,0xA5,0xED,0x85,0xD4,0x4C,0x04, +0xDC,0x20,0x44,0xDA,0x18,0x60,0x38,0x60,0xA5,0xE0,0xF0,0xFA,0xA5,0xD4,0xF0,0xF4, +0x20,0xCF,0xDC,0x38,0xE5,0xE0,0x18,0x69,0x40,0x30,0xEB,0x20,0xE0,0xDC,0xE6,0xF5, +0x4C,0x4E,0xDB,0xA2,0x00,0xB5,0xD5,0x95,0xD4,0xE8,0xE0,0x0C,0xD0,0xF7,0xA0,0x05, +0x38,0xF8,0xB9,0xDA,0x00,0xF9,0xE6,0x00,0x99,0xDA,0x00,0x88,0x10,0xF4,0xD8,0x90, +0x04,0xE6,0xD9,0xD0,0xE9,0x20,0x0F,0xDD,0x06,0xD9,0x06,0xD9,0x06,0xD9,0x06,0xD9, +0xA0,0x05,0x38,0xF8,0xB9,0xDA,0x00,0xF9,0xE0,0x00,0x99,0xDA,0x00,0x88,0x10,0xF4, +0xD8,0x90,0x04,0xE6,0xD9,0xD0,0xE9,0x20,0x09,0xDD,0xC6,0xF5,0xD0,0xB5,0x20,0x62, +0xDC,0x4C,0x1A,0xDB,0x20,0xAF,0xDB,0xA4,0xF2,0x90,0x02,0xB1,0xF3,0xC8,0x84,0xF2, +0x60,0xA4,0xF2,0xA9,0x20,0xD1,0xF3,0xD0,0x03,0xC8,0xD0,0xF9,0x84,0xF2,0x60,0xA4, +0xF2,0xB1,0xF3,0x38,0xE9,0x30,0x90,0x18,0xC9,0x0A,0x60,0xA5,0xF2,0x48,0x20,0x94, +0xDB,0x90,0x1F,0xC9,0x2E,0xF0,0x14,0xC9,0x2B,0xF0,0x07,0xC9,0x2D,0xF0,0x03,0x68, +0x38,0x60,0x20,0x94,0xDB,0x90,0x0B,0xC9,0x2E,0xD0,0xF4,0x20,0x94,0xDB,0x90,0x02, +0xB0,0xED,0x68,0x85,0xF2,0x18,0x60,0xA2,0xE7,0xD0,0x02,0xA2,0xD5,0xA0,0x04,0x18, +0x36,0x04,0x36,0x03,0x36,0x02,0x36,0x01,0x36,0x00,0x26,0xEC,0x88,0xD0,0xF0,0x60, +0xA2,0x00,0x86,0xDA,0xA2,0x04,0xA5,0xD4,0xF0,0x2E,0xA5,0xD5,0xD0,0x1A,0xA0,0x00, +0xB9,0xD6,0x00,0x99,0xD5,0x00,0xC8,0xC0,0x05,0x90,0xF5,0xC6,0xD4,0xCA,0xD0,0xEA, +0xA5,0xD5,0xD0,0x04,0x85,0xD4,0x18,0x60,0xA5,0xD4,0x29,0x7F,0xC9,0x71,0x90,0x01, +0x60,0xC9,0x0F,0xB0,0x03,0x20,0x44,0xDA,0x18,0x60,0xA2,0xD4,0xD0,0x02,0xA2,0xE0, +0x86,0xF9,0x85,0xF7,0x85,0xF8,0xA0,0x04,0xB5,0x04,0x95,0x05,0xCA,0x88,0xD0,0xF8, +0xA9,0x00,0x95,0x05,0xA6,0xF9,0xC6,0xF7,0xD0,0xEC,0xB5,0x00,0x18,0x65,0xF8,0x95, +0x00,0x60,0xA2,0x0A,0xB5,0xD4,0x95,0xD5,0xCA,0x10,0xF9,0xA9,0x00,0x85,0xD4,0x60, +0x85,0xF7,0xA2,0x00,0xA0,0x00,0x20,0x93,0xDC,0x38,0xE9,0x01,0x85,0xF7,0xB5,0xD5, +0x4A,0x4A,0x4A,0x4A,0x20,0x9D,0xDC,0xB5,0xD5,0x29,0x0F,0x20,0x9D,0xDC,0xE8,0xE0, +0x05,0x90,0xE3,0xA5,0xF7,0xD0,0x05,0xA9,0x2E,0x20,0x9F,0xDC,0x60,0x09,0x30,0x99, +0x80,0x05,0xC8,0x60,0xA2,0x0A,0xBD,0x80,0x05,0xC9,0x2E,0xF0,0x07,0xC9,0x30,0xD0, +0x07,0xCA,0xD0,0xF2,0xCA,0xBD,0x80,0x05,0x60,0x20,0xEB,0xDB,0xA5,0xEC,0x29,0x0F, +0x60,0x38,0xA5,0xF3,0xE9,0x01,0x85,0xF3,0xA5,0xF4,0xE9,0x00,0x85,0xF4,0x60,0xA5, +0xD4,0x45,0xE0,0x29,0x80,0x85,0xEE,0x06,0xE0,0x46,0xE0,0xA5,0xD4,0x29,0x7F,0x60, +0x05,0xEE,0x85,0xED,0xA9,0x00,0x85,0xD4,0x85,0xE0,0x20,0x28,0xDD,0x20,0xE7,0xDB, +0xA5,0xEC,0x29,0x0F,0x85,0xE6,0xA9,0x05,0x85,0xF5,0x20,0x34,0xDD,0x20,0x44,0xDA, +0x60,0xA2,0xD9,0xD0,0x06,0xA2,0xD9,0xD0,0x08,0xA2,0xDF,0xA0,0xE5,0xD0,0x04,0xA2, +0xDF,0xA0,0xEB,0xA9,0x05,0x85,0xF7,0x18,0xF8,0xB5,0x00,0x79,0x00,0x00,0x95,0x00, +0xCA,0x88,0xC6,0xF7,0x10,0xF3,0xD8,0x60,0xA0,0x05,0xB9,0xE0,0x00,0x99,0xE6,0x00, +0x88,0x10,0xF7,0x60,0xA0,0x05,0xB9,0xD4,0x00,0x99,0xDA,0x00,0x88,0x10,0xF7,0x60, +0x86,0xFE,0x84,0xFF,0x85,0xEF,0xA2,0xE0,0xA0,0x05,0x20,0xA7,0xDD,0x20,0xB6,0xDD, +0xA6,0xFE,0xA4,0xFF,0x20,0x89,0xDD,0xC6,0xEF,0xF0,0x2D,0x20,0xDB,0xDA,0xB0,0x28, +0x18,0xA5,0xFE,0x69,0x06,0x85,0xFE,0x90,0x06,0xA5,0xFF,0x69,0x00,0x85,0xFF,0xA6, +0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20,0x66,0xDA,0xB0,0x0D,0xC6,0xEF,0xF0,0x09,0xA2, +0xE0,0xA0,0x05,0x20,0x98,0xDD,0x30,0xD3,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB1, +0xFC,0x99,0xD4,0x00,0x88,0x10,0xF8,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB1,0xFC, +0x99,0xE0,0x00,0x88,0x10,0xF8,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB9,0xD4,0x00, +0x91,0xFC,0x88,0x10,0xF8,0x60,0xA2,0x05,0xB5,0xD4,0x95,0xE0,0xCA,0x10,0xF9,0x60, +0xA2,0x89,0xA0,0xDE,0x20,0x98,0xDD,0x20,0xDB,0xDA,0xB0,0x7F,0xA9,0x00,0x85,0xF1, +0xA5,0xD4,0x85,0xF0,0x29,0x7F,0x85,0xD4,0x38,0xE9,0x40,0x30,0x26,0xC9,0x04,0x10, +0x6A,0xA2,0xE6,0xA0,0x05,0x20,0xA7,0xDD,0x20,0xD2,0xD9,0xA5,0xD4,0x85,0xF1,0xA5, +0xD5,0xD0,0x58,0x20,0xAA,0xD9,0x20,0xB6,0xDD,0xA2,0xE6,0xA0,0x05,0x20,0x89,0xDD, +0x20,0x60,0xDA,0xA9,0x0A,0xA2,0x4D,0xA0,0xDE,0x20,0x40,0xDD,0x20,0xB6,0xDD,0x20, +0xDB,0xDA,0xA5,0xF1,0xF0,0x23,0x18,0x6A,0x85,0xE0,0xA9,0x01,0x90,0x02,0xA9,0x10, +0x85,0xE1,0xA2,0x04,0xA9,0x00,0x95,0xE2,0xCA,0x10,0xFB,0xA5,0xE0,0x18,0x69,0x40, +0xB0,0x19,0x30,0x17,0x85,0xE0,0x20,0xDB,0xDA,0xA5,0xF0,0x10,0x0D,0x20,0xB6,0xDD, +0xA2,0x8F,0xA0,0xDE,0x20,0x89,0xDD,0x20,0x28,0xDB,0x60,0x38,0x60,0x3D,0x17,0x94, +0x19,0x00,0x00,0x3D,0x57,0x33,0x05,0x00,0x00,0x3E,0x05,0x54,0x76,0x62,0x00,0x3E, +0x32,0x19,0x62,0x27,0x00,0x3F,0x01,0x68,0x60,0x30,0x36,0x3F,0x07,0x32,0x03,0x27, +0x41,0x3F,0x25,0x43,0x34,0x56,0x75,0x3F,0x66,0x27,0x37,0x30,0x50,0x40,0x01,0x15, +0x12,0x92,0x55,0x3F,0x99,0x99,0x99,0x99,0x99,0x3F,0x43,0x42,0x94,0x48,0x19,0x40, +0x01,0x00,0x00,0x00,0x00,0x86,0xFE,0x84,0xFF,0xA2,0xE0,0xA0,0x05,0x20,0xA7,0xDD, +0xA6,0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20,0x66,0xDA,0xA2,0xE6,0xA0,0x05,0x20,0xA7, +0xDD,0xA2,0xE0,0xA0,0x05,0x20,0x89,0xDD,0xA6,0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20, +0x60,0xDA,0xA2,0xE6,0xA0,0x05,0x20,0x98,0xDD,0x20,0x28,0xDB,0x60,0xA9,0x01,0xD0, +0x02,0xA9,0x00,0x85,0xF0,0xA5,0xD4,0x10,0x02,0x38,0x60,0xA5,0xD4,0x85,0xE0,0x38, +0xE9,0x40,0x0A,0x85,0xF1,0xA5,0xD5,0x29,0xF0,0xD0,0x04,0xA9,0x01,0xD0,0x04,0xE6, +0xF1,0xA9,0x10,0x85,0xE1,0xA2,0x04,0xA9,0x00,0x95,0xE2,0xCA,0x10,0xFB,0x20,0x28, +0xDB,0xA2,0x66,0xA0,0xDF,0x20,0x95,0xDE,0xA2,0xE6,0xA0,0x05,0x20,0xA7,0xDD,0x20, +0xB6,0xDD,0x20,0xDB,0xDA,0xA9,0x0A,0xA2,0x72,0xA0,0xDF,0x20,0x40,0xDD,0xA2,0xE6, +0xA0,0x05,0x20,0x98,0xDD,0x20,0xDB,0xDA,0xA2,0x6C,0xA0,0xDF,0x20,0x98,0xDD,0x20, +0x66,0xDA,0x20,0xB6,0xDD,0xA9,0x00,0x85,0xD5,0xA5,0xF1,0x85,0xD4,0x10,0x07,0x49, +0xFF,0x18,0x69,0x01,0x85,0xD4,0x20,0xAA,0xD9,0x24,0xF1,0x10,0x06,0xA9,0x80,0x05, +0xD4,0x85,0xD4,0x20,0x66,0xDA,0xA5,0xF0,0xF0,0x0A,0xA2,0x89,0xA0,0xDE,0x20,0x98, +0xDD,0x20,0x28,0xDB,0x18,0x60,0x40,0x03,0x16,0x22,0x77,0x66,0x3F,0x50,0x00,0x00, +0x00,0x00,0x3F,0x49,0x15,0x57,0x11,0x08,0xBF,0x51,0x70,0x49,0x47,0x08,0x3F,0x39, +0x20,0x57,0x61,0x95,0xBF,0x04,0x39,0x63,0x03,0x55,0x3F,0x10,0x09,0x30,0x12,0x64, +0x3F,0x09,0x39,0x08,0x04,0x60,0x3F,0x12,0x42,0x58,0x47,0x42,0x3F,0x17,0x37,0x12, +0x06,0x08,0x3F,0x28,0x95,0x29,0x71,0x17,0x3F,0x86,0x85,0x88,0x96,0x44,0x3E,0x16, +0x05,0x44,0x49,0x00,0xBE,0x95,0x68,0x38,0x45,0x00,0x3F,0x02,0x68,0x79,0x94,0x16, +0xBF,0x04,0x92,0x78,0x90,0x80,0x3F,0x07,0x03,0x15,0x20,0x00,0xBF,0x08,0x92,0x29, +0x12,0x44,0x3F,0x11,0x08,0x40,0x09,0x11,0xBF,0x14,0x28,0x31,0x56,0x04,0x3F,0x19, +0x99,0x98,0x77,0x44,0xBF,0x33,0x33,0x33,0x31,0x13,0x3F,0x99,0x99,0x99,0x99,0x99, +0x3F,0x78,0x53,0x98,0x16,0x34,0x98,0x16,0x34,0xFC,0xE0,0x32,0x50,0xD9,0x68,0x11, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, +0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0x66,0x66,0xFF,0x66,0x00, +0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00,0x00,0x66,0x6C,0x18,0x30,0x66,0x46,0x00, +0x1C,0x36,0x1C,0x38,0x6F,0x66,0x3B,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x0E,0x1C,0x18,0x18,0x1C,0x0E,0x00,0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, +0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, +0x00,0x3C,0x66,0x6E,0x76,0x66,0x3C,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x7E,0x00, +0x00,0x3C,0x66,0x0C,0x18,0x30,0x7E,0x00,0x00,0x7E,0x0C,0x18,0x0C,0x66,0x3C,0x00, +0x00,0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x00,0x00,0x7E,0x60,0x7C,0x06,0x66,0x3C,0x00, +0x00,0x3C,0x60,0x7C,0x66,0x66,0x3C,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x30,0x00, +0x00,0x3C,0x66,0x3C,0x66,0x66,0x3C,0x00,0x00,0x3C,0x66,0x3E,0x06,0x0C,0x38,0x00, +0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, +0x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, +0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x00,0x3C,0x66,0x0C,0x18,0x00,0x18,0x00, +0x00,0x3C,0x66,0x6E,0x6E,0x60,0x3E,0x00,0x00,0x18,0x3C,0x66,0x66,0x7E,0x66,0x00, +0x00,0x7C,0x66,0x7C,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00, +0x00,0x78,0x6C,0x66,0x66,0x6C,0x78,0x00,0x00,0x7E,0x60,0x7C,0x60,0x60,0x7E,0x00, +0x00,0x7E,0x60,0x7C,0x60,0x60,0x60,0x00,0x00,0x3E,0x60,0x60,0x6E,0x66,0x3E,0x00, +0x00,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x7E,0x00, +0x00,0x06,0x06,0x06,0x06,0x66,0x3C,0x00,0x00,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00, +0x00,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x00, +0x00,0x66,0x76,0x7E,0x7E,0x6E,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3C,0x66,0x66,0x66,0x6C,0x36,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x6C,0x66,0x00,0x00,0x3C,0x60,0x3C,0x06,0x06,0x3C,0x00, +0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, +0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, +0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x18,0x00, +0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x1E,0x00, +0x00,0x40,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, +0x00,0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, +0x00,0x36,0x7F,0x7F,0x3E,0x1C,0x08,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00, +0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18, +0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03, +0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F, +0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00, +0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0, +0x00,0x1C,0x1C,0x77,0x77,0x08,0x1C,0x00,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18, +0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0x18, +0x00,0x00,0x3C,0x7E,0x7E,0x7E,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, +0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18, +0x18,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, +0x18,0x18,0x18,0x1F,0x1F,0x00,0x00,0x00,0x78,0x60,0x78,0x60,0x7E,0x18,0x1E,0x00, +0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00, +0x00,0x18,0x30,0x7E,0x30,0x18,0x00,0x00,0x00,0x18,0x0C,0x7E,0x0C,0x18,0x00,0x00, +0x00,0x18,0x3C,0x7E,0x7E,0x3C,0x18,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00, +0x00,0x60,0x60,0x7C,0x66,0x66,0x7C,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x3C,0x00, +0x00,0x06,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, +0x00,0x0E,0x18,0x3E,0x18,0x18,0x18,0x00,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x7C, +0x00,0x60,0x60,0x7C,0x66,0x66,0x66,0x00,0x00,0x18,0x00,0x38,0x18,0x18,0x3C,0x00, +0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3C,0x00,0x60,0x60,0x6C,0x78,0x6C,0x66,0x00, +0x00,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, +0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, +0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x06, +0x00,0x00,0x7C,0x66,0x60,0x60,0x60,0x00,0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, +0x00,0x18,0x7E,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x00, +0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x63,0x6B,0x7F,0x3E,0x36,0x00, +0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x3E,0x0C,0x78, +0x00,0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00,0x00,0x18,0x3C,0x7E,0x7E,0x18,0x3C,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x7E,0x78,0x7C,0x6E,0x66,0x06,0x00, +0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00,0x10,0x18,0x1C,0x1E,0x1C,0x18,0x10,0x00, +0xFB,0xF3,0x33,0xF6,0x3D,0xF6,0xA3,0xF6,0x33,0xF6,0x3C,0xF6,0x4C,0xE4,0xF3,0xF9, +0xF5,0xF3,0x33,0xF6,0x92,0xF5,0xB6,0xF5,0x33,0xF6,0xFB,0xFC,0x4C,0xE4,0xF3,0xF6, +0x33,0xF6,0x33,0xF6,0xE1,0xF6,0x3C,0xF6,0x33,0xF6,0x3C,0xF6,0x4C,0xE4,0xF3,0x00, +0x9E,0xEE,0xDB,0xEE,0x9D,0xEE,0xA6,0xEE,0x80,0xEE,0x9D,0xEE,0x4C,0x78,0xEE,0x00, +0x4B,0xEF,0x2A,0xF0,0xD5,0xEF,0x0F,0xF0,0x27,0xF0,0x4A,0xEF,0x4C,0x41,0xEF,0x00, +0x4C,0xEA,0xED,0x4C,0xF0,0xED,0x4C,0xC4,0xE4,0x4C,0x59,0xE9,0x4C,0x12,0xE9,0x4C, +0xD1,0xE7,0x4C,0x3E,0xE9,0x4C,0x44,0xE9,0x4C,0xF6,0xEB,0x4C,0xD5,0xE6,0x4C,0xA6, +0xE4,0x4C,0x23,0xF2,0x4C,0x1B,0xF1,0x4C,0x25,0xF1,0x4C,0xE9,0xEF,0x4C,0x5D,0xEF, +0xB3,0xE7,0xB2,0xE7,0xB2,0xE7,0xB2,0xE7,0xBE,0xFF,0x11,0xEB,0x90,0xEA,0xD1,0xEA, +0xB2,0xE7,0xB2,0xE7,0xB2,0xE7,0xF6,0xE6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xD1,0xE7,0x3E,0xE9,0xA2,0x00,0xA9,0xFF,0x9D,0x40,0x03,0xA9,0xC0,0x9D, +0x46,0x03,0xA9,0xE4,0x9D,0x47,0x03,0x8A,0x18,0x69,0x10,0xAA,0xC9,0x80,0x90,0xE8, +0x60,0xA0,0x85,0x60,0x85,0x2F,0x86,0x2E,0x8A,0x29,0x0F,0xD0,0x04,0xE0,0x80,0x90, +0x05,0xA0,0x86,0x4C,0x1B,0xE6,0xA0,0x00,0xBD,0x40,0x03,0x99,0x20,0x00,0xE8,0xC8, +0xC0,0x0C,0x90,0xF4,0xA0,0x84,0xA5,0x22,0xC9,0x03,0x90,0x25,0xA8,0xC0,0x0E,0x90, +0x02,0xA0,0x0E,0x84,0x17,0xB9,0xC6,0xE6,0xF0,0x0F,0xC9,0x02,0xF0,0x35,0xC9,0x08, +0xB0,0x4C,0xC9,0x04,0xF0,0x63,0x4C,0xC9,0xE5,0xA5,0x20,0xC9,0xFF,0xF0,0x05,0xA0, +0x81,0x4C,0x1B,0xE6,0x20,0x9E,0xE6,0xB0,0xF8,0x20,0x3D,0xE6,0xB0,0xF3,0x20,0x89, +0xE6,0xA9,0x0B,0x85,0x17,0x20,0x3D,0xE6,0xA5,0x2C,0x85,0x26,0xA5,0x2D,0x85,0x27, +0x4C,0x1D,0xE6,0xA0,0x01,0x84,0x23,0x20,0x3D,0xE6,0xB0,0x03,0x20,0x89,0xE6,0xA9, +0xFF,0x85,0x20,0xA9,0xE4,0x85,0x27,0xA9,0xC0,0x85,0x26,0x4C,0x1D,0xE6,0xA5,0x20, +0xC9,0xFF,0xD0,0x05,0x20,0x9E,0xE6,0xB0,0xB8,0x20,0x3D,0xE6,0x20,0x89,0xE6,0xA6, +0x2E,0xBD,0x40,0x03,0x85,0x20,0x4C,0x1D,0xE6,0xA5,0x22,0x25,0x2A,0xD0,0x05,0xA0, +0x83,0x4C,0x1B,0xE6,0x20,0x3D,0xE6,0xB0,0xF8,0xA5,0x28,0x05,0x29,0xD0,0x08,0x20, +0x89,0xE6,0x85,0x2F,0x4C,0x1D,0xE6,0x20,0x89,0xE6,0x85,0x2F,0x30,0x35,0xA0,0x00, +0x91,0x24,0x20,0x70,0xE6,0xA5,0x22,0x29,0x02,0xD0,0x0C,0xA5,0x2F,0xC9,0x9B,0xD0, +0x06,0x20,0x63,0xE6,0x4C,0xC3,0xE5,0x20,0x63,0xE6,0xD0,0xDB,0xA5,0x22,0x29,0x02, +0xD0,0x11,0x20,0x89,0xE6,0x85,0x2F,0x30,0x0A,0xA5,0x2F,0xC9,0x9B,0xD0,0xF3,0xA9, +0x89,0x85,0x23,0x20,0x77,0xE6,0x4C,0x1D,0xE6,0xA5,0x22,0x25,0x2A,0xD0,0x05,0xA0, +0x87,0x4C,0x1B,0xE6,0x20,0x3D,0xE6,0xB0,0xF8,0xA5,0x28,0x05,0x29,0xD0,0x06,0xA5, +0x2F,0xE6,0x28,0xD0,0x06,0xA0,0x00,0xB1,0x24,0x85,0x2F,0x20,0x89,0xE6,0x30,0x25, +0x20,0x70,0xE6,0xA5,0x22,0x29,0x02,0xD0,0x0C,0xA5,0x2F,0xC9,0x9B,0xD0,0x06,0x20, +0x63,0xE6,0x4C,0x15,0xE6,0x20,0x63,0xE6,0xD0,0xDB,0xA5,0x22,0x29,0x02,0xD0,0x05, +0xA9,0x9B,0x20,0x89,0xE6,0x20,0x77,0xE6,0x4C,0x1D,0xE6,0x84,0x23,0xA4,0x2E,0xB9, +0x44,0x03,0x85,0x24,0xB9,0x45,0x03,0x85,0x25,0xA2,0x00,0xB5,0x20,0x99,0x40,0x03, +0xE8,0xC8,0xE0,0x0C,0x90,0xF5,0xA5,0x2F,0xA6,0x2E,0xA4,0x23,0x60,0xA4,0x20,0xC0, +0x22,0x90,0x04,0xA0,0x85,0xB0,0x1B,0xB9,0x1B,0x03,0x85,0x2C,0xB9,0x1C,0x03,0x85, +0x2D,0xA4,0x17,0xB9,0xC6,0xE6,0xA8,0xB1,0x2C,0xAA,0xC8,0xB1,0x2C,0x85,0x2D,0x86, +0x2C,0x18,0x60,0xC6,0x28,0xA5,0x28,0xC9,0xFF,0xD0,0x02,0xC6,0x29,0x05,0x29,0x60, +0xE6,0x24,0xD0,0x02,0xE6,0x25,0x60,0xA6,0x2E,0x38,0xBD,0x48,0x03,0xE5,0x28,0x85, +0x28,0xBD,0x49,0x03,0xE5,0x29,0x85,0x29,0x60,0xA0,0x92,0x20,0x93,0xE6,0x84,0x23, +0xC0,0x00,0x60,0xAA,0xA5,0x2D,0x48,0xA5,0x2C,0x48,0x8A,0xA6,0x2E,0x60,0xA0,0x00, +0xB1,0x24,0xF0,0x0C,0xA0,0x21,0xD9,0x1A,0x03,0xF0,0x0A,0x88,0x88,0x88,0x10,0xF6, +0xA0,0x82,0x38,0xB0,0x13,0x98,0x85,0x20,0x38,0xA0,0x01,0xB1,0x24,0xE9,0x30,0xC9, +0x0A,0x90,0x02,0xA9,0x01,0x85,0x21,0x18,0x60,0x00,0x04,0x04,0x04,0x04,0x06,0x06, +0x06,0x06,0x02,0x08,0x0A,0xA9,0x40,0x8D,0x0E,0xD4,0xA9,0x38,0x8D,0x02,0xD3,0x8D, +0x03,0xD3,0xA9,0x00,0x8D,0x00,0xD3,0x8D,0x01,0xD3,0xA9,0x3C,0x8D,0x02,0xD3,0x8D, +0x03,0xD3,0x60,0x6C,0x16,0x02,0x48,0xA9,0x10,0x2C,0x0E,0xD2,0xD0,0x0D,0xA9,0xEF, +0x8D,0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x6C,0x0C,0x02,0xA9,0x20,0x2C,0x0E,0xD2, +0xD0,0x0D,0xA9,0xDF,0x8D,0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x6C,0x0A,0x02,0xA9, +0x08,0x24,0x10,0xF0,0x12,0x2C,0x0E,0xD2,0xD0,0x0D,0xA9,0xF7,0x8D,0x0E,0xD2,0xA5, +0x10,0x8D,0x0E,0xD2,0x6C,0x0E,0x02,0xAD,0x0E,0xD2,0x6A,0xB0,0x0D,0xA9,0xFE,0x8D, +0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x6C,0x10,0x02,0x6A,0xB0,0x0D,0xA9,0xFD,0x8D, +0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x6C,0x12,0x02,0x6A,0xB0,0x0A,0xA9,0xFB,0x8D, +0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x2C,0x0E,0xD2,0x70,0x0D,0xA9,0xBF,0x8D,0x0E, +0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x6C,0x08,0x02,0x30,0x18,0xA9,0x7F,0x8D,0x0E,0xD2, +0xA5,0x10,0x8D,0x0E,0xD2,0xA9,0x00,0x85,0x11,0x8D,0xFF,0x02,0x8D,0xF0,0x02,0x85, +0x4D,0x68,0x40,0x2C,0x02,0xD3,0x10,0x06,0xAD,0x00,0xD3,0x6C,0x02,0x02,0x2C,0x03, +0xD3,0x10,0x06,0xAD,0x01,0xD3,0x6C,0x04,0x02,0x08,0x68,0x29,0x10,0xF0,0x03,0x6C, +0x06,0x02,0x68,0x40,0x2C,0x0F,0xD4,0x10,0x03,0x6C,0x00,0x02,0x48,0xAD,0x0F,0xD4, +0x29,0x20,0xF0,0x03,0x4C,0x74,0xE4,0x8A,0x48,0x98,0x48,0x8D,0x0F,0xD4,0x6C,0x22, +0x02,0xE6,0x14,0xD0,0x08,0xE6,0x4D,0xE6,0x13,0xD0,0x02,0xE6,0x12,0xA9,0xFE,0xA2, +0x00,0xA4,0x4D,0x10,0x06,0x85,0x4D,0xA6,0x13,0xA9,0xF6,0x85,0x4E,0x86,0x4F,0xA2, +0x00,0x20,0xF5,0xE8,0xD0,0x03,0x20,0xEF,0xE8,0xA5,0x42,0xD0,0x08,0xBA,0xBD,0x04, +0x01,0x29,0x04,0xF0,0x03,0x4C,0x3E,0xE9,0x58,0xAD,0x0D,0xD4,0x8D,0x35,0x02,0xAD, +0x0C,0xD4,0x8D,0x34,0x02,0xAD,0x31,0x02,0x8D,0x03,0xD4,0xAD,0x30,0x02,0x8D,0x02, +0xD4,0xAD,0x2F,0x02,0x8D,0x00,0xD4,0xAD,0x6F,0x02,0x8D,0x1B,0xD0,0xA9,0x08,0x8D, +0x1F,0xD0,0xA2,0x08,0xBD,0xC0,0x02,0x45,0x4F,0x25,0x4E,0x9D,0x12,0xD0,0xCA,0x10, +0xF3,0xAD,0xF4,0x02,0x8D,0x09,0xD4,0xAD,0xF3,0x02,0x8D,0x01,0xD4,0xA2,0x02,0x20, +0xF5,0xE8,0xD0,0x03,0x20,0xF2,0xE8,0xA2,0x02,0xE8,0xE8,0xBD,0x18,0x02,0x1D,0x19, +0x02,0xF0,0x06,0x20,0xF5,0xE8,0x9D,0x26,0x02,0xE0,0x08,0xD0,0xEC,0xAD,0x0F,0xD2, +0x29,0x04,0xF0,0x08,0xAD,0xF1,0x02,0xF0,0x03,0xCE,0xF1,0x02,0xAD,0x2B,0x02,0xF0, +0x17,0xAD,0x0F,0xD2,0x29,0x04,0xD0,0x60,0xCE,0x2B,0x02,0xD0,0x0B,0xA9,0x06,0x8D, +0x2B,0x02,0xAD,0x09,0xD2,0x8D,0xFC,0x02,0xA0,0x01,0xA2,0x03,0xB9,0x00,0xD3,0x4A, +0x4A,0x4A,0x4A,0x9D,0x78,0x02,0xCA,0xB9,0x00,0xD3,0x29,0x0F,0x9D,0x78,0x02,0xCA, +0x88,0x10,0xE9,0xA2,0x03,0xBD,0x10,0xD0,0x9D,0x84,0x02,0xBD,0x00,0xD2,0x9D,0x70, +0x02,0xBD,0x04,0xD2,0x9D,0x74,0x02,0xCA,0x10,0xEB,0x8D,0x0B,0xD2,0xA2,0x06,0xA0, +0x03,0xB9,0x78,0x02,0x4A,0x4A,0x4A,0x9D,0x7D,0x02,0xA9,0x00,0x2A,0x9D,0x7C,0x02, +0xCA,0xCA,0x88,0x10,0xEC,0x6C,0x24,0x02,0xA9,0x00,0x8D,0x2B,0x02,0xF0,0xA9,0x6C, +0x26,0x02,0x6C,0x28,0x02,0xBC,0x18,0x02,0xD0,0x08,0xBC,0x19,0x02,0xF0,0x10,0xDE, +0x19,0x02,0xDE,0x18,0x02,0xD0,0x08,0xBC,0x19,0x02,0xD0,0x03,0xA9,0x00,0x60,0xA9, +0xFF,0x60,0x0A,0x8D,0x2D,0x02,0xA9,0x00,0x8D,0x0E,0xD4,0x8A,0xAE,0x2D,0x02,0x9D, +0x17,0x02,0x98,0x9D,0x16,0x02,0xA9,0x40,0x8D,0x0E,0xD4,0x2C,0x0F,0xD4,0x50,0x0D, +0xA9,0xE9,0x48,0xA9,0x3D,0x48,0x08,0x48,0x48,0x48,0x6C,0x22,0x02,0x60,0x68,0xA8, +0x68,0xAA,0x68,0x40,0xA9,0x3C,0x8D,0x02,0xD3,0xA9,0x3C,0x8D,0x03,0xD3,0xA9,0x03, +0x8D,0x32,0x02,0x85,0x41,0x8D,0x0F,0xD2,0x60,0xBA,0x8E,0x18,0x03,0xA9,0x01,0x85, +0x42,0xAD,0x00,0x03,0xC9,0x60,0xD0,0x03,0x4C,0x84,0xEB,0xA9,0x00,0x8D,0x0F,0x03, +0xA9,0x01,0x85,0x37,0xA9,0x0D,0x85,0x36,0xA9,0x28,0x8D,0x04,0xD2,0xA9,0x00,0x8D, +0x06,0xD2,0x18,0xAD,0x00,0x03,0x6D,0x01,0x03,0x69,0xFF,0x8D,0x3A,0x02,0xAD,0x02, +0x03,0x8D,0x3B,0x02,0xAD,0x0A,0x03,0x8D,0x3C,0x02,0xAD,0x0B,0x03,0x8D,0x3D,0x02, +0x18,0xA9,0x3A,0x85,0x32,0x69,0x04,0x85,0x34,0xA9,0x02,0x85,0x33,0x85,0x35,0xA9, +0x34,0x8D,0x03,0xD3,0x20,0x8E,0xEC,0xAD,0x3F,0x02,0xD0,0x03,0x98,0xD0,0x07,0xC6, +0x36,0x10,0xB5,0x4C,0x06,0xEA,0xAD,0x03,0x03,0x10,0x0C,0xA9,0x0D,0x85,0x36,0x20, +0x6E,0xEB,0x20,0x8E,0xEC,0xF0,0xE8,0x20,0x79,0xEC,0xA9,0x00,0x8D,0x3F,0x02,0x20, +0x9F,0xEC,0xF0,0x12,0x2C,0x03,0x03,0x70,0x07,0xAD,0x3F,0x02,0xD0,0x18,0xF0,0x1D, +0x20,0x6E,0xEB,0x20,0xE2,0xEA,0xAD,0x3F,0x02,0xF0,0x05,0xAD,0x19,0x03,0x85,0x30, +0xA5,0x30,0xC9,0x01,0xF0,0x07,0xC6,0x37,0x30,0x03,0x4C,0x74,0xE9,0x20,0x63,0xEC, +0xA9,0x00,0x85,0x42,0xA4,0x30,0x8C,0x03,0x03,0x60,0xA9,0x00,0x8D,0x3F,0x02,0x18, +0xA9,0x3E,0x85,0x32,0x69,0x01,0x85,0x34,0xA9,0x02,0x85,0x33,0x85,0x35,0xA9,0xFF, +0x85,0x3C,0x20,0xE2,0xEA,0xA0,0xFF,0xA5,0x30,0xC9,0x01,0xD0,0x19,0xAD,0x3E,0x02, +0xC9,0x41,0xF0,0x21,0xC9,0x43,0xF0,0x1D,0xC9,0x45,0xD0,0x06,0xA9,0x90,0x85,0x30, +0xD0,0x04,0xA9,0x8B,0x85,0x30,0xA5,0x30,0xC9,0x8A,0xF0,0x07,0xA9,0xFF,0x8D,0x3F, +0x02,0xD0,0x02,0xA0,0x00,0xA5,0x30,0x8D,0x19,0x03,0x60,0xA9,0x01,0x85,0x30,0x20, +0xF6,0xEB,0xA0,0x00,0x84,0x31,0x84,0x3B,0x84,0x3A,0xB1,0x32,0x8D,0x0D,0xD2,0x85, +0x31,0xA5,0x11,0xD0,0x03,0x4C,0xA4,0xED,0xA5,0x3A,0xF0,0xF5,0x20,0x63,0xEC,0x60, +0x98,0x48,0xE6,0x32,0xD0,0x02,0xE6,0x33,0xA5,0x33,0xC5,0x35,0x90,0x22,0xA5,0x32, +0xC5,0x34,0x90,0x1C,0xA5,0x3B,0xD0,0x0B,0xA5,0x31,0x8D,0x0D,0xD2,0xA9,0xFF,0x85, +0x3B,0xD0,0x09,0xA5,0x10,0x09,0x08,0x85,0x10,0x8D,0x0E,0xD2,0x68,0xA8,0x68,0x40, +0xA0,0x00,0xB1,0x32,0x8D,0x0D,0xD2,0x18,0x65,0x31,0x69,0x00,0x85,0x31,0x4C,0xBC, +0xEA,0xA5,0x3B,0xF0,0x0B,0x85,0x3A,0xA5,0x10,0x29,0xF7,0x85,0x10,0x8D,0x0E,0xD2, +0x68,0x40,0xA9,0x00,0xAC,0x0F,0x03,0xD0,0x02,0x85,0x31,0x85,0x38,0x85,0x39,0xA9, +0x01,0x85,0x30,0x20,0x1F,0xEC,0xA9,0x3C,0x8D,0x03,0xD3,0xA5,0x11,0xD0,0x03,0x4C, +0xA4,0xED,0xAD,0x17,0x03,0xF0,0x05,0xA5,0x39,0xF0,0xF0,0x60,0xA9,0x8A,0x85,0x30, +0x60,0x98,0x48,0xAD,0x0F,0xD2,0x8D,0x0A,0xD2,0x30,0x04,0xA0,0x8C,0x84,0x30,0x29, +0x20,0xD0,0x04,0xA0,0x8E,0x84,0x30,0xA5,0x38,0xF0,0x13,0xAD,0x0D,0xD2,0xC5,0x31, +0xF0,0x04,0xA0,0x8F,0x84,0x30,0xA9,0xFF,0x85,0x39,0x68,0xA8,0x68,0x40,0xAD,0x0D, +0xD2,0xA0,0x00,0x91,0x32,0x18,0x65,0x31,0x69,0x00,0x85,0x31,0xE6,0x32,0xD0,0x02, +0xE6,0x33,0xA5,0x33,0xC5,0x35,0x90,0xE2,0xA5,0x32,0xC5,0x34,0x90,0xDC,0xA5,0x3C, +0xF0,0x06,0xA9,0x00,0x85,0x3C,0xF0,0xCE,0xA9,0xFF,0x85,0x38,0xD0,0xCC,0x18,0xAD, +0x04,0x03,0x85,0x32,0x6D,0x08,0x03,0x85,0x34,0xAD,0x05,0x03,0x85,0x33,0x6D,0x09, +0x03,0x85,0x35,0x60,0xAD,0x03,0x03,0x10,0x2E,0xA9,0xCC,0x8D,0x04,0xD2,0xA9,0x05, +0x8D,0x06,0xD2,0x20,0xF6,0xEB,0xA0,0x0D,0xAD,0x0B,0x03,0x30,0x02,0xA0,0x96,0xA2, +0x00,0x20,0xBD,0xED,0xA9,0x34,0x8D,0x02,0xD3,0xAD,0x17,0x03,0xD0,0xFB,0x20,0x6E, +0xEB,0x20,0x6B,0xEA,0x4C,0xE3,0xEB,0xA9,0xFF,0x8D,0x0F,0x03,0xA0,0x08,0xAD,0x0B, +0x03,0x30,0x02,0xA0,0x64,0xA2,0x00,0x20,0xBD,0xED,0xA9,0x34,0x8D,0x02,0xD3,0xAD, +0x17,0x03,0xD0,0xFB,0x20,0x6E,0xEB,0x20,0x79,0xEC,0x20,0xBD,0xED,0x20,0x14,0xED, +0x20,0xE2,0xEA,0xAD,0x0B,0x03,0x30,0x05,0xA9,0x3C,0x8D,0x02,0xD3,0x4C,0x0D,0xEA, +0xA9,0x00,0x8D,0x17,0x03,0x60,0xA9,0x07,0x2D,0x32,0x02,0x09,0x20,0xAC,0x00,0x03, +0xC0,0x60,0xD0,0x0C,0x09,0x08,0xA0,0x07,0x8C,0x02,0xD2,0xA0,0x05,0x8C,0x00,0xD2, +0x8D,0x32,0x02,0x8D,0x0F,0xD2,0xA9,0xC7,0x25,0x10,0x09,0x10,0x4C,0x35,0xEC,0xA9, +0x07,0x2D,0x32,0x02,0x09,0x10,0x8D,0x32,0x02,0x8D,0x0F,0xD2,0x8D,0x0A,0xD2,0xA9, +0xC7,0x25,0x10,0x09,0x20,0x85,0x10,0x8D,0x0E,0xD2,0xA9,0x28,0x8D,0x08,0xD2,0xA2, +0x06,0xA9,0xA8,0xA4,0x41,0xD0,0x02,0xA9,0xA0,0x9D,0x01,0xD2,0xCA,0xCA,0x10,0xF9, +0xA9,0xA0,0x8D,0x05,0xD2,0xAC,0x00,0x03,0xC0,0x60,0xF0,0x06,0x8D,0x01,0xD2,0x8D, +0x03,0xD2,0x60,0xEA,0xA9,0xC7,0x25,0x10,0x85,0x10,0x8D,0x0E,0xD2,0xA2,0x06,0xA9, +0x00,0x9D,0x01,0xD2,0xCA,0xCA,0x10,0xF9,0x60,0xAD,0x06,0x03,0x6A,0x6A,0xA8,0x29, +0x3F,0xAA,0x98,0x6A,0x29,0xC0,0xA8,0x60,0x11,0xEB,0x90,0xEA,0xD1,0xEA,0xA2,0x01, +0xA0,0xFF,0x88,0xD0,0xFD,0xCA,0xD0,0xF8,0x20,0x6B,0xEA,0xA0,0x02,0xA2,0x00,0x20, +0xBD,0xED,0x20,0x1A,0xEA,0x98,0x60,0x8D,0x10,0x03,0x8C,0x11,0x03,0x20,0x08,0xED, +0x8D,0x10,0x03,0xAD,0x0C,0x03,0x20,0x08,0xED,0x8D,0x0C,0x03,0xAD,0x10,0x03,0x38, +0xED,0x0C,0x03,0x8D,0x12,0x03,0xAD,0x11,0x03,0x38,0xED,0x0D,0x03,0xA8,0xA9,0x64, +0x18,0x69,0x9C,0x88,0x10,0xFA,0x18,0x6D,0x12,0x03,0xA8,0x4A,0x4A,0x4A,0x0A,0x38, +0xE9,0x16,0xAA,0x98,0x29,0x07,0xA8,0xA9,0xF5,0x18,0x69,0x0B,0x88,0x10,0xFA,0xA0, +0x00,0x8C,0x0E,0x03,0x38,0xE9,0x07,0x10,0x03,0xCE,0x0E,0x03,0x18,0x7D,0xD2,0xED, +0xA8,0xAD,0x0E,0x03,0x7D,0xD3,0xED,0x60,0xC9,0x7C,0x30,0x04,0x38,0xE9,0x7C,0x60, +0x18,0x69,0x20,0x60,0xA5,0x11,0xD0,0x03,0x4C,0xA4,0xED,0x78,0xAD,0x17,0x03,0xD0, +0x02,0xF0,0x25,0xAD,0x0F,0xD2,0x29,0x10,0xD0,0xEA,0x8D,0x16,0x03,0xAE,0x0B,0xD4, +0xA4,0x14,0x8E,0x0C,0x03,0x8C,0x0D,0x03,0xA2,0x01,0x8E,0x15,0x03,0xA0,0x0A,0xA5, +0x11,0xF0,0x61,0xAD,0x17,0x03,0xD0,0x04,0x58,0x4C,0x0C,0xEB,0xAD,0x0F,0xD2,0x29, +0x10,0xCD,0x16,0x03,0xF0,0xE9,0x8D,0x16,0x03,0x88,0xD0,0xE3,0xCE,0x15,0x03,0x30, +0x12,0xAD,0x0B,0xD4,0xA4,0x14,0x20,0xA7,0xEC,0x8C,0xEE,0x02,0x8D,0xEF,0x02,0xA0, +0x09,0xD0,0xCC,0xAD,0xEE,0x02,0x8D,0x04,0xD2,0xAD,0xEF,0x02,0x8D,0x06,0xD2,0xA9, +0x00,0x8D,0x0F,0xD2,0xAD,0x32,0x02,0x8D,0x0F,0xD2,0xA9,0x55,0x91,0x32,0xC8,0x91, +0x32,0xA9,0xAA,0x85,0x31,0x18,0xA5,0x32,0x69,0x02,0x85,0x32,0xA5,0x33,0x69,0x00, +0x85,0x33,0x58,0x60,0x20,0x63,0xEC,0xA9,0x3C,0x8D,0x02,0xD3,0x8D,0x03,0xD3,0xA9, +0x80,0x85,0x30,0xAE,0x18,0x03,0x9A,0xC6,0x11,0x58,0x4C,0x0D,0xEA,0xA9,0xF0,0x8D, +0x26,0x02,0xA9,0xEB,0x8D,0x27,0x02,0xA9,0x01,0x8D,0x17,0x03,0x78,0x20,0x5C,0xE4, +0x58,0x60,0xE8,0x03,0x43,0x04,0x9E,0x04,0xF9,0x04,0x54,0x05,0xAF,0x05,0x0A,0x06, +0x65,0x06,0xC0,0x06,0x1A,0x07,0x75,0x07,0xD0,0x07,0xA9,0xA0,0x8D,0x46,0x02,0x60, +0xA9,0x31,0x8D,0x00,0x03,0xAD,0x46,0x02,0xAE,0x02,0x03,0xE0,0x21,0xF0,0x02,0xA9, +0x07,0x8D,0x06,0x03,0xA2,0x40,0xA0,0x80,0xAD,0x02,0x03,0xC9,0x57,0xD0,0x02,0xA2, +0x80,0xC9,0x53,0xD0,0x0C,0xA9,0xEA,0x8D,0x04,0x03,0xA9,0x02,0x8D,0x05,0x03,0xA0, +0x04,0x8E,0x03,0x03,0x8C,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0x20,0x59,0xE4,0x10, +0x01,0x60,0xAD,0x02,0x03,0xC9,0x53,0xD0,0x0A,0x20,0x6D,0xEE,0xA0,0x02,0xB1,0x15, +0x8D,0x46,0x02,0xAD,0x02,0x03,0xC9,0x21,0xD0,0x1F,0x20,0x6D,0xEE,0xA0,0xFE,0xC8, +0xC8,0xB1,0x15,0xC9,0xFF,0xD0,0xF8,0xC8,0xB1,0x15,0xC8,0xC9,0xFF,0xD0,0xF2,0x88, +0x88,0x8C,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0xAC,0x03,0x03,0x60,0xAD,0x04,0x03, +0x85,0x15,0xAD,0x05,0x03,0x85,0x16,0x60,0xA9,0x1E,0x85,0x1C,0x60,0xEA,0x02,0xC0, +0x03,0xA9,0x04,0x85,0x1E,0xAE,0x7D,0xEE,0xAC,0x7E,0xEE,0xA9,0x53,0x8D,0x02,0x03, +0x8D,0x0A,0x03,0x20,0xE6,0xEE,0x20,0x59,0xE4,0x30,0x03,0x20,0x14,0xEF,0x60,0x20, +0x81,0xEE,0xA9,0x00,0x85,0x1D,0x60,0x85,0x1F,0x20,0x1A,0xEF,0xA6,0x1D,0xA5,0x1F, +0x9D,0xC0,0x03,0xE8,0xE4,0x1E,0xF0,0x13,0x86,0x1D,0xC9,0x9B,0xF0,0x03,0xA0,0x01, +0x60,0xA9,0x20,0x9D,0xC0,0x03,0xE8,0xE4,0x1E,0xD0,0xF8,0xA9,0x00,0x85,0x1D,0xAE, +0x7F,0xEE,0xAC,0x80,0xEE,0x20,0xE6,0xEE,0x20,0x59,0xE4,0x60,0x20,0x1A,0xEF,0xA6, +0x1D,0xD0,0xDE,0xA0,0x01,0x60,0x8E,0x04,0x03,0x8C,0x05,0x03,0xA9,0x40,0x8D,0x00, +0x03,0xA9,0x01,0x8D,0x01,0x03,0xA9,0x80,0xAE,0x02,0x03,0xE0,0x53,0xD0,0x02,0xA9, +0x40,0x8D,0x03,0x03,0xA5,0x1E,0x8D,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0xA5,0x1C, +0x8D,0x06,0x03,0x60,0xAD,0xEC,0x02,0x85,0x1C,0x60,0xA0,0x57,0xA5,0x2B,0xC9,0x4E, +0xD0,0x04,0xA2,0x28,0xD0,0x0E,0xC9,0x44,0xD0,0x04,0xA2,0x14,0xD0,0x06,0xC9,0x53, +0xD0,0x0B,0xA2,0x1D,0x86,0x1E,0x8C,0x02,0x03,0x8D,0x0A,0x03,0x60,0xA9,0x4E,0xD0, +0xDD,0xA9,0xCC,0x8D,0xEE,0x02,0xA9,0x05,0x8D,0xEF,0x02,0x60,0xA5,0x2B,0x85,0x3E, +0xA5,0x2A,0x29,0x0C,0xC9,0x04,0xF0,0x05,0xC9,0x08,0xF0,0x39,0x60,0xA9,0x00,0x8D, +0x89,0x02,0x85,0x3F,0xA9,0x01,0x20,0x58,0xF0,0x30,0x24,0xA9,0x34,0x8D,0x02,0xD3, +0xA0,0xE0,0xA2,0x01,0xA9,0x03,0x8D,0x2A,0x02,0x20,0x5C,0xE4,0xAD,0x2A,0x02,0xD0, +0xFB,0xA9,0x80,0x85,0x3D,0x8D,0x8A,0x02,0x4C,0xD3,0xEF,0xA0,0x80,0xC6,0x11,0xA9, +0x00,0x8D,0x89,0x02,0x60,0xA9,0x80,0x8D,0x89,0x02,0xA9,0x02,0x20,0x58,0xF0,0x30, +0xEE,0xA9,0xCC,0x8D,0x04,0xD2,0xA9,0x05,0x8D,0x06,0xD2,0xA9,0x60,0x8D,0x00,0x03, +0x20,0x68,0xE4,0xA9,0x34,0x8D,0x02,0xD3,0xA9,0x03,0xA2,0x03,0xA0,0xC0,0x20,0x5C, +0xE4,0xA9,0xFF,0x8D,0x2A,0x02,0xA5,0x11,0xF0,0xC1,0xAD,0x2A,0x02,0xD0,0xF7,0xA9, +0x00,0x85,0x3D,0xA0,0x01,0x60,0xA5,0x3F,0x30,0x33,0xA6,0x3D,0xEC,0x8A,0x02,0xF0, +0x08,0xBD,0x00,0x04,0xE6,0x3D,0xA0,0x01,0x60,0xA9,0x52,0x20,0x95,0xF0,0x98,0x30, +0xF7,0xA9,0x00,0x85,0x3D,0xA2,0x80,0xAD,0xFF,0x03,0xC9,0xFE,0xF0,0x0D,0xC9,0xFA, +0xD0,0x03,0xAE,0x7F,0x04,0x8E,0x8A,0x02,0x4C,0xD6,0xEF,0xC6,0x3F,0xA0,0x88,0x60, +0xA6,0x3D,0x9D,0x00,0x04,0xE6,0x3D,0xA0,0x01,0xE0,0x7F,0xF0,0x01,0x60,0xA9,0xFC, +0x20,0xD2,0xF0,0xA9,0x00,0x85,0x3D,0x60,0xA0,0x01,0x60,0xAD,0x89,0x02,0x30,0x08, +0xA0,0x01,0xA9,0x3C,0x8D,0x02,0xD3,0x60,0xA6,0x3D,0xF0,0x0A,0x8E,0x7F,0x04,0xA9, +0xFA,0x20,0xD2,0xF0,0x30,0xEC,0xA2,0x7F,0xA9,0x00,0x9D,0x00,0x04,0xCA,0x10,0xFA, +0xA9,0xFE,0x20,0xD2,0xF0,0x4C,0x32,0xF0,0x85,0x40,0xA5,0x14,0x18,0x69,0x19,0xAA, +0xA9,0xFF,0x8D,0x1F,0xD0,0xA9,0x00,0xA0,0xF0,0x88,0xD0,0xFD,0x8D,0x1F,0xD0,0xA0, +0xF0,0x88,0xD0,0xFD,0xE4,0x14,0xD0,0xE8,0xC6,0x40,0xF0,0x0B,0x8A,0x18,0x69,0x08, +0xAA,0xE4,0x14,0xD0,0xFC,0xF0,0xD3,0x20,0x8C,0xF0,0x98,0x60,0xAD,0x25,0xE4,0x48, +0xAD,0x24,0xE4,0x48,0x60,0x8D,0x02,0x03,0xA9,0x00,0x8D,0x09,0x03,0xA9,0x83,0x8D, +0x08,0x03,0xA9,0x03,0x8D,0x05,0x03,0xA9,0xFD,0x8D,0x04,0x03,0xA9,0x60,0x8D,0x00, +0x03,0xA9,0x00,0x8D,0x01,0x03,0xA9,0x23,0x8D,0x06,0x03,0xAD,0x02,0x03,0xA0,0x40, +0xC9,0x52,0xF0,0x02,0xA0,0x80,0x8C,0x03,0x03,0xA5,0x3E,0x8D,0x0B,0x03,0x20,0x59, +0xE4,0x60,0x8D,0xFF,0x03,0xA9,0x55,0x8D,0xFD,0x03,0x8D,0xFE,0x03,0xA9,0x57,0x20, +0x95,0xF0,0x60,0x50,0x30,0xE4,0x43,0x40,0xE4,0x45,0x00,0xE4,0x53,0x10,0xE4,0x4B, +0x20,0xE4,0x7D,0x41,0x54,0x41,0x52,0x49,0x20,0x43,0x4F,0x4D,0x50,0x55,0x54,0x45, +0x52,0x20,0x2D,0x20,0x4D,0x45,0x4D,0x4F,0x20,0x50,0x41,0x44,0x9B,0x42,0x4F,0x4F, +0x54,0x20,0x45,0x52,0x52,0x4F,0x52,0x9B,0x45,0x3A,0x9B,0x78,0xAD,0x44,0x02,0xD0, +0x04,0xA9,0xFF,0xD0,0x03,0x78,0xA9,0x00,0x85,0x08,0xD8,0xA2,0xFF,0x9A,0x20,0x3F, +0xF2,0x20,0x81,0xF2,0xA5,0x08,0xD0,0x28,0xA9,0x00,0xA0,0x08,0x85,0x04,0x85,0x05, +0x91,0x04,0xC8,0xC0,0x00,0xD0,0xF9,0xE6,0x05,0xA6,0x05,0xE4,0x06,0xD0,0xF1,0xAD, +0x72,0xE4,0x85,0x0A,0xAD,0x73,0xE4,0x85,0x0B,0xA9,0xFF,0x8D,0x44,0x02,0xD0,0x13, +0xA2,0x00,0x8A,0x9D,0x00,0x02,0x9D,0x00,0x03,0xCA,0xD0,0xF7,0xA2,0x10,0x95,0x00, +0xE8,0x10,0xFB,0xA9,0x02,0x85,0x52,0xA9,0x27,0x85,0x53,0xA2,0x25,0xBD,0x80,0xE4, +0x9D,0x00,0x02,0xCA,0x10,0xF7,0x20,0x94,0xF2,0x58,0xA2,0x0E,0xBD,0xE3,0xF0,0x9D, +0x1A,0x03,0xCA,0x10,0xF7,0xA2,0x00,0x86,0x07,0x86,0x06,0xAE,0xE4,0x02,0xE0,0x90, +0xB0,0x0A,0xAD,0xFC,0x9F,0xD0,0x05,0xE6,0x07,0x20,0x3C,0xF2,0xAE,0xE4,0x02,0xE0, +0xB0,0xB0,0x0A,0xAE,0xFC,0xBF,0xD0,0x05,0xE6,0x06,0x20,0x39,0xF2,0xA9,0x03,0xA2, +0x00,0x9D,0x42,0x03,0xA9,0x18,0x9D,0x44,0x03,0xA9,0xF1,0x9D,0x45,0x03,0xA9,0x0C, +0x9D,0x4A,0x03,0x20,0x56,0xE4,0x10,0x03,0x4C,0x25,0xF1,0xE8,0xD0,0xFD,0xC8,0x10, +0xFA,0x20,0xB2,0xF3,0xA5,0x06,0x05,0x07,0xF0,0x12,0xA5,0x06,0xF0,0x03,0xAD,0xFD, +0xBF,0xA6,0x07,0xF0,0x03,0x0D,0xFD,0x9F,0x29,0x01,0xF0,0x03,0x20,0xCF,0xF2,0xA9, +0x00,0x8D,0x44,0x02,0xA5,0x06,0xF0,0x0A,0xAD,0xFD,0xBF,0x29,0x04,0xF0,0x03,0x6C, +0xFA,0xBF,0xA5,0x07,0xF0,0x0A,0xAD,0xFD,0x9F,0x29,0x04,0xF0,0xDF,0x6C,0xFA,0x9F, +0x6C,0x0A,0x00,0xA2,0xF2,0xA0,0xF0,0x20,0x85,0xF3,0x20,0x30,0xF2,0x4C,0x2A,0xF2, +0xAD,0x05,0xE4,0x48,0xAD,0x04,0xE4,0x48,0x60,0x6C,0xFE,0xBF,0x6C,0xFE,0x9F,0xAD, +0xFC,0xBF,0xD0,0x12,0xEE,0xFC,0xBF,0xAD,0xFC,0xBF,0xD0,0x0A,0xAD,0xFD,0xBF,0x29, +0x80,0xF0,0x03,0x6C,0xFE,0xBF,0xCE,0xFC,0xBF,0xA9,0x00,0x85,0x05,0xA9,0x10,0x85, +0x06,0xA0,0x00,0xB1,0x05,0x85,0x07,0x49,0xFF,0x85,0x04,0x91,0x05,0xB1,0x05,0xC5, +0x04,0xD0,0x0D,0xA5,0x07,0x91,0x05,0xA5,0x06,0x18,0x69,0x10,0x85,0x06,0xD0,0xE3, +0x60,0xA9,0x00,0xAA,0x9D,0x00,0xD0,0x9D,0x00,0xD4,0x9D,0x00,0xD2,0x9D,0x00,0xD3, +0xE8,0xD0,0xF1,0x60,0xC6,0x11,0xA5,0x06,0x8D,0xE4,0x02,0x8D,0xE6,0x02,0xA9,0x00, +0x8D,0xE5,0x02,0xA9,0x00,0x8D,0xE7,0x02,0xA9,0x07,0x8D,0xE8,0x02,0x20,0x0C,0xE4, +0x20,0x1C,0xE4,0x20,0x2C,0xE4,0x20,0x3C,0xE4,0x20,0x4C,0xE4,0x20,0x6E,0xE4,0x20, +0x65,0xE4,0x20,0x6B,0xE4,0xAD,0x1F,0xD0,0x29,0x01,0xD0,0x02,0xE6,0x4A,0x60,0xA5, +0x08,0xF0,0x0A,0xA5,0x09,0x29,0x01,0xF0,0x03,0x20,0x7E,0xF3,0x60,0xA9,0x01,0x8D, +0x01,0x03,0xA9,0x53,0x8D,0x02,0x03,0x20,0x53,0xE4,0x10,0x01,0x60,0xA9,0x00,0x8D, +0x0B,0x03,0xA9,0x01,0x8D,0x0A,0x03,0xA9,0x00,0x8D,0x04,0x03,0xA9,0x04,0x8D,0x05, +0x03,0x20,0x9D,0xF3,0x10,0x08,0x20,0x81,0xF3,0xA5,0x4B,0xF0,0xE0,0x60,0xA2,0x03, +0xBD,0x00,0x04,0x9D,0x40,0x02,0xCA,0x10,0xF7,0xAD,0x42,0x02,0x85,0x04,0xAD,0x43, +0x02,0x85,0x05,0xAD,0x04,0x04,0x85,0x0C,0xAD,0x05,0x04,0x85,0x0D,0xA0,0x7F,0xB9, +0x00,0x04,0x91,0x04,0x88,0x10,0xF8,0x18,0xA5,0x04,0x69,0x80,0x85,0x04,0xA5,0x05, +0x69,0x00,0x85,0x05,0xCE,0x41,0x02,0xF0,0x11,0xEE,0x0A,0x03,0x20,0x9D,0xF3,0x10, +0xDC,0x20,0x81,0xF3,0xA5,0x4B,0xD0,0xAE,0xF0,0xF2,0xA5,0x4B,0xF0,0x03,0x20,0x9D, +0xF3,0x20,0x6C,0xF3,0xB0,0xA0,0x20,0x7E,0xF3,0xE6,0x09,0x60,0x18,0xAD,0x42,0x02, +0x69,0x06,0x85,0x04,0xAD,0x43,0x02,0x69,0x00,0x85,0x05,0x6C,0x04,0x00,0x6C,0x0C, +0x00,0xA2,0x0D,0xA0,0xF1,0x8A,0xA2,0x00,0x9D,0x44,0x03,0x98,0x9D,0x45,0x03,0xA9, +0x09,0x9D,0x42,0x03,0xA9,0xFF,0x9D,0x48,0x03,0x20,0x56,0xE4,0x60,0xA5,0x4B,0xF0, +0x03,0x4C,0x7A,0xE4,0xA9,0x52,0x8D,0x02,0x03,0xA9,0x01,0x8D,0x01,0x03,0x20,0x53, +0xE4,0x60,0xA5,0x08,0xF0,0x0A,0xA5,0x09,0x29,0x02,0xF0,0x03,0x20,0xE1,0xF3,0x60, +0xA5,0x4A,0xF0,0x1C,0xA9,0x80,0x85,0x3E,0xE6,0x4B,0x20,0x7D,0xE4,0x20,0x01,0xF3, +0xA9,0x00,0x85,0x4B,0x85,0x4A,0x06,0x09,0xA5,0x0C,0x85,0x02,0xA5,0x0D,0x85,0x03, +0x60,0x6C,0x02,0x00,0xA9,0xFF,0x8D,0xFC,0x02,0xAD,0xE6,0x02,0x29,0xF0,0x85,0x6A, +0xA9,0x40,0x8D,0xBE,0x02,0x60,0xA5,0x2B,0x29,0x0F,0xD0,0x08,0xA5,0x2A,0x29,0x0F, +0x85,0x2A,0xA9,0x00,0x85,0x57,0xA9,0xE0,0x8D,0xF4,0x02,0xA9,0x02,0x8D,0xF3,0x02, +0x8D,0x2F,0x02,0xA9,0x01,0x85,0x4C,0xA9,0xC0,0x05,0x10,0x85,0x10,0x8D,0x0E,0xD2, +0xA9,0x00,0x8D,0x93,0x02,0x85,0x64,0x85,0x7B,0x8D,0xF0,0x02,0xA0,0x0E,0xA9,0x01, +0x99,0xA3,0x02,0x88,0x10,0xFA,0xA2,0x04,0xBD,0xC1,0xFE,0x9D,0xC4,0x02,0xCA,0x10, +0xF7,0xA4,0x6A,0x88,0x8C,0x95,0x02,0xA9,0x60,0x8D,0x94,0x02,0xA6,0x57,0xBD,0x69, +0xFE,0xD0,0x04,0xA9,0x91,0x85,0x4C,0x85,0x51,0xA5,0x6A,0x85,0x65,0xBC,0x45,0xFE, +0xA9,0x28,0x20,0x21,0xF9,0x88,0xD0,0xF8,0xAD,0x6F,0x02,0x29,0x3F,0x85,0x67,0xA8, +0xE0,0x08,0x90,0x17,0x8A,0x6A,0x6A,0x6A,0x29,0xC0,0x05,0x67,0xA8,0xA9,0x10,0x20, +0x21,0xF9,0xE0,0x0B,0xD0,0x05,0xA9,0x06,0x8D,0xC8,0x02,0x8C,0x6F,0x02,0xA5,0x64, +0x85,0x58,0xA5,0x65,0x85,0x59,0xAD,0x0B,0xD4,0xC9,0x7A,0xD0,0xF9,0x20,0x1F,0xF9, +0xBD,0x75,0xFE,0xF0,0x06,0xA9,0xFF,0x85,0x64,0xC6,0x65,0xA5,0x64,0x85,0x68,0xA5, +0x65,0x85,0x69,0x20,0x13,0xF9,0xA9,0x41,0x20,0x17,0xF9,0x86,0x66,0xA9,0x18,0x8D, +0xBF,0x02,0xA5,0x57,0xC9,0x09,0xB0,0x2D,0xA5,0x2A,0x29,0x10,0xF0,0x27,0xA9,0x04, +0x8D,0xBF,0x02,0xA2,0x02,0xA9,0x02,0x20,0x17,0xF9,0xCA,0x10,0xF8,0xA4,0x6A,0x88, +0x98,0x20,0x17,0xF9,0xA9,0x60,0x20,0x17,0xF9,0xA9,0x42,0x20,0x17,0xF9,0x18,0xA9, +0x0C,0x65,0x66,0x85,0x66,0xA4,0x66,0xBE,0x51,0xFE,0xA5,0x51,0x20,0x17,0xF9,0xCA, +0xD0,0xF8,0xA5,0x57,0xC9,0x08,0x90,0x1C,0xA2,0x5D,0xA5,0x6A,0x38,0xE9,0x10,0x20, +0x17,0xF9,0xA9,0x00,0x20,0x17,0xF9,0xA9,0x4F,0x20,0x17,0xF9,0xA5,0x51,0x20,0x17, +0xF9,0xCA,0xD0,0xF8,0xA5,0x59,0x20,0x17,0xF9,0xA5,0x58,0x20,0x17,0xF9,0xA5,0x51, +0x09,0x40,0x20,0x17,0xF9,0xA9,0x70,0x20,0x17,0xF9,0xA9,0x70,0x20,0x17,0xF9,0xA5, +0x64,0x8D,0x30,0x02,0xA5,0x65,0x8D,0x31,0x02,0xA9,0x70,0x20,0x17,0xF9,0xA5,0x64, +0x8D,0xE5,0x02,0xA5,0x65,0x8D,0xE6,0x02,0xA5,0x68,0x85,0x64,0xA5,0x69,0x85,0x65, +0xAD,0x31,0x02,0x20,0x17,0xF9,0xAD,0x30,0x02,0x20,0x17,0xF9,0xA5,0x4C,0x10,0x07, +0x48,0x20,0xFC,0xF3,0x68,0xA8,0x60,0xA5,0x2A,0x29,0x20,0xD0,0x0B,0x20,0xB9,0xF7, +0x8D,0x90,0x02,0xA5,0x52,0x8D,0x91,0x02,0xA9,0x22,0x0D,0x2F,0x02,0x8D,0x2F,0x02, +0x4C,0x21,0xF6,0x20,0x96,0xFA,0x20,0xA2,0xF5,0x20,0x32,0xFB,0x20,0xD4,0xF9,0x4C, +0x34,0xF6,0x20,0x47,0xF9,0xB1,0x64,0x2D,0xA0,0x02,0x46,0x6F,0xB0,0x03,0x4A,0x10, +0xF9,0x8D,0xFA,0x02,0xC9,0x00,0x60,0x8D,0xFB,0x02,0x20,0x96,0xFA,0xAD,0xFB,0x02, +0xC9,0x7D,0xD0,0x06,0x20,0xB9,0xF7,0x4C,0x21,0xF6,0xAD,0xFB,0x02,0xC9,0x9B,0xD0, +0x06,0x20,0x30,0xFA,0x4C,0x21,0xF6,0x20,0xE0,0xF5,0x20,0xD8,0xF9,0x4C,0x21,0xF6, +0xAD,0xFF,0x02,0xD0,0xFB,0xA2,0x02,0xB5,0x54,0x95,0x5A,0xCA,0x10,0xF9,0xAD,0xFB, +0x02,0xA8,0x2A,0x2A,0x2A,0x2A,0x29,0x03,0xAA,0x98,0x29,0x9F,0x1D,0xF6,0xFE,0x8D, +0xFA,0x02,0x20,0x47,0xF9,0xAD,0xFA,0x02,0x46,0x6F,0xB0,0x04,0x0A,0x4C,0x08,0xF6, +0x2D,0xA0,0x02,0x85,0x50,0xAD,0xA0,0x02,0x49,0xFF,0x31,0x64,0x05,0x50,0x91,0x64, +0x60,0x20,0xA2,0xF5,0x85,0x5D,0xA6,0x57,0xD0,0x0A,0xAE,0xF0,0x02,0xD0,0x05,0x49, +0x80,0x20,0xFF,0xF5,0xA4,0x4C,0xA9,0x01,0x85,0x4C,0xAD,0xFB,0x02,0x60,0x20,0xB3, +0xFC,0x20,0x88,0xFA,0xA5,0x6B,0xD0,0x34,0xA5,0x54,0x85,0x6C,0xA5,0x55,0x85,0x6D, +0x20,0xE2,0xF6,0x84,0x4C,0xAD,0xFB,0x02,0xC9,0x9B,0xF0,0x12,0x20,0xAD,0xF6,0x20, +0xB3,0xFC,0xA5,0x63,0xC9,0x71,0xD0,0x03,0x20,0x0A,0xF9,0x4C,0x50,0xF6,0x20,0xE4, +0xFA,0x20,0x00,0xFC,0xA5,0x6C,0x85,0x54,0xA5,0x6D,0x85,0x55,0xA5,0x6B,0xF0,0x11, +0xC6,0x6B,0xF0,0x0D,0xA5,0x4C,0x30,0xF8,0x20,0x93,0xF5,0x8D,0xFB,0x02,0x4C,0xB3, +0xFC,0x20,0x30,0xFA,0xA9,0x9B,0x8D,0xFB,0x02,0x20,0x21,0xF6,0x84,0x4C,0x4C,0xB3, +0xFC,0x6C,0x64,0x00,0x8D,0xFB,0x02,0x20,0xB3,0xFC,0x20,0x88,0xFA,0x20,0xE4,0xFA, +0x20,0x8D,0xFC,0xF0,0x09,0x0E,0xA2,0x02,0x20,0xCA,0xF5,0x4C,0xB3,0xFC,0xAD,0xFE, +0x02,0x0D,0xA2,0x02,0xD0,0xEF,0x0E,0xA2,0x02,0xE8,0xBD,0xC6,0xFE,0x85,0x64,0xBD, +0xC7,0xFE,0x85,0x65,0x20,0xA1,0xF6,0x20,0x21,0xF6,0x4C,0xB3,0xFC,0xA9,0xFF,0x8D, +0xFC,0x02,0xA5,0x2A,0x4A,0xB0,0x62,0xA9,0x80,0xA6,0x11,0xF0,0x58,0xAD,0xFC,0x02, +0xC9,0xFF,0xF0,0xEE,0x85,0x7C,0xA2,0xFF,0x8E,0xFC,0x02,0x20,0xD8,0xFC,0xAA,0xE0, +0xC0,0x90,0x02,0xA2,0x03,0xBD,0xFE,0xFE,0x8D,0xFB,0x02,0xC9,0x80,0xF0,0xCE,0xC9, +0x81,0xD0,0x0B,0xAD,0xB6,0x02,0x49,0x80,0x8D,0xB6,0x02,0x4C,0xDD,0xF6,0xC9,0x82, +0xD0,0x07,0xA9,0x00,0x8D,0xBE,0x02,0xF0,0xB4,0xC9,0x83,0xD0,0x07,0xA9,0x40,0x8D, +0xBE,0x02,0xD0,0xA9,0xC9,0x84,0xD0,0x07,0xA9,0x80,0x8D,0xBE,0x02,0xD0,0x9E,0xC9, +0x85,0xD0,0x0A,0xA9,0x88,0x85,0x4C,0x85,0x11,0xA9,0x9B,0xD0,0x26,0xA5,0x7C,0xC9, +0x40,0xB0,0x15,0xAD,0xFB,0x02,0xC9,0x61,0x90,0x0E,0xC9,0x7B,0xB0,0x0A,0xAD,0xBE, +0x02,0xF0,0x05,0x05,0x7C,0x4C,0xFE,0xF6,0x20,0x8D,0xFC,0xF0,0x09,0xAD,0xFB,0x02, +0x4D,0xB6,0x02,0x8D,0xFB,0x02,0x4C,0x34,0xF6,0xA9,0x80,0x8D,0xA2,0x02,0x60,0xC6, +0x54,0x10,0x06,0xAE,0xBF,0x02,0xCA,0x86,0x54,0x4C,0x5C,0xFC,0xE6,0x54,0xA5,0x54, +0xCD,0xBF,0x02,0x90,0xF4,0xA2,0x00,0xF0,0xEE,0xC6,0x55,0xA5,0x55,0x30,0x04,0xC5, +0x52,0xB0,0x04,0xA5,0x53,0x85,0x55,0x4C,0xDD,0xFB,0xE6,0x55,0xA5,0x55,0xC5,0x53, +0x90,0xF5,0xF0,0xF3,0xA5,0x52,0x4C,0xA5,0xF7,0x20,0xF3,0xFC,0xA0,0x00,0x98,0x91, +0x64,0xC8,0xD0,0xFB,0xE6,0x65,0xA6,0x65,0xE4,0x6A,0x90,0xF3,0xA9,0xFF,0x99,0xB2, +0x02,0xC8,0xC0,0x04,0x90,0xF8,0x20,0xE4,0xFC,0x85,0x63,0x85,0x6D,0xA9,0x00,0x85, +0x54,0x85,0x56,0x85,0x6C,0x60,0xA5,0x63,0xC5,0x52,0xF0,0x21,0xA5,0x55,0xC5,0x52, +0xD0,0x03,0x20,0x73,0xFC,0x20,0x99,0xF7,0xA5,0x55,0xC5,0x53,0xD0,0x07,0xA5,0x54, +0xF0,0x03,0x20,0x7F,0xF7,0xA9,0x20,0x8D,0xFB,0x02,0x20,0xE0,0xF5,0x4C,0xDD,0xFB, +0x20,0xAA,0xF7,0xA5,0x55,0xC5,0x52,0xD0,0x0A,0x20,0x34,0xFA,0x20,0x20,0xFB,0x90, +0x02,0xB0,0x07,0xA5,0x63,0x20,0x25,0xFB,0x90,0xE6,0x4C,0xDD,0xFB,0xA5,0x63,0x4C, +0x06,0xFB,0xA5,0x63,0x4C,0x12,0xFB,0x20,0x9D,0xFC,0x20,0xA2,0xF5,0x85,0x7D,0xA9, +0x00,0x8D,0xBB,0x02,0x20,0xFF,0xF5,0xA5,0x63,0x48,0x20,0xDC,0xF9,0x68,0xC5,0x63, +0xB0,0x0C,0xA5,0x7D,0x48,0x20,0xA2,0xF5,0x85,0x7D,0x68,0x4C,0x44,0xF8,0x20,0xA8, +0xFC,0xCE,0xBB,0x02,0x30,0x04,0xC6,0x54,0xD0,0xF7,0x4C,0xDD,0xFB,0x20,0x9D,0xFC, +0x20,0x47,0xF9,0xA5,0x64,0x85,0x68,0xA5,0x65,0x85,0x69,0xA5,0x63,0x48,0x20,0xD4, +0xF9,0x68,0xC5,0x63,0xB0,0x10,0xA5,0x54,0xCD,0xBF,0x02,0xB0,0x09,0x20,0xA2,0xF5, +0xA0,0x00,0x91,0x68,0xF0,0xDA,0xA0,0x00,0x98,0x91,0x68,0x20,0x68,0xFC,0x20,0xA8, +0xFC,0x4C,0xDD,0xFB,0x38,0x20,0x7B,0xFB,0xA5,0x52,0x85,0x55,0x20,0x47,0xF9,0xA5, +0x64,0x85,0x68,0x18,0x69,0x28,0x85,0x66,0xA5,0x65,0x85,0x69,0x69,0x00,0x85,0x67, +0xA6,0x54,0xE0,0x17,0xF0,0x08,0x20,0x4E,0xFB,0xE8,0xE0,0x17,0xD0,0xF8,0x20,0x9B, +0xFB,0x4C,0xDD,0xFB,0x20,0xDD,0xFB,0xA4,0x51,0x84,0x54,0xA4,0x54,0x98,0x38,0x20, +0x23,0xFB,0x08,0x98,0x18,0x69,0x78,0x28,0x20,0x04,0xFB,0xC8,0xC0,0x18,0xD0,0xED, +0xAD,0xB4,0x02,0x09,0x01,0x8D,0xB4,0x02,0xA5,0x52,0x85,0x55,0x20,0x47,0xF9,0x20, +0xB7,0xFB,0x20,0x20,0xFB,0x90,0xD4,0x4C,0xDD,0xFB,0xA0,0x20,0x20,0xD8,0xFC,0x88, +0x10,0xFA,0x60,0xA9,0x02,0xD0,0x0A,0xA4,0x4C,0x30,0x2B,0xA0,0x00,0x91,0x64,0xA9, +0x01,0x8D,0x9E,0x02,0xA5,0x4C,0x30,0x1E,0xA5,0x64,0x38,0xED,0x9E,0x02,0x85,0x64, +0xB0,0x02,0xC6,0x65,0xA5,0x0F,0xC5,0x65,0x90,0x0C,0xD0,0x06,0xA5,0x0E,0xC5,0x64, +0x90,0x04,0xA9,0x93,0x85,0x4C,0x60,0xA5,0x54,0x48,0xA5,0x55,0x48,0xA5,0x56,0x48, +0x20,0xF3,0xFC,0xA5,0x54,0x85,0x66,0xA9,0x00,0x85,0x67,0xA5,0x66,0x0A,0x26,0x67, +0x85,0x51,0xA4,0x67,0x8C,0x9F,0x02,0x0A,0x26,0x67,0x0A,0x26,0x67,0x18,0x65,0x51, +0x85,0x66,0xA5,0x67,0x6D,0x9F,0x02,0x85,0x67,0xA6,0x57,0xBC,0x81,0xFE,0x88,0x30, +0x07,0x06,0x66,0x26,0x67,0x4C,0x7E,0xF9,0xBC,0xA5,0xFE,0xA5,0x55,0xA2,0x07,0x88, +0x30,0x0A,0xCA,0x46,0x56,0x6A,0x6E,0xA1,0x02,0x4C,0x8F,0xF9,0xC8,0x18,0x65,0x66, +0x85,0x66,0x90,0x02,0xE6,0x67,0x38,0x6E,0xA1,0x02,0x18,0xCA,0x10,0xF9,0xAE,0xA1, +0x02,0xA5,0x66,0x18,0x65,0x64,0x85,0x64,0x85,0x5E,0xA5,0x67,0x65,0x65,0x85,0x65, +0x85,0x5F,0xBD,0xB1,0xFE,0x8D,0xA0,0x02,0x85,0x6F,0x68,0x85,0x56,0x68,0x85,0x55, +0x68,0x85,0x54,0x60,0xA9,0x00,0xF0,0x02,0xA9,0x9B,0x85,0x7D,0xE6,0x63,0xE6,0x55, +0xD0,0x02,0xE6,0x56,0xA5,0x55,0xA6,0x57,0xDD,0x8D,0xFE,0xF0,0x0B,0xE0,0x00,0xD0, +0x06,0xC5,0x53,0xF0,0x02,0xB0,0x01,0x60,0xE0,0x08,0x90,0x04,0xA5,0x56,0xF0,0xF7, +0xA5,0x57,0xD0,0x30,0xA5,0x63,0xC9,0x51,0x90,0x0A,0xA5,0x7D,0xF0,0x26,0x20,0x30, +0xFA,0x4C,0x77,0xFA,0x20,0x34,0xFA,0xA5,0x54,0x18,0x69,0x78,0x20,0x25,0xFB,0x90, +0x08,0xA5,0x7D,0xF0,0x04,0x18,0x20,0xA5,0xF8,0x4C,0xDD,0xFB,0xA9,0x00,0xF0,0x02, +0xA9,0x9B,0x85,0x7D,0x20,0xE4,0xFC,0xA9,0x00,0x85,0x56,0xE6,0x54,0xA6,0x57,0xA0, +0x18,0x24,0x7B,0x10,0x05,0xA0,0x04,0x98,0xD0,0x03,0xBD,0x99,0xFE,0xC5,0x54,0xD0, +0x26,0x8C,0x9D,0x02,0x8A,0xD0,0x20,0xA5,0x7D,0xF0,0x1C,0xC9,0x9B,0x38,0xF0,0x01, +0x18,0x20,0xAC,0xFB,0xEE,0xBB,0x02,0xC6,0x6C,0xCE,0x9D,0x02,0xAD,0xB2,0x02,0x38, +0x10,0xEF,0xAD,0x9D,0x02,0x85,0x54,0x4C,0xDD,0xFB,0x38,0xB5,0x70,0xE5,0x74,0x95, +0x70,0xB5,0x71,0xE5,0x75,0x95,0x71,0x60,0xAD,0xBF,0x02,0xC9,0x04,0xF0,0x07,0xA5, +0x57,0xF0,0x03,0x20,0xFC,0xF3,0xA9,0x27,0xC5,0x53,0xB0,0x02,0x85,0x53,0xA6,0x57, +0xBD,0x99,0xFE,0xC5,0x54,0x90,0x2A,0xF0,0x28,0xE0,0x08,0xD0,0x0A,0xA5,0x56,0xF0, +0x13,0xC9,0x01,0xD0,0x1C,0xF0,0x04,0xA5,0x56,0xD0,0x16,0xBD,0x8D,0xFE,0xC5,0x55, +0x90,0x0F,0xF0,0x0D,0xA9,0x01,0x85,0x4C,0xA9,0x80,0xA6,0x11,0x85,0x11,0xF0,0x06, +0x60,0x20,0xD6,0xF7,0xA9,0x8D,0x85,0x4C,0x68,0x68,0xA5,0x7B,0x10,0x03,0x20,0xB9, +0xFC,0x4C,0x34,0xF6,0xA0,0x00,0xA5,0x5D,0x91,0x5E,0x60,0x48,0x29,0x07,0xAA,0xBD, +0xB9,0xFE,0x85,0x6E,0x68,0x4A,0x4A,0x4A,0xAA,0x60,0x2E,0xB4,0x02,0x2E,0xB3,0x02, +0x2E,0xB2,0x02,0x60,0x90,0x0C,0x20,0xEB,0xFA,0xBD,0xA3,0x02,0x05,0x6E,0x9D,0xA3, +0x02,0x60,0x20,0xEB,0xFA,0xA5,0x6E,0x49,0xFF,0x3D,0xA3,0x02,0x9D,0xA3,0x02,0x60, +0xA5,0x54,0x18,0x69,0x78,0x20,0xEB,0xFA,0x18,0xBD,0xA3,0x02,0x25,0x6E,0xF0,0x01, +0x38,0x60,0xAD,0xFA,0x02,0xA4,0x57,0xC0,0x03,0xB0,0x0F,0x2A,0x2A,0x2A,0x2A,0x29, +0x03,0xAA,0xAD,0xFA,0x02,0x29,0x9F,0x1D,0xFA,0xFE,0x8D,0xFB,0x02,0x60,0xA9,0x02, +0x85,0x65,0xA9,0x47,0x85,0x64,0xA0,0x27,0xB1,0x66,0x85,0x50,0xB1,0x68,0x91,0x66, +0xA5,0x50,0x91,0x64,0x88,0x10,0xF1,0xA5,0x65,0x85,0x69,0xA5,0x64,0x85,0x68,0x18, +0xA5,0x66,0x69,0x28,0x85,0x66,0x90,0x02,0xE6,0x67,0x60,0x08,0xA0,0x17,0x98,0x20, +0x22,0xFB,0x08,0x98,0x18,0x69,0x79,0x28,0x20,0x04,0xFB,0x88,0x30,0x04,0xC4,0x54, +0xB0,0xEC,0xA5,0x54,0x18,0x69,0x78,0x28,0x4C,0x04,0xFB,0xA5,0x52,0x85,0x55,0x20, +0x47,0xF9,0xA0,0x27,0xA9,0x00,0x91,0x64,0x88,0x10,0xFB,0x60,0x20,0xFA,0xFA,0xA5, +0x58,0x85,0x64,0xA5,0x59,0x85,0x65,0xA0,0x28,0xB1,0x64,0xA6,0x6A,0xCA,0xE4,0x65, +0xD0,0x08,0xA2,0xD7,0xE4,0x64,0xB0,0x02,0xA9,0x00,0xA0,0x00,0x91,0x64,0xE6,0x64, +0xD0,0xE5,0xE6,0x65,0xA5,0x65,0xC5,0x6A,0xD0,0xDD,0x4C,0xDD,0xFB,0xA9,0x00,0x85, +0x63,0xA5,0x54,0x85,0x51,0xA5,0x51,0x20,0x22,0xFB,0xB0,0x0C,0xA5,0x63,0x18,0x69, +0x28,0x85,0x63,0xC6,0x51,0x4C,0xE5,0xFB,0x18,0xA5,0x63,0x65,0x55,0x85,0x63,0x60, +0x20,0x9D,0xFC,0xA5,0x63,0x48,0xA5,0x6C,0x85,0x54,0xA5,0x6D,0x85,0x55,0xA9,0x01, +0x85,0x6B,0xA2,0x17,0xA5,0x7B,0x10,0x02,0xA2,0x03,0xE4,0x54,0xD0,0x0B,0xA5,0x55, +0xC5,0x53,0xD0,0x05,0xE6,0x6B,0x4C,0x39,0xFC,0x20,0xD4,0xF9,0xE6,0x6B,0xA5,0x63, +0xC5,0x52,0xD0,0xDE,0xC6,0x54,0x20,0x99,0xF7,0x20,0xA2,0xF5,0xD0,0x17,0xC6,0x6B, +0xA5,0x63,0xC5,0x52,0xF0,0x0F,0x20,0x99,0xF7,0xA5,0x55,0xC5,0x53,0xD0,0x02,0xC6, +0x54,0xA5,0x6B,0xD0,0xE4,0x68,0x85,0x63,0x20,0xA8,0xFC,0x60,0x20,0xDD,0xFB,0xA5, +0x51,0x85,0x6C,0xA5,0x52,0x85,0x6D,0x60,0xA5,0x63,0xC5,0x52,0xD0,0x02,0xC6,0x54, +0x20,0xDD,0xFB,0xA5,0x63,0xC5,0x52,0xF0,0x13,0x20,0x47,0xF9,0xA5,0x53,0x38,0xE5, +0x52,0xA8,0xB1,0x64,0xD0,0x06,0x88,0x10,0xF9,0x4C,0xDB,0xF8,0x60,0xA2,0x2D,0xBD, +0xC6,0xFE,0xCD,0xFB,0x02,0xF0,0x05,0xCA,0xCA,0xCA,0x10,0xF3,0x60,0xA2,0x02,0xB5, +0x54,0x9D,0xB8,0x02,0xCA,0x10,0xF8,0x60,0xA2,0x02,0xBD,0xB8,0x02,0x95,0x54,0xCA, +0x10,0xF8,0x60,0x20,0xB9,0xFC,0x4C,0x34,0xF6,0xAD,0xBF,0x02,0xC9,0x18,0xF0,0x17, +0xA2,0x0B,0xB5,0x54,0x48,0xBD,0x90,0x02,0x95,0x54,0x68,0x9D,0x90,0x02,0xCA,0x10, +0xF1,0xA5,0x7B,0x49,0xFF,0x85,0x7B,0x60,0xA2,0x7F,0x8E,0x1F,0xD0,0x8E,0x0A,0xD4, +0xCA,0x10,0xF7,0x60,0xA9,0x00,0xA6,0x7B,0xD0,0x04,0xA6,0x57,0xD0,0x02,0xA5,0x52, +0x85,0x55,0x60,0xA5,0x58,0x85,0x64,0xA5,0x59,0x85,0x65,0x60,0xA2,0x00,0xA5,0x22, +0xC9,0x11,0xF0,0x08,0xC9,0x12,0xF0,0x03,0xA0,0x84,0x60,0xE8,0x8E,0xB7,0x02,0xA5, +0x54,0x85,0x60,0xA5,0x55,0x85,0x61,0xA5,0x56,0x85,0x62,0xA9,0x01,0x85,0x79,0x85, +0x7A,0x38,0xA5,0x60,0xE5,0x5A,0x85,0x76,0xB0,0x0D,0xA9,0xFF,0x85,0x79,0xA5,0x76, +0x49,0xFF,0x18,0x69,0x01,0x85,0x76,0x38,0xA5,0x61,0xE5,0x5B,0x85,0x77,0xA5,0x62, +0xE5,0x5C,0x85,0x78,0xB0,0x16,0xA9,0xFF,0x85,0x7A,0xA5,0x77,0x49,0xFF,0x85,0x77, +0xA5,0x78,0x49,0xFF,0x85,0x78,0xE6,0x77,0xD0,0x02,0xE6,0x78,0xA2,0x02,0xA0,0x00, +0x84,0x73,0x98,0x95,0x70,0xB5,0x5A,0x95,0x54,0xCA,0x10,0xF6,0xA5,0x77,0xE8,0xA8, +0xA5,0x78,0x85,0x7F,0x85,0x75,0xD0,0x0B,0xA5,0x77,0xC5,0x76,0xB0,0x05,0xA5,0x76, +0xA2,0x02,0xA8,0x98,0x85,0x7E,0x85,0x74,0x48,0xA5,0x75,0x4A,0x68,0x6A,0x95,0x70, +0xA5,0x7E,0x05,0x7F,0xD0,0x03,0x4C,0x42,0xFE,0x18,0xA5,0x70,0x65,0x76,0x85,0x70, +0x90,0x02,0xE6,0x71,0xA5,0x71,0xC5,0x75,0x90,0x14,0xD0,0x06,0xA5,0x70,0xC5,0x74, +0x90,0x0C,0x18,0xA5,0x54,0x65,0x79,0x85,0x54,0xA2,0x00,0x20,0x7A,0xFA,0x18,0xA5, +0x72,0x65,0x77,0x85,0x72,0xA5,0x73,0x65,0x78,0x85,0x73,0xC5,0x75,0x90,0x27,0xD0, +0x06,0xA5,0x72,0xC5,0x74,0x90,0x1F,0x24,0x7A,0x10,0x10,0xC6,0x55,0xA5,0x55,0xC9, +0xFF,0xD0,0x0E,0xA5,0x56,0xF0,0x0A,0xC6,0x56,0x10,0x06,0xE6,0x55,0xD0,0x02,0xE6, +0x56,0xA2,0x02,0x20,0x7A,0xFA,0x20,0x96,0xFA,0x20,0xE0,0xF5,0xAD,0xB7,0x02,0xF0, +0x2F,0x20,0x9D,0xFC,0xAD,0xFB,0x02,0x8D,0xBC,0x02,0xA5,0x54,0x48,0x20,0xDC,0xF9, +0x68,0x85,0x54,0x20,0x96,0xFA,0x20,0xA2,0xF5,0xD0,0x0C,0xAD,0xFD,0x02,0x8D,0xFB, +0x02,0x20,0xE0,0xF5,0x4C,0x0A,0xFE,0xAD,0xBC,0x02,0x8D,0xFB,0x02,0x20,0xA8,0xFC, +0x38,0xA5,0x7E,0xE9,0x01,0x85,0x7E,0xA5,0x7F,0xE9,0x00,0x85,0x7F,0x30,0x03,0x4C, +0x90,0xFD,0x4C,0x34,0xF6,0x18,0x10,0x0A,0x0A,0x10,0x1C,0x34,0x64,0xC4,0xC4,0xC4, +0xC4,0x17,0x17,0x0B,0x17,0x2F,0x2F,0x5F,0x5F,0x61,0x61,0x61,0x61,0x13,0x13,0x09, +0x13,0x27,0x27,0x4F,0x4F,0x41,0x41,0x41,0x41,0x02,0x06,0x07,0x08,0x09,0x0A,0x0B, +0x0D,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01, +0x01,0x02,0x01,0x01,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x28,0x14,0x14, +0x28,0x50,0x50,0xA0,0xA0,0x40,0x50,0x50,0x50,0x18,0x18,0x0C,0x18,0x30,0x30,0x60, +0x60,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x02,0x03,0x02,0x03,0x02,0x03,0x01,0x01, +0x01,0x00,0xFF,0xF0,0x0F,0xC0,0x30,0x0C,0x03,0x80,0x40,0x20,0x10,0x08,0x04,0x02, +0x01,0x28,0xCA,0x94,0x46,0x00,0x1B,0x79,0xF7,0x1C,0x7F,0xF7,0x1D,0x8C,0xF7,0x1E, +0x99,0xF7,0x1F,0xAA,0xF7,0x7D,0xB9,0xF7,0x7E,0xE6,0xF7,0x7F,0x10,0xF8,0x9B,0x30, +0xFA,0x9C,0xD4,0xF8,0x9D,0xA4,0xF8,0x9E,0x32,0xF8,0x9F,0x2D,0xF8,0xFD,0x0A,0xF9, +0xFE,0x6D,0xF8,0xFF,0x37,0xF8,0x40,0x00,0x20,0x60,0x20,0x40,0x00,0x60,0x6C,0x6A, +0x3B,0x80,0x80,0x6B,0x2B,0x2A,0x6F,0x80,0x70,0x75,0x9B,0x69,0x2D,0x3D,0x76,0x80, +0x63,0x80,0x80,0x62,0x78,0x7A,0x34,0x80,0x33,0x36,0x1B,0x35,0x32,0x31,0x2C,0x20, +0x2E,0x6E,0x80,0x6D,0x2F,0x81,0x72,0x80,0x65,0x79,0x7F,0x74,0x77,0x71,0x39,0x80, +0x30,0x37,0x7E,0x38,0x3C,0x3E,0x66,0x68,0x64,0x80,0x82,0x67,0x73,0x61,0x4C,0x4A, +0x3A,0x80,0x80,0x4B,0x5C,0x5E,0x4F,0x80,0x50,0x55,0x9B,0x49,0x5F,0x7C,0x56,0x80, +0x43,0x80,0x80,0x42,0x58,0x5A,0x24,0x80,0x23,0x26,0x1B,0x25,0x22,0x21,0x5B,0x20, +0x5D,0x4E,0x80,0x4D,0x3F,0x81,0x52,0x80,0x45,0x59,0x9F,0x54,0x57,0x51,0x28,0x80, +0x29,0x27,0x9C,0x40,0x7D,0x9D,0x46,0x48,0x44,0x80,0x83,0x47,0x53,0x41,0x0C,0x0A, +0x7B,0x80,0x80,0x0B,0x1E,0x1F,0x0F,0x80,0x10,0x15,0x9B,0x09,0x1C,0x1D,0x16,0x80, +0x03,0x80,0x80,0x02,0x18,0x1A,0x80,0x80,0x85,0x80,0x1B,0x80,0xFD,0x80,0x00,0x20, +0x60,0x0E,0x80,0x0D,0x80,0x81,0x12,0x80,0x05,0x19,0x9E,0x14,0x17,0x11,0x80,0x80, +0x80,0x80,0xFE,0x80,0x7D,0xFF,0x06,0x08,0x04,0x80,0x84,0x07,0x13,0x01,0xAD,0x09, +0xD2,0xCD,0xF2,0x02,0xD0,0x05,0xAD,0xF1,0x02,0xD0,0x20,0xAD,0x09,0xD2,0xC9,0x9F, +0xD0,0x0A,0xAD,0xFF,0x02,0x49,0xFF,0x8D,0xFF,0x02,0xB0,0x0F,0x8D,0xFC,0x02,0x8D, +0xF2,0x02,0xA9,0x03,0x8D,0xF1,0x02,0xA9,0x00,0x85,0x4D,0xA9,0x30,0x8D,0x2B,0x02, +0x68,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x57,0xB4,0xE7,0x77,0xE4,0xF3,0xE6, +}; diff --git a/MCUME_teensy41/teensy800/romatariosb.h b/MCUME_teensy41/teensy800/romatariosb.h new file mode 100644 index 0000000..c0691f9 --- /dev/null +++ b/MCUME_teensy41/teensy800/romatariosb.h @@ -0,0 +1,642 @@ +const UBYTE PROGMEM romos[10240] = { +0x20,0xA1,0xDB,0x20,0xBB,0xDB,0xB0,0x39,0xA2,0xED,0xA0,0x04,0x20,0x48,0xDA,0xA2, +0xFF,0x86,0xF1,0x20,0x44,0xDA,0xF0,0x04,0xA9,0xFF,0x85,0xF0,0x20,0x94,0xDB,0xB0, +0x21,0x48,0xA6,0xD5,0xD0,0x11,0x20,0xEB,0xDB,0x68,0x05,0xD9,0x85,0xD9,0xA6,0xF1, +0x30,0xE6,0xE8,0x86,0xF1,0xD0,0xE1,0x68,0xA6,0xF1,0x10,0x02,0xE6,0xED,0x4C,0x18, +0xD8,0x60,0xC9,0x2E,0xF0,0x14,0xC9,0x45,0xF0,0x19,0xA6,0xF0,0xD0,0x68,0xC9,0x2B, +0xF0,0xC6,0xC9,0x2D,0xF0,0x00,0x85,0xEE,0xF0,0xBE,0xA6,0xF1,0x10,0x58,0xE8,0x86, +0xF1,0xF0,0xB5,0xA5,0xF2,0x85,0xEC,0x20,0x94,0xDB,0xB0,0x37,0xAA,0xA5,0xED,0x48, +0x86,0xED,0x20,0x94,0xDB,0xB0,0x17,0x48,0xA5,0xED,0x0A,0x85,0xED,0x0A,0x0A,0x65, +0xED,0x85,0xED,0x68,0x18,0x65,0xED,0x85,0xED,0xA4,0xF2,0x20,0x9D,0xDB,0xA5,0xEF, +0xF0,0x09,0xA5,0xED,0x49,0xFF,0x18,0x69,0x01,0x85,0xED,0x68,0x18,0x65,0xED,0x85, +0xED,0xD0,0x13,0xC9,0x2B,0xF0,0x06,0xC9,0x2D,0xD0,0x07,0x85,0xEF,0x20,0x94,0xDB, +0x90,0xBA,0xA5,0xEC,0x85,0xF2,0xC6,0xF2,0xA5,0xED,0xA6,0xF1,0x30,0x05,0xF0,0x03, +0x38,0xE5,0xF1,0x48,0x2A,0x68,0x6A,0x85,0xED,0x90,0x03,0x20,0xEB,0xDB,0xA5,0xED, +0x18,0x69,0x44,0x85,0xD4,0x20,0x00,0xDC,0xB0,0x0B,0xA6,0xEE,0xF0,0x06,0xA5,0xD4, +0x09,0x80,0x85,0xD4,0x18,0x60,0x20,0x51,0xDA,0xA9,0x30,0x8D,0x7F,0x05,0xA5,0xD4, +0xF0,0x28,0x29,0x7F,0xC9,0x3F,0x90,0x28,0xC9,0x45,0xB0,0x24,0x38,0xE9,0x3F,0x20, +0x70,0xDC,0x20,0xA4,0xDC,0x09,0x80,0x9D,0x80,0x05,0xAD,0x80,0x05,0xC9,0x2E,0xF0, +0x03,0x4C,0x88,0xD9,0x20,0xC1,0xDC,0x4C,0x9C,0xD9,0xA9,0xB0,0x8D,0x80,0x05,0x60, +0xA9,0x01,0x20,0x70,0xDC,0x20,0xA4,0xDC,0xE8,0x86,0xF2,0xA5,0xD4,0x0A,0x38,0xE9, +0x80,0xAE,0x80,0x05,0xE0,0x30,0xF0,0x17,0xAE,0x81,0x05,0xAC,0x82,0x05,0x8E,0x82, +0x05,0x8C,0x81,0x05,0xA6,0xF2,0xE0,0x02,0xD0,0x02,0xE6,0xF2,0x18,0x69,0x01,0x85, +0xED,0xA9,0x45,0xA4,0xF2,0x20,0x9F,0xDC,0x84,0xF2,0xA5,0xED,0x10,0x0B,0xA9,0x00, +0x38,0xE5,0xED,0x85,0xED,0xA9,0x2D,0xD0,0x02,0xA9,0x2B,0x20,0x9F,0xDC,0xA2,0x00, +0xA5,0xED,0x38,0xE9,0x0A,0x90,0x03,0xE8,0xD0,0xF8,0x18,0x69,0x0A,0x48,0x8A,0x20, +0x9D,0xDC,0x68,0x09,0x80,0x20,0x9D,0xDC,0xAD,0x80,0x05,0xC9,0x30,0xD0,0x0D,0x18, +0xA5,0xF3,0x69,0x01,0x85,0xF3,0xA5,0xF4,0x69,0x00,0x85,0xF4,0xA5,0xD4,0x10,0x09, +0x20,0xC1,0xDC,0xA0,0x00,0xA9,0x2D,0x91,0xF3,0x60,0xA5,0xD4,0x85,0xF8,0xA5,0xD5, +0x85,0xF7,0x20,0x44,0xDA,0xF8,0xA0,0x10,0x06,0xF8,0x26,0xF7,0xA2,0x03,0xB5,0xD4, +0x75,0xD4,0x95,0xD4,0xCA,0xD0,0xF7,0x88,0xD0,0xEE,0xD8,0xA9,0x42,0x85,0xD4,0x4C, +0x00,0xDC,0xA9,0x00,0x85,0xF7,0x85,0xF8,0xA5,0xD4,0x30,0x66,0xC9,0x43,0xB0,0x62, +0x38,0xE9,0x40,0x90,0x3F,0x69,0x00,0x0A,0x85,0xF5,0x20,0x5A,0xDA,0xB0,0x53,0xA5, +0xF7,0x85,0xF9,0xA5,0xF8,0x85,0xFA,0x20,0x5A,0xDA,0xB0,0x46,0x20,0x5A,0xDA,0xB0, +0x41,0x18,0xA5,0xF8,0x65,0xFA,0x85,0xF8,0xA5,0xF7,0x65,0xF9,0x85,0xF7,0xB0,0x32, +0x20,0xB9,0xDC,0x18,0x65,0xF8,0x85,0xF8,0xA5,0xF7,0x69,0x00,0xB0,0x24,0x85,0xF7, +0xC6,0xF5,0xD0,0xC6,0x20,0xB9,0xDC,0xC9,0x05,0x90,0x0D,0x18,0xA5,0xF8,0x69,0x01, +0x85,0xF8,0xA5,0xF7,0x69,0x00,0x85,0xF7,0xA5,0xF8,0x85,0xD4,0xA5,0xF7,0x85,0xD5, +0x18,0x60,0x38,0x60,0xA2,0xD4,0xA0,0x06,0xA9,0x00,0x95,0x00,0xE8,0x88,0xD0,0xFA, +0x60,0xA9,0x05,0x85,0xF4,0xA9,0x80,0x85,0xF3,0x60,0x18,0x26,0xF8,0x26,0xF7,0x60, +0xA5,0xE0,0x49,0x80,0x85,0xE0,0xA5,0xE0,0x29,0x7F,0x85,0xF7,0xA5,0xD4,0x29,0x7F, +0x38,0xE5,0xF7,0x10,0x10,0xA2,0x05,0xB5,0xD4,0xB4,0xE0,0x95,0xE0,0x98,0x95,0xD4, +0xCA,0x10,0xF4,0x30,0xE1,0xF0,0x07,0xC9,0x05,0xB0,0x19,0x20,0x3E,0xDC,0xF8,0xA5, +0xD4,0x45,0xE0,0x30,0x1E,0xA2,0x04,0x18,0xB5,0xD5,0x75,0xE1,0x95,0xD5,0xCA,0x10, +0xF7,0xD8,0xB0,0x03,0x4C,0x00,0xDC,0xA9,0x01,0x20,0x3A,0xDC,0xA9,0x01,0x85,0xD5, +0x4C,0x00,0xDC,0xA2,0x04,0x38,0xB5,0xD5,0xF5,0xE1,0x95,0xD5,0xCA,0x10,0xF7,0x90, +0x04,0xD8,0x4C,0x00,0xDC,0xA5,0xD4,0x49,0x80,0x85,0xD4,0x38,0xA2,0x04,0xA9,0x00, +0xF5,0xD5,0x95,0xD5,0xCA,0x10,0xF7,0xD8,0x4C,0x00,0xDC,0xA5,0xD4,0xF0,0x45,0xA5, +0xE0,0xF0,0x3E,0x20,0xCF,0xDC,0x38,0xE9,0x40,0x38,0x65,0xE0,0x30,0x38,0x20,0xE0, +0xDC,0xA5,0xDF,0x29,0x0F,0x85,0xF6,0xC6,0xF6,0x30,0x06,0x20,0x01,0xDD,0x4C,0xF7, +0xDA,0xA5,0xDF,0x4A,0x4A,0x4A,0x4A,0x85,0xF6,0xC6,0xF6,0x30,0x06,0x20,0x05,0xDD, +0x4C,0x09,0xDB,0x20,0x62,0xDC,0xC6,0xF5,0xD0,0xD7,0xA5,0xED,0x85,0xD4,0x4C,0x04, +0xDC,0x20,0x44,0xDA,0x18,0x60,0x38,0x60,0xA5,0xE0,0xF0,0xFA,0xA5,0xD4,0xF0,0xF4, +0x20,0xCF,0xDC,0x38,0xE5,0xE0,0x18,0x69,0x40,0x30,0xEB,0x20,0xE0,0xDC,0xE6,0xF5, +0x4C,0x4E,0xDB,0xA2,0x00,0xB5,0xD5,0x95,0xD4,0xE8,0xE0,0x0C,0xD0,0xF7,0xA0,0x05, +0x38,0xF8,0xB9,0xDA,0x00,0xF9,0xE6,0x00,0x99,0xDA,0x00,0x88,0x10,0xF4,0xD8,0x90, +0x04,0xE6,0xD9,0xD0,0xE9,0x20,0x0F,0xDD,0x06,0xD9,0x06,0xD9,0x06,0xD9,0x06,0xD9, +0xA0,0x05,0x38,0xF8,0xB9,0xDA,0x00,0xF9,0xE0,0x00,0x99,0xDA,0x00,0x88,0x10,0xF4, +0xD8,0x90,0x04,0xE6,0xD9,0xD0,0xE9,0x20,0x09,0xDD,0xC6,0xF5,0xD0,0xB5,0x20,0x62, +0xDC,0x4C,0x1A,0xDB,0x20,0xAF,0xDB,0xA4,0xF2,0x90,0x02,0xB1,0xF3,0xC8,0x84,0xF2, +0x60,0xA4,0xF2,0xA9,0x20,0xD1,0xF3,0xD0,0x03,0xC8,0xD0,0xF9,0x84,0xF2,0x60,0xA4, +0xF2,0xB1,0xF3,0x38,0xE9,0x30,0x90,0x18,0xC9,0x0A,0x60,0xA5,0xF2,0x48,0x20,0x94, +0xDB,0x90,0x1F,0xC9,0x2E,0xF0,0x14,0xC9,0x2B,0xF0,0x07,0xC9,0x2D,0xF0,0x03,0x68, +0x38,0x60,0x20,0x94,0xDB,0x90,0x0B,0xC9,0x2E,0xD0,0xF4,0x20,0x94,0xDB,0x90,0x02, +0xB0,0xED,0x68,0x85,0xF2,0x18,0x60,0xA2,0xE7,0xD0,0x02,0xA2,0xD5,0xA0,0x04,0x18, +0x36,0x04,0x36,0x03,0x36,0x02,0x36,0x01,0x36,0x00,0x26,0xEC,0x88,0xD0,0xF0,0x60, +0xA2,0x00,0x86,0xDA,0xA2,0x04,0xA5,0xD4,0xF0,0x2E,0xA5,0xD5,0xD0,0x1A,0xA0,0x00, +0xB9,0xD6,0x00,0x99,0xD5,0x00,0xC8,0xC0,0x05,0x90,0xF5,0xC6,0xD4,0xCA,0xD0,0xEA, +0xA5,0xD5,0xD0,0x04,0x85,0xD4,0x18,0x60,0xA5,0xD4,0x29,0x7F,0xC9,0x71,0x90,0x01, +0x60,0xC9,0x0F,0xB0,0x03,0x20,0x44,0xDA,0x18,0x60,0xA2,0xD4,0xD0,0x02,0xA2,0xE0, +0x86,0xF9,0x85,0xF7,0x85,0xF8,0xA0,0x04,0xB5,0x04,0x95,0x05,0xCA,0x88,0xD0,0xF8, +0xA9,0x00,0x95,0x05,0xA6,0xF9,0xC6,0xF7,0xD0,0xEC,0xB5,0x00,0x18,0x65,0xF8,0x95, +0x00,0x60,0xA2,0x0A,0xB5,0xD4,0x95,0xD5,0xCA,0x10,0xF9,0xA9,0x00,0x85,0xD4,0x60, +0x85,0xF7,0xA2,0x00,0xA0,0x00,0x20,0x93,0xDC,0x38,0xE9,0x01,0x85,0xF7,0xB5,0xD5, +0x4A,0x4A,0x4A,0x4A,0x20,0x9D,0xDC,0xB5,0xD5,0x29,0x0F,0x20,0x9D,0xDC,0xE8,0xE0, +0x05,0x90,0xE3,0xA5,0xF7,0xD0,0x05,0xA9,0x2E,0x20,0x9F,0xDC,0x60,0x09,0x30,0x99, +0x80,0x05,0xC8,0x60,0xA2,0x0A,0xBD,0x80,0x05,0xC9,0x2E,0xF0,0x07,0xC9,0x30,0xD0, +0x07,0xCA,0xD0,0xF2,0xCA,0xBD,0x80,0x05,0x60,0x20,0xEB,0xDB,0xA5,0xEC,0x29,0x0F, +0x60,0x38,0xA5,0xF3,0xE9,0x01,0x85,0xF3,0xA5,0xF4,0xE9,0x00,0x85,0xF4,0x60,0xA5, +0xD4,0x45,0xE0,0x29,0x80,0x85,0xEE,0x06,0xE0,0x46,0xE0,0xA5,0xD4,0x29,0x7F,0x60, +0x05,0xEE,0x85,0xED,0xA9,0x00,0x85,0xD4,0x85,0xE0,0x20,0x28,0xDD,0x20,0xE7,0xDB, +0xA5,0xEC,0x29,0x0F,0x85,0xE6,0xA9,0x05,0x85,0xF5,0x20,0x34,0xDD,0x20,0x44,0xDA, +0x60,0xA2,0xD9,0xD0,0x06,0xA2,0xD9,0xD0,0x08,0xA2,0xDF,0xA0,0xE5,0xD0,0x04,0xA2, +0xDF,0xA0,0xEB,0xA9,0x05,0x85,0xF7,0x18,0xF8,0xB5,0x00,0x79,0x00,0x00,0x95,0x00, +0xCA,0x88,0xC6,0xF7,0x10,0xF3,0xD8,0x60,0xA0,0x05,0xB9,0xE0,0x00,0x99,0xE6,0x00, +0x88,0x10,0xF7,0x60,0xA0,0x05,0xB9,0xD4,0x00,0x99,0xDA,0x00,0x88,0x10,0xF7,0x60, +0x86,0xFE,0x84,0xFF,0x85,0xEF,0xA2,0xE0,0xA0,0x05,0x20,0xA7,0xDD,0x20,0xB6,0xDD, +0xA6,0xFE,0xA4,0xFF,0x20,0x89,0xDD,0xC6,0xEF,0xF0,0x2D,0x20,0xDB,0xDA,0xB0,0x28, +0x18,0xA5,0xFE,0x69,0x06,0x85,0xFE,0x90,0x06,0xA5,0xFF,0x69,0x00,0x85,0xFF,0xA6, +0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20,0x66,0xDA,0xB0,0x0D,0xC6,0xEF,0xF0,0x09,0xA2, +0xE0,0xA0,0x05,0x20,0x98,0xDD,0x30,0xD3,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB1, +0xFC,0x99,0xD4,0x00,0x88,0x10,0xF8,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB1,0xFC, +0x99,0xE0,0x00,0x88,0x10,0xF8,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB9,0xD4,0x00, +0x91,0xFC,0x88,0x10,0xF8,0x60,0xA2,0x05,0xB5,0xD4,0x95,0xE0,0xCA,0x10,0xF9,0x60, +0xA2,0x89,0xA0,0xDE,0x20,0x98,0xDD,0x20,0xDB,0xDA,0xB0,0x7F,0xA9,0x00,0x85,0xF1, +0xA5,0xD4,0x85,0xF0,0x29,0x7F,0x85,0xD4,0x38,0xE9,0x40,0x30,0x26,0xC9,0x04,0x10, +0x6A,0xA2,0xE6,0xA0,0x05,0x20,0xA7,0xDD,0x20,0xD2,0xD9,0xA5,0xD4,0x85,0xF1,0xA5, +0xD5,0xD0,0x58,0x20,0xAA,0xD9,0x20,0xB6,0xDD,0xA2,0xE6,0xA0,0x05,0x20,0x89,0xDD, +0x20,0x60,0xDA,0xA9,0x0A,0xA2,0x4D,0xA0,0xDE,0x20,0x40,0xDD,0x20,0xB6,0xDD,0x20, +0xDB,0xDA,0xA5,0xF1,0xF0,0x23,0x18,0x6A,0x85,0xE0,0xA9,0x01,0x90,0x02,0xA9,0x10, +0x85,0xE1,0xA2,0x04,0xA9,0x00,0x95,0xE2,0xCA,0x10,0xFB,0xA5,0xE0,0x18,0x69,0x40, +0xB0,0x19,0x30,0x17,0x85,0xE0,0x20,0xDB,0xDA,0xA5,0xF0,0x10,0x0D,0x20,0xB6,0xDD, +0xA2,0x8F,0xA0,0xDE,0x20,0x89,0xDD,0x20,0x28,0xDB,0x60,0x38,0x60,0x3D,0x17,0x94, +0x19,0x00,0x00,0x3D,0x57,0x33,0x05,0x00,0x00,0x3E,0x05,0x54,0x76,0x62,0x00,0x3E, +0x32,0x19,0x62,0x27,0x00,0x3F,0x01,0x68,0x60,0x30,0x36,0x3F,0x07,0x32,0x03,0x27, +0x41,0x3F,0x25,0x43,0x34,0x56,0x75,0x3F,0x66,0x27,0x37,0x30,0x50,0x40,0x01,0x15, +0x12,0x92,0x55,0x3F,0x99,0x99,0x99,0x99,0x99,0x3F,0x43,0x42,0x94,0x48,0x19,0x40, +0x01,0x00,0x00,0x00,0x00,0x86,0xFE,0x84,0xFF,0xA2,0xE0,0xA0,0x05,0x20,0xA7,0xDD, +0xA6,0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20,0x66,0xDA,0xA2,0xE6,0xA0,0x05,0x20,0xA7, +0xDD,0xA2,0xE0,0xA0,0x05,0x20,0x89,0xDD,0xA6,0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20, +0x60,0xDA,0xA2,0xE6,0xA0,0x05,0x20,0x98,0xDD,0x20,0x28,0xDB,0x60,0xA9,0x01,0xD0, +0x02,0xA9,0x00,0x85,0xF0,0xA5,0xD4,0x10,0x02,0x38,0x60,0xA5,0xD4,0x85,0xE0,0x38, +0xE9,0x40,0x0A,0x85,0xF1,0xA5,0xD5,0x29,0xF0,0xD0,0x04,0xA9,0x01,0xD0,0x04,0xE6, +0xF1,0xA9,0x10,0x85,0xE1,0xA2,0x04,0xA9,0x00,0x95,0xE2,0xCA,0x10,0xFB,0x20,0x28, +0xDB,0xA2,0x66,0xA0,0xDF,0x20,0x95,0xDE,0xA2,0xE6,0xA0,0x05,0x20,0xA7,0xDD,0x20, +0xB6,0xDD,0x20,0xDB,0xDA,0xA9,0x0A,0xA2,0x72,0xA0,0xDF,0x20,0x40,0xDD,0xA2,0xE6, +0xA0,0x05,0x20,0x98,0xDD,0x20,0xDB,0xDA,0xA2,0x6C,0xA0,0xDF,0x20,0x98,0xDD,0x20, +0x66,0xDA,0x20,0xB6,0xDD,0xA9,0x00,0x85,0xD5,0xA5,0xF1,0x85,0xD4,0x10,0x07,0x49, +0xFF,0x18,0x69,0x01,0x85,0xD4,0x20,0xAA,0xD9,0x24,0xF1,0x10,0x06,0xA9,0x80,0x05, +0xD4,0x85,0xD4,0x20,0x66,0xDA,0xA5,0xF0,0xF0,0x0A,0xA2,0x89,0xA0,0xDE,0x20,0x98, +0xDD,0x20,0x28,0xDB,0x18,0x60,0x40,0x03,0x16,0x22,0x77,0x66,0x3F,0x50,0x00,0x00, +0x00,0x00,0x3F,0x49,0x15,0x57,0x11,0x08,0xBF,0x51,0x70,0x49,0x47,0x08,0x3F,0x39, +0x20,0x57,0x61,0x95,0xBF,0x04,0x39,0x63,0x03,0x55,0x3F,0x10,0x09,0x30,0x12,0x64, +0x3F,0x09,0x39,0x08,0x04,0x60,0x3F,0x12,0x42,0x58,0x47,0x42,0x3F,0x17,0x37,0x12, +0x06,0x08,0x3F,0x28,0x95,0x29,0x71,0x17,0x3F,0x86,0x85,0x88,0x96,0x44,0x3E,0x16, +0x05,0x44,0x49,0x00,0xBE,0x95,0x68,0x38,0x45,0x00,0x3F,0x02,0x68,0x79,0x94,0x16, +0xBF,0x04,0x92,0x78,0x90,0x80,0x3F,0x07,0x03,0x15,0x20,0x00,0xBF,0x08,0x92,0x29, +0x12,0x44,0x3F,0x11,0x08,0x40,0x09,0x11,0xBF,0x14,0x28,0x31,0x56,0x04,0x3F,0x19, +0x99,0x98,0x77,0x44,0xBF,0x33,0x33,0x33,0x31,0x13,0x3F,0x99,0x99,0x99,0x99,0x99, +0x3F,0x78,0x53,0x98,0x16,0x34,0x98,0x16,0x34,0xFC,0xE0,0x32,0x50,0xD9,0x68,0x11, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, +0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0x66,0x66,0xFF,0x66,0x00, +0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00,0x00,0x66,0x6C,0x18,0x30,0x66,0x46,0x00, +0x1C,0x36,0x1C,0x38,0x6F,0x66,0x3B,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x0E,0x1C,0x18,0x18,0x1C,0x0E,0x00,0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, +0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, +0x00,0x3C,0x66,0x6E,0x76,0x66,0x3C,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x7E,0x00, +0x00,0x3C,0x66,0x0C,0x18,0x30,0x7E,0x00,0x00,0x7E,0x0C,0x18,0x0C,0x66,0x3C,0x00, +0x00,0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x00,0x00,0x7E,0x60,0x7C,0x06,0x66,0x3C,0x00, +0x00,0x3C,0x60,0x7C,0x66,0x66,0x3C,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x30,0x00, +0x00,0x3C,0x66,0x3C,0x66,0x66,0x3C,0x00,0x00,0x3C,0x66,0x3E,0x06,0x0C,0x38,0x00, +0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, +0x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, +0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x00,0x3C,0x66,0x0C,0x18,0x00,0x18,0x00, +0x00,0x3C,0x66,0x6E,0x6E,0x60,0x3E,0x00,0x00,0x18,0x3C,0x66,0x66,0x7E,0x66,0x00, +0x00,0x7C,0x66,0x7C,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00, +0x00,0x78,0x6C,0x66,0x66,0x6C,0x78,0x00,0x00,0x7E,0x60,0x7C,0x60,0x60,0x7E,0x00, +0x00,0x7E,0x60,0x7C,0x60,0x60,0x60,0x00,0x00,0x3E,0x60,0x60,0x6E,0x66,0x3E,0x00, +0x00,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x7E,0x00, +0x00,0x06,0x06,0x06,0x06,0x66,0x3C,0x00,0x00,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00, +0x00,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x00, +0x00,0x66,0x76,0x7E,0x7E,0x6E,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3C,0x66,0x66,0x66,0x6C,0x36,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x6C,0x66,0x00,0x00,0x3C,0x60,0x3C,0x06,0x06,0x3C,0x00, +0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, +0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, +0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x18,0x00, +0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x1E,0x00, +0x00,0x40,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, +0x00,0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, +0x00,0x36,0x7F,0x7F,0x3E,0x1C,0x08,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00, +0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18, +0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03, +0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F, +0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00, +0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0, +0x00,0x1C,0x1C,0x77,0x77,0x08,0x1C,0x00,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18, +0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0x18, +0x00,0x00,0x3C,0x7E,0x7E,0x7E,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, +0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18, +0x18,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, +0x18,0x18,0x18,0x1F,0x1F,0x00,0x00,0x00,0x78,0x60,0x78,0x60,0x7E,0x18,0x1E,0x00, +0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00, +0x00,0x18,0x30,0x7E,0x30,0x18,0x00,0x00,0x00,0x18,0x0C,0x7E,0x0C,0x18,0x00,0x00, +0x00,0x18,0x3C,0x7E,0x7E,0x3C,0x18,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00, +0x00,0x60,0x60,0x7C,0x66,0x66,0x7C,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x3C,0x00, +0x00,0x06,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, +0x00,0x0E,0x18,0x3E,0x18,0x18,0x18,0x00,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x7C, +0x00,0x60,0x60,0x7C,0x66,0x66,0x66,0x00,0x00,0x18,0x00,0x38,0x18,0x18,0x3C,0x00, +0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3C,0x00,0x60,0x60,0x6C,0x78,0x6C,0x66,0x00, +0x00,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, +0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, +0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x06, +0x00,0x00,0x7C,0x66,0x60,0x60,0x60,0x00,0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, +0x00,0x18,0x7E,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x00, +0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x63,0x6B,0x7F,0x3E,0x36,0x00, +0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x3E,0x0C,0x78, +0x00,0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00,0x00,0x18,0x3C,0x7E,0x7E,0x18,0x3C,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x7E,0x78,0x7C,0x6E,0x66,0x06,0x00, +0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00,0x10,0x18,0x1C,0x1E,0x1C,0x18,0x10,0x00, +0xFB,0xF3,0x33,0xF6,0x3D,0xF6,0xA3,0xF6,0x33,0xF6,0x3C,0xF6,0x4C,0xE4,0xF3,0x00, +0xF5,0xF3,0x33,0xF6,0x92,0xF5,0xB6,0xF5,0x33,0xF6,0xFB,0xFC,0x4C,0xE4,0xF3,0x00, +0x33,0xF6,0x33,0xF6,0xE1,0xF6,0x3C,0xF6,0x33,0xF6,0x3C,0xF6,0x4C,0xE4,0xF3,0x00, +0x9E,0xEE,0xDB,0xEE,0x9D,0xEE,0xA6,0xEE,0x80,0xEE,0x9D,0xEE,0x4C,0x78,0xEE,0x00, +0x4B,0xEF,0x2A,0xF0,0xD5,0xEF,0x0F,0xF0,0x27,0xF0,0x4A,0xEF,0x4C,0x41,0xEF,0x00, +0x4C,0xEA,0xED,0x4C,0xF0,0xED,0x4C,0xC4,0xE4,0x4C,0x59,0xE9,0x4C,0xED,0xE8,0x4C, +0xAE,0xE7,0x4C,0x05,0xE9,0x4C,0x44,0xE9,0x4C,0xF2,0xEB,0x4C,0xD5,0xE6,0x4C,0xA6, +0xE4,0x4C,0x23,0xF2,0x4C,0x1B,0xF1,0x4C,0x25,0xF1,0x4C,0xE9,0xEF,0x4C,0x5D,0xEF, +0x90,0xE7,0x8F,0xE7,0x8F,0xE7,0x8F,0xE7,0xBE,0xFF,0x0F,0xEB,0x90,0xEA,0xCF,0xEA, +0x8F,0xE7,0x8F,0xE7,0x8F,0xE7,0x06,0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xAE,0xE7,0x05,0xE9,0xA2,0x00,0xA9,0xFF,0x9D,0x40,0x03,0xA9,0xC0,0x9D, +0x46,0x03,0xA9,0xE4,0x9D,0x47,0x03,0x8A,0x18,0x69,0x10,0xAA,0xC9,0x80,0x90,0xE8, +0x60,0xA0,0x85,0x60,0x85,0x2F,0x86,0x2E,0x8A,0x29,0x0F,0xD0,0x04,0xE0,0x80,0x90, +0x05,0xA0,0x86,0x4C,0x1B,0xE6,0xA0,0x00,0xBD,0x40,0x03,0x99,0x20,0x00,0xE8,0xC8, +0xC0,0x0C,0x90,0xF4,0xA0,0x84,0xA5,0x22,0xC9,0x03,0x90,0x25,0xA8,0xC0,0x0E,0x90, +0x02,0xA0,0x0E,0x84,0x17,0xB9,0xC6,0xE6,0xF0,0x0F,0xC9,0x02,0xF0,0x35,0xC9,0x08, +0xB0,0x4C,0xC9,0x04,0xF0,0x63,0x4C,0xC9,0xE5,0xA5,0x20,0xC9,0xFF,0xF0,0x05,0xA0, +0x81,0x4C,0x1B,0xE6,0x20,0x9E,0xE6,0xB0,0xF8,0x20,0x3D,0xE6,0xB0,0xF3,0x20,0x89, +0xE6,0xA9,0x0B,0x85,0x17,0x20,0x3D,0xE6,0xA5,0x2C,0x85,0x26,0xA5,0x2D,0x85,0x27, +0x4C,0x1D,0xE6,0xA0,0x01,0x84,0x23,0x20,0x3D,0xE6,0xB0,0x03,0x20,0x89,0xE6,0xA9, +0xFF,0x85,0x20,0xA9,0xE4,0x85,0x27,0xA9,0xC0,0x85,0x26,0x4C,0x1D,0xE6,0xA5,0x20, +0xC9,0xFF,0xD0,0x05,0x20,0x9E,0xE6,0xB0,0xB8,0x20,0x3D,0xE6,0x20,0x89,0xE6,0xA6, +0x2E,0xBD,0x40,0x03,0x85,0x20,0x4C,0x1D,0xE6,0xA5,0x22,0x25,0x2A,0xD0,0x05,0xA0, +0x83,0x4C,0x1B,0xE6,0x20,0x3D,0xE6,0xB0,0xF8,0xA5,0x28,0x05,0x29,0xD0,0x08,0x20, +0x89,0xE6,0x85,0x2F,0x4C,0x1D,0xE6,0x20,0x89,0xE6,0x85,0x2F,0x30,0x35,0xA0,0x00, +0x91,0x24,0x20,0x70,0xE6,0xA5,0x22,0x29,0x02,0xD0,0x0C,0xA5,0x2F,0xC9,0x9B,0xD0, +0x06,0x20,0x63,0xE6,0x4C,0xC3,0xE5,0x20,0x63,0xE6,0xD0,0xDB,0xA5,0x22,0x29,0x02, +0xD0,0x11,0x20,0x89,0xE6,0x85,0x2F,0x30,0x0A,0xA5,0x2F,0xC9,0x9B,0xD0,0xF3,0xA9, +0x89,0x85,0x23,0x20,0x77,0xE6,0x4C,0x1D,0xE6,0xA5,0x22,0x25,0x2A,0xD0,0x05,0xA0, +0x87,0x4C,0x1B,0xE6,0x20,0x3D,0xE6,0xB0,0xF8,0xA5,0x28,0x05,0x29,0xD0,0x06,0xA5, +0x2F,0xE6,0x28,0xD0,0x06,0xA0,0x00,0xB1,0x24,0x85,0x2F,0x20,0x89,0xE6,0x30,0x25, +0x20,0x70,0xE6,0xA5,0x22,0x29,0x02,0xD0,0x0C,0xA5,0x2F,0xC9,0x9B,0xD0,0x06,0x20, +0x63,0xE6,0x4C,0x15,0xE6,0x20,0x63,0xE6,0xD0,0xDB,0xA5,0x22,0x29,0x02,0xD0,0x05, +0xA9,0x9B,0x20,0x89,0xE6,0x20,0x77,0xE6,0x4C,0x1D,0xE6,0x84,0x23,0xA4,0x2E,0xB9, +0x44,0x03,0x85,0x24,0xB9,0x45,0x03,0x85,0x25,0xA2,0x00,0xB5,0x20,0x99,0x40,0x03, +0xE8,0xC8,0xE0,0x0C,0x90,0xF5,0xA5,0x2F,0xA6,0x2E,0xA4,0x23,0x60,0xA4,0x20,0xC0, +0x22,0x90,0x04,0xA0,0x85,0xB0,0x1B,0xB9,0x1B,0x03,0x85,0x2C,0xB9,0x1C,0x03,0x85, +0x2D,0xA4,0x17,0xB9,0xC6,0xE6,0xA8,0xB1,0x2C,0xAA,0xC8,0xB1,0x2C,0x85,0x2D,0x86, +0x2C,0x18,0x60,0xC6,0x28,0xA5,0x28,0xC9,0xFF,0xD0,0x02,0xC6,0x29,0x05,0x29,0x60, +0xE6,0x24,0xD0,0x02,0xE6,0x25,0x60,0xA6,0x2E,0x38,0xBD,0x48,0x03,0xE5,0x28,0x85, +0x28,0xBD,0x49,0x03,0xE5,0x29,0x85,0x29,0x60,0xA0,0x92,0x20,0x93,0xE6,0x84,0x23, +0xC0,0x00,0x60,0xAA,0xA5,0x2D,0x48,0xA5,0x2C,0x48,0x8A,0xA6,0x2E,0x60,0xA0,0x00, +0xB1,0x24,0xF0,0x0C,0xA0,0x21,0xD9,0x1A,0x03,0xF0,0x0A,0x88,0x88,0x88,0x10,0xF6, +0xA0,0x82,0x38,0xB0,0x13,0x98,0x85,0x20,0x38,0xA0,0x01,0xB1,0x24,0xE9,0x30,0xC9, +0x0A,0x90,0x02,0xA9,0x01,0x85,0x21,0x18,0x60,0x00,0x04,0x04,0x04,0x04,0x06,0x06, +0x06,0x06,0x02,0x08,0x0A,0xA9,0x40,0x8D,0x0E,0xD4,0xA9,0x38,0x8D,0x02,0xD3,0x8D, +0x03,0xD3,0xA9,0x00,0x8D,0x00,0xD3,0xEA,0xEA,0xEA,0xA9,0x3C,0x8D,0x02,0xD3,0x8D, +0x03,0xD3,0x60,0x6C,0x16,0x02,0x80,0x40,0x04,0x02,0x01,0x08,0x10,0x20,0x36,0x08, +0x14,0x12,0x10,0x0E,0x0C,0x0A,0x48,0xAD,0x0E,0xD2,0x29,0x20,0xD0,0x0D,0xA9,0xDF, +0x8D,0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0x6C,0x0A,0x02,0x8A,0x48,0xA2,0x06,0xBD, +0xF6,0xE6,0xE0,0x05,0xD0,0x04,0x25,0x10,0xF0,0x05,0x2C,0x0E,0xD2,0xF0,0x06,0xCA, +0x10,0xED,0x4C,0x62,0xE7,0x49,0xFF,0x8D,0x0E,0xD2,0xA5,0x10,0x8D,0x0E,0xD2,0xBD, +0xFE,0xE6,0xAA,0xBD,0x00,0x02,0x8D,0x8C,0x02,0xBD,0x01,0x02,0x8D,0x8D,0x02,0x68, +0xAA,0x6C,0x8C,0x02,0xA9,0x00,0x85,0x11,0x8D,0xFF,0x02,0x8D,0xF0,0x02,0x85,0x4D, +0x68,0x40,0x68,0xAA,0x2C,0x02,0xD3,0x10,0x06,0xAD,0x00,0xD3,0x6C,0x02,0x02,0x2C, +0x03,0xD3,0x10,0x06,0xAD,0x01,0xD3,0x6C,0x04,0x02,0x68,0x8D,0x8C,0x02,0x68,0x48, +0x29,0x10,0xF0,0x07,0xAD,0x8C,0x02,0x48,0x6C,0x06,0x02,0xAD,0x8C,0x02,0x48,0x68, +0x40,0x2C,0x0F,0xD4,0x10,0x03,0x6C,0x00,0x02,0x48,0xAD,0x0F,0xD4,0x29,0x20,0xF0, +0x03,0x4C,0x74,0xE4,0x8A,0x48,0x98,0x48,0x8D,0x0F,0xD4,0x6C,0x22,0x02,0xE6,0x14, +0xD0,0x08,0xE6,0x4D,0xE6,0x13,0xD0,0x02,0xE6,0x12,0xA9,0xFE,0xA2,0x00,0xA4,0x4D, +0x10,0x06,0x85,0x4D,0xA6,0x13,0xA9,0xF6,0x85,0x4E,0x86,0x4F,0xA2,0x00,0x20,0xD0, +0xE8,0xD0,0x03,0x20,0xCA,0xE8,0xA5,0x42,0xD0,0x08,0xBA,0xBD,0x04,0x01,0x29,0x04, +0xF0,0x03,0x4C,0x05,0xE9,0xAD,0x0D,0xD4,0x8D,0x35,0x02,0xAD,0x0C,0xD4,0x8D,0x34, +0x02,0xAD,0x31,0x02,0x8D,0x03,0xD4,0xAD,0x30,0x02,0x8D,0x02,0xD4,0xAD,0x2F,0x02, +0x8D,0x00,0xD4,0xAD,0x6F,0x02,0x8D,0x1B,0xD0,0xA2,0x08,0x8E,0x1F,0xD0,0x58,0xBD, +0xC0,0x02,0x45,0x4F,0x25,0x4E,0x9D,0x12,0xD0,0xCA,0x10,0xF2,0xAD,0xF4,0x02,0x8D, +0x09,0xD4,0xAD,0xF3,0x02,0x8D,0x01,0xD4,0xA2,0x02,0x20,0xD0,0xE8,0xD0,0x03,0x20, +0xCD,0xE8,0xA2,0x02,0xE8,0xE8,0xBD,0x18,0x02,0x1D,0x19,0x02,0xF0,0x06,0x20,0xD0, +0xE8,0x9D,0x26,0x02,0xE0,0x08,0xD0,0xEC,0xAD,0x0F,0xD2,0x29,0x04,0xF0,0x08,0xAD, +0xF1,0x02,0xF0,0x03,0xCE,0xF1,0x02,0xAD,0x2B,0x02,0xF0,0x17,0xAD,0x0F,0xD2,0x29, +0x04,0xD0,0x60,0xCE,0x2B,0x02,0xD0,0x0B,0xA9,0x06,0x8D,0x2B,0x02,0xAD,0x09,0xD2, +0x8D,0xFC,0x02,0xA0,0x01,0xA2,0x03,0xB9,0x00,0xD3,0x4A,0x4A,0x4A,0x4A,0x9D,0x78, +0x02,0xCA,0xB9,0x00,0xD3,0x29,0x0F,0x9D,0x78,0x02,0xCA,0x88,0x10,0xE9,0xA2,0x03, +0xBD,0x10,0xD0,0x9D,0x84,0x02,0xBD,0x00,0xD2,0x9D,0x70,0x02,0xBD,0x04,0xD2,0x9D, +0x74,0x02,0xCA,0x10,0xEB,0x8D,0x0B,0xD2,0xA2,0x06,0xA0,0x03,0xB9,0x78,0x02,0x4A, +0x4A,0x4A,0x9D,0x7D,0x02,0xA9,0x00,0x2A,0x9D,0x7C,0x02,0xCA,0xCA,0x88,0x10,0xEC, +0x6C,0x24,0x02,0xA9,0x00,0x8D,0x2B,0x02,0xF0,0xA9,0x6C,0x26,0x02,0x6C,0x28,0x02, +0xBC,0x18,0x02,0xD0,0x08,0xBC,0x19,0x02,0xF0,0x10,0xDE,0x19,0x02,0xDE,0x18,0x02, +0xD0,0x08,0xBC,0x19,0x02,0xD0,0x03,0xA9,0x00,0x60,0xA9,0xFF,0x60,0x0A,0x8D,0x2D, +0x02,0x8A,0xA2,0x05,0x8D,0x0A,0xD4,0xCA,0xD0,0xFD,0xAE,0x2D,0x02,0x9D,0x17,0x02, +0x98,0x9D,0x16,0x02,0x60,0x68,0xA8,0x68,0xAA,0x68,0x40,0x66,0x66,0x7E,0x66,0x00, +0x00,0x7C,0x4C,0xED,0xE8,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00, +0x00,0x78,0x6C,0x66,0x66,0x6C,0x78,0x00,0x00,0x7E,0x60,0x7C,0x60,0x60,0x7E,0x00, +0x00,0x7E,0x60,0x7C,0x60,0x60,0x60,0x00,0x00,0x3E,0x60,0x60,0x6E,0x66,0x3E,0x00, +0x00,0x66,0x66,0x7E,0xA9,0x3C,0x8D,0x02,0xD3,0xA9,0x3C,0x8D,0x03,0xD3,0xA9,0x03, +0x8D,0x32,0x02,0x85,0x41,0x8D,0x0F,0xD2,0x60,0xBA,0x8E,0x18,0x03,0xA9,0x01,0x85, +0x42,0xAD,0x00,0x03,0xC9,0x60,0xD0,0x03,0x4C,0x80,0xEB,0xA9,0x00,0x8D,0x0F,0x03, +0xA9,0x01,0x85,0x37,0xA9,0x0D,0x85,0x36,0xA9,0x28,0x8D,0x04,0xD2,0xA9,0x00,0x8D, +0x06,0xD2,0x18,0xAD,0x00,0x03,0x6D,0x01,0x03,0x69,0xFF,0x8D,0x3A,0x02,0xAD,0x02, +0x03,0x8D,0x3B,0x02,0xAD,0x0A,0x03,0x8D,0x3C,0x02,0xAD,0x0B,0x03,0x8D,0x3D,0x02, +0x18,0xA9,0x3A,0x85,0x32,0x69,0x04,0x85,0x34,0xA9,0x02,0x85,0x33,0x85,0x35,0xA9, +0x34,0x8D,0x03,0xD3,0x20,0x8A,0xEC,0xAD,0x3F,0x02,0xD0,0x03,0x98,0xD0,0x07,0xC6, +0x36,0x10,0xB5,0x4C,0x06,0xEA,0xAD,0x03,0x03,0x10,0x0C,0xA9,0x0D,0x85,0x36,0x20, +0x6A,0xEB,0x20,0x8A,0xEC,0xF0,0xE8,0x20,0x75,0xEC,0xA9,0x00,0x8D,0x3F,0x02,0x20, +0x9B,0xEC,0xF0,0x12,0x2C,0x03,0x03,0x70,0x07,0xAD,0x3F,0x02,0xD0,0x18,0xF0,0x1D, +0x20,0x6A,0xEB,0x20,0xE0,0xEA,0xAD,0x3F,0x02,0xF0,0x05,0xAD,0x19,0x03,0x85,0x30, +0xA5,0x30,0xC9,0x01,0xF0,0x07,0xC6,0x37,0x30,0x03,0x4C,0x74,0xE9,0x20,0x5F,0xEC, +0xA9,0x00,0x85,0x42,0xA4,0x30,0x8C,0x03,0x03,0x60,0xA9,0x00,0x8D,0x3F,0x02,0x18, +0xA9,0x3E,0x85,0x32,0x69,0x01,0x85,0x34,0xA9,0x02,0x85,0x33,0x85,0x35,0xA9,0xFF, +0x85,0x3C,0x20,0xE0,0xEA,0xA0,0xFF,0xA5,0x30,0xC9,0x01,0xD0,0x19,0xAD,0x3E,0x02, +0xC9,0x41,0xF0,0x21,0xC9,0x43,0xF0,0x1D,0xC9,0x45,0xD0,0x06,0xA9,0x90,0x85,0x30, +0xD0,0x04,0xA9,0x8B,0x85,0x30,0xA5,0x30,0xC9,0x8A,0xF0,0x07,0xA9,0xFF,0x8D,0x3F, +0x02,0xD0,0x02,0xA0,0x00,0xA5,0x30,0x8D,0x19,0x03,0x60,0xA9,0x01,0x85,0x30,0x20, +0xF2,0xEB,0xA0,0x00,0x84,0x31,0x84,0x3B,0x84,0x3A,0xB1,0x32,0x8D,0x0D,0xD2,0x85, +0x31,0xA5,0x11,0xD0,0x03,0x4C,0xA0,0xED,0xA5,0x3A,0xF0,0xF5,0x20,0x5F,0xEC,0x60, +0x98,0x48,0xE6,0x32,0xD0,0x02,0xE6,0x33,0xA5,0x32,0xC5,0x34,0xA5,0x33,0xE5,0x35, +0x90,0x1C,0xA5,0x3B,0xD0,0x0B,0xA5,0x31,0x8D,0x0D,0xD2,0xA9,0xFF,0x85,0x3B,0xD0, +0x09,0xA5,0x10,0x09,0x08,0x85,0x10,0x8D,0x0E,0xD2,0x68,0xA8,0x68,0x40,0xA0,0x00, +0xB1,0x32,0x8D,0x0D,0xD2,0x18,0x65,0x31,0x69,0x00,0x85,0x31,0x4C,0xBA,0xEA,0xA5, +0x3B,0xF0,0x0B,0x85,0x3A,0xA5,0x10,0x29,0xF7,0x85,0x10,0x8D,0x0E,0xD2,0x68,0x40, +0xA9,0x00,0xAC,0x0F,0x03,0xD0,0x02,0x85,0x31,0x85,0x38,0x85,0x39,0xA9,0x01,0x85, +0x30,0x20,0x1B,0xEC,0xA9,0x3C,0x8D,0x03,0xD3,0xA5,0x11,0xD0,0x03,0x4C,0xA0,0xED, +0xAD,0x17,0x03,0xF0,0x05,0xA5,0x39,0xF0,0xF0,0x60,0xA9,0x8A,0x85,0x30,0x60,0x98, +0x48,0xAD,0x0F,0xD2,0x8D,0x0A,0xD2,0x30,0x04,0xA0,0x8C,0x84,0x30,0x29,0x20,0xD0, +0x04,0xA0,0x8E,0x84,0x30,0xA5,0x38,0xF0,0x13,0xAD,0x0D,0xD2,0xC5,0x31,0xF0,0x04, +0xA0,0x8F,0x84,0x30,0xA9,0xFF,0x85,0x39,0x68,0xA8,0x68,0x40,0xAD,0x0D,0xD2,0xA0, +0x00,0x91,0x32,0x18,0x65,0x31,0x69,0x00,0x85,0x31,0xE6,0x32,0xD0,0x02,0xE6,0x33, +0xA5,0x32,0xC5,0x34,0xA5,0x33,0xE5,0x35,0x90,0xDE,0xA5,0x3C,0xF0,0x06,0xA9,0x00, +0x85,0x3C,0xF0,0xD0,0xA9,0xFF,0x85,0x38,0xD0,0xCE,0x18,0xAD,0x04,0x03,0x85,0x32, +0x6D,0x08,0x03,0x85,0x34,0xAD,0x05,0x03,0x85,0x33,0x6D,0x09,0x03,0x85,0x35,0x60, +0xAD,0x03,0x03,0x10,0x2E,0xA9,0xCC,0x8D,0x04,0xD2,0xA9,0x05,0x8D,0x06,0xD2,0x20, +0xF2,0xEB,0xA0,0x0F,0xAD,0x0B,0x03,0x30,0x02,0xA0,0xB4,0xA2,0x00,0x20,0xB9,0xED, +0xA9,0x34,0x8D,0x02,0xD3,0xAD,0x17,0x03,0xD0,0xFB,0x20,0x6A,0xEB,0x20,0x6B,0xEA, +0x4C,0xDF,0xEB,0xA9,0xFF,0x8D,0x0F,0x03,0xA0,0x0A,0xAD,0x0B,0x03,0x30,0x02,0xA0, +0x78,0xA2,0x00,0x20,0xB9,0xED,0xA9,0x34,0x8D,0x02,0xD3,0xAD,0x17,0x03,0xD0,0xFB, +0x20,0x6A,0xEB,0x20,0x75,0xEC,0x20,0xB9,0xED,0x20,0x10,0xED,0x20,0xE0,0xEA,0xAD, +0x0B,0x03,0x30,0x05,0xA9,0x3C,0x8D,0x02,0xD3,0x4C,0x0D,0xEA,0xA9,0x00,0x8D,0x17, +0x03,0x60,0xA9,0x07,0x2D,0x32,0x02,0x09,0x20,0xAC,0x00,0x03,0xC0,0x60,0xD0,0x0C, +0x09,0x08,0xA0,0x07,0x8C,0x02,0xD2,0xA0,0x05,0x8C,0x00,0xD2,0x8D,0x32,0x02,0x8D, +0x0F,0xD2,0xA9,0xC7,0x25,0x10,0x09,0x10,0x4C,0x31,0xEC,0xA9,0x07,0x2D,0x32,0x02, +0x09,0x10,0x8D,0x32,0x02,0x8D,0x0F,0xD2,0x8D,0x0A,0xD2,0xA9,0xC7,0x25,0x10,0x09, +0x20,0x85,0x10,0x8D,0x0E,0xD2,0xA9,0x28,0x8D,0x08,0xD2,0xA2,0x06,0xA9,0xA8,0xA4, +0x41,0xD0,0x02,0xA9,0xA0,0x9D,0x01,0xD2,0xCA,0xCA,0x10,0xF9,0xA9,0xA0,0x8D,0x05, +0xD2,0xAC,0x00,0x03,0xC0,0x60,0xF0,0x06,0x8D,0x01,0xD2,0x8D,0x03,0xD2,0x60,0xEA, +0xA9,0xC7,0x25,0x10,0x85,0x10,0x8D,0x0E,0xD2,0xA2,0x06,0xA9,0x00,0x9D,0x01,0xD2, +0xCA,0xCA,0x10,0xF9,0x60,0xAD,0x06,0x03,0x6A,0x6A,0xA8,0x29,0x3F,0xAA,0x98,0x6A, +0x29,0xC0,0xA8,0x60,0x0F,0xEB,0x90,0xEA,0xCF,0xEA,0xA2,0x01,0xA0,0xFF,0x88,0xD0, +0xFD,0xCA,0xD0,0xF8,0x20,0x6B,0xEA,0xA0,0x02,0xA2,0x00,0x20,0xB9,0xED,0x20,0x1A, +0xEA,0x98,0x60,0x8D,0x10,0x03,0x8C,0x11,0x03,0x20,0x04,0xED,0x8D,0x10,0x03,0xAD, +0x0C,0x03,0x20,0x04,0xED,0x8D,0x0C,0x03,0xAD,0x10,0x03,0x38,0xED,0x0C,0x03,0x8D, +0x12,0x03,0xAD,0x11,0x03,0x38,0xED,0x0D,0x03,0xA8,0xA9,0x7D,0x18,0x69,0x83,0x88, +0x10,0xFA,0x18,0x6D,0x12,0x03,0xA8,0x4A,0x4A,0x4A,0x0A,0x38,0xE9,0x16,0xAA,0x98, +0x29,0x07,0xA8,0xA9,0xF5,0x18,0x69,0x0B,0x88,0x10,0xFA,0xA0,0x00,0x8C,0x0E,0x03, +0x38,0xE9,0x07,0x10,0x03,0xCE,0x0E,0x03,0x18,0x7D,0xD0,0xED,0xA8,0xAD,0x0E,0x03, +0x7D,0xD1,0xED,0x60,0xC9,0x7C,0x30,0x04,0x38,0xE9,0x7C,0x60,0x18,0x69,0x07,0x60, +0xA5,0x11,0xD0,0x03,0x4C,0xA0,0xED,0x78,0xAD,0x17,0x03,0xD0,0x02,0xF0,0x25,0xAD, +0x0F,0xD2,0x29,0x10,0xD0,0xEA,0x8D,0x16,0x03,0xAE,0x0B,0xD4,0xA4,0x14,0x8E,0x0C, +0x03,0x8C,0x0D,0x03,0xA2,0x01,0x8E,0x15,0x03,0xA0,0x0A,0xA5,0x11,0xF0,0x61,0xAD, +0x17,0x03,0xD0,0x04,0x58,0x4C,0x0A,0xEB,0xAD,0x0F,0xD2,0x29,0x10,0xCD,0x16,0x03, +0xF0,0xE9,0x8D,0x16,0x03,0x88,0xD0,0xE3,0xCE,0x15,0x03,0x30,0x12,0xAD,0x0B,0xD4, +0xA4,0x14,0x20,0xA3,0xEC,0x8C,0xEE,0x02,0x8D,0xEF,0x02,0xA0,0x09,0xD0,0xCC,0xAD, +0xEE,0x02,0x8D,0x04,0xD2,0xAD,0xEF,0x02,0x8D,0x06,0xD2,0xA9,0x00,0x8D,0x0F,0xD2, +0xAD,0x32,0x02,0x8D,0x0F,0xD2,0xA9,0x55,0x91,0x32,0xC8,0x91,0x32,0xA9,0xAA,0x85, +0x31,0x18,0xA5,0x32,0x69,0x02,0x85,0x32,0xA5,0x33,0x69,0x00,0x85,0x33,0x58,0x60, +0x20,0x5F,0xEC,0xA9,0x3C,0x8D,0x02,0xD3,0x8D,0x03,0xD3,0xA9,0x80,0x85,0x30,0xAE, +0x18,0x03,0x9A,0xC6,0x11,0x58,0x4C,0x0D,0xEA,0xA9,0xEC,0x8D,0x26,0x02,0xA9,0xEB, +0x8D,0x27,0x02,0xA9,0x01,0x78,0x20,0x5C,0xE4,0xA9,0x01,0x8D,0x17,0x03,0x58,0x60, +0xE8,0x03,0x43,0x04,0x9E,0x04,0xF9,0x04,0x54,0x05,0xAF,0x05,0x0A,0x06,0x65,0x06, +0xC0,0x06,0x1A,0x07,0x75,0x07,0xD0,0x07,0x24,0x85,0xA9,0xA0,0x8D,0x46,0x02,0x60, +0xA9,0x31,0x8D,0x00,0x03,0xAD,0x46,0x02,0xAE,0x02,0x03,0xE0,0x21,0xF0,0x02,0xA9, +0x07,0x8D,0x06,0x03,0xA2,0x40,0xA0,0x80,0xAD,0x02,0x03,0xC9,0x57,0xD0,0x02,0xA2, +0x80,0xC9,0x53,0xD0,0x0C,0xA9,0xEA,0x8D,0x04,0x03,0xA9,0x02,0x8D,0x05,0x03,0xA0, +0x04,0x8E,0x03,0x03,0x8C,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0x20,0x59,0xE4,0x10, +0x01,0x60,0xAD,0x02,0x03,0xC9,0x53,0xD0,0x0A,0x20,0x6D,0xEE,0xA0,0x02,0xB1,0x15, +0x8D,0x46,0x02,0xAD,0x02,0x03,0xC9,0x21,0xD0,0x1F,0x20,0x6D,0xEE,0xA0,0xFE,0xC8, +0xC8,0xB1,0x15,0xC9,0xFF,0xD0,0xF8,0xC8,0xB1,0x15,0xC8,0xC9,0xFF,0xD0,0xF2,0x88, +0x88,0x8C,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0xAC,0x03,0x03,0x60,0xAD,0x04,0x03, +0x85,0x15,0xAD,0x05,0x03,0x85,0x16,0x60,0xA9,0x1E,0x85,0x1C,0x60,0xEA,0x02,0xC0, +0x03,0xA9,0x04,0x85,0x1E,0xAE,0x7D,0xEE,0xAC,0x7E,0xEE,0xA9,0x53,0x8D,0x02,0x03, +0x8D,0x0A,0x03,0x20,0xE6,0xEE,0x20,0x59,0xE4,0x30,0x03,0x20,0x14,0xEF,0x60,0x20, +0x81,0xEE,0xA9,0x00,0x85,0x1D,0x60,0x85,0x1F,0x20,0x1A,0xEF,0xA6,0x1D,0xA5,0x1F, +0x9D,0xC0,0x03,0xE8,0xE4,0x1E,0xF0,0x13,0x86,0x1D,0xC9,0x9B,0xF0,0x03,0xA0,0x01, +0x60,0xA9,0x20,0x9D,0xC0,0x03,0xE8,0xE4,0x1E,0xD0,0xF8,0xA9,0x00,0x85,0x1D,0xAE, +0x7F,0xEE,0xAC,0x80,0xEE,0x20,0xE6,0xEE,0x20,0x59,0xE4,0x60,0x20,0x1A,0xEF,0xA6, +0x1D,0xD0,0xDE,0xA0,0x01,0x60,0x8E,0x04,0x03,0x8C,0x05,0x03,0xA9,0x40,0x8D,0x00, +0x03,0xA9,0x01,0x8D,0x01,0x03,0xA9,0x80,0xAE,0x02,0x03,0xE0,0x53,0xD0,0x02,0xA9, +0x40,0x8D,0x03,0x03,0xA5,0x1E,0x8D,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0xA5,0x1C, +0x8D,0x06,0x03,0x60,0xAD,0xEC,0x02,0x85,0x1C,0x60,0xA0,0x57,0xA5,0x2B,0xC9,0x4E, +0xD0,0x04,0xA2,0x28,0xD0,0x0E,0xC9,0x44,0xD0,0x04,0xA2,0x14,0xD0,0x06,0xC9,0x53, +0xD0,0x0B,0xA2,0x1D,0x86,0x1E,0x8C,0x02,0x03,0x8D,0x0A,0x03,0x60,0xA9,0x4E,0xD0, +0xDD,0xA9,0xCC,0x8D,0xEE,0x02,0xA9,0x05,0x8D,0xEF,0x02,0x60,0xA5,0x2B,0x85,0x3E, +0xA5,0x2A,0x29,0x0C,0xC9,0x04,0xF0,0x05,0xC9,0x08,0xF0,0x39,0x60,0xA9,0x00,0x8D, +0x89,0x02,0x85,0x3F,0xA9,0x01,0x20,0x58,0xF0,0x30,0x24,0xA9,0x34,0x8D,0x02,0xD3, +0xA0,0x40,0xA2,0x02,0xA9,0x03,0x8D,0x2A,0x02,0x20,0x5C,0xE4,0xAD,0x2A,0x02,0xD0, +0xFB,0xA9,0x80,0x85,0x3D,0x8D,0x8A,0x02,0x4C,0xD3,0xEF,0xA0,0x80,0xC6,0x11,0xA9, +0x00,0x8D,0x89,0x02,0x60,0xA9,0x80,0x8D,0x89,0x02,0xA9,0x02,0x20,0x58,0xF0,0x30, +0xEE,0xA9,0xCC,0x8D,0x04,0xD2,0xA9,0x05,0x8D,0x06,0xD2,0xA9,0x60,0x8D,0x00,0x03, +0x20,0x68,0xE4,0xA9,0x34,0x8D,0x02,0xD3,0xA9,0x03,0xA2,0x04,0xA0,0x80,0x20,0x5C, +0xE4,0xA9,0xFF,0x8D,0x2A,0x02,0xA5,0x11,0xF0,0xC1,0xAD,0x2A,0x02,0xD0,0xF7,0xA9, +0x00,0x85,0x3D,0xA0,0x01,0x60,0xA5,0x3F,0x30,0x33,0xA6,0x3D,0xEC,0x8A,0x02,0xF0, +0x08,0xBD,0x00,0x04,0xE6,0x3D,0xA0,0x01,0x60,0xA9,0x52,0x20,0x95,0xF0,0x98,0x30, +0xF7,0xA9,0x00,0x85,0x3D,0xA2,0x80,0xAD,0xFF,0x03,0xC9,0xFE,0xF0,0x0D,0xC9,0xFA, +0xD0,0x03,0xAE,0x7F,0x04,0x8E,0x8A,0x02,0x4C,0xD6,0xEF,0xC6,0x3F,0xA0,0x88,0x60, +0xA6,0x3D,0x9D,0x00,0x04,0xE6,0x3D,0xA0,0x01,0xE0,0x7F,0xF0,0x01,0x60,0xA9,0xFC, +0x20,0xD2,0xF0,0xA9,0x00,0x85,0x3D,0x60,0xA0,0x01,0x60,0xAD,0x89,0x02,0x30,0x08, +0xA0,0x01,0xA9,0x3C,0x8D,0x02,0xD3,0x60,0xA6,0x3D,0xF0,0x0A,0x8E,0x7F,0x04,0xA9, +0xFA,0x20,0xD2,0xF0,0x30,0xEC,0xA2,0x7F,0xA9,0x00,0x9D,0x00,0x04,0xCA,0x10,0xFA, +0xA9,0xFE,0x20,0xD2,0xF0,0x4C,0x32,0xF0,0x85,0x40,0xA5,0x14,0x18,0x69,0x1E,0xAA, +0xA9,0xFF,0x8D,0x1F,0xD0,0xA9,0x00,0xA0,0xF0,0x88,0xD0,0xFD,0x8D,0x1F,0xD0,0xA0, +0xF0,0x88,0xD0,0xFD,0xE4,0x14,0xD0,0xE8,0xC6,0x40,0xF0,0x0B,0x8A,0x18,0x69,0x0A, +0xAA,0xE4,0x14,0xD0,0xFC,0xF0,0xD3,0x20,0x8C,0xF0,0x98,0x60,0xAD,0x25,0xE4,0x48, +0xAD,0x24,0xE4,0x48,0x60,0x8D,0x02,0x03,0xA9,0x00,0x8D,0x09,0x03,0xA9,0x83,0x8D, +0x08,0x03,0xA9,0x03,0x8D,0x05,0x03,0xA9,0xFD,0x8D,0x04,0x03,0xA9,0x60,0x8D,0x00, +0x03,0xA9,0x00,0x8D,0x01,0x03,0xA9,0x23,0x8D,0x06,0x03,0xAD,0x02,0x03,0xA0,0x40, +0xC9,0x52,0xF0,0x02,0xA0,0x80,0x8C,0x03,0x03,0xA5,0x3E,0x8D,0x0B,0x03,0x20,0x59, +0xE4,0x60,0x8D,0xFF,0x03,0xA9,0x55,0x8D,0xFD,0x03,0x8D,0xFE,0x03,0xA9,0x57,0x20, +0x95,0xF0,0x60,0x50,0x30,0xE4,0x43,0x40,0xE4,0x45,0x00,0xE4,0x53,0x10,0xE4,0x4B, +0x20,0xE4,0x7D,0x41,0x54,0x41,0x52,0x49,0x20,0x43,0x4F,0x4D,0x50,0x55,0x54,0x45, +0x52,0x20,0x2D,0x20,0x4D,0x45,0x4D,0x4F,0x20,0x50,0x41,0x44,0x9B,0x42,0x4F,0x4F, +0x54,0x20,0x45,0x52,0x52,0x4F,0x52,0x9B,0x45,0x3A,0x9B,0x78,0xAD,0x44,0x02,0xD0, +0x04,0xA9,0xFF,0xD0,0x03,0x78,0xA9,0x00,0x85,0x08,0xD8,0xA2,0xFF,0x9A,0x20,0x44, +0xF2,0x20,0x77,0xF2,0xA5,0x08,0xD0,0x28,0xA9,0x00,0xA0,0x08,0x85,0x04,0x85,0x05, +0x91,0x04,0xC8,0xC0,0x00,0xD0,0xF9,0xE6,0x05,0xA6,0x05,0xE4,0x06,0xD0,0xF1,0xAD, +0x72,0xE4,0x85,0x0A,0xAD,0x73,0xE4,0x85,0x0B,0xA9,0xFF,0x8D,0x44,0x02,0xD0,0x13, +0xA2,0x00,0x8A,0x9D,0x00,0x02,0x9D,0x00,0x03,0xCA,0xD0,0xF7,0xA2,0x10,0x95,0x00, +0xE8,0x10,0xFB,0xA9,0x02,0x85,0x52,0xA9,0x27,0x85,0x53,0xA2,0x25,0xBD,0x80,0xE4, +0x9D,0x00,0x02,0xCA,0x10,0xF7,0x20,0x8A,0xF2,0x58,0xA2,0x0E,0xBD,0xE3,0xF0,0x9D, +0x1A,0x03,0xCA,0x10,0xF7,0xA2,0x00,0x86,0x07,0x86,0x06,0xAE,0xE4,0x02,0xE0,0x90, +0xB0,0x0A,0xAD,0xFC,0x9F,0xD0,0x05,0xE6,0x07,0x20,0x3C,0xF2,0xAE,0xE4,0x02,0xE0, +0xB0,0xB0,0x0A,0xAE,0xFC,0xBF,0xD0,0x05,0xE6,0x06,0x20,0x39,0xF2,0xA9,0x03,0xA2, +0x00,0x9D,0x42,0x03,0xA9,0x18,0x9D,0x44,0x03,0xA9,0xF1,0x9D,0x45,0x03,0xA9,0x0C, +0x9D,0x4A,0x03,0x20,0x56,0xE4,0x10,0x03,0x4C,0x25,0xF1,0xE8,0xD0,0xFD,0xC8,0x10, +0xFA,0x20,0xB2,0xF3,0xA5,0x06,0x05,0x07,0xF0,0x12,0xA5,0x06,0xF0,0x03,0xAD,0xFD, +0xBF,0xA6,0x07,0xF0,0x03,0x0D,0xFD,0x9F,0x29,0x01,0xF0,0x03,0x20,0xCF,0xF2,0xA9, +0x00,0x8D,0x44,0x02,0xA5,0x06,0xF0,0x0A,0xAD,0xFD,0xBF,0x29,0x04,0xF0,0x03,0x6C, +0xFA,0xBF,0xA5,0x07,0xF0,0x0A,0xAD,0xFD,0x9F,0x29,0x04,0xF0,0xDF,0x6C,0xFA,0x9F, +0x6C,0x0A,0x00,0xA2,0xF2,0xA0,0xF0,0x20,0x85,0xF3,0x20,0x30,0xF2,0x4C,0x2A,0xF2, +0xAD,0x05,0xE4,0x48,0xAD,0x04,0xE4,0x48,0x60,0x6C,0xFE,0xBF,0x6C,0xFE,0x9F,0xC9, +0xD0,0xD0,0x1C,0x60,0xEE,0xFC,0xBF,0xAD,0xFC,0xBF,0xD0,0x08,0xAD,0xFD,0xBF,0x10, +0x03,0x6C,0xFE,0xBF,0xCE,0xFC,0xBF,0xA0,0x00,0x84,0x05,0xA9,0x10,0x85,0x06,0xB1, +0x05,0x49,0xFF,0x91,0x05,0xD1,0x05,0xD0,0xDA,0x49,0xFF,0x91,0x05,0xA5,0x06,0x18, +0x69,0x10,0x85,0x06,0x4C,0x3F,0xF2,0xA9,0x00,0xAA,0x9D,0x00,0xD0,0x9D,0x00,0xD4, +0x9D,0x00,0xD2,0xEA,0xEA,0xEA,0xE8,0xD0,0xF1,0x60,0xC6,0x11,0xA9,0x54,0x8D,0x36, +0x02,0xA9,0xE7,0x8D,0x37,0x02,0xA5,0x06,0x8D,0xE4,0x02,0x8D,0xE6,0x02,0xA9,0x00, +0x8D,0xE5,0x02,0xA9,0x00,0x8D,0xE7,0x02,0xA9,0x07,0x8D,0xE8,0x02,0x20,0x0C,0xE4, +0x20,0x1C,0xE4,0x20,0x2C,0xE4,0x20,0x3C,0xE4,0x20,0x4C,0xE4,0x20,0x6E,0xE4,0x20, +0x65,0xE4,0x20,0x6B,0xE4,0xAD,0x1F,0xD0,0x29,0x01,0xD0,0x02,0xE6,0x4A,0x60,0xA5, +0x08,0xF0,0x0A,0xA5,0x09,0x29,0x01,0xF0,0x03,0x20,0x7E,0xF3,0x60,0xA9,0x01,0x8D, +0x01,0x03,0xA9,0x53,0x8D,0x02,0x03,0x20,0x53,0xE4,0x10,0x01,0x60,0xA9,0x00,0x8D, +0x0B,0x03,0xA9,0x01,0x8D,0x0A,0x03,0xA9,0x00,0x8D,0x04,0x03,0xA9,0x04,0x8D,0x05, +0x03,0x20,0x9D,0xF3,0x10,0x08,0x20,0x81,0xF3,0xA5,0x4B,0xF0,0xE0,0x60,0xA2,0x03, +0xBD,0x00,0x04,0x9D,0x40,0x02,0xCA,0x10,0xF7,0xAD,0x42,0x02,0x85,0x04,0xAD,0x43, +0x02,0x85,0x05,0xAD,0x04,0x04,0x85,0x0C,0xAD,0x05,0x04,0x85,0x0D,0xA0,0x7F,0xB9, +0x00,0x04,0x91,0x04,0x88,0x10,0xF8,0x18,0xA5,0x04,0x69,0x80,0x85,0x04,0xA5,0x05, +0x69,0x00,0x85,0x05,0xCE,0x41,0x02,0xF0,0x11,0xEE,0x0A,0x03,0x20,0x9D,0xF3,0x10, +0xDC,0x20,0x81,0xF3,0xA5,0x4B,0xD0,0xAE,0xF0,0xF2,0xA5,0x4B,0xF0,0x03,0x20,0x9D, +0xF3,0x20,0x6C,0xF3,0xB0,0xA0,0x20,0x7E,0xF3,0xE6,0x09,0x60,0x18,0xAD,0x42,0x02, +0x69,0x06,0x85,0x04,0xAD,0x43,0x02,0x69,0x00,0x85,0x05,0x6C,0x04,0x00,0x6C,0x0C, +0x00,0xA2,0x0D,0xA0,0xF1,0x8A,0xA2,0x00,0x9D,0x44,0x03,0x98,0x9D,0x45,0x03,0xA9, +0x09,0x9D,0x42,0x03,0xA9,0xFF,0x9D,0x48,0x03,0x20,0x56,0xE4,0x60,0xA5,0x4B,0xF0, +0x03,0x4C,0x7A,0xE4,0xA9,0x52,0x8D,0x02,0x03,0xA9,0x01,0x8D,0x01,0x03,0x20,0x53, +0xE4,0x60,0xA5,0x08,0xF0,0x0A,0xA5,0x09,0x29,0x02,0xF0,0x03,0x20,0xE1,0xF3,0x60, +0xA5,0x4A,0xF0,0x1C,0xA9,0x80,0x85,0x3E,0xE6,0x4B,0x20,0x7D,0xE4,0x20,0x01,0xF3, +0xA9,0x00,0x85,0x4B,0x85,0x4A,0x06,0x09,0xA5,0x0C,0x85,0x02,0xA5,0x0D,0x85,0x03, +0x60,0x6C,0x02,0x00,0xA9,0xFF,0x8D,0xFC,0x02,0xAD,0xE6,0x02,0x29,0xF0,0x85,0x6A, +0xA9,0x40,0x8D,0xBE,0x02,0x60,0xA5,0x2B,0x29,0x0F,0xD0,0x08,0xA5,0x2A,0x29,0x0F, +0x85,0x2A,0xA9,0x00,0x85,0x57,0xA9,0xE0,0x8D,0xF4,0x02,0xA9,0x02,0x8D,0xF3,0x02, +0x8D,0x2F,0x02,0xA9,0x01,0x85,0x4C,0xA9,0xC0,0x05,0x10,0x85,0x10,0x8D,0x0E,0xD2, +0xA9,0x00,0x8D,0x93,0x02,0x85,0x64,0x85,0x7B,0x8D,0xF0,0x02,0xA0,0x0E,0xA9,0x01, +0x99,0xA3,0x02,0x88,0x10,0xFA,0xA2,0x04,0xBD,0xC1,0xFE,0x9D,0xC4,0x02,0xCA,0x10, +0xF7,0xA4,0x6A,0x88,0x8C,0x95,0x02,0xA9,0x60,0x8D,0x94,0x02,0xA6,0x57,0xBD,0x69, +0xFE,0xD0,0x04,0xA9,0x91,0x85,0x4C,0x85,0x51,0xA5,0x6A,0x85,0x65,0xBC,0x45,0xFE, +0xA9,0x28,0x20,0x21,0xF9,0x88,0xD0,0xF8,0xAD,0x6F,0x02,0x29,0x3F,0x85,0x67,0xA8, +0xE0,0x08,0x90,0x17,0x8A,0x6A,0x6A,0x6A,0x29,0xC0,0x05,0x67,0xA8,0xA9,0x10,0x20, +0x21,0xF9,0xE0,0x0B,0xD0,0x05,0xA9,0x06,0x8D,0xC8,0x02,0x8C,0x6F,0x02,0xA5,0x64, +0x85,0x58,0xA5,0x65,0x85,0x59,0xAD,0x0B,0xD4,0xC9,0x7A,0xD0,0xF9,0x20,0x1F,0xF9, +0xBD,0x75,0xFE,0xF0,0x06,0xA9,0xFF,0x85,0x64,0xC6,0x65,0xA5,0x64,0x85,0x68,0xA5, +0x65,0x85,0x69,0x20,0x13,0xF9,0xA9,0x41,0x20,0x17,0xF9,0x86,0x66,0xA9,0x18,0x8D, +0xBF,0x02,0xA5,0x57,0xC9,0x09,0xB0,0x2D,0xA5,0x2A,0x29,0x10,0xF0,0x27,0xA9,0x04, +0x8D,0xBF,0x02,0xA2,0x02,0xA9,0x02,0x20,0x17,0xF9,0xCA,0x10,0xF8,0xA4,0x6A,0x88, +0x98,0x20,0x17,0xF9,0xA9,0x60,0x20,0x17,0xF9,0xA9,0x42,0x20,0x17,0xF9,0x18,0xA9, +0x0C,0x65,0x66,0x85,0x66,0xA4,0x66,0xBE,0x51,0xFE,0xA5,0x51,0x20,0x17,0xF9,0xCA, +0xD0,0xF8,0xA5,0x57,0xC9,0x08,0x90,0x1C,0xA2,0x5D,0xA5,0x6A,0x38,0xE9,0x10,0x20, +0x17,0xF9,0xA9,0x00,0x20,0x17,0xF9,0xA9,0x4F,0x20,0x17,0xF9,0xA5,0x51,0x20,0x17, +0xF9,0xCA,0xD0,0xF8,0xA5,0x59,0x20,0x17,0xF9,0xA5,0x58,0x20,0x17,0xF9,0xA5,0x51, +0x09,0x40,0x20,0x17,0xF9,0xA9,0x70,0x20,0x17,0xF9,0xA9,0x70,0x20,0x17,0xF9,0xA5, +0x64,0x8D,0x30,0x02,0xA5,0x65,0x8D,0x31,0x02,0xA9,0x70,0x20,0x17,0xF9,0xA5,0x64, +0x8D,0xE5,0x02,0xA5,0x65,0x8D,0xE6,0x02,0xA5,0x68,0x85,0x64,0xA5,0x69,0x85,0x65, +0xAD,0x31,0x02,0x20,0x17,0xF9,0xAD,0x30,0x02,0x20,0x17,0xF9,0xA5,0x4C,0x10,0x07, +0x48,0x20,0xFC,0xF3,0x68,0xA8,0x60,0xA5,0x2A,0x29,0x20,0xD0,0x0B,0x20,0xB9,0xF7, +0x8D,0x90,0x02,0xA5,0x52,0x8D,0x91,0x02,0xA9,0x22,0x0D,0x2F,0x02,0x8D,0x2F,0x02, +0x4C,0x21,0xF6,0x20,0x96,0xFA,0x20,0xA2,0xF5,0x20,0x32,0xFB,0x20,0xD4,0xF9,0x4C, +0x34,0xF6,0x20,0x47,0xF9,0xB1,0x64,0x2D,0xA0,0x02,0x46,0x6F,0xB0,0x03,0x4A,0x10, +0xF9,0x8D,0xFA,0x02,0xC9,0x00,0x60,0x8D,0xFB,0x02,0x20,0x96,0xFA,0xAD,0xFB,0x02, +0xC9,0x7D,0xD0,0x06,0x20,0xB9,0xF7,0x4C,0x21,0xF6,0xAD,0xFB,0x02,0xC9,0x9B,0xD0, +0x06,0x20,0x30,0xFA,0x4C,0x21,0xF6,0x20,0xE0,0xF5,0x20,0xD8,0xF9,0x4C,0x21,0xF6, +0xAD,0xFF,0x02,0xD0,0xFB,0xA2,0x02,0xB5,0x54,0x95,0x5A,0xCA,0x10,0xF9,0xAD,0xFB, +0x02,0xA8,0x2A,0x2A,0x2A,0x2A,0x29,0x03,0xAA,0x98,0x29,0x9F,0x1D,0xF6,0xFE,0x8D, +0xFA,0x02,0x20,0x47,0xF9,0xAD,0xFA,0x02,0x46,0x6F,0xB0,0x04,0x0A,0x4C,0x08,0xF6, +0x2D,0xA0,0x02,0x85,0x50,0xAD,0xA0,0x02,0x49,0xFF,0x31,0x64,0x05,0x50,0x91,0x64, +0x60,0x20,0xA2,0xF5,0x85,0x5D,0xA6,0x57,0xD0,0x0A,0xAE,0xF0,0x02,0xD0,0x05,0x49, +0x80,0x20,0xFF,0xF5,0xA4,0x4C,0xA9,0x01,0x85,0x4C,0xAD,0xFB,0x02,0x60,0x20,0xB3, +0xFC,0x20,0x88,0xFA,0xA5,0x6B,0xD0,0x34,0xA5,0x54,0x85,0x6C,0xA5,0x55,0x85,0x6D, +0x20,0xE2,0xF6,0x84,0x4C,0xAD,0xFB,0x02,0xC9,0x9B,0xF0,0x12,0x20,0xAD,0xF6,0x20, +0xB3,0xFC,0xA5,0x63,0xC9,0x71,0xD0,0x03,0x20,0x0A,0xF9,0x4C,0x50,0xF6,0x20,0xE4, +0xFA,0x20,0x00,0xFC,0xA5,0x6C,0x85,0x54,0xA5,0x6D,0x85,0x55,0xA5,0x6B,0xF0,0x11, +0xC6,0x6B,0xF0,0x0D,0xA5,0x4C,0x30,0xF8,0x20,0x93,0xF5,0x8D,0xFB,0x02,0x4C,0xB3, +0xFC,0x20,0x30,0xFA,0xA9,0x9B,0x8D,0xFB,0x02,0x20,0x21,0xF6,0x84,0x4C,0x4C,0xB3, +0xFC,0x6C,0x64,0x00,0x8D,0xFB,0x02,0x20,0xB3,0xFC,0x20,0x88,0xFA,0x20,0xE4,0xFA, +0x20,0x8D,0xFC,0xF0,0x09,0x0E,0xA2,0x02,0x20,0xCA,0xF5,0x4C,0xB3,0xFC,0xAD,0xFE, +0x02,0x0D,0xA2,0x02,0xD0,0xEF,0x0E,0xA2,0x02,0xE8,0xBD,0xC6,0xFE,0x85,0x64,0xBD, +0xC7,0xFE,0x85,0x65,0x20,0xA1,0xF6,0x20,0x21,0xF6,0x4C,0xB3,0xFC,0xA9,0xFF,0x8D, +0xFC,0x02,0xA5,0x2A,0x4A,0xB0,0x62,0xA9,0x80,0xA6,0x11,0xF0,0x58,0xAD,0xFC,0x02, +0xC9,0xFF,0xF0,0xEE,0x85,0x7C,0xA2,0xFF,0x8E,0xFC,0x02,0x20,0xD8,0xFC,0xAA,0xE0, +0xC0,0x90,0x02,0xA2,0x03,0xBD,0xFE,0xFE,0x8D,0xFB,0x02,0xC9,0x80,0xF0,0xCE,0xC9, +0x81,0xD0,0x0B,0xAD,0xB6,0x02,0x49,0x80,0x8D,0xB6,0x02,0x4C,0xDD,0xF6,0xC9,0x82, +0xD0,0x07,0xA9,0x00,0x8D,0xBE,0x02,0xF0,0xB4,0xC9,0x83,0xD0,0x07,0xA9,0x40,0x8D, +0xBE,0x02,0xD0,0xA9,0xC9,0x84,0xD0,0x07,0xA9,0x80,0x8D,0xBE,0x02,0xD0,0x9E,0xC9, +0x85,0xD0,0x0A,0xA9,0x88,0x85,0x4C,0x85,0x11,0xA9,0x9B,0xD0,0x26,0xA5,0x7C,0xC9, +0x40,0xB0,0x15,0xAD,0xFB,0x02,0xC9,0x61,0x90,0x0E,0xC9,0x7B,0xB0,0x0A,0xAD,0xBE, +0x02,0xF0,0x05,0x05,0x7C,0x4C,0xFE,0xF6,0x20,0x8D,0xFC,0xF0,0x09,0xAD,0xFB,0x02, +0x4D,0xB6,0x02,0x8D,0xFB,0x02,0x4C,0x34,0xF6,0xA9,0x80,0x8D,0xA2,0x02,0x60,0xC6, +0x54,0x10,0x06,0xAE,0xBF,0x02,0xCA,0x86,0x54,0x4C,0x5C,0xFC,0xE6,0x54,0xA5,0x54, +0xCD,0xBF,0x02,0x90,0xF4,0xA2,0x00,0xF0,0xEE,0xC6,0x55,0xA5,0x55,0x30,0x04,0xC5, +0x52,0xB0,0x04,0xA5,0x53,0x85,0x55,0x4C,0xDD,0xFB,0xE6,0x55,0xA5,0x55,0xC5,0x53, +0x90,0xF5,0xF0,0xF3,0xA5,0x52,0x4C,0xA5,0xF7,0x20,0xF3,0xFC,0xA0,0x00,0x98,0x91, +0x64,0xC8,0xD0,0xFB,0xE6,0x65,0xA6,0x65,0xE4,0x6A,0x90,0xF3,0xA9,0xFF,0x99,0xB2, +0x02,0xC8,0xC0,0x04,0x90,0xF8,0x20,0xE4,0xFC,0x85,0x63,0x85,0x6D,0xA9,0x00,0x85, +0x54,0x85,0x56,0x85,0x6C,0x60,0xA5,0x63,0xC5,0x52,0xF0,0x21,0xA5,0x55,0xC5,0x52, +0xD0,0x03,0x20,0x73,0xFC,0x20,0x99,0xF7,0xA5,0x55,0xC5,0x53,0xD0,0x07,0xA5,0x54, +0xF0,0x03,0x20,0x7F,0xF7,0xA9,0x20,0x8D,0xFB,0x02,0x20,0xE0,0xF5,0x4C,0xDD,0xFB, +0x20,0xAA,0xF7,0xA5,0x55,0xC5,0x52,0xD0,0x0A,0x20,0x34,0xFA,0x20,0x20,0xFB,0x90, +0x02,0xB0,0x07,0xA5,0x63,0x20,0x25,0xFB,0x90,0xE6,0x4C,0xDD,0xFB,0xA5,0x63,0x4C, +0x06,0xFB,0xA5,0x63,0x4C,0x12,0xFB,0x20,0x9D,0xFC,0x20,0xA2,0xF5,0x85,0x7D,0xA9, +0x00,0x8D,0xBB,0x02,0x20,0xFF,0xF5,0xA5,0x63,0x48,0x20,0xDC,0xF9,0x68,0xC5,0x63, +0xB0,0x0C,0xA5,0x7D,0x48,0x20,0xA2,0xF5,0x85,0x7D,0x68,0x4C,0x44,0xF8,0x20,0xA8, +0xFC,0xCE,0xBB,0x02,0x30,0x04,0xC6,0x54,0xD0,0xF7,0x4C,0xDD,0xFB,0x20,0x9D,0xFC, +0x20,0x47,0xF9,0xA5,0x64,0x85,0x68,0xA5,0x65,0x85,0x69,0xA5,0x63,0x48,0x20,0xD4, +0xF9,0x68,0xC5,0x63,0xB0,0x10,0xA5,0x54,0xCD,0xBF,0x02,0xB0,0x09,0x20,0xA2,0xF5, +0xA0,0x00,0x91,0x68,0xF0,0xDA,0xA0,0x00,0x98,0x91,0x68,0x20,0x68,0xFC,0x20,0xA8, +0xFC,0x4C,0xDD,0xFB,0x38,0x20,0x7B,0xFB,0xA5,0x52,0x85,0x55,0x20,0x47,0xF9,0xA5, +0x64,0x85,0x68,0x18,0x69,0x28,0x85,0x66,0xA5,0x65,0x85,0x69,0x69,0x00,0x85,0x67, +0xA6,0x54,0xE0,0x17,0xF0,0x08,0x20,0x4E,0xFB,0xE8,0xE0,0x17,0xD0,0xF8,0x20,0x9B, +0xFB,0x4C,0xDD,0xFB,0x20,0xDD,0xFB,0xA4,0x51,0x84,0x54,0xA4,0x54,0x98,0x38,0x20, +0x23,0xFB,0x08,0x98,0x18,0x69,0x78,0x28,0x20,0x04,0xFB,0xC8,0xC0,0x18,0xD0,0xED, +0xAD,0xB4,0x02,0x09,0x01,0x8D,0xB4,0x02,0xA5,0x52,0x85,0x55,0x20,0x47,0xF9,0x20, +0xB7,0xFB,0x20,0x20,0xFB,0x90,0xD4,0x4C,0xDD,0xFB,0x60,0x20,0x20,0xD8,0xFC,0x88, +0x10,0xFA,0x60,0xA9,0x02,0xD0,0x0A,0xA4,0x4C,0x30,0x2B,0xA0,0x00,0x91,0x64,0xA9, +0x01,0x8D,0x9E,0x02,0xA5,0x4C,0x30,0x1E,0xA5,0x64,0x38,0xED,0x9E,0x02,0x85,0x64, +0xB0,0x02,0xC6,0x65,0xA5,0x0F,0xC5,0x65,0x90,0x0C,0xD0,0x06,0xA5,0x0E,0xC5,0x64, +0x90,0x04,0xA9,0x93,0x85,0x4C,0x60,0xA5,0x54,0x48,0xA5,0x55,0x48,0xA5,0x56,0x48, +0x20,0xF3,0xFC,0xA5,0x54,0x85,0x66,0xA9,0x00,0x85,0x67,0xA5,0x66,0x0A,0x26,0x67, +0x85,0x51,0xA4,0x67,0x8C,0x9F,0x02,0x0A,0x26,0x67,0x0A,0x26,0x67,0x18,0x65,0x51, +0x85,0x66,0xA5,0x67,0x6D,0x9F,0x02,0x85,0x67,0xA6,0x57,0xBC,0x81,0xFE,0x88,0x30, +0x07,0x06,0x66,0x26,0x67,0x4C,0x7E,0xF9,0xBC,0xA5,0xFE,0xA5,0x55,0xA2,0x07,0x88, +0x30,0x0A,0xCA,0x46,0x56,0x6A,0x6E,0xA1,0x02,0x4C,0x8F,0xF9,0xC8,0x18,0x65,0x66, +0x85,0x66,0x90,0x02,0xE6,0x67,0x38,0x6E,0xA1,0x02,0x18,0xCA,0x10,0xF9,0xAE,0xA1, +0x02,0xA5,0x66,0x18,0x65,0x64,0x85,0x64,0x85,0x5E,0xA5,0x67,0x65,0x65,0x85,0x65, +0x85,0x5F,0xBD,0xB1,0xFE,0x8D,0xA0,0x02,0x85,0x6F,0x68,0x85,0x56,0x68,0x85,0x55, +0x68,0x85,0x54,0x60,0xA9,0x00,0xF0,0x02,0xA9,0x9B,0x85,0x7D,0xE6,0x63,0xE6,0x55, +0xD0,0x02,0xE6,0x56,0xA5,0x55,0xA6,0x57,0xDD,0x8D,0xFE,0xF0,0x0B,0xE0,0x00,0xD0, +0x06,0xC5,0x53,0xF0,0x02,0xB0,0x01,0x60,0xE0,0x08,0x90,0x04,0xA5,0x56,0xF0,0xF7, +0xA5,0x57,0xD0,0x30,0xA5,0x63,0xC9,0x51,0x90,0x0A,0xA5,0x7D,0xF0,0x26,0x20,0x30, +0xFA,0x4C,0x77,0xFA,0x20,0x34,0xFA,0xA5,0x54,0x18,0x69,0x78,0x20,0x25,0xFB,0x90, +0x08,0xA5,0x7D,0xF0,0x04,0x18,0x20,0xA5,0xF8,0x4C,0xDD,0xFB,0xA9,0x00,0xF0,0x02, +0xA9,0x9B,0x85,0x7D,0x20,0xE4,0xFC,0xA9,0x00,0x85,0x56,0xE6,0x54,0xA6,0x57,0xA0, +0x18,0x24,0x7B,0x10,0x05,0xA0,0x04,0x98,0xD0,0x03,0xBD,0x99,0xFE,0xC5,0x54,0xD0, +0x26,0x8C,0x9D,0x02,0x8A,0xD0,0x20,0xA5,0x7D,0xF0,0x1C,0xC9,0x9B,0x38,0xF0,0x01, +0x18,0x20,0xAC,0xFB,0xEE,0xBB,0x02,0xC6,0x6C,0xCE,0x9D,0x02,0xAD,0xB2,0x02,0x38, +0x10,0xEF,0xAD,0x9D,0x02,0x85,0x54,0x4C,0xDD,0xFB,0x38,0xB5,0x70,0xE5,0x74,0x95, +0x70,0xB5,0x71,0xE5,0x75,0x95,0x71,0x60,0xAD,0xBF,0x02,0xC9,0x04,0xF0,0x07,0xA5, +0x57,0xF0,0x03,0x20,0xFC,0xF3,0xA9,0x27,0xC5,0x53,0xB0,0x02,0x85,0x53,0xA6,0x57, +0xBD,0x99,0xFE,0xC5,0x54,0x90,0x2A,0xF0,0x28,0xE0,0x08,0xD0,0x0A,0xA5,0x56,0xF0, +0x13,0xC9,0x01,0xD0,0x1C,0xF0,0x04,0xA5,0x56,0xD0,0x16,0xBD,0x8D,0xFE,0xC5,0x55, +0x90,0x0F,0xF0,0x0D,0xA9,0x01,0x85,0x4C,0xA9,0x80,0xA6,0x11,0x85,0x11,0xF0,0x06, +0x60,0x20,0xD6,0xF7,0xA9,0x8D,0x85,0x4C,0x68,0x68,0xA5,0x7B,0x10,0x03,0x20,0xB9, +0xFC,0x4C,0x34,0xF6,0xA0,0x00,0xA5,0x5D,0x91,0x5E,0x60,0x48,0x29,0x07,0xAA,0xBD, +0xB9,0xFE,0x85,0x6E,0x68,0x4A,0x4A,0x4A,0xAA,0x60,0x2E,0xB4,0x02,0x2E,0xB3,0x02, +0x2E,0xB2,0x02,0x60,0x90,0x0C,0x20,0xEB,0xFA,0xBD,0xA3,0x02,0x05,0x6E,0x9D,0xA3, +0x02,0x60,0x20,0xEB,0xFA,0xA5,0x6E,0x49,0xFF,0x3D,0xA3,0x02,0x9D,0xA3,0x02,0x60, +0xA5,0x54,0x18,0x69,0x78,0x20,0xEB,0xFA,0x18,0xBD,0xA3,0x02,0x25,0x6E,0xF0,0x01, +0x38,0x60,0xAD,0xFA,0x02,0xA4,0x57,0xC0,0x03,0xB0,0x0F,0x2A,0x2A,0x2A,0x2A,0x29, +0x03,0xAA,0xAD,0xFA,0x02,0x29,0x9F,0x1D,0xFA,0xFE,0x8D,0xFB,0x02,0x60,0xA9,0x02, +0x85,0x65,0xA9,0x47,0x85,0x64,0xA0,0x27,0xB1,0x66,0x85,0x50,0xB1,0x68,0x91,0x66, +0xA5,0x50,0x91,0x64,0x88,0x10,0xF1,0xA5,0x65,0x85,0x69,0xA5,0x64,0x85,0x68,0x18, +0xA5,0x66,0x69,0x28,0x85,0x66,0x90,0x02,0xE6,0x67,0x60,0x08,0xA0,0x17,0x98,0x20, +0x22,0xFB,0x08,0x98,0x18,0x69,0x79,0x28,0x20,0x04,0xFB,0x88,0x30,0x04,0xC4,0x54, +0xB0,0xEC,0xA5,0x54,0x18,0x69,0x78,0x28,0x4C,0x04,0xFB,0xA5,0x52,0x85,0x55,0x20, +0x47,0xF9,0xA0,0x27,0xA9,0x00,0x91,0x64,0x88,0x10,0xFB,0x60,0x20,0xFA,0xFA,0xA5, +0x58,0x85,0x64,0xA5,0x59,0x85,0x65,0xA0,0x28,0xB1,0x64,0xA6,0x6A,0xCA,0xE4,0x65, +0xD0,0x08,0xA2,0xD7,0xE4,0x64,0xB0,0x02,0xA9,0x00,0xA0,0x00,0x91,0x64,0xE6,0x64, +0xD0,0xE5,0xE6,0x65,0xA5,0x65,0xC5,0x6A,0xD0,0xDD,0x4C,0xDD,0xFB,0xA9,0x00,0x85, +0x63,0xA5,0x54,0x85,0x51,0xA5,0x51,0x20,0x22,0xFB,0xB0,0x0C,0xA5,0x63,0x18,0x69, +0x28,0x85,0x63,0xC6,0x51,0x4C,0xE5,0xFB,0x18,0xA5,0x63,0x65,0x55,0x85,0x63,0x60, +0x20,0x9D,0xFC,0xA5,0x63,0x48,0xA5,0x6C,0x85,0x54,0xA5,0x6D,0x85,0x55,0xA9,0x01, +0x85,0x6B,0xA2,0x17,0xA5,0x7B,0x10,0x02,0xA2,0x03,0xE4,0x54,0xD0,0x0B,0xA5,0x55, +0xC5,0x53,0xD0,0x05,0xE6,0x6B,0x4C,0x39,0xFC,0x20,0xD4,0xF9,0xE6,0x6B,0xA5,0x63, +0xC5,0x52,0xD0,0xDE,0xC6,0x54,0x20,0x99,0xF7,0x20,0xA2,0xF5,0xD0,0x17,0xC6,0x6B, +0xA5,0x63,0xC5,0x52,0xF0,0x0F,0x20,0x99,0xF7,0xA5,0x55,0xC5,0x53,0xD0,0x02,0xC6, +0x54,0xA5,0x6B,0xD0,0xE4,0x68,0x85,0x63,0x20,0xA8,0xFC,0x60,0x20,0xDD,0xFB,0xA5, +0x51,0x85,0x6C,0xA5,0x52,0x85,0x6D,0x60,0xA5,0x63,0xC5,0x52,0xD0,0x02,0xC6,0x54, +0x20,0xDD,0xFB,0xA5,0x63,0xC5,0x52,0xF0,0x13,0x20,0x47,0xF9,0xA5,0x53,0x38,0xE5, +0x52,0xA8,0xB1,0x64,0xD0,0x06,0x88,0x10,0xF9,0x4C,0xDB,0xF8,0x60,0xA2,0x2D,0xBD, +0xC6,0xFE,0xCD,0xFB,0x02,0xF0,0x05,0xCA,0xCA,0xCA,0x10,0xF3,0x60,0xA2,0x02,0xB5, +0x54,0x9D,0xB8,0x02,0xCA,0x10,0xF8,0x60,0xA2,0x02,0xBD,0xB8,0x02,0x95,0x54,0xCA, +0x10,0xF8,0x60,0x20,0xB9,0xFC,0x4C,0x34,0xF6,0xAD,0xBF,0x02,0xC9,0x18,0xF0,0x17, +0xA2,0x0B,0xB5,0x54,0x48,0xBD,0x90,0x02,0x95,0x54,0x68,0x9D,0x90,0x02,0xCA,0x10, +0xF1,0xA5,0x7B,0x49,0xFF,0x85,0x7B,0x60,0xA2,0x7F,0x8E,0x1F,0xD0,0x8E,0x0A,0xD4, +0xCA,0x10,0xF7,0x60,0xA9,0x00,0xA6,0x7B,0xD0,0x04,0xA6,0x57,0xD0,0x02,0xA5,0x52, +0x85,0x55,0x60,0xA5,0x58,0x85,0x64,0xA5,0x59,0x85,0x65,0x60,0xA2,0x00,0xA5,0x22, +0xC9,0x11,0xF0,0x08,0xC9,0x12,0xF0,0x03,0xA0,0x84,0x60,0xE8,0x8E,0xB7,0x02,0xA5, +0x54,0x85,0x60,0xA5,0x55,0x85,0x61,0xA5,0x56,0x85,0x62,0xA9,0x01,0x85,0x79,0x85, +0x7A,0x38,0xA5,0x60,0xE5,0x5A,0x85,0x76,0xB0,0x0D,0xA9,0xFF,0x85,0x79,0xA5,0x76, +0x49,0xFF,0x18,0x69,0x01,0x85,0x76,0x38,0xA5,0x61,0xE5,0x5B,0x85,0x77,0xA5,0x62, +0xE5,0x5C,0x85,0x78,0xB0,0x16,0xA9,0xFF,0x85,0x7A,0xA5,0x77,0x49,0xFF,0x85,0x77, +0xA5,0x78,0x49,0xFF,0x85,0x78,0xE6,0x77,0xD0,0x02,0xE6,0x78,0xA2,0x02,0xA0,0x00, +0x84,0x73,0x98,0x95,0x70,0xB5,0x5A,0x95,0x54,0xCA,0x10,0xF6,0xA5,0x77,0xE8,0xA8, +0xA5,0x78,0x85,0x7F,0x85,0x75,0xD0,0x0B,0xA5,0x77,0xC5,0x76,0xB0,0x05,0xA5,0x76, +0xA2,0x02,0xA8,0x98,0x85,0x7E,0x85,0x74,0x48,0xA5,0x75,0x4A,0x68,0x6A,0x95,0x70, +0xA5,0x7E,0x05,0x7F,0xD0,0x03,0x4C,0x42,0xFE,0x18,0xA5,0x70,0x65,0x76,0x85,0x70, +0x90,0x02,0xE6,0x71,0xA5,0x71,0xC5,0x75,0x90,0x14,0xD0,0x06,0xA5,0x70,0xC5,0x74, +0x90,0x0C,0x18,0xA5,0x54,0x65,0x79,0x85,0x54,0xA2,0x00,0x20,0x7A,0xFA,0x18,0xA5, +0x72,0x65,0x77,0x85,0x72,0xA5,0x73,0x65,0x78,0x85,0x73,0xC5,0x75,0x90,0x27,0xD0, +0x06,0xA5,0x72,0xC5,0x74,0x90,0x1F,0x24,0x7A,0x10,0x10,0xC6,0x55,0xA5,0x55,0xC9, +0xFF,0xD0,0x0E,0xA5,0x56,0xF0,0x0A,0xC6,0x56,0x10,0x06,0xE6,0x55,0xD0,0x02,0xE6, +0x56,0xA2,0x02,0x20,0x7A,0xFA,0x20,0x96,0xFA,0x20,0xE0,0xF5,0xAD,0xB7,0x02,0xF0, +0x2F,0x20,0x9D,0xFC,0xAD,0xFB,0x02,0x8D,0xBC,0x02,0xA5,0x54,0x48,0x20,0xDC,0xF9, +0x68,0x85,0x54,0x20,0x96,0xFA,0x20,0xA2,0xF5,0xD0,0x0C,0xAD,0xFD,0x02,0x8D,0xFB, +0x02,0x20,0xE0,0xF5,0x4C,0x0A,0xFE,0xAD,0xBC,0x02,0x8D,0xFB,0x02,0x20,0xA8,0xFC, +0x38,0xA5,0x7E,0xE9,0x01,0x85,0x7E,0xA5,0x7F,0xE9,0x00,0x85,0x7F,0x30,0x03,0x4C, +0x90,0xFD,0x4C,0x34,0xF6,0x18,0x10,0x0A,0x0A,0x10,0x1C,0x34,0x64,0xC4,0xC4,0xC4, +0xC4,0x17,0x17,0x0B,0x17,0x2F,0x2F,0x5F,0x5F,0x61,0x61,0x61,0x61,0x13,0x13,0x09, +0x13,0x27,0x27,0x4F,0x4F,0x41,0x41,0x41,0x41,0x02,0x06,0x07,0x08,0x09,0x0A,0x0B, +0x0D,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01, +0x01,0x02,0x01,0x01,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x28,0x14,0x14, +0x28,0x50,0x50,0xA0,0xA0,0x40,0x50,0x50,0x50,0x18,0x18,0x0C,0x18,0x30,0x30,0x60, +0x60,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x02,0x03,0x02,0x03,0x02,0x03,0x01,0x01, +0x01,0x00,0xFF,0xF0,0x0F,0xC0,0x30,0x0C,0x03,0x80,0x40,0x20,0x10,0x08,0x04,0x02, +0x01,0x28,0xCA,0x94,0x46,0x00,0x1B,0x79,0xF7,0x1C,0x7F,0xF7,0x1D,0x8C,0xF7,0x1E, +0x99,0xF7,0x1F,0xAA,0xF7,0x7D,0xB9,0xF7,0x7E,0xE6,0xF7,0x7F,0x10,0xF8,0x9B,0x30, +0xFA,0x9C,0xD4,0xF8,0x9D,0xA4,0xF8,0x9E,0x32,0xF8,0x9F,0x2D,0xF8,0xFD,0x0A,0xF9, +0xFE,0x6D,0xF8,0xFF,0x37,0xF8,0x40,0x00,0x20,0x60,0x20,0x40,0x00,0x60,0x6C,0x6A, +0x3B,0x80,0x80,0x6B,0x2B,0x2A,0x6F,0x80,0x70,0x75,0x9B,0x69,0x2D,0x3D,0x76,0x80, +0x63,0x80,0x80,0x62,0x78,0x7A,0x34,0x80,0x33,0x36,0x1B,0x35,0x32,0x31,0x2C,0x20, +0x2E,0x6E,0x80,0x6D,0x2F,0x81,0x72,0x80,0x65,0x79,0x7F,0x74,0x77,0x71,0x39,0x80, +0x30,0x37,0x7E,0x38,0x3C,0x3E,0x66,0x68,0x64,0x80,0x82,0x67,0x73,0x61,0x4C,0x4A, +0x3A,0x80,0x80,0x4B,0x5C,0x5E,0x4F,0x80,0x50,0x55,0x9B,0x49,0x5F,0x7C,0x56,0x80, +0x43,0x80,0x80,0x42,0x58,0x5A,0x24,0x80,0x23,0x26,0x1B,0x25,0x22,0x21,0x5B,0x20, +0x5D,0x4E,0x80,0x4D,0x3F,0x81,0x52,0x80,0x45,0x59,0x9F,0x54,0x57,0x51,0x28,0x80, +0x29,0x27,0x9C,0x40,0x7D,0x9D,0x46,0x48,0x44,0x80,0x83,0x47,0x53,0x41,0x0C,0x0A, +0x7B,0x80,0x80,0x0B,0x1E,0x1F,0x0F,0x80,0x10,0x15,0x9B,0x09,0x1C,0x1D,0x16,0x80, +0x03,0x80,0x80,0x02,0x18,0x1A,0x80,0x80,0x85,0x80,0x1B,0x80,0xFD,0x80,0x00,0x20, +0x60,0x0E,0x80,0x0D,0x80,0x81,0x12,0x80,0x05,0x19,0x9E,0x14,0x17,0x11,0x80,0x80, +0x80,0x80,0xFE,0x80,0x7D,0xFF,0x06,0x08,0x04,0x80,0x84,0x07,0x13,0x01,0xAD,0x09, +0xD2,0xCD,0xF2,0x02,0xD0,0x05,0xAD,0xF1,0x02,0xD0,0x20,0xAD,0x09,0xD2,0xC9,0x9F, +0xD0,0x0A,0xAD,0xFF,0x02,0x49,0xFF,0x8D,0xFF,0x02,0xB0,0x0F,0x8D,0xFC,0x02,0x8D, +0xF2,0x02,0xA9,0x03,0x8D,0xF1,0x02,0xA9,0x00,0x85,0x4D,0xA9,0x30,0x8D,0x2B,0x02, +0x68,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0xE6,0x91,0xE7,0x25,0xF1,0xF3,0xE6, +}; diff --git a/MCUME_teensy41/teensy800/romatarixl.h b/MCUME_teensy41/teensy800/romatarixl.h new file mode 100644 index 0000000..2582bee --- /dev/null +++ b/MCUME_teensy41/teensy800/romatarixl.h @@ -0,0 +1,1026 @@ +const UBYTE romos[16384] = { +0x11,0x92,0x10,0x05,0x83,0x00,0x42,0x42,0x00,0x00,0x01,0x02,0xA9,0x40,0x8D,0x0E, +0xD4,0xAD,0x13,0xD0,0x8D,0xFA,0x03,0x60,0x2C,0x0F,0xD4,0x10,0x03,0x6C,0x00,0x02, +0xD8,0x48,0x8A,0x48,0x98,0x48,0x8D,0x0F,0xD4,0x6C,0x22,0x02,0xD8,0x6C,0x16,0x02, +0x48,0xAD,0x0E,0xD2,0x29,0x20,0xD0,0x0D,0xA9,0xDF,0x8D,0x0E,0xD2,0xA5,0x10,0x8D, +0x0E,0xD2,0x6C,0x0A,0x02,0x8A,0x48,0xAD,0xFF,0xD1,0x2D,0x49,0x02,0xF0,0x03,0x6C, +0x38,0x02,0xA2,0x06,0xBD,0xCF,0xC0,0xE0,0x05,0xD0,0x04,0x25,0x10,0xF0,0x05,0x2C, +0x0E,0xD2,0xF0,0x06,0xCA,0x10,0xED,0x4C,0xA0,0xC0,0x49,0xFF,0x8D,0x0E,0xD2,0xA5, +0x10,0x8D,0x0E,0xD2,0xE0,0x00,0xD0,0x05,0xAD,0x6D,0x02,0xD0,0x23,0xBD,0xD7,0xC0, +0xAA,0xBD,0x00,0x02,0x8D,0x8C,0x02,0xBD,0x01,0x02,0x8D,0x8D,0x02,0x68,0xAA,0x6C, +0x8C,0x02,0xA9,0x00,0x85,0x11,0x8D,0xFF,0x02,0x8D,0xF0,0x02,0x85,0x4D,0x68,0x40, +0x68,0xAA,0x2C,0x02,0xD3,0x10,0x06,0xAD,0x00,0xD3,0x6C,0x02,0x02,0x2C,0x03,0xD3, +0x10,0x06,0xAD,0x01,0xD3,0x6C,0x04,0x02,0x68,0x8D,0x8C,0x02,0x68,0x48,0x29,0x10, +0xF0,0x07,0xAD,0x8C,0x02,0x48,0x6C,0x06,0x02,0xAD,0x8C,0x02,0x48,0x68,0x40,0x80, +0x40,0x04,0x02,0x01,0x08,0x10,0x20,0x36,0x08,0x14,0x12,0x10,0x0E,0x0C,0x0A,0x4C, +0xDF,0xC0,0xE6,0x14,0xD0,0x08,0xE6,0x4D,0xE6,0x13,0xD0,0x02,0xE6,0x12,0xA9,0xFE, +0xA2,0x00,0xA4,0x4D,0x10,0x06,0x85,0x4D,0xA6,0x13,0xA9,0xF6,0x85,0x4E,0x86,0x4F, +0xAD,0xC5,0x02,0x45,0x4F,0x25,0x4E,0x8D,0x17,0xD0,0xA2,0x00,0x20,0x55,0xC2,0xD0, +0x03,0x20,0x4F,0xC2,0xA5,0x42,0xD0,0x08,0xBA,0xBD,0x04,0x01,0x29,0x04,0xF0,0x03, +0x4C,0x8A,0xC2,0xAD,0x13,0xD0,0xCD,0xFA,0x03,0xD0,0xB4,0xAD,0x0D,0xD4,0x8D,0x35, +0x02,0xAD,0x0C,0xD4,0x8D,0x34,0x02,0xAD,0x31,0x02,0x8D,0x03,0xD4,0xAD,0x30,0x02, +0x8D,0x02,0xD4,0xAD,0x2F,0x02,0x8D,0x00,0xD4,0xAD,0x6F,0x02,0x8D,0x1B,0xD0,0xAD, +0x6C,0x02,0xF0,0x0E,0xCE,0x6C,0x02,0xA9,0x08,0x38,0xED,0x6C,0x02,0x29,0x07,0x8D, +0x05,0xD4,0xA2,0x08,0x8E,0x1F,0xD0,0x58,0xBD,0xC0,0x02,0x45,0x4F,0x25,0x4E,0x9D, +0x12,0xD0,0xCA,0x10,0xF2,0xAD,0xF4,0x02,0x8D,0x09,0xD4,0xAD,0xF3,0x02,0x8D,0x01, +0xD4,0xA2,0x02,0x20,0x55,0xC2,0xD0,0x03,0x20,0x52,0xC2,0xA2,0x02,0xE8,0xE8,0xBD, +0x18,0x02,0x1D,0x19,0x02,0xF0,0x06,0x20,0x55,0xC2,0x9D,0x26,0x02,0xE0,0x08,0xD0, +0xEC,0xAD,0x0F,0xD2,0x29,0x04,0xF0,0x08,0xAD,0xF1,0x02,0xF0,0x03,0xCE,0xF1,0x02, +0xAD,0x2B,0x02,0xF0,0x3E,0xAD,0x0F,0xD2,0x29,0x04,0xD0,0x32,0xCE,0x2B,0x02,0xD0, +0x32,0xAD,0x6D,0x02,0xD0,0x2D,0xAD,0xDA,0x02,0x8D,0x2B,0x02,0xAD,0x09,0xD2,0xC9, +0x9F,0xF0,0x20,0xC9,0x83,0xF0,0x1C,0xC9,0x84,0xF0,0x18,0xC9,0x94,0xF0,0x14,0x29, +0x3F,0xC9,0x11,0xF0,0x0E,0xAD,0x09,0xD2,0x8D,0xFC,0x02,0x4C,0xF3,0xC1,0xA9,0x00, +0x8D,0x2B,0x02,0xAD,0x00,0xD3,0x4A,0x4A,0x4A,0x4A,0x8D,0x79,0x02,0x8D,0x7B,0x02, +0xAD,0x00,0xD3,0x29,0x0F,0x8D,0x78,0x02,0x8D,0x7A,0x02,0xAD,0x10,0xD0,0x8D,0x84, +0x02,0x8D,0x86,0x02,0xAD,0x11,0xD0,0x8D,0x85,0x02,0x8D,0x87,0x02,0xA2,0x03,0xBD, +0x00,0xD2,0x9D,0x70,0x02,0x9D,0x74,0x02,0xCA,0x10,0xF4,0x8D,0x0B,0xD2,0xA2,0x02, +0xA0,0x01,0xB9,0x78,0x02,0x4A,0x4A,0x4A,0x9D,0x7D,0x02,0x9D,0x81,0x02,0xA9,0x00, +0x2A,0x9D,0x7C,0x02,0x9D,0x80,0x02,0xCA,0xCA,0x88,0x10,0xE6,0x6C,0x24,0x02,0x6C, +0x26,0x02,0x6C,0x28,0x02,0xBC,0x18,0x02,0xD0,0x08,0xBC,0x19,0x02,0xF0,0x10,0xDE, +0x19,0x02,0xDE,0x18,0x02,0xD0,0x08,0xBC,0x19,0x02,0xD0,0x03,0xA9,0x00,0x60,0xA9, +0xFF,0x60,0x0A,0x8D,0x2D,0x02,0x8A,0xA2,0x05,0x8D,0x0A,0xD4,0xCA,0xD0,0xFD,0xAE, +0x2D,0x02,0x9D,0x17,0x02,0x98,0x9D,0x16,0x02,0x60,0x68,0xA8,0x68,0xAA,0x68,0x40, +0x78,0xAD,0x13,0xD0,0xCD,0xFA,0x03,0xD0,0x2F,0x6A,0x90,0x05,0x20,0xC9,0xC4,0xD0, +0x27,0xAD,0x44,0x02,0xD0,0x22,0xA9,0xFF,0xD0,0x20,0x78,0xA2,0x8C,0x88,0xD0,0xFD, +0xCA,0xD0,0xFA,0xAD,0x3D,0x03,0xC9,0x5C,0xD0,0x0E,0xAD,0x3E,0x03,0xC9,0x93,0xD0, +0x07,0xAD,0x3F,0x03,0xC9,0x25,0xF0,0xC8,0xA9,0x00,0x85,0x08,0x78,0xD8,0xA2,0xFF, +0x9A,0x20,0x71,0xC4,0xA9,0x01,0x85,0x01,0xA5,0x08,0xD0,0x52,0xA9,0x00,0xA0,0x08, +0x85,0x04,0x85,0x05,0xA9,0xFF,0x91,0x04,0xD1,0x04,0xF0,0x02,0x46,0x01,0xA9,0x00, +0x91,0x04,0xD1,0x04,0xF0,0x02,0x46,0x01,0xC8,0xD0,0xE9,0xE6,0x05,0xA6,0x05,0xE4, +0x06,0xD0,0xE1,0xA9,0x23,0x85,0x0A,0xA9,0xF2,0x85,0x0B,0xAD,0x01,0xD3,0x29,0x7F, +0x8D,0x01,0xD3,0x20,0x73,0xFF,0xB0,0x05,0x20,0x92,0xFF,0x90,0x02,0x46,0x01,0xAD, +0x01,0xD3,0x09,0x80,0x8D,0x01,0xD3,0xA9,0xFF,0x8D,0x44,0x02,0xD0,0x22,0xA2,0x00, +0xAD,0xEC,0x03,0xF0,0x07,0x8E,0x0E,0x00,0x8E,0x0F,0x00,0x8A,0x9D,0x00,0x02,0xE0, +0xED,0xB0,0x03,0x9D,0x00,0x03,0xCA,0xD0,0xF3,0xA2,0x10,0x95,0x00,0xE8,0x10,0xFB, +0xA2,0x00,0xAD,0x01,0xD3,0x29,0x02,0xF0,0x01,0xE8,0x8E,0xF8,0x03,0xA9,0x5C,0x8D, +0x3D,0x03,0xA9,0x93,0x8D,0x3E,0x03,0xA9,0x25,0x8D,0x3F,0x03,0xA9,0x02,0x85,0x52, +0xA9,0x27,0x85,0x53,0xAD,0x14,0xD0,0x29,0x0E,0xD0,0x08,0xA9,0x05,0xA2,0x01,0xA0, +0x28,0xD0,0x06,0xA9,0x06,0xA2,0x00,0xA0,0x30,0x8D,0xDA,0x02,0x86,0x62,0x8C,0xD9, +0x02,0xA2,0x25,0xBD,0x4B,0xC4,0x9D,0x00,0x02,0xCA,0x10,0xF7,0xA2,0x0E,0xBD,0x2E, +0xC4,0x9D,0x1A,0x03,0xCA,0x10,0xF7,0x20,0x35,0xC5,0x58,0xA5,0x01,0xD0,0x15,0xAD, +0x01,0xD3,0x29,0x7F,0x8D,0x01,0xD3,0xA9,0x02,0x8D,0xF3,0x02,0xA9,0xE0,0x8D,0xF4, +0x02,0x4C,0x03,0x50,0xA2,0x00,0x86,0x06,0xAE,0xE4,0x02,0xE0,0xB0,0xB0,0x0D,0xAE, +0xFC,0xBF,0xD0,0x08,0xE6,0x06,0x20,0xC9,0xC4,0x20,0x29,0xC4,0xA9,0x03,0xA2,0x00, +0x9D,0x42,0x03,0xA9,0x48,0x9D,0x44,0x03,0xA9,0xC4,0x9D,0x45,0x03,0xA9,0x0C,0x9D, +0x4A,0x03,0x20,0x56,0xE4,0x10,0x03,0x4C,0xAA,0xC2,0xE8,0xD0,0xFD,0xC8,0x10,0xFA, +0x20,0x6E,0xC6,0xA5,0x06,0xF0,0x06,0xAD,0xFD,0xBF,0x6A,0x90,0x06,0x20,0x8B,0xC5, +0x20,0x39,0xE7,0xA9,0x00,0x8D,0x44,0x02,0xA5,0x06,0xF0,0x0A,0xAD,0xFD,0xBF,0x29, +0x04,0xF0,0x03,0x6C,0xFA,0xBF,0x6C,0x0A,0x00,0x6C,0xFE,0xBF,0x18,0x60,0x50,0x30, +0xE4,0x43,0x40,0xE4,0x45,0x00,0xE4,0x53,0x10,0xE4,0x4B,0x20,0xE4,0x42,0x4F,0x4F, +0x54,0x20,0x45,0x52,0x52,0x4F,0x52,0x9B,0x45,0x3A,0x9B,0xCE,0xC0,0xCD,0xC0,0xCD, +0xC0,0xCD,0xC0,0x19,0xFC,0x2C,0xEB,0xAD,0xEA,0xEC,0xEA,0xCD,0xC0,0xCD,0xC0,0xCD, +0xC0,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE2,0xC0,0x8A, +0xC2,0xAD,0x13,0xD0,0x6A,0x90,0x0D,0xAD,0xFC,0xBF,0xD0,0x08,0xAD,0xFD,0xBF,0x10, +0x03,0x6C,0xFE,0xBF,0x20,0xDA,0xC4,0xAD,0x01,0xD3,0x09,0x02,0x8D,0x01,0xD3,0xA5, +0x08,0xF0,0x07,0xAD,0xF8,0x03,0xD0,0x11,0xF0,0x07,0xAD,0x1F,0xD0,0x29,0x04,0xF0, +0x08,0xAD,0x01,0xD3,0x29,0xFD,0x8D,0x01,0xD3,0xA9,0x00,0xA8,0x85,0x05,0xA9,0x28, +0x85,0x06,0xB1,0x05,0x49,0xFF,0x91,0x05,0xD1,0x05,0xD0,0x0C,0x49,0xFF,0x91,0x05, +0xD1,0x05,0xD0,0x04,0xE6,0x06,0xD0,0xEA,0x60,0xA9,0x00,0xAA,0x18,0x7D,0xF0,0xBF, +0xE8,0xD0,0xFA,0xCD,0xEB,0x03,0x8D,0xEB,0x03,0x60,0xA9,0x00,0xAA,0x8D,0x03,0xD3, +0x9D,0x00,0xD0,0x9D,0x00,0xD4,0x9D,0x00,0xD2,0xE0,0x01,0xF0,0x03,0x9D,0x00,0xD3, +0xE8,0xD0,0xED,0xA9,0x3C,0x8D,0x03,0xD3,0xA9,0xFF,0x8D,0x01,0xD3,0xA9,0x38,0x8D, +0x02,0xD3,0x8D,0x03,0xD3,0xA9,0x00,0x8D,0x00,0xD3,0xA9,0xFF,0x8D,0x01,0xD3,0xA9, +0x3C,0x8D,0x02,0xD3,0x8D,0x03,0xD3,0xAD,0x01,0xD3,0xAD,0x00,0xD3,0xA9,0x22,0x8D, +0x0F,0xD2,0xA9,0xA0,0x8D,0x05,0xD2,0x8D,0x07,0xD2,0xA9,0x28,0x8D,0x08,0xD2,0xA9, +0xFF,0x8D,0x0D,0xD2,0x60,0xC6,0x11,0xA9,0x92,0x8D,0x36,0x02,0xA9,0xC0,0x8D,0x37, +0x02,0xA5,0x06,0x8D,0xE4,0x02,0x8D,0xE6,0x02,0xA9,0x00,0x8D,0xE5,0x02,0xA9,0x00, +0x8D,0xE7,0x02,0xA9,0x07,0x8D,0xE8,0x02,0x20,0x0C,0xE4,0x20,0x1C,0xE4,0x20,0x2C, +0xE4,0x20,0x3C,0xE4,0x20,0x4C,0xE4,0x20,0x6E,0xE4,0x20,0x65,0xE4,0x20,0x6B,0xE4, +0x20,0x50,0xE4,0xA9,0x6E,0x8D,0x38,0x02,0xA9,0xC9,0x8D,0x39,0x02,0x20,0x9B,0xE4, +0xAD,0x1F,0xD0,0x29,0x01,0x49,0x01,0x8D,0xE9,0x03,0x60,0xA5,0x08,0xF0,0x09,0xA5, +0x09,0x29,0x01,0xF0,0x33,0x4C,0x3B,0xC6,0xA9,0x01,0x8D,0x01,0x03,0xA9,0x53,0x8D, +0x02,0x03,0x20,0x53,0xE4,0x30,0x21,0xA9,0x00,0x8D,0x0B,0x03,0xA9,0x01,0x8D,0x0A, +0x03,0xA9,0x00,0x8D,0x04,0x03,0xA9,0x04,0x8D,0x05,0x03,0x20,0x59,0xC6,0x10,0x09, +0x20,0x3E,0xC6,0xAD,0xEA,0x03,0xF0,0xDF,0x60,0xA2,0x03,0xBD,0x00,0x04,0x9D,0x40, +0x02,0xCA,0x10,0xF7,0xAD,0x42,0x02,0x85,0x04,0xAD,0x43,0x02,0x85,0x05,0xAD,0x04, +0x04,0x85,0x0C,0xAD,0x05,0x04,0x85,0x0D,0xA0,0x7F,0xB9,0x00,0x04,0x91,0x04,0x88, +0x10,0xF8,0x18,0xA5,0x04,0x69,0x80,0x85,0x04,0xA5,0x05,0x69,0x00,0x85,0x05,0xCE, +0x41,0x02,0xF0,0x12,0xEE,0x0A,0x03,0x20,0x59,0xC6,0x10,0xDC,0x20,0x3E,0xC6,0xAD, +0xEA,0x03,0xD0,0xAC,0xF0,0xF1,0xAD,0xEA,0x03,0xF0,0x03,0x20,0x59,0xC6,0x20,0x29, +0xC6,0xB0,0x9D,0x20,0x3B,0xC6,0xE6,0x09,0x60,0x18,0xAD,0x42,0x02,0x69,0x06,0x85, +0x04,0xAD,0x43,0x02,0x69,0x00,0x85,0x05,0x6C,0x04,0x00,0x6C,0x0C,0x00,0xA2,0x3D, +0xA0,0xC4,0x8A,0xA2,0x00,0x9D,0x44,0x03,0x98,0x9D,0x45,0x03,0xA9,0x09,0x9D,0x42, +0x03,0xA9,0xFF,0x9D,0x48,0x03,0x4C,0x56,0xE4,0xAD,0xEA,0x03,0xF0,0x03,0x4C,0x7A, +0xE4,0xA9,0x52,0x8D,0x02,0x03,0xA9,0x01,0x8D,0x01,0x03,0x4C,0x53,0xE4,0xA5,0x08, +0xF0,0x09,0xA5,0x09,0x29,0x02,0xF0,0x27,0x4C,0xA0,0xC6,0xAD,0xE9,0x03,0xF0,0x1F, +0xA9,0x80,0x85,0x3E,0xEE,0xEA,0x03,0x20,0x7D,0xE4,0x20,0xBB,0xC5,0xA9,0x00,0x8D, +0xEA,0x03,0x8D,0xE9,0x03,0x06,0x09,0xA5,0x0C,0x85,0x02,0xA5,0x0D,0x85,0x03,0x60, +0x6C,0x02,0x00,0xA9,0xA0,0x8D,0x46,0x02,0xA9,0x80,0x8D,0xD5,0x02,0xA9,0x00,0x8D, +0xD6,0x02,0x60,0xA9,0x31,0x8D,0x00,0x03,0xAD,0x46,0x02,0xAE,0x02,0x03,0xE0,0x21, +0xF0,0x02,0xA9,0x07,0x8D,0x06,0x03,0xA2,0x40,0xAD,0x02,0x03,0xC9,0x50,0xF0,0x04, +0xC9,0x57,0xD0,0x02,0xA2,0x80,0xC9,0x53,0xD0,0x10,0xA9,0xEA,0x8D,0x04,0x03,0xA9, +0x02,0x8D,0x05,0x03,0xA0,0x04,0xA9,0x00,0xF0,0x06,0xAC,0xD5,0x02,0xAD,0xD6,0x02, +0x8E,0x03,0x03,0x8C,0x08,0x03,0x8D,0x09,0x03,0x20,0x59,0xE4,0x10,0x01,0x60,0xAD, +0x02,0x03,0xC9,0x53,0xD0,0x0A,0x20,0x3A,0xC7,0xA0,0x02,0xB1,0x15,0x8D,0x46,0x02, +0xAD,0x02,0x03,0xC9,0x21,0xD0,0x1F,0x20,0x3A,0xC7,0xA0,0xFE,0xC8,0xC8,0xB1,0x15, +0xC9,0xFF,0xD0,0xF8,0xC8,0xB1,0x15,0xC8,0xC9,0xFF,0xD0,0xF2,0x88,0x88,0x8C,0x08, +0x03,0xA9,0x00,0x8D,0x09,0x03,0xAC,0x03,0x03,0x60,0xAD,0x04,0x03,0x85,0x15,0xAD, +0x05,0x03,0x85,0x16,0x60,0xA2,0x05,0xA9,0x00,0x9D,0xC9,0x02,0xCA,0x10,0xF8,0xA9, +0x00,0x8D,0x33,0x02,0x20,0xCF,0xC7,0xA0,0x9C,0xB0,0x39,0x8D,0x88,0x02,0x20,0xCF, +0xC7,0xA0,0x9C,0xB0,0x2F,0x8D,0x45,0x02,0xAD,0x88,0x02,0xC9,0x0B,0xF0,0x26,0x2A, +0xAA,0xBD,0xE4,0xC8,0x8D,0xC9,0x02,0xBD,0xE5,0xC8,0x8D,0xCA,0x02,0xAD,0x45,0x02, +0xCD,0x33,0x02,0xF0,0xCA,0x20,0xCF,0xC7,0xA0,0x9C,0xB0,0x08,0x20,0xD2,0xC7,0xEE, +0x33,0x02,0xD0,0xE9,0x60,0x20,0xCF,0xC7,0xA0,0x9C,0xB0,0x2C,0x8D,0xC9,0x02,0x20, +0xCF,0xC7,0xA0,0x9C,0xB0,0x22,0x8D,0xCA,0x02,0xAD,0x45,0x02,0xC9,0x01,0xF0,0x16, +0x90,0x17,0x18,0xAD,0xC9,0x02,0x6D,0xD1,0x02,0xA8,0xAD,0xCA,0x02,0x6D,0xD2,0x02, +0x8C,0xC9,0x02,0x8D,0xCA,0x02,0xA0,0x01,0x60,0xA0,0x00,0xA9,0x00,0xF0,0xF1,0x6C, +0xCF,0x02,0x6C,0xC9,0x02,0xAC,0x33,0x02,0xC0,0x01,0xF0,0x0A,0xB0,0x73,0x8D,0x4A, +0x02,0x8D,0x8E,0x02,0x90,0x6A,0x8D,0x4B,0x02,0x8D,0x8F,0x02,0xA2,0x00,0xAD,0x88, +0x02,0xF0,0x06,0xC9,0x0A,0xF0,0x15,0xA2,0x02,0x18,0xAD,0x4A,0x02,0x7D,0xD1,0x02, +0x8D,0x8E,0x02,0xAD,0x4B,0x02,0x7D,0xD2,0x02,0x8D,0x8F,0x02,0x18,0xAD,0x8E,0x02, +0x6D,0x45,0x02,0x48,0xA9,0x00,0x6D,0x8F,0x02,0xA8,0x68,0x38,0xE9,0x02,0xB0,0x01, +0x88,0x48,0x98,0xDD,0xCC,0x02,0x68,0x90,0x10,0xD0,0x05,0xDD,0xCB,0x02,0x90,0x09, +0x9D,0xCB,0x02,0x48,0x98,0x9D,0xCC,0x02,0x68,0xAE,0x88,0x02,0xE0,0x01,0xF0,0x10, +0xCC,0xE6,0x02,0x90,0x0B,0xD0,0x05,0xCD,0xE5,0x02,0x90,0x04,0x68,0x68,0xA0,0x9D, +0x60,0x38,0x48,0xAD,0x33,0x02,0xE9,0x02,0x18,0x6D,0x8E,0x02,0x85,0x36,0xA9,0x00, +0x6D,0x8F,0x02,0x85,0x37,0x68,0xA0,0x00,0x91,0x36,0x4C,0x50,0xC8,0x18,0x6D,0x8E, +0x02,0x85,0x36,0xA9,0x00,0x6D,0x8F,0x02,0x85,0x37,0xA0,0x00,0xB1,0x36,0x18,0x6D, +0xD1,0x02,0x91,0x36,0xE6,0x36,0xD0,0x02,0xE6,0x37,0xB1,0x36,0x6D,0xD2,0x02,0x91, +0x36,0x60,0xA2,0x00,0xAC,0x88,0x02,0xC0,0x04,0x90,0x02,0xA2,0x02,0x18,0x6D,0x8E, +0x02,0x85,0x36,0xA9,0x00,0x6D,0x8F,0x02,0x85,0x37,0xA0,0x00,0xB1,0x36,0x18,0x7D, +0xD1,0x02,0x91,0x36,0x60,0x48,0xAD,0x33,0x02,0x6A,0x68,0xB0,0x15,0x18,0x6D,0x8E, +0x02,0x85,0x36,0xA9,0x00,0x6D,0x8F,0x02,0x85,0x37,0xA0,0x00,0xB1,0x36,0x8D,0x88, +0x02,0x60,0x18,0x6D,0xD1,0x02,0xA9,0x00,0x6D,0xD2,0x02,0x6D,0x88,0x02,0xA0,0x00, +0x91,0x36,0xF0,0xED,0xD5,0xC7,0xD5,0xC7,0x92,0xC8,0x92,0xC8,0x92,0xC8,0x92,0xC8, +0x6D,0xC8,0x6D,0xC8,0xB5,0xC8,0xB5,0xC8,0xD5,0xC7,0x95,0xC7,0xA9,0xFF,0x8D,0x44, +0x02,0xAD,0x01,0xD3,0x29,0x7F,0x8D,0x01,0xD3,0x4C,0x83,0xE4,0xA9,0x01,0x8D,0x48, +0x02,0xAD,0x48,0x02,0x8D,0xFF,0xD1,0xAD,0x03,0xD8,0xC9,0x80,0xD0,0x0A,0xAD,0x0B, +0xD8,0xC9,0x91,0xD0,0x03,0x20,0x19,0xD8,0x0E,0x48,0x02,0xD0,0xE4,0xA9,0x00,0x8D, +0xFF,0xD1,0x60,0xA9,0x01,0x8D,0x42,0x00,0xAD,0x01,0x03,0x48,0xAD,0x47,0x02,0xF0, +0x1A,0xA2,0x08,0x20,0xAF,0xC9,0xF0,0x13,0x8A,0x48,0x20,0x05,0xD8,0x68,0xAA,0x90, +0xF2,0xA9,0x00,0x8D,0x48,0x02,0x8D,0xFF,0xD1,0xF0,0x03,0x20,0x71,0xE9,0x68,0x8D, +0x01,0x03,0xA9,0x00,0x8D,0x42,0x00,0x8C,0x03,0x03,0xAC,0x03,0x03,0x60,0xA2,0x08, +0x6A,0xB0,0x03,0xCA,0xD0,0xFA,0xAD,0x48,0x02,0x48,0xBD,0x20,0xCA,0x8D,0x48,0x02, +0x8D,0xFF,0xD1,0x20,0x08,0xD8,0x68,0x8D,0x48,0x02,0x8D,0xFF,0xD1,0x68,0xAA,0x68, +0x40,0xA0,0x01,0x4C,0xDC,0xC9,0xA0,0x03,0x4C,0xDC,0xC9,0xA0,0x05,0x4C,0xDC,0xC9, +0xA0,0x07,0x4C,0xDC,0xC9,0xA0,0x09,0x4C,0xDC,0xC9,0xA0,0x0B,0x4C,0xDC,0xC9,0xCA, +0x10,0x09,0xA9,0x00,0x8D,0x48,0x02,0x8D,0xFF,0xD1,0x60,0xAD,0x47,0x02,0x3D,0x21, +0xCA,0xF0,0xEC,0x8D,0x48,0x02,0x8D,0xFF,0xD1,0x60,0xB9,0x0D,0xD8,0x48,0x88,0xB9, +0x0D,0xD8,0x48,0xAD,0x4C,0x02,0xAE,0x4D,0x02,0xA0,0x92,0x60,0x8D,0x4C,0x02,0x8E, +0x4D,0x02,0xAD,0x42,0x00,0x48,0xA9,0x01,0x8D,0x42,0x00,0xA2,0x08,0x20,0xAF,0xC9, +0xF0,0x11,0x8A,0x48,0x98,0x48,0x20,0xCA,0xC9,0x90,0x20,0x8D,0x4C,0x02,0x68,0x68, +0x4C,0x05,0xCA,0xA0,0x82,0xA9,0x00,0x8D,0x48,0x02,0x8D,0xFF,0xD1,0x68,0x8D,0x42, +0x00,0xAD,0x4C,0x02,0x8C,0x4D,0x02,0xAC,0x4D,0x02,0x60,0x68,0xA8,0x68,0xAA,0x90, +0xCC,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0xAE,0x2E,0x00,0xBD,0x4D,0x03,0x20, +0xDE,0xE7,0xB0,0x20,0x18,0x20,0x9E,0xE8,0xB0,0x1A,0xAE,0x2E,0x00,0xBD,0x4C,0x03, +0x20,0x16,0xE7,0xB0,0x0F,0xAE,0x2E,0x00,0x9D,0x40,0x03,0x85,0x20,0xA9,0x03,0x85, +0x17,0x4C,0x5C,0xE5,0x4C,0x10,0xE5,0x00,0x13,0x16,0xD1,0xE4,0xE4,0xE8,0x29,0xEB, +0xEE,0x00,0x00,0x2D,0x25,0x2D,0x2F,0x32,0x39,0x00,0x34,0x25,0x33,0x34,0x00,0x00, +0x00,0x32,0x2F,0x2D,0x32,0x21,0x2D,0x00,0x00,0x2B,0x25,0x39,0x22,0x2F,0x21,0x32, +0x24,0x00,0x34,0x25,0x33,0x34,0x00,0x00,0x00,0xB2,0x91,0x00,0x92,0x00,0x93,0x00, +0x94,0x00,0xA8,0x00,0xA1,0x00,0xA2,0x00,0x00,0x00,0x5B,0x00,0x11,0x00,0x12,0x00, +0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x10,0x00, +0x1C,0x00,0x1E,0x00,0xA2,0x80,0xB3,0x00,0x00,0x00,0xFF,0xFF,0x00,0x31,0x00,0x37, +0x00,0x25,0x00,0x32,0x00,0x34,0x00,0x39,0x00,0x35,0x00,0x29,0x00,0x2F,0x00,0x30, +0x00,0x0D,0x00,0x1D,0x00,0xB2,0xB4,0x00,0x00,0x00,0x80,0xDC,0x80,0x00,0x21,0x00, +0x33,0x00,0x24,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x2A,0x00,0x2B,0x00,0x2C,0x00, +0x1B,0x00,0x0B,0x00,0x0A,0x00,0xA3,0x00,0x00,0x00,0x80,0xB3,0xA8,0x80,0x00,0x3A, +0x00,0x38,0x00,0x23,0x00,0x36,0x00,0x22,0x00,0x2E,0x00,0x2D,0x00,0x0C,0x00,0x0E, +0x00,0x0F,0x00,0x80,0xB3,0xA8,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, +0xB3,0x80,0xB0,0x80,0xA1,0x80,0xA3,0x80,0xA5,0x80,0x80,0x80,0xA2,0x80,0xA1,0x80, +0xB2,0x80,0x00,0x33,0x00,0x30,0x00,0x21,0x00,0x23,0x00,0x25,0x00,0x00,0x00,0x22, +0x00,0x21,0x00,0x32,0x00,0x00,0x33,0x28,0x00,0x22,0x00,0x33,0x00,0x5C,0x00,0x36, +0x2F,0x29,0x23,0x25,0x00,0x03,0xA0,0x11,0xA9,0x00,0x18,0x71,0x4A,0x88,0x10,0xFB, +0x69,0x00,0x49,0xFF,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, +0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0x66,0x66,0xFF,0x66,0x00, +0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00,0x00,0x66,0x6C,0x18,0x30,0x66,0x46,0x00, +0x1C,0x36,0x1C,0x38,0x6F,0x66,0x3B,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x0E,0x1C,0x18,0x18,0x1C,0x0E,0x00,0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, +0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, +0x00,0x3C,0x66,0x6E,0x76,0x66,0x3C,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x7E,0x00, +0x00,0x3C,0x66,0x0C,0x18,0x30,0x7E,0x00,0x00,0x7E,0x0C,0x18,0x0C,0x66,0x3C,0x00, +0x00,0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x00,0x00,0x7E,0x60,0x7C,0x06,0x66,0x3C,0x00, +0x00,0x3C,0x60,0x7C,0x66,0x66,0x3C,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x30,0x00, +0x00,0x3C,0x66,0x3C,0x66,0x66,0x3C,0x00,0x00,0x3C,0x66,0x3E,0x06,0x0C,0x38,0x00, +0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, +0x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, +0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x00,0x3C,0x66,0x0C,0x18,0x00,0x18,0x00, +0x00,0x3C,0x66,0x6E,0x6E,0x60,0x3E,0x00,0x00,0x18,0x3C,0x66,0x66,0x7E,0x66,0x00, +0x00,0x7C,0x66,0x7C,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00, +0x00,0x78,0x6C,0x66,0x66,0x6C,0x78,0x00,0x00,0x7E,0x60,0x7C,0x60,0x60,0x7E,0x00, +0x00,0x7E,0x60,0x7C,0x60,0x60,0x60,0x00,0x00,0x3E,0x60,0x60,0x6E,0x66,0x3E,0x00, +0x00,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x7E,0x00, +0x00,0x06,0x06,0x06,0x06,0x66,0x3C,0x00,0x00,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00, +0x00,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x00, +0x00,0x66,0x76,0x7E,0x7E,0x6E,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3C,0x66,0x66,0x66,0x6C,0x36,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x6C,0x66,0x00,0x00,0x3C,0x60,0x3C,0x06,0x06,0x3C,0x00, +0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, +0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, +0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x18,0x00, +0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x1E,0x00, +0x00,0x40,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, +0x00,0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, +0x0C,0x18,0x3C,0x06,0x3E,0x66,0x3E,0x00,0x30,0x18,0x00,0x66,0x66,0x66,0x3E,0x00, +0x36,0x6C,0x00,0x76,0x76,0x7E,0x6E,0x00,0x0C,0x18,0x7E,0x60,0x7C,0x60,0x7E,0x00, +0x00,0x00,0x3C,0x60,0x60,0x3C,0x18,0x30,0x3C,0x66,0x00,0x3C,0x66,0x66,0x3C,0x00, +0x30,0x18,0x00,0x3C,0x66,0x66,0x3C,0x00,0x30,0x18,0x00,0x38,0x18,0x18,0x3C,0x00, +0x1C,0x30,0x30,0x78,0x30,0x30,0x7E,0x00,0x00,0x66,0x00,0x38,0x18,0x18,0x3C,0x00, +0x00,0x66,0x00,0x66,0x66,0x66,0x3E,0x00,0x36,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00, +0x66,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00,0x0C,0x18,0x00,0x66,0x66,0x66,0x3E,0x00, +0x0C,0x18,0x00,0x3C,0x66,0x66,0x3C,0x00,0x00,0x66,0x00,0x3C,0x66,0x66,0x3C,0x00, +0x66,0x00,0x66,0x66,0x66,0x66,0x7E,0x00,0x3C,0x66,0x1C,0x06,0x3E,0x66,0x3E,0x00, +0x3C,0x66,0x00,0x66,0x66,0x66,0x3E,0x00,0x3C,0x66,0x00,0x38,0x18,0x18,0x3C,0x00, +0x0C,0x18,0x3C,0x66,0x7E,0x60,0x3C,0x00,0x30,0x18,0x3C,0x66,0x7E,0x60,0x3C,0x00, +0x36,0x6C,0x00,0x7C,0x66,0x66,0x66,0x00,0x3C,0xC3,0x3C,0x66,0x7E,0x60,0x3C,0x00, +0x18,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00,0x30,0x18,0x3C,0x06,0x3E,0x66,0x3E,0x00, +0x18,0x00,0x18,0x3C,0x66,0x7E,0x66,0x00,0x78,0x60,0x78,0x60,0x7E,0x18,0x1E,0x00, +0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00, +0x00,0x18,0x30,0x7E,0x30,0x18,0x00,0x00,0x00,0x18,0x0C,0x7E,0x0C,0x18,0x00,0x00, +0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00, +0x00,0x60,0x60,0x7C,0x66,0x66,0x7C,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x3C,0x00, +0x00,0x06,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, +0x00,0x0E,0x18,0x3E,0x18,0x18,0x18,0x00,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x7C, +0x00,0x60,0x60,0x7C,0x66,0x66,0x66,0x00,0x00,0x18,0x00,0x38,0x18,0x18,0x3C,0x00, +0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3C,0x00,0x60,0x60,0x6C,0x78,0x6C,0x66,0x00, +0x00,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, +0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, +0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x06, +0x00,0x00,0x7C,0x66,0x60,0x60,0x60,0x00,0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, +0x00,0x18,0x7E,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x00, +0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x63,0x6B,0x7F,0x3E,0x36,0x00, +0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x3E,0x0C,0x78, +0x00,0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00,0x66,0x66,0x18,0x3C,0x66,0x7E,0x66,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x7E,0x78,0x7C,0x6E,0x66,0x06,0x00, +0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00,0x10,0x18,0x1C,0x1E,0x1C,0x18,0x10,0x00, +0x4C,0x09,0x50,0x20,0x86,0x50,0x4C,0x91,0x52,0x20,0x86,0x50,0xA9,0x00,0x85,0x80, +0x85,0x81,0x85,0x82,0x8D,0x08,0xD2,0xA9,0x03,0x8D,0x0F,0xD2,0x20,0x10,0x55,0xA9, +0x40,0x8D,0x0E,0xD4,0xA2,0x00,0x20,0x73,0x57,0xA2,0x3A,0xA0,0x51,0x20,0x9E,0x50, +0xA9,0xD0,0x8D,0x00,0x02,0xA9,0x50,0x8D,0x01,0x02,0xA2,0x0C,0xA9,0xAA,0x20,0x2A, +0x57,0xA2,0x00,0x8E,0x0A,0xD4,0xE8,0xD0,0xFA,0xAD,0x0B,0xD4,0xC9,0x18,0xB0,0xF9, +0xA9,0x10,0x85,0x87,0xA9,0xC0,0x8D,0x0E,0xD4,0xAD,0x1F,0xD0,0x29,0x01,0xD0,0xF9, +0xA9,0xFF,0x8D,0xFC,0x02,0xA5,0x86,0x29,0x0F,0xC9,0x01,0xF0,0x10,0xC9,0x02,0xF0, +0x0F,0xC9,0x04,0xF0,0x0E,0xA9,0x88,0x85,0x86,0xA9,0xFF,0x85,0x82,0x4C,0x91,0x52, +0x4C,0x57,0x55,0x4C,0x50,0x54,0xA9,0x11,0x85,0x86,0xA9,0x21,0x8D,0x2F,0x02,0xA9, +0xC0,0x8D,0x0E,0xD4,0xA9,0x41,0x85,0x83,0xA9,0xFF,0x8D,0xFC,0x02,0x60,0x85,0x8A, +0x98,0x48,0x8A,0x48,0xA9,0x00,0x8D,0x2F,0x02,0x8D,0xDC,0x02,0xA9,0xDA,0x8D,0x00, +0x02,0xA9,0x53,0x8D,0x01,0x02,0xA2,0x00,0x8A,0x20,0x2A,0x57,0x68,0xAA,0x68,0xA8, +0x8E,0x30,0x02,0x86,0x84,0x8C,0x31,0x02,0x84,0x85,0xA9,0x21,0x8D,0x2F,0x02,0x60, +0x48,0x8A,0x48,0xA2,0x7A,0xA5,0x87,0xC9,0x01,0xF0,0x1F,0x29,0x01,0xF0,0x0A,0xE6, +0xA2,0xA5,0xA2,0x29,0x20,0xF0,0x02,0xA2,0x2C,0x8E,0x0A,0xD4,0x8E,0x16,0xD0,0x18, +0x66,0x87,0xA9,0x00,0x85,0x4D,0x68,0xAA,0x68,0x40,0xA5,0x88,0xD0,0x16,0xAD,0x1F, +0xD0,0x29,0x02,0xD0,0x1A,0xA5,0x86,0x2A,0x26,0x86,0xA9,0x20,0x85,0xA2,0xA9,0xFF, +0x85,0x88,0xD0,0x0B,0xAD,0x1F,0xD0,0x29,0x02,0xF0,0x04,0xA9,0x00,0x85,0x88,0xA5, +0x86,0x29,0x0F,0x09,0x10,0x85,0x87,0xE6,0x80,0xD0,0x02,0xE6,0x81,0xA5,0x81,0xC9, +0xFA,0xD0,0x04,0x58,0x4C,0x75,0x50,0x4C,0xD3,0x50,0x70,0x70,0x70,0x70,0x70,0x47, +0x61,0x51,0x70,0x70,0x70,0x4E,0x00,0x30,0x70,0xF0,0xC6,0x71,0x51,0x70,0x86,0x70, +0x86,0x70,0x06,0x70,0x70,0x4E,0x00,0x30,0x70,0x70,0x70,0x42,0xB1,0x51,0x41,0x3A, +0x51,0x00,0x00,0x00,0x00,0x33,0x25,0x2C,0x26,0x00,0x34,0x25,0x33,0x34,0x00,0x00, +0x00,0x00,0x00,0x2D,0x25,0x2D,0x2F,0x32,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x21,0x35,0x24,0x29,0x2F,0x0D,0x36,0x29,0x33,0x35,0x21,0x2C,0x00, +0x00,0x00,0x00,0x2B,0x25,0x39,0x22,0x2F,0x21,0x32,0x24,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x21,0x2C,0x2C,0x00,0x34,0x25,0x33,0x34,0x33,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x42,0xB3,0xA5,0xAC,0xA5,0xA3,0xB4,0x56,0x0C,0x42,0xB3, +0xB4,0xA1,0xB2,0xB4,0x56,0x2F,0x32,0x42,0xB2,0xA5,0xB3,0xA5,0xB4,0x56,0x00,0x00, +0x00,0x70,0x70,0x70,0x46,0x00,0x30,0x70,0x70,0x06,0x70,0x08,0x70,0x70,0x06,0x70, +0x08,0x70,0x08,0x70,0x08,0x70,0x08,0x70,0x70,0x70,0x01,0xED,0x51,0xA0,0x40,0x42, +0xF5,0x51,0x01,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xB2,0xA5,0xB3,0xA5,0xB4, +0x56,0x2F,0x32,0x42,0xA8,0xA5,0xAC,0xB0,0x56,0x34,0x2F,0x00,0x25,0x38,0x29,0x34, +0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x70,0x46,0x00,0x30,0x70,0x70,0x70,0x70, +0x02,0x70,0x70,0x02,0x70,0x02,0x70,0x02,0x70,0x02,0x70,0x02,0x70,0x70,0x01,0xED, +0x51,0x70,0x70,0x70,0x70,0x46,0x71,0x52,0x70,0x06,0x70,0x70,0x4B,0x00,0x31,0x0B, +0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, +0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, +0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x70,0x46,0x00,0x30,0x70,0x01,0xED, +0x51,0x00,0x00,0x21,0x35,0x24,0x29,0x2F,0x0D,0x36,0x29,0x33,0x35,0x21,0x2C,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x25,0x33,0x34,0x00,0x00,0x00,0x00,0x00, +0x00,0xA2,0xD1,0xA0,0x51,0xA9,0x00,0x20,0x9E,0x50,0xA2,0x01,0x20,0x73,0x57,0xA2, +0x00,0x20,0x59,0x57,0xA2,0x01,0x20,0x59,0x57,0xAD,0x20,0x30,0xC9,0xAA,0xF0,0x17, +0xA9,0x55,0x20,0x8E,0x53,0x20,0xB1,0x53,0x20,0x73,0xFF,0xB0,0x05,0xA9,0xFF,0x4C, +0xC4,0x52,0xA9,0xAA,0x20,0x8E,0x53,0xAD,0x24,0x30,0xC9,0xAA,0xF0,0x17,0xA9,0x55, +0x20,0x99,0x53,0x20,0xB1,0x53,0x20,0x92,0xFF,0xB0,0x05,0xA9,0xFF,0x4C,0xE2,0x52, +0xA9,0xAA,0x20,0x99,0x53,0xA9,0xC0,0x85,0x8D,0xA9,0x04,0x85,0xA4,0xA9,0x00,0x85, +0x8E,0x85,0x90,0x85,0x91,0x85,0x8F,0xA6,0x8E,0xBD,0x38,0x30,0x25,0x8D,0xC9,0x80, +0xF0,0x5C,0xC9,0x08,0xF0,0x58,0xA9,0x44,0x20,0xC3,0x53,0xA5,0xA4,0x20,0xA4,0x53, +0xA5,0xA4,0x49,0x0C,0x85,0xA4,0xA2,0x07,0xBD,0x4A,0x54,0xC5,0x91,0xF0,0x37,0xCA, +0x10,0xF6,0xA9,0x04,0x85,0x92,0xA2,0x00,0xA0,0x00,0x8A,0x91,0x90,0xE8,0xC8,0xD0, +0xF9,0x86,0x93,0xA0,0x00,0xB1,0x90,0xC5,0x93,0xD0,0x10,0xE6,0x93,0xC8,0xD0,0xF5, +0xE8,0xD0,0xE5,0xE6,0x91,0xC6,0x92,0xD0,0xDD,0xF0,0x0E,0x20,0xB1,0x53,0xA9,0x88, +0x20,0xC3,0x53,0x4C,0x5E,0x53,0x20,0xB5,0x53,0xA9,0xCC,0x20,0xC3,0x53,0xA5,0x8D, +0x30,0x26,0xA9,0xC0,0x85,0x8D,0xE6,0x8E,0x18,0xA5,0x8F,0x69,0x04,0x85,0x91,0x85, +0x8F,0xCD,0xE4,0x02,0xD0,0x81,0xA5,0x82,0xD0,0x03,0x4C,0xA9,0x52,0xA9,0x0C,0x20, +0xA4,0x53,0x20,0xB5,0x53,0x4C,0x57,0x55,0xA9,0x0C,0x85,0x8D,0xD0,0xDA,0xA2,0x04, +0x20,0x2A,0x57,0x29,0xFC,0x8D,0x23,0x30,0x60,0xA2,0x08,0x20,0x2A,0x57,0x29,0xFC, +0x8D,0x27,0x30,0x60,0x85,0xA5,0xAD,0x01,0xD3,0x29,0xF3,0x05,0xA5,0x8D,0x01,0xD3, +0x60,0xA2,0x3C,0xD0,0x02,0xA2,0x96,0xA0,0xFF,0x8C,0x0A,0xD4,0x88,0xD0,0xFA,0xCA, +0xD0,0xF5,0x60,0x48,0xA6,0x8E,0xA5,0x8D,0x49,0xFF,0x3D,0x38,0x30,0x9D,0x38,0x30, +0x68,0x25,0x8D,0x1D,0x38,0x30,0x9D,0x38,0x30,0x60,0x48,0xA9,0x0C,0x8D,0x17,0xD0, +0xAD,0xC8,0x02,0x8D,0x18,0xD0,0xA9,0x00,0x85,0x4D,0xAD,0xDC,0x02,0xF0,0x0E,0xA9, +0x00,0x8D,0xDC,0x02,0xA9,0x0C,0x20,0xA4,0x53,0x58,0x4C,0x0C,0x50,0xA5,0x8A,0xF0, +0x47,0xAD,0x1F,0xD0,0x29,0x01,0xF0,0x04,0xA9,0xB3,0xD0,0x02,0xA9,0x33,0x8D,0x1C, +0x30,0xAD,0x1F,0xD0,0x29,0x02,0xF0,0x04,0xA9,0xF3,0xD0,0x02,0xA9,0x73,0x8D,0x1E, +0x30,0xAD,0x1F,0xD0,0x29,0x04,0xF0,0x04,0xA9,0xAF,0xD0,0x02,0xA9,0x2F,0x8D,0x20, +0x30,0xAD,0x1F,0xD0,0x29,0x07,0xC9,0x07,0xF0,0x09,0xA9,0x64,0x8D,0x02,0xD2,0xA9, +0xA8,0xD0,0x02,0xA9,0x00,0x8D,0x03,0xD2,0x68,0x40,0x00,0x50,0x54,0x30,0x30,0x30, +0xA2,0x00,0x86,0x94,0xA2,0x03,0x20,0x73,0x57,0xA2,0x15,0xA0,0x52,0xA9,0xFF,0x20, +0x9E,0x50,0xA2,0x02,0x20,0x59,0x57,0xA2,0x07,0x20,0x59,0x57,0xA5,0x82,0xF0,0x13, +0xA6,0x94,0xBD,0x45,0x55,0xE6,0x94,0xA6,0x94,0xE0,0x13,0xD0,0x14,0x20,0xB5,0x53, +0x4C,0x91,0x52,0xAD,0xFC,0x02,0xC9,0xFF,0xF0,0xF9,0xC9,0xC0,0xB0,0xF5,0xAD,0xFC, +0x02,0xA2,0xFF,0x8E,0xFC,0x02,0x48,0x29,0x80,0xF0,0x05,0xA2,0x08,0x20,0x59,0x57, +0x68,0x48,0x29,0x40,0xF0,0x0A,0xA2,0x05,0x20,0x59,0x57,0xA2,0x04,0x20,0x59,0x57, +0x68,0x29,0x3F,0xC9,0x21,0xF0,0x68,0xC9,0x2C,0xF0,0x74,0xC9,0x34,0xF0,0x68,0xC9, +0x0C,0xF0,0x76,0xAA,0xBD,0x9C,0x57,0x48,0xA9,0x21,0x85,0x95,0xA9,0x30,0x85,0x96, +0x68,0xA0,0xFF,0xC8,0xD1,0x95,0xD0,0xFB,0xB1,0x95,0x49,0x80,0x91,0x95,0xA5,0x82, +0xF0,0x13,0x20,0x05,0x55,0xA2,0x14,0x20,0xB7,0x53,0x20,0x10,0x55,0xA2,0x0A,0x20, +0xB7,0x53,0x4C,0x62,0x54,0x20,0x05,0x55,0xAD,0x0F,0xD2,0x29,0x04,0xF0,0xF9,0x20, +0x10,0x55,0x4C,0x62,0x54,0xA9,0x64,0x8D,0x00,0xD2,0xA9,0xA8,0x8D,0x01,0xD2,0x60, +0xA9,0x00,0x8D,0x01,0xD2,0x8D,0x03,0xD2,0x8D,0x05,0xD2,0x8D,0x07,0xD2,0x60,0xA2, +0x03,0x20,0x59,0x57,0x4C,0xDE,0x54,0xA2,0x06,0x20,0x59,0x57,0x4C,0xDE,0x54,0xA9, +0x7F,0x8D,0x52,0x30,0x8D,0x53,0x30,0xD0,0xA5,0xA9,0x32,0x8D,0x6D,0x30,0xA9,0x34, +0x8D,0x6E,0x30,0xD0,0x99,0x52,0x08,0x0A,0x2B,0x28,0x0D,0x3D,0x39,0x2D,0x1F,0x30, +0x35,0x1A,0x7F,0x2D,0x3F,0x28,0x0D,0xA2,0x02,0x20,0x73,0x57,0xA9,0x00,0x85,0x97, +0xA9,0x00,0x85,0x98,0xA2,0x31,0xA0,0x52,0xA9,0x00,0x20,0x9E,0x50,0xA2,0x09,0x20, +0x59,0x57,0xA5,0x97,0x4A,0x18,0x69,0x11,0x8D,0x0B,0x30,0xA2,0x0F,0xA9,0xFF,0x9D, +0x50,0x31,0x9D,0xB0,0x31,0x9D,0x10,0x32,0x9D,0x70,0x32,0x9D,0xD0,0x32,0xCA,0x10, +0xEC,0xA9,0x00,0x85,0x99,0xA9,0x0C,0x85,0x9A,0xA6,0x99,0xBD,0x17,0x57,0xA8,0xBD, +0x16,0x57,0xAA,0xA5,0x9A,0x20,0x85,0x56,0x18,0xA5,0x9A,0x69,0x06,0x85,0x9A,0xE6, +0x99,0xE6,0x99,0xA5,0x99,0xC9,0x14,0xD0,0xE0,0x20,0xB1,0x53,0xA2,0x54,0xA0,0x31, +0xA9,0x00,0x20,0x85,0x56,0xA9,0x51,0x20,0x6C,0x56,0xA2,0x86,0xA0,0x31,0xA9,0x00, +0x20,0x85,0x56,0xA9,0x5B,0x20,0x6C,0x56,0xA2,0xF8,0xA0,0x30,0xA9,0x48,0x20,0x85, +0x56,0xA2,0xC7,0xA0,0x30,0xA9,0x54,0x20,0x85,0x56,0xA2,0x48,0xA0,0x32,0xA9,0x4E, +0x20,0x85,0x56,0xA9,0x44,0x20,0x6C,0x56,0xA2,0xCA,0xA0,0x30,0xA9,0x48,0x20,0x85, +0x56,0xA2,0x1A,0xA0,0x32,0xA9,0x4E,0x20,0x85,0x56,0xA2,0xCA,0xA0,0x31,0xA9,0x06, +0x20,0x85,0x56,0xA9,0x3C,0x20,0x6C,0x56,0xA2,0x3C,0xA0,0x30,0xA9,0x48,0x20,0x85, +0x56,0xA2,0x8C,0xA0,0x31,0xA9,0x4E,0x20,0x85,0x56,0xA2,0x3C,0xA0,0x31,0xA9,0x06, +0x20,0x85,0x56,0xA9,0x2D,0x20,0x6C,0x56,0xA2,0x9E,0xA0,0x30,0xA9,0x48,0x20,0x85, +0x56,0xA2,0xEE,0xA0,0x31,0xA9,0x4E,0x20,0x85,0x56,0xA9,0x35,0x20,0x6C,0x56,0x20, +0xB5,0x53,0xE6,0x97,0xE6,0x97,0xA5,0x97,0xC9,0x08,0xD0,0x07,0xA5,0x82,0xD0,0x06, +0x4C,0x5C,0x55,0x4C,0x60,0x55,0x20,0xB5,0x53,0x4C,0x50,0x54,0xA4,0x97,0x99,0x00, +0xD2,0xA9,0xA8,0x99,0x01,0xD2,0xA6,0x98,0xBD,0xB6,0x56,0xAA,0x20,0xB7,0x53,0xE6, +0x98,0x20,0x10,0x55,0x60,0x86,0x9B,0x84,0x9C,0xAA,0xA0,0x00,0xA9,0x10,0x85,0x9D, +0xA9,0x06,0x85,0xA3,0xBD,0xBC,0x56,0x11,0x9B,0x91,0x9B,0x20,0xAA,0x56,0xC6,0x9D, +0xD0,0xF2,0xE6,0x9D,0xE8,0xC6,0xA3,0xD0,0xEB,0x60,0x18,0xA5,0x9B,0x69,0x10,0x85, +0x9B,0x90,0x02,0xE6,0x9C,0x60,0x20,0x20,0x20,0x10,0x10,0x20,0x01,0x1F,0x3F,0x7F, +0x3E,0x1C,0x00,0x41,0x42,0x4C,0x70,0x40,0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x43, +0x44,0x48,0x48,0x48,0x00,0x44,0x22,0x10,0x08,0x07,0x00,0x04,0x08,0x05,0x02,0x00, +0x00,0x30,0x48,0x88,0x84,0x84,0x00,0x88,0x88,0x90,0xA0,0xC0,0x00,0xF0,0x88,0x84, +0x82,0x82,0x00,0x82,0x82,0x84,0x88,0xF0,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80, +0x80,0x80,0x80,0x80,0x00,0x1C,0x3E,0x7F,0x7E,0x7C,0x40,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0x04,0x06,0x05,0x06,0xC1,0x30,0x21,0x31,0x81,0x31,0xF1,0x31,0x02,0x30, +0x62,0x30,0x22,0x31,0x82,0x31,0xC2,0x30,0xC2,0x31,0x48,0xBD,0xDC,0x57,0x85,0x9E, +0xBD,0xDD,0x57,0x85,0x9F,0xBD,0xDE,0x57,0x85,0xA0,0xBD,0xDF,0x57,0x85,0xA1,0xA0, +0x00,0x68,0x91,0x9E,0xE6,0x9E,0xD0,0x02,0xE6,0x9F,0x48,0xA5,0x9E,0xC5,0xA0,0xD0, +0xF0,0xA5,0x9F,0xC5,0xA1,0xD0,0xEA,0x68,0x60,0xBD,0x57,0xCA,0xA8,0xBD,0xEC,0x57, +0x85,0x9E,0xBD,0xF6,0x57,0xAA,0xB9,0x61,0xCA,0x9D,0x00,0x30,0xC8,0xE8,0xC6,0x9E, +0xD0,0xF4,0x60,0xBD,0x8C,0x57,0x8D,0xC4,0x02,0xBD,0x90,0x57,0x8D,0xC5,0x02,0xBD, +0x94,0x57,0x8D,0xC6,0x02,0xBD,0x98,0x57,0x8D,0xC8,0x02,0x60,0x2C,0x0C,0x2A,0x18, +0x0F,0x32,0x0C,0x0E,0xD2,0xD6,0x00,0xB4,0xD2,0xA0,0x30,0xB4,0x2C,0x2A,0x1B,0x91, +0x92,0x2B,0x0B,0x0A,0x2F,0x00,0x30,0x35,0xB2,0x29,0x0D,0x1D,0x36,0xA8,0x23,0x93, +0x94,0x22,0x38,0x3A,0x14,0x00,0x13,0x16,0x5B,0x15,0x12,0x11,0x0C,0x00,0x0E,0x2E, +0x00,0x2D,0x0F,0xA1,0x32,0x00,0x25,0x39,0xFF,0x34,0x37,0x31,0x19,0x00,0x10,0x17, +0xA2,0x18,0x1C,0x1E,0x26,0x28,0x24,0x00,0xA3,0x27,0x33,0x21,0x00,0x30,0xFF,0x3E, +0x20,0x30,0x24,0x30,0x24,0x30,0x28,0x30,0x00,0x30,0x20,0x30,0x13,0x03,0x13,0x13, +0x04,0x04,0x03,0xA8,0x03,0x07,0x00,0x28,0x00,0xB7,0x92,0xAB,0x4C,0x22,0x72,0x04, +0x20,0xA1,0xDB,0x20,0xBB,0xDB,0xB0,0x39,0xA2,0xED,0xA0,0x04,0x20,0x48,0xDA,0xA2, +0xFF,0x86,0xF1,0x20,0x44,0xDA,0xF0,0x04,0xA9,0xFF,0x85,0xF0,0x20,0x94,0xDB,0xB0, +0x21,0x48,0xA6,0xD5,0xD0,0x11,0x20,0xEB,0xDB,0x68,0x05,0xD9,0x85,0xD9,0xA6,0xF1, +0x30,0xE6,0xE8,0x86,0xF1,0xD0,0xE1,0x68,0xA6,0xF1,0x10,0x02,0xE6,0xED,0x4C,0x18, +0xD8,0x60,0xC9,0x2E,0xF0,0x14,0xC9,0x45,0xF0,0x19,0xA6,0xF0,0xD0,0x68,0xC9,0x2B, +0xF0,0xC6,0xC9,0x2D,0xF0,0x00,0x85,0xEE,0xF0,0xBE,0xA6,0xF1,0x10,0x58,0xE8,0x86, +0xF1,0xF0,0xB5,0xA5,0xF2,0x85,0xEC,0x20,0x94,0xDB,0xB0,0x37,0xAA,0xA5,0xED,0x48, +0x86,0xED,0x20,0x94,0xDB,0xB0,0x17,0x48,0xA5,0xED,0x0A,0x85,0xED,0x0A,0x0A,0x65, +0xED,0x85,0xED,0x68,0x18,0x65,0xED,0x85,0xED,0xA4,0xF2,0x20,0x9D,0xDB,0xA5,0xEF, +0xF0,0x09,0xA5,0xED,0x49,0xFF,0x18,0x69,0x01,0x85,0xED,0x68,0x18,0x65,0xED,0x85, +0xED,0xD0,0x13,0xC9,0x2B,0xF0,0x06,0xC9,0x2D,0xD0,0x07,0x85,0xEF,0x20,0x94,0xDB, +0x90,0xBA,0xA5,0xEC,0x85,0xF2,0xC6,0xF2,0xA5,0xED,0xA6,0xF1,0x30,0x05,0xF0,0x03, +0x38,0xE5,0xF1,0x48,0x2A,0x68,0x6A,0x85,0xED,0x90,0x03,0x20,0xEB,0xDB,0xA5,0xED, +0x18,0x69,0x44,0x85,0xD4,0x20,0x00,0xDC,0xB0,0x0B,0xA6,0xEE,0xF0,0x06,0xA5,0xD4, +0x09,0x80,0x85,0xD4,0x18,0x60,0x20,0x51,0xDA,0xA9,0x30,0x8D,0x7F,0x05,0xA5,0xD4, +0xF0,0x28,0x29,0x7F,0xC9,0x3F,0x90,0x28,0xC9,0x45,0xB0,0x24,0x38,0xE9,0x3F,0x20, +0x70,0xDC,0x20,0xA4,0xDC,0x09,0x80,0x9D,0x80,0x05,0xAD,0x80,0x05,0xC9,0x2E,0xF0, +0x03,0x4C,0x88,0xD9,0x20,0xC1,0xDC,0x4C,0x9C,0xD9,0xA9,0xB0,0x8D,0x80,0x05,0x60, +0xA9,0x01,0x20,0x70,0xDC,0x20,0xA4,0xDC,0xE8,0x86,0xF2,0xA5,0xD4,0x0A,0x38,0xE9, +0x80,0xAE,0x80,0x05,0xE0,0x30,0xF0,0x17,0xAE,0x81,0x05,0xAC,0x82,0x05,0x8E,0x82, +0x05,0x8C,0x81,0x05,0xA6,0xF2,0xE0,0x02,0xD0,0x02,0xE6,0xF2,0x18,0x69,0x01,0x85, +0xED,0xA9,0x45,0xA4,0xF2,0x20,0x9F,0xDC,0x84,0xF2,0xA5,0xED,0x10,0x0B,0xA9,0x00, +0x38,0xE5,0xED,0x85,0xED,0xA9,0x2D,0xD0,0x02,0xA9,0x2B,0x20,0x9F,0xDC,0xA2,0x00, +0xA5,0xED,0x38,0xE9,0x0A,0x90,0x03,0xE8,0xD0,0xF8,0x18,0x69,0x0A,0x48,0x8A,0x20, +0x9D,0xDC,0x68,0x09,0x80,0x20,0x9D,0xDC,0xAD,0x80,0x05,0xC9,0x30,0xD0,0x0D,0x18, +0xA5,0xF3,0x69,0x01,0x85,0xF3,0xA5,0xF4,0x69,0x00,0x85,0xF4,0xA5,0xD4,0x10,0x09, +0x20,0xC1,0xDC,0xA0,0x00,0xA9,0x2D,0x91,0xF3,0x60,0xA5,0xD4,0x85,0xF8,0xA5,0xD5, +0x85,0xF7,0x20,0x44,0xDA,0xF8,0xA0,0x10,0x06,0xF8,0x26,0xF7,0xA2,0x03,0xB5,0xD4, +0x75,0xD4,0x95,0xD4,0xCA,0xD0,0xF7,0x88,0xD0,0xEE,0xD8,0xA9,0x42,0x85,0xD4,0x4C, +0x00,0xDC,0xA9,0x00,0x85,0xF7,0x85,0xF8,0xA5,0xD4,0x30,0x66,0xC9,0x43,0xB0,0x62, +0x38,0xE9,0x40,0x90,0x3F,0x69,0x00,0x0A,0x85,0xF5,0x20,0x5A,0xDA,0xB0,0x53,0xA5, +0xF7,0x85,0xF9,0xA5,0xF8,0x85,0xFA,0x20,0x5A,0xDA,0xB0,0x46,0x20,0x5A,0xDA,0xB0, +0x41,0x18,0xA5,0xF8,0x65,0xFA,0x85,0xF8,0xA5,0xF7,0x65,0xF9,0x85,0xF7,0xB0,0x32, +0x20,0xB9,0xDC,0x18,0x65,0xF8,0x85,0xF8,0xA5,0xF7,0x69,0x00,0xB0,0x24,0x85,0xF7, +0xC6,0xF5,0xD0,0xC6,0x20,0xB9,0xDC,0xC9,0x05,0x90,0x0D,0x18,0xA5,0xF8,0x69,0x01, +0x85,0xF8,0xA5,0xF7,0x69,0x00,0x85,0xF7,0xA5,0xF8,0x85,0xD4,0xA5,0xF7,0x85,0xD5, +0x18,0x60,0x38,0x60,0xA2,0xD4,0xA0,0x06,0xA9,0x00,0x95,0x00,0xE8,0x88,0xD0,0xFA, +0x60,0xA9,0x05,0x85,0xF4,0xA9,0x80,0x85,0xF3,0x60,0x18,0x26,0xF8,0x26,0xF7,0x60, +0xA5,0xE0,0x49,0x80,0x85,0xE0,0xA5,0xE0,0x29,0x7F,0x85,0xF7,0xA5,0xD4,0x29,0x7F, +0x38,0xE5,0xF7,0x10,0x10,0xA2,0x05,0xB5,0xD4,0xB4,0xE0,0x95,0xE0,0x98,0x95,0xD4, +0xCA,0x10,0xF4,0x30,0xE1,0xF0,0x07,0xC9,0x05,0xB0,0x19,0x20,0x3E,0xDC,0xF8,0xA5, +0xD4,0x45,0xE0,0x30,0x1E,0xA2,0x04,0x18,0xB5,0xD5,0x75,0xE1,0x95,0xD5,0xCA,0x10, +0xF7,0xD8,0xB0,0x03,0x4C,0x00,0xDC,0xA9,0x01,0x20,0x3A,0xDC,0xA9,0x01,0x85,0xD5, +0x4C,0x00,0xDC,0xA2,0x04,0x38,0xB5,0xD5,0xF5,0xE1,0x95,0xD5,0xCA,0x10,0xF7,0x90, +0x04,0xD8,0x4C,0x00,0xDC,0xA5,0xD4,0x49,0x80,0x85,0xD4,0x38,0xA2,0x04,0xA9,0x00, +0xF5,0xD5,0x95,0xD5,0xCA,0x10,0xF7,0xD8,0x4C,0x00,0xDC,0xA5,0xD4,0xF0,0x45,0xA5, +0xE0,0xF0,0x3E,0x20,0xCF,0xDC,0x38,0xE9,0x40,0x38,0x65,0xE0,0x30,0x38,0x20,0xE0, +0xDC,0xA5,0xDF,0x29,0x0F,0x85,0xF6,0xC6,0xF6,0x30,0x06,0x20,0x01,0xDD,0x4C,0xF7, +0xDA,0xA5,0xDF,0x4A,0x4A,0x4A,0x4A,0x85,0xF6,0xC6,0xF6,0x30,0x06,0x20,0x05,0xDD, +0x4C,0x09,0xDB,0x20,0x62,0xDC,0xC6,0xF5,0xD0,0xD7,0xA5,0xED,0x85,0xD4,0x4C,0x04, +0xDC,0x20,0x44,0xDA,0x18,0x60,0x38,0x60,0xA5,0xE0,0xF0,0xFA,0xA5,0xD4,0xF0,0xF4, +0x20,0xCF,0xDC,0x38,0xE5,0xE0,0x18,0x69,0x40,0x30,0xEB,0x20,0xE0,0xDC,0xE6,0xF5, +0x4C,0x4E,0xDB,0xA2,0x00,0xB5,0xD5,0x95,0xD4,0xE8,0xE0,0x0C,0xD0,0xF7,0xA0,0x05, +0x38,0xF8,0xB9,0xDA,0x00,0xF9,0xE6,0x00,0x99,0xDA,0x00,0x88,0x10,0xF4,0xD8,0x90, +0x04,0xE6,0xD9,0xD0,0xE9,0x20,0x0F,0xDD,0x06,0xD9,0x06,0xD9,0x06,0xD9,0x06,0xD9, +0xA0,0x05,0x38,0xF8,0xB9,0xDA,0x00,0xF9,0xE0,0x00,0x99,0xDA,0x00,0x88,0x10,0xF4, +0xD8,0x90,0x04,0xE6,0xD9,0xD0,0xE9,0x20,0x09,0xDD,0xC6,0xF5,0xD0,0xB5,0x20,0x62, +0xDC,0x4C,0x1A,0xDB,0x20,0xAF,0xDB,0xA4,0xF2,0x90,0x02,0xB1,0xF3,0xC8,0x84,0xF2, +0x60,0xA4,0xF2,0xA9,0x20,0xD1,0xF3,0xD0,0x03,0xC8,0xD0,0xF9,0x84,0xF2,0x60,0xA4, +0xF2,0xB1,0xF3,0x38,0xE9,0x30,0x90,0x18,0xC9,0x0A,0x60,0xA5,0xF2,0x48,0x20,0x94, +0xDB,0x90,0x1F,0xC9,0x2E,0xF0,0x14,0xC9,0x2B,0xF0,0x07,0xC9,0x2D,0xF0,0x03,0x68, +0x38,0x60,0x20,0x94,0xDB,0x90,0x0B,0xC9,0x2E,0xD0,0xF4,0x20,0x94,0xDB,0x90,0x02, +0xB0,0xED,0x68,0x85,0xF2,0x18,0x60,0xA2,0xE7,0xD0,0x02,0xA2,0xD5,0xA0,0x04,0x18, +0x36,0x04,0x36,0x03,0x36,0x02,0x36,0x01,0x36,0x00,0x26,0xEC,0x88,0xD0,0xF0,0x60, +0xA2,0x00,0x86,0xDA,0xA2,0x04,0xA5,0xD4,0xF0,0x2E,0xA5,0xD5,0xD0,0x1A,0xA0,0x00, +0xB9,0xD6,0x00,0x99,0xD5,0x00,0xC8,0xC0,0x05,0x90,0xF5,0xC6,0xD4,0xCA,0xD0,0xEA, +0xA5,0xD5,0xD0,0x04,0x85,0xD4,0x18,0x60,0xA5,0xD4,0x29,0x7F,0xC9,0x71,0x90,0x01, +0x60,0xC9,0x0F,0xB0,0x03,0x20,0x44,0xDA,0x18,0x60,0xA2,0xD4,0xD0,0x02,0xA2,0xE0, +0x86,0xF9,0x85,0xF7,0x85,0xF8,0xA0,0x04,0xB5,0x04,0x95,0x05,0xCA,0x88,0xD0,0xF8, +0xA9,0x00,0x95,0x05,0xA6,0xF9,0xC6,0xF7,0xD0,0xEC,0xB5,0x00,0x18,0x65,0xF8,0x95, +0x00,0x60,0xA2,0x0A,0xB5,0xD4,0x95,0xD5,0xCA,0x10,0xF9,0xA9,0x00,0x85,0xD4,0x60, +0x85,0xF7,0xA2,0x00,0xA0,0x00,0x20,0x93,0xDC,0x38,0xE9,0x01,0x85,0xF7,0xB5,0xD5, +0x4A,0x4A,0x4A,0x4A,0x20,0x9D,0xDC,0xB5,0xD5,0x29,0x0F,0x20,0x9D,0xDC,0xE8,0xE0, +0x05,0x90,0xE3,0xA5,0xF7,0xD0,0x05,0xA9,0x2E,0x20,0x9F,0xDC,0x60,0x09,0x30,0x99, +0x80,0x05,0xC8,0x60,0xA2,0x0A,0xBD,0x80,0x05,0xC9,0x2E,0xF0,0x07,0xC9,0x30,0xD0, +0x07,0xCA,0xD0,0xF2,0xCA,0xBD,0x80,0x05,0x60,0x20,0xEB,0xDB,0xA5,0xEC,0x29,0x0F, +0x60,0x38,0xA5,0xF3,0xE9,0x01,0x85,0xF3,0xA5,0xF4,0xE9,0x00,0x85,0xF4,0x60,0xA5, +0xD4,0x45,0xE0,0x29,0x80,0x85,0xEE,0x06,0xE0,0x46,0xE0,0xA5,0xD4,0x29,0x7F,0x60, +0x05,0xEE,0x85,0xED,0xA9,0x00,0x85,0xD4,0x85,0xE0,0x20,0x28,0xDD,0x20,0xE7,0xDB, +0xA5,0xEC,0x29,0x0F,0x85,0xE6,0xA9,0x05,0x85,0xF5,0x20,0x34,0xDD,0x20,0x44,0xDA, +0x60,0xA2,0xD9,0xD0,0x06,0xA2,0xD9,0xD0,0x08,0xA2,0xDF,0xA0,0xE5,0xD0,0x04,0xA2, +0xDF,0xA0,0xEB,0xA9,0x05,0x85,0xF7,0x18,0xF8,0xB5,0x00,0x79,0x00,0x00,0x95,0x00, +0xCA,0x88,0xC6,0xF7,0x10,0xF3,0xD8,0x60,0xA0,0x05,0xB9,0xE0,0x00,0x99,0xE6,0x00, +0x88,0x10,0xF7,0x60,0xA0,0x05,0xB9,0xD4,0x00,0x99,0xDA,0x00,0x88,0x10,0xF7,0x60, +0x86,0xFE,0x84,0xFF,0x85,0xEF,0xA2,0xE0,0xA0,0x05,0x20,0xA7,0xDD,0x20,0xB6,0xDD, +0xA6,0xFE,0xA4,0xFF,0x20,0x89,0xDD,0xC6,0xEF,0xF0,0x2D,0x20,0xDB,0xDA,0xB0,0x28, +0x18,0xA5,0xFE,0x69,0x06,0x85,0xFE,0x90,0x06,0xA5,0xFF,0x69,0x00,0x85,0xFF,0xA6, +0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20,0x66,0xDA,0xB0,0x0D,0xC6,0xEF,0xF0,0x09,0xA2, +0xE0,0xA0,0x05,0x20,0x98,0xDD,0x30,0xD3,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB1, +0xFC,0x99,0xD4,0x00,0x88,0x10,0xF8,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB1,0xFC, +0x99,0xE0,0x00,0x88,0x10,0xF8,0x60,0x86,0xFC,0x84,0xFD,0xA0,0x05,0xB9,0xD4,0x00, +0x91,0xFC,0x88,0x10,0xF8,0x60,0xA2,0x05,0xB5,0xD4,0x95,0xE0,0xCA,0x10,0xF9,0x60, +0xA2,0x89,0xA0,0xDE,0x20,0x98,0xDD,0x20,0xDB,0xDA,0xB0,0x7F,0xA9,0x00,0x85,0xF1, +0xA5,0xD4,0x85,0xF0,0x29,0x7F,0x85,0xD4,0x38,0xE9,0x40,0x30,0x26,0xC9,0x04,0x10, +0x6A,0xA2,0xE6,0xA0,0x05,0x20,0xA7,0xDD,0x20,0xD2,0xD9,0xA5,0xD4,0x85,0xF1,0xA5, +0xD5,0xD0,0x58,0x20,0xAA,0xD9,0x20,0xB6,0xDD,0xA2,0xE6,0xA0,0x05,0x20,0x89,0xDD, +0x20,0x60,0xDA,0xA9,0x0A,0xA2,0x4D,0xA0,0xDE,0x20,0x40,0xDD,0x20,0xB6,0xDD,0x20, +0xDB,0xDA,0xA5,0xF1,0xF0,0x23,0x18,0x6A,0x85,0xE0,0xA9,0x01,0x90,0x02,0xA9,0x10, +0x85,0xE1,0xA2,0x04,0xA9,0x00,0x95,0xE2,0xCA,0x10,0xFB,0xA5,0xE0,0x18,0x69,0x40, +0xB0,0x19,0x30,0x17,0x85,0xE0,0x20,0xDB,0xDA,0xA5,0xF0,0x10,0x0D,0x20,0xB6,0xDD, +0xA2,0x8F,0xA0,0xDE,0x20,0x89,0xDD,0x20,0x28,0xDB,0x60,0x38,0x60,0x3D,0x17,0x94, +0x19,0x00,0x00,0x3D,0x57,0x33,0x05,0x00,0x00,0x3E,0x05,0x54,0x76,0x62,0x00,0x3E, +0x32,0x19,0x62,0x27,0x00,0x3F,0x01,0x68,0x60,0x30,0x36,0x3F,0x07,0x32,0x03,0x27, +0x41,0x3F,0x25,0x43,0x34,0x56,0x75,0x3F,0x66,0x27,0x37,0x30,0x50,0x40,0x01,0x15, +0x12,0x92,0x55,0x3F,0x99,0x99,0x99,0x99,0x99,0x3F,0x43,0x42,0x94,0x48,0x19,0x40, +0x01,0x00,0x00,0x00,0x00,0x86,0xFE,0x84,0xFF,0xA2,0xE0,0xA0,0x05,0x20,0xA7,0xDD, +0xA6,0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20,0x66,0xDA,0xA2,0xE6,0xA0,0x05,0x20,0xA7, +0xDD,0xA2,0xE0,0xA0,0x05,0x20,0x89,0xDD,0xA6,0xFE,0xA4,0xFF,0x20,0x98,0xDD,0x20, +0x60,0xDA,0xA2,0xE6,0xA0,0x05,0x20,0x98,0xDD,0x20,0x28,0xDB,0x60,0xA9,0x01,0xD0, +0x02,0xA9,0x00,0x85,0xF0,0xA5,0xD4,0xF0,0x05,0x30,0x03,0x4C,0xF6,0xDF,0x38,0x60, +0xE9,0x40,0x0A,0x85,0xF1,0xA5,0xD5,0x29,0xF0,0xD0,0x04,0xA9,0x01,0xD0,0x04,0xE6, +0xF1,0xA9,0x10,0x85,0xE1,0xA2,0x04,0xA9,0x00,0x95,0xE2,0xCA,0x10,0xFB,0x20,0x28, +0xDB,0xA2,0x66,0xA0,0xDF,0x20,0x95,0xDE,0xA2,0xE6,0xA0,0x05,0x20,0xA7,0xDD,0x20, +0xB6,0xDD,0x20,0xDB,0xDA,0xA9,0x0A,0xA2,0x72,0xA0,0xDF,0x20,0x40,0xDD,0xA2,0xE6, +0xA0,0x05,0x20,0x98,0xDD,0x20,0xDB,0xDA,0xA2,0x6C,0xA0,0xDF,0x20,0x98,0xDD,0x20, +0x66,0xDA,0x20,0xB6,0xDD,0xA9,0x00,0x85,0xD5,0xA5,0xF1,0x85,0xD4,0x10,0x07,0x49, +0xFF,0x18,0x69,0x01,0x85,0xD4,0x20,0xAA,0xD9,0x24,0xF1,0x10,0x06,0xA9,0x80,0x05, +0xD4,0x85,0xD4,0x20,0x66,0xDA,0xA5,0xF0,0xF0,0x0A,0xA2,0x89,0xA0,0xDE,0x20,0x98, +0xDD,0x20,0x28,0xDB,0x18,0x60,0x40,0x03,0x16,0x22,0x77,0x66,0x3F,0x50,0x00,0x00, +0x00,0x00,0x3F,0x49,0x15,0x57,0x11,0x08,0xBF,0x51,0x70,0x49,0x47,0x08,0x3F,0x39, +0x20,0x57,0x61,0x95,0xBF,0x04,0x39,0x63,0x03,0x55,0x3F,0x10,0x09,0x30,0x12,0x64, +0x3F,0x09,0x39,0x08,0x04,0x60,0x3F,0x12,0x42,0x58,0x47,0x42,0x3F,0x17,0x37,0x12, +0x06,0x08,0x3F,0x28,0x95,0x29,0x71,0x17,0x3F,0x86,0x85,0x88,0x96,0x44,0x3E,0x16, +0x05,0x44,0x49,0x00,0xBE,0x95,0x68,0x38,0x45,0x00,0x3F,0x02,0x68,0x79,0x94,0x16, +0xBF,0x04,0x92,0x78,0x90,0x80,0x3F,0x07,0x03,0x15,0x20,0x00,0xBF,0x08,0x92,0x29, +0x12,0x44,0x3F,0x11,0x08,0x40,0x09,0x11,0xBF,0x14,0x28,0x31,0x56,0x04,0x3F,0x19, +0x99,0x98,0x77,0x44,0xBF,0x33,0x33,0x33,0x31,0x13,0x3F,0x99,0x99,0x99,0x99,0x99, +0x3F,0x78,0x53,0x98,0x16,0x34,0xA5,0xD4,0x85,0xE0,0x38,0x4C,0xE0,0xDE,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, +0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0x66,0x66,0xFF,0x66,0x00, +0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00,0x00,0x66,0x6C,0x18,0x30,0x66,0x46,0x00, +0x1C,0x36,0x1C,0x38,0x6F,0x66,0x3B,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x0E,0x1C,0x18,0x18,0x1C,0x0E,0x00,0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, +0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, +0x00,0x3C,0x66,0x6E,0x76,0x66,0x3C,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x7E,0x00, +0x00,0x3C,0x66,0x0C,0x18,0x30,0x7E,0x00,0x00,0x7E,0x0C,0x18,0x0C,0x66,0x3C,0x00, +0x00,0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x00,0x00,0x7E,0x60,0x7C,0x06,0x66,0x3C,0x00, +0x00,0x3C,0x60,0x7C,0x66,0x66,0x3C,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x30,0x00, +0x00,0x3C,0x66,0x3C,0x66,0x66,0x3C,0x00,0x00,0x3C,0x66,0x3E,0x06,0x0C,0x38,0x00, +0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, +0x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, +0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x00,0x3C,0x66,0x0C,0x18,0x00,0x18,0x00, +0x00,0x3C,0x66,0x6E,0x6E,0x60,0x3E,0x00,0x00,0x18,0x3C,0x66,0x66,0x7E,0x66,0x00, +0x00,0x7C,0x66,0x7C,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00, +0x00,0x78,0x6C,0x66,0x66,0x6C,0x78,0x00,0x00,0x7E,0x60,0x7C,0x60,0x60,0x7E,0x00, +0x00,0x7E,0x60,0x7C,0x60,0x60,0x60,0x00,0x00,0x3E,0x60,0x60,0x6E,0x66,0x3E,0x00, +0x00,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x7E,0x00, +0x00,0x06,0x06,0x06,0x06,0x66,0x3C,0x00,0x00,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00, +0x00,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x00, +0x00,0x66,0x76,0x7E,0x7E,0x6E,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3C,0x66,0x66,0x66,0x6C,0x36,0x00, +0x00,0x7C,0x66,0x66,0x7C,0x6C,0x66,0x00,0x00,0x3C,0x60,0x3C,0x06,0x06,0x3C,0x00, +0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, +0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, +0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x18,0x00, +0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x1E,0x00, +0x00,0x40,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, +0x00,0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, +0x00,0x36,0x7F,0x7F,0x3E,0x1C,0x08,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00, +0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18, +0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03, +0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F, +0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00, +0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0, +0x00,0x1C,0x1C,0x77,0x77,0x08,0x1C,0x00,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18, +0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0x18, +0x00,0x00,0x3C,0x7E,0x7E,0x7E,0x3C,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, +0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18, +0x18,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, +0x18,0x18,0x18,0x1F,0x1F,0x00,0x00,0x00,0x78,0x60,0x78,0x60,0x7E,0x18,0x1E,0x00, +0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00, +0x00,0x18,0x30,0x7E,0x30,0x18,0x00,0x00,0x00,0x18,0x0C,0x7E,0x0C,0x18,0x00,0x00, +0x00,0x18,0x3C,0x7E,0x7E,0x3C,0x18,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00, +0x00,0x60,0x60,0x7C,0x66,0x66,0x7C,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x3C,0x00, +0x00,0x06,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, +0x00,0x0E,0x18,0x3E,0x18,0x18,0x18,0x00,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x7C, +0x00,0x60,0x60,0x7C,0x66,0x66,0x66,0x00,0x00,0x18,0x00,0x38,0x18,0x18,0x3C,0x00, +0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3C,0x00,0x60,0x60,0x6C,0x78,0x6C,0x66,0x00, +0x00,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, +0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, +0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x06, +0x00,0x00,0x7C,0x66,0x60,0x60,0x60,0x00,0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, +0x00,0x18,0x7E,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x00, +0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x63,0x6B,0x7F,0x3E,0x36,0x00, +0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x3E,0x0C,0x78, +0x00,0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00,0x00,0x18,0x3C,0x7E,0x7E,0x18,0x3C,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x7E,0x78,0x7C,0x6E,0x66,0x06,0x00, +0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00,0x10,0x18,0x1C,0x1E,0x1C,0x18,0x10,0x00, +0x93,0xEF,0x2D,0xF2,0x49,0xF2,0xAF,0xF2,0x1D,0xF2,0x2C,0xF2,0x4C,0x6E,0xEF,0x00, +0x8D,0xEF,0x2D,0xF2,0x7F,0xF1,0xA3,0xF1,0x1D,0xF2,0xAE,0xF9,0x4C,0x6E,0xEF,0x00, +0x1D,0xF2,0x1D,0xF2,0xFC,0xF2,0x2C,0xF2,0x1D,0xF2,0x2C,0xF2,0x4C,0x6E,0xEF,0x00, +0xC1,0xFE,0x06,0xFF,0xC0,0xFE,0xCA,0xFE,0xA2,0xFE,0xC0,0xFE,0x4C,0x99,0xFE,0x00, +0xE5,0xFC,0xCE,0xFD,0x79,0xFD,0xB3,0xFD,0xCB,0xFD,0xE4,0xFC,0x4C,0xDB,0xFC,0x00, +0x4C,0xA3,0xC6,0x4C,0xB3,0xC6,0x4C,0xDF,0xE4,0x4C,0x33,0xC9,0x4C,0x72,0xC2,0x4C, +0xE2,0xC0,0x4C,0x8A,0xC2,0x4C,0x5C,0xE9,0x4C,0x17,0xEC,0x4C,0x0C,0xC0,0x4C,0xC1, +0xE4,0x4C,0x23,0xF2,0x4C,0x90,0xC2,0x4C,0xC8,0xC2,0x4C,0x8D,0xFD,0x4C,0xF7,0xFC, +0x4C,0x23,0xF2,0x4C,0x00,0x50,0x4C,0xBC,0xEE,0x4C,0x15,0xE9,0x4C,0x98,0xE8,0x90, +0xC9,0x95,0xC9,0x9A,0xC9,0x9F,0xC9,0xA4,0xC9,0xA9,0xC9,0x4C,0x0C,0xC9,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x60,0xA2,0x00,0xA9,0xFF,0x9D,0x40,0x03,0xA9,0xDB,0x9D,0x46,0x03,0xA9,0xE4,0x9D, +0x47,0x03,0x8A,0x18,0x69,0x10,0xAA,0xC9,0x80,0x90,0xE8,0x60,0xA0,0x85,0x60,0x85, +0x2F,0x86,0x2E,0x8A,0x29,0x0F,0xD0,0x04,0xE0,0x80,0x90,0x05,0xA0,0x86,0x4C,0x70, +0xE6,0xA0,0x00,0xBD,0x40,0x03,0x99,0x20,0x00,0xE8,0xC8,0xC0,0x0C,0x90,0xF4,0xA5, +0x20,0xC9,0x7F,0xD0,0x15,0xA5,0x22,0xC9,0x0C,0xF0,0x71,0xAD,0xE9,0x02,0xD0,0x05, +0xA0,0x82,0x4C,0x70,0xE6,0x20,0x29,0xCA,0x30,0xF8,0xA0,0x84,0xA5,0x22,0xC9,0x03, +0x90,0x25,0xA8,0xC0,0x0E,0x90,0x02,0xA0,0x0E,0x84,0x17,0xB9,0x2A,0xE7,0xF0,0x0F, +0xC9,0x02,0xF0,0x48,0xC9,0x08,0xB0,0x5F,0xC9,0x04,0xF0,0x76,0x4C,0x1E,0xE6,0xA5, +0x20,0xC9,0xFF,0xF0,0x05,0xA0,0x81,0x4C,0x70,0xE6,0xAD,0xE9,0x02,0xD0,0x27,0x20, +0xFF,0xE6,0xB0,0x22,0xA9,0x00,0x8D,0xEA,0x02,0x8D,0xEB,0x02,0x20,0x95,0xE6,0xB0, +0xE6,0x20,0xEA,0xE6,0xA9,0x0B,0x85,0x17,0x20,0x95,0xE6,0xA5,0x2C,0x85,0x26,0xA5, +0x2D,0x85,0x27,0x4C,0x72,0xE6,0x20,0xF9,0xEE,0x4C,0x70,0xE6,0xA0,0x01,0x84,0x23, +0x20,0x95,0xE6,0xB0,0x03,0x20,0xEA,0xE6,0xA9,0xFF,0x85,0x20,0xA9,0xE4,0x85,0x27, +0xA9,0xDB,0x85,0x26,0x4C,0x72,0xE6,0xA5,0x20,0xC9,0xFF,0xD0,0x05,0x20,0xFF,0xE6, +0xB0,0xA5,0x20,0x95,0xE6,0x20,0xEA,0xE6,0xA6,0x2E,0xBD,0x40,0x03,0x85,0x20,0x4C, +0x72,0xE6,0xA5,0x22,0x25,0x2A,0xD0,0x05,0xA0,0x83,0x4C,0x70,0xE6,0x20,0x95,0xE6, +0xB0,0xF8,0xA5,0x28,0x05,0x29,0xD0,0x08,0x20,0xEA,0xE6,0x85,0x2F,0x4C,0x72,0xE6, +0x20,0xEA,0xE6,0x85,0x2F,0x30,0x41,0xA0,0x00,0x91,0x24,0x20,0xD1,0xE6,0xA5,0x22, +0x29,0x02,0xD0,0x0C,0xA5,0x2F,0xC9,0x9B,0xD0,0x06,0x20,0xBB,0xE6,0x4C,0x18,0xE6, +0x20,0xBB,0xE6,0xD0,0xDB,0xA5,0x22,0x29,0x02,0xD0,0x1D,0x20,0xEA,0xE6,0x85,0x2F, +0x30,0x0A,0xA5,0x2F,0xC9,0x9B,0xD0,0xF3,0xA9,0x89,0x85,0x23,0x20,0xC8,0xE6,0xA0, +0x00,0xA9,0x9B,0x91,0x24,0x20,0xD1,0xE6,0x20,0xD8,0xE6,0x4C,0x72,0xE6,0xA5,0x22, +0x25,0x2A,0xD0,0x05,0xA0,0x87,0x4C,0x70,0xE6,0x20,0x95,0xE6,0xB0,0xF8,0xA5,0x28, +0x05,0x29,0xD0,0x06,0xA5,0x2F,0xE6,0x28,0xD0,0x06,0xA0,0x00,0xB1,0x24,0x85,0x2F, +0x20,0xEA,0xE6,0x08,0x20,0xD1,0xE6,0x20,0xBB,0xE6,0x28,0x30,0x1D,0xA5,0x22,0x29, +0x02,0xD0,0x06,0xA5,0x2F,0xC9,0x9B,0xF0,0x11,0xA5,0x28,0x05,0x29,0xD0,0xDB,0xA5, +0x22,0x29,0x02,0xD0,0x05,0xA9,0x9B,0x20,0xEA,0xE6,0x20,0xD8,0xE6,0x4C,0x72,0xE6, +0x84,0x23,0xA4,0x2E,0xB9,0x44,0x03,0x85,0x24,0xB9,0x45,0x03,0x85,0x25,0xA2,0x00, +0x8E,0xE9,0x02,0xB5,0x20,0x99,0x40,0x03,0xE8,0xC8,0xE0,0x0C,0x90,0xF5,0xA5,0x2F, +0xA6,0x2E,0xA4,0x23,0x60,0xA4,0x20,0xC0,0x22,0x90,0x04,0xA0,0x85,0xB0,0x1B,0xB9, +0x1B,0x03,0x85,0x2C,0xB9,0x1C,0x03,0x85,0x2D,0xA4,0x17,0xB9,0x2A,0xE7,0xA8,0xB1, +0x2C,0xAA,0xC8,0xB1,0x2C,0x85,0x2D,0x86,0x2C,0x18,0x60,0xA5,0x28,0xD0,0x02,0xC6, +0x29,0xC6,0x28,0xA5,0x28,0x05,0x29,0x60,0xA5,0x24,0xD0,0x02,0xC6,0x25,0xC6,0x24, +0x60,0xE6,0x24,0xD0,0x02,0xE6,0x25,0x60,0xA6,0x2E,0x38,0xBD,0x48,0x03,0xE5,0x28, +0x85,0x28,0xBD,0x49,0x03,0xE5,0x29,0x85,0x29,0x60,0xA0,0x92,0x20,0xF4,0xE6,0x84, +0x23,0xC0,0x00,0x60,0xAA,0xA5,0x2D,0x48,0xA5,0x2C,0x48,0x8A,0xA6,0x2E,0x60,0x38, +0xA0,0x01,0xB1,0x24,0xE9,0x31,0x30,0x04,0xC9,0x09,0x90,0x02,0xA9,0x00,0x85,0x21, +0xE6,0x21,0xA0,0x00,0xB1,0x24,0xF0,0x0C,0xA0,0x21,0xD9,0x1A,0x03,0xF0,0x09,0x88, +0x88,0x88,0x10,0xF6,0xA0,0x82,0x38,0x60,0x98,0x85,0x20,0x18,0x60,0x00,0x04,0x04, +0x04,0x04,0x06,0x06,0x06,0x06,0x02,0x08,0x0A,0xA5,0x08,0xF0,0x25,0xA9,0xE9,0x85, +0x4A,0xA9,0x03,0x85,0x4B,0xA0,0x12,0x18,0xB1,0x4A,0xAA,0xC8,0x71,0x4A,0xF0,0x26, +0xB1,0x4A,0x85,0x4B,0x86,0x4A,0x20,0x56,0xCB,0xD0,0x1B,0x20,0x94,0xE8,0xB0,0x16, +0x90,0xE3,0xA9,0x00,0x8D,0xFB,0x03,0x8D,0xFC,0x03,0xA9,0x4F,0xD0,0x2D,0xA9,0x00, +0xA8,0x20,0xBE,0xE7,0x10,0x01,0x60,0x18,0xAD,0xE7,0x02,0x6D,0xEA,0x02,0x8D,0x12, +0x03,0xAD,0xE8,0x02,0x6D,0xEB,0x02,0x8D,0x13,0x03,0x38,0xAD,0xE5,0x02,0xED,0x12, +0x03,0xAD,0xE6,0x02,0xED,0x13,0x03,0xB0,0x09,0xA9,0x4E,0xA8,0x20,0xBE,0xE7,0x4C, +0x6E,0xE7,0xAD,0xEC,0x02,0xAE,0xE7,0x02,0x8E,0xEC,0x02,0xAE,0xE8,0x02,0x8E,0xED, +0x02,0x20,0xDE,0xE7,0x30,0xE3,0x38,0x20,0x9E,0xE8,0xB0,0xDD,0x90,0xB0,0x48,0xA2, +0x09,0xBD,0xD4,0xE7,0x9D,0x00,0x03,0xCA,0x10,0xF7,0x8C,0x0B,0x03,0x68,0x8D,0x0A, +0x03,0x4C,0x59,0xE4,0x4F,0x01,0x40,0x40,0xEA,0x02,0x1E,0x00,0x04,0x00,0x8D,0x13, +0x03,0xA2,0x00,0x8E,0x12,0x03,0xCA,0x8E,0x15,0x03,0xAD,0xEC,0x02,0x6A,0x90,0x08, +0xEE,0xEC,0x02,0xD0,0x03,0xEE,0xED,0x02,0xAD,0xEC,0x02,0x8D,0xD1,0x02,0xAD,0xED, +0x02,0x8D,0xD2,0x02,0xA9,0x16,0x8D,0xCF,0x02,0xA9,0xE8,0x8D,0xD0,0x02,0xA9,0x80, +0x8D,0xD3,0x02,0x4C,0x45,0xC7,0xAE,0x15,0x03,0xE8,0x8E,0x15,0x03,0xF0,0x08,0xAE, +0x15,0x03,0xBD,0x7D,0x03,0x18,0x60,0xA9,0x80,0x8D,0x15,0x03,0x20,0x33,0xE8,0x10, +0xEE,0x38,0x60,0xA2,0x0B,0xBD,0x51,0xE8,0x9D,0x00,0x03,0xCA,0x10,0xF7,0xAE,0x12, +0x03,0x8E,0x0A,0x03,0xE8,0x8E,0x12,0x03,0xAD,0x13,0x03,0x8D,0x00,0x03,0x4C,0x59, +0xE4,0x00,0x01,0x26,0x40,0xFD,0x03,0x1E,0x00,0x80,0x00,0x00,0x00,0x8C,0x12,0x03, +0x8D,0x13,0x03,0xA9,0xE9,0x85,0x4A,0xA9,0x03,0x85,0x4B,0xA0,0x12,0xB1,0x4A,0xAA, +0xC8,0xB1,0x4A,0xCD,0x13,0x03,0xD0,0x07,0xEC,0x12,0x03,0xD0,0x02,0x18,0x60,0xC9, +0x00,0xD0,0x06,0xE0,0x00,0xD0,0x02,0x38,0x60,0x86,0x4A,0x85,0x4B,0x20,0x56,0xCB, +0xD0,0xF5,0xF0,0xD7,0x38,0x08,0xB0,0x28,0x8D,0xED,0x02,0x8C,0xEC,0x02,0x08,0xA9, +0x00,0xA8,0x20,0x5D,0xE8,0xB0,0x27,0xA0,0x12,0xAD,0xEC,0x02,0x91,0x4A,0xAA,0xC8, +0xAD,0xED,0x02,0x91,0x4A,0x86,0x4A,0x85,0x4B,0xA9,0x00,0x91,0x4A,0x88,0x91,0x4A, +0x20,0x00,0xE9,0x90,0x0C,0xAD,0xED,0x02,0xAC,0xEC,0x02,0x20,0x15,0xE9,0x28,0x38, +0x60,0x28,0xB0,0x09,0xA9,0x00,0xA0,0x10,0x91,0x4A,0xC8,0x91,0x4A,0x18,0xA0,0x10, +0xAD,0xE7,0x02,0x71,0x4A,0x8D,0xE7,0x02,0xC8,0xAD,0xE8,0x02,0x71,0x4A,0x8D,0xE8, +0x02,0xA0,0x0F,0xA9,0x00,0x91,0x4A,0x20,0x56,0xCB,0xA0,0x0F,0x91,0x4A,0x18,0x60, +0x18,0xA5,0x4A,0x69,0x0C,0x8D,0x12,0x03,0xA5,0x4B,0x69,0x00,0x8D,0x13,0x03,0x6C, +0x12,0x03,0x4C,0x72,0xC2,0x20,0x5D,0xE8,0xB0,0x3B,0xA8,0xA5,0x4A,0x48,0xA5,0x4B, +0x48,0x86,0x4A,0x84,0x4B,0xAD,0x44,0x02,0xD0,0x0F,0xA0,0x10,0x18,0xB1,0x4A,0xC8, +0x71,0x4A,0xD0,0x1F,0x20,0x56,0xCB,0xD0,0x1A,0xA0,0x12,0xB1,0x4A,0xAA,0xC8,0xB1, +0x4A,0xA8,0x68,0x85,0x4B,0x68,0x85,0x4A,0x98,0xA0,0x13,0x91,0x4A,0x88,0x8A,0x91, +0x4A,0x18,0x60,0x68,0x68,0x38,0x60,0x00,0x00,0x4C,0x33,0xC9,0xA9,0x3C,0x8D,0x02, +0xD3,0xA9,0x3C,0x8D,0x03,0xD3,0xA9,0x03,0x8D,0x32,0x02,0x85,0x41,0x8D,0x0F,0xD2, +0x60,0xBA,0x8E,0x18,0x03,0xA9,0x01,0x85,0x42,0xAD,0x00,0x03,0xC9,0x60,0xD0,0x03, +0x4C,0x9D,0xEB,0xA9,0x00,0x8D,0x0F,0x03,0xA9,0x01,0x8D,0xBD,0x02,0xA9,0x0D,0x8D, +0x9C,0x02,0xA9,0x28,0x8D,0x04,0xD2,0xA9,0x00,0x8D,0x06,0xD2,0x18,0xAD,0x00,0x03, +0x6D,0x01,0x03,0x69,0xFF,0x8D,0x3A,0x02,0xAD,0x02,0x03,0x8D,0x3B,0x02,0xAD,0x0A, +0x03,0x8D,0x3C,0x02,0xAD,0x0B,0x03,0x8D,0x3D,0x02,0x18,0xA9,0x3A,0x85,0x32,0x69, +0x04,0x85,0x34,0xA9,0x02,0x85,0x33,0x85,0x35,0xA9,0x34,0x8D,0x03,0xD3,0x20,0xAF, +0xEC,0xAD,0x3F,0x02,0xD0,0x03,0x98,0xD0,0x08,0xCE,0x9C,0x02,0x10,0xB4,0x4C,0x22, +0xEA,0xAD,0x03,0x03,0x10,0x0D,0xA9,0x0D,0x8D,0x9C,0x02,0x20,0x87,0xEB,0x20,0xAF, +0xEC,0xF0,0x2F,0x20,0x9A,0xEC,0xA9,0x00,0x8D,0x3F,0x02,0x20,0xC0,0xEC,0xF0,0x12, +0x2C,0x03,0x03,0x70,0x07,0xAD,0x3F,0x02,0xD0,0x18,0xF0,0x1E,0x20,0x87,0xEB,0x20, +0xFD,0xEA,0xAD,0x3F,0x02,0xF0,0x05,0xAD,0x19,0x03,0x85,0x30,0xA5,0x30,0xC9,0x01, +0xF0,0x08,0xCE,0xBD,0x02,0x30,0x03,0x4C,0x8D,0xE9,0x20,0x84,0xEC,0xA9,0x00,0x85, +0x42,0xA4,0x30,0x8C,0x03,0x03,0x60,0xA9,0x00,0x8D,0x3F,0x02,0x18,0xA9,0x3E,0x85, +0x32,0x69,0x01,0x85,0x34,0xA9,0x02,0x85,0x33,0x85,0x35,0xA9,0xFF,0x85,0x3C,0x20, +0xFD,0xEA,0xA0,0xFF,0xA5,0x30,0xC9,0x01,0xD0,0x19,0xAD,0x3E,0x02,0xC9,0x41,0xF0, +0x21,0xC9,0x43,0xF0,0x1D,0xC9,0x45,0xD0,0x06,0xA9,0x90,0x85,0x30,0xD0,0x04,0xA9, +0x8B,0x85,0x30,0xA5,0x30,0xC9,0x8A,0xF0,0x07,0xA9,0xFF,0x8D,0x3F,0x02,0xD0,0x02, +0xA0,0x00,0xA5,0x30,0x8D,0x19,0x03,0x60,0xA9,0x01,0x85,0x30,0x20,0x17,0xEC,0xA0, +0x00,0x84,0x31,0x84,0x3B,0x84,0x3A,0xB1,0x32,0x8D,0x0D,0xD2,0x85,0x31,0xA5,0x11, +0xD0,0x03,0x4C,0xC7,0xED,0xA5,0x3A,0xF0,0xF5,0x20,0x84,0xEC,0x60,0x98,0x48,0xE6, +0x32,0xD0,0x02,0xE6,0x33,0xA5,0x32,0xC5,0x34,0xA5,0x33,0xE5,0x35,0x90,0x1C,0xA5, +0x3B,0xD0,0x0B,0xA5,0x31,0x8D,0x0D,0xD2,0xA9,0xFF,0x85,0x3B,0xD0,0x09,0xA5,0x10, +0x09,0x08,0x85,0x10,0x8D,0x0E,0xD2,0x68,0xA8,0x68,0x40,0xA0,0x00,0xB1,0x32,0x8D, +0x0D,0xD2,0x18,0x65,0x31,0x69,0x00,0x85,0x31,0x4C,0xD7,0xEA,0xA5,0x3B,0xF0,0x0B, +0x85,0x3A,0xA5,0x10,0x29,0xF7,0x85,0x10,0x8D,0x0E,0xD2,0x68,0x40,0xA9,0x00,0xAC, +0x0F,0x03,0xD0,0x02,0x85,0x31,0x85,0x38,0x85,0x39,0xA9,0x01,0x85,0x30,0x20,0x40, +0xEC,0xA9,0x3C,0x8D,0x03,0xD3,0xA5,0x11,0xD0,0x03,0x4C,0xC7,0xED,0xAD,0x17,0x03, +0xF0,0x05,0xA5,0x39,0xF0,0xF0,0x60,0xA9,0x8A,0x85,0x30,0x60,0x98,0x48,0xAD,0x0F, +0xD2,0x8D,0x0A,0xD2,0x30,0x04,0xA0,0x8C,0x84,0x30,0x29,0x20,0xD0,0x04,0xA0,0x8E, +0x84,0x30,0xA5,0x38,0xF0,0x13,0xAD,0x0D,0xD2,0xC5,0x31,0xF0,0x04,0xA0,0x8F,0x84, +0x30,0xA9,0xFF,0x85,0x39,0x68,0xA8,0x68,0x40,0xAD,0x0D,0xD2,0xA0,0x00,0x91,0x32, +0x18,0x65,0x31,0x69,0x00,0x85,0x31,0xE6,0x32,0xD0,0x02,0xE6,0x33,0xA5,0x32,0xC5, +0x34,0xA5,0x33,0xE5,0x35,0x90,0xDE,0xA5,0x3C,0xF0,0x06,0xA9,0x00,0x85,0x3C,0xF0, +0xD0,0xA9,0xFF,0x85,0x38,0xD0,0xCE,0x18,0xAD,0x04,0x03,0x85,0x32,0x6D,0x08,0x03, +0x85,0x34,0xAD,0x05,0x03,0x85,0x33,0x6D,0x09,0x03,0x85,0x35,0x60,0xAD,0x03,0x03, +0x10,0x32,0xA9,0xCC,0x8D,0x04,0xD2,0xA9,0x05,0x8D,0x06,0xD2,0x20,0x17,0xEC,0xA6, +0x62,0xBC,0x15,0xEE,0xAD,0x0B,0x03,0x30,0x03,0xBC,0x11,0xEE,0xA2,0x00,0x20,0xE2, +0xED,0xA9,0x34,0x8D,0x02,0xD3,0xAD,0x17,0x03,0xD0,0xFB,0x20,0x87,0xEB,0x20,0x88, +0xEA,0x4C,0x04,0xEC,0xA9,0xFF,0x8D,0x0F,0x03,0xA6,0x62,0xBC,0x17,0xEE,0xAD,0x0B, +0x03,0x30,0x03,0xBC,0x13,0xEE,0xA2,0x00,0x20,0xE2,0xED,0xA9,0x34,0x8D,0x02,0xD3, +0xAD,0x17,0x03,0xD0,0xFB,0x20,0x87,0xEB,0x20,0x9A,0xEC,0x20,0xE2,0xED,0x20,0x3D, +0xED,0x20,0xFD,0xEA,0xAD,0x0B,0x03,0x30,0x05,0xA9,0x3C,0x8D,0x02,0xD3,0x4C,0x2A, +0xEA,0xA9,0x00,0x8D,0x17,0x03,0x60,0xA9,0x07,0x2D,0x32,0x02,0x09,0x20,0xAC,0x00, +0x03,0xC0,0x60,0xD0,0x0C,0x09,0x08,0xA0,0x07,0x8C,0x02,0xD2,0xA0,0x05,0x8C,0x00, +0xD2,0x8D,0x32,0x02,0x8D,0x0F,0xD2,0xA9,0xC7,0x25,0x10,0x09,0x10,0x4C,0x56,0xEC, +0xA9,0x07,0x2D,0x32,0x02,0x09,0x10,0x8D,0x32,0x02,0x8D,0x0F,0xD2,0x8D,0x0A,0xD2, +0xA9,0xC7,0x25,0x10,0x09,0x20,0x85,0x10,0x8D,0x0E,0xD2,0xA9,0x28,0x8D,0x08,0xD2, +0xA2,0x06,0xA9,0xA8,0xA4,0x41,0xD0,0x02,0xA9,0xA0,0x9D,0x01,0xD2,0xCA,0xCA,0x10, +0xF9,0xA9,0xA0,0x8D,0x05,0xD2,0xAC,0x00,0x03,0xC0,0x60,0xF0,0x06,0x8D,0x01,0xD2, +0x8D,0x03,0xD2,0x60,0xEA,0xA9,0xC7,0x25,0x10,0x85,0x10,0x8D,0x0E,0xD2,0xA2,0x06, +0xA9,0x00,0x9D,0x01,0xD2,0xCA,0xCA,0x10,0xF9,0x60,0xAD,0x06,0x03,0x6A,0x6A,0xA8, +0x29,0x3F,0xAA,0x98,0x6A,0x29,0xC0,0xA8,0x60,0x2C,0xEB,0xAD,0xEA,0xEC,0xEA,0xA2, +0x01,0xA0,0xFF,0x88,0xD0,0xFD,0xCA,0xD0,0xF8,0x20,0x88,0xEA,0xA0,0x02,0xA2,0x00, +0x20,0xE2,0xED,0x20,0x37,0xEA,0x98,0x60,0x8D,0x10,0x03,0x8C,0x11,0x03,0x20,0x2E, +0xED,0x8D,0x10,0x03,0xAD,0x0C,0x03,0x20,0x2E,0xED,0x8D,0x0C,0x03,0xAD,0x10,0x03, +0x38,0xED,0x0C,0x03,0x8D,0x12,0x03,0xAD,0x11,0x03,0x38,0xED,0x0D,0x03,0xA8,0xA6, +0x62,0xA9,0x00,0x38,0xFD,0x19,0xEE,0x18,0x7D,0x19,0xEE,0x88,0x10,0xF9,0x18,0x6D, +0x12,0x03,0xA8,0x4A,0x4A,0x4A,0x0A,0x38,0xE9,0x16,0xAA,0x98,0x29,0x07,0xA8,0xA9, +0xF5,0x18,0x69,0x0B,0x88,0x10,0xFA,0xA0,0x00,0x38,0xE9,0x07,0x10,0x01,0x88,0x18, +0x7D,0xF9,0xED,0x8D,0xEE,0x02,0x98,0x7D,0xFA,0xED,0x8D,0xEF,0x02,0x60,0xC9,0x7C, +0x30,0x04,0x38,0xE9,0x7C,0x60,0x18,0xA6,0x62,0x7D,0x1B,0xEE,0x60,0xA5,0x11,0xD0, +0x03,0x4C,0xC7,0xED,0x78,0xAD,0x17,0x03,0xD0,0x02,0xF0,0x25,0xAD,0x0F,0xD2,0x29, +0x10,0xD0,0xEA,0x8D,0x16,0x03,0xAE,0x0B,0xD4,0xA4,0x14,0x8E,0x0C,0x03,0x8C,0x0D, +0x03,0xA2,0x01,0x8E,0x15,0x03,0xA0,0x0A,0xA5,0x11,0xF0,0x5B,0xAD,0x17,0x03,0xD0, +0x04,0x58,0x4C,0x27,0xEB,0xAD,0x0F,0xD2,0x29,0x10,0xCD,0x16,0x03,0xF0,0xE9,0x8D, +0x16,0x03,0x88,0xD0,0xE3,0xCE,0x15,0x03,0x30,0x0C,0xAD,0x0B,0xD4,0xA4,0x14,0x20, +0xC8,0xEC,0xA0,0x09,0xD0,0xD2,0xAD,0xEE,0x02,0x8D,0x04,0xD2,0xAD,0xEF,0x02,0x8D, +0x06,0xD2,0xA9,0x00,0x8D,0x0F,0xD2,0xAD,0x32,0x02,0x8D,0x0F,0xD2,0xA9,0x55,0x91, +0x32,0xC8,0x91,0x32,0xA9,0xAA,0x85,0x31,0x18,0xA5,0x32,0x69,0x02,0x85,0x32,0xA5, +0x33,0x69,0x00,0x85,0x33,0x58,0x60,0x20,0x84,0xEC,0xA9,0x3C,0x8D,0x02,0xD3,0xA9, +0x3C,0x8D,0x03,0xD3,0xA9,0x80,0x85,0x30,0xAE,0x18,0x03,0x9A,0xC6,0x11,0x58,0x4C, +0x2A,0xEA,0xA9,0x11,0x8D,0x26,0x02,0xA9,0xEC,0x8D,0x27,0x02,0xA9,0x01,0x78,0x20, +0x5C,0xE4,0xA9,0x01,0x8D,0x17,0x03,0x58,0x60,0xE8,0x03,0x43,0x04,0x9E,0x04,0xF9, +0x04,0x54,0x05,0xAF,0x05,0x0A,0x06,0x65,0x06,0xC0,0x06,0x1A,0x07,0x75,0x07,0xD0, +0x07,0xB4,0x96,0x78,0x64,0x0F,0x0D,0x0A,0x08,0x83,0x9C,0x07,0x20,0x18,0x10,0x0A, +0x0A,0x10,0x1C,0x34,0x64,0xC4,0xC4,0xC4,0xC4,0x1C,0x10,0x64,0xC4,0x17,0x17,0x0B, +0x17,0x2F,0x2F,0x5F,0x5F,0x61,0x61,0x61,0x61,0x17,0x0B,0xBF,0x61,0x13,0x13,0x09, +0x13,0x27,0x27,0x4F,0x4F,0x41,0x41,0x41,0x41,0x13,0x09,0x9F,0x41,0x02,0x06,0x07, +0x08,0x09,0x0A,0x0B,0x0D,0x0F,0x0F,0x0F,0x0F,0x04,0x05,0x0C,0x0E,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x01,0x01,0x03,0x02,0x02, +0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x03,0x28,0x14,0x14, +0x28,0x50,0x50,0xA0,0xA0,0x40,0x50,0x50,0x50,0x28,0x28,0xA0,0xA0,0x18,0x18,0x0C, +0x18,0x30,0x30,0x60,0x60,0xC0,0xC0,0xC0,0xC0,0x18,0x0C,0xC0,0xC0,0x00,0x00,0x00, +0x02,0x03,0x02,0x03,0x02,0x03,0x01,0x01,0x01,0x00,0x00,0x03,0x02,0xFF,0xF0,0x0F, +0xC0,0x30,0x0C,0x03,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x48,0x98,0x48,0x8A, +0xA2,0x00,0xDD,0x1A,0x03,0xF0,0x1E,0xE8,0xE8,0xE8,0xE0,0x22,0x30,0xF4,0xA2,0x00, +0xA8,0xA9,0x00,0xDD,0x1A,0x03,0xF0,0x13,0xE8,0xE8,0xE8,0xE0,0x22,0x30,0xF4,0x68, +0x68,0xA0,0xFF,0x38,0x60,0x68,0xA8,0x68,0xE8,0x38,0x60,0x98,0x9D,0x1A,0x03,0x68, +0x9D,0x1B,0x03,0x68,0x9D,0x1C,0x03,0x18,0x60,0xA0,0x00,0xB1,0x24,0xA4,0x21,0x20, +0xBE,0xE7,0x10,0x03,0xA0,0x82,0x60,0xA9,0x7F,0x85,0x20,0xA9,0x25,0x85,0x26,0xA9, +0xEF,0x85,0x27,0xAD,0xEC,0x02,0xAE,0x2E,0x00,0x9D,0x4D,0x03,0xA0,0x00,0xB1,0x24, +0x9D,0x4C,0x03,0xA0,0x01,0x60,0x48,0x8A,0x48,0x29,0x0F,0xD0,0x10,0xE0,0x80,0x10, +0x0C,0xAD,0xE9,0x02,0xD0,0x0B,0xA0,0x82,0x68,0x68,0xC0,0x00,0x60,0xA0,0x86,0x30, +0xF7,0x8E,0x2E,0x00,0xA0,0x00,0xBD,0x40,0x03,0x99,0x20,0x00,0xE8,0xC8,0xC0,0x0C, +0x30,0xF4,0x20,0x29,0xCA,0x30,0xE1,0x68,0xAA,0x68,0xA8,0xA5,0x27,0x48,0xA5,0x26, +0x48,0x98,0xA0,0x92,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x4C,0x05,0xFD,0xA9,0xFF, +0x8D,0xFC,0x02,0xAD,0xE4,0x02,0x85,0x6A,0xA9,0x40,0x8D,0xBE,0x02,0xA9,0x51,0x85, +0x79,0xA9,0xFB,0x85,0x7A,0xA9,0x11,0x85,0x60,0xA9,0xFC,0x85,0x61,0x60,0xA5,0x2B, +0x29,0x0F,0xD0,0x08,0xA5,0x2A,0x29,0x0F,0x85,0x2A,0xA9,0x00,0x85,0x57,0xC9,0x10, +0x90,0x05,0xA9,0x91,0x4C,0x54,0xF1,0xA9,0xE0,0x8D,0xF4,0x02,0xA9,0xCC,0x8D,0x6B, +0x02,0xA9,0x02,0x8D,0xF3,0x02,0x8D,0x2F,0x02,0xA9,0x01,0x85,0x4C,0xA9,0xC0,0x05, +0x10,0x85,0x10,0x8D,0x0E,0xD2,0xA9,0x40,0x8D,0x0E,0xD4,0x2C,0x6E,0x02,0x10,0x0C, +0xA9,0xC4,0x8D,0x00,0x02,0xA9,0xFC,0x8D,0x01,0x02,0xA9,0xC0,0x8D,0x0E,0xD4,0xA9, +0x00,0x8D,0x93,0x02,0x85,0x64,0x85,0x7B,0x8D,0xF0,0x02,0xA0,0x0E,0xA9,0x01,0x99, +0xA3,0x02,0x88,0x10,0xFA,0xA2,0x04,0xBD,0x08,0xFB,0x9D,0xC4,0x02,0xCA,0x10,0xF7, +0xA4,0x6A,0x88,0x8C,0x95,0x02,0xA9,0x60,0x8D,0x94,0x02,0xA6,0x57,0xBD,0x4D,0xEE, +0x85,0x51,0xA5,0x6A,0x85,0x65,0xBC,0x1D,0xEE,0xA9,0x28,0x20,0x7A,0xF5,0x88,0xD0, +0xF8,0xAD,0x6F,0x02,0x29,0x3F,0x85,0x67,0xA8,0xE0,0x08,0x90,0x1F,0xE0,0x0F,0xF0, +0x0D,0xE0,0x0C,0xB0,0x17,0x8A,0x6A,0x6A,0x6A,0x29,0xC0,0x05,0x67,0xA8,0xA9,0x10, +0x20,0x7A,0xF5,0xE0,0x0B,0xD0,0x05,0xA9,0x06,0x8D,0xC8,0x02,0x8C,0x6F,0x02,0xA5, +0x64,0x85,0x58,0xA5,0x65,0x85,0x59,0xAD,0x0B,0xD4,0xC9,0x7A,0xD0,0xF9,0x20,0x78, +0xF5,0xBD,0x5D,0xEE,0xF0,0x06,0xA9,0xFF,0x85,0x64,0xC6,0x65,0x20,0x65,0xF5,0xA5, +0x64,0x85,0x68,0xA5,0x65,0x85,0x69,0xA9,0x41,0x20,0x70,0xF5,0x86,0x66,0xA9,0x18, +0x8D,0xBF,0x02,0xA5,0x57,0xC9,0x0C,0xB0,0x04,0xC9,0x09,0xB0,0x39,0xA5,0x2A,0x29, +0x10,0xF0,0x33,0xA9,0x04,0x8D,0xBF,0x02,0xA2,0x02,0xAD,0x6E,0x02,0xF0,0x03,0x20, +0xA0,0xF5,0xA9,0x02,0x20,0x69,0xF5,0xCA,0x10,0xF8,0xA4,0x6A,0x88,0x98,0x20,0x70, +0xF5,0xA9,0x60,0x20,0x70,0xF5,0xA9,0x42,0x20,0x69,0xF5,0x18,0xA9,0x10,0x65,0x66, +0xA8,0xBE,0x2D,0xEE,0xD0,0x15,0xA4,0x66,0xBE,0x2D,0xEE,0xA5,0x57,0xD0,0x0C,0xAD, +0x6E,0x02,0xF0,0x07,0x20,0xA0,0xF5,0xA9,0x22,0x85,0x51,0xA5,0x51,0x20,0x70,0xF5, +0xCA,0xD0,0xF8,0xA5,0x57,0xC9,0x08,0x90,0x26,0xC9,0x0F,0xF0,0x04,0xC9,0x0C,0xB0, +0x1E,0xA2,0x5D,0xA5,0x6A,0x38,0xE9,0x10,0x20,0x70,0xF5,0xA9,0x00,0x20,0x70,0xF5, +0xA5,0x51,0x09,0x40,0x20,0x70,0xF5,0xA5,0x51,0x20,0x70,0xF5,0xCA,0xD0,0xF8,0xA5, +0x59,0x20,0x70,0xF5,0xA5,0x58,0x20,0x70,0xF5,0xA5,0x51,0x09,0x40,0x20,0x70,0xF5, +0xA9,0x70,0x20,0x70,0xF5,0xA9,0x70,0x20,0x70,0xF5,0xA5,0x64,0x8D,0x30,0x02,0xA5, +0x65,0x8D,0x31,0x02,0xA9,0x70,0x20,0x70,0xF5,0xA5,0x64,0x8D,0xE5,0x02,0xA5,0x65, +0x8D,0xE6,0x02,0xA0,0x01,0xAD,0x30,0x02,0x91,0x68,0xC8,0xAD,0x31,0x02,0x91,0x68, +0xA5,0x4C,0x10,0x10,0x8D,0xEC,0x03,0x20,0x94,0xEF,0xAD,0xEC,0x03,0xA0,0x00,0x8C, +0xEC,0x03,0xA8,0x60,0xA5,0x2A,0x29,0x20,0xD0,0x0B,0x20,0x20,0xF4,0x8D,0x90,0x02, +0xA5,0x52,0x8D,0x91,0x02,0xA9,0x22,0x0D,0x2F,0x02,0x8D,0x2F,0x02,0x4C,0x0B,0xF2, +0x20,0xCA,0xF6,0x20,0x8F,0xF1,0x20,0x6A,0xF7,0x20,0x0A,0xF6,0x4C,0x1E,0xF2,0x20, +0xAC,0xF5,0xB1,0x64,0x2D,0xA0,0x02,0x46,0x6F,0xB0,0x03,0x4A,0x10,0xF9,0x8D,0xFA, +0x02,0xC9,0x00,0x60,0x8D,0xFB,0x02,0xC9,0x7D,0xD0,0x06,0x20,0x20,0xF4,0x4C,0x0B, +0xF2,0x20,0xCA,0xF6,0xAD,0xFB,0x02,0xC9,0x9B,0xD0,0x06,0x20,0x61,0xF6,0x4C,0x0B, +0xF2,0x20,0xCA,0xF1,0x20,0x0E,0xF6,0x4C,0x0B,0xF2,0xAD,0xFF,0x02,0xD0,0xFB,0xA2, +0x02,0xB5,0x54,0x95,0x5A,0xCA,0x10,0xF9,0xAD,0xFB,0x02,0xA8,0x2A,0x2A,0x2A,0x2A, +0x29,0x03,0xAA,0x98,0x29,0x9F,0x1D,0x49,0xFB,0x8D,0xFA,0x02,0x20,0xAC,0xF5,0xAD, +0xFA,0x02,0x46,0x6F,0xB0,0x04,0x0A,0x4C,0xF2,0xF1,0x2D,0xA0,0x02,0x85,0x50,0xAD, +0xA0,0x02,0x49,0xFF,0x31,0x64,0x05,0x50,0x91,0x64,0x60,0x20,0x8F,0xF1,0x85,0x5D, +0xA6,0x57,0xD0,0x0A,0xAE,0xF0,0x02,0xD0,0x05,0x49,0x80,0x20,0xE9,0xF1,0xA4,0x4C, +0x4C,0x26,0xF2,0x4C,0xFC,0xC8,0xA9,0x01,0x85,0x4C,0xAD,0xFB,0x02,0x60,0x2C,0x6E, +0x02,0x10,0xEB,0xA9,0x40,0x8D,0x0E,0xD4,0xA9,0x00,0x8D,0x6E,0x02,0xA9,0xCE,0x8D, +0x00,0x02,0xA9,0xC0,0x8D,0x01,0x02,0x4C,0x94,0xEF,0x20,0x62,0xF9,0x20,0xBC,0xF6, +0xA5,0x6B,0xD0,0x34,0xA5,0x54,0x85,0x6C,0xA5,0x55,0x85,0x6D,0x20,0xFD,0xF2,0x84, +0x4C,0xAD,0xFB,0x02,0xC9,0x9B,0xF0,0x12,0x20,0xBE,0xF2,0x20,0x62,0xF9,0xA5,0x63, +0xC9,0x71,0xD0,0x03,0x20,0x56,0xF5,0x4C,0x5C,0xF2,0x20,0x18,0xF7,0x20,0xB1,0xF8, +0xA5,0x6C,0x85,0x54,0xA5,0x6D,0x85,0x55,0xA5,0x6B,0xF0,0x11,0xC6,0x6B,0xF0,0x0D, +0xA5,0x4C,0x30,0xF8,0x20,0x80,0xF1,0x8D,0xFB,0x02,0x4C,0x62,0xF9,0x20,0x61,0xF6, +0xA9,0x9B,0x8D,0xFB,0x02,0x20,0x0B,0xF2,0x84,0x4C,0x4C,0x62,0xF9,0x6C,0x64,0x00, +0x8D,0xFB,0x02,0x20,0x62,0xF9,0x20,0xBC,0xF6,0xA9,0x00,0x8D,0xE8,0x03,0x20,0x18, +0xF7,0x20,0x3C,0xF9,0xF0,0x09,0x0E,0xA2,0x02,0x20,0xB4,0xF1,0x4C,0x62,0xF9,0xAD, +0xFE,0x02,0x0D,0xA2,0x02,0xD0,0xEF,0x0E,0xA2,0x02,0xE8,0xAD,0xE8,0x03,0xF0,0x05, +0x8A,0x18,0x69,0x2D,0xAA,0xBD,0x0D,0xFB,0x85,0x64,0xBD,0x0E,0xFB,0x85,0x65,0x20, +0xAD,0xF2,0x20,0x0B,0xF2,0x4C,0x62,0xF9,0xA9,0xFF,0x8D,0xFC,0x02,0xA9,0x00,0x8D, +0xE8,0x03,0xA5,0x2A,0x4A,0xB0,0x6F,0xA9,0x80,0xA6,0x11,0xF0,0x65,0xAD,0xFC,0x02, +0xC9,0xFF,0xF0,0xE9,0x85,0x7C,0xA2,0xFF,0x8E,0xFC,0x02,0xAE,0xDB,0x02,0xD0,0x03, +0x20,0x83,0xF9,0xA8,0xC0,0xC0,0xB0,0xD0,0xB1,0x79,0x8D,0xFB,0x02,0xAA,0x30,0x03, +0x4C,0xB4,0xF3,0xC9,0x80,0xF0,0xC1,0xC9,0x81,0xD0,0x0A,0xAD,0xB6,0x02,0x49,0x80, +0x8D,0xB6,0x02,0xB0,0xB3,0xC9,0x82,0xD0,0x0C,0xAD,0xBE,0x02,0xF0,0x0B,0xA9,0x00, +0x8D,0xBE,0x02,0xF0,0xA3,0xC9,0x83,0xD0,0x07,0xA9,0x40,0x8D,0xBE,0x02,0xD0,0x98, +0xC9,0x84,0xD0,0x08,0xA9,0x80,0x8D,0xBE,0x02,0x4C,0xF8,0xF2,0xC9,0x85,0xD0,0x0B, +0xA9,0x88,0x85,0x4C,0x85,0x11,0xA9,0x9B,0x4C,0xDA,0xF3,0xC9,0x89,0xD0,0x10,0xAD, +0xDB,0x02,0x49,0xFF,0x8D,0xDB,0x02,0xD0,0x03,0x20,0x83,0xF9,0x4C,0xF8,0xF2,0xC9, +0x8E,0xB0,0x12,0xC9,0x8A,0x90,0xF5,0xE9,0x8A,0x06,0x7C,0x10,0x02,0x09,0x04,0xA8, +0xB1,0x60,0x4C,0x2A,0xF3,0xC9,0x92,0xB0,0x0B,0xC9,0x8E,0x90,0xDF,0xE9,0x72,0xEE, +0xE8,0x03,0xD0,0x26,0xA5,0x7C,0xC9,0x40,0xB0,0x15,0xAD,0xFB,0x02,0xC9,0x61,0x90, +0x0E,0xC9,0x7B,0xB0,0x0A,0xAD,0xBE,0x02,0xF0,0x05,0x05,0x7C,0x4C,0x23,0xF3,0x20, +0x3C,0xF9,0xF0,0x09,0xAD,0xFB,0x02,0x4D,0xB6,0x02,0x8D,0xFB,0x02,0x4C,0x1E,0xF2, +0xA9,0x80,0x8D,0xA2,0x02,0x60,0xC6,0x54,0x10,0x06,0xAE,0xBF,0x02,0xCA,0x86,0x54, +0x4C,0x0C,0xF9,0xE6,0x54,0xA5,0x54,0xCD,0xBF,0x02,0x90,0xF4,0xA2,0x00,0xF0,0xEE, +0xC6,0x55,0xA5,0x55,0x30,0x04,0xC5,0x52,0xB0,0x04,0xA5,0x53,0x85,0x55,0x4C,0x8E, +0xF8,0xE6,0x55,0xA5,0x55,0xC5,0x53,0x90,0xF5,0xF0,0xF3,0xA5,0x52,0x4C,0x0C,0xF4, +0x20,0xA6,0xF9,0xA4,0x64,0xA9,0x00,0x85,0x64,0x91,0x64,0xC8,0xD0,0xFB,0xE6,0x65, +0xA6,0x65,0xE4,0x6A,0x90,0xF3,0xA9,0xFF,0x99,0xB2,0x02,0xC8,0xC0,0x04,0x90,0xF8, +0x20,0x97,0xF9,0x85,0x63,0x85,0x6D,0xA9,0x00,0x85,0x54,0x85,0x56,0x85,0x6C,0x60, +0xA5,0x63,0xC5,0x52,0xF0,0x21,0xA5,0x55,0xC5,0x52,0xD0,0x03,0x20,0x23,0xF9,0x20, +0x00,0xF4,0xA5,0x55,0xC5,0x53,0xD0,0x07,0xA5,0x54,0xF0,0x03,0x20,0xE6,0xF3,0xA9, +0x20,0x8D,0xFB,0x02,0x20,0xCA,0xF1,0x4C,0x8E,0xF8,0x20,0x11,0xF4,0xA5,0x55,0xC5, +0x52,0xD0,0x08,0x20,0x65,0xF6,0x20,0x58,0xF7,0xB0,0x07,0xA5,0x63,0x20,0x5D,0xF7, +0x90,0xE8,0x4C,0x8E,0xF8,0xA5,0x63,0x4C,0x3E,0xF7,0xA5,0x63,0x4C,0x4A,0xF7,0x20, +0x4C,0xF9,0x20,0x8F,0xF1,0x85,0x7D,0xA9,0x00,0x8D,0xBB,0x02,0x20,0xE9,0xF1,0xA5, +0x63,0x48,0x20,0x12,0xF6,0x68,0xC5,0x63,0xB0,0x0C,0xA5,0x7D,0x48,0x20,0x8F,0xF1, +0x85,0x7D,0x68,0x4C,0xAC,0xF4,0x20,0x57,0xF9,0xCE,0xBB,0x02,0x30,0x04,0xC6,0x54, +0xD0,0xF7,0x4C,0x8E,0xF8,0x20,0x4C,0xF9,0x20,0xAC,0xF5,0xA5,0x64,0x85,0x68,0xA5, +0x65,0x85,0x69,0xA5,0x63,0x48,0x20,0x0A,0xF6,0x68,0xC5,0x63,0xB0,0x10,0xA5,0x54, +0xCD,0xBF,0x02,0xB0,0x09,0x20,0x8F,0xF1,0xA0,0x00,0x91,0x68,0xF0,0xDA,0xA0,0x00, +0x98,0x91,0x68,0x20,0x18,0xF9,0x20,0x57,0xF9,0x4C,0x8E,0xF8,0x38,0x20,0xC2,0xF7, +0xA5,0x52,0x85,0x55,0x20,0xAC,0xF5,0x20,0x8E,0xF7,0x20,0xE2,0xF7,0x4C,0x8E,0xF8, +0x20,0x8E,0xF8,0xA4,0x51,0x84,0x54,0xA4,0x54,0x98,0x38,0x20,0x5B,0xF7,0x08,0x98, +0x18,0x69,0x78,0x28,0x20,0x3C,0xF7,0xC8,0xC0,0x18,0xD0,0xED,0xAD,0xB4,0x02,0x09, +0x01,0x8D,0xB4,0x02,0xA9,0x00,0x85,0x55,0x20,0xAC,0xF5,0x20,0x2A,0xF8,0x20,0x58, +0xF7,0x90,0xD4,0x4C,0x1B,0xF4,0xA0,0x20,0x20,0x83,0xF9,0x88,0x10,0xFA,0x60,0x20, +0x40,0xF4,0x4C,0xE6,0xF3,0xA9,0x02,0xD0,0x11,0xAC,0x6E,0x02,0xF0,0x02,0x09,0x20, +0xA4,0x4C,0x30,0x2B,0xA0,0x00,0x91,0x64,0xA9,0x01,0x8D,0x9E,0x02,0xA5,0x4C,0x30, +0x1E,0xA5,0x64,0x38,0xED,0x9E,0x02,0x85,0x64,0xB0,0x02,0xC6,0x65,0xA5,0x0F,0xC5, +0x65,0x90,0x0C,0xD0,0x06,0xA5,0x0E,0xC5,0x64,0x90,0x04,0xA9,0x93,0x85,0x4C,0x60, +0xA9,0x02,0x20,0x70,0xF5,0xA9,0xA2,0x20,0x70,0xF5,0xCA,0x60,0xA2,0x01,0x86,0x66, +0xCA,0x86,0x65,0xA5,0x54,0x0A,0x26,0x65,0x0A,0x26,0x65,0x65,0x54,0x85,0x64,0x90, +0x02,0xE6,0x65,0xA4,0x57,0xBE,0x6D,0xEE,0x06,0x64,0x26,0x65,0xCA,0xD0,0xF9,0xA5, +0x56,0x4A,0xA5,0x55,0xBE,0x9D,0xEE,0xF0,0x06,0x6A,0x06,0x66,0xCA,0xD0,0xFA,0x65, +0x64,0x90,0x02,0xE6,0x65,0x18,0x65,0x58,0x85,0x64,0x85,0x5E,0xA5,0x65,0x65,0x59, +0x85,0x65,0x85,0x5F,0xBE,0x9D,0xEE,0xBD,0x04,0xFB,0x25,0x55,0x65,0x66,0xA8,0xB9, +0xAC,0xEE,0x8D,0xA0,0x02,0x85,0x6F,0xA0,0x00,0x60,0xA9,0x00,0xF0,0x02,0xA9,0x9B, +0x85,0x7D,0xE6,0x63,0xE6,0x55,0xD0,0x02,0xE6,0x56,0xA5,0x55,0xA6,0x57,0xDD,0x7D, +0xEE,0xF0,0x0A,0xE0,0x00,0xD0,0xE2,0xC5,0x53,0xF0,0xDE,0x90,0xDC,0xE0,0x08,0xD0, +0x04,0xA5,0x56,0xF0,0xD4,0xA5,0x57,0xD0,0x2C,0xA5,0x63,0xC9,0x51,0x90,0x0A,0xA5, +0x7D,0xF0,0x22,0x20,0x61,0xF6,0x4C,0xAB,0xF6,0x20,0x65,0xF6,0xA5,0x54,0x18,0x69, +0x78,0x20,0x5D,0xF7,0x90,0x08,0xA5,0x7D,0xF0,0x04,0x18,0x20,0x0D,0xF5,0x4C,0x8E, +0xF8,0xA9,0x9B,0x85,0x7D,0x20,0x97,0xF9,0xA9,0x00,0x85,0x56,0xE6,0x54,0xA6,0x57, +0xA0,0x18,0x24,0x7B,0x10,0x05,0xA0,0x04,0x98,0xD0,0x03,0xBD,0x8D,0xEE,0xC5,0x54, +0xD0,0x29,0x8C,0x9D,0x02,0x8A,0xD0,0x23,0xA5,0x7D,0xF0,0x1F,0xC9,0x9B,0xF0,0x01, +0x18,0x20,0xF7,0xF7,0xEE,0xBB,0x02,0xC6,0x6C,0x10,0x02,0xE6,0x6C,0xCE,0x9D,0x02, +0xAD,0xB2,0x02,0x38,0x10,0xEB,0xAD,0x9D,0x02,0x85,0x54,0x4C,0x8E,0xF8,0x38,0xB5, +0x70,0xE5,0x74,0x95,0x70,0xB5,0x71,0xE5,0x75,0x95,0x71,0x60,0xAD,0xBF,0x02,0xC9, +0x04,0xF0,0x07,0xA5,0x57,0xF0,0x03,0x20,0x94,0xEF,0xA9,0x27,0xC5,0x53,0xB0,0x02, +0x85,0x53,0xA6,0x57,0xBD,0x8D,0xEE,0xC5,0x54,0x90,0x2A,0xF0,0x28,0xE0,0x08,0xD0, +0x0A,0xA5,0x56,0xF0,0x13,0xC9,0x01,0xD0,0x1C,0xF0,0x04,0xA5,0x56,0xD0,0x16,0xBD, +0x7D,0xEE,0xC5,0x55,0x90,0x0F,0xF0,0x0D,0xA9,0x01,0x85,0x4C,0xA9,0x80,0xA6,0x11, +0x85,0x11,0xF0,0x06,0x60,0x20,0x40,0xF4,0xA9,0x8D,0x85,0x4C,0x68,0x68,0xA5,0x7B, +0x10,0x03,0x4C,0x62,0xF9,0x4C,0x1E,0xF2,0xA0,0x00,0xA5,0x5F,0xF0,0x04,0xA5,0x5D, +0x91,0x5E,0x60,0x48,0x29,0x07,0xAA,0xBD,0xB4,0xEE,0x85,0x6E,0x68,0x4A,0x4A,0x4A, +0xAA,0x60,0x2E,0xB4,0x02,0x2E,0xB3,0x02,0x2E,0xB2,0x02,0x60,0x90,0x0C,0x20,0x23, +0xF7,0xBD,0xA3,0x02,0x05,0x6E,0x9D,0xA3,0x02,0x60,0x20,0x23,0xF7,0xA5,0x6E,0x49, +0xFF,0x3D,0xA3,0x02,0x9D,0xA3,0x02,0x60,0xA5,0x54,0x18,0x69,0x78,0x20,0x23,0xF7, +0x18,0xBD,0xA3,0x02,0x25,0x6E,0xF0,0x01,0x38,0x60,0xAD,0xFA,0x02,0xA4,0x57,0xC0, +0x0E,0xB0,0x17,0xC0,0x0C,0xB0,0x04,0xC0,0x03,0xB0,0x0F,0x2A,0x2A,0x2A,0x2A,0x29, +0x03,0xAA,0xAD,0xFA,0x02,0x29,0x9F,0x1D,0x4D,0xFB,0x8D,0xFB,0x02,0x60,0xA6,0x6A, +0xCA,0x86,0x69,0x86,0x67,0xA9,0xB0,0x85,0x68,0xA9,0xD8,0x85,0x66,0xA6,0x54,0xE8, +0xEC,0xBF,0x02,0xF0,0xE8,0xA0,0x27,0xB1,0x68,0x91,0x66,0x88,0x10,0xF9,0x38,0xA5, +0x68,0x85,0x66,0xE9,0x28,0x85,0x68,0xA5,0x69,0x85,0x67,0xE9,0x00,0x85,0x69,0x4C, +0x9F,0xF7,0x08,0xA0,0x16,0x98,0x20,0x5A,0xF7,0x08,0x98,0x18,0x69,0x79,0x28,0x20, +0x3C,0xF7,0x88,0x30,0x04,0xC4,0x54,0xB0,0xEC,0xA5,0x54,0x18,0x69,0x78,0x28,0x4C, +0x3C,0xF7,0xA5,0x52,0x85,0x55,0x20,0xAC,0xF5,0x38,0xA5,0x53,0xE5,0x52,0xA8,0xA9, +0x00,0x91,0x64,0x88,0x10,0xFB,0x60,0x20,0x32,0xF7,0xAD,0x6E,0x02,0xF0,0x28,0xAD, +0x6C,0x02,0xD0,0xFB,0xA9,0x08,0x8D,0x6C,0x02,0xAD,0x6C,0x02,0xC9,0x01,0xD0,0xF9, +0xAD,0x0B,0xD4,0xC9,0x40,0xB0,0xF9,0xA2,0x0D,0xAD,0xBF,0x02,0xC9,0x04,0xD0,0x02, +0xA2,0x70,0xEC,0x0B,0xD4,0xB0,0xFB,0x20,0xA6,0xF9,0xA5,0x64,0xA6,0x65,0xE8,0xE4, +0x6A,0xF0,0x06,0x38,0xE9,0x10,0x4C,0x2E,0xF8,0x69,0x27,0xD0,0x0A,0xA6,0x65,0xE8, +0xE4,0x6A,0xF0,0x38,0x18,0x69,0x10,0xA8,0x85,0x7E,0x38,0xA5,0x64,0xE5,0x7E,0x85, +0x64,0xB0,0x02,0xC6,0x65,0xA5,0x64,0x18,0x69,0x28,0x85,0x7E,0xA5,0x65,0x69,0x00, +0x85,0x7F,0xB1,0x7E,0x91,0x64,0xC8,0xD0,0xF9,0xA0,0x10,0xA5,0x64,0xC9,0xD8,0xF0, +0x0B,0x18,0x69,0xF0,0x85,0x64,0x90,0xDD,0xE6,0x65,0xD0,0xD9,0xA6,0x6A,0xCA,0x86, +0x7F,0xA2,0xD8,0x86,0x7E,0xA9,0x00,0xA0,0x27,0x91,0x7E,0x88,0x10,0xFB,0xA9,0x00, +0x85,0x63,0xA5,0x54,0x85,0x51,0xA5,0x51,0x20,0x5A,0xF7,0xB0,0x0C,0xA5,0x63,0x18, +0x69,0x28,0x85,0x63,0xC6,0x51,0x4C,0x96,0xF8,0x18,0xA5,0x63,0x65,0x55,0x85,0x63, +0x60,0x20,0x4C,0xF9,0xA5,0x63,0x48,0xA5,0x6C,0x85,0x54,0xA5,0x6D,0x85,0x55,0xA9, +0x01,0x85,0x6B,0xA2,0x17,0xA5,0x7B,0x10,0x02,0xA2,0x03,0xE4,0x54,0xD0,0x0B,0xA5, +0x55,0xC5,0x53,0xD0,0x05,0xE6,0x6B,0x4C,0xEA,0xF8,0x20,0x0A,0xF6,0xE6,0x6B,0xA5, +0x63,0xC5,0x52,0xD0,0xDE,0xC6,0x54,0x20,0x00,0xF4,0x20,0x8F,0xF1,0xD0,0x17,0xC6, +0x6B,0xA5,0x63,0xC5,0x52,0xF0,0x0F,0x20,0x00,0xF4,0xA5,0x55,0xC5,0x53,0xD0,0x02, +0xC6,0x54,0xA5,0x6B,0xD0,0xE4,0x68,0x85,0x63,0x4C,0x57,0xF9,0x20,0x8E,0xF8,0xA5, +0x51,0x85,0x6C,0xA5,0x52,0x85,0x6D,0x60,0xA5,0x63,0xC5,0x52,0xD0,0x02,0xC6,0x54, +0x20,0x8E,0xF8,0xA5,0x63,0xC5,0x52,0xF0,0xEE,0x20,0xAC,0xF5,0xA5,0x53,0x38,0xE5, +0x52,0xA8,0xB1,0x64,0xD0,0xE1,0x88,0x10,0xF9,0x4C,0x27,0xF5,0xA2,0x2D,0xBD,0x0D, +0xFB,0xCD,0xFB,0x02,0xF0,0x05,0xCA,0xCA,0xCA,0x10,0xF3,0x60,0xA2,0x02,0xB5,0x54, +0x9D,0xB8,0x02,0xCA,0x10,0xF8,0x60,0xA2,0x02,0xBD,0xB8,0x02,0x95,0x54,0xCA,0x10, +0xF8,0x60,0xAD,0xBF,0x02,0xC9,0x18,0xF0,0x17,0xA2,0x0B,0xB5,0x54,0x48,0xBD,0x90, +0x02,0x95,0x54,0x68,0x9D,0x90,0x02,0xCA,0x10,0xF1,0xA5,0x7B,0x49,0xFF,0x85,0x7B, +0x4C,0x1E,0xF2,0xA2,0x7E,0x48,0x8E,0x1F,0xD0,0xAD,0x0B,0xD4,0xCD,0x0B,0xD4,0xF0, +0xFB,0xCA,0xCA,0x10,0xF1,0x68,0x60,0xA9,0x00,0xA6,0x7B,0xD0,0x04,0xA6,0x57,0xD0, +0x02,0xA5,0x52,0x85,0x55,0x60,0xA5,0x58,0x85,0x64,0xA5,0x59,0x85,0x65,0x60,0xA2, +0x00,0xA5,0x22,0xC9,0x11,0xF0,0x08,0xC9,0x12,0xF0,0x03,0xA0,0x84,0x60,0xE8,0x8E, +0xB7,0x02,0xA5,0x54,0x8D,0xF5,0x02,0xA5,0x55,0x8D,0xF6,0x02,0xA5,0x56,0x8D,0xF7, +0x02,0xA9,0x01,0x8D,0xF8,0x02,0x8D,0xF9,0x02,0x38,0xAD,0xF5,0x02,0xE5,0x5A,0x85, +0x76,0xB0,0x0E,0xA9,0xFF,0x8D,0xF8,0x02,0xA5,0x76,0x49,0xFF,0x18,0x69,0x01,0x85, +0x76,0x38,0xAD,0xF6,0x02,0xE5,0x5B,0x85,0x77,0xAD,0xF7,0x02,0xE5,0x5C,0x85,0x78, +0xB0,0x17,0xA9,0xFF,0x8D,0xF9,0x02,0xA5,0x77,0x49,0xFF,0x85,0x77,0xA5,0x78,0x49, +0xFF,0x85,0x78,0xE6,0x77,0xD0,0x02,0xE6,0x78,0xA2,0x02,0xA0,0x00,0x84,0x73,0x98, +0x95,0x70,0xB5,0x5A,0x95,0x54,0xCA,0x10,0xF6,0xA5,0x77,0xE8,0xA8,0xA5,0x78,0x85, +0x7F,0x85,0x75,0xD0,0x0B,0xA5,0x77,0xC5,0x76,0xB0,0x05,0xA5,0x76,0xA2,0x02,0xA8, +0x98,0x85,0x7E,0x85,0x74,0x48,0xA5,0x75,0x4A,0x68,0x6A,0x95,0x70,0xA5,0x7E,0x05, +0x7F,0xD0,0x03,0x4C,0x01,0xFB,0x18,0xA5,0x70,0x65,0x76,0x85,0x70,0x90,0x02,0xE6, +0x71,0xA5,0x71,0xC5,0x75,0x90,0x15,0xD0,0x06,0xA5,0x70,0xC5,0x74,0x90,0x0D,0x18, +0xA5,0x54,0x6D,0xF8,0x02,0x85,0x54,0xA2,0x00,0x20,0xAE,0xF6,0x18,0xA5,0x72,0x65, +0x77,0x85,0x72,0xA5,0x73,0x65,0x78,0x85,0x73,0xC5,0x75,0x90,0x28,0xD0,0x06,0xA5, +0x72,0xC5,0x74,0x90,0x20,0x2C,0xF9,0x02,0x10,0x10,0xC6,0x55,0xA5,0x55,0xC9,0xFF, +0xD0,0x0E,0xA5,0x56,0xF0,0x0A,0xC6,0x56,0x10,0x06,0xE6,0x55,0xD0,0x02,0xE6,0x56, +0xA2,0x02,0x20,0xAE,0xF6,0x20,0xCA,0xF6,0x20,0xCA,0xF1,0xAD,0xB7,0x02,0xF0,0x2F, +0x20,0x4C,0xF9,0xAD,0xFB,0x02,0x8D,0xBC,0x02,0xA5,0x54,0x48,0x20,0x12,0xF6,0x68, +0x85,0x54,0x20,0xCA,0xF6,0x20,0x8F,0xF1,0xD0,0x0C,0xAD,0xFD,0x02,0x8D,0xFB,0x02, +0x20,0xCA,0xF1,0x4C,0xC9,0xFA,0xAD,0xBC,0x02,0x8D,0xFB,0x02,0x20,0x57,0xF9,0x38, +0xA5,0x7E,0xE9,0x01,0x85,0x7E,0xA5,0x7F,0xE9,0x00,0x85,0x7F,0x30,0x03,0x4C,0x4D, +0xFA,0x4C,0x1E,0xF2,0x00,0x01,0x03,0x07,0x28,0xCA,0x94,0x46,0x00,0x1B,0xE0,0xF3, +0x1C,0xE6,0xF3,0x1D,0xF3,0xF3,0x1E,0x00,0xF4,0x1F,0x11,0xF4,0x7D,0x20,0xF4,0x7E, +0x50,0xF4,0x7F,0x7A,0xF4,0x9B,0x61,0xF6,0x9C,0x20,0xF5,0x9D,0x0C,0xF5,0x9E,0x9A, +0xF4,0x9F,0x95,0xF4,0xFD,0x56,0xF5,0xFE,0xD5,0xF4,0xFF,0x9F,0xF4,0x1C,0x40,0xF4, +0x1D,0x5F,0xF5,0x1E,0x1B,0xF4,0x1F,0x0A,0xF4,0x40,0x00,0x20,0x60,0x20,0x40,0x00, +0x60,0x6C,0x6A,0x3B,0x8A,0x8B,0x6B,0x2B,0x2A,0x6F,0x80,0x70,0x75,0x9B,0x69,0x2D, +0x3D,0x76,0x80,0x63,0x8C,0x8D,0x62,0x78,0x7A,0x34,0x80,0x33,0x36,0x1B,0x35,0x32, +0x31,0x2C,0x20,0x2E,0x6E,0x80,0x6D,0x2F,0x81,0x72,0x80,0x65,0x79,0x7F,0x74,0x77, +0x71,0x39,0x80,0x30,0x37,0x7E,0x38,0x3C,0x3E,0x66,0x68,0x64,0x80,0x82,0x67,0x73, +0x61,0x4C,0x4A,0x3A,0x8A,0x8B,0x4B,0x5C,0x5E,0x4F,0x80,0x50,0x55,0x9B,0x49,0x5F, +0x7C,0x56,0x80,0x43,0x8C,0x8D,0x42,0x58,0x5A,0x24,0x80,0x23,0x26,0x1B,0x25,0x22, +0x21,0x5B,0x20,0x5D,0x4E,0x80,0x4D,0x3F,0x81,0x52,0x80,0x45,0x59,0x9F,0x54,0x57, +0x51,0x28,0x80,0x29,0x27,0x9C,0x40,0x7D,0x9D,0x46,0x48,0x44,0x80,0x83,0x47,0x53, +0x41,0x0C,0x0A,0x7B,0x80,0x80,0x0B,0x1E,0x1F,0x0F,0x80,0x10,0x15,0x9B,0x09,0x1C, +0x1D,0x16,0x80,0x03,0x89,0x80,0x02,0x18,0x1A,0x80,0x80,0x85,0x80,0x1B,0x80,0xFD, +0x80,0x00,0x20,0x60,0x0E,0x80,0x0D,0x80,0x81,0x12,0x80,0x05,0x19,0x9E,0x14,0x17, +0x11,0x80,0x80,0x80,0x80,0xFE,0x80,0x7D,0xFF,0x06,0x08,0x04,0x80,0x84,0x07,0x13, +0x01,0x1C,0x1D,0x1E,0x1F,0x8E,0x8F,0x90,0x91,0x8A,0x48,0x98,0x48,0xAC,0x01,0xD3, +0xAD,0x09,0xD2,0xCD,0xF2,0x02,0xD0,0x05,0xAE,0xF1,0x02,0xD0,0x49,0xAE,0x6D,0x02, +0xC9,0x83,0xD0,0x13,0x8A,0x49,0xFF,0x8D,0x6D,0x02,0xD0,0x05,0x98,0x09,0x04,0xD0, +0x03,0x98,0x29,0xFB,0xA8,0xB0,0x26,0x8A,0xD0,0x3D,0xAD,0x09,0xD2,0xAA,0xC9,0x9F, +0xD0,0x0A,0xAD,0xFF,0x02,0x49,0xFF,0x8D,0xFF,0x02,0xB0,0x11,0x29,0x3F,0xC9,0x11, +0xD0,0x2E,0x8E,0xDC,0x02,0xF0,0x06,0x8E,0xFC,0x02,0x8E,0xF2,0x02,0xA9,0x03,0x8D, +0xF1,0x02,0xA9,0x00,0x85,0x4D,0xAD,0xD9,0x02,0x8D,0x2B,0x02,0xAD,0x2F,0x02,0xD0, +0x06,0xAD,0xDD,0x02,0x8D,0x2F,0x02,0x8C,0x01,0xD3,0x68,0xA8,0x68,0xAA,0x68,0x40, +0xE0,0x84,0xF0,0x21,0xE0,0x94,0xD0,0xCF,0xAD,0xF4,0x02,0xAE,0x6B,0x02,0x8D,0x6B, +0x02,0x8E,0xF4,0x02,0xE0,0xCC,0xF0,0x06,0x98,0x09,0x08,0xA8,0xD0,0xBF,0x98,0x29, +0xF7,0xA8,0x4C,0x6D,0xFC,0xAD,0x2F,0x02,0xF0,0xCD,0x8D,0xDD,0x02,0xA9,0x00,0x8D, +0x2F,0x02,0xF0,0xC3,0x48,0xAD,0xC6,0x02,0x4D,0x4F,0x00,0x2D,0x4E,0x00,0x8D,0x0A, +0xD4,0x8D,0x17,0xD0,0x68,0x40,0x00,0x00,0x4C,0x83,0xF9,0xA9,0xCC,0x8D,0xEE,0x02, +0xA9,0x05,0x8D,0xEF,0x02,0x60,0xA5,0x2B,0x85,0x3E,0xA5,0x2A,0x29,0x0C,0xC9,0x04, +0xF0,0x05,0xC9,0x08,0xF0,0x3E,0x60,0xA9,0x00,0x8D,0x89,0x02,0x85,0x3F,0xA9,0x01, +0x20,0xFC,0xFD,0x30,0x29,0xA9,0x34,0x8D,0x02,0xD3,0xA6,0x62,0xBC,0x93,0xFE,0xBD, +0x91,0xFE,0xAA,0xA9,0x03,0x8D,0x2A,0x02,0x20,0x5C,0xE4,0xAD,0x2A,0x02,0xD0,0xFB, +0xA9,0x80,0x85,0x3D,0x8D,0x8A,0x02,0x4C,0x77,0xFD,0xA0,0x80,0xC6,0x11,0xA9,0x00, +0x8D,0x89,0x02,0x60,0xA9,0x80,0x8D,0x89,0x02,0xA9,0x02,0x20,0xFC,0xFD,0x30,0xEE, +0xA9,0xCC,0x8D,0x04,0xD2,0xA9,0x05,0x8D,0x06,0xD2,0xA9,0x60,0x8D,0x00,0x03,0x20, +0x68,0xE4,0xA9,0x34,0x8D,0x02,0xD3,0xA6,0x62,0xBC,0x8F,0xFE,0xBD,0x8D,0xFE,0xAA, +0xA9,0x03,0x20,0x5C,0xE4,0xA9,0xFF,0x8D,0x2A,0x02,0xA5,0x11,0xF0,0xBC,0xAD,0x2A, +0x02,0xD0,0xF7,0xA9,0x00,0x85,0x3D,0xA0,0x01,0x60,0xA5,0x3F,0x30,0x33,0xA6,0x3D, +0xEC,0x8A,0x02,0xF0,0x08,0xBD,0x00,0x04,0xE6,0x3D,0xA0,0x01,0x60,0xA9,0x52,0x20, +0x3F,0xFE,0x98,0x30,0xF7,0xA9,0x00,0x85,0x3D,0xA2,0x80,0xAD,0xFF,0x03,0xC9,0xFE, +0xF0,0x0D,0xC9,0xFA,0xD0,0x03,0xAE,0x7F,0x04,0x8E,0x8A,0x02,0x4C,0x7A,0xFD,0xC6, +0x3F,0xA0,0x88,0x60,0xA6,0x3D,0x9D,0x00,0x04,0xE6,0x3D,0xA0,0x01,0xE0,0x7F,0xF0, +0x01,0x60,0xA9,0xFC,0x20,0x7C,0xFE,0xA9,0x00,0x85,0x3D,0x60,0xA0,0x01,0x60,0xAD, +0x89,0x02,0x30,0x08,0xA0,0x01,0xA9,0x3C,0x8D,0x02,0xD3,0x60,0xA6,0x3D,0xF0,0x0A, +0x8E,0x7F,0x04,0xA9,0xFA,0x20,0x7C,0xFE,0x30,0xEC,0xA2,0x7F,0xA9,0x00,0x9D,0x00, +0x04,0xCA,0x10,0xFA,0xA9,0xFE,0x20,0x7C,0xFE,0x4C,0xD6,0xFD,0x85,0x40,0xA5,0x14, +0x18,0xA6,0x62,0x7D,0x95,0xFE,0xAA,0xA9,0xFF,0x8D,0x1F,0xD0,0xA9,0x00,0xA0,0xF0, +0x88,0xD0,0xFD,0x8D,0x1F,0xD0,0xA0,0xF0,0x88,0xD0,0xFD,0xE4,0x14,0xD0,0xE8,0xC6, +0x40,0xF0,0x0E,0x8A,0x18,0xA6,0x62,0x7D,0x97,0xFE,0xAA,0xE4,0x14,0xD0,0xFC,0xF0, +0xCD,0x20,0x36,0xFE,0x98,0x60,0xAD,0x25,0xE4,0x48,0xAD,0x24,0xE4,0x48,0x60,0x8D, +0x02,0x03,0xA9,0x00,0x8D,0x09,0x03,0xA9,0x83,0x8D,0x08,0x03,0xA9,0x03,0x8D,0x05, +0x03,0xA9,0xFD,0x8D,0x04,0x03,0xA9,0x60,0x8D,0x00,0x03,0xA9,0x00,0x8D,0x01,0x03, +0xA9,0x23,0x8D,0x06,0x03,0xAD,0x02,0x03,0xA0,0x40,0xC9,0x52,0xF0,0x02,0xA0,0x80, +0x8C,0x03,0x03,0xA5,0x3E,0x8D,0x0B,0x03,0x20,0x59,0xE4,0x60,0x8D,0xFF,0x03,0xA9, +0x55,0x8D,0xFD,0x03,0x8D,0xFE,0x03,0xA9,0x57,0x20,0x3F,0xFE,0x60,0x04,0x03,0x80, +0xC0,0x02,0x01,0x40,0xE0,0x1E,0x19,0x0A,0x08,0xA9,0x1E,0x8D,0x14,0x03,0x60,0xEA, +0x02,0xC0,0x03,0xA9,0x04,0x8D,0xDF,0x02,0xAE,0x9F,0xFE,0xAC,0xA0,0xFE,0xA9,0x53, +0x8D,0x02,0x03,0x8D,0x0A,0x03,0x20,0x14,0xFF,0x20,0x59,0xE4,0x30,0x03,0x20,0x44, +0xFF,0x60,0x20,0xA3,0xFE,0xA9,0x00,0x8D,0xDE,0x02,0x60,0x48,0xBD,0x41,0x03,0x85, +0x21,0x20,0x4B,0xFF,0xAE,0xDE,0x02,0x68,0x9D,0xC0,0x03,0xE8,0xEC,0xDF,0x02,0xF0, +0x15,0x8E,0xDE,0x02,0xC9,0x9B,0xF0,0x03,0xA0,0x01,0x60,0xA9,0x20,0x9D,0xC0,0x03, +0xE8,0xEC,0xDF,0x02,0xD0,0xF7,0xA9,0x00,0x8D,0xDE,0x02,0xAE,0xA1,0xFE,0xAC,0xA2, +0xFE,0x20,0x14,0xFF,0x4C,0x59,0xE4,0x20,0x4B,0xFF,0xA9,0x9B,0xAE,0xDE,0x02,0xD0, +0xDC,0xA0,0x01,0x60,0x8E,0x04,0x03,0x8C,0x05,0x03,0xA9,0x40,0x8D,0x00,0x03,0xA5, +0x21,0x8D,0x01,0x03,0xA9,0x80,0xAE,0x02,0x03,0xE0,0x53,0xD0,0x02,0xA9,0x40,0x8D, +0x03,0x03,0xAD,0xDF,0x02,0x8D,0x08,0x03,0xA9,0x00,0x8D,0x09,0x03,0xAD,0x14,0x03, +0x8D,0x06,0x03,0x60,0xAD,0xEC,0x02,0x8D,0x14,0x03,0x60,0xA0,0x57,0xA5,0x2B,0xC9, +0x4E,0xD0,0x04,0xA2,0x28,0xD0,0x0E,0xC9,0x44,0xD0,0x04,0xA2,0x14,0xD0,0x06,0xC9, +0x53,0xD0,0x0C,0xA2,0x1D,0x8E,0xDF,0x02,0x8C,0x02,0x03,0x8D,0x0A,0x03,0x60,0xA9, +0x4E,0xD0,0xDC,0xA2,0x00,0x86,0x8B,0x86,0x8C,0x20,0xA9,0xFF,0xE0,0x0C,0xD0,0xF9, +0xAD,0x00,0xC0,0xAE,0x01,0xC0,0xC5,0x8B,0xD0,0x06,0xE4,0x8C,0xD0,0x02,0x18,0x60, +0x38,0x60,0xA2,0x00,0x86,0x8B,0x86,0x8C,0xA2,0x0C,0x20,0xA9,0xFF,0x20,0xA9,0xFF, +0xAD,0xF8,0xFF,0xAE,0xF9,0xFF,0x4C,0x86,0xFF,0xA0,0x00,0xBD,0xD7,0xFF,0x99,0x9E, +0x00,0xE8,0xC8,0xC0,0x04,0xD0,0xF4,0xA0,0x00,0x18,0xB1,0x9E,0x65,0x8B,0x85,0x8B, +0x90,0x02,0xE6,0x8C,0xE6,0x9E,0xD0,0x02,0xE6,0x9F,0xA5,0x9E,0xC5,0xA0,0xD0,0xE9, +0xA5,0x9F,0xC5,0xA1,0xD0,0xE3,0x60,0x02,0xC0,0x00,0xD0,0x00,0x50,0x00,0x58,0x00, +0xD8,0x00,0xE0,0x00,0xE0,0xF8,0xFF,0xFA,0xFF,0x00,0x00,0x00,0x00,0x00,0x10,0x05, +0x83,0x02,0x42,0x42,0x00,0x00,0x01,0x02,0x8C,0x6C,0x18,0xC0,0xAA,0xC2,0x2C,0xC0, +}; diff --git a/MCUME_teensy41/teensy800/sio.c b/MCUME_teensy41/teensy800/sio.c new file mode 100644 index 0000000..575c914 --- /dev/null +++ b/MCUME_teensy41/teensy800/sio.c @@ -0,0 +1,55 @@ +/* + * sio.c - Serial I/O emulation + * + * Copyright (C) 1995-1998 David Firth + * Copyright (C) 1998-2010 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Atari800 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define _POSIX_C_SOURCE 200112L /* for snprintf */ + +#include +#include +#include +#include + +#include "antic.h" /* ANTIC_ypos */ +#include "atari.h" +#include "cpu.h" +#include "memory.h" +#include "pokey.h" +#include "pokeysnd.h" +#include "sio.h" + + + + +/* Put a byte that comes out of POKEY. So get it here... */ +void SIO_PutByte(int byte) +{ +} + +/* Get a byte from the floppy to the pokey. */ +int SIO_GetByte(void) +{ + int byte = 0; + + return byte; +} + diff --git a/MCUME_teensy41/teensy800/sio.h b/MCUME_teensy41/teensy800/sio.h new file mode 100644 index 0000000..8a182f9 --- /dev/null +++ b/MCUME_teensy41/teensy800/sio.h @@ -0,0 +1,61 @@ +#ifndef SIO_H_ +#define SIO_H_ + + +#include /* FILENAME_MAX */ + +#include "atari.h" + +#define SIO_MAX_DRIVES 8 + +typedef enum SIO_tagUnitStatus { + SIO_OFF, + SIO_NO_DISK, + SIO_READ_ONLY, + SIO_READ_WRITE +} SIO_UnitStatus; + +extern char SIO_status[256]; +extern SIO_UnitStatus SIO_drive_status[SIO_MAX_DRIVES]; +extern char SIO_filename[SIO_MAX_DRIVES][FILENAME_MAX]; + +#define SIO_LAST_READ 0 +#define SIO_LAST_WRITE 1 +extern int SIO_last_op; +extern int SIO_last_op_time; +extern int SIO_last_drive; /* 1 .. 8 */ +extern int SIO_last_sector; + +int SIO_Mount(int diskno, const char *filename, int b_open_readonly); +void SIO_Dismount(int diskno); +void SIO_DisableDrive(int diskno); +int SIO_RotateDisks(void); +void SIO_Handler(void); + +UBYTE SIO_ChkSum(const UBYTE *buffer, int length); +void SIO_SwitchCommandFrame(int onoff); +void SIO_PutByte(int byte); +int SIO_GetByte(void); +int SIO_Initialise(int *argc, char *argv[]); +void SIO_Exit(void); + +/* Some defines about the serial I/O timing. Currently fixed! */ +#define SIO_XMTDONE_INTERVAL 15 +#define SIO_SERIN_INTERVAL 8 +#define SIO_SEROUT_INTERVAL 8 +#define SIO_ACK_INTERVAL 36 + +/* These functions are also used by the 1450XLD Parallel disk device */ +extern int SIO_format_sectorcount[SIO_MAX_DRIVES]; +extern int SIO_format_sectorsize[SIO_MAX_DRIVES]; +int SIO_ReadStatusBlock(int unit, UBYTE *buffer); +int SIO_FormatDisk(int unit, UBYTE *buffer, int sectsize, int sectcount); +void SIO_SizeOfSector(UBYTE unit, int sector, int *sz, ULONG *ofs); +int SIO_ReadSector(int unit, int sector, UBYTE *buffer); +int SIO_DriveStatus(int unit, UBYTE *buffer); +int SIO_WriteStatusBlock(int unit, const UBYTE *buffer); +int SIO_WriteSector(int unit, int sector, const UBYTE *buffer); +void SIO_StateSave(void); +void SIO_StateRead(void); + +#endif /* SIO_H_ */ diff --git a/MCUME_teensy41/teensy800/teensy800.ino b/MCUME_teensy41/teensy800/teensy800.ino new file mode 100644 index 0000000..687492b --- /dev/null +++ b/MCUME_teensy41/teensy800/teensy800.ino @@ -0,0 +1,202 @@ +extern "C" { + #include "iopins.h" + #include "emuapi.h" +} + +extern "C" { +#include "atari800.h" +} + +#ifdef HAS_T4_VGA +#include "vga_t_dma.h" +TFT_T_DMA tft; +#else +#include "tft_t_dma.h" +TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT); +#endif + +bool vgaMode = false; + +static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; +static IntervalTimer myTimer; +volatile boolean vbl=true; +static int skip=0; +static elapsedMicros tius; + +static void vblCount() { + if (vbl) { + vbl = false; + } else { + vbl = true; + } +} + +void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) +{ + if (index>8, + 320 & 0xFF, // YEND = 320 + ST7735_INVON , DELAY, // 7: hack + 10, + ST7735_NORON , DELAY, // 8: Normal display on, no args, w/delay + 10, // 10 ms delay + ST7735_DISPON , DELAY, // 9: Main screen turn on, no args, w/delay + 255 +#endif +}; + +static void dmaInterrupt() { + dmatx.clearInterrupt(); + curTransfer++; + if (curTransfer >= nbTransfer) { + curTransfer = 0; + if (cancelled) { + dmatx.disable(); + rstop = 1; + } + } + arm_dcache_flush(blocks[curTransfer], LINES_PER_BLOCK*TFT_WIDTH*2); +} + +static void setDmaStruct() { + uint32_t remaining = TFT_HEIGHT*TFT_WIDTH*2; + int i=0; + uint16_t col=RGBVAL16(0x00,0x00,0x00);; + while (remaining > 0) { + uint16_t * fb = blocks[i]; + int32_t len = (remaining >= (LINES_PER_BLOCK*TFT_WIDTH*2)?LINES_PER_BLOCK*TFT_WIDTH*2:remaining); +#ifdef TFT_DEBUG + Serial.println((unsigned long)blocks[i]); + Serial.println(remaining); +#endif + switch (i) { + case 0: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb0[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0x00,0xff,0x00); +#endif + break; + case 1: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb1[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0x00,0xff,0xff); +#endif + break; + case 2: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb2[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0x00,0x00,0xff); +#endif + break; + case 3: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb3[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0xff,0x00,0xff); +#endif + break; + } + blocks[i] = fb; + if (blocks[i] == 0) { + Serial.print("ILI9341 allocaltion failed for block "); + Serial.println(i); + delay(10000); + } + + for (int j=0;jATTR_DST = 1; + dmasettings[i].replaceSettingsOnCompletion(dmasettings[i+1]); + dmasettings[i].interruptAtCompletion(); + remaining -= len; + i++; + } + dmasettings[i-1].replaceSettingsOnCompletion(dmasettings[0]); + nbTransfer = i; +#ifdef TFT_DEBUG + Serial.println(nbTransfer); +#endif +} + + +TFT_T_DMA::TFT_T_DMA(uint8_t cs, uint8_t dc, uint8_t rst, uint8_t mosi, uint8_t sclk, uint8_t miso, uint8_t touch_cs, uint8_t touch_irq) +{ + _cs = cs; + _dc = dc; + _rst = rst; + _mosi = mosi; + _sclk = sclk; + _miso = miso; + pinMode(_dc, OUTPUT); + pinMode(_cs, OUTPUT); + digitalWrite(_cs, 1); + digitalWrite(_dc, 1); + if ( (touch_cs != 255) && (touch_irq != 255) ) { + _touch_irq = touch_irq; + _touch_cs = touch_cs; + pinMode(_touch_cs, OUTPUT); + pinMode(touch_irq, INPUT_PULLUP); + digitalWrite(_touch_cs, 1); + } +} + + +void TFT_T_DMA::setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2) { + int dx=0; + int dy=0; +#ifdef ST7789 + if (TFT_REALWIDTH == TFT_REALHEIGHT) + { +#ifdef ROTATE_SCREEN + if (!flipped) { + dy += 80; + } +#else + if (flipped) { + dx += 80; + } +#endif + } +#endif + + digitalWrite(_dc, 0); + SPI.transfer(TFT_CASET); + digitalWrite(_dc, 1); + SPI.transfer16(x1+dx); + digitalWrite(_dc, 1); + SPI.transfer16(x2+dx); + digitalWrite(_dc, 0); + SPI.transfer(TFT_PASET); + digitalWrite(_dc, 1); + SPI.transfer16(y1+dy); + digitalWrite(_dc, 1); + SPI.transfer16(y2+dy); + + digitalWrite(_dc, 0); + SPI.transfer(TFT_RAMWR); + digitalWrite(_dc, 1); + + return; + + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + + digitalWrite(_dc, 0); + SPI.transfer(TFT_CASET); + digitalWrite(_dc, 1); + + SPI.transfer16(x1+dx); + SPI.transfer16(x2+dx); + + digitalWrite(_dc, 0); + SPI.transfer(TFT_PASET); + digitalWrite(_dc, 1); + SPI.transfer16(y1+dy); + SPI.transfer16(y2+dy); + + digitalWrite(_dc, 0); + SPI.transfer(TFT_RAMWR); + digitalWrite(_dc, 1); + + digitalWrite(_cs, 1); + SPI.endTransaction(); +} + + + + +void TFT_T_DMA::begin(void) { + SPI.setMOSI(_mosi); + SPI.setMISO(_miso); + SPI.setSCK(_sclk); + SPI.begin(); + + // Initialize display + if (_rst != 0xff) { + pinMode(_rst, OUTPUT); + digitalWrite(_rst, HIGH); + delay(100); + digitalWrite(_rst, LOW); + delay(100); + digitalWrite(_rst, HIGH); + delay(200); + } + + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + const uint8_t *addr = init_commands; + digitalWrite(_cs, 0); +#ifdef ILI9341 + while (1) { + uint8_t count = *addr++; + if (count-- == 0) break; + + digitalWrite(_dc, 0); + SPI.transfer(*addr++); + + while (count-- > 0) { + digitalWrite(_dc, 1); + SPI.transfer(*addr++); + } + } + + digitalWrite(_dc, 0); + SPI.transfer(ILI9341_SLPOUT); + digitalWrite(_dc, 1); + digitalWrite(_cs, 1); + SPI.endTransaction(); + + digitalWrite(_dc, 1); + digitalWrite(_cs, 1); + SPI.endTransaction(); + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_dc, 0); + digitalWrite(_cs, 0); + SPI.transfer(ILI9341_DISPON); + digitalWrite(_dc, 1); + digitalWrite(_cs, 1); +#endif +#ifdef ST7789 + uint8_t numCommands, numArgs; + uint16_t ms; + numCommands = *addr++; // Number of commands to follow + while(numCommands--) { // For each command... + digitalWrite(_dc, 0); + SPI.transfer(*addr++); + numArgs = *addr++; // Number of args to follow + ms = numArgs & DELAY; // If hibit set, delay follows args + numArgs &= ~DELAY; // Mask out delay bit + while(numArgs > 1) { // For each argument... + digitalWrite(_dc, 1); + SPI.transfer(*addr++); + numArgs--; + } + + if (numArgs) { + digitalWrite(_dc, 1); + SPI.transfer(*addr++); + } + if(ms) { + ms = *addr++; // Read post-command delay time (ms) + if(ms == 255) ms = 500; // If 255, delay for 500 ms + digitalWrite(_cs, 1); + SPI.endTransaction(); + delay(ms); + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + } + } + digitalWrite(_cs, 1); +#endif + setArea(0, 0, TFT_REALWIDTH-1, TFT_REALHEIGHT-1); + SPI.endTransaction(); + + cancelled = false; + +#ifdef FLIP_SCREEN + flipscreen(true); +#else + flipscreen(false); +#endif +#ifdef ST7789 + if (TFT_REALWIDTH != TFT_REALHEIGHT) + { + flipscreen(true); + } +#endif +}; + + + +void TFT_T_DMA::flipscreen(bool flip) +{ + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_dc, 0); + digitalWrite(_cs, 0); + SPI.transfer(TFT_MADCTL); + digitalWrite(_dc, 1); + if (flip) { + flipped=true; +#ifdef ILI9341 + SPI.transfer(ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR); +#endif +#ifdef ST7789 +#ifdef ROTATE_SCREEN + SPI.transfer(ST77XX_MADCTL_RGB); +#else + SPI.transfer(ST77XX_MADCTL_MY | ST77XX_MADCTL_MV |ST77XX_MADCTL_RGB); +#endif +#endif + } + else { + flipped=false; +#ifdef ILI9341 + SPI.transfer(ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR); +#endif +#ifdef ST7789 +#ifdef ROTATE_SCREEN + SPI.transfer(ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_RGB); +#else + SPI.transfer(ST77XX_MADCTL_MX | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB); +#endif +#endif + } + digitalWrite(_cs, 1); + SPI.endTransaction(); +} + +boolean TFT_T_DMA::isflipped(void) +{ + return(flipped); +} + + +#define PRREG(x) Serial.print(#x" 0x"); Serial.println(x,HEX) + + +void TFT_T_DMA::startDMA(void) { + curTransfer = 0; + rstop = 0; + //dmatx.begin(true); + dmatx.attachInterrupt(dmaInterrupt); + setDmaStruct(); + setArea((TFT_REALWIDTH-TFT_WIDTH)/2, (TFT_REALHEIGHT-TFT_HEIGHT)/2, (TFT_REALWIDTH-TFT_WIDTH)/2 + TFT_WIDTH-1, (TFT_REALHEIGHT-TFT_HEIGHT)/2+TFT_HEIGHT-1); + fillScreen(RGBVAL16(0x00,0x00,0x00)); + + digitalWrite(_cs, HIGH); + SPI.begin(); + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + + + LPSPIP_CR &= ~LPSPI_CR_MEN;//disable LPSPI: + LPSPIP_CFGR1 |= LPSPI_CFGR1_NOSTALL; //prevent stall from RX + LPSPIP_TCR = 15; // Framesize 16 Bits + //LPSPIP_FCR = 0; // Fifo Watermark + LPSPIP_DER = LPSPI_DER_TDDE; //TX DMA Request Enable + LPSPIP_CR |= LPSPI_CR_MEN; //enable LPSPI: + dmatx.triggerAtHardwareEvent( DMAMUX_SOURCE_LPSPIP_TX ); + + dmatx = dmasettings[0]; + digitalWrite(_cs, 0); + setArea((TFT_REALWIDTH-TFT_WIDTH)/2, (TFT_REALHEIGHT-TFT_HEIGHT)/2, (TFT_REALWIDTH-TFT_WIDTH)/2+TFT_WIDTH-1, (TFT_REALHEIGHT-TFT_HEIGHT)/2+TFT_HEIGHT-1); + digitalWrite(_dc, 0); + SPI.transfer(TFT_RAMWR); + digitalWrite(_dc, 1); + dmatx.enable(); +} + + +void TFT_T_DMA::stopDMA(void) { + rstop = 0; + wait(); + delay(50); + cancelled = false; + dmatx.detachInterrupt(); + fillScreen(RGBVAL16(0x00,0x00,0x00)); + SPI.end(); +#ifdef ST7789 + begin(); +#endif +#ifdef ILI9341 + SPI.begin(); + digitalWrite(_cs, 0); + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + SPI.endTransaction(); + digitalWrite(_cs, 1); + digitalWrite(_dc, 1); +#endif + setArea(0, 0, TFT_REALWIDTH-1, TFT_REALHEIGHT-1); +} + +void TFT_T_DMA::wait(void) { + rstop = 1; + unsigned long m = millis(); + cancelled = true; + while (!rstop) { + if ((millis() - m) > 100) break; + delay(10); + asm volatile("wfi"); + }; + rstop = 0; +} + +int TFT_T_DMA::get_frame_buffer_size(int *width, int *height){ + if (width != nullptr) *width = TFT_REALWIDTH; + if (height != nullptr) *height = TFT_REALHEIGHT; + return TFT_REALWIDTH; +} + + +/*********************************************************************************************** + Touch functions + ***********************************************************************************************/ +/* Code based on ... + * + * @file XPT2046.cpp + * @date 19.02.2016 + * @author Markus Sattler + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the XPT2046 driver for Arduino. + */ + +#define ADC_MAX 0x0fff + +void TFT_T_DMA::enableTouchIrq() +{ + SPI.beginTransaction(SPI_SETTING); + digitalWrite(_touch_cs, LOW); + const uint8_t buf[4] = { (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Y)), 0x00, 0x00, 0x00 }; + SPI.transfer((void*)&buf[0],3); + digitalWrite(_touch_cs, HIGH); + SPI.endTransaction(); +} + +//Default callibration for non flipped +#define TX_MIN 30 +#define TY_MIN 20 +#define TX_MAX 300 +#define TY_MAX 220 + +//Default callibration for flipped +#define TFX_MIN 20 +#define TFY_MIN 25 +#define TFX_MAX 288 +#define TFY_MAX 221 + +static uint16_t txMin; +static uint16_t tyMin; +static uint16_t txMax; +static uint16_t tyMax; + + +void TFT_T_DMA::callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { + if ( (xMin >= 0) && (yMin >= 0) && (xMax < 320) && (yMax < 200) ) { + txMin = xMin; + tyMin = yMin; + txMax = xMax; + tyMax = yMax; + } + else { + if (flipped) { + txMin = TFX_MIN; + tyMin = TFY_MIN; + txMax = TFX_MAX; + tyMax = TFY_MAX; + } + else { + txMin = TX_MIN; + tyMin = TY_MIN; + txMax = TX_MAX; + tyMax = TY_MAX; + } + } +} + + +void TFT_T_DMA::readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { + if ( TOUCH_ENABLED() ) { + uint16_t x = 0; + uint16_t y = 0; + uint16_t z1 = 0; + uint16_t z2 = 0; + uint8_t i = 0; + int16_t xraw=0, yraw=0; + + SPI.beginTransaction(SPI_SETTING); + digitalWrite(_touch_cs, LOW); + + for(; i < 15; i++) { + // SPI requirer 32bit aliment + uint8_t buf[12] = { + (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Y) | XPT2046_CFG_PWR(3)), 0x00, 0x00, + (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_X) | XPT2046_CFG_PWR(3)), 0x00, 0x00, + (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Z1)| XPT2046_CFG_PWR(3)), 0x00, 0x00, + (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Z2)| XPT2046_CFG_PWR(3)), 0x00, 0x00 + }; + SPI.transfer(&buf[0], &buf[0], 12); + y += (buf[1] << 8 | buf[2])>>3; + x += (buf[4] << 8 | buf[5])>>3; + z1 += (buf[7] << 8 | buf[8])>>3; + z2 += (buf[10] << 8 | buf[11])>>3; + } + enableTouchIrq(); + + if(i == 0) { + *oX = 0; + *oY = 0; + *oZ = 0; + } + else { + x /= i; + y /= i; + z1 /= i; + z2 /= i; + } + + digitalWrite(_touch_cs, HIGH); + SPI.endTransaction(); + int z = z1 + ADC_MAX - z2; + if (flipped) { + xraw = x; + yraw = y; + } else { + xraw = ADC_MAX - x; + yraw = ADC_MAX - y; + } + xraw=(xraw*TFT_REALWIDTH)/(ADC_MAX+1); + yraw=(yraw*TFT_REALHEIGHT)/(ADC_MAX+1); + + *oX = xraw; + *oY = yraw; + *oZ = z; + } + else + { + *oX = 0; + *oY = 0; + *oZ = 0; + } +} + +void TFT_T_DMA::readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { + readRaw(oX,oY,oZ); + // callibrate ... + if(*oX >= txMin) *oX = ((*oX - txMin)*TFT_REALWIDTH)/(txMax-txMin); + if(*oY >= tyMin) *oY = ((*oY - tyMin)*TFT_REALHEIGHT)/(tyMax-tyMin); + //Serial.print(*oX); + //Serial.print(" "); + //Serial.println(*oY); +} + + +/*********************************************************************************************** + No DMA functions + ***********************************************************************************************/ +void TFT_T_DMA::fillScreenNoDma(uint16_t color) { + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + setArea(0, 0, TFT_REALWIDTH-1, TFT_REALHEIGHT-1); + //digitalWrite(_dc, 0); + //SPI.transfer(TFT_RAMWR); + int i,j; + for (j=0; j(arx+arw)) || ((x+w)(ary+arh)) || ((y+h) arx) && (x<(arx+arw)) ) { + arw = arw - (x-arx); + arx = arx + (x-arx); + } else { + bmp_offx = arx; + } + if ( ((x+w) > arx) && ((x+w)<(arx+arw)) ) { + arw -= (arx+arw-x-w); + } + if ( (y > ary) && (y<(ary+arh)) ) { + arh = arh - (y-ary); + ary = ary + (y-ary); + } else { + bmp_offy = ary; + } + if ( ((y+h) > ary) && ((y+h)<(ary+arh)) ) { + arh -= (ary+arh-y-h); + } + } + + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + setArea(arx, ary, arx+arw-1, ary+arh-1); + //digitalWrite(_dc, 0); + //SPI.transfer(TFT_RAMWR); + + bitmap = bitmap + bmp_offy*w + bmp_offx; + for (int row=0;row> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + } + bits = *charpt++; + //digitalWrite(_dc, 1); + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPI.transfer16(fgcolor); + else SPI.transfer16(bgcolor); + } + x +=8; +#ifdef ILI9341 + digitalWrite(_dc, 0); + SPI.transfer(ILI9341_SLPOUT); + digitalWrite(_dc, 1); +#endif + digitalWrite(_cs, 1); + SPI.endTransaction(); + } + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + setArea(0, 0, (TFT_REALWIDTH-1), (TFT_REALHEIGHT-1)); + digitalWrite(_cs, 1); + SPI.endTransaction(); +} + + + + + + +/*********************************************************************************************** + DMA functions + ***********************************************************************************************/ +uint16_t * TFT_T_DMA::getLineBuffer(int j) +{ + uint16_t * block=blocks[j>>6]; + return(&block[(j&0x3F)*TFT_REALWIDTH]); +} + +void TFT_T_DMA::writeScreen(int width, int height, int stride, uint8_t *buf, uint16_t *palette16) { + uint8_t *buffer=buf; + uint8_t *src; + + int i,j,y=0; + if (width*2 <= TFT_REALWIDTH) { + for (j=0; j>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH]; + src=buffer; + for (i=0; i>6]; + dst=&block[(y&0x3F)*TFT_WIDTH]; + src=buffer; + for (i=0; i>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH+(TFT_WIDTH-width)/2]; + src=buffer; + for (i=0; i>6]; + dst=&block[(y&0x3F)*TFT_WIDTH+(TFT_WIDTH-width)/2]; + src=buffer; + for (i=0; i>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH]; + if (width > TFT_WIDTH) { +#ifdef TFT_LINEARINT + int delta = (width/(width-TFT_WIDTH))-1; + int pos = delta; + for (int i=0; i> 8]]; + pos +=step; + } +#endif + } + else if ((width*2) == TFT_WIDTH) { + for (int i=0; i>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH]; + if (width > TFT_WIDTH) { +#ifdef TFT_LINEARINT + int delta = (width/(width-TFT_WIDTH))-1; + int pos = delta; + for (int i=0; i> 8]; + pos +=step; + } +#endif + } + else if ((width*2) == TFT_WIDTH) { + for (int i=0; i>6]; + uint16_t * dst=&block[(j&0x3F)*TFT_WIDTH]; + for (i=0; i>6]; + uint16_t * dst=&block[(l&0x3F)*TFT_WIDTH+x]; + for (i=0; i>6]; + dst=&block[(l&0x3F)*TFT_WIDTH+x]; + bits = *charpt; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + l++; + } + block=blocks[l>>6]; + dst=&block[(l&0x3F)*TFT_WIDTH+x]; + bits = *charpt++; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + l++; + } + x +=8; + } +} + +void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap) { + drawSprite(x,y,bitmap, 0,0,0,0); +} + +void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t arx, uint16_t ary, uint16_t arw, uint16_t arh) +{ + int bmp_offx = 0; + int bmp_offy = 0; + uint16_t *bmp_ptr; + + int w =*bitmap++; + int h = *bitmap++; + + + if ( (arw == 0) || (arh == 0) ) { + // no crop window + arx = x; + ary = y; + arw = w; + arh = h; + } + else { + if ( (x>(arx+arw)) || ((x+w)(ary+arh)) || ((y+h) arx) && (x<(arx+arw)) ) { + arw = arw - (x-arx); + arx = arx + (x-arx); + } else { + bmp_offx = arx; + } + if ( ((x+w) > arx) && ((x+w)<(arx+arw)) ) { + arw -= (arx+arw-x-w); + } + if ( (y > ary) && (y<(ary+arh)) ) { + arh = arh - (y-ary); + ary = ary + (y-ary); + } else { + bmp_offy = ary; + } + if ( ((y+h) > ary) && ((y+h)<(ary+arh)) ) { + arh -= (ary+arh-y-h); + } + } + + + int l=ary; + bitmap = bitmap + bmp_offy*w + bmp_offx; + for (int row=0;row>6]; + uint16_t * dst=&block[(l&0x3F)*TFT_WIDTH+arx]; + bmp_ptr = (uint16_t*)bitmap; + for (int col=0;col +#include +#include +#endif + +#include "tft_t_dma_config.h" + +#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b ) +#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) ) +#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) ) +#define R16(rgb) ((rgb>>8)&0xf8) +#define G16(rgb) ((rgb>>3)&0xfc) +#define B16(rgb) ((rgb<<3)&0xf8) + +#define PAL_COLOR_MASK 0xff + +#ifdef LOHRES +#define TFT_WIDTH 240 +#define TFT_REALWIDTH 240 +#else +#define TFT_WIDTH 320 +#define TFT_REALWIDTH 320 +#endif +#define TFT_HEIGHT 240 +#define TFT_REALHEIGHT 240 + +//#define WIDTH 272 +//#define HEIGHT 228 + +#define LINES_PER_BLOCK 64 +#define NR_OF_BLOCK 4 +#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK + + +#ifdef ILI9341 + +#define ILI9341_NOP 0x00 +#define ILI9341_SWRESET 0x01 +#define ILI9341_RDDID 0x04 +#define ILI9341_RDDST 0x09 + +#define ILI9341_SLPIN 0x10 +#define ILI9341_SLPOUT 0x11 +#define ILI9341_PTLON 0x12 +#define ILI9341_NORON 0x13 + +#define ILI9341_RDMODE 0x0A +#define ILI9341_RDMADCTL 0x0B +#define ILI9341_RDPIXFMT 0x0C +#define ILI9341_RDIMGFMT 0x0D +#define ILI9341_RDSELFDIAG 0x0F + +#define ILI9341_INVOFF 0x20 +#define ILI9341_INVON 0x21 +#define ILI9341_GAMMASET 0x26 +#define ILI9341_DISPOFF 0x28 +#define ILI9341_DISPON 0x29 + +#define ILI9341_CASET 0x2A +#define ILI9341_PASET 0x2B +#define ILI9341_RAMWR 0x2C +#define ILI9341_RAMRD 0x2E + +#define ILI9341_PTLAR 0x30 +#define ILI9341_MADCTL 0x36 +#define ILI9341_VSCRSADD 0x37 +#define ILI9341_PIXFMT 0x3A + +#define ILI9341_FRMCTR1 0xB1 +#define ILI9341_FRMCTR2 0xB2 +#define ILI9341_FRMCTR3 0xB3 +#define ILI9341_INVCTR 0xB4 +#define ILI9341_DFUNCTR 0xB6 + +#define ILI9341_PWCTR1 0xC0 +#define ILI9341_PWCTR2 0xC1 +#define ILI9341_PWCTR3 0xC2 +#define ILI9341_PWCTR4 0xC3 +#define ILI9341_PWCTR5 0xC4 +#define ILI9341_VMCTR1 0xC5 +#define ILI9341_VMCTR2 0xC7 + +#define ILI9341_RDID1 0xDA +#define ILI9341_RDID2 0xDB +#define ILI9341_RDID3 0xDC +#define ILI9341_RDID4 0xDD + +#define ILI9341_GMCTRP1 0xE0 +#define ILI9341_GMCTRN1 0xE1 + +#define ILI9341_MADCTL_MY 0x80 +#define ILI9341_MADCTL_MX 0x40 +#define ILI9341_MADCTL_MV 0x20 +#define ILI9341_MADCTL_ML 0x10 +#define ILI9341_MADCTL_RGB 0x00 +#define ILI9341_MADCTL_BGR 0x08 +#define ILI9341_MADCTL_MH 0x04 + +#define TFT_CASET ILI9341_CASET +#define TFT_PASET ILI9341_PASET +#define TFT_RAMWR ILI9341_RAMWR +#define TFT_MADCTL ILI9341_MADCTL + +#endif + + +#ifdef ST7789 + +#define ST7735_NOP 0x00 +#define ST7735_SWRESET 0x01 +#define ST7735_RDDID 0x04 +#define ST7735_RDDST 0x09 + +#define ST7735_SLPIN 0x10 +#define ST7735_SLPOUT 0x11 +#define ST7735_PTLON 0x12 +#define ST7735_NORON 0x13 + +#define ST7735_INVOFF 0x20 +#define ST7735_INVON 0x21 +#define ST7735_DISPOFF 0x28 +#define ST7735_DISPON 0x29 +#define ST7735_CASET 0x2A +#define ST7735_RASET 0x2B +#define ST7735_RAMWR 0x2C +#define ST7735_RAMRD 0x2E + +#define ST7735_PTLAR 0x30 +#define ST7735_COLMOD 0x3A +#define ST7735_MADCTL 0x36 + +#define ST7735_FRMCTR1 0xB1 +#define ST7735_FRMCTR2 0xB2 +#define ST7735_FRMCTR3 0xB3 +#define ST7735_INVCTR 0xB4 +#define ST7735_DISSET5 0xB6 + +#define ST7735_PWCTR1 0xC0 +#define ST7735_PWCTR2 0xC1 +#define ST7735_PWCTR3 0xC2 +#define ST7735_PWCTR4 0xC3 +#define ST7735_PWCTR5 0xC4 +#define ST7735_VMCTR1 0xC5 + +#define ST7735_RDID1 0xDA +#define ST7735_RDID2 0xDB +#define ST7735_RDID3 0xDC +#define ST7735_RDID4 0xDD + +#define ST7735_PWCTR6 0xFC + +#define ST7735_GMCTRP1 0xE0 +#define ST7735_GMCTRN1 0xE1 + +#define ST77XX_MADCTL_MY 0x80 +#define ST77XX_MADCTL_MX 0x40 +#define ST77XX_MADCTL_MV 0x20 +#define ST77XX_MADCTL_ML 0x10 +#define ST77XX_MADCTL_RGB 0x00 +#define ST77XX_MADCTL_BGR 0x08 +#define ST77XX_MADCTL_MH 0x04 + +#define TFT_CASET ST7735_CASET +#define TFT_PASET ST7735_RASET +#define TFT_RAMWR ST7735_RAMWR +#define TFT_MADCTL ST7735_MADCTL + +#endif + + + +#ifdef __cplusplus + +class TFT_T_DMA +{ + public: + TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37); + + void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2); + void begin(void); + void flipscreen(bool flip); + boolean isflipped(void); + void startDMA(void); + void stopDMA(); + int get_frame_buffer_size(int *width, int *height); + + // Touch screen functions + #define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255)) + bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); } + void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ); + void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ); + void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax); + + // NoDMA functions + void writeScreenNoDma(const uint16_t *pcolors); + void fillScreenNoDma(uint16_t color); + void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize); + void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap); + void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh); + + // DMA functions + uint16_t * getLineBuffer(int j); + void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16); + void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16); + void writeLine(int width, int height, int y, uint16_t *buf); + void fillScreen(uint16_t color); + void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize); + void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap); + void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh); + + protected: + uint8_t _rst, _cs, _dc; + uint8_t _miso, _mosi, _sclk; + uint8_t _touch_irq=255, _touch_cs=255; + bool flipped=false; + + void wait(void); + void enableTouchIrq(); +}; + +#endif +#endif diff --git a/MCUME_teensy41/teensy800/tft_t_dma_config.h b/MCUME_teensy41/teensy800/tft_t_dma_config.h new file mode 100644 index 0000000..0a712da --- /dev/null +++ b/MCUME_teensy41/teensy800/tft_t_dma_config.h @@ -0,0 +1,13 @@ +#include "platform_config.h" + +//#define ST7789 1 +//#define ILI9341 1 + +#define TFT_LINEARINT 1 +#define LINEARINT_HACK 1 + +//#define FLIP_SCREEN 1 +//#define TFT_DEBUG 1 +#if defined(__IMXRT1052__) || defined(__IMXRT1062__) +//#define TFT_STATICFB 1 +#endif diff --git a/MCUME_teensy41/teensy800/vga_t_dma.h b/MCUME_teensy41/teensy800/vga_t_dma.h new file mode 100644 index 0000000..81a986b --- /dev/null +++ b/MCUME_teensy41/teensy800/vga_t_dma.h @@ -0,0 +1,53 @@ +/* + Wrapping class to extend VGA_T4 to TFT_T_DMA +*/ + +#ifndef _VGA_T_DMAH_ +#define _VGA_T_DMAH_ + +#ifdef __cplusplus +#include +#endif + + +#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) ) +#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) ) + + + + +#define TFT_WIDTH 320 +#define TFT_REALWIDTH 320 + +#define TFT_HEIGHT 240 +#define TFT_REALHEIGHT 240 + + + +#ifdef __cplusplus + +class TFT_T_DMA: public VGA_T4 +{ + public: + // Fake touch screen functions + bool isTouching(void) { return false; } + void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { } + void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }; + void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { } + + // fake DMA functions + void startDMA(void) { }; + void stopDMA(void) { }; + + // fake no DMA functions + void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); } + void fillScreenNoDma(vga_pixel color) { clear(color); } + void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); } + void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); } + void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap) { drawSprite(x, y, bitmap); } + void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); } +}; + + +#endif +#endif diff --git a/MCUME_teensy41/teensynofrendo/keyboard_osd.h b/MCUME_teensy41/teensynofrendo/keyboard_osd.h deleted file mode 100644 index 062eb4e..0000000 --- a/MCUME_teensy41/teensynofrendo/keyboard_osd.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef keyboard_osd_h_ -#define keyboard_osd_h_ - -extern bool virtualkeyboardIsActive(void); -extern void drawVirtualkeyboard(void); -extern void toggleVirtualkeyboard(bool keepOn); -extern void handleVirtualkeyboard(void); - -extern bool callibrationActive(void); -extern int handleCallibration(uint16_t bClick); - -extern bool menuActive(void); -extern char * menuSelection(void); -extern void toggleMenu(bool on); -extern int handleMenu(uint16_t bClick); - - -#endif - diff --git a/MCUME_teensy41/teensynofrendo/teensynofrendo.ino b/MCUME_teensy41/teensynofrendo/teensynofrendo.ino index 5d04a66..5d3256f 100644 --- a/MCUME_teensy41/teensynofrendo/teensynofrendo.ino +++ b/MCUME_teensy41/teensynofrendo/teensynofrendo.ino @@ -2,7 +2,6 @@ extern "C" { #include "iopins.h" #include "emuapi.h" } -#include "keyboard_osd.h" #include "nes_emu.h"