add ZX81 emulator to T-COMPUTER platform

This commit is contained in:
jean-marcharvengt 2022-02-26 23:25:55 +01:00
parent e0594ee404
commit 7fbfd0ba0c
26 changed files with 24853 additions and 0 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,316 @@
/** EMULib Emulation Library *********************************/
/** **/
/** AY8910.c **/
/** **/
/** This file contains emulation for the AY8910 sound chip **/
/** produced by General Instruments, Yamaha, etc. See **/
/** AY8910.h for declarations. **/
/** **/
/** Copyright (C) Marat Fayzullin 1996-2014 **/
/** You are not allowed to distribute this software **/
/** commercially. Please, notify me, if you make any **/
/** changes to this file. **/
/*************************************************************/
#include "AY8910.h"
#include "emuapi.h"
#include <string.h>
static const unsigned char Envelopes[16][32] =
{
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
{ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
};
static const int Volumes[16] =
{ 0,1,2,4,6,8,11,16,23,32,45,64,90,128,180,255 };
//{ 0,16,33,50,67,84,101,118,135,152,169,186,203,220,237,254 };
/** Reset8910() **********************************************/
/** Reset the sound chip and use sound channels from the **/
/** one given in First. **/
/*************************************************************/
void Reset8910(register AY8910 *D,int ClockHz,int First)
{
static byte RegInit[16] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFD,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00
};
int J;
/* Reset state */
memcpy(D->R,RegInit,sizeof(D->R));
D->EPhase = 0;
D->Clock = ClockHz>>4;
D->First = First;
D->Sync = AY8910_ASYNC;
D->Changed = 0x00;
D->EPeriod = 0;
D->ECount = 0;
D->Latch = 0x00;
/* Set sound types */
//SetSound(0+First,SND_MELODIC);
//SetSound(1+First,SND_MELODIC);
//SetSound(2+First,SND_MELODIC);
//SetSound(3+First,SND_NOISE);
//SetSound(4+First,SND_NOISE);
//SetSound(5+First,SND_NOISE);
/* Silence all channels */
for(J=0;J<AY8910_CHANNELS;J++)
{
D->Freq[J]=D->Volume[J]=0;
#if HAS_SND
emu_sndPlaySound(J+First, 0, 0);
#endif
//Sound(J+First,0,0);
}
}
/** WrCtrl8910() *********************************************/
/** Write a value V to the PSG Control Port. **/
/*************************************************************/
void WrCtrl8910(AY8910 *D,byte V)
{
D->Latch=V&0x0F;
}
/** WrData8910() *********************************************/
/** Write a value V to the PSG Data Port. **/
/*************************************************************/
void WrData8910(AY8910 *D,byte V)
{
Write8910(D,D->Latch,V);
}
/** RdData8910() *********************************************/
/** Read a value from the PSG Data Port. **/
/*************************************************************/
byte RdData8910(AY8910 *D)
{
return(D->R[D->Latch]);
}
/** Write8910() **********************************************/
/** Call this function to output a value V into the sound **/
/** chip. **/
/*************************************************************/
void Write8910(register AY8910 *D,register byte R,register byte V)
{
register int J,I;
switch(R)
{
case 1:
case 3:
case 5:
V&=0x0F;
/* Fall through */
case 0:
case 2:
case 4:
/* Write value */
D->R[R]=V;
/* Exit if the channel is silenced */
if(D->R[7]&(1<<(R>>1))) return;
/* Go to the first register in the pair */
R&=0xFE;
/* Compute frequency */
J=((int)(D->R[R+1]&0x0F)<<8)+D->R[R];
/* Compute channel number */
R>>=1;
/* Assign frequency */
D->Freq[R]=D->Clock/(J? J:0x1000);
/* Compute changed channels mask */
D->Changed|=1<<R;
break;
case 6:
/* Write value */
D->R[6]=V&=0x1F;
/* Exit if noise channels are silenced */
if(!(~D->R[7]&0x38)) return;
/* Compute and assign noise frequency */
/* Shouldn't do <<2, but need to keep frequency down */
J=D->Clock/((V&0x1F? (V&0x1F):0x20)<<2);
if(!(D->R[7]&0x08)) D->Freq[3]=J;
if(!(D->R[7]&0x10)) D->Freq[4]=J;
if(!(D->R[7]&0x20)) D->Freq[5]=J;
/* Compute changed channels mask */
D->Changed|=0x38&~D->R[7];
break;
case 7:
/* Find changed channels */
R=(V^D->R[7])&0x3F;
D->Changed|=R;
/* Write value */
D->R[7]=V;
/* Update frequencies */
for(J=0;R&&(J<AY8910_CHANNELS);J++,R>>=1,V>>=1)
if(R&1)
{
if(V&1) D->Freq[J]=0;
else if(J<3)
{
I=((int)(D->R[J*2+1]&0x0F)<<8)+D->R[J*2];
D->Freq[J]=D->Clock/(I? I:0x1000);
}
else
{
/* Shouldn't do <<2, but need to keep frequency down */
I=D->R[6]&0x1F;
D->Freq[J]=D->Clock/((I? I:0x20)<<2);
}
}
break;
case 8:
case 9:
case 10:
/* Write value */
D->R[R]=V&=0x1F;
/* Compute channel number */
R-=8;
/* Compute and assign new volume */
J=Volumes[V&0x10? Envelopes[D->R[13]&0x0F][D->EPhase]:(V&0x0F)];
D->Volume[R]=J;
D->Volume[R+3]=(J+1)>>1;
/* Compute changed channels mask */
D->Changed|=(0x09<<R)&~D->R[7];
break;
case 11:
case 12:
/* Write value */
D->R[R]=V;
/* Compute envelope period (why not <<4?) */
J=((int)D->R[12]<<8)+D->R[11];
D->EPeriod=1000*(J? J:0x10000)/D->Clock;
/* No channels changed */
return;
case 13:
/* Write value */
D->R[R]=V&=0x0F;
/* Reset envelope */
D->ECount = 0;
D->EPhase = 0;
for(J=0;J<AY8910_CHANNELS/2;++J)
if(D->R[J+8]&0x10)
{
I = Volumes[Envelopes[V][0]];
D->Volume[J] = I;
D->Volume[J+3] = (I+1)>>1;
D->Changed |= (0x09<<J)&~D->R[7];
}
break;
case 14:
case 15:
/* Write value */
D->R[R]=V;
/* No channels changed */
return;
default:
/* Wrong register, do nothing */
return;
}
/* For asynchronous mode, make Sound() calls right away */
if(!D->Sync&&D->Changed) Sync8910(D,AY8910_FLUSH);
}
/** Loop8910() ***********************************************/
/** Call this function periodically to update volume **/
/** envelopes. Use mS to pass the time since the last call **/
/** of Loop8910() in milliseconds. **/
/*************************************************************/
void Loop8910(register AY8910 *D,int mS)
{
register int J,I;
/* Exit if no envelope running */
if(!D->EPeriod) return;
/* Count milliseconds */
D->ECount += mS;
if(D->ECount<D->EPeriod) return;
/* Count steps */
J = D->ECount/D->EPeriod;
D->ECount -= J*D->EPeriod;
/* Count phases */
D->EPhase += J;
if(D->EPhase>31)
D->EPhase = (D->R[13]&0x09)==0x08? (D->EPhase&0x1F):31;
/* Set envelope volumes for relevant channels */
for(I=0;I<3;++I)
if(D->R[I+8]&0x10)
{
J = Volumes[Envelopes[D->R[13]&0x0F][D->EPhase]];
D->Volume[I] = J;
D->Volume[I+3] = (J+1)>>1;
D->Changed |= (0x09<<I)&~D->R[7];
}
/* For asynchronous mode, make Sound() calls right away */
if(!D->Sync&&D->Changed) Sync8910(D,AY8910_FLUSH);
}
/** Sync8910() ***********************************************/
/** Flush all accumulated changes by issuing Sound() calls **/
/** and set the synchronization on/off. The second argument **/
/** should be AY8910_SYNC/AY8910_ASYNC to set/reset sync, **/
/** or AY8910_FLUSH to leave sync mode as it is. To emulate **/
/** noise channels with MIDI drums, OR second argument with **/
/** AY8910_DRUMS. **/
/*************************************************************/
void Sync8910(register AY8910 *D,register byte Sync)
{
register int J,I;
/* Hit MIDI drums for noise channels, if requested */
if(Sync&AY8910_DRUMS)
{
Sync&=~AY8910_DRUMS;
J = (D->Freq[3]? D->Volume[3]:0)
+ (D->Freq[4]? D->Volume[4]:0)
+ (D->Freq[5]? D->Volume[5]:0);
if(J) {
//Drum(DRM_MIDI|28,(J+2)/3);
}
}
if(Sync!=AY8910_FLUSH) D->Sync=Sync;
for(J=0,I=D->Changed;I&&(J<AY8910_CHANNELS);J++,I>>=1)
if(I&1) {
#if HAS_SND
emu_sndPlaySound(J+D->First, D->Volume[J], D->Freq[J]);
#endif
//Sound(J+D->First,D->Freq[J],D->Volume[J]);
}
D->Changed=0x00;
}

View file

@ -0,0 +1,98 @@
/** EMULib Emulation Library *********************************/
/** **/
/** AY8910.h **/
/** **/
/** This file contains emulation for the AY8910 sound chip **/
/** produced by General Instruments, Yamaha, etc. See **/
/** AY8910.c for the actual code. **/
/** **/
/** Copyright (C) Marat Fayzullin 1996-2014 **/
/** You are not allowed to distribute this software **/
/** commercially. Please, notify me, if you make any **/
/** changes to this file. **/
/*************************************************************/
#ifndef AY8910_H
#define AY8910_H
#ifdef __cplusplus
extern "C" {
#endif
#define AY8910_CHANNELS 6 /* 3 melodic + 3 noise chanls */
#define AY8910_ASYNC 0 /* Asynchronous emulation */
#define AY8910_SYNC 1 /* Synchronous emulation */
#define AY8910_FLUSH 2 /* Flush buffers only */
#define AY8910_DRUMS 0x80 /* Hit drums for noise chnls */
#ifndef BYTE_TYPE_DEFINED
#define BYTE_TYPE_DEFINED
typedef unsigned char byte;
#endif
/** AY8910 ***************************************************/
/** This data structure stores AY8910 state. **/
/*************************************************************/
typedef struct
{
byte R[16]; /* PSG registers contents */
int Freq[AY8910_CHANNELS]; /* Frequencies (0 for off) */
int Volume[AY8910_CHANNELS]; /* Volumes (0..255) */
int Clock; /* Base clock used by PSG */
int First; /* First used Sound() channel */
byte Changed; /* Bitmap of changed channels */
byte Sync; /* AY8910_SYNC/AY8910_ASYNC */
byte Latch; /* Latch for the register num */
int EPeriod; /* Envelope step in msecs */
int ECount; /* Envelope step counter */
int EPhase; /* Envelope phase */
} AY8910;
/** Reset8910() **********************************************/
/** Reset the sound chip and use sound channels from the **/
/** one given in First. **/
/*************************************************************/
void Reset8910(register AY8910 *D,int ClockHz,int First);
/** Write8910() **********************************************/
/** Call this function to output a value V into the sound **/
/** chip. **/
/*************************************************************/
void Write8910(register AY8910 *D,register byte R,register byte V);
/** WrCtrl8910() *********************************************/
/** Write a value V to the PSG Control Port. **/
/*************************************************************/
void WrCtrl8910(AY8910 *D,byte V);
/** WrData8910() *********************************************/
/** Write a value V to the PSG Data Port. **/
/*************************************************************/
void WrData8910(AY8910 *D,byte V);
/** RdData8910() *********************************************/
/** Read a value from the PSG Data Port. **/
/*************************************************************/
byte RdData8910(AY8910 *D);
/** Sync8910() ***********************************************/
/** Flush all accumulated changes by issuing Sound() calls **/
/** and set the synchronization on/off. The second argument **/
/** should be AY8910_SYNC/AY8910_ASYNC to set/reset sync, **/
/** or AY8910_FLUSH to leave sync mode as it is. To emulate **/
/** noise channels with MIDI drums, OR second argument with **/
/** AY8910_DRUMS. **/
/*************************************************************/
void Sync8910(register AY8910 *D,register byte Sync);
/** Loop8910() ***********************************************/
/** Call this function periodically to update volume **/
/** envelopes. Use mS to pass the time since the last call **/
/** of Loop8910() in milliseconds. **/
/*************************************************************/
void Loop8910(register AY8910 *D,int mS);
#ifdef __cplusplus
}
#endif
#endif /* AY8910_H */

View file

@ -0,0 +1,361 @@
#include "emuapi.h"
#ifdef HAS_SND
#include "AudioPlaySystem.h"
#include <Arduino.h>
#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<len;i++)
{
s =((v0*square[(chan[0].spos>>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

View file

@ -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

View file

@ -0,0 +1,462 @@
/* Emulation of the Z80 CPU with hooks into the other parts of z81.
* Copyright (C) 1994 Ian Collier.
* z81 changes (C) 1995-2001 Russell Marks.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <string.h> /* for memset/memcpy */
#include "z80.h"
#define parity(a) (partable[a])
unsigned char partable[256]={
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4
};
unsigned long tstates=0,tsmax=65000,frames=0;
/* odd place to have this, but the display does work in an odd way :-) */
unsigned char scrnbmp_new[ZX_VID_FULLWIDTH*ZX_VID_FULLHEIGHT/8]; /* written */
/* checked against for diffs */
int liney=0, lineyi=0;
int vsy=0;
unsigned long linestart=0;
int vsync_toggle=0,vsync_lasttoggle=0;
static int linestate=0, linex=0, nrmvideo=1;
#define LINEX ((tstates-linestart)>>2)
/* for vsync off -> on */
void vsync_raise(void)
{
/* save current pos */
vsy=liney;
}
/* for vsync on -> off */
void vsync_lower(void)
{
int ny=liney,y;
vsync_toggle++;
/* we don't emulate this stuff by default; if nothing else,
* it can be fscking annoying when you're typing in a program.
*/
if(!vsync_visuals)
return;
/* even when we do emulate it, we don't bother with x timing,
* just the y. It gives reasonable results without being too
* complicated, I think.
*/
if(vsy<0) vsy=0;
if(vsy>=ZX_VID_FULLHEIGHT) vsy=ZX_VID_FULLHEIGHT-1;
if(ny<0) ny=0;
if(ny>=ZX_VID_FULLHEIGHT) ny=ZX_VID_FULLHEIGHT-1;
/* XXX both of these could/should be made into single memset calls */
if(ny<vsy)
{
/* must be wrapping around a frame edge; do bottom half */
for(y=vsy;y<ZX_VID_FULLHEIGHT;y++)
memset(scrnbmp_new+y*(ZX_VID_FULLWIDTH/8),0xff,ZX_VID_FULLWIDTH/8);
vsy=0;
}
for(y=vsy;y<ny;y++)
memset(scrnbmp_new+y*(ZX_VID_FULLWIDTH/8),0xff,ZX_VID_FULLWIDTH/8);
}
unsigned char a, f, b, c, d, e, h, l;
unsigned char r, a1, f1, b1, c1, d1, e1, h1, l1, i, iff1, iff2, im;
unsigned short pc;
unsigned short ix, iy, sp;
unsigned long nextlinetime=0,linegap=208,lastvsyncpend=0;
unsigned char radjust;
unsigned char ixoriy, new_ixoriy;
unsigned char intsample=0;
unsigned char op;
int ulacharline=0;
int nmipend=0,intpend=0,vsyncpend=0,vsynclen=0;
int hsyncskip=0;
int framewait=0;
void ExecZ80(void)
{
int retval=0;
while(1)
{
/* this *has* to be checked before radjust is incr'd */
if(intsample && !(radjust&64))
intpend=1;
ixoriy=new_ixoriy;
new_ixoriy=0;
intsample=1;
op=fetch(pc&0x7fff);
if (pc&0x8000 && !(op&64) && linestate==0) {
nrmvideo = i<0x20 || radjust==0xdf;
linestate = 1;
linex = 5;
if (liney<ZX_VID_MARGIN) liney=ZX_VID_MARGIN;
} else if (linestate>=1) {
if (op&64) {
linestate = 0;
linex = ZX_VID_FULLWIDTH/8;
if (ramsize>=4 && !zx80) {
liney++;
lineyi=1;
}
} else {
linestate++;
linex++;
}
}
if (!nrmvideo) ulacharline = 0;
if((pc&0x8000) && !(op&64))
{
int x,y,v;
/* do the ULA's char-generating stuff */
x=linex;
y=liney;
/* printf("ULA %3d,%3d = %02X\n",x,y,op);*/
if(y>=0 && y<ZX_VID_FULLHEIGHT && x>=0 && x<ZX_VID_FULLWIDTH/8)
{
/* XXX I think this is what's needed for the `true hi-res'
* stuff from the ULA's side, but the timing is messed up
* at the moment so not worth it currently.
*/
if (nrmvideo)
v=mem[((i&0xfe)<<8)|((op&63)<<3)|ulacharline];
else
v=mem[(i<<8)|(r&0x80)|(radjust&0x7f)];
//if(taguladisp) v^=128;
scrnbmp_new[y*(ZX_VID_FULLWIDTH/8)+x]=((op&128)?~v:v);
}
op=0; /* the CPU sees a nop */
}
pc++;
radjust++;
switch(op)
{
#include "z80ops.h"
}
if(tstates>=tsmax)
{
retval=1;
tstates-=tsmax;
linestart-=tsmax;
nextlinetime-=tsmax;
lastvsyncpend-=tsmax;
vsync_lasttoggle=vsync_toggle;
vsync_toggle=0;
frames++;
frame_pause();
}
/* the vsync length test is pretty arbitrary, because
* the timing isn't very accurate (more or less an instruction
* count) - but it's good enough in practice.
*
* the vsync_toggle test is fairly arbitrary too;
* there has to have been `not too many' for a TV to get
* confused. In practice, more than one would screw it up,
* but since we could be looking at over a frames' worth
* given where vsync_toggle is zeroed, we play it safe.
* also, we use a copy of the previous chunk's worth,
* since we need a full frame(-plus) to decide this.
*/
if(vsynclen && !vsync)
{
if(vsynclen>=10)
{
if(vsync_lasttoggle<=2)
{
vsyncpend=1; /* start of frame */
/* FAST mode screws up without this, but it's a bit
* unpleasant... :-/
*/
tstates=nextlinetime;
}
}
else
{
/* independent timing for this would be awkward, so
* anywhere on the line is good enough. Also,
* don't count it as a toggle.
*/
vsync_toggle--;
hsyncskip=1;
}
}
/* should do this all the time vsync is set */
if(vsync)
{
ulacharline=0;
vsynclen++;
}
else {
vsynclen=0;
}
if(tstates>=nextlinetime) /* new line */
{
/* generate fake sync if we haven't had one for a while;
* but if we just loaded/saved, wait for the first real frame instead
* to avoid jumpiness.
*/
if(!vsync && tstates-lastvsyncpend>=tsmax && !framewait)
vsyncpend=1;
/* but that won't ever happen if we always have vsync on -
* i.e., if we're grinding away in FAST mode. So for that
* case, we check for vsync being held for a full frame.
*/
if(vsync_visuals && vsynclen>=tsmax)
{
vsyncpend=1;
vsynclen=1;
goto postcopy; /* skip the usual copying */
}
if(!vsyncpend)
{
if (!lineyi) liney++;
if(hsyncgen && !hsyncskip)
{
ulacharline++;
ulacharline&=7;
}
}
else
{
bitbufBlit(scrnbmp_new);
postcopy:
memset(scrnbmp_new,0,sizeof(scrnbmp_new));
lastvsyncpend=tstates;
vsyncpend=0;
framewait=0;
liney=-1; /* XXX might be something up here */
}
if(nmigen)
nmipend=1;
hsyncskip=0;
linestart=nextlinetime;
nextlinetime+=linegap;
}
if(intsample && nmipend)
{
nmipend=0;
if(nmigen)
{
iff2=iff1;
iff1=0;
/* hardware syncs tstates to falling of NMI pulse (?),
* so a slight kludge here...
*/
if(fetch(pc&0x7fff)==0x76)
{
pc++;
tstates=linestart;
}
else
{
/* this seems curiously long, but equally, seems
* to be just about right. :-)
*/
tstates+=27;
}
push2(pc);
pc=0x66;
}
}
if(intsample && intpend)
{
intpend=0;
if(iff1)
{
if(fetch(pc&0x7fff)==0x76)pc++;
iff1=iff2=0;
tstates+=5; /* accompanied by an input from the data bus */
switch(im)
{
case 0: /* IM 0 */
case 1: /* undocumented */
case 2: /* IM 1 */
/* there is little to distinguish between these cases */
tstates+=9; /* perhaps */
push2(pc);
pc=0x38;
break;
case 3: /* IM 2 */
/* (seems unlikely it'd ever be used on the '81, but...) */
tstates+=13; /* perhaps */
{
int addr=fetch2((i<<8)|0xff);
push2(pc);
pc=addr;
}
}
}
}
/* this isn't used for any sort of Z80 interrupts,
* purely for the emulator's UI.
*/
if(interrupted)
{
if(interrupted==1)
{
do_interrupt(); /* also zeroes it */
}
else /* must be 2 */
{
/* a kludge to let us do a reset */
interrupted=0;
a=f=b=c=d=e=h=l=a1=f1=b1=c1=d1=e1=h1=l1=i=iff1=iff2=im=r=0;
ixoriy=new_ixoriy=0;
ix=iy=sp=pc=0;
tstates=radjust=0;
nextlinetime=linegap;
vsyncpend=vsynclen=0;
hsyncskip=0;
}
}
if (retval) break;
}
}
void ResetZ80(void)
{
a=f=b=c=d=e=h=l=a1=f1=b1=c1=d1=e1=h1=l1=i=iff1=iff2=im=r=0;
ixoriy=new_ixoriy=0;
ix=iy=sp=pc=0;
tstates=radjust=0;
nextlinetime=linegap;
tstates=0;
frames=0;
liney=0;
vsy=0;
linestart=0;
vsync_toggle=0;
vsync_lasttoggle=0;
/* we load a snapshot, in effect.This does the registers.
*/
if(autoload)
{
if (zx80) {
/* Registers (common values) */
a = 0x00; f = 0x44; b = 0x00; c = 0x00;
d = 0x07; e = 0xae; h = 0x40; l = 0x2a;
pc = 0x0283;
ix = 0x0000; iy = 0x4000; i = 0x0e; r = 0xdd;
a1 = 0x00; f1 = 0x00; b1 = 0x00; c1 = 0x21;
d1 = 0xd8; e1 = 0xf0; h1 = 0xd8; l1 = 0xf0;
iff1 = 0x00; iff2 = 0x00; im = 0x02;
radjust = 0x6a;
/* Machine Stack (common values) */
if (ramsize >= 16) {
sp = 0x8000 - 4;
} else {
sp = 0x4000 - 4 + ramsize * 1024;
}
mem[sp + 0] = 0x47;
mem[sp + 1] = 0x04;
mem[sp + 2] = 0xba;
mem[sp + 3] = 0x3f;
/* Now override if RAM configuration changes things
* (there's a possibility these changes are unimportant) */
if (ramsize == 16) {
mem[sp + 2] = 0x22;
}
} else {
static unsigned char bit1[9]={0xFF,0x80,0xFC,0x7F,0x00,0x80,0x00,0xFE,0xFF};
static unsigned char bit2[4]={0x76,0x06,0x00,0x3e};
/* memory will already be zeroed at this point */
memcpy(mem+0x4000,bit1,9);
memcpy(mem+0x7ffc,bit2,4);
a=0x0B; f=0x85; b=0x00; c=0xFF;
d=0x43; e=0x99; h=0xC3; l=0x99;
a1=0xE2; f1=0xA1; b1=0x81; c1=0x02;
d1=0x00; e1=0x2B; h1=0x00; l1=0x00;
i=0x1E; iff1=iff2=0;
im=2;
r=0xDD; radjust=0xCA;
ix=0x281; iy=0x4000;
sp=0x7FFC;
pc=0x207;
}
/* finally, load. It'll reset (via reset81) if it fails. */
load_p(32768);
/* wait for a real frame, to avoid an annoying frame `jump'. */
framewait=1;
}
}

View file

@ -0,0 +1,79 @@
/* z81/xz81, Linux console and X ZX81/ZX80 emulators.
* Copyright (C) 1994 Ian Collier. z81 changes (C) 1995-2001 Russell Marks.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "common.h"
#define Z80_quit 1
#define Z80_NMI 2
#define Z80_reset 3
#define Z80_load 4
#define Z80_save 5
#define Z80_log 6
extern int interrupted;
extern unsigned long tstates,tsmax,frames;
extern void setzx80mode(void);
extern void vsync_raise(void);
extern void vsync_lower(void);
extern void ResetZ80(void);
extern void ExecZ80(void);
#define fetch(x) (memptr[(unsigned short)(x)>>10][(x)&1023])
#define fetch2(x) ((fetch((x)+1)<<8)|fetch(x))
#define store(x,y) do {\
unsigned short off=(x)&1023;\
unsigned char page=(unsigned short)(x)>>10;\
int attr=memattr[page];\
if(attr){\
memptr[page][off]=(y);\
}\
} while(0)
#define store2b(x,hi,lo) do {\
unsigned short off=(x)&1023;\
unsigned char page=(unsigned short)(x)>>10;\
int attr=memattr[page];\
if(attr) { \
memptr[page][off]=(lo);\
memptr[page][off+1]=(hi);\
}\
} while(0)
#define store2(x,y) store2b(x,(y)>>8,(y)&255)
#ifdef __GNUC__
static void inline storefunc(unsigned short ad,unsigned char b){
store(ad,b);
}
#undef store
#define store(x,y) storefunc(x,y)
static void inline store2func(unsigned short ad,unsigned char b1,unsigned char b2){
store2b(ad,b1,b2);
}
#undef store2b
#define store2b(x,hi,lo) store2func(x,hi,lo)
#endif
#define bc ((b<<8)|c)
#define de ((d<<8)|e)
#define hl ((h<<8)|l)

View file

@ -0,0 +1,177 @@
/* Emulations of the CB operations of the Z80 instruction set.
* Copyright (C) 1994 Ian Collier.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define var_t unsigned char t
#define rlc(x) (x=(x<<1)|(x>>7),rflags(x,x&1))
#define rrc(x) do{var_t=x&1;x=(x>>1)|(t<<7);rflags(x,t);}while(0)
#define rl(x) do{var_t=x>>7;x=(x<<1)|(f&1);rflags(x,t);}while(0)
#define rr(x) do{var_t=x&1;x=(x>>1)|(f<<7);rflags(x,t);}while(0)
#define sla(x) do{var_t=x>>7;x<<=1;rflags(x,t);}while(0)
#define sra(x) do{var_t=x&1;x=((signed char)x)>>1;rflags(x,t);}while(0)
#define sll(x) do{var_t=x>>7;x=(x<<1)|1;rflags(x,t);}while(0)
#define srl(x) do{var_t=x&1;x>>=1;rflags(x,t);}while(0)
#define rflags(x,c) (f=(c)|(x&0xa8)|((!x)<<6)|parity(x))
#define bit(n,x) (f=(f&1)|((x&(1<<n))?0x10:0x54)|(x&0x28))
#define set(n,x) (x|=(1<<n))
#define res(n,x) (x&=~(1<<n))
{
/* reg/val are initialised to stop gcc's (incorrect) warning,
* and static to save initialising them every time.
*/
static unsigned char reg=0,val=0;
unsigned short addr;
unsigned char op;
if(ixoriy){
addr=(ixoriy==1?ix:iy)+(signed char)fetch(pc);
pc++;
tstates+=8;
op=fetch(pc);
reg=op&7;
op=(op&0xf8)|6;
}
else{
op=fetch(pc);
tstates+=4;
radjust++;
addr=hl;
}
pc++;
if(op<64)switch(op){
case 0: rlc(b); break;
case 1: rlc(c); break;
case 2: rlc(d); break;
case 3: rlc(e); break;
case 4: rlc(h); break;
case 5: rlc(l); break;
case 6: tstates+=7;val=fetch(addr);rlc(val);store(addr,val);break;
case 7: rlc(a); break;
case 8: rrc(b); break;
case 9: rrc(c); break;
case 10: rrc(d); break;
case 11: rrc(e); break;
case 12: rrc(h); break;
case 13: rrc(l); break;
case 14: tstates+=7;val=fetch(addr);rrc(val);store(addr,val);break;
case 15: rrc(a); break;
case 0x10: rl(b); break;
case 0x11: rl(c); break;
case 0x12: rl(d); break;
case 0x13: rl(e); break;
case 0x14: rl(h); break;
case 0x15: rl(l); break;
case 0x16: tstates+=7;val=fetch(addr);rl(val);store(addr,val);break;
case 0x17: rl(a); break;
case 0x18: rr(b); break;
case 0x19: rr(c); break;
case 0x1a: rr(d); break;
case 0x1b: rr(e); break;
case 0x1c: rr(h); break;
case 0x1d: rr(l); break;
case 0x1e: tstates+=7;val=fetch(addr);rr(val);store(addr,val);break;
case 0x1f: rr(a); break;
case 0x20: sla(b); break;
case 0x21: sla(c); break;
case 0x22: sla(d); break;
case 0x23: sla(e); break;
case 0x24: sla(h); break;
case 0x25: sla(l); break;
case 0x26: tstates+=7;val=fetch(addr);sla(val);store(addr,val);break;
case 0x27: sla(a); break;
case 0x28: sra(b); break;
case 0x29: sra(c); break;
case 0x2a: sra(d); break;
case 0x2b: sra(e); break;
case 0x2c: sra(h); break;
case 0x2d: sra(l); break;
case 0x2e: tstates+=7;val=fetch(addr);sra(val);store(addr,val);break;
case 0x2f: sra(a); break;
case 0x30: sll(b); break;
case 0x31: sll(c); break;
case 0x32: sll(d); break;
case 0x33: sll(e); break;
case 0x34: sll(h); break;
case 0x35: sll(l); break;
case 0x36: tstates+=7;val=fetch(addr);sll(val);store(addr,val);break;
case 0x37: sll(a); break;
case 0x38: srl(b); break;
case 0x39: srl(c); break;
case 0x3a: srl(d); break;
case 0x3b: srl(e); break;
case 0x3c: srl(h); break;
case 0x3d: srl(l); break;
case 0x3e: tstates+=7;val=fetch(addr);srl(val);store(addr,val);break;
case 0x3f: srl(a); break;
}
else{
unsigned char n=(op>>3)&7;
switch(op&0xc7){
case 0x40: bit(n,b); break;
case 0x41: bit(n,c); break;
case 0x42: bit(n,d); break;
case 0x43: bit(n,e); break;
case 0x44: bit(n,h); break;
case 0x45: bit(n,l); break;
case 0x46: tstates+=4;val=fetch(addr);bit(n,val);store(addr,val);break;
case 0x47: bit(n,a); break;
case 0x80: res(n,b); break;
case 0x81: res(n,c); break;
case 0x82: res(n,d); break;
case 0x83: res(n,e); break;
case 0x84: res(n,h); break;
case 0x85: res(n,l); break;
case 0x86: tstates+=4;val=fetch(addr);res(n,val);store(addr,val);break;
case 0x87: res(n,a); break;
case 0xc0: set(n,b); break;
case 0xc1: set(n,c); break;
case 0xc2: set(n,d); break;
case 0xc3: set(n,e); break;
case 0xc4: set(n,h); break;
case 0xc5: set(n,l); break;
case 0xc6: tstates+=4;val=fetch(addr);set(n,val);store(addr,val);break;
case 0xc7: set(n,a); break;
}
}
if(ixoriy)switch(reg){
case 0:b=val; break;
case 1:c=val; break;
case 2:d=val; break;
case 3:e=val; break;
case 4:h=val; break;
case 5:l=val; break;
case 7:a=val; break;
}
}
#undef var_t
#undef rlc
#undef rrc
#undef rl
#undef rr
#undef sla
#undef sra
#undef sll
#undef srl
#undef rflags
#undef bit
#undef set
#undef res

View file

@ -0,0 +1,46 @@
typedef unsigned char byte;
//typedef unsigned short word;
#define WIDTH 320
#define HEIGHT 192
#define BORDER 32
#define CYCLES_PER_FRAME 65000//3500000/50
/* full internal image with overscan (but not hsync/vsync areas) */
#define ZX_VID_MARGIN 55
#define ZX_VID_HMARGIN (8*8)
#define ZX_VID_FULLWIDTH (2*ZX_VID_HMARGIN+32*8) /* sic */
#define ZX_VID_FULLHEIGHT (2*ZX_VID_MARGIN+192)
/* AY board types */
#define AY_TYPE_NONE 0
#define AY_TYPE_QUICKSILVA 1
#define AY_TYPE_ZONX 2
extern unsigned char * mem;
extern unsigned char *memptr[64];
extern int memattr[64];
extern unsigned long tstates,tsmax;
extern int vsync_visuals;
extern int ramsize;
extern int interrupted;
extern int nmigen,hsyncgen,vsync;
extern int autoload;
extern int zx80;
extern void sighandler(int a);
extern unsigned int in(int h,int l);
extern unsigned int out(int h,int l,int a);
extern void do_interrupt();
extern void save_p(int a);
extern void load_p(int a);
extern void do_interrupt();
extern void reset81();
extern void frame_pause(void);
extern void bitbufBlit(unsigned char * buf);

View file

@ -0,0 +1,545 @@
/* Emulations of the ED operations of the Z80 instruction set.
* Copyright (C) 1994 Ian Collier.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define input(var) { unsigned short u;\
var=u=in(b,c);\
tstates+=u>>8;\
f=(f&1)|(var&0xa8)|((!var)<<6)|parity(var);\
}
#define sbchl(x) { unsigned short z=(x);\
unsigned long t=(hl-z-cy)&0x1ffff;\
f=((t>>8)&0xa8)|(t>>16)|2|\
(((hl&0xfff)<(z&0xfff)+cy)<<4)|\
(((hl^z)&(hl^t)&0x8000)>>13)|\
((!(t&0xffff))<<6)|2;\
l=t;\
h=t>>8;\
}
#define adchl(x) { unsigned short z=(x);\
unsigned long t=hl+z+cy;\
f=((t>>8)&0xa8)|(t>>16)|\
(((hl&0xfff)+(z&0xfff)+cy>0xfff)<<4)|\
(((~hl^z)&(hl^t)&0x8000)>>13)|\
((!(t&0xffff))<<6)|2;\
l=t;\
h=t>>8;\
}
#define neg (a=-a,\
f=(a&0xa8)|((!a)<<6)|(((a&15)>0)<<4)|((a==128)<<2)|2|(a>0))
{
unsigned char op=fetch(pc&0x7fff);
pc++;
radjust++;
switch(op){
instr(0x40,8);
input(b);
endinstr;
instr(0x41,8);
tstates+=out(b,c,b);
endinstr;
instr(0x42,11);
sbchl(bc);
endinstr;
instr(0x43,16);
{unsigned short addr=fetch2(pc);
pc+=2;
store2b(addr,b,c);
}
endinstr;
instr(0x44,4);
neg;
endinstr;
instr(0x45,4);
iff1=iff2;
ret;
endinstr;
instr(0x46,4);
im=0;
endinstr;
instr(0x47,5);
i=a;
endinstr;
instr(0x48,8);
input(c);
endinstr;
instr(0x49,8);
tstates+=out(b,c,c);
endinstr;
instr(0x4a,11);
adchl(bc);
endinstr;
instr(0x4b,16);
{unsigned short addr=fetch2(pc);
pc+=2;
c=fetch(addr);
b=fetch(addr+1);
}
endinstr;
instr(0x4c,4);
neg;
endinstr;
instr(0x4d,4);
ret;
endinstr;
instr(0x4e,4);
im=1;
endinstr;
instr(0x4f,5);
r=a;
radjust=r;
endinstr;
instr(0x50,8);
input(d);
endinstr;
instr(0x51,8);
tstates+=out(b,c,d);
endinstr;
instr(0x52,11);
sbchl(de);
endinstr;
instr(0x53,16);
{unsigned short addr=fetch2(pc);
pc+=2;
store2b(addr,d,e);
}
endinstr;
instr(0x54,4);
neg;
endinstr;
instr(0x55,4);
ret;
endinstr;
instr(0x56,4);
im=2;
endinstr;
instr(0x57,5);
a=i;
f=(f&1)|(a&0xa8)|((!a)<<6)|(iff2<<2);
endinstr;
instr(0x58,8);
input(e);
endinstr;
instr(0x59,8);
tstates+=out(b,c,e);
endinstr;
instr(0x5a,11);
adchl(de);
endinstr;
instr(0x5b,16);
{unsigned short addr=fetch2(pc);
pc+=2;
e=fetch(addr);
d=fetch(addr+1);
}
endinstr;
instr(0x5c,4);
neg;
endinstr;
instr(0x5d,4);
ret;
endinstr;
instr(0x5e,4);
im=3;
endinstr;
instr(0x5f,5);
r=(r&0x80)|(radjust&0x7f);
a=r;
f=(f&1)|(a&0xa8)|((!a)<<6)|(iff2<<2);
endinstr;
instr(0x60,8);
input(h);
endinstr;
instr(0x61,8);
tstates+=out(b,c,h);
endinstr;
instr(0x62,11);
sbchl(hl);
endinstr;
instr(0x63,16);
{unsigned short addr=fetch2(pc);
pc+=2;
store2b(addr,h,l);
}
endinstr;
instr(0x64,4);
neg;
endinstr;
instr(0x65,4);
ret;
endinstr;
instr(0x66,4);
im=0;
endinstr;
instr(0x67,14);
{unsigned char t=fetch(hl);
unsigned char u=(a<<4)|(t>>4);
a=(a&0xf0)|(t&0x0f);
store(hl,u);
f=(f&1)|(a&0xa8)|((!a)<<6)|parity(a);
}
endinstr;
instr(0x68,8);
input(l);
endinstr;
instr(0x69,8);
tstates+=out(b,c,l);
endinstr;
instr(0x6a,11);
adchl(hl);
endinstr;
instr(0x6b,16);
{unsigned short addr=fetch2(pc);
pc+=2;
l=fetch(addr);
h=fetch(addr+1);
}
endinstr;
instr(0x6c,4);
neg;
endinstr;
instr(0x6d,4);
ret;
endinstr;
instr(0x6e,4);
im=1;
endinstr;
instr(0x6f,5);
{unsigned char t=fetch(hl);
unsigned char u=(a&0x0f)|(t<<4);
a=(a&0xf0)|(t>>4);
store(hl,u);
f=(f&1)|(a&0xa8)|((!a)<<6)|parity(a);
}
endinstr;
instr(0x70,8);
{unsigned char x;input(x);}
endinstr;
instr(0x71,8);
tstates+=out(b,c,0);
endinstr;
instr(0x72,11);
sbchl(sp);
endinstr;
instr(0x73,16);
{unsigned short addr=fetch2(pc);
pc+=2;
store2(addr,sp);
}
endinstr;
instr(0x74,4);
neg;
endinstr;
instr(0x75,4);
ret;
endinstr;
instr(0x76,4);
im=2;
endinstr;
instr(0x78,8);
input(a);
endinstr;
instr(0x79,8);
tstates+=out(b,c,a);
endinstr;
instr(0x7a,11);
adchl(sp);
endinstr;
instr(0x7b,16);
{unsigned short addr=fetch2(pc);
pc+=2;
sp=fetch2(addr);
}
endinstr;
instr(0x7c,4);
neg;
endinstr;
instr(0x7d,4);
ret;
endinstr;
instr(0x7e,4);
im=3;
endinstr;
instr(0xa0,12);
{unsigned char x=fetch(hl);
store(de,x);
if(!++l)h++;
if(!++e)d++;
if(!c--)b--;
f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2);
}
endinstr;
instr(0xa1,12);
{unsigned char carry=cy;
cpa(fetch(hl));
if(!++l)h++;
if(!c--)b--;
f=(f&0xfa)|carry|(((b|c)>0)<<2);
}
endinstr;
instr(0xa2,12);
{unsigned short t=in(b,c);
store(hl,t);
tstates+=t>>8;
if(!++l)h++;
b--;
f=(b&0xa8)|((b>0)<<6)|2|((parity(b)^c)&4);
}
endinstr;
instr(0xa3,12); /* I can't determine the correct flags outcome for the
block OUT instructions. Spec says that the carry
flag is left unchanged and N is set to 1, but that
doesn't seem to be the case... */
{unsigned char x=fetch(hl);
tstates+=out(b,c,x);
if(!++l)h++;
b--;
f=(f&1)|0x12|(b&0xa8)|((b==0)<<6);
}
endinstr;
instr(0xa8,12);
{unsigned char x=fetch(hl);
store(de,x);
if(!l--)h--;
if(!e--)d--;
if(!c--)b--;
f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2);
}
endinstr;
instr(0xa9,12);
{unsigned char carry=cy;
cpa(fetch(hl));
if(!l--)h--;
if(!c--)b--;
f=(f&0xfa)|carry|(((b|c)>0)<<2);
}
endinstr;
instr(0xaa,12);
{unsigned short t=in(b,c);
store(hl,t);
tstates+=t>>8;
if(!l--)h--;
b--;
f=(b&0xa8)|((b>0)<<6)|2|((parity(b)^c^4)&4);
}
endinstr;
instr(0xab,12);
{unsigned char x=fetch(hl);
tstates+=out(b,c,x);
if(!l--)h--;
b--;
f=(f&1)|0x12|(b&0xa8)|((b==0)<<6);
}
endinstr;
/* Note: the Z80 implements "*R" as "*" followed by JR -2. No reason
to change this... */
instr(0xb0,12);
{unsigned char x=fetch(hl);
store(de,x);
if(!++l)h++;
if(!++e)d++;
if(!c--)b--;
f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2);
if(b|c)pc-=2,tstates+=5;
}
endinstr;
instr(0xb1,12);
{unsigned char carry=cy;
cpa(fetch(hl));
if(!++l)h++;
if(!c--)b--;
f=(f&0xfa)|carry|(((b|c)>0)<<2);
if((f&0x44)==4)pc-=2,tstates+=5;
}
endinstr;
instr(0xb2,12);
{unsigned short t=in(b,c);
store(hl,t);
tstates+=t>>8;
if(!++l)h++;
b--;
f=(b&0xa8)|((b>0)<<6)|2|((parity(b)^c)&4);
if(b)pc-=2,tstates+=5;
}
endinstr;
instr(0xb3,12);
{unsigned char x=fetch(hl);
tstates+=out(b,c,x);
if(!++l)h++;
b--;
f=(f&1)|0x12|(b&0xa8)|((b==0)<<6);
if(b)pc-=2,tstates+=5;
}
endinstr;
instr(0xb8,12);
{unsigned char x=fetch(hl);
store(de,x);
if(!l--)h--;
if(!e--)d--;
if(!c--)b--;
f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2);
if(b|c)pc-=2,tstates+=5;
}
endinstr;
instr(0xb9,12);
{unsigned char carry=cy;
cpa(fetch(hl));
if(!l--)h--;
if(!c--)b--;
f=(f&0xfa)|carry|(((b|c)>0)<<2);
if((f&0x44)==4)pc-=2,tstates+=5;
}
endinstr;
instr(0xba,12);
{unsigned short t=in(b,c);
store(hl,t);
tstates+=t>>8;
if(!l--)h--;
b--;
f=(b&0xa8)|((b>0)<<6)|2|((parity(b)^c^4)&4);
if(b)pc-=2,tstates+=5;
}
endinstr;
instr(0xbb,12);
{unsigned char x=fetch(hl);
tstates+=out(b,c,x);
if(!l--)h--;
b--;
f=(f&1)|0x12|(b&0xa8)|((b==0)<<6);
if(b)pc-=2,tstates+=5;
}
endinstr;
/* save/load patches */
instr(0xfc,4);
#ifdef SZ81 /* Added by Thunor */
if(!zx80 && hl < 0x8000)
{
sdl_load_file(hl,LOAD_FILE_METHOD_NAMEDLOAD);
}
else /* if((!zx80 && hl >= 0x8000) || zx80) */
{
sdl_load_file(hl,LOAD_FILE_METHOD_SELECTLOAD);
}
#else
load_p(hl);
#endif
framewait=1;
endinstr;
instr(0xfd,4);
#ifdef SZ81 /* Added by Thunor */
if(zx80)
{
sdl_save_file(hl,SAVE_FILE_METHOD_UNNAMEDSAVE);
}
else
{
sdl_save_file(hl,SAVE_FILE_METHOD_NAMEDSAVE);
}
#else
save_p(hl);
#endif
framewait=1;
endinstr;
default: tstates+=4;
}}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,213 @@
#ifndef EMUAPI_H
#define EMUAPI_H
#include "platform_config.h"
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " ZX81/ZX80 Emulator"
#define ROMSDIR "z81"
#define emu_Init(ROM) {z81_Start(ROM); z81_Init(); }
#define emu_Step(x) {z81_Step();}
#define emu_Input(x) {z81_Input(x);}
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 2
#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 *)" \" $ *()\x1a"
#define keylables_map2_1 (char *)" \x19"
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10 "
const unsigned short key_map2[] = {
0,'"',0,'$',0,0,0,'*','(',')',127, // shiftothers
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_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

View file

@ -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
};

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,206 @@
extern "C" {
#include "iopins.h"
#include "emuapi.h"
}
extern "C" {
#include "zx81.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<PALETTE_SIZE) {
//Serial.println("%d: %d %d %d\n", index, r,g,b);
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.waitSync();
#else
while (vbl==vb) {};
#endif
}
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine16(width,height,line, VBuf);
#else
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
// ****************************************************
// the setup() method runs once, when the sketch starts
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
}
// ****************************************************
// the loop() method runs continuously
// ****************************************************
void loop(void)
{
if (menuActive()) {
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
emu_start();
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 16666); //to run every 16.666ms
}
delay(20);
}
else {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
delay(10);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// emu_Input(bClick);
//}
}
}
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
#ifdef HAS_T4_VGA
tft.begin_audio(256, mymixer.snd_Mixer);
#else
mymixer.begin_audio(256, mymixer.snd_Mixer);
#endif
// sgtl5000_1.enable();
// sgtl5000_1.volume(0.6);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
//mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,232 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#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 192
#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

View file

@ -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

View file

@ -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 <VGA_t4.h>
#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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,259 @@
const unsigned char PROGMEM zx80rom[] = {
0x21, 0xff, 0x7f, 0x3e, 0x3f, 0xc3, 0x61, 0x02, 0xe1, 0x6e, 0xfd, 0xcb, 0x00, 0x7e, 0x18, 0x03,
0xc3, 0x60, 0x05, 0xc8, 0xfd, 0x75, 0x00, 0xc9, 0x18, 0x38, 0x2a, 0x26, 0x40, 0x7e, 0xa7, 0xc0,
0xcd, 0x52, 0x00, 0x18, 0xf9, 0xcd, 0x55, 0x00, 0xcd, 0x1a, 0x00, 0x06, 0x00, 0xc3, 0xe1, 0x09,
0xcd, 0x4f, 0x09, 0xd0, 0xc5, 0xc3, 0xf3, 0x0c, 0x0d, 0xc2, 0x45, 0x00, 0xe1, 0x05, 0xc8, 0xcb,
0xd9, 0xed, 0x4f, 0xfb, 0xe9, 0xd1, 0xc8, 0x18, 0xf8, 0xcd, 0x25, 0x00, 0x7e, 0xfe, 0xd9, 0xc2,
0xae, 0x08, 0x2a, 0x26, 0x40, 0x23, 0x22, 0x26, 0x40, 0x7e, 0xfe, 0xb0, 0xc0, 0x22, 0x04, 0x40,
0xfd, 0xcb, 0x19, 0x7e, 0x28, 0xef, 0xfd, 0xcb, 0x01, 0xd6, 0x18, 0xe9, 0x3f, 0x3d, 0x28, 0x3b,
0x26, 0x38, 0x29, 0x2b, 0x2c, 0x36, 0x3c, 0x2a, 0x37, 0x39, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x1c,
0x25, 0x24, 0x23, 0x22, 0x35, 0x34, 0x2e, 0x3a, 0x3e, 0x76, 0x31, 0x30, 0x2f, 0x2d, 0x00, 0x1b,
0x32, 0x33, 0x27, 0x0e, 0xd7, 0x0f, 0xdf, 0x09, 0x08, 0x06, 0x07, 0x0b, 0x02, 0x03, 0x04, 0x05,
0x0a, 0xdb, 0xe0, 0xd5, 0xd6, 0x72, 0x77, 0x74, 0x73, 0x70, 0x71, 0xde, 0xd9, 0xda, 0x0d, 0x01,
0x75, 0xe3, 0xdd, 0xdc, 0xe2, 0x0c, 0xd8, 0xe4, 0xe5, 0xe1, 0xd4, 0x8f, 0x81, 0x39, 0x2d, 0x2a,
0xb3, 0x39, 0xb4, 0x99, 0x9a, 0x91, 0x90, 0x33, 0x34, 0xb9, 0x92, 0x93, 0x94, 0x95, 0x26, 0x33,
0xa9, 0x34, 0xb7, 0x14, 0x94, 0x96, 0x97, 0x98, 0x31, 0x2e, 0x38, 0xb9, 0x37, 0x2a, 0x39, 0x3a,
0x37, 0xb3, 0x28, 0x31, 0xb8, 0x29, 0x2e, 0xb2, 0x38, 0x26, 0x3b, 0xaa, 0x2b, 0x34, 0xb7, 0x2c,
0x34, 0x00, 0x39, 0xb4, 0x35, 0x34, 0x30, 0xaa, 0x2e, 0x33, 0x35, 0x3a, 0xb9, 0x37, 0x26, 0x33,
0x29, 0x34, 0x32, 0x2e, 0x38, 0xaa, 0x31, 0x2a, 0xb9, 0x8f, 0x8f, 0x33, 0x2a, 0x3d, 0xb9, 0x35,
0x37, 0x2e, 0x33, 0xb9, 0x8f, 0x33, 0x2a, 0xbc, 0x37, 0x3a, 0xb3, 0x38, 0x39, 0x34, 0xb5, 0x28,
0x34, 0x33, 0x39, 0x2e, 0x33, 0x3a, 0xaa, 0x2e, 0xab, 0x2c, 0x34, 0x00, 0x38, 0x3a, 0xa7, 0x31,
0x34, 0x26, 0xa9, 0x28, 0x31, 0x2a, 0x26, 0xb7, 0x37, 0x2a, 0xb2, 0x8f, 0xcd, 0xad, 0x01, 0x06,
0x08, 0x10, 0xfe, 0x2a, 0x1e, 0x40, 0x23, 0x22, 0x1e, 0x40, 0x21, 0xff, 0xff, 0x06, 0xfe, 0x48,
0xed, 0x78, 0xf6, 0x01, 0xf6, 0xe0, 0x57, 0x2f, 0xfe, 0x01, 0x9f, 0xb0, 0xa5, 0x6f, 0x7c, 0xa2,
0x67, 0xcb, 0x00, 0xed, 0x78, 0x38, 0xed, 0x1f, 0xcb, 0x14, 0x17, 0x17, 0x17, 0x9f, 0xe6, 0x18,
0xc6, 0x20, 0x32, 0x23, 0x40, 0xed, 0x4b, 0x26, 0x40, 0x22, 0x26, 0x40, 0x78, 0xc6, 0x02, 0xed,
0x42, 0xeb, 0x21, 0x22, 0x40, 0x7e, 0xb2, 0xb3, 0xc8, 0x78, 0xfe, 0xfe, 0x9f, 0x06, 0x1f, 0xb6,
0xa0, 0x1f, 0x77, 0x05, 0x10, 0xfe, 0xd3, 0xff, 0x3e, 0xec, 0x06, 0x19, 0x2a, 0x0c, 0x40, 0xcb,
0xfc, 0xcd, 0xad, 0x01, 0x3e, 0xf3, 0x04, 0x2b, 0xfd, 0x35, 0x23, 0x18, 0x8f, 0xfd, 0x4e, 0x23,
0xed, 0x4f, 0x3e, 0xdd, 0xfb, 0xe9, 0xd1, 0x11, 0xcb, 0x12, 0x3e, 0x7f, 0xdb, 0xfe, 0x1f, 0x30,
0x42, 0x10, 0xfe, 0x1b, 0x7a, 0xb3, 0x20, 0xf2, 0x21, 0x00, 0x40, 0x11, 0x08, 0xf8, 0xcb, 0x06,
0x9f, 0xe6, 0x05, 0xc6, 0x04, 0x4f, 0xd3, 0xff, 0x06, 0x24, 0x10, 0xfe, 0x3e, 0x7f, 0xdb, 0xfe,
0x06, 0x23, 0x10, 0xfe, 0x0d, 0x20, 0xef, 0x42, 0x00, 0x10, 0xfd, 0x16, 0xfe, 0x1d, 0x20, 0xde,
0x1f, 0x30, 0x10, 0xcd, 0xf8, 0x01, 0x18, 0xd3, 0x23, 0xeb, 0x2a, 0x0a, 0x40, 0x37, 0xed, 0x52,
0xeb, 0xd0, 0xe1, 0xc3, 0x83, 0x02, 0xd1, 0x11, 0x12, 0x57, 0x3e, 0x7f, 0xdb, 0xfe, 0x1f, 0x30,
0xf2, 0x17, 0x17, 0x38, 0xf2, 0x1b, 0x7a, 0xb3, 0x20, 0xf0, 0xfd, 0x34, 0x0b, 0x21, 0x00, 0x40,
0x1e, 0x08, 0x3e, 0x7f, 0xdb, 0xfe, 0x1f, 0x30, 0x24, 0x17, 0x17, 0x30, 0xf5, 0x0e, 0x94, 0x06,
0x1a, 0x0d, 0xdb, 0xfe, 0x17, 0xcb, 0x79, 0x79, 0x38, 0xf5, 0x10, 0xf5, 0x20, 0x04, 0xfe, 0x56,
0x30, 0xe0, 0x3f, 0xcb, 0x16, 0x1d, 0x20, 0xda, 0xcd, 0xf8, 0x01, 0x18, 0xd3, 0x15, 0xf2, 0x00,
0x00, 0xfd, 0x35, 0x0b, 0x18, 0xad, 0xcb, 0xb8, 0xcb, 0xb0, 0xed, 0x43, 0x06, 0x40, 0xc1, 0x18,
0x22, 0x36, 0x01, 0x2b, 0xbc, 0x20, 0xfa, 0x23, 0x35, 0x28, 0xfc, 0xf9, 0xf5, 0x3e, 0x0e, 0xed,
0x47, 0xed, 0x56, 0xfd, 0x21, 0x00, 0x40, 0x21, 0x28, 0x40, 0x22, 0x08, 0x40, 0x36, 0x80, 0x23,
0x22, 0x0a, 0x40, 0x2a, 0x0a, 0x40, 0x36, 0xb0, 0x23, 0x36, 0x76, 0x23, 0x22, 0x0c, 0x40, 0xfd,
0x36, 0x12, 0x02, 0xcd, 0x47, 0x07, 0xeb, 0x78, 0xfd, 0x96, 0x12, 0x38, 0x5a, 0x3c, 0x47, 0xd9,
0x2a, 0x06, 0x40, 0xed, 0x5b, 0x13, 0x40, 0xed, 0x52, 0xeb, 0x30, 0x04, 0x19, 0x22, 0x13, 0x40,
0xcd, 0x0a, 0x06, 0x1e, 0x00, 0xcd, 0xf7, 0x04, 0x38, 0xfb, 0x1d, 0x20, 0x33, 0xe5, 0x2a, 0x06,
0x40, 0xcd, 0x0a, 0x06, 0xe1, 0xa7, 0xed, 0x52, 0x21, 0x13, 0x40, 0x30, 0x0b, 0xeb, 0x7e, 0x23,
0xed, 0xa0, 0x12, 0x18, 0xbe, 0x21, 0x06, 0x40, 0x5e, 0x23, 0x56, 0xe5, 0xeb, 0x23, 0xcd, 0x0a,
0x06, 0xcd, 0xc2, 0x03, 0xe1, 0xfd, 0xcb, 0x19, 0x6e, 0x20, 0x0c, 0x72, 0x2b, 0x73, 0x18, 0xa3,
0xcd, 0xc2, 0x05, 0xed, 0x53, 0x0e, 0x40, 0xfd, 0x36, 0x01, 0x01, 0x2a, 0x0a, 0x40, 0xcd, 0xbe,
0x07, 0xed, 0x5b, 0x0e, 0x40, 0xfd, 0x46, 0x12, 0x0e, 0x01, 0xd9, 0x2a, 0x0a, 0x40, 0xcd, 0x12,
0x05, 0x38, 0x0a, 0x21, 0x12, 0x40, 0x34, 0x3e, 0x18, 0xbe, 0x30, 0xb7, 0x77, 0xcd, 0xc2, 0x05,
0xcd, 0x3f, 0x01, 0xcb, 0x28, 0x9f, 0xf6, 0x26, 0x2e, 0x05, 0x95, 0x85, 0x37, 0xcb, 0x19, 0x38,
0xfa, 0x0c, 0x20, 0xc3, 0x48, 0x2d, 0x2e, 0x01, 0x20, 0xf1, 0x21, 0x6b, 0x00, 0x5f, 0x19, 0x7e,
0xfd, 0xcb, 0x01, 0x56, 0x28, 0x07, 0xc6, 0xc0, 0xfe, 0xe6, 0x30, 0x01, 0x7e, 0xfe, 0xc0, 0xea,
0x5e, 0x03, 0x2a, 0x04, 0x40, 0x01, 0x01, 0x00, 0xcd, 0xd5, 0x05, 0x12, 0x18, 0x99, 0x5f, 0x21,
0x92, 0x02, 0x19, 0x19, 0x4e, 0x23, 0x46, 0xc5, 0x2a, 0x04, 0x40, 0xc9, 0x01, 0x01, 0x00, 0xc3,
0x66, 0x06, 0xa9, 0x03, 0xd5, 0x02, 0x82, 0x03, 0x87, 0x03, 0xb9, 0x03, 0xcb, 0x03, 0x08, 0x04,
0x95, 0x03, 0xcd, 0x9e, 0x03, 0x2b, 0x2b, 0x23, 0x7e, 0xfe, 0x76, 0x28, 0x1a, 0x36, 0xb0, 0x2a,
0x04, 0x40, 0x77, 0x18, 0xc7, 0xcd, 0x9e, 0x03, 0x2b, 0xcd, 0x6c, 0x03, 0x18, 0xbe, 0xed, 0x5b,
0x0a, 0x40, 0x1a, 0xfe, 0xb0, 0xc0, 0xd1, 0x18, 0xb3, 0x2a, 0x06, 0x40, 0xcd, 0x0a, 0x06, 0xeb,
0xcd, 0xc2, 0x03, 0x21, 0x07, 0x40, 0xc3, 0xe5, 0x02, 0x11, 0x00, 0x00, 0x18, 0xf5, 0xeb, 0x11,
0xba, 0x03, 0x7e, 0xe6, 0xc0, 0x20, 0xf7, 0x56, 0x23, 0x5e, 0xc9, 0x0e, 0x00, 0xed, 0x5b, 0x0a,
0x40, 0xd9, 0x2a, 0x06, 0x40, 0xcd, 0x0a, 0x06, 0xcd, 0xc2, 0x03, 0x7a, 0xb3, 0xca, 0x83, 0x02,
0x2b, 0xcd, 0xbf, 0x06, 0x2b, 0xcd, 0x24, 0x06, 0x23, 0x23, 0x0b, 0x0b, 0xd9, 0xd5, 0xd9, 0xd1,
0x3e, 0xb0, 0x12, 0x13, 0xe5, 0x21, 0x22, 0x00, 0x19, 0x09, 0xed, 0x72, 0x30, 0xa9, 0xe1, 0xed,
0xb0, 0xed, 0x53, 0x0c, 0x40, 0xc3, 0x93, 0x02, 0x2a, 0x15, 0x40, 0x7c, 0xb5, 0x20, 0x98, 0x2a,
0x04, 0x40, 0xcd, 0x6c, 0x03, 0x2a, 0x0a, 0x40, 0x22, 0x26, 0x40, 0xcd, 0x1a, 0x00, 0xfd, 0xcb,
0x19, 0x6e, 0x20, 0x18, 0xcd, 0x79, 0x06, 0xd9, 0x7c, 0xb5, 0xc2, 0xba, 0x04, 0x2b, 0x2b, 0x22,
0x02, 0x40, 0xcd, 0x47, 0x07, 0xd9, 0x7e, 0xfe, 0x76, 0xca, 0x83, 0x02, 0xfd, 0x36, 0x00, 0xff,
0xfd, 0x36, 0x01, 0x88, 0xcd, 0xbe, 0x07, 0xcd, 0x0a, 0x0d, 0xed, 0x5b, 0x02, 0x40, 0x21, 0x19,
0x40, 0xcb, 0x6e, 0x28, 0x03, 0xcb, 0xae, 0x13, 0xfd, 0xcb, 0x00, 0x7e, 0x28, 0x2a, 0x21, 0x01,
0x40, 0xcb, 0x5e, 0xcb, 0x9e, 0x2a, 0x26, 0x40, 0x23, 0x28, 0x09, 0xeb, 0x7c, 0xe6, 0xc0, 0x20,
0x17, 0xcd, 0x0a, 0x06, 0x7e, 0xe6, 0xc0, 0x20, 0x0f, 0x56, 0x23, 0x5e, 0xed, 0x53, 0x02, 0x40,
0x23, 0x3e, 0x7f, 0xdb, 0xfe, 0x1f, 0x38, 0xbc, 0xcd, 0xe0, 0x06, 0xcd, 0xc2, 0x05, 0x01, 0x20,
0x01, 0xd9, 0x3a, 0x00, 0x40, 0xed, 0x4b, 0x02, 0x40, 0x3c, 0x28, 0x0c, 0xfe, 0x09, 0x20, 0x01,
0x03, 0xed, 0x43, 0x17, 0x40, 0x20, 0x01, 0x0b, 0xcd, 0x56, 0x05, 0x3e, 0x15, 0xd7, 0xcd, 0xa1,
0x06, 0xcd, 0xc2, 0x05, 0xcd, 0x3f, 0x01, 0xc3, 0x83, 0x02, 0x22, 0x06, 0x40, 0xd9, 0xeb, 0xcd,
0x47, 0x07, 0xed, 0x52, 0xd9, 0xcd, 0x0a, 0x06, 0xe5, 0x20, 0x06, 0xcd, 0x24, 0x06, 0xcd, 0x66,
0x06, 0xd9, 0x23, 0x44, 0x4d, 0x7d, 0xd6, 0x03, 0xb4, 0xc4, 0x4f, 0x09, 0xe1, 0x30, 0x15, 0xc5,
0x2b, 0xcd, 0xd5, 0x05, 0x13, 0x2a, 0x0c, 0x40, 0x2b, 0xc1, 0x0b, 0xed, 0xb8, 0x2a, 0x06, 0x40,
0xeb, 0x72, 0x23, 0x73, 0xc3, 0x83, 0x02, 0xed, 0x4b, 0x06, 0x40, 0xcd, 0x1c, 0x06, 0x16, 0x97,
0x28, 0x05, 0x11, 0x00, 0x00, 0xcb, 0x13, 0x7e, 0xfe, 0x40, 0xdc, 0xbf, 0x06, 0xd0, 0x23, 0x7a,
0xd7, 0xd0, 0xfd, 0xcb, 0x01, 0xc6, 0xed, 0x4b, 0x15, 0x40, 0xa7, 0xed, 0x42, 0x20, 0x04, 0x3e,
0xb8, 0xd7, 0xc8, 0x09, 0x7e, 0x23, 0xfe, 0xb0, 0x28, 0x12, 0xfe, 0xc0, 0xea, 0x59, 0x05, 0x38,
0x05, 0xcd, 0x84, 0x05, 0x18, 0x03, 0xcd, 0x59, 0x05, 0xd0, 0x18, 0xda, 0xfd, 0xcb, 0x01, 0x56,
0x20, 0x01, 0x3c, 0xd7, 0x18, 0xf3, 0x7b, 0x07, 0x0f, 0xd8, 0x18, 0x10, 0xaf, 0x09, 0x3c, 0x38,
0xfc, 0xed, 0x42, 0x3d, 0x28, 0xf0, 0x1e, 0x1c, 0x83, 0xa7, 0x28, 0x04, 0xfd, 0xcb, 0x01, 0x86,
0xd9, 0x67, 0x17, 0x17, 0x0d, 0x30, 0x02, 0x0e, 0x00, 0xfa, 0x74, 0x05, 0x38, 0x0e, 0x20, 0x0c,
0x3e, 0x76, 0x12, 0x13, 0x38, 0x02, 0x0e, 0x20, 0xa7, 0x05, 0x28, 0x06, 0x68, 0xcd, 0x58, 0x09,
0x12, 0x13, 0xd9, 0xc9, 0xcd, 0xa8, 0x05, 0x30, 0x09, 0xfd, 0xcb, 0x01, 0x46, 0x20, 0x03, 0xaf,
0xd7, 0xd0, 0x0a, 0xe6, 0x3f, 0xcd, 0x59, 0x05, 0xd0, 0x0a, 0x03, 0x87, 0x30, 0xf4, 0xfe, 0x38,
0xd8, 0xaf, 0xfd, 0xcb, 0x01, 0xc6, 0x18, 0xb8, 0xe5, 0x21, 0xba, 0x00, 0x96, 0x23, 0x38, 0x09,
0x3c, 0x47, 0xcb, 0x7e, 0x23, 0x28, 0xfb, 0x10, 0xf9, 0x44, 0x4d, 0xe1, 0x0a, 0xe6, 0x3f, 0xc6,
0xe4, 0xc9, 0xd9, 0xaf, 0xb8, 0x28, 0x09, 0xb9, 0x3e, 0x76, 0x28, 0x02, 0x12, 0x13, 0x10, 0xfc,
0xed, 0x53, 0x10, 0x40, 0xc9, 0xcd, 0xdf, 0x05, 0x2a, 0x10, 0x40, 0xeb, 0xed, 0xb8, 0xc9, 0xf5,
0xe5, 0x21, 0x08, 0x40, 0x3e, 0x05, 0x5e, 0x23, 0x56, 0xe3, 0xa7, 0xed, 0x52, 0x19, 0xe3, 0x30,
0x09, 0xd5, 0xeb, 0x09, 0xeb, 0x72, 0x2b, 0x73, 0x23, 0xd1, 0x23, 0x3d, 0x20, 0xe8, 0xeb, 0xd1,
0xf1, 0xa7, 0xed, 0x52, 0x44, 0x4d, 0x03, 0x19, 0xeb, 0xc9, 0xe5, 0x21, 0x28, 0x40, 0x54, 0x5d,
0xc1, 0xeb, 0xcd, 0x1c, 0x06, 0xd0, 0xc5, 0xcd, 0x24, 0x06, 0x18, 0xf4, 0x7e, 0xb8, 0xc0, 0x23,
0x7e, 0x2b, 0xb9, 0xc9, 0xe5, 0x7e, 0x87, 0xfa, 0x35, 0x06, 0x38, 0x17, 0x23, 0x3e, 0x76, 0x23,
0x47, 0xed, 0xb1, 0x18, 0x1d, 0x01, 0x02, 0x00, 0x38, 0x01, 0x48, 0x17, 0x17, 0x23, 0x7e, 0x30,
0xfb, 0x18, 0x0c, 0xe6, 0x40, 0x3e, 0x01, 0x28, 0xe6, 0x23, 0x7e, 0x23, 0x06, 0x00, 0x4f, 0x03,
0x09, 0x09, 0xd1, 0xa7, 0xed, 0x52, 0x44, 0x4d, 0x19, 0xeb, 0xc9, 0x2a, 0x0a, 0x40, 0x2b, 0xed,
0x5b, 0x08, 0x40, 0xcd, 0x53, 0x06, 0xc5, 0x78, 0x2f, 0x47, 0x79, 0x2f, 0x4f, 0x03, 0xcd, 0xdf,
0x05, 0xeb, 0xe1, 0x19, 0xd5, 0xed, 0xb0, 0xe1, 0xc9, 0x7e, 0xd9, 0x21, 0x00, 0x00, 0x44, 0xd6,
0x1c, 0x38, 0x17, 0xfe, 0x0a, 0x30, 0x13, 0x4f, 0x3e, 0x0d, 0xbc, 0x30, 0x01, 0x67, 0x54, 0x5d,
0x29, 0x29, 0x19, 0x29, 0x09, 0xd9, 0xdf, 0xd9, 0x18, 0xe5, 0x7c, 0x22, 0x22, 0x40, 0xd9, 0x17,
0xc9, 0xd5, 0xe5, 0x60, 0x69, 0xcb, 0x78, 0x28, 0x0c, 0x3e, 0x12, 0xcd, 0x59, 0x05, 0x30, 0x2d,
0x21, 0x01, 0x00, 0xed, 0x42, 0x1e, 0xff, 0x01, 0xf0, 0xd8, 0xcd, 0x4c, 0x05, 0x18, 0x09, 0xd5,
0x56, 0x23, 0x5e, 0xe5, 0xeb, 0x1e, 0x00, 0x37, 0x01, 0x18, 0xfc, 0xdc, 0x4c, 0x05, 0x01, 0x9c,
0xff, 0xdc, 0x4c, 0x05, 0x0e, 0xf6, 0xdc, 0x4c, 0x05, 0x7d, 0xdc, 0x56, 0x05, 0xe1, 0xd1, 0xc9,
0xfd, 0xcb, 0x01, 0x7e, 0xe1, 0xc8, 0xd9, 0xed, 0x5b, 0x0e, 0x40, 0xed, 0x4b, 0x24, 0x40, 0xd9,
0xe9, 0xfd, 0xcb, 0x00, 0x7e, 0xc8, 0xcd, 0xe0, 0x06, 0x2a, 0x22, 0x40, 0xfd, 0xcb, 0x01, 0x76,
0x28, 0x0a, 0x44, 0x4d, 0xcd, 0xa1, 0x06, 0x18, 0x1a, 0xd7, 0x30, 0x19, 0x7e, 0x23, 0xfe, 0x01,
0x28, 0x28, 0xcb, 0x77, 0x28, 0xf3, 0xcd, 0x84, 0x05, 0x18, 0xef, 0xcd, 0xe0, 0x06, 0x3e, 0x76,
0xcd, 0x59, 0x05, 0x38, 0x15, 0xcf, 0x04, 0xcd, 0xe0, 0x06, 0xfd, 0xcb, 0x01, 0xc6, 0xaf, 0xd7,
0x30, 0xf3, 0xd9, 0x79, 0xd9, 0x3d, 0xe6, 0x07, 0x20, 0xf4, 0xd9, 0xeb, 0xed, 0x43, 0x24, 0x40,
0x22, 0x0e, 0x40, 0x22, 0x10, 0x40, 0xc9, 0x2a, 0x0c, 0x40, 0x36, 0x76, 0x23, 0x01, 0x21, 0x17,
0x18, 0xea, 0x4f, 0x2c, 0x64, 0x3f, 0x59, 0x2b, 0x17, 0x4b, 0x36, 0x4e, 0x10, 0x5e, 0x5d, 0x2a,
0x2d, 0x5a, 0x61, 0x3b, 0x18, 0x4d, 0x0d, 0x11, 0x44, 0x4c, 0x31, 0x50, 0x01, 0xe3, 0x02, 0x06,
0x00, 0x34, 0x09, 0x06, 0xd5, 0x05, 0xb9, 0x08, 0x06, 0x00, 0x43, 0x09, 0x00, 0x2e, 0x09, 0x00,
0x65, 0x09, 0x04, 0xe3, 0x06, 0xd6, 0x05, 0xc4, 0x08, 0x04, 0x00, 0xf9, 0x08, 0x05, 0x72, 0x09,
0x01, 0x00, 0x9a, 0x09, 0x04, 0xda, 0x06, 0xd9, 0x00, 0xd3, 0x0c, 0x05, 0x4a, 0x08, 0x03, 0x3d,
0x09, 0x03, 0x56, 0x02, 0x06, 0xd8, 0x05, 0xd1, 0x09, 0x03, 0x23, 0x09, 0x00, 0x06, 0x02, 0x00,
0xb6, 0x01, 0x00, 0x30, 0x09, 0x00, 0x5b, 0x06, 0x00, 0x47, 0x07, 0x05, 0x44, 0x08, 0x2b, 0x22,
0x26, 0x40, 0x21, 0x00, 0x00, 0x00, 0x22, 0x15, 0x40, 0x21, 0x19, 0x40, 0xcb, 0x6e, 0x28, 0x07,
0xcb, 0xbe, 0x46, 0xdf, 0xc3, 0x89, 0x08, 0xcb, 0xfe, 0xe7, 0xcd, 0x79, 0x06, 0x38, 0x06, 0xd9,
0x11, 0xf0, 0xd8, 0x19, 0xd9, 0xdc, 0xae, 0x08, 0xcd, 0x1a, 0x00, 0xfd, 0xcb, 0x19, 0xbe, 0x01,
0x00, 0x00, 0xed, 0x43, 0x22, 0x40, 0xfe, 0x76, 0xc8, 0x4f, 0xe7, 0x79, 0xd6, 0xe6, 0x38, 0xe5,
0x4f, 0x21, 0x52, 0x07, 0x09, 0x4e, 0x09, 0x18, 0x03, 0x2a, 0x1a, 0x40, 0x7e, 0x23, 0x22, 0x1a,
0x40, 0x01, 0x09, 0x08, 0xc5, 0x4f, 0x17, 0x38, 0x0d, 0x21, 0x36, 0x08, 0x06, 0x00, 0x09, 0x4e,
0x09, 0xe5, 0xcd, 0x1a, 0x00, 0xc9, 0xcd, 0x1a, 0x00, 0xfe, 0xd5, 0x20, 0x04, 0xfd, 0xcb, 0x19,
0xfe, 0xb9, 0x20, 0x7a, 0xe7, 0xc9, 0x1f, 0x33, 0x4d, 0x17, 0x64, 0x1b, 0x6c, 0xfd, 0xcb, 0x01,
0x7e, 0xc0, 0xc1, 0x7e, 0xfe, 0x76, 0xc4, 0xae, 0x08, 0x7e, 0xfe, 0x76, 0xc8, 0xe7, 0x18, 0xfa,
0xfe, 0x76, 0xc4, 0xa8, 0x08, 0xbf, 0xc1, 0xcc, 0x3d, 0x08, 0xeb, 0x2a, 0x1a, 0x40, 0x4e, 0x23,
0x46, 0xeb, 0xc5, 0xed, 0x4b, 0x22, 0x40, 0x78, 0xb1, 0xc9, 0xcd, 0x14, 0x0d, 0x30, 0x3f, 0xfd,
0xcb, 0x01, 0x7e, 0xca, 0xad, 0x0a, 0x22, 0x20, 0x40, 0xfd, 0xcb, 0x01, 0xbe, 0xcd, 0xad, 0x0a,
0xfd, 0xcb, 0x01, 0xfe, 0xc9, 0xc1, 0xfd, 0x46, 0x01, 0xc5, 0xef, 0xd1, 0x01, 0x3d, 0x0c, 0x3a,
0x01, 0x40, 0xcb, 0x7f, 0x20, 0xcc, 0xaa, 0xe6, 0x40, 0xc4, 0xae, 0x08, 0x18, 0xa5, 0x22, 0x20,
0x40, 0xcd, 0x14, 0x0d, 0x30, 0x08, 0xdf, 0xc9, 0xef, 0xfd, 0xcb, 0x01, 0x76, 0xc0, 0x3a, 0x15,
0x40, 0xfd, 0xb6, 0x16, 0xc0, 0x22, 0x15, 0x40, 0xc9, 0x20, 0x06, 0xfd, 0xcb, 0x01, 0x7e, 0x20,
0x89, 0xc3, 0xe8, 0x07, 0xc5, 0xcd, 0xa8, 0x08, 0xc1, 0xcd, 0x3d, 0x08, 0x2a, 0x22, 0x40, 0xe5,
0xcd, 0x3d, 0x0c, 0xc1, 0xfd, 0xcb, 0x00, 0x7e, 0xc8, 0xc5, 0x2b, 0xcb, 0x7e, 0xcb, 0xfe, 0x23,
0x23, 0x20, 0x07, 0x01, 0x04, 0x00, 0x23, 0xcd, 0xd5, 0x05, 0x23, 0xd1, 0x73, 0x23, 0x72, 0x23,
0xed, 0x5b, 0x02, 0x40, 0x13, 0x73, 0x23, 0x72, 0xc9, 0x2a, 0x20, 0x40, 0xcd, 0x3b, 0x0b, 0xfd,
0xcb, 0x00, 0x7e, 0xc8, 0xeb, 0x2b, 0x2b, 0xcb, 0x7e, 0x28, 0x16, 0x13, 0x23, 0x73, 0x23, 0x72,
0x23, 0x4e, 0x23, 0x46, 0xc5, 0xe3, 0xcd, 0xcd, 0x0d, 0xe1, 0xd8, 0x23, 0x4e, 0x23, 0x46, 0x18,
0x13, 0xcf, 0x00, 0x20, 0x04, 0xed, 0x4b, 0x1e, 0x40, 0xed, 0x43, 0x1c, 0x40, 0xc9, 0xcf, 0x08,
0xed, 0x4b, 0x17, 0x40, 0xed, 0x43, 0x02, 0x40, 0xfd, 0xcb, 0x01, 0xde, 0xc9, 0xcd, 0x34, 0x09,
0xc3, 0x5b, 0x06, 0x2a, 0x02, 0x40, 0x23, 0xe3, 0xe5, 0xcd, 0x34, 0x09, 0x01, 0x06, 0x00, 0x2a,
0x10, 0x40, 0x09, 0xeb, 0x2a, 0x25, 0x40, 0x67, 0x3e, 0x13, 0x85, 0x6f, 0x7c, 0x26, 0x00, 0x19,
0xed, 0x72, 0xd8, 0xcf, 0x03, 0xe1, 0xc1, 0xe5, 0x78, 0xfe, 0x3f, 0x20, 0xc7, 0xe1, 0xc5, 0xe5,
0xcf, 0x06, 0x7e, 0xfe, 0x76, 0xca, 0x1b, 0x07, 0xd6, 0xd8, 0xce, 0x00, 0x28, 0x13, 0xef, 0xcd,
0xf1, 0x06, 0xcd, 0x1a, 0x00, 0xd6, 0xd8, 0xce, 0x00, 0x28, 0x06, 0xcd, 0x3d, 0x08, 0xc3, 0x1b,
0x07, 0xd4, 0x27, 0x07, 0xe7, 0xfe, 0x76, 0xc8, 0x18, 0xde, 0xfd, 0xcb, 0x03, 0x7e, 0x20, 0x2f,
0xe1, 0x21, 0x19, 0x40, 0xcb, 0xee, 0xcb, 0xb6, 0x3a, 0x01, 0x40, 0xe6, 0x40, 0x01, 0x02, 0x00,
0x20, 0x02, 0x0e, 0x04, 0xb6, 0x77, 0xf7, 0xd0, 0x36, 0x76, 0x79, 0x0f, 0x0f, 0x38, 0x03, 0x12,
0x2b, 0x77, 0x2b, 0x36, 0xb0, 0x3a, 0x25, 0x40, 0x3c, 0x32, 0x12, 0x40, 0xc3, 0xf7, 0x02, 0xcf,
0x07, 0xc5, 0xef, 0xd1, 0xcd, 0x3d, 0x08, 0x3a, 0x22, 0x40, 0xfd, 0xcb, 0x00, 0x7e, 0xc8, 0x12,
0xc9, 0x48, 0xc5, 0xcd, 0x18, 0x0d, 0x38, 0x3c, 0x01, 0x00, 0x09, 0x51, 0x59, 0xd6, 0xdc, 0x28,
0x26, 0x1b, 0x06, 0x04, 0x3c, 0x28, 0x20, 0x3c, 0x28, 0x22, 0xfe, 0x27, 0x20, 0x10, 0xfd, 0xcb,
0x01, 0xb6, 0x23, 0x22, 0x22, 0x40, 0xdf, 0x3d, 0x28, 0x17, 0xfe, 0x75, 0x20, 0xf8, 0xcd, 0xae,
0x08, 0xd9, 0x01, 0x00, 0x00, 0x18, 0x35, 0xd5, 0xc5, 0xe7, 0x18, 0xc7, 0xcd, 0x49, 0x00, 0x18,
0x16, 0xdf, 0x18, 0x13, 0xfe, 0x26, 0x38, 0x05, 0xcd, 0xad, 0x0a, 0x18, 0x0a, 0xcd, 0x79, 0x06,
0xdc, 0xae, 0x08, 0xfd, 0xcb, 0x01, 0xf6, 0xcd, 0x1a, 0x00, 0xd9, 0x01, 0x00, 0x00, 0xd6, 0xdc,
0x38, 0x0a, 0xfe, 0x0a, 0x30, 0x06, 0x4f, 0x21, 0xa3, 0x0a, 0x09, 0x46, 0xd1, 0x7a, 0xb8, 0x38,
0x37, 0xa7, 0xd9, 0xc8, 0xd9, 0xfd, 0xcb, 0x01, 0x7e, 0x28, 0x14, 0x16, 0x00, 0x21, 0x1f, 0x0d,
0x19, 0x19, 0x5e, 0x23, 0x56, 0x21, 0x7f, 0x0a, 0xe3, 0xd5, 0xed, 0x5b, 0x22, 0x40, 0xc9, 0x7b,
0xfe, 0x0a, 0x1f, 0x1f, 0xfd, 0xae, 0x01, 0xe6, 0x40, 0xd9, 0xc4, 0xae, 0x08, 0xd9, 0xe1, 0x22,
0x22, 0x40, 0xfd, 0xcb, 0x01, 0xf6, 0x18, 0xc4, 0xd5, 0x79, 0xfd, 0xcb, 0x01, 0x76, 0x20, 0x0a,
0xc6, 0x03, 0x4f, 0xfe, 0x0a, 0xd9, 0xdc, 0xae, 0x08, 0xd9, 0x2a, 0x22, 0x40, 0xe5, 0xc5, 0xd9,
0xc3, 0x19, 0x0a, 0x06, 0x06, 0x08, 0x07, 0x03, 0x02, 0x0a, 0x05, 0x05, 0x05, 0xe5, 0x21, 0x01,
0x40, 0xcb, 0xae, 0xcb, 0xf6, 0xdf, 0xfe, 0x0d, 0xca, 0x30, 0x0b, 0xfe, 0xda, 0xca, 0x2b, 0x0b,
0xcd, 0x18, 0x0d, 0x30, 0x03, 0xdf, 0x18, 0xf8, 0xfe, 0xda, 0x28, 0x0a, 0xfe, 0x0d, 0xc2, 0x35,
0x0b, 0xdf, 0xfe, 0xda, 0x20, 0x51, 0x11, 0xbf, 0x0b, 0xe1, 0xe5, 0x4e, 0xcd, 0x55, 0x00, 0x13,
0x1a, 0xb9, 0x28, 0xf7, 0xe6, 0x3f, 0xb9, 0x20, 0x05, 0x3e, 0xda, 0xbe, 0x28, 0x0b, 0x1a, 0xa7,
0x28, 0x35, 0x13, 0x17, 0x30, 0xf8, 0x13, 0x18, 0xe0, 0xd5, 0xcd, 0x49, 0x00, 0xd1, 0xe3, 0x21,
0x01, 0x40, 0x1a, 0xae, 0xe6, 0x40, 0x20, 0x1f, 0xcb, 0xee, 0xcb, 0xf6, 0x1a, 0xe6, 0x3f, 0xfe,
0x0d, 0x20, 0x02, 0xcb, 0xb6, 0xcb, 0x7e, 0xe1, 0xc8, 0x21, 0xba, 0x0b, 0xe5, 0xeb, 0x23, 0x5e,
0x23, 0x56, 0xd5, 0x2a, 0x22, 0x40, 0xc9, 0xe1, 0xc3, 0xae, 0x08, 0xcd, 0x49, 0x00, 0x18, 0x05,
0xfd, 0xcb, 0x01, 0xb6, 0xdf, 0xe1, 0xfd, 0xcb, 0x01, 0x7e, 0xc8, 0x4e, 0x23, 0x7e, 0xe5, 0xfe,
0xda, 0x20, 0x19, 0xc5, 0xed, 0x4b, 0x26, 0x40, 0xc5, 0xcd, 0x25, 0x00, 0xe1, 0x22, 0x26, 0x40,
0xc1, 0x21, 0x00, 0x40, 0xcb, 0x7e, 0x20, 0x13, 0x36, 0x02, 0xe1, 0xc9, 0xcb, 0xa9, 0xfe, 0x0d,
0x28, 0x09, 0xcb, 0xf1, 0xcd, 0x18, 0x0d, 0x38, 0x02, 0xcb, 0xe9, 0x2a, 0x08, 0x40, 0x7e, 0xe6,
0x7f, 0xca, 0xd0, 0x0c, 0xb9, 0x20, 0x1c, 0x17, 0x87, 0xfa, 0xa4, 0x0b, 0x30, 0x3a, 0xd1, 0xd5,
0xe5, 0x23, 0x1a, 0x13, 0xbe, 0x28, 0xfa, 0xf6, 0x80, 0xbe, 0x20, 0x06, 0x1a, 0xcd, 0x18, 0x0d,
0x30, 0x09, 0xe1, 0xc5, 0xcd, 0x24, 0x06, 0xeb, 0xc1, 0x18, 0xd3, 0xd1, 0xd1, 0x23, 0x5e, 0x23,
0x56, 0xeb, 0x18, 0x16, 0x38, 0xf6, 0xe3, 0x2a, 0x22, 0x40, 0xcb, 0x04, 0xd1, 0x20, 0x0f, 0x13,
0x1a, 0xbd, 0x38, 0x0a, 0x29, 0x19, 0x18, 0xe5, 0xd1, 0x23, 0x22, 0x22, 0x40, 0xc9, 0xcf, 0x02,
0x35, 0x2a, 0x2a, 0xf0, 0x24, 0x0c, 0x28, 0x2d, 0x37, 0xcd, 0x28, 0x0c, 0x28, 0x34, 0x29, 0xaa,
0x24, 0x0c, 0x37, 0x33, 0xe9, 0xed, 0x0b, 0x39, 0x31, 0x8d, 0x38, 0x0c, 0x3a, 0x38, 0xf7, 0xf0,
0x06, 0x38, 0x39, 0x37, 0xcd, 0x10, 0x0c, 0x26, 0x27, 0xf8, 0xf2, 0x0d, 0x00, 0xe5, 0x2a, 0x1c,
0x40, 0x11, 0x4d, 0x00, 0x7c, 0xb5, 0x28, 0x0b, 0xcd, 0x55, 0x0d, 0xa7, 0xed, 0x42, 0x30, 0x05,
0x23, 0x18, 0x02, 0xed, 0x52, 0x22, 0x1c, 0x40, 0xd1, 0xcd, 0x55, 0x0d, 0x60, 0x69, 0x23, 0xc9,
0xd9, 0x01, 0x07, 0x00, 0xf7, 0x30, 0x1d, 0xd5, 0xd9, 0x44, 0x4d, 0xcd, 0xa1, 0x06, 0xd9, 0x3e,
0x01, 0x12, 0xe1, 0xc9, 0x6e, 0x26, 0x00, 0xc9, 0x01, 0x02, 0x00, 0x7d, 0xf7, 0x30, 0x05, 0x36,
0x01, 0x2b, 0x77, 0xc9, 0x21, 0x30, 0x0c, 0xc9, 0x7e, 0x3d, 0xc8, 0x23, 0xc9, 0xfd, 0xcb, 0x00,
0x7e, 0xc8, 0xc5, 0x2a, 0x20, 0x40, 0xcd, 0x3b, 0x0b, 0x21, 0x00, 0x40, 0x7e, 0xfe, 0x02, 0x28,
0xd1, 0x17, 0xfd, 0xcb, 0x01, 0x76, 0x38, 0x3b, 0x36, 0xff, 0x28, 0x47, 0x2a, 0x20, 0x40, 0x01,
0x02, 0x00, 0x03, 0x23, 0x7e, 0xcd, 0x18, 0x0d, 0x38, 0xf8, 0xfe, 0xda, 0x28, 0x62, 0xf7, 0x30,
0xb1, 0xd5, 0x2a, 0x20, 0x40, 0x0b, 0x0b, 0x0b, 0x1b, 0x78, 0xb1, 0x3e, 0x40, 0x28, 0x08, 0xed,
0xb0, 0x7e, 0xf6, 0x80, 0x12, 0x3e, 0x60, 0xe1, 0xcd, 0xb9, 0x0c, 0xeb, 0x1b, 0xe1, 0xeb, 0x72,
0x2b, 0x73, 0xc9, 0x20, 0xf8, 0xe1, 0xcd, 0xa4, 0x0c, 0x2a, 0x22, 0x40, 0x2b, 0xcd, 0x24, 0x06,
0xc3, 0x66, 0x06, 0xe1, 0x3e, 0x01, 0x01, 0x01, 0x00, 0xbe, 0x23, 0x03, 0x20, 0xfb, 0xe5, 0xf7,
0xeb, 0xe1, 0xd0, 0xed, 0xb8, 0xeb, 0x23, 0x3e, 0xa0, 0xeb, 0x2a, 0x20, 0x40, 0xae, 0xeb, 0xf5,
0xcd, 0x0d, 0x0d, 0xf1, 0x2b, 0x77, 0x2a, 0x0c, 0x40, 0x22, 0x0a, 0x40, 0x2b, 0x36, 0x80, 0xc9,
0xe1, 0xcf, 0x01, 0xa0, 0xc2, 0xbe, 0x0b, 0xc5, 0x60, 0x69, 0x23, 0x23, 0x29, 0x44, 0x4d, 0xf7,
0xd2, 0x22, 0x0c, 0x2b, 0x54, 0x5d, 0x1b, 0x0b, 0x0b, 0x36, 0x00, 0xed, 0xb8, 0xc1, 0x71, 0x3e,
0x80, 0x18, 0xc6, 0x2a, 0x0a, 0x40, 0xe5, 0x2a, 0x0c, 0x40, 0x2b, 0xcd, 0xd5, 0x05, 0x23, 0x23,
0xc1, 0xed, 0x43, 0x0a, 0x40, 0xc1, 0xeb, 0x23, 0x37, 0xc9, 0x2a, 0x0c, 0x40, 0xed, 0x5b, 0x0a,
0x40, 0xc3, 0x63, 0x06, 0xfe, 0x26, 0x18, 0x02, 0xfe, 0x1c, 0x3f, 0xd0, 0xfe, 0x40, 0xc9, 0x39,
0x0d, 0x3e, 0x0d, 0x44, 0x0d, 0x90, 0x0d, 0xb5, 0x0d, 0xbc, 0x0d, 0x70, 0x0d, 0xc3, 0x0d, 0xcc,
0x0d, 0xcd, 0x0d, 0xd9, 0x0d, 0xdf, 0x0d, 0xde, 0x0d, 0xa7, 0xed, 0x52, 0x18, 0x03, 0xa7, 0xed,
0x5a, 0xe0, 0xcf, 0x05, 0xcd, 0xed, 0x0d, 0xc5, 0x08, 0xcd, 0x55, 0x0d, 0x20, 0x3f, 0xc1, 0x08,
0x1f, 0xd0, 0xc3, 0xf6, 0x0d, 0x44, 0x4d, 0x3e, 0x10, 0x21, 0x00, 0x00, 0x29, 0xcb, 0x11, 0xcb,
0x10, 0x30, 0x04, 0x19, 0x30, 0x01, 0x03, 0x3d, 0x20, 0xf2, 0x7c, 0xe6, 0x80, 0xb0, 0xb1, 0xc9,
0xcb, 0x7a, 0x20, 0xce, 0xaf, 0xcd, 0xf2, 0x0d, 0xa3, 0x08, 0xc5, 0x42, 0x4b, 0xeb, 0x21, 0x01,
0x00, 0x0b, 0xcb, 0x78, 0x20, 0xc8, 0xc5, 0xcd, 0x55, 0x0d, 0xc1, 0x28, 0xf4, 0xc1, 0x18, 0xb2,
0x7a, 0xb3, 0x28, 0xae, 0xcd, 0xed, 0x0d, 0xc5, 0x1f, 0xed, 0x6a, 0x7c, 0x4d, 0x21, 0x00, 0x00,
0x06, 0x10, 0xed, 0x6a, 0xed, 0x52, 0x30, 0x01, 0x19, 0xcb, 0x11, 0x17, 0x10, 0xf4, 0x67, 0x69,
0x23, 0xc1, 0xd8, 0x18, 0x41, 0x7c, 0xa2, 0x67, 0x7d, 0xa3, 0x6f, 0xc9, 0x7c, 0xb2, 0x67, 0x7d,
0xb3, 0x6f, 0xc9, 0xa7, 0xed, 0x52, 0x21, 0xff, 0xff, 0xc8, 0x23, 0xc9, 0xeb, 0xa7, 0xed, 0x52,
0x7c, 0x17, 0xe2, 0xd6, 0x0d, 0x3f, 0xed, 0x62, 0xc9, 0xcd, 0xe4, 0x0d, 0x18, 0xe8, 0xeb, 0xcd,
0xe4, 0x0d, 0x18, 0xf2, 0x1a, 0xbe, 0xc0, 0x3d, 0xc8, 0x13, 0x23, 0x18, 0xf7, 0xaf, 0xcd, 0xf1,
0x0d, 0xeb, 0xcb, 0x7c, 0xc8, 0x3c, 0x08, 0x7c, 0x2f, 0x67, 0x7d, 0x2f, 0x6f, 0x23, 0x08, 0xc9,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1e, 0x21, 0x78, 0x20, 0x20, 0x7f, 0x00, 0x00, 0x08, 0x3e, 0x48, 0x3e, 0x09, 0x3e, 0x08,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x3e, 0x41, 0x06, 0x08, 0x00, 0x08, 0x00,
0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,
0x00, 0x00, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00,
0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00,
0x00, 0x1c, 0x22, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x0c, 0x14, 0x04, 0x04, 0x04, 0x1e, 0x00,
0x00, 0x3e, 0x41, 0x01, 0x3e, 0x40, 0x7f, 0x00, 0x00, 0x3e, 0x41, 0x06, 0x01, 0x41, 0x3e, 0x00,
0x00, 0x0c, 0x14, 0x24, 0x44, 0x7f, 0x04, 0x00, 0x00, 0x7f, 0x40, 0x7e, 0x01, 0x41, 0x3e, 0x00,
0x00, 0x3e, 0x40, 0x7e, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x7f, 0x01, 0x02, 0x04, 0x08, 0x08, 0x00,
0x00, 0x3e, 0x41, 0x3e, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x3e, 0x41, 0x41, 0x3f, 0x01, 0x3e, 0x00,
0x00, 0x3e, 0x41, 0x41, 0x7f, 0x41, 0x41, 0x00, 0x00, 0x7e, 0x41, 0x7e, 0x41, 0x41, 0x7e, 0x00,
0x00, 0x1e, 0x21, 0x40, 0x40, 0x21, 0x1e, 0x00, 0x00, 0x7c, 0x42, 0x41, 0x41, 0x42, 0x7c, 0x00,
0x00, 0x7f, 0x40, 0x7c, 0x40, 0x40, 0x7f, 0x00, 0x00, 0x7f, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x00,
0x00, 0x1e, 0x21, 0x40, 0x47, 0x21, 0x1e, 0x00, 0x00, 0x41, 0x41, 0x7f, 0x41, 0x41, 0x41, 0x00,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x02, 0x02, 0x02, 0x42, 0x22, 0x1c, 0x00,
0x00, 0x42, 0x44, 0x78, 0x44, 0x42, 0x41, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7f, 0x00,
0x00, 0x41, 0x63, 0x55, 0x49, 0x41, 0x41, 0x00, 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, 0x41, 0x00,
0x00, 0x3e, 0x41, 0x41, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x7e, 0x41, 0x41, 0x7e, 0x40, 0x40, 0x00,
0x00, 0x3e, 0x41, 0x41, 0x49, 0x45, 0x3e, 0x00, 0x00, 0x7e, 0x41, 0x41, 0x7e, 0x44, 0x42, 0x00,
0x00, 0x3e, 0x40, 0x3e, 0x01, 0x41, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x41, 0x41, 0x41, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x41, 0x41, 0x41, 0x22, 0x14, 0x08, 0x00,
0x00, 0x41, 0x41, 0x41, 0x49, 0x55, 0x22, 0x00, 0x00, 0x21, 0x12, 0x0c, 0x0c, 0x12, 0x21, 0x00,
0x00, 0x41, 0x22, 0x1c, 0x08, 0x08, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x04, 0x08, 0x10, 0x7f, 0x00,
};

View file

@ -0,0 +1,764 @@
#include "z80.h"
#include "Arduino.h"
#include "zx80rom.h"
#include "zx81rom.h"
#include "emuapi.h"
#include "common.h"
#include "AY8910.h"
#define MEMORYRAM_SIZE 0x10000
static AY8910 ay;
EXTMEM byte memo[ MEMORYRAM_SIZE ];
byte * mem = &memo[0];
unsigned char *memptr[64];
int memattr[64];
int unexpanded=0;
int nmigen=0,hsyncgen=0,vsync=0;
int vsync_visuals=0;
int signal_int_flag=0;
int interrupted=0;
int ramsize=32; //32;
/* the keyboard state and other */
static byte keyboard[ 8 ] = {0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff};
static byte * XBuf=0;
int zx80=0;
int autoload=1;
struct { unsigned char R,G,B; } Palette[16] = {
{ 0, 0, 0},
{ 255, 255, 255}
};
const byte map_qw[8][5] = {
{25, 6,27,29,224},// vcxz<caps shift=Lshift>
{10, 9, 7,22, 4}, // gfdsa
{23,21, 8,26,20}, // trewq
{34,33,32,31,30}, // 54321
{35,36,37,38,39}, // 67890
{28,24,12,18,19}, // yuiop
{11,13,14,15,40}, // hjkl<enter>
{ 5,17,16,1,44}, // bnm. <space>
};
static char tapename[64]={0};
static const int kBuf[]={13,25,19,25,19,40}; //,21,40}; // LOAD "" (J shift p shift p, R ENTER)
static const int tBuf[]={2,0,2,0,2,2};//200!,2,2};
static int kcount=0;
static int timeout=100;
unsigned int in(int h, int l)
{
int ts=0; /* additional cycles*256 */
int tapezeromask=0x80; /* = 0x80 if no tape noise (?) */
if(!(l&4)) l=0xfb;
if(!(l&1)) l=0xfe;
switch(l)
{
//case 0xfb:
// return(printer_inout(0,0));
case 0xfe:
/* also disables hsync/vsync if nmi off
* (yes, vsync requires nmi off too, Flight Simulation confirms this)
*/
if(!nmigen)
{
hsyncgen=0;
/* if vsync was on before, record position */
if(!vsync)
vsync_raise();
vsync=1;
}
switch(h)
{
case 0xfe: return(ts|(keyboard[0]^tapezeromask));
case 0xfd: return(ts|(keyboard[1]^tapezeromask));
case 0xfb: return(ts|(keyboard[2]^tapezeromask));
case 0xf7: return(ts|(keyboard[3]^tapezeromask));
case 0xef: return(ts|(keyboard[4]^tapezeromask));
case 0xdf: return(ts|(keyboard[5]^tapezeromask));
case 0xbf: return(ts|(keyboard[6]^tapezeromask));
case 0x7f: return(ts|(keyboard[7]^tapezeromask));
default:
{
int i,mask,retval=0xff;
/* some games (e.g. ZX Galaxians) do smart-arse things
* like zero more than one bit. What we have to do to
* support this is AND together any for which the corresponding
* bit is zero.
*/
for(i=0,mask=1;i<8;i++,mask<<=1)
if(!(h&mask))
retval&=keyboard[i];
return(ts|(retval^tapezeromask));
}
}
break;
}
return(ts|255);
}
unsigned int out(int h,int l,int a)
{
/* either in from fe or out to ff takes one extra cycle;
* experimentation strongly suggests not only that out to
* ff takes one extra, but that *all* outs do.
*/
int ts=1; /* additional cycles */
/* the examples in the manual (using DF/0F) and the
* documented ports (CF/0F) don't match, so decode is
* important for that.
*/
if(!(l&0xf0)) /* not sure how many needed, so assume all 4 */
l=0x0f;
else
if(!(l&0x20)) /* bit 5 low is common to DF and CF */
l=0xdf;
if(!(l&4)) l=0xfb;
if(!(l&2)) l=0xfd;
if(!(l&1)) l=0xfe;
switch(l)
{
case 0x0f: /* Zon X data */
WrData8910(&ay,a);
break;
case 0xdf: /* Zon X reg. select */
WrCtrl8910(&ay,(a &0x0F));
break;
case 0xfb:
return(ts/*|printer_inout(1,a)*/);
case 0xfd:
nmigen=0;
if(vsync)
vsync_lower();
vsync=0;
hsyncgen=1;
break;
case 0xfe:
if(!zx80)
{
nmigen=1;
break;
}
/* falls through, if zx80 */
case 0xff: /* XXX should *any* out turn off vsync? */
/* fill screen gap since last raising of vsync */
if(vsync)
vsync_lower();
vsync=0;
hsyncgen=1;
break;
}
return(ts);
}
void sighandler(int a)
{
signal_int_flag=1;
}
void frame_pause(void)
{
signal_int_flag=0;
if(interrupted<2)
interrupted=1;
}
void do_interrupt()
{
/* being careful here not to screw up any pending reset... */
if(interrupted==1)
interrupted=0;
}
void bitbufBlit(unsigned char * buf)
{
emu_DrawVsync();
memset( XBuf, 1, WIDTH*8 );
buf = buf + (ZX_VID_MARGIN*(ZX_VID_FULLWIDTH/8));
int y,x,i;
byte d;
for(y=0;y<192;y++)
{
byte * src = buf + 4;
for(x=0;x<32;x++)
{
byte * dst=&XBuf[(x<<3)+BORDER];
d = *src++;
for (i=0;i<8;i++)
{
if ( d & 128 )
{
*dst++=0;
}
else
{
*dst++=1;
}
d <<= 1;
}
}
emu_DrawLine(&XBuf[0], WIDTH, HEIGHT, y);
buf += (ZX_VID_FULLWIDTH/8);
}
}
#define INV_KEY 0
const int16_t keyboardAsciiConv[] = // Ascii to Spectrum keys
{
/* 0x00 */ INV_KEY,
/* 0x01 */ INV_KEY,
/* 0x02 */ INV_KEY,
/* 0x03 */ INV_KEY,
/* 0x04 */ INV_KEY,
/* 0x05 */ INV_KEY,
/* 0x06 */ INV_KEY,
/* 0x07 */ INV_KEY,
/* 0x08 */ INV_KEY,
/* 0x09 */ INV_KEY, // tab
/* 0x0A */ 40, // enter
/* 0x0B */ INV_KEY,
/* 0x0C */ INV_KEY,
/* 0x0D */ INV_KEY,
/* 0x0E */ INV_KEY,
/* 0x0F */ INV_KEY,
/* 0x10 */ INV_KEY,
/* 0x11 */ INV_KEY,
/* 0x12 */ INV_KEY,
/* 0x13 */ INV_KEY,
/* 0x14 */ INV_KEY,
/* 0x15 */ INV_KEY,
/* 0x16 */ INV_KEY,
/* 0x17 */ INV_KEY,
/* 0x18 */ INV_KEY,
/* 0x19 */ INV_KEY,
/* 0x1A */ INV_KEY,
/* 0x1B */ INV_KEY, // esc
/* 0x1C */ INV_KEY,
/* 0x1D */ INV_KEY,
/* 0x1E */ INV_KEY,
/* 0x1F */ INV_KEY,
/* 0x20 */ 44, // space
/* 0x21 */ 30+64, // ! exclamation mark
/* 0x22 */ 19+64, // " double quote
/* 0x23 */ INV_KEY, // # dies
/* 0x24 */ 24+64, // $ dollar
/* 0x25 */ INV_KEY, // % percent
/* 0x26 */ INV_KEY, // & ampercent
/* 0x27 */ INV_KEY, // ' singlequote
/* 0x28 */ 12+64, // ( bracket left
/* 0x29 */ 18+64, // ) bracket right
/* 0x2A */ 5+64, // * mult
/* 0x2B */ 14+64, // + plus
/* 0x2C */ 1+64, // , comma
/* 0x2D */ 13+64, // - minus
/* 0x2E */ 1, // . period
/* 0x2F */ 25+64, // / slash
/* 0x30 */ 39, // 0
/* 0x31 */ 30, // 1
/* 0x32 */ 31, // 2
/* 0x33 */ 32, // 3
/* 0x34 */ 33, // 4
/* 0x35 */ 34, // 5
/* 0x36 */ 35, // 6
/* 0x37 */ 36, // 7
/* 0x38 */ 37, // 8
/* 0x39 */ 38, // 9
/* 0x3A */ 29+64, // : colon
/* 0x3B */ 27+64, // ; semi colon
/* 0x3C */ 17+64, // <
/* 0x3D */ 15+64, // = equal
/* 0x3E */ 16+64, // >
/* 0x3F */ 6+64, // ?
/* 0x40 */ INV_KEY, // @
/* 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, // baclslach
/* 0x5D */ INV_KEY, // square braquet close
/* 0x5E */ INV_KEY, // ^ circonflex
/* 0x5F */ INV_KEY, // _ undescore
/* 0x60 */ INV_KEY, // `backquote
/* 0x61 */ 4, // a
/* 0x62 */ 5, // b
/* 0x63 */ 6, // c
/* 0x64 */ 7, // d
/* 0x65 */ 8, // e
/* 0x66 */ 9, // f
/* 0x67 */ 10, // g
/* 0x68 */ 11, // h
/* 0x69 */ 12, // i
/* 0x6A */ 13, // j
/* 0x6B */ 14, // k
/* 0x6C */ 15, // l
/* 0x6D */ 16, // m
/* 0x6E */ 17, // n
/* 0x6F */ 18, // o
/* 0x70 */ 19, // p
/* 0x71 */ 20, // q
/* 0x72 */ 21, // r
/* 0x73 */ 22, // s
/* 0x74 */ 23, // t
/* 0x75 */ 24, // u
/* 0x76 */ 25, // v
/* 0x77 */ 26, // w
/* 0x78 */ 27, // x
/* 0x79 */ 28, // y
/* 0x7A */ 29, // z
/* 0x7B */ INV_KEY, // curly bracket open
/* 0x7C */ INV_KEY, // or
/* 0x7D */ INV_KEY, // curly bracket close
/* 0x7E */ INV_KEY, // tilt
/* 0x7F */ 39+64, // 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 */ 37+64, // U
/* 0xD8 */ 34+64, // L
/* 0xD9 */ 35+64, // R
/* 0xDA */ 36+64, // D
/* 0xDB */ INV_KEY,
/* 0xDC */ INV_KEY,
/* 0xDD */ INV_KEY,
/* 0xDE */ INV_KEY,
/* 0xDF */ INV_KEY
};
static void updateKeyboard (int asckey)
{
int hk = keyboardAsciiConv[asckey];
memset(keyboard, 0xff, sizeof(keyboard));
{
int shift = hk;
if (hk >=128) hk -= 128;
else if (hk >=64) hk -= 64;
// scan all possibilities
for (int j=0;j<8;j++) {
for(int i=0;i<5;i++){
if ( /*(k == map_qw[j][i]) ||*/ (hk == map_qw[j][i]) ) {
keyboard[j] &= ~ (1<<(4-i));
}
}
}
if (shift >=64) keyboard[0] &= ~ (1<<0); // SHift
//else if (shift >=64) keyboard[7] &= ~ (1<<1); // SHift symboles
}
}
static void handleKeyBuf(void)
{
if (timeout) {
timeout--;
if (timeout==0) {
memset(keyboard, 0xff, sizeof(keyboard));
emu_printf("key up");
}
}
else {
if (!(kcount == (sizeof(kBuf)/sizeof(int)))) {
emu_printf("key dw");
timeout=tBuf[kcount];
int k=kBuf[kcount++];
// scan all possibilities
for (int j=0;j<8;j++) {
for(int i=0;i<5;i++){
if ( (k == map_qw[j][i]) ) {
keyboard[j] &= ~ (1<<(4-i));
}
}
}
if (timeout == 0) {
timeout=tBuf[kcount];
int k=kBuf[kcount++];
// scan all possibilities
for (int j=0;j<8;j++) {
for(int i=0;i<5;i++){
if ( (k == map_qw[j][i]) ) {
keyboard[j] &= ~ (1<<(4-i));
}
}
}
}
}
}
}
/* despite the name, this also works for the ZX80 :-) */
void reset81()
{
interrupted=2; /* will cause a reset */
memset(mem+0x4000,0,0xc000);
}
void load_p(int a)
{
emu_printf("loading...");
/*
int got_ascii_already=0;
if(zx80) {
}
else
{
if(a>=32768)
{
got_ascii_already=1;
emu_printf("got ascii");
}
if(!got_ascii_already)
{
}
}
*/
int size = emu_FileSize(tapename);
int f = emu_FileOpen(tapename, "r+b");
if ( !f ) {
/* the partial snap will crash without a file, so reset */
if(autoload)
reset81(),autoload=0;
return;
}
autoload=0;
emu_FileRead(mem + (zx80?0x4000:0x4009), size, f);
emu_FileClose(f);
if(zx80)
store(0x400b,fetch(0x400b)+1);
}
void save_p(int a)
{
}
void zx81hacks()
{
/* patch save routine */
mem[0x2fc]=0xed; mem[0x2fd]=0xfd;
mem[0x2fe]=0xc3; mem[0x2ff]=0x07; mem[0x300]=0x02;
/* patch load routine */
mem[0x347]=0xeb;
mem[0x348]=0xed; mem[0x349]=0xfc;
mem[0x34a]=0xc3; mem[0x34b]=0x07; mem[0x34c]=0x02;
}
void zx80hacks()
{
/* patch save routine */
mem[0x1b6]=0xed; mem[0x1b7]=0xfd;
mem[0x1b8]=0xc3; mem[0x1b9]=0x83; mem[0x1ba]=0x02;
/* patch load routine */
mem[0x206]=0xed; mem[0x207]=0xfc;
mem[0x208]=0xc3; mem[0x209]=0x83; mem[0x20a]=0x02;
}
static void initmem()
{
int f;
int count;
if(zx80)
{
memset(mem+0x1000,0,0xf000);
}
else
{
memset(mem+0x2000,0,0xe000);
}
/* ROM setup */
count=0;
for(f=0;f<16;f++)
{
memattr[f]=memattr[32+f]=0;
memptr[f]=memptr[32+f]=mem+1024*count;
count++;
if(count>=(zx80?4:8)) count=0;
}
/* RAM setup */
if(unexpanded)
ramsize=1;
count=0;
for(f=16;f<32;f++)
{
memattr[f]=memattr[32+f]=1;
memptr[f]=memptr[32+f]=mem+1024*(16+count);
count++;
if(count>=ramsize) count=0;
}
/* z81's ROM and RAM initialisation code is OK for <= 16K RAM but beyond
* that it requires a little tweaking.
*
* The following diagram shows the ZX81 + 8K ROM. The ZX80 version is
* the same except that each 8K ROM region will contain two copies of
* the 4K ROM.
*
* RAM less than 16K is mirrored throughout the 16K region.
*
* The ROM will only detect up to 8000h when setting RAMTOP, therefore
* having more than 16K RAM will require RAMTOP to be set by the user
* (or user program) to either 49152 for 32K or 65535 for 48/56K.
*
* 1K to 16K 32K 48K 56K Extra Info.
*
* 65535 +----------+ +----------+ +----------+ +----------+
* (FFFFh) | 16K RAM | | 16K RAM | | 16K RAM | | 16K RAM | DFILE can be
* | mirrored | | mirrored | | | | | wholly here.
* | | | | | | | |
* | | | | | | | | BASIC variables
* | | | | | | | | can go here.
* 49152 +----------+ +----------+ +----------+ +----------+
* (C000h) | 8K ROM | | 16K RAM | | 16K RAM | | 16K RAM | BASIC program
* | mirrored | | | | | | | is restricted
* 40960 +----------+ | | | | | | to here.
* (A000h) | 8K ROM | | | | | | |
* | mirrored | | | | | | |
* 32768 +----------+ +----------+ +----------+ +----------+
* (8000h) | 16K RAM | | 16K RAM | | 16K RAM | | 16K RAM | No machine code
* | | | | | | | | beyond here.
* | | | | | | | |
* | | | | | | | | DFILE can be
* | | | | | | | | wholly here.
* 16384 +----------+ +----------+ +----------+ +----------+
* (4000h) | 8K ROM | | 8K ROM | | 8K ROM | | 8K RAM |
* | mirrored | | mirrored | | mirrored | | |
* 8192 +----------+ +----------+ +----------+ +----------+
* (2000h) | 8K ROM | | 8K ROM | | 8K ROM | | 8K ROM |
* | | | | | | | |
* 0 +----------+ +----------+ +----------+ +----------+
*/
switch(ramsize)
{
case 56:
for(f=8;f<16;f++)
{
memattr[f]=1; /* It's now writable */
memptr[f]=mem+1024*f;
}
case 48:
for(f=48;f<64;f++)
{
memattr[f]=1;
memptr[f]=mem+1024*f;
}
case 32:
for(f=32;f<48;f++)
{
memattr[f]=1;
memptr[f]=mem+1024*f;
}
break;
}
if(zx80)
zx80hacks();
else
zx81hacks();
}
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 z81_Input(int click) {
ik = emu_GetPad();
ihk = emu_ReadI2CKeyboard();
}
void z81_Init(void)
{
#if HAS_SND
emu_sndInit();
#endif
if (XBuf == 0) XBuf = (byte *)emu_Malloc(WIDTH*8);
/* Set up the palette */
int J;
for(J=0;J<2;J++)
emu_SetPaletteEntry(Palette[J].R,Palette[J].G,Palette[J].B, J);
//emu_printf("Allocating RAM");
//if (mem == 0) mem = emu_Malloc(MEMORYRAM_SIZE);
Reset8910(&ay,3500000,0);
/* load rom with ghosting at 0x2000 */
int siz=(zx80?4096:8192);
if(zx80)
{
memcpy( mem + 0x0000, zx80rom, siz );
}
else
{
memcpy( mem + 0x0000, zx81rom, siz );
}
memcpy(mem+siz,mem,siz);
if(zx80)
memcpy(mem+siz*2,mem,siz*2);
initmem();
/* reset the keyboard state */
memset( keyboard, 255, sizeof( keyboard ) );
ResetZ80();
}
void z81_Step(void)
{
ExecZ80();
sighandler(0);
int k = ik;
int hk = ihk;
if (iusbhk) hk = iusbhk;
updateKeyboard(hk);
Loop8910(&ay,20);
}
static int endsWith(const char * s, const char * suffix)
{
int retval = 0;
int len = strlen(s);
int slen = strlen(suffix);
if (len > slen ) {
if (!strcmp(&s[len-slen], suffix)) {
retval = 1;
}
}
return (retval);
}
void z81_Start(char * filename)
{
char c;
strncpy(tapename,filename,64);
int f = emu_FileOpen(tapename, "r+b");
if ( f ) {
int fsize = emu_FileRead(&c, 1, f);
if ( fsize == 0) {
autoload = 0;
emu_printf("no autoload");
}
emu_FileClose(f);
}
emu_setKeymap(1);
if ( (endsWith(filename, ".80")) || (endsWith(filename, ".o")) || (endsWith(filename, ".O"))) {
zx80=1;
ramsize=48;
emu_setKeymap(0);
}
else if (endsWith(filename, ".56") ) {
ramsize = 56;
}
}

View file

@ -0,0 +1,4 @@
extern void z81_Init(void);
extern void z81_Step(void);
extern void z81_Start(char * filename);
extern void z81_Input(int click);

View file

@ -0,0 +1,515 @@
const unsigned char PROGMEM zx81rom[] = {
0xd3, 0xfd, 0x01, 0xff, 0x7f, 0xc3, 0xcb, 0x03, 0x2a, 0x16, 0x40, 0x22, 0x18, 0x40, 0x18, 0x46,
0xa7, 0xc2, 0xf1, 0x07, 0xc3, 0xf5, 0x07, 0xff, 0x2a, 0x16, 0x40, 0x7e, 0xa7, 0xc0, 0x00, 0x00,
0xcd, 0x49, 0x00, 0x18, 0xf7, 0xff, 0xff, 0xff, 0xc3, 0x9d, 0x19, 0xf1, 0xd9, 0xe3, 0xd9, 0xc9,
0xc5, 0x2a, 0x14, 0x40, 0xe5, 0xc3, 0x88, 0x14, 0x0d, 0xc2, 0x45, 0x00, 0xe1, 0x05, 0xc8, 0xcb,
0xd9, 0xed, 0x4f, 0xfb, 0xe9, 0xd1, 0xc8, 0x18, 0xf8, 0x2a, 0x16, 0x40, 0x23, 0x22, 0x16, 0x40,
0x7e, 0xfe, 0x7f, 0xc0, 0x18, 0xf6, 0xe1, 0x6e, 0xfd, 0x75, 0x00, 0xed, 0x7b, 0x02, 0x40, 0xcd,
0x07, 0x02, 0xc3, 0xbc, 0x14, 0xff, 0x08, 0x3c, 0xfa, 0x6d, 0x00, 0x28, 0x02, 0x08, 0xc9, 0x08,
0xf5, 0xc5, 0xd5, 0xe5, 0x2a, 0x0c, 0x40, 0xcb, 0xfc, 0x76, 0xd3, 0xfd, 0xdd, 0xe9, 0x3f, 0x3d,
0x28, 0x3b, 0x26, 0x38, 0x29, 0x2b, 0x2c, 0x36, 0x3c, 0x2a, 0x37, 0x39, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x1c, 0x25, 0x24, 0x23, 0x22, 0x35, 0x34, 0x2e, 0x3a, 0x3e, 0x76, 0x31, 0x30, 0x2f, 0x2d,
0x00, 0x1b, 0x32, 0x33, 0x27, 0x0e, 0x19, 0x0f, 0x18, 0xe3, 0xe1, 0xe4, 0xe5, 0xe2, 0xc0, 0xd9,
0xe0, 0xdb, 0xdd, 0x75, 0xda, 0xde, 0xdf, 0x72, 0x77, 0x74, 0x73, 0x70, 0x71, 0x0b, 0x11, 0x10,
0x0d, 0xdc, 0x79, 0x14, 0x15, 0x16, 0xd8, 0x0c, 0x1a, 0x12, 0x13, 0x17, 0xcd, 0xce, 0xc1, 0x78,
0xca, 0xcb, 0xcc, 0xd1, 0xd2, 0xc7, 0xc8, 0xc9, 0xcf, 0x40, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
0x78, 0x78, 0x78, 0x78, 0xc2, 0xd3, 0xc4, 0xd6, 0xd5, 0x78, 0xd4, 0xc6, 0xc5, 0xd0, 0x78, 0x78,
0x42, 0xd7, 0x41, 0x08, 0x0a, 0x09, 0x8a, 0x89, 0x81, 0x82, 0x07, 0x84, 0x06, 0x01, 0x02, 0x87,
0x04, 0x05, 0x77, 0x78, 0x85, 0x03, 0x83, 0x8b, 0x91, 0x90, 0x8d, 0x86, 0x78, 0x92, 0x95, 0x96,
0x88, 0x8f, 0x0b, 0x8b, 0x26, 0xb9, 0x39, 0x26, 0xa7, 0x8f, 0x28, 0x34, 0x29, 0xaa, 0x3b, 0x26,
0xb1, 0x31, 0x2a, 0xb3, 0x38, 0x2e, 0xb3, 0x28, 0x34, 0xb8, 0x39, 0x26, 0xb3, 0x26, 0x38, 0xb3,
0x26, 0x28, 0xb8, 0x26, 0x39, 0xb3, 0x31, 0xb3, 0x2a, 0x3d, 0xb5, 0x2e, 0x33, 0xb9, 0x38, 0x36,
0xb7, 0x38, 0x2c, 0xb3, 0x26, 0x27, 0xb8, 0x35, 0x2a, 0x2a, 0xb0, 0x3a, 0x38, 0xb7, 0x38, 0x39,
0x37, 0x8d, 0x28, 0x2d, 0x37, 0x8d, 0x33, 0x34, 0xb9, 0x17, 0x97, 0x34, 0xb7, 0x26, 0x33, 0xa9,
0x13, 0x94, 0x12, 0x94, 0x13, 0x92, 0x39, 0x2d, 0x2a, 0xb3, 0x39, 0xb4, 0x38, 0x39, 0x2a, 0xb5,
0x31, 0x35, 0x37, 0x2e, 0x33, 0xb9, 0x31, 0x31, 0x2e, 0x38, 0xb9, 0x38, 0x39, 0x34, 0xb5, 0x38,
0x31, 0x34, 0xbc, 0x2b, 0x26, 0x38, 0xb9, 0x33, 0x2a, 0xbc, 0x38, 0x28, 0x37, 0x34, 0x31, 0xb1,
0x28, 0x34, 0x33, 0xb9, 0x29, 0x2e, 0xb2, 0x37, 0x2a, 0xb2, 0x2b, 0x34, 0xb7, 0x2c, 0x34, 0x39,
0xb4, 0x2c, 0x34, 0x38, 0x3a, 0xa7, 0x2e, 0x33, 0x35, 0x3a, 0xb9, 0x31, 0x34, 0x26, 0xa9, 0x31,
0x2e, 0x38, 0xb9, 0x31, 0x2a, 0xb9, 0x35, 0x26, 0x3a, 0x38, 0xaa, 0x33, 0x2a, 0x3d, 0xb9, 0x35,
0x34, 0x30, 0xaa, 0x35, 0x37, 0x2e, 0x33, 0xb9, 0x35, 0x31, 0x34, 0xb9, 0x37, 0x3a, 0xb3, 0x38,
0x26, 0x3b, 0xaa, 0x37, 0x26, 0x33, 0xa9, 0x2e, 0xab, 0x28, 0x31, 0xb8, 0x3a, 0x33, 0x35, 0x31,
0x34, 0xb9, 0x28, 0x31, 0x2a, 0x26, 0xb7, 0x37, 0x2a, 0x39, 0x3a, 0x37, 0xb3, 0x28, 0x34, 0x35,
0xbe, 0x37, 0x33, 0xa9, 0x2e, 0x33, 0x30, 0x2a, 0x3e, 0x8d, 0x35, 0xae, 0x23, 0xeb, 0x2a, 0x14,
0x40, 0x37, 0xed, 0x52, 0xeb, 0xd0, 0xe1, 0x21, 0x3b, 0x40, 0x7e, 0x17, 0xae, 0x17, 0xd0, 0x3e,
0x7f, 0x08, 0x06, 0x11, 0xd3, 0xfe, 0x10, 0xfe, 0xd3, 0xfd, 0x08, 0x17, 0x30, 0x08, 0xcb, 0xfe,
0xf5, 0xc5, 0xd5, 0xe5, 0x18, 0x03, 0xcb, 0xb6, 0xc9, 0x2a, 0x34, 0x40, 0x2b, 0x3e, 0x7f, 0xa4,
0xb5, 0x7c, 0x20, 0x03, 0x17, 0x18, 0x02, 0x46, 0x37, 0x67, 0x22, 0x34, 0x40, 0xd0, 0xcd, 0xbb,
0x02, 0xed, 0x4b, 0x25, 0x40, 0x22, 0x25, 0x40, 0x78, 0xc6, 0x02, 0xed, 0x42, 0x3a, 0x27, 0x40,
0xb4, 0xb5, 0x58, 0x06, 0x0b, 0x21, 0x3b, 0x40, 0xcb, 0x86, 0x20, 0x08, 0xcb, 0x7e, 0xcb, 0xc6,
0xc8, 0x05, 0x00, 0x37, 0x21, 0x27, 0x40, 0x3f, 0xcb, 0x10, 0x10, 0xfe, 0x46, 0x7b, 0xfe, 0xfe,
0x9f, 0x06, 0x1f, 0xb6, 0xa0, 0x1f, 0x77, 0xd3, 0xff, 0x2a, 0x0c, 0x40, 0xcb, 0xfc, 0xcd, 0x92,
0x02, 0xed, 0x5f, 0x01, 0x01, 0x19, 0x3e, 0xf5, 0xcd, 0xb5, 0x02, 0x2b, 0xcd, 0x92, 0x02, 0xc3,
0x29, 0x02, 0xdd, 0xe1, 0xfd, 0x4e, 0x28, 0xfd, 0xcb, 0x3b, 0x7e, 0x28, 0x0c, 0x79, 0xed, 0x44,
0x3c, 0x08, 0xd3, 0xfe, 0xe1, 0xd1, 0xc1, 0xf1, 0xc9, 0x3e, 0xfc, 0x06, 0x01, 0xcd, 0xb5, 0x02,
0x2b, 0xe3, 0xe3, 0xdd, 0xe9, 0xed, 0x4f, 0x3e, 0xdd, 0xfb, 0xe9, 0x21, 0xff, 0xff, 0x01, 0xfe,
0xfe, 0xed, 0x78, 0xf6, 0x01, 0xf6, 0xe0, 0x57, 0x2f, 0xfe, 0x01, 0x9f, 0xb0, 0xa5, 0x6f, 0x7c,
0xa2, 0x67, 0xcb, 0x00, 0xed, 0x78, 0x38, 0xed, 0x1f, 0xcb, 0x14, 0x17, 0x17, 0x17, 0x9f, 0xe6,
0x18, 0xc6, 0x1f, 0x32, 0x28, 0x40, 0xc9, 0xfd, 0xcb, 0x3b, 0x7e, 0xc8, 0x76, 0xd3, 0xfd, 0xfd,
0xcb, 0x3b, 0xbe, 0xc9, 0xcf, 0x0e, 0xcd, 0xa8, 0x03, 0x38, 0xf9, 0xeb, 0x11, 0xcb, 0x12, 0xcd,
0x46, 0x0f, 0x30, 0x2e, 0x10, 0xfe, 0x1b, 0x7a, 0xb3, 0x20, 0xf4, 0xcd, 0x1e, 0x03, 0xcb, 0x7e,
0x23, 0x28, 0xf8, 0x21, 0x09, 0x40, 0xcd, 0x1e, 0x03, 0xcd, 0xfc, 0x01, 0x18, 0xf8, 0x5e, 0x37,
0xcb, 0x13, 0xc8, 0x9f, 0xe6, 0x05, 0xc6, 0x04, 0x4f, 0xd3, 0xff, 0x06, 0x23, 0x10, 0xfe, 0xcd,
0x46, 0x0f, 0x30, 0x72, 0x06, 0x1e, 0x10, 0xfe, 0x0d, 0x20, 0xee, 0xa7, 0x10, 0xfd, 0x18, 0xe0,
0xcd, 0xa8, 0x03, 0xcb, 0x12, 0xcb, 0x0a, 0xcd, 0x4c, 0x03, 0x18, 0xfb, 0x0e, 0x01, 0x06, 0x00,
0x3e, 0x7f, 0xdb, 0xfe, 0xd3, 0xff, 0x1f, 0x30, 0x49, 0x17, 0x17, 0x38, 0x28, 0x10, 0xf1, 0xf1,
0xba, 0xd2, 0xe5, 0x03, 0x62, 0x6b, 0xcd, 0x4c, 0x03, 0xcb, 0x7a, 0x79, 0x20, 0x03, 0xbe, 0x20,
0xd6, 0x23, 0x17, 0x30, 0xf1, 0xfd, 0x34, 0x15, 0x21, 0x09, 0x40, 0x50, 0xcd, 0x4c, 0x03, 0x71,
0xcd, 0xfc, 0x01, 0x18, 0xf6, 0xd5, 0x1e, 0x94, 0x06, 0x1a, 0x1d, 0xdb, 0xfe, 0x17, 0xcb, 0x7b,
0x7b, 0x38, 0xf5, 0x10, 0xf5, 0xd1, 0x20, 0x04, 0xfe, 0x56, 0x30, 0xb2, 0x3f, 0xcb, 0x11, 0x30,
0xad, 0xc9, 0x7a, 0xa7, 0x28, 0xbb, 0xcf, 0x0c, 0xcd, 0x55, 0x0f, 0x3a, 0x01, 0x40, 0x87, 0xfa,
0x9a, 0x0d, 0xe1, 0xd0, 0xe5, 0xcd, 0xe7, 0x02, 0xcd, 0xf8, 0x13, 0x62, 0x6b, 0x0d, 0xf8, 0x09,
0xcb, 0xfe, 0xc9, 0xcd, 0xe7, 0x02, 0xed, 0x4b, 0x04, 0x40, 0x0b, 0x60, 0x69, 0x3e, 0x3f, 0x36,
0x02, 0x2b, 0xbc, 0x20, 0xfa, 0xa7, 0xed, 0x42, 0x09, 0x23, 0x30, 0x06, 0x35, 0x28, 0x03, 0x35,
0x28, 0xf3, 0x22, 0x04, 0x40, 0x2a, 0x04, 0x40, 0x2b, 0x36, 0x3e, 0x2b, 0xf9, 0x2b, 0x2b, 0x22,
0x02, 0x40, 0x3e, 0x1e, 0xed, 0x47, 0xed, 0x56, 0xfd, 0x21, 0x00, 0x40, 0xfd, 0x36, 0x3b, 0x40,
0x21, 0x7d, 0x40, 0x22, 0x0c, 0x40, 0x06, 0x19, 0x36, 0x76, 0x23, 0x10, 0xfb, 0x22, 0x10, 0x40,
0xcd, 0x9a, 0x14, 0xcd, 0xad, 0x14, 0xcd, 0x07, 0x02, 0xcd, 0x2a, 0x0a, 0x2a, 0x0a, 0x40, 0xed,
0x5b, 0x23, 0x40, 0xa7, 0xed, 0x52, 0xeb, 0x30, 0x04, 0x19, 0x22, 0x23, 0x40, 0xcd, 0xd8, 0x09,
0x28, 0x01, 0xeb, 0xcd, 0x3e, 0x07, 0xfd, 0x35, 0x1e, 0x20, 0x37, 0x2a, 0x0a, 0x40, 0xcd, 0xd8,
0x09, 0x2a, 0x16, 0x40, 0x37, 0xed, 0x52, 0x21, 0x23, 0x40, 0x30, 0x0b, 0xeb, 0x7e, 0x23, 0xed,
0xa0, 0x12, 0x18, 0xc5, 0x21, 0x0a, 0x40, 0x5e, 0x23, 0x56, 0xe5, 0xeb, 0x23, 0xcd, 0xd8, 0x09,
0xcd, 0xbb, 0x05, 0xe1, 0xfd, 0xcb, 0x2d, 0x6e, 0x20, 0x08, 0x72, 0x2b, 0x73, 0x18, 0xaa, 0xcd,
0xad, 0x14, 0x2a, 0x14, 0x40, 0x7e, 0xfe, 0x7e, 0x20, 0x08, 0x01, 0x06, 0x00, 0xcd, 0x60, 0x0a,
0x18, 0xf3, 0xfe, 0x76, 0x23, 0x20, 0xee, 0xcd, 0x37, 0x05, 0xcd, 0x1f, 0x0a, 0x2a, 0x14, 0x40,
0xfd, 0x36, 0x00, 0xff, 0xcd, 0x66, 0x07, 0xfd, 0xcb, 0x00, 0x7e, 0x20, 0x24, 0x3a, 0x22, 0x40,
0xfe, 0x18, 0x30, 0x1d, 0x3c, 0x32, 0x22, 0x40, 0x47, 0x0e, 0x01, 0xcd, 0x18, 0x09, 0x54, 0x5d,
0x7e, 0x2b, 0xbe, 0x20, 0xfc, 0x23, 0xeb, 0x3a, 0x05, 0x40, 0xfe, 0x4d, 0xdc, 0x5d, 0x0a, 0x18,
0xc9, 0x21, 0x00, 0x00, 0x22, 0x18, 0x40, 0x21, 0x3b, 0x40, 0xcb, 0x7e, 0xcc, 0x29, 0x02, 0xcb,
0x46, 0x28, 0xfc, 0xed, 0x4b, 0x25, 0x40, 0xcd, 0x4b, 0x0f, 0xcd, 0xbd, 0x07, 0x30, 0x93, 0x3a,
0x06, 0x40, 0x3d, 0xfa, 0x08, 0x05, 0x20, 0x0f, 0x32, 0x06, 0x40, 0x1d, 0x7b, 0xd6, 0x27, 0x38,
0x01, 0x5f, 0x21, 0xcc, 0x00, 0x18, 0x0e, 0x7e, 0xfe, 0x76, 0x28, 0x2f, 0xfe, 0x40, 0xcb, 0xff,
0x38, 0x19, 0x21, 0xc7, 0x00, 0x19, 0x18, 0x0d, 0x7e, 0xfd, 0xcb, 0x01, 0x56, 0x20, 0x07, 0xc6,
0xc0, 0xfe, 0xe6, 0x30, 0x01, 0x7e, 0xfe, 0xf0, 0xea, 0x2d, 0x05, 0x5f, 0xcd, 0x37, 0x05, 0x7b,
0xcd, 0x26, 0x05, 0xc3, 0x72, 0x04, 0xcd, 0x9b, 0x09, 0x12, 0xc9, 0x3e, 0x78, 0x5f, 0x21, 0x82,
0x04, 0x19, 0x19, 0x4e, 0x23, 0x46, 0xc5, 0x2a, 0x14, 0x40, 0xfd, 0xcb, 0x2d, 0x6e, 0x20, 0x16,
0xfd, 0xcb, 0x01, 0x96, 0x7e, 0xfe, 0x7f, 0xc8, 0x23, 0xcd, 0xb4, 0x07, 0x28, 0xf6, 0xfe, 0x26,
0x38, 0xf2, 0xfe, 0xde, 0x28, 0xea, 0xfd, 0xcb, 0x01, 0xd6, 0x18, 0xe8, 0x01, 0x01, 0x00, 0xc3,
0x60, 0x0a, 0x9f, 0x05, 0x54, 0x04, 0x76, 0x05, 0x7f, 0x05, 0xaf, 0x05, 0xc4, 0x05, 0x0c, 0x06,
0x8b, 0x05, 0xaf, 0x05, 0xaf, 0x05, 0xcd, 0x93, 0x05, 0x7e, 0x36, 0x7f, 0x23, 0x18, 0x09, 0x23,
0x7e, 0xfe, 0x76, 0x28, 0x18, 0x36, 0x7f, 0x2b, 0x77, 0x18, 0x98, 0xcd, 0x93, 0x05, 0xcd, 0x5c,
0x05, 0x18, 0xf6, 0x2b, 0xed, 0x5b, 0x14, 0x40, 0x1a, 0xfe, 0x7f, 0xc0, 0xd1, 0x18, 0xea, 0x2a,
0x0a, 0x40, 0xcd, 0xd8, 0x09, 0xeb, 0xcd, 0xbb, 0x05, 0x21, 0x0b, 0x40, 0xc3, 0x64, 0x04, 0x7b,
0xe6, 0x07, 0x32, 0x06, 0x40, 0x18, 0xe6, 0xeb, 0x11, 0xc2, 0x04, 0x7e, 0xe6, 0xc0, 0x20, 0xf7,
0x56, 0x23, 0x5e, 0xc9, 0xcd, 0x1f, 0x0a, 0x21, 0x6f, 0x04, 0xe5, 0xfd, 0xcb, 0x2d, 0x6e, 0xc0,
0x2a, 0x14, 0x40, 0x22, 0x0e, 0x40, 0x21, 0x21, 0x18, 0x22, 0x39, 0x40, 0x2a, 0x0a, 0x40, 0xcd,
0xd8, 0x09, 0xcd, 0xbb, 0x05, 0x7a, 0xb3, 0xc8, 0x2b, 0xcd, 0xa5, 0x0a, 0x23, 0x4e, 0x23, 0x46,
0x23, 0xed, 0x5b, 0x0e, 0x40, 0x3e, 0x7f, 0x12, 0x13, 0xe5, 0x21, 0x1d, 0x00, 0x19, 0x09, 0xed,
0x72, 0xe1, 0xd0, 0xed, 0xb0, 0xeb, 0xd1, 0xcd, 0xa6, 0x14, 0x18, 0x91, 0xcd, 0x1f, 0x0a, 0x21,
0x72, 0x04, 0xfd, 0xcb, 0x2d, 0x6e, 0x20, 0x11, 0x2a, 0x14, 0x40, 0x7e, 0xfe, 0xff, 0x28, 0x06,
0xcd, 0xe2, 0x08, 0xcd, 0x2a, 0x0a, 0x21, 0x19, 0x04, 0xe5, 0xcd, 0xba, 0x0c, 0xe1, 0xcd, 0x37,
0x05, 0xcd, 0x5c, 0x05, 0xcd, 0x73, 0x0a, 0x20, 0x15, 0x78, 0xb1, 0xc2, 0xe0, 0x06, 0x0b, 0x0b,
0xed, 0x43, 0x07, 0x40, 0xfd, 0x36, 0x22, 0x02, 0xed, 0x5b, 0x0c, 0x40, 0x18, 0x13, 0xfe, 0x76,
0x28, 0x12, 0xed, 0x4b, 0x30, 0x40, 0xcd, 0x18, 0x09, 0xed, 0x5b, 0x29, 0x40, 0xfd, 0x36, 0x22,
0x02, 0xdf, 0xfe, 0x76, 0xca, 0x13, 0x04, 0xfd, 0x36, 0x01, 0x80, 0xeb, 0x22, 0x29, 0x40, 0xeb,
0xcd, 0x4d, 0x00, 0xcd, 0xc1, 0x0c, 0xfd, 0xcb, 0x01, 0x8e, 0x3e, 0xc0, 0xfd, 0x77, 0x19, 0xcd,
0xa3, 0x14, 0xfd, 0xcb, 0x2d, 0xae, 0xfd, 0xcb, 0x00, 0x7e, 0x28, 0x22, 0x2a, 0x29, 0x40, 0xa6,
0x20, 0x1c, 0x56, 0x23, 0x5e, 0xed, 0x53, 0x07, 0x40, 0x23, 0x5e, 0x23, 0x56, 0x23, 0xeb, 0x19,
0xcd, 0x46, 0x0f, 0x38, 0xc7, 0x21, 0x00, 0x40, 0xcb, 0x7e, 0x28, 0x02, 0x36, 0x0c, 0xfd, 0xcb,
0x38, 0x7e, 0xcc, 0x71, 0x08, 0x01, 0x21, 0x01, 0xcd, 0x18, 0x09, 0x3a, 0x00, 0x40, 0xed, 0x4b,
0x07, 0x40, 0x3c, 0x28, 0x0c, 0xfe, 0x09, 0x20, 0x01, 0x03, 0xed, 0x43, 0x2b, 0x40, 0x20, 0x01,
0x0b, 0xcd, 0xeb, 0x07, 0x3e, 0x18, 0xd7, 0xcd, 0x98, 0x0a, 0xcd, 0xad, 0x14, 0xc3, 0xc1, 0x04,
0xed, 0x43, 0x0a, 0x40, 0x2a, 0x16, 0x40, 0xeb, 0x21, 0x13, 0x04, 0xe5, 0x2a, 0x1a, 0x40, 0xed,
0x52, 0xe5, 0xc5, 0xcd, 0xe7, 0x02, 0xcd, 0x2a, 0x0a, 0xe1, 0xcd, 0xd8, 0x09, 0x20, 0x06, 0xcd,
0xf2, 0x09, 0xcd, 0x60, 0x0a, 0xc1, 0x79, 0x3d, 0xb0, 0xc8, 0xc5, 0x03, 0x03, 0x03, 0x03, 0x2b,
0xcd, 0x9e, 0x09, 0xcd, 0x07, 0x02, 0xc1, 0xc5, 0x13, 0x2a, 0x1a, 0x40, 0x2b, 0xed, 0xb8, 0x2a,
0x0a, 0x40, 0xeb, 0xc1, 0x70, 0x2b, 0x71, 0x2b, 0x73, 0x2b, 0x72, 0xc9, 0xfd, 0xcb, 0x01, 0xce,
0xcd, 0xa7, 0x0e, 0x78, 0xe6, 0x3f, 0x67, 0x69, 0x22, 0x0a, 0x40, 0xcd, 0xd8, 0x09, 0x1e, 0x00,
0xcd, 0x45, 0x07, 0x18, 0xfb, 0xed, 0x4b, 0x0a, 0x40, 0xcd, 0xea, 0x09, 0x16, 0x92, 0x28, 0x05,
0x11, 0x00, 0x00, 0xcb, 0x13, 0xfd, 0x73, 0x1e, 0x7e, 0xfe, 0x40, 0xc1, 0xd0, 0xc5, 0xcd, 0xa5,
0x0a, 0x23, 0x7a, 0xd7, 0x23, 0x23, 0x22, 0x16, 0x40, 0xfd, 0xcb, 0x01, 0xc6, 0xed, 0x4b, 0x18,
0x40, 0x2a, 0x16, 0x40, 0xa7, 0xed, 0x42, 0x20, 0x03, 0x3e, 0xb8, 0xd7, 0x2a, 0x16, 0x40, 0x7e,
0x23, 0xcd, 0xb4, 0x07, 0x22, 0x16, 0x40, 0x28, 0xe4, 0xfe, 0x7f, 0x28, 0x10, 0xfe, 0x76, 0x28,
0x5d, 0xcb, 0x77, 0x28, 0x05, 0xcd, 0x4b, 0x09, 0x18, 0xd3, 0xd7, 0x18, 0xd0, 0x3a, 0x06, 0x40,
0x06, 0xab, 0xa7, 0x20, 0x05, 0x3a, 0x01, 0x40, 0x06, 0xb0, 0x1f, 0x1f, 0xe6, 0x01, 0x80, 0xcd,
0xf5, 0x07, 0x18, 0xb9, 0xfe, 0x7e, 0xc0, 0x23, 0x23, 0x23, 0x23, 0x23, 0xc9, 0x16, 0x00, 0xcb,
0x28, 0x9f, 0xf6, 0x26, 0x2e, 0x05, 0x95, 0x85, 0x37, 0xcb, 0x19, 0x38, 0xfa, 0x0c, 0xc0, 0x48,
0x2d, 0x2e, 0x01, 0x20, 0xf2, 0x21, 0x7d, 0x00, 0x5f, 0x19, 0x37, 0xc9, 0x7b, 0xa7, 0xf8, 0x18,
0x10, 0xaf, 0x09, 0x3c, 0x38, 0xfc, 0xed, 0x42, 0x3d, 0x28, 0xf1, 0x1e, 0x1c, 0x83, 0xa7, 0x28,
0x04, 0xfd, 0xcb, 0x01, 0x86, 0xd9, 0xe5, 0xfd, 0xcb, 0x01, 0x4e, 0x20, 0x05, 0xcd, 0x08, 0x08,
0x18, 0x03, 0xcd, 0x51, 0x08, 0xe1, 0xd9, 0xc9, 0x57, 0xed, 0x4b, 0x39, 0x40, 0x79, 0xfe, 0x21,
0x28, 0x1a, 0x3e, 0x76, 0xba, 0x28, 0x30, 0x2a, 0x0e, 0x40, 0xbe, 0x7a, 0x20, 0x20, 0x0d, 0x20,
0x19, 0x23, 0x22, 0x0e, 0x40, 0x0e, 0x21, 0x05, 0xed, 0x43, 0x39, 0x40, 0x78, 0xfd, 0xbe, 0x22,
0x28, 0x03, 0xa7, 0x20, 0xdd, 0x2e, 0x04, 0xc3, 0x58, 0x00, 0xcd, 0x9b, 0x09, 0xeb, 0x77, 0x23,
0x22, 0x0e, 0x40, 0xfd, 0x35, 0x39, 0xc9, 0x0e, 0x21, 0x05, 0xfd, 0xcb, 0x01, 0xc6, 0xc3, 0x18,
0x09, 0xfe, 0x76, 0x28, 0x1c, 0x4f, 0x3a, 0x38, 0x40, 0xe6, 0x7f, 0xfe, 0x5c, 0x6f, 0x26, 0x40,
0xcc, 0x71, 0x08, 0x71, 0x2c, 0xfd, 0x75, 0x38, 0xc9, 0x16, 0x16, 0x2a, 0x0c, 0x40, 0x23, 0x18,
0x05, 0x16, 0x01, 0x21, 0x3c, 0x40, 0xcd, 0xe7, 0x02, 0xc5, 0xe5, 0xaf, 0x5f, 0xd3, 0xfb, 0xe1,
0xcd, 0x46, 0x0f, 0x38, 0x05, 0x1f, 0xd3, 0xfb, 0xcf, 0x0c, 0xdb, 0xfb, 0x87, 0xfa, 0xde, 0x08,
0x30, 0xee, 0xe5, 0xd5, 0x7a, 0xfe, 0x02, 0x9f, 0xa3, 0x07, 0xa3, 0x57, 0x4e, 0x79, 0x23, 0xfe,
0x76, 0x28, 0x24, 0xe5, 0xcb, 0x27, 0x87, 0x87, 0x26, 0x0f, 0xcb, 0x14, 0x83, 0x6f, 0xcb, 0x11,
0x9f, 0xae, 0x4f, 0x06, 0x08, 0x7a, 0xcb, 0x01, 0x1f, 0x67, 0xdb, 0xfb, 0x1f, 0x30, 0xfb, 0x7c,
0xd3, 0xfb, 0x10, 0xf1, 0xe1, 0x18, 0xd5, 0xdb, 0xfb, 0x1f, 0x30, 0xfb, 0x7a, 0x0f, 0xd3, 0xfb,
0xd1, 0x1c, 0xcb, 0x5b, 0x28, 0xa7, 0xc1, 0x15, 0x20, 0xa0, 0x3e, 0x04, 0xd3, 0xfb, 0xcd, 0x07,
0x02, 0xc1, 0x21, 0x5c, 0x40, 0x36, 0x76, 0x06, 0x20, 0x2b, 0x36, 0x00, 0x10, 0xfb, 0x7d, 0xcb,
0xff, 0x32, 0x38, 0x40, 0xc9, 0x3e, 0x17, 0x90, 0x38, 0x0b, 0xfd, 0xbe, 0x22, 0xda, 0x35, 0x08,
0x3c, 0x47, 0x3e, 0x1f, 0x91, 0xda, 0xad, 0x0e, 0xc6, 0x02, 0x4f, 0xfd, 0xcb, 0x01, 0x4e, 0x28,
0x07, 0x3e, 0x5d, 0x91, 0x32, 0x38, 0x40, 0xc9, 0xed, 0x43, 0x39, 0x40, 0x2a, 0x10, 0x40, 0x51,
0x3e, 0x22, 0x91, 0x4f, 0x3e, 0x76, 0x04, 0x2b, 0xbe, 0x20, 0xfc, 0x10, 0xfa, 0x23, 0xed, 0xb1,
0x2b, 0x22, 0x0e, 0x40, 0x37, 0xe0, 0x15, 0xc8, 0xc5, 0xcd, 0x9e, 0x09, 0xc1, 0x41, 0x62, 0x6b,
0x36, 0x00, 0x2b, 0x10, 0xfb, 0xeb, 0x23, 0x22, 0x0e, 0x40, 0xc9, 0xf5, 0xcd, 0x75, 0x09, 0x30,
0x08, 0xfd, 0xcb, 0x01, 0x46, 0x20, 0x02, 0xaf, 0xd7, 0x0a, 0xe6, 0x3f, 0xd7, 0x0a, 0x03, 0x87,
0x30, 0xf7, 0xc1, 0xcb, 0x78, 0xc8, 0xfe, 0x1a, 0x28, 0x03, 0xfe, 0x38, 0xd8, 0xaf, 0xfd, 0xcb,
0x01, 0xc6, 0xc3, 0xf5, 0x07, 0xe5, 0x21, 0x11, 0x01, 0xcb, 0x7f, 0x28, 0x02, 0xe6, 0x3f, 0xfe,
0x43, 0x30, 0x10, 0x47, 0x04, 0xcb, 0x7e, 0x23, 0x28, 0xfb, 0x10, 0xf9, 0xcb, 0x77, 0x20, 0x02,
0xfe, 0x18, 0x3f, 0x44, 0x4d, 0xe1, 0xd0, 0x0a, 0xc6, 0xe4, 0xc9, 0x01, 0x01, 0x00, 0xe5, 0xcd,
0xc5, 0x0e, 0xe1, 0xcd, 0xad, 0x09, 0x2a, 0x1c, 0x40, 0xeb, 0xed, 0xb8, 0xc9, 0xf5, 0xe5, 0x21,
0x0c, 0x40, 0x3e, 0x09, 0x5e, 0x23, 0x56, 0xe3, 0xa7, 0xed, 0x52, 0x19, 0xe3, 0x30, 0x09, 0xd5,
0xeb, 0x09, 0xeb, 0x72, 0x2b, 0x73, 0x23, 0xd1, 0x23, 0x3d, 0x20, 0xe8, 0xeb, 0xd1, 0xf1, 0xa7,
0xed, 0x52, 0x44, 0x4d, 0x03, 0x19, 0xeb, 0xc9, 0xe5, 0x21, 0x7d, 0x40, 0x54, 0x5d, 0xc1, 0xcd,
0xea, 0x09, 0xd0, 0xc5, 0xcd, 0xf2, 0x09, 0xeb, 0x18, 0xf4, 0x7e, 0xb8, 0xc0, 0x23, 0x7e, 0x2b,
0xb9, 0xc9, 0xe5, 0x7e, 0xfe, 0x40, 0x38, 0x17, 0xcb, 0x6f, 0x28, 0x14, 0x87, 0xfa, 0x01, 0x0a,
0x3f, 0x01, 0x05, 0x00, 0x30, 0x02, 0x0e, 0x11, 0x17, 0x23, 0x7e, 0x30, 0xfb, 0x18, 0x06, 0x23,
0x23, 0x4e, 0x23, 0x46, 0x23, 0x09, 0xd1, 0xa7, 0xed, 0x52, 0x44, 0x4d, 0x19, 0xeb, 0xc9, 0xfd,
0x46, 0x22, 0xc5, 0xcd, 0x2c, 0x0a, 0xc1, 0x05, 0x18, 0x02, 0x06, 0x18, 0xfd, 0xcb, 0x01, 0x8e,
0x0e, 0x21, 0xc5, 0xcd, 0x18, 0x09, 0xc1, 0x3a, 0x05, 0x40, 0xfe, 0x4d, 0x38, 0x14, 0xfd, 0xcb,
0x3a, 0xfe, 0xaf, 0xcd, 0xf5, 0x07, 0x2a, 0x39, 0x40, 0x7d, 0xb4, 0xe6, 0x7e, 0x20, 0xf3, 0xc3,
0x18, 0x09, 0x54, 0x5d, 0x2b, 0x48, 0x06, 0x00, 0xed, 0xb0, 0x2a, 0x10, 0x40, 0xcd, 0x17, 0x0a,
0xc5, 0x78, 0x2f, 0x47, 0x79, 0x2f, 0x4f, 0x03, 0xcd, 0xad, 0x09, 0xeb, 0xe1, 0x19, 0xd5, 0xed,
0xb0, 0xe1, 0xc9, 0x2a, 0x14, 0x40, 0xcd, 0x4d, 0x00, 0xdf, 0xfd, 0xcb, 0x2d, 0x6e, 0xc0, 0x21,
0x5d, 0x40, 0x22, 0x1c, 0x40, 0xcd, 0x48, 0x15, 0xcd, 0x8a, 0x15, 0x38, 0x04, 0x21, 0xf0, 0xd8,
0x09, 0xda, 0x9a, 0x0d, 0xbf, 0xc3, 0xbc, 0x14, 0xd5, 0xe5, 0xaf, 0xcb, 0x78, 0x20, 0x20, 0x60,
0x69, 0x1e, 0xff, 0x18, 0x08, 0xd5, 0x56, 0x23, 0x5e, 0xe5, 0xeb, 0x1e, 0x00, 0x01, 0x18, 0xfc,
0xcd, 0xe1, 0x07, 0x01, 0x9c, 0xff, 0xcd, 0xe1, 0x07, 0x0e, 0xf6, 0xcd, 0xe1, 0x07, 0x7d, 0xcd,
0xeb, 0x07, 0xe1, 0xd1, 0xc9, 0xcd, 0xa6, 0x0d, 0xe1, 0xc8, 0xe9, 0xfd, 0xcb, 0x01, 0xce, 0x7e,
0xfe, 0x76, 0xca, 0x84, 0x0b, 0xd6, 0x1a, 0xce, 0x00, 0x28, 0x69, 0xfe, 0xa7, 0x20, 0x1b, 0xe7,
0xcd, 0x92, 0x0d, 0xfe, 0x1a, 0xc2, 0x9a, 0x0d, 0xe7, 0xcd, 0x92, 0x0d, 0xcd, 0x4e, 0x0b, 0xef,
0x01, 0x34, 0xcd, 0xf5, 0x0b, 0xcd, 0xf5, 0x08, 0x18, 0x3d, 0xfe, 0xa8, 0x20, 0x33, 0xe7, 0xcd,
0x92, 0x0d, 0xcd, 0x4e, 0x0b, 0xcd, 0x02, 0x0c, 0xc2, 0xad, 0x0e, 0xe6, 0x1f, 0x4f, 0xfd, 0xcb,
0x01, 0x4e, 0x28, 0x0a, 0xfd, 0x96, 0x38, 0xcb, 0xff, 0xc6, 0x3c, 0xd4, 0x71, 0x08, 0xfd, 0x86,
0x39, 0xfe, 0x21, 0x3a, 0x3a, 0x40, 0xde, 0x01, 0xcd, 0xfa, 0x08, 0xfd, 0xcb, 0x01, 0xc6, 0x18,
0x06, 0xcd, 0x55, 0x0f, 0xcd, 0x55, 0x0b, 0xdf, 0xd6, 0x1a, 0xce, 0x00, 0x28, 0x06, 0xcd, 0x1d,
0x0d, 0xc3, 0x84, 0x0b, 0xd4, 0x8b, 0x0b, 0xe7, 0xfe, 0x76, 0xc8, 0xc3, 0xd5, 0x0a, 0xcd, 0xa6,
0x0d, 0xc0, 0xe1, 0x18, 0xe2, 0xcd, 0xc5, 0x0a, 0xfd, 0xcb, 0x01, 0x76, 0xcc, 0xf8, 0x13, 0x28,
0x0a, 0xc3, 0xdb, 0x15, 0x3e, 0x0b, 0xd7, 0xed, 0x5b, 0x18, 0x40, 0x78, 0xb1, 0x0b, 0xc8, 0x1a,
0x13, 0xed, 0x53, 0x18, 0x40, 0xcb, 0x77, 0x28, 0xed, 0xfe, 0xc0, 0x28, 0xe7, 0xc5, 0xcd, 0x4b,
0x09, 0xc1, 0x18, 0xe3, 0xcd, 0xc5, 0x0a, 0x3e, 0x76, 0xd7, 0xc9, 0xcd, 0xc5, 0x0a, 0xfd, 0xcb,
0x01, 0xc6, 0xaf, 0xd7, 0xed, 0x4b, 0x39, 0x40, 0x79, 0xfd, 0xcb, 0x01, 0x4e, 0x28, 0x05, 0x3e,
0x5d, 0xfd, 0x96, 0x38, 0x0e, 0x11, 0xb9, 0x30, 0x02, 0x0e, 0x01, 0xcd, 0x0b, 0x09, 0xc9, 0xcd,
0xf5, 0x0b, 0xed, 0x43, 0x36, 0x40, 0x3e, 0x2b, 0x90, 0xda, 0xad, 0x0e, 0x47, 0x3e, 0x01, 0xcb,
0x28, 0x30, 0x02, 0x3e, 0x04, 0xcb, 0x29, 0x30, 0x01, 0x07, 0xf5, 0xcd, 0xf5, 0x08, 0x7e, 0x07,
0xfe, 0x10, 0x30, 0x06, 0x0f, 0x30, 0x02, 0xee, 0x8f, 0x47, 0x11, 0x9e, 0x0c, 0x3a, 0x30, 0x40,
0x93, 0xfa, 0xe9, 0x0b, 0xf1, 0x2f, 0xa0, 0x18, 0x02, 0xf1, 0xb0, 0xfe, 0x08, 0x38, 0x02, 0xee,
0x8f, 0xd9, 0xd7, 0xd9, 0xc9, 0xcd, 0x02, 0x0c, 0x47, 0xc5, 0xcd, 0x02, 0x0c, 0x59, 0xc1, 0x51,
0x4f, 0xc9, 0xcd, 0xcd, 0x15, 0xda, 0xad, 0x0e, 0x0e, 0x01, 0xc8, 0x0e, 0xff, 0xc9, 0xfd, 0x46,
0x22, 0x0e, 0x21, 0xcd, 0x18, 0x09, 0xcd, 0x9b, 0x09, 0x7e, 0x12, 0xfd, 0x34, 0x3a, 0x2a, 0x0c,
0x40, 0x23, 0x54, 0x5d, 0xed, 0xb1, 0xc3, 0x5d, 0x0a, 0x8b, 0x8d, 0x2d, 0x7f, 0x81, 0x49, 0x75,
0x5f, 0x40, 0x42, 0x2b, 0x17, 0x1f, 0x37, 0x52, 0x45, 0x0f, 0x6d, 0x2b, 0x44, 0x2d, 0x5a, 0x3b,
0x4c, 0x45, 0x0d, 0x52, 0x5a, 0x4d, 0x15, 0x6a, 0x01, 0x14, 0x02, 0x06, 0x00, 0x81, 0x0e, 0x06,
0xde, 0x05, 0xab, 0x0d, 0x06, 0x00, 0xb5, 0x0e, 0x00, 0xdc, 0x0c, 0x00, 0xd8, 0x0e, 0x04, 0x14,
0x06, 0xdf, 0x06, 0x05, 0xb9, 0x0d, 0x04, 0x00, 0x2e, 0x0e, 0x05, 0xcf, 0x0a, 0x01, 0x00, 0xe9,
0x0e, 0x05, 0x09, 0x14, 0x05, 0x6a, 0x0d, 0x00, 0xc3, 0x03, 0x03, 0xaf, 0x0e, 0x03, 0x30, 0x07,
0x06, 0x1a, 0x06, 0x00, 0x92, 0x0e, 0x03, 0x6c, 0x0e, 0x05, 0x40, 0x03, 0x05, 0xf6, 0x02, 0x00,
0x7c, 0x0e, 0x00, 0x9a, 0x14, 0x00, 0x2a, 0x0a, 0x06, 0x1a, 0x06, 0x00, 0xaf, 0x0b, 0x06, 0x1a,
0x06, 0x00, 0xaf, 0x0b, 0x00, 0x0e, 0x0c, 0x06, 0x00, 0x32, 0x0f, 0x00, 0x2b, 0x0f, 0x00, 0x23,
0x0f, 0x00, 0x69, 0x08, 0x05, 0xcb, 0x0a, 0x03, 0x2c, 0x07, 0xfd, 0x36, 0x01, 0x01, 0xcd, 0x73,
0x0a, 0xcd, 0xbc, 0x14, 0x21, 0x00, 0x40, 0x36, 0xff, 0x21, 0x2d, 0x40, 0xcb, 0x6e, 0x28, 0x0e,
0xfe, 0xe3, 0x7e, 0xc2, 0x6f, 0x0d, 0xcd, 0xa6, 0x0d, 0xc8, 0xcf, 0x0c, 0xcf, 0x08, 0xdf, 0x06,
0x00, 0xfe, 0x76, 0xc8, 0x4f, 0xe7, 0x79, 0xd6, 0xe1, 0x38, 0x3b, 0x4f, 0x21, 0x29, 0x0c, 0x09,
0x4e, 0x09, 0x18, 0x03, 0x2a, 0x30, 0x40, 0x7e, 0x23, 0x22, 0x30, 0x40, 0x01, 0xf4, 0x0c, 0xc5,
0x4f, 0xfe, 0x0b, 0x30, 0x0b, 0x21, 0x16, 0x0d, 0x06, 0x00, 0x09, 0x4e, 0x09, 0xe5, 0xdf, 0xc9,
0xdf, 0xb9, 0x20, 0x12, 0xe7, 0xc9, 0x17, 0x25, 0x53, 0x0f, 0x6b, 0x13, 0x76, 0xcd, 0xa6, 0x0d,
0xc0, 0xc1, 0x7e, 0xfe, 0x76, 0xc8, 0x18, 0x72, 0xfe, 0x76, 0xcd, 0x9c, 0x0d, 0xbf, 0xc1, 0xcc,
0x1d, 0x0d, 0xeb, 0x2a, 0x30, 0x40, 0x4e, 0x23, 0x46, 0xeb, 0xc5, 0xc9, 0xcd, 0x1c, 0x11, 0xfd,
0x36, 0x2d, 0x00, 0x30, 0x08, 0xfd, 0xcb, 0x2d, 0xce, 0x20, 0x18, 0xcf, 0x01, 0xcc, 0xa7, 0x11,
0xfd, 0xcb, 0x01, 0x76, 0x20, 0x0d, 0xaf, 0xcd, 0xa6, 0x0d, 0xc4, 0xf8, 0x13, 0x21, 0x2d, 0x40,
0xb6, 0x77, 0xeb, 0xed, 0x43, 0x2e, 0x40, 0x22, 0x12, 0x40, 0xc9, 0xc1, 0x3a, 0x01, 0x40, 0xf5,
0xcd, 0x55, 0x0f, 0xf1, 0x01, 0x21, 0x13, 0xfd, 0x56, 0x01, 0xaa, 0xe6, 0x40, 0x20, 0x1b, 0xcb,
0x7a, 0x20, 0xb7, 0x18, 0x9d, 0xcd, 0x1c, 0x11, 0xf5, 0x79, 0xf6, 0x9f, 0x3c, 0x20, 0x0b, 0xf1,
0x18, 0xad, 0xcd, 0x55, 0x0f, 0xfd, 0xcb, 0x01, 0x76, 0xc0, 0xcf, 0x0b, 0x20, 0xf4, 0xcd, 0xa6,
0x0d, 0xc8, 0xef, 0xa0, 0x34, 0xc9, 0xfd, 0xcb, 0x01, 0x7e, 0xc9, 0xcd, 0xa6, 0x0d, 0x28, 0x06,
0xef, 0x02, 0x34, 0x1a, 0xa7, 0xc8, 0xc3, 0xde, 0x0c, 0xfe, 0xe0, 0x20, 0x09, 0xe7, 0xcd, 0x92,
0x0d, 0xcd, 0x1d, 0x0d, 0x18, 0x06, 0xcd, 0x1d, 0x0d, 0xef, 0xa1, 0x34, 0xef, 0xc0, 0x02, 0x01,
0xe0, 0x01, 0x34, 0xcd, 0x21, 0x13, 0x22, 0x1f, 0x40, 0x2b, 0x7e, 0xcb, 0xfe, 0x01, 0x06, 0x00,
0x09, 0x07, 0x38, 0x06, 0xcb, 0x21, 0xcd, 0x9e, 0x09, 0x23, 0xe5, 0xef, 0x02, 0x02, 0x34, 0xe1,
0xeb, 0x0e, 0x0a, 0xed, 0xb0, 0x2a, 0x07, 0x40, 0xeb, 0x13, 0x73, 0x23, 0x72, 0xcd, 0x5a, 0x0e,
0xd0, 0xfd, 0xcb, 0x08, 0x7e, 0xc0, 0xfd, 0x46, 0x2e, 0xcb, 0xb0, 0x2a, 0x29, 0x40, 0x7e, 0xe6,
0xc0, 0x20, 0x17, 0xc5, 0xcd, 0xf2, 0x09, 0xc1, 0x23, 0x23, 0x23, 0xcd, 0x4c, 0x00, 0xdf, 0xfe,
0xf3, 0xeb, 0x20, 0xea, 0xeb, 0xe7, 0xeb, 0xb8, 0x20, 0xe4, 0x22, 0x29, 0x40, 0xc9, 0xfd, 0xcb,
0x2d, 0x4e, 0xc2, 0x4b, 0x0d, 0x2a, 0x12, 0x40, 0xcb, 0x7e, 0x28, 0x1c, 0x23, 0x22, 0x1f, 0x40,
0xef, 0xe0, 0xe2, 0x0f, 0xc0, 0x02, 0x34, 0xcd, 0x5a, 0x0e, 0xd8, 0x2a, 0x1f, 0x40, 0x11, 0x0f,
0x00, 0x19, 0x5e, 0x23, 0x56, 0xeb, 0x18, 0x2e, 0xcf, 0x00, 0xef, 0xe1, 0xe0, 0xe2, 0x32, 0x00,
0x02, 0x01, 0x03, 0x33, 0x00, 0x04, 0x34, 0xa7, 0xc9, 0x34, 0x37, 0xc9, 0xcd, 0xa7, 0x0e, 0x78,
0xb1, 0x20, 0x04, 0xed, 0x4b, 0x34, 0x40, 0xed, 0x43, 0x32, 0x40, 0xc9, 0x2a, 0x2b, 0x40, 0x18,
0x05, 0xcd, 0xa7, 0x0e, 0x60, 0x69, 0x7c, 0xfe, 0xf0, 0x30, 0x22, 0xcd, 0xd8, 0x09, 0x22, 0x29,
0x40, 0xc9, 0xcd, 0xcd, 0x15, 0x38, 0x16, 0x28, 0x02, 0xed, 0x44, 0xf5, 0xcd, 0xa7, 0x0e, 0xf1,
0xfd, 0xcb, 0x00, 0x7e, 0xc8, 0x02, 0xc9, 0xcd, 0x8a, 0x15, 0x38, 0x01, 0xc8, 0xcf, 0x0a, 0xcd,
0x81, 0x0e, 0xc3, 0x9a, 0x14, 0x2a, 0x07, 0x40, 0x23, 0xe3, 0xe5, 0xed, 0x73, 0x02, 0x40, 0xcd,
0x81, 0x0e, 0x01, 0x06, 0x00, 0x2a, 0x1c, 0x40, 0x09, 0x38, 0x08, 0xeb, 0x21, 0x24, 0x00, 0x19,
0xed, 0x72, 0xd8, 0x2e, 0x03, 0xc3, 0x58, 0x00, 0xe1, 0xe3, 0x7c, 0xfe, 0x3e, 0x28, 0x06, 0xed,
0x73, 0x02, 0x40, 0x18, 0xa1, 0xe3, 0xe5, 0xcf, 0x06, 0xfd, 0xcb, 0x08, 0x7e, 0x20, 0x32, 0xcd,
0xa3, 0x14, 0x21, 0x2d, 0x40, 0xcb, 0xee, 0xcb, 0xb6, 0x3a, 0x01, 0x40, 0xe6, 0x40, 0x01, 0x02,
0x00, 0x20, 0x02, 0x0e, 0x04, 0xb6, 0x77, 0xf7, 0x36, 0x76, 0x79, 0x0f, 0x0f, 0x38, 0x05, 0x3e,
0x0b, 0x12, 0x2b, 0x77, 0x2b, 0x36, 0x7f, 0x2a, 0x39, 0x40, 0x22, 0x30, 0x40, 0xe1, 0xc3, 0x72,
0x04, 0xcf, 0x07, 0xcd, 0xe7, 0x02, 0xfd, 0xcb, 0x3b, 0xb6, 0xc9, 0xfd, 0xcb, 0x3b, 0xf6, 0xc3,
0x07, 0x02, 0xcd, 0xa7, 0x0e, 0xcd, 0xe7, 0x02, 0x60, 0x69, 0xcd, 0x2d, 0x02, 0xfd, 0x36, 0x35,
0xff, 0xcd, 0x07, 0x02, 0x18, 0x05, 0x3e, 0x7f, 0xdb, 0xfe, 0x1f, 0xfd, 0xcb, 0x3b, 0x86, 0x3e,
0xff, 0x32, 0x27, 0x40, 0xc9, 0xdf, 0x06, 0x00, 0xc5, 0xfe, 0x40, 0x20, 0x2f, 0xcd, 0xa6, 0x0d,
0x28, 0x28, 0xed, 0x4b, 0x32, 0x40, 0xcd, 0x20, 0x15, 0xef, 0xa1, 0x0f, 0x30, 0x37, 0x16, 0x04,
0x30, 0x80, 0x41, 0x00, 0x00, 0x80, 0x2e, 0x02, 0xa1, 0x03, 0x2d, 0x34, 0xcd, 0x8a, 0x15, 0xed,
0x43, 0x32, 0x40, 0x7e, 0xa7, 0x28, 0x03, 0xd6, 0x10, 0x77, 0x18, 0x0d, 0xfe, 0x42, 0x20, 0x0d,
0xcd, 0xa6, 0x0d, 0x28, 0x04, 0xef, 0xa3, 0x34, 0x34, 0xe7, 0xc3, 0x83, 0x10, 0xfe, 0x41, 0x20,
0x11, 0xcd, 0xbb, 0x02, 0x44, 0x4d, 0x51, 0x14, 0xc4, 0xbd, 0x07, 0x7a, 0x8a, 0x42, 0x4f, 0xeb,
0x18, 0x3b, 0xcd, 0xd2, 0x14, 0x38, 0x6e, 0xfe, 0x1b, 0xca, 0x47, 0x10, 0x01, 0xd8, 0x09, 0xfe,
0x16, 0x28, 0x5d, 0xfe, 0x10, 0x20, 0x0f, 0xcd, 0x49, 0x00, 0xcd, 0x55, 0x0f, 0xfe, 0x11, 0x20,
0x2e, 0xcd, 0x49, 0x00, 0x18, 0x22, 0xfe, 0x0b, 0x20, 0x28, 0xcd, 0x49, 0x00, 0xe5, 0x18, 0x03,
0xcd, 0x49, 0x00, 0xfe, 0x0b, 0x20, 0x14, 0xd1, 0xa7, 0xed, 0x52, 0x44, 0x4d, 0x21, 0x01, 0x40,
0xcb, 0xb6, 0xcb, 0x7e, 0xc4, 0xc3, 0x12, 0xe7, 0xc3, 0x88, 0x10, 0xfe, 0x76, 0x20, 0xe1, 0xc3,
0x9a, 0x0d, 0xd6, 0xc4, 0x38, 0xf9, 0x01, 0xec, 0x04, 0xfe, 0x13, 0x28, 0x13, 0x30, 0xf0, 0x06,
0x10, 0xc6, 0xd9, 0x4f, 0xfe, 0xdc, 0x30, 0x02, 0xcb, 0xb1, 0xfe, 0xea, 0x38, 0x02, 0xcb, 0xb9,
0xc5, 0xe7, 0xc3, 0x59, 0x0f, 0xfe, 0x26, 0x38, 0x1e, 0xcd, 0x1c, 0x11, 0xda, 0x4b, 0x0d, 0xcc,
0xa7, 0x11, 0x3a, 0x01, 0x40, 0xfe, 0xc0, 0x38, 0x4e, 0x23, 0xed, 0x5b, 0x1c, 0x40, 0xcd, 0xf6,
0x19, 0xeb, 0x22, 0x1c, 0x40, 0x18, 0x40, 0xcd, 0xa6, 0x0d, 0x20, 0x23, 0xcd, 0xd9, 0x14, 0xdf,
0x01, 0x06, 0x00, 0xcd, 0x9e, 0x09, 0x23, 0x36, 0x7e, 0x23, 0xeb, 0x2a, 0x1c, 0x40, 0x0e, 0x05,
0xa7, 0xed, 0x42, 0x22, 0x1c, 0x40, 0xed, 0xb0, 0xeb, 0x2b, 0xcd, 0x4c, 0x00, 0x18, 0x14, 0xe7,
0xfe, 0x7e, 0x20, 0xfb, 0x23, 0xed, 0x5b, 0x1c, 0x40, 0xcd, 0xf6, 0x19, 0xed, 0x53, 0x1c, 0x40,
0x22, 0x16, 0x40, 0xfd, 0xcb, 0x01, 0xf6, 0xdf, 0xfe, 0x10, 0x20, 0x0c, 0xfd, 0xcb, 0x01, 0x76,
0x20, 0x2a, 0xcd, 0x63, 0x12, 0xe7, 0x18, 0xf0, 0x01, 0xc3, 0x00, 0xfe, 0x12, 0x38, 0x1d, 0xd6,
0x16, 0x30, 0x04, 0xc6, 0x0d, 0x18, 0x0e, 0xfe, 0x03, 0x38, 0x0a, 0xd6, 0xc2, 0x38, 0x0d, 0xfe,
0x06, 0x30, 0x09, 0xc6, 0x03, 0x81, 0x4f, 0x21, 0x4c, 0x10, 0x09, 0x46, 0xd1, 0x7a, 0xb8, 0x38,
0x2c, 0xa7, 0xca, 0x18, 0x00, 0xc5, 0xd5, 0xcd, 0xa6, 0x0d, 0x28, 0x09, 0x7b, 0xe6, 0x3f, 0x47,
0xef, 0x37, 0x34, 0x18, 0x09, 0x7b, 0xfd, 0xae, 0x01, 0xe6, 0x40, 0xc2, 0x9a, 0x0d, 0xd1, 0x21,
0x01, 0x40, 0xcb, 0xf6, 0xcb, 0x7b, 0x20, 0x02, 0xcb, 0xb6, 0xc1, 0x18, 0xcf, 0xd5, 0x79, 0xfd,
0xcb, 0x01, 0x76, 0x20, 0x15, 0xe6, 0x3f, 0xc6, 0x08, 0x4f, 0xfe, 0x10, 0x20, 0x04, 0xcb, 0xf1,
0x18, 0x08, 0x38, 0xd7, 0xfe, 0x17, 0x28, 0x02, 0xcb, 0xf9, 0xc5, 0xe7, 0xc3, 0x59, 0x0f, 0x06,
0x08, 0x08, 0x0a, 0x02, 0x03, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0xfd, 0xcb, 0x01, 0xf6,
0xdf, 0xcd, 0xce, 0x14, 0xd2, 0x9a, 0x0d, 0xe5, 0x4f, 0xe7, 0xe5, 0xcb, 0xa9, 0xfe, 0x10, 0x28,
0x17, 0xcb, 0xf1, 0xfe, 0x0d, 0x28, 0x0c, 0xcb, 0xe9, 0xcd, 0xd2, 0x14, 0x30, 0x0a, 0xcb, 0xb1,
0xe7, 0x18, 0xf6, 0xe7, 0xfd, 0xcb, 0x01, 0xb6, 0x41, 0xcd, 0xa6, 0x0d, 0x20, 0x08, 0x79, 0xe6,
0xe0, 0xcb, 0xff, 0x4f, 0x18, 0x34, 0x2a, 0x10, 0x40, 0x7e, 0xe6, 0x7f, 0x28, 0x2a, 0xb9, 0x20,
0x1f, 0x17, 0x87, 0xf2, 0x95, 0x11, 0x38, 0x2d, 0xd1, 0xd5, 0xe5, 0x23, 0x1a, 0x13, 0xa7, 0x28,
0xfb, 0xbe, 0x28, 0xf7, 0xf6, 0x80, 0xbe, 0x20, 0x06, 0x1a, 0xcd, 0xd2, 0x14, 0x30, 0x15, 0xe1,
0xc5, 0xcd, 0xf2, 0x09, 0xeb, 0xc1, 0x18, 0xd1, 0xcb, 0xf8, 0xd1, 0xdf, 0xfe, 0x10, 0x28, 0x09,
0xcb, 0xe8, 0x18, 0x0d, 0xd1, 0xd1, 0xd1, 0xe5, 0xdf, 0xcd, 0xd2, 0x14, 0x30, 0x03, 0xe7, 0x18,
0xf8, 0xe1, 0xcb, 0x10, 0xcb, 0x70, 0xc9, 0xaf, 0x47, 0xcb, 0x79, 0x20, 0x4b, 0xcb, 0x7e, 0x20,
0x0e, 0x3c, 0x23, 0x4e, 0x23, 0x46, 0x23, 0xeb, 0xcd, 0xc3, 0x12, 0xdf, 0xc3, 0x5a, 0x12, 0x23,
0x23, 0x23, 0x46, 0xcb, 0x71, 0x28, 0x0a, 0x05, 0x28, 0xe8, 0xeb, 0xdf, 0xfe, 0x10, 0x20, 0x61,
0xeb, 0xeb, 0x18, 0x24, 0xe5, 0xdf, 0xe1, 0xfe, 0x1a, 0x28, 0x20, 0xcb, 0x79, 0x28, 0x52, 0xcb,
0x71, 0x20, 0x06, 0xfe, 0x11, 0x20, 0x3c, 0xe7, 0xc9, 0xfe, 0x11, 0x28, 0x6c, 0xfe, 0xdf, 0x20,
0x32, 0xdf, 0x2b, 0x22, 0x16, 0x40, 0x18, 0x5e, 0x21, 0x00, 0x00, 0xe5, 0xe7, 0xe1, 0x79, 0xfe,
0xc0, 0x20, 0x09, 0xdf, 0xfe, 0x11, 0x28, 0x51, 0xfe, 0xdf, 0x28, 0xe5, 0xc5, 0xe5, 0xcd, 0xff,
0x12, 0xe3, 0xeb, 0xcd, 0xdd, 0x12, 0x38, 0x19, 0x0b, 0xcd, 0x05, 0x13, 0x09, 0xd1, 0xc1, 0x10,
0xb3, 0xcb, 0x79, 0x20, 0x66, 0xe5, 0xcb, 0x71, 0x20, 0x13, 0x42, 0x4b, 0xdf, 0xfe, 0x11, 0x28,
0x02, 0xcf, 0x02, 0xe7, 0xe1, 0x11, 0x05, 0x00, 0xcd, 0x05, 0x13, 0x09, 0xc9, 0xcd, 0xff, 0x12,
0xe3, 0xcd, 0x05, 0x13, 0xc1, 0x09, 0x23, 0x42, 0x4b, 0xeb, 0xcd, 0xc2, 0x12, 0xdf, 0xfe, 0x11,
0x28, 0x07, 0xfe, 0x1a, 0x20, 0xdb, 0xcd, 0x63, 0x12, 0xe7, 0xfe, 0x10, 0x28, 0xf8, 0xfd, 0xcb,
0x01, 0xb6, 0xc9, 0xcd, 0xa6, 0x0d, 0xc4, 0xf8, 0x13, 0xe7, 0xfe, 0x11, 0x28, 0x50, 0xd5, 0xaf,
0xf5, 0xc5, 0x11, 0x01, 0x00, 0xdf, 0xe1, 0xfe, 0xdf, 0x28, 0x17, 0xf1, 0xcd, 0xde, 0x12, 0xf5,
0x50, 0x59, 0xe5, 0xdf, 0xe1, 0xfe, 0xdf, 0x28, 0x09, 0xfe, 0x11, 0xc2, 0x9a, 0x0d, 0x62, 0x6b,
0x18, 0x13, 0xe5, 0xe7, 0xe1, 0xfe, 0x11, 0x28, 0x0c, 0xf1, 0xcd, 0xde, 0x12, 0xf5, 0xdf, 0x60,
0x69, 0xfe, 0x11, 0x20, 0xe6, 0xf1, 0xe3, 0x19, 0x2b, 0xe3, 0xa7, 0xed, 0x52, 0x01, 0x00, 0x00,
0x38, 0x07, 0x23, 0xa7, 0xfa, 0x31, 0x12, 0x44, 0x4d, 0xd1, 0xfd, 0xcb, 0x01, 0xb6, 0xcd, 0xa6,
0x0d, 0xc8, 0xaf, 0xc5, 0xcd, 0xeb, 0x19, 0xc1, 0x2a, 0x1c, 0x40, 0x77, 0x23, 0x73, 0x23, 0x72,
0x23, 0x71, 0x23, 0x70, 0x23, 0x22, 0x1c, 0x40, 0xfd, 0xcb, 0x01, 0xb6, 0xc9, 0xaf, 0xd5, 0xe5,
0xf5, 0xcd, 0x92, 0x0d, 0xf1, 0xcd, 0xa6, 0x0d, 0x28, 0x12, 0xf5, 0xcd, 0xa7, 0x0e, 0xd1, 0x78,
0xb1, 0x37, 0x28, 0x05, 0xe1, 0xe5, 0xa7, 0xed, 0x42, 0x7a, 0xde, 0x00, 0xe1, 0xd1, 0xc9, 0xeb,
0x23, 0x5e, 0x23, 0x56, 0xc9, 0xcd, 0xa6, 0x0d, 0xc8, 0xc5, 0x06, 0x10, 0x7c, 0x4d, 0x21, 0x00,
0x00, 0x29, 0x38, 0x06, 0xcb, 0x11, 0x17, 0x30, 0x04, 0x19, 0xda, 0xd3, 0x0e, 0x10, 0xf2, 0xc1,
0xc9, 0x2a, 0x12, 0x40, 0xfd, 0xcb, 0x2d, 0x4e, 0x28, 0x44, 0x01, 0x05, 0x00, 0x03, 0x23, 0x7e,
0xa7, 0x28, 0xfb, 0xcd, 0xd2, 0x14, 0x38, 0xf5, 0xfe, 0x0d, 0xca, 0xc8, 0x13, 0xf7, 0xd5, 0x2a,
0x12, 0x40, 0x1b, 0x79, 0xd6, 0x06, 0x47, 0x3e, 0x40, 0x28, 0x0e, 0x23, 0x7e, 0xa7, 0x28, 0xfb,
0x13, 0x12, 0x10, 0xf7, 0xf6, 0x80, 0x12, 0x3e, 0x80, 0x2a, 0x12, 0x40, 0xae, 0xe1, 0xcd, 0xe7,
0x13, 0xe5, 0xef, 0x02, 0x34, 0xe1, 0x01, 0x05, 0x00, 0xa7, 0xed, 0x42, 0x18, 0x40, 0xfd, 0xcb,
0x01, 0x76, 0x28, 0x06, 0x11, 0x06, 0x00, 0x19, 0x18, 0xe7, 0x2a, 0x12, 0x40, 0xed, 0x4b, 0x2e,
0x40, 0xfd, 0xcb, 0x2d, 0x46, 0x20, 0x30, 0x78, 0xb1, 0xc8, 0xe5, 0xf7, 0xd5, 0xc5, 0x54, 0x5d,
0x23, 0x36, 0x00, 0xed, 0xb8, 0xe5, 0xcd, 0xf8, 0x13, 0xe1, 0xe3, 0xa7, 0xed, 0x42, 0x09, 0x30,
0x02, 0x44, 0x4d, 0xe3, 0xeb, 0x78, 0xb1, 0x28, 0x02, 0xed, 0xb0, 0xc1, 0xd1, 0xe1, 0xeb, 0x78,
0xb1, 0xc8, 0xd5, 0xed, 0xb0, 0xe1, 0xc9, 0x2b, 0x2b, 0x2b, 0x7e, 0xe5, 0xc5, 0xcd, 0xce, 0x13,
0xc1, 0xe1, 0x03, 0x03, 0x03, 0xc3, 0x60, 0x0a, 0x3e, 0x60, 0x2a, 0x12, 0x40, 0xae, 0xf5, 0xcd,
0xf8, 0x13, 0xeb, 0x09, 0xe5, 0x03, 0x03, 0x03, 0xf7, 0xeb, 0xe1, 0x0b, 0x0b, 0xc5, 0xed, 0xb8,
0xeb, 0xc1, 0x0b, 0x70, 0x2b, 0x71, 0xf1, 0xf5, 0xcd, 0xc7, 0x14, 0xf1, 0x2b, 0x77, 0x2a, 0x1a,
0x40, 0x22, 0x14, 0x40, 0x2b, 0x36, 0x80, 0xc9, 0x2a, 0x1c, 0x40, 0x2b, 0x46, 0x2b, 0x4e, 0x2b,
0x56, 0x2b, 0x5e, 0x2b, 0x7e, 0x22, 0x1c, 0x40, 0xc9, 0xcd, 0x1c, 0x11, 0xc2, 0x9a, 0x0d, 0xcd,
0xa6, 0x0d, 0x20, 0x08, 0xcb, 0xb1, 0xcd, 0xa7, 0x11, 0xcd, 0x1d, 0x0d, 0x38, 0x08, 0xc5, 0xcd,
0xf2, 0x09, 0xcd, 0x60, 0x0a, 0xc1, 0xcb, 0xf9, 0x06, 0x00, 0xc5, 0x21, 0x01, 0x00, 0xcb, 0x71,
0x20, 0x02, 0x2e, 0x05, 0xeb, 0xe7, 0x26, 0x40, 0xcd, 0xdd, 0x12, 0xda, 0x31, 0x12, 0xe1, 0xc5,
0x24, 0xe5, 0x60, 0x69, 0xcd, 0x05, 0x13, 0xeb, 0xdf, 0xfe, 0x1a, 0x28, 0xe8, 0xfe, 0x11, 0x20,
0xbb, 0xe7, 0xc1, 0x79, 0x68, 0x26, 0x00, 0x23, 0x23, 0x29, 0x19, 0xda, 0xd3, 0x0e, 0xd5, 0xc5,
0xe5, 0x44, 0x4d, 0x2a, 0x14, 0x40, 0x2b, 0xcd, 0x9e, 0x09, 0x23, 0x77, 0xc1, 0x0b, 0x0b, 0x0b,
0x23, 0x71, 0x23, 0x70, 0xf1, 0x23, 0x77, 0x62, 0x6b, 0x1b, 0x36, 0x00, 0xc1, 0xed, 0xb8, 0xc1,
0x70, 0x2b, 0x71, 0x2b, 0x3d, 0x20, 0xf8, 0xc9, 0x2a, 0x1a, 0x40, 0x2b, 0xcd, 0x9e, 0x09, 0x23,
0x23, 0xc1, 0xed, 0x43, 0x14, 0x40, 0xc1, 0xeb, 0x23, 0xc9, 0x2a, 0x10, 0x40, 0x36, 0x80, 0x23,
0x22, 0x14, 0x40, 0x2a, 0x14, 0x40, 0x22, 0x1a, 0x40, 0x22, 0x1c, 0x40, 0xc9, 0x2a, 0x14, 0x40,
0x36, 0x7f, 0x23, 0x36, 0x76, 0x23, 0xfd, 0x36, 0x22, 0x02, 0x18, 0xea, 0x21, 0x5d, 0x40, 0x22,
0x1f, 0x40, 0x2a, 0x1a, 0x40, 0x18, 0xe2, 0xed, 0x5b, 0x14, 0x40, 0xc3, 0x5d, 0x0a, 0xfe, 0x26,
0x18, 0x02, 0xfe, 0x1c, 0x3f, 0xd0, 0xfe, 0x40, 0xc9, 0xcd, 0x48, 0x15, 0xfe, 0x1b, 0x20, 0x15,
0xef, 0xa1, 0xc0, 0x02, 0x34, 0xe7, 0xcd, 0x14, 0x15, 0x38, 0x0a, 0xef, 0xe0, 0xa4, 0x05, 0xc0,
0x04, 0x0f, 0x34, 0x18, 0xf0, 0xfe, 0x2a, 0xc0, 0xfd, 0x36, 0x5d, 0xff, 0xe7, 0xfe, 0x15, 0x28,
0x07, 0xfe, 0x16, 0x20, 0x04, 0xfd, 0x34, 0x5d, 0xe7, 0xcd, 0x48, 0x15, 0xef, 0xe0, 0x00, 0x02,
0x18, 0x38, 0x34, 0xc9, 0xfe, 0x1c, 0xd8, 0xfe, 0x26, 0x3f, 0xd8, 0xd6, 0x1c, 0x4f, 0x06, 0x00,
0xfd, 0x21, 0x00, 0x40, 0xc5, 0xef, 0xa0, 0x34, 0xc1, 0x36, 0x91, 0x78, 0xa7, 0x20, 0x07, 0x77,
0xb1, 0xc8, 0x41, 0x4e, 0x36, 0x89, 0x35, 0xcb, 0x21, 0xcb, 0x10, 0x30, 0xf9, 0xcb, 0x38, 0xcb,
0x19, 0x23, 0x70, 0x23, 0x71, 0x2b, 0x2b, 0xc9, 0xf5, 0xef, 0xa0, 0x34, 0xf1, 0xcd, 0x14, 0x15,
0xd8, 0xef, 0x01, 0xa4, 0x04, 0x0f, 0x34, 0xe7, 0x18, 0xf3, 0xef, 0x2d, 0x32, 0xc0, 0x02, 0x27,
0xa1, 0x03, 0x2d, 0x32, 0x00, 0x22, 0x2d, 0x30, 0x33, 0x40, 0x03, 0x2d, 0x32, 0x00, 0x0c, 0x01,
0x02, 0x01, 0x30, 0x80, 0x48, 0x18, 0x96, 0x80, 0x2f, 0x04, 0x02, 0x01, 0xa4, 0xe0, 0x00, 0x04,
0x04, 0x2f, 0x02, 0x05, 0x01, 0x2f, 0xda, 0x02, 0x34, 0xc9, 0xcd, 0xf8, 0x13, 0xa7, 0x20, 0x05,
0x47, 0x4f, 0xf5, 0x18, 0x31, 0x43, 0x59, 0x4a, 0xd6, 0x91, 0x3f, 0xcb, 0x78, 0xf5, 0xcb, 0xf8,
0x38, 0x24, 0x3c, 0xed, 0x44, 0xfe, 0x08, 0x38, 0x06, 0x59, 0x48, 0x06, 0x00, 0xd6, 0x08, 0xa7,
0x57, 0x7b, 0x07, 0x28, 0x07, 0xcb, 0x38, 0xcb, 0x19, 0x15, 0x20, 0xf9, 0x30, 0x08, 0x03, 0x78,
0xb1, 0x20, 0x03, 0xf1, 0x37, 0xf5, 0xc5, 0xef, 0x34, 0xc1, 0xf1, 0x79, 0xc9, 0xcd, 0x8a, 0x15,
0xd8, 0xf5, 0x05, 0x04, 0x28, 0x03, 0xf1, 0x37, 0xc9, 0xf1, 0xc9, 0xef, 0x2d, 0x32, 0x00, 0x0b,
0x2d, 0x33, 0x00, 0x0d, 0x02, 0x34, 0x3e, 0x1c, 0xd7, 0xc9, 0x27, 0x34, 0x3e, 0x16, 0xd7, 0xef,
0x34, 0x7e, 0xcd, 0x1d, 0x15, 0xef, 0x30, 0x78, 0x00, 0x80, 0x03, 0x30, 0xef, 0x1a, 0x20, 0x9a,
0x85, 0x04, 0x24, 0xc1, 0x30, 0x34, 0x00, 0x03, 0x18, 0x38, 0xa2, 0x0f, 0x24, 0x34, 0x21, 0x6b,
0x40, 0x36, 0x90, 0x06, 0x0a, 0x23, 0xe5, 0xc5, 0xef, 0xa4, 0x2e, 0x01, 0x34, 0xcd, 0xcd, 0x15,
0xf6, 0x90, 0xc1, 0xe1, 0x77, 0x10, 0xee, 0x23, 0x01, 0x08, 0x00, 0xe5, 0x2b, 0x7e, 0xfe, 0x90,
0x28, 0xfa, 0xed, 0x42, 0xe5, 0x7e, 0xc6, 0x6b, 0xf5, 0xf1, 0x23, 0x7e, 0xce, 0x00, 0x27, 0xf5,
0xe6, 0x0f, 0x77, 0xcb, 0xfe, 0x28, 0xf2, 0xf1, 0xe1, 0x06, 0x06, 0x36, 0x80, 0x2b, 0x10, 0xfb,
0xef, 0x02, 0xe1, 0x34, 0xcd, 0xcd, 0x15, 0x28, 0x02, 0xed, 0x44, 0x5f, 0x1c, 0x1c, 0xe1, 0x2b,
0x1d, 0x7e, 0xe6, 0x0f, 0x28, 0xf9, 0x7b, 0xd6, 0x05, 0xfe, 0x08, 0xf2, 0x82, 0x16, 0xfe, 0xf6,
0xfa, 0x82, 0x16, 0xc6, 0x06, 0x28, 0x48, 0xfa, 0xb2, 0x16, 0x47, 0xcd, 0xd0, 0x16, 0x10, 0xfb,
0x18, 0x40, 0x43, 0xcd, 0xd0, 0x16, 0xcd, 0xc2, 0x16, 0x3e, 0x2a, 0xd7, 0x78, 0xa7, 0xf2, 0x98,
0x16, 0xed, 0x44, 0x47, 0x3e, 0x16, 0x18, 0x02, 0x3e, 0x15, 0xd7, 0x78, 0x06, 0xff, 0x04, 0xd6,
0x0a, 0x30, 0xfb, 0xc6, 0x0a, 0x4f, 0x78, 0xa7, 0x28, 0x03, 0xcd, 0xeb, 0x07, 0x79, 0xcd, 0xeb,
0x07, 0xc9, 0xed, 0x44, 0x47, 0x3e, 0x1b, 0xd7, 0x3e, 0x1c, 0xd7, 0x10, 0xfd, 0x18, 0x09, 0x3e,
0x1c, 0xd7, 0x35, 0x34, 0xe8, 0x3e, 0x1b, 0xd7, 0x35, 0x34, 0xe8, 0xcd, 0xd0, 0x16, 0x18, 0xf8,
0x7e, 0xe6, 0x0f, 0xcd, 0xeb, 0x07, 0x2b, 0xc9, 0x7e, 0x36, 0x00, 0xa7, 0xc8, 0x23, 0xcb, 0x7e,
0xcb, 0xfe, 0x2b, 0xc8, 0xc5, 0x01, 0x05, 0x00, 0x09, 0x41, 0x4f, 0x37, 0x2b, 0x7e, 0x2f, 0xce,
0x00, 0x77, 0x10, 0xf8, 0x79, 0xc1, 0xc9, 0xe5, 0xf5, 0x4e, 0x23, 0x46, 0x77, 0x23, 0x79, 0x4e,
0xc5, 0x23, 0x4e, 0x23, 0x46, 0xeb, 0x57, 0x5e, 0xd5, 0x23, 0x56, 0x23, 0x5e, 0xd5, 0xd9, 0xd1,
0xe1, 0xc1, 0xd9, 0x23, 0x56, 0x23, 0x5e, 0xf1, 0xe1, 0xc9, 0xa7, 0xc8, 0xfe, 0x21, 0x30, 0x16,
0xc5, 0x47, 0xd9, 0xcb, 0x2d, 0xcb, 0x1a, 0xcb, 0x1b, 0xd9, 0xcb, 0x1a, 0xcb, 0x1b, 0x10, 0xf2,
0xc1, 0xd0, 0xcd, 0x41, 0x17, 0xc0, 0xd9, 0xaf, 0x2e, 0x00, 0x57, 0x5d, 0xd9, 0x11, 0x00, 0x00,
0xc9, 0x1c, 0xc0, 0x14, 0xc0, 0xd9, 0x1c, 0x20, 0x01, 0x14, 0xd9, 0xc9, 0x1a, 0xa7, 0xc8, 0x13,
0x1a, 0xee, 0x80, 0x12, 0x1b, 0xd9, 0xe5, 0xd9, 0xd5, 0xe5, 0xcd, 0xd8, 0x16, 0x47, 0xeb, 0xcd,
0xd8, 0x16, 0x4f, 0xb8, 0x30, 0x03, 0x78, 0x41, 0xeb, 0xf5, 0x90, 0xcd, 0xf7, 0x16, 0xcd, 0x1a,
0x17, 0xf1, 0xe1, 0x77, 0xe5, 0x68, 0x61, 0x19, 0xd9, 0xeb, 0xed, 0x4a, 0xeb, 0x7c, 0x8d, 0x6f,
0x1f, 0xad, 0xd9, 0xeb, 0xe1, 0x1f, 0x30, 0x08, 0x3e, 0x01, 0xcd, 0x1a, 0x17, 0x34, 0x28, 0x23,
0xd9, 0x7d, 0xe6, 0x80, 0xd9, 0x23, 0x77, 0x2b, 0x28, 0x1f, 0x7b, 0xed, 0x44, 0x3f, 0x5f, 0x7a,
0x2f, 0xce, 0x00, 0x57, 0xd9, 0x7b, 0x2f, 0xce, 0x00, 0x5f, 0x7a, 0x2f, 0xce, 0x00, 0x30, 0x07,
0x1f, 0xd9, 0x34, 0xca, 0x80, 0x18, 0xd9, 0x57, 0xd9, 0xaf, 0x18, 0x6c, 0x37, 0x35, 0x34, 0xc8,
0x23, 0xae, 0xcb, 0xfe, 0x2b, 0xc9, 0xaf, 0xcd, 0xbc, 0x17, 0xd8, 0xd9, 0xe5, 0xd9, 0xd5, 0xeb,
0xcd, 0xbc, 0x17, 0xeb, 0x38, 0x5a, 0xe5, 0xcd, 0xf7, 0x16, 0x78, 0xa7, 0xed, 0x62, 0xd9, 0xe5,
0xed, 0x62, 0xd9, 0x06, 0x21, 0x18, 0x11, 0x30, 0x05, 0x19, 0xd9, 0xed, 0x5a, 0xd9, 0xd9, 0xcb,
0x1c, 0xcb, 0x1d, 0xd9, 0xcb, 0x1c, 0xcb, 0x1d, 0xd9, 0xcb, 0x18, 0xcb, 0x19, 0xd9, 0xcb, 0x19,
0x1f, 0x10, 0xe4, 0xeb, 0xd9, 0xeb, 0xd9, 0xc1, 0xe1, 0x78, 0x81, 0x20, 0x01, 0xa7, 0x3d, 0x3f,
0x17, 0x3f, 0x1f, 0xf2, 0x19, 0x18, 0x30, 0x68, 0xa7, 0x3c, 0x20, 0x08, 0x38, 0x06, 0xd9, 0xcb,
0x7a, 0xd9, 0x20, 0x5c, 0x77, 0xd9, 0x78, 0xd9, 0x30, 0x15, 0x7e, 0xa7, 0x3e, 0x80, 0x28, 0x01,
0xaf, 0xd9, 0xa2, 0xcd, 0x38, 0x17, 0x07, 0x77, 0x38, 0x2e, 0x23, 0x77, 0x2b, 0x18, 0x29, 0x06,
0x20, 0xd9, 0xcb, 0x7a, 0xd9, 0x20, 0x12, 0x07, 0xcb, 0x13, 0xcb, 0x12, 0xd9, 0xcb, 0x13, 0xcb,
0x12, 0xd9, 0x35, 0x28, 0xd7, 0x10, 0xea, 0x18, 0xd7, 0x17, 0x30, 0x0c, 0xcd, 0x41, 0x17, 0x20,
0x07, 0xd9, 0x16, 0x80, 0xd9, 0x34, 0x28, 0x18, 0xe5, 0x23, 0xd9, 0xd5, 0xd9, 0xc1, 0x78, 0x17,
0xcb, 0x16, 0x1f, 0x77, 0x23, 0x71, 0x23, 0x72, 0x23, 0x73, 0xe1, 0xd1, 0xd9, 0xe1, 0xd9, 0xc9,
0xcf, 0x05, 0xeb, 0xaf, 0xcd, 0xbc, 0x17, 0x38, 0xf7, 0xeb, 0xcd, 0xbc, 0x17, 0xd8, 0xd9, 0xe5,
0xd9, 0xd5, 0xe5, 0xcd, 0xf7, 0x16, 0xd9, 0xe5, 0x60, 0x69, 0xd9, 0x61, 0x68, 0xaf, 0x06, 0xdf,
0x18, 0x10, 0x17, 0xcb, 0x11, 0xd9, 0xcb, 0x11, 0xcb, 0x10, 0xd9, 0x29, 0xd9, 0xed, 0x6a, 0xd9,
0x38, 0x10, 0xed, 0x52, 0xd9, 0xed, 0x52, 0xd9, 0x30, 0x0f, 0x19, 0xd9, 0xed, 0x5a, 0xd9, 0xa7,
0x18, 0x08, 0xa7, 0xed, 0x52, 0xd9, 0xed, 0x52, 0xd9, 0x37, 0x04, 0xfa, 0xa2, 0x18, 0xf5, 0x28,
0xe1, 0x5f, 0x51, 0xd9, 0x59, 0x50, 0xf1, 0xcb, 0x18, 0xf1, 0xcb, 0x18, 0xd9, 0xc1, 0xe1, 0x78,
0x91, 0xc3, 0x10, 0x18, 0x7e, 0xfe, 0x81, 0x30, 0x06, 0x36, 0x00, 0x3e, 0x20, 0x18, 0x05, 0xd6,
0xa0, 0xf0, 0xed, 0x44, 0xd5, 0xeb, 0x2b, 0x47, 0xcb, 0x38, 0xcb, 0x38, 0xcb, 0x38, 0x28, 0x05,
0x36, 0x00, 0x2b, 0x10, 0xfb, 0xe6, 0x07, 0x28, 0x09, 0x47, 0x3e, 0xff, 0xcb, 0x27, 0x10, 0xfc,
0xa6, 0x77, 0xeb, 0xd1, 0xc9, 0x00, 0xb0, 0x00, 0x31, 0x00, 0x30, 0x00, 0xf1, 0x49, 0x0f, 0xda,
0xa2, 0x34, 0x20, 0x2f, 0x1c, 0x72, 0x1a, 0xe3, 0x19, 0x4c, 0x17, 0xc6, 0x17, 0x82, 0x18, 0xe2,
0x1d, 0xed, 0x1a, 0xf3, 0x1a, 0x03, 0x1b, 0x03, 0x1b, 0x03, 0x1b, 0x03, 0x1b, 0x03, 0x1b, 0x03,
0x1b, 0x55, 0x17, 0xf8, 0x1a, 0x03, 0x1b, 0x03, 0x1b, 0x03, 0x1b, 0x03, 0x1b, 0x03, 0x1b, 0x03,
0x1b, 0x62, 0x1b, 0xa0, 0x1a, 0x06, 0x1c, 0xa4, 0x1b, 0x11, 0x1c, 0x49, 0x1d, 0x3e, 0x1d, 0x6e,
0x1d, 0xc4, 0x1d, 0xd4, 0x1d, 0x76, 0x1d, 0xa9, 0x1c, 0x5b, 0x1c, 0x46, 0x1c, 0xdb, 0x1d, 0xaf,
0x1a, 0xaa, 0x1a, 0xbe, 0x1a, 0xc5, 0x1a, 0xd5, 0x1b, 0x8f, 0x1b, 0xd5, 0x1a, 0xf6, 0x19, 0x37,
0x1c, 0x23, 0x1c, 0xfc, 0x19, 0x17, 0x1c, 0xdb, 0x1a, 0xce, 0x1a, 0x2b, 0x00, 0x18, 0x1d, 0xe4,
0x18, 0xe4, 0x19, 0x5a, 0x15, 0x7f, 0x1a, 0x51, 0x1a, 0x63, 0x1a, 0x45, 0x1a, 0xcd, 0x85, 0x1b,
0x78, 0x32, 0x1e, 0x40, 0xd9, 0xe3, 0xd9, 0xed, 0x53, 0x1c, 0x40, 0xd9, 0x7e, 0x23, 0xe5, 0xa7,
0xf2, 0xc2, 0x19, 0x57, 0xe6, 0x60, 0x0f, 0x0f, 0x0f, 0x0f, 0xc6, 0x72, 0x6f, 0x7a, 0xe6, 0x1f,
0x18, 0x0e, 0xfe, 0x18, 0x30, 0x08, 0xd9, 0x01, 0xfb, 0xff, 0x54, 0x5d, 0x09, 0xd9, 0x07, 0x6f,
0x11, 0x23, 0x19, 0x26, 0x00, 0x19, 0x5e, 0x23, 0x56, 0x21, 0xa7, 0x19, 0xe3, 0xd5, 0xd9, 0xed,
0x4b, 0x1d, 0x40, 0xc9, 0xf1, 0x3a, 0x1e, 0x40, 0xd9, 0x18, 0xc3, 0xd5, 0xe5, 0x01, 0x05, 0x00,
0xcd, 0xc5, 0x0e, 0xe1, 0xd1, 0xc9, 0xcd, 0xeb, 0x19, 0xed, 0xb0, 0xc9, 0x62, 0x6b, 0xcd, 0xeb,
0x19, 0xd9, 0xe5, 0xd9, 0xe3, 0xc5, 0x7e, 0xe6, 0xc0, 0x07, 0x07, 0x4f, 0x0c, 0x7e, 0xe6, 0x3f,
0x20, 0x02, 0x23, 0x7e, 0xc6, 0x50, 0x12, 0x3e, 0x05, 0x91, 0x23, 0x13, 0x06, 0x00, 0xed, 0xb0,
0xc1, 0xe3, 0xd9, 0xe1, 0xd9, 0x47, 0xaf, 0x05, 0xc8, 0x12, 0x13, 0x18, 0xfa, 0xa7, 0xc8, 0xf5,
0xd5, 0x11, 0x00, 0x00, 0xcd, 0xfe, 0x19, 0xd1, 0xf1, 0x3d, 0x18, 0xf2, 0x4f, 0x07, 0x07, 0x81,
0x4f, 0x06, 0x00, 0x09, 0xc9, 0xd5, 0x2a, 0x1f, 0x40, 0xcd, 0x3c, 0x1a, 0xcd, 0xf6, 0x19, 0xe1,
0xc9, 0x62, 0x6b, 0xd9, 0xe5, 0x21, 0x15, 0x19, 0xd9, 0xcd, 0x2d, 0x1a, 0xcd, 0xfe, 0x19, 0xd9,
0xe1, 0xd9, 0xc9, 0xe5, 0xeb, 0x2a, 0x1f, 0x40, 0xcd, 0x3c, 0x1a, 0xeb, 0xcd, 0xf6, 0x19, 0xeb,
0xe1, 0xc9, 0x06, 0x05, 0x1a, 0x4e, 0xeb, 0x12, 0x71, 0x23, 0x13, 0x10, 0xf7, 0xeb, 0xc9, 0x47,
0xcd, 0xa0, 0x19, 0x2d, 0x0f, 0xc0, 0x02, 0xa0, 0xc2, 0x2d, 0xe0, 0x04, 0xe2, 0xc1, 0x03, 0x34,
0xcd, 0xfc, 0x19, 0xcd, 0xa4, 0x19, 0x0f, 0x01, 0xc2, 0x02, 0x31, 0xee, 0xe1, 0x03, 0x34, 0xc9,
0x7e, 0xa7, 0xc8, 0x23, 0x7e, 0xee, 0x80, 0x77, 0x2b, 0xc9, 0x23, 0xcb, 0xbe, 0x2b, 0xc9, 0x23,
0x7e, 0x2b, 0x35, 0x34, 0x37, 0xc4, 0xe0, 0x1a, 0x23, 0x07, 0xcb, 0x1e, 0x2b, 0xc9, 0xcd, 0xa7,
0x0e, 0x0a, 0xc3, 0x1d, 0x15, 0xcd, 0xa7, 0x0e, 0x21, 0x20, 0x15, 0xe5, 0xc5, 0xc9, 0x7e, 0xa7,
0xc8, 0x3e, 0xff, 0x18, 0x07, 0x7e, 0xed, 0x44, 0x3f, 0x18, 0x05, 0xaf, 0x23, 0xae, 0x2b, 0x07,
0xe5, 0x06, 0x05, 0x36, 0x00, 0x23, 0x10, 0xfb, 0xe1, 0xd0, 0x36, 0x81, 0xc9, 0x1a, 0xa7, 0xc8,
0x37, 0x18, 0xed, 0x1a, 0xa7, 0xc0, 0x18, 0xe8, 0x1a, 0xa7, 0xc0, 0xd5, 0x1b, 0xaf, 0x12, 0x1b,
0x12, 0xd1, 0xc9, 0x78, 0xd6, 0x08, 0xcb, 0x57, 0x20, 0x01, 0x3d, 0x0f, 0x30, 0x08, 0xf5, 0xe5,
0xcd, 0x72, 0x1a, 0xd1, 0xeb, 0xf1, 0xcb, 0x57, 0x20, 0x07, 0x0f, 0xf5, 0xcd, 0x4c, 0x17, 0x18,
0x33, 0x0f, 0xf5, 0xcd, 0xf8, 0x13, 0xd5, 0xc5, 0xcd, 0xf8, 0x13, 0xe1, 0x7c, 0xb5, 0xe3, 0x78,
0x20, 0x0b, 0xb1, 0xc1, 0x28, 0x04, 0xf1, 0x3f, 0x18, 0x16, 0xf1, 0x18, 0x13, 0xb1, 0x28, 0x0d,
0x1a, 0x96, 0x38, 0x09, 0x20, 0xed, 0x0b, 0x13, 0x23, 0xe3, 0x2b, 0x18, 0xdf, 0xc1, 0xf1, 0xa7,
0xf5, 0xef, 0xa0, 0x34, 0xf1, 0xf5, 0xdc, 0xd5, 0x1a, 0xcd, 0xce, 0x1a, 0xf1, 0x0f, 0xd4, 0xd5,
0x1a, 0xc9, 0xcd, 0xf8, 0x13, 0xd5, 0xc5, 0xcd, 0xf8, 0x13, 0xe1, 0xe5, 0xd5, 0xc5, 0x09, 0x44,
0x4d, 0xf7, 0xcd, 0xc3, 0x12, 0xc1, 0xe1, 0x78, 0xb1, 0x28, 0x02, 0xed, 0xb0, 0xc1, 0xe1, 0x78,
0xb1, 0x28, 0x02, 0xed, 0xb0, 0x2a, 0x1c, 0x40, 0x11, 0xfb, 0xff, 0xe5, 0x19, 0xd1, 0xc9, 0xcd,
0xcd, 0x15, 0x38, 0x0e, 0x20, 0x0c, 0xf5, 0x01, 0x01, 0x00, 0xf7, 0xf1, 0x12, 0xcd, 0xc3, 0x12,
0xeb, 0xc9, 0xcf, 0x0a, 0x2a, 0x16, 0x40, 0xe5, 0xcd, 0xf8, 0x13, 0xd5, 0x03, 0xf7, 0xe1, 0xed,
0x53, 0x16, 0x40, 0xd5, 0xed, 0xb0, 0xeb, 0x2b, 0x36, 0x76, 0xfd, 0xcb, 0x01, 0xbe, 0xcd, 0x92,
0x0d, 0xcd, 0x22, 0x0d, 0xe1, 0x22, 0x16, 0x40, 0xfd, 0xcb, 0x01, 0xfe, 0xcd, 0x55, 0x0f, 0xe1,
0x22, 0x16, 0x40, 0x18, 0xb0, 0x01, 0x01, 0x00, 0xf7, 0x36, 0x76, 0x2a, 0x39, 0x40, 0xe5, 0x2e,
0xff, 0x22, 0x39, 0x40, 0x2a, 0x0e, 0x40, 0xe5, 0xed, 0x53, 0x0e, 0x40, 0xd5, 0xcd, 0xdb, 0x15,
0xd1, 0x2a, 0x0e, 0x40, 0xa7, 0xed, 0x52, 0x44, 0x4d, 0xe1, 0x22, 0x0e, 0x40, 0xe1, 0x22, 0x39,
0x40, 0xcd, 0xc3, 0x12, 0xeb, 0xc9, 0xcd, 0xf8, 0x13, 0x78, 0xb1, 0x28, 0x01, 0x1a, 0xc3, 0x1d,
0x15, 0xcd, 0xf8, 0x13, 0xc3, 0x20, 0x15, 0xd9, 0xe5, 0x21, 0x1e, 0x40, 0x35, 0xe1, 0x20, 0x04,
0x23, 0xd9, 0xc9, 0xd9, 0x5e, 0xaf, 0xcb, 0x7b, 0x28, 0x01, 0x2f, 0x57, 0x19, 0xd9, 0xc9, 0x1a,
0xa7, 0x20, 0xf0, 0xd9, 0x23, 0xd9, 0xc9, 0xef, 0xc0, 0x02, 0x2d, 0xe0, 0x05, 0x24, 0xe0, 0x01,
0xc0, 0x04, 0x03, 0xe0, 0x34, 0xc9, 0xef, 0x2d, 0x32, 0x00, 0x04, 0x36, 0x34, 0xc9, 0x2d, 0x36,
0xc0, 0x03, 0xe0, 0x01, 0x2c, 0x00, 0x03, 0xa1, 0x03, 0x34, 0xc9, 0xef, 0x30, 0xf1, 0x38, 0xaa,
0x3b, 0x29, 0x04, 0x2d, 0x24, 0xc3, 0x03, 0x2d, 0x0f, 0xa1, 0x03, 0x88, 0x13, 0x36, 0x58, 0x65,
0x66, 0x9d, 0x78, 0x65, 0x40, 0xa2, 0x60, 0x32, 0xc9, 0xe7, 0x21, 0xf7, 0xaf, 0x24, 0xeb, 0x2f,
0xb0, 0xb0, 0x14, 0xee, 0x7e, 0xbb, 0x94, 0x58, 0xf1, 0x3a, 0x7e, 0xf8, 0xcf, 0xe3, 0x34, 0xcd,
0xcd, 0x15, 0x20, 0x07, 0x38, 0x03, 0x86, 0x30, 0x09, 0xcf, 0x05, 0x38, 0x07, 0x96, 0x30, 0x04,
0xed, 0x44, 0x77, 0xc9, 0xef, 0x02, 0xa0, 0x34, 0xc9, 0xef, 0x2d, 0x33, 0x00, 0x04, 0x34, 0xcf,
0x09, 0xa0, 0x02, 0x34, 0x7e, 0x36, 0x80, 0xcd, 0x1d, 0x15, 0xef, 0x30, 0x38, 0x00, 0x03, 0x01,
0x2d, 0x30, 0xf0, 0x4c, 0xcc, 0xcc, 0xcd, 0x03, 0x33, 0x00, 0x08, 0x01, 0xa1, 0x03, 0x01, 0x34,
0x34, 0xef, 0x01, 0x30, 0xf0, 0x31, 0x72, 0x17, 0xf8, 0x04, 0x01, 0xa2, 0x03, 0xa2, 0x03, 0x2d,
0x30, 0x32, 0x20, 0x04, 0xa2, 0x03, 0x8c, 0x11, 0xac, 0x14, 0x09, 0x56, 0xda, 0xa5, 0x59, 0x30,
0xc5, 0x5c, 0x90, 0xaa, 0x9e, 0x70, 0x6f, 0x61, 0xa1, 0xcb, 0xda, 0x96, 0xa4, 0x31, 0x9f, 0xb4,
0xe7, 0xa0, 0xfe, 0x5c, 0xfc, 0xea, 0x1b, 0x43, 0xca, 0x36, 0xed, 0xa7, 0x9c, 0x7e, 0x5e, 0xf0,
0x6e, 0x23, 0x80, 0x93, 0x04, 0x0f, 0x34, 0xc9, 0xef, 0x30, 0xee, 0x22, 0xf9, 0x83, 0x6e, 0x04,
0x2d, 0xa2, 0x0f, 0x24, 0x03, 0x2d, 0x0f, 0x2d, 0x0f, 0x2d, 0x27, 0xa1, 0x03, 0x2d, 0x33, 0xc0,
0x00, 0x04, 0x02, 0x34, 0xc9, 0xa1, 0x03, 0x01, 0x32, 0x00, 0x02, 0x18, 0x34, 0xc9, 0xef, 0x35,
0x27, 0xa1, 0x03, 0xe0, 0x00, 0x06, 0x18, 0x2f, 0x03, 0xef, 0x35, 0x2d, 0x2d, 0x04, 0x2d, 0x0f,
0xa1, 0x03, 0x86, 0x14, 0xe6, 0x5c, 0x1f, 0x0b, 0xa3, 0x8f, 0x38, 0xee, 0xe9, 0x15, 0x63, 0xbb,
0x23, 0xee, 0x92, 0x0d, 0xcd, 0xed, 0xf1, 0x23, 0x5d, 0x1b, 0xea, 0x04, 0x34, 0xc9, 0xef, 0x2d,
0x1c, 0x01, 0x1d, 0x05, 0x34, 0xc9, 0x7e, 0xfe, 0x81, 0x38, 0x0e, 0xef, 0xa1, 0x18, 0x01, 0x05,
0x2d, 0x32, 0xa3, 0x01, 0x00, 0x06, 0x18, 0x2f, 0x03, 0xef, 0xa0, 0x01, 0x2d, 0x2d, 0x04, 0x2d,
0x0f, 0xa1, 0x03, 0x8c, 0x10, 0xb2, 0x13, 0x0e, 0x55, 0xe4, 0x8d, 0x58, 0x39, 0xbc, 0x5b, 0x98,
0xfd, 0x9e, 0x00, 0x36, 0x75, 0xa0, 0xdb, 0xe8, 0xb4, 0x63, 0x42, 0xc4, 0xe6, 0xb5, 0x09, 0x36,
0xbe, 0xe9, 0x36, 0x73, 0x1b, 0x5d, 0xec, 0xd8, 0xde, 0x63, 0xbe, 0xf0, 0x61, 0xa1, 0xb3, 0x0c,
0x04, 0x0f, 0x34, 0xc9, 0xef, 0x2d, 0x2d, 0x04, 0xa1, 0x03, 0x18, 0x25, 0xa1, 0x0f, 0x05, 0x21,
0x2d, 0x0f, 0x34, 0xc9, 0xef, 0x1f, 0xa3, 0x03, 0x18, 0x34, 0xc9, 0xef, 0x2d, 0x2c, 0x00, 0x1e,
0xa2, 0x34, 0xef, 0x01, 0x2d, 0x2c, 0x00, 0x07, 0x22, 0x04, 0x34, 0xc3, 0x5b, 0x1c, 0x02, 0x2d,
0x2c, 0x00, 0x09, 0xa0, 0x01, 0x33, 0x00, 0x06, 0xa1, 0x01, 0x05, 0x02, 0xa1, 0x34, 0xc9, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0xaa, 0x55,
0xaa, 0x55, 0xaa, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x22, 0x78, 0x20, 0x20, 0x7e, 0x00, 0x00, 0x08, 0x3e, 0x28, 0x3e, 0x0a, 0x3e, 0x08,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x42, 0x04, 0x08, 0x00, 0x08, 0x00,
0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x00, 0x00, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00,
0x00, 0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x04, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x3e, 0x08, 0x14, 0x00,
0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x3c, 0x46, 0x4a, 0x52, 0x62, 0x3c, 0x00, 0x00, 0x18, 0x28, 0x08, 0x08, 0x08, 0x3e, 0x00,
0x00, 0x3c, 0x42, 0x02, 0x3c, 0x40, 0x7e, 0x00, 0x00, 0x3c, 0x42, 0x0c, 0x02, 0x42, 0x3c, 0x00,
0x00, 0x08, 0x18, 0x28, 0x48, 0x7e, 0x08, 0x00, 0x00, 0x7e, 0x40, 0x7c, 0x02, 0x42, 0x3c, 0x00,
0x00, 0x3c, 0x40, 0x7c, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00,
0x00, 0x3c, 0x42, 0x3c, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x3e, 0x02, 0x3c, 0x00,
0x00, 0x3c, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x00, 0x00, 0x7c, 0x42, 0x7c, 0x42, 0x42, 0x7c, 0x00,
0x00, 0x3c, 0x42, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x44, 0x78, 0x00,
0x00, 0x7e, 0x40, 0x7c, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x7e, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x00,
0x00, 0x3c, 0x42, 0x40, 0x4e, 0x42, 0x3c, 0x00, 0x00, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x00,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x02, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00,
0x00, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00,
0x00, 0x42, 0x66, 0x5a, 0x42, 0x42, 0x42, 0x00, 0x00, 0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x00,
0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x00,
0x00, 0x3c, 0x42, 0x42, 0x52, 0x4a, 0x3c, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x7c, 0x44, 0x42, 0x00,
0x00, 0x3c, 0x40, 0x3c, 0x02, 0x42, 0x3c, 0x00, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00,
0x00, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x24, 0x00, 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00,
0x00, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x10, 0x20, 0x7e, 0x00,
};