kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
add coloco and oddysey emu to T-COMPUTER
rodzic
d35010f31d
commit
51e82c6482
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -33,8 +33,8 @@ typedef struct
|
|||
|
||||
|
||||
// global variables
|
||||
EXTMEM static unsigned char MemPool[8*1024*1024];
|
||||
unsigned char * memory=&MemPool[0];
|
||||
//EXTMEM static unsigned char MemPool[8*1024*1024];
|
||||
unsigned char * memory=NULL; //&MemPool[0];
|
||||
int tv_mode = TV_PAL;
|
||||
UBYTE INPUT_key_consol;
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,378 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** Codes.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the main table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
case JR_C: if(R->AF.B.l&C_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
|
||||
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
|
||||
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_P: if(!(R->AF.B.l&S_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_C: if(R->AF.B.l&C_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_M: if(R->AF.B.l&S_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
|
||||
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_C: if(R->AF.B.l&C_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_M: if(R->AF.B.l&S_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
|
||||
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||
case ADD_H: M_ADD(R->HL.B.h);break;
|
||||
case ADD_L: M_ADD(R->HL.B.l);break;
|
||||
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||
case ADD_xHL: I=RdZ80(R->HL.W);M_ADD(I);break;
|
||||
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||
|
||||
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||
case SUB_H: M_SUB(R->HL.B.h);break;
|
||||
case SUB_L: M_SUB(R->HL.B.l);break;
|
||||
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case SUB_xHL: I=RdZ80(R->HL.W);M_SUB(I);break;
|
||||
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||
|
||||
case AND_B: M_AND(R->BC.B.h);break;
|
||||
case AND_C: M_AND(R->BC.B.l);break;
|
||||
case AND_D: M_AND(R->DE.B.h);break;
|
||||
case AND_E: M_AND(R->DE.B.l);break;
|
||||
case AND_H: M_AND(R->HL.B.h);break;
|
||||
case AND_L: M_AND(R->HL.B.l);break;
|
||||
case AND_A: M_AND(R->AF.B.h);break;
|
||||
case AND_xHL: I=RdZ80(R->HL.W);M_AND(I);break;
|
||||
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||
|
||||
case OR_B: M_OR(R->BC.B.h);break;
|
||||
case OR_C: M_OR(R->BC.B.l);break;
|
||||
case OR_D: M_OR(R->DE.B.h);break;
|
||||
case OR_E: M_OR(R->DE.B.l);break;
|
||||
case OR_H: M_OR(R->HL.B.h);break;
|
||||
case OR_L: M_OR(R->HL.B.l);break;
|
||||
case OR_A: M_OR(R->AF.B.h);break;
|
||||
case OR_xHL: I=RdZ80(R->HL.W);M_OR(I);break;
|
||||
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||
|
||||
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||
case ADC_H: M_ADC(R->HL.B.h);break;
|
||||
case ADC_L: M_ADC(R->HL.B.l);break;
|
||||
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||
case ADC_xHL: I=RdZ80(R->HL.W);M_ADC(I);break;
|
||||
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||
|
||||
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||
case SBC_H: M_SBC(R->HL.B.h);break;
|
||||
case SBC_L: M_SBC(R->HL.B.l);break;
|
||||
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||
case SBC_xHL: I=RdZ80(R->HL.W);M_SBC(I);break;
|
||||
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||
|
||||
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||
case XOR_H: M_XOR(R->HL.B.h);break;
|
||||
case XOR_L: M_XOR(R->HL.B.l);break;
|
||||
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||
case XOR_xHL: I=RdZ80(R->HL.W);M_XOR(I);break;
|
||||
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||
|
||||
case CP_B: M_CP(R->BC.B.h);break;
|
||||
case CP_C: M_CP(R->BC.B.l);break;
|
||||
case CP_D: M_CP(R->DE.B.h);break;
|
||||
case CP_E: M_CP(R->DE.B.l);break;
|
||||
case CP_H: M_CP(R->HL.B.h);break;
|
||||
case CP_L: M_CP(R->HL.B.l);break;
|
||||
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case CP_xHL: I=RdZ80(R->HL.W);M_CP(I);break;
|
||||
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||
|
||||
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||
case LD_HL_WORD: M_LDWORD(HL);break;
|
||||
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||
|
||||
case LD_PC_HL: R->PC.W=R->HL.W;break;
|
||||
case LD_SP_HL: R->SP.W=R->HL.W;break;
|
||||
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||
|
||||
case ADD_HL_BC: M_ADDW(HL,BC);break;
|
||||
case ADD_HL_DE: M_ADDW(HL,DE);break;
|
||||
case ADD_HL_HL: M_ADDW(HL,HL);break;
|
||||
case ADD_HL_SP: M_ADDW(HL,SP);break;
|
||||
|
||||
case DEC_BC: R->BC.W--;break;
|
||||
case DEC_DE: R->DE.W--;break;
|
||||
case DEC_HL: R->HL.W--;break;
|
||||
case DEC_SP: R->SP.W--;break;
|
||||
|
||||
case INC_BC: R->BC.W++;break;
|
||||
case INC_DE: R->DE.W++;break;
|
||||
case INC_HL: R->HL.W++;break;
|
||||
case INC_SP: R->SP.W++;break;
|
||||
|
||||
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||
case DEC_H: M_DEC(R->HL.B.h);break;
|
||||
case DEC_L: M_DEC(R->HL.B.l);break;
|
||||
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||
case DEC_xHL: I=RdZ80(R->HL.W);M_DEC(I);WrZ80(R->HL.W,I);break;
|
||||
|
||||
case INC_B: M_INC(R->BC.B.h);break;
|
||||
case INC_C: M_INC(R->BC.B.l);break;
|
||||
case INC_D: M_INC(R->DE.B.h);break;
|
||||
case INC_E: M_INC(R->DE.B.l);break;
|
||||
case INC_H: M_INC(R->HL.B.h);break;
|
||||
case INC_L: M_INC(R->HL.B.l);break;
|
||||
case INC_A: M_INC(R->AF.B.h);break;
|
||||
case INC_xHL: I=RdZ80(R->HL.W);M_INC(I);WrZ80(R->HL.W,I);break;
|
||||
|
||||
case RLCA:
|
||||
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RLA:
|
||||
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRCA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
|
||||
case RST00: M_RST(0x0000);break;
|
||||
case RST08: M_RST(0x0008);break;
|
||||
case RST10: M_RST(0x0010);break;
|
||||
case RST18: M_RST(0x0018);break;
|
||||
case RST20: M_RST(0x0020);break;
|
||||
case RST28: M_RST(0x0028);break;
|
||||
case RST30: M_RST(0x0030);break;
|
||||
case RST38: M_RST(0x0038);break;
|
||||
|
||||
case PUSH_BC: M_PUSH(BC);break;
|
||||
case PUSH_DE: M_PUSH(DE);break;
|
||||
case PUSH_HL: M_PUSH(HL);break;
|
||||
case PUSH_AF: M_PUSH(AF);break;
|
||||
|
||||
case POP_BC: M_POP(BC);break;
|
||||
case POP_DE: M_POP(DE);break;
|
||||
case POP_HL: M_POP(HL);break;
|
||||
case POP_AF: M_POP(AF);break;
|
||||
|
||||
case DJNZ: if(--R->BC.B.h) { M_JR; } else R->PC.W++;break;
|
||||
case JP: M_JP;break;
|
||||
case JR: M_JR;break;
|
||||
case CALL: M_CALL;break;
|
||||
case RET: M_RET;break;
|
||||
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||
case NOP: break;
|
||||
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||
case HALT: R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||
|
||||
case DI:
|
||||
R->IFF&=0xFE;
|
||||
break;
|
||||
case EI:
|
||||
R->IFF|=0x01;
|
||||
if(R->IRequest!=INT_NONE)
|
||||
{
|
||||
R->IFF|=0x20;
|
||||
R->IBackup=R->ICount;
|
||||
R->ICount=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCF:
|
||||
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||
break;
|
||||
|
||||
case EXX:
|
||||
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||
break;
|
||||
|
||||
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||
|
||||
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||
case LD_H_B: R->HL.B.h=R->BC.B.h;break;
|
||||
case LD_L_B: R->HL.B.l=R->BC.B.h;break;
|
||||
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||
case LD_xHL_B: WrZ80(R->HL.W,R->BC.B.h);break;
|
||||
|
||||
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||
case LD_H_C: R->HL.B.h=R->BC.B.l;break;
|
||||
case LD_L_C: R->HL.B.l=R->BC.B.l;break;
|
||||
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||
case LD_xHL_C: WrZ80(R->HL.W,R->BC.B.l);break;
|
||||
|
||||
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||
case LD_H_D: R->HL.B.h=R->DE.B.h;break;
|
||||
case LD_L_D: R->HL.B.l=R->DE.B.h;break;
|
||||
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||
case LD_xHL_D: WrZ80(R->HL.W,R->DE.B.h);break;
|
||||
|
||||
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||
case LD_H_E: R->HL.B.h=R->DE.B.l;break;
|
||||
case LD_L_E: R->HL.B.l=R->DE.B.l;break;
|
||||
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||
case LD_xHL_E: WrZ80(R->HL.W,R->DE.B.l);break;
|
||||
|
||||
case LD_B_H: R->BC.B.h=R->HL.B.h;break;
|
||||
case LD_C_H: R->BC.B.l=R->HL.B.h;break;
|
||||
case LD_D_H: R->DE.B.h=R->HL.B.h;break;
|
||||
case LD_E_H: R->DE.B.l=R->HL.B.h;break;
|
||||
case LD_H_H: R->HL.B.h=R->HL.B.h;break;
|
||||
case LD_L_H: R->HL.B.l=R->HL.B.h;break;
|
||||
case LD_A_H: R->AF.B.h=R->HL.B.h;break;
|
||||
case LD_xHL_H: WrZ80(R->HL.W,R->HL.B.h);break;
|
||||
|
||||
case LD_B_L: R->BC.B.h=R->HL.B.l;break;
|
||||
case LD_C_L: R->BC.B.l=R->HL.B.l;break;
|
||||
case LD_D_L: R->DE.B.h=R->HL.B.l;break;
|
||||
case LD_E_L: R->DE.B.l=R->HL.B.l;break;
|
||||
case LD_H_L: R->HL.B.h=R->HL.B.l;break;
|
||||
case LD_L_L: R->HL.B.l=R->HL.B.l;break;
|
||||
case LD_A_L: R->AF.B.h=R->HL.B.l;break;
|
||||
case LD_xHL_L: WrZ80(R->HL.W,R->HL.B.l);break;
|
||||
|
||||
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||
case LD_H_A: R->HL.B.h=R->AF.B.h;break;
|
||||
case LD_L_A: R->HL.B.l=R->AF.B.h;break;
|
||||
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||
case LD_xHL_A: WrZ80(R->HL.W,R->AF.B.h);break;
|
||||
|
||||
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||
|
||||
case LD_B_xHL: R->BC.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_C_xHL: R->BC.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_D_xHL: R->DE.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_E_xHL: R->DE.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_H_xHL: R->HL.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_L_xHL: R->HL.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_A_xHL: R->AF.B.h=RdZ80(R->HL.W);break;
|
||||
|
||||
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_H_BYTE: R->HL.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_L_BYTE: R->HL.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_xHL_BYTE: WrZ80(R->HL.W,RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_xWORD_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->HL.B.l);
|
||||
WrZ80(J.W,R->HL.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->HL.B.l=RdZ80(J.W++);
|
||||
R->HL.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_A_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->AF.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_xWORD_A:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);
|
||||
break;
|
||||
|
||||
case EX_HL_xSP:
|
||||
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->HL.B.l);
|
||||
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->HL.B.h);
|
||||
R->HL.W=J.W;
|
||||
break;
|
||||
|
||||
case DAA:
|
||||
J.W=R->AF.B.h;
|
||||
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||
R->AF.W=DAATable[J.W];
|
||||
break;
|
||||
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: %02X at PC=%04X\n",
|
||||
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-1
|
||||
);
|
||||
break;
|
|
@ -0,0 +1,204 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesCB.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the CB table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case RLC_B: M_RLC(R->BC.B.h);break; case RLC_C: M_RLC(R->BC.B.l);break;
|
||||
case RLC_D: M_RLC(R->DE.B.h);break; case RLC_E: M_RLC(R->DE.B.l);break;
|
||||
case RLC_H: M_RLC(R->HL.B.h);break; case RLC_L: M_RLC(R->HL.B.l);break;
|
||||
case RLC_xHL: I=RdZ80(R->HL.W);M_RLC(I);WrZ80(R->HL.W,I);break;
|
||||
case RLC_A: M_RLC(R->AF.B.h);break;
|
||||
|
||||
case RRC_B: M_RRC(R->BC.B.h);break; case RRC_C: M_RRC(R->BC.B.l);break;
|
||||
case RRC_D: M_RRC(R->DE.B.h);break; case RRC_E: M_RRC(R->DE.B.l);break;
|
||||
case RRC_H: M_RRC(R->HL.B.h);break; case RRC_L: M_RRC(R->HL.B.l);break;
|
||||
case RRC_xHL: I=RdZ80(R->HL.W);M_RRC(I);WrZ80(R->HL.W,I);break;
|
||||
case RRC_A: M_RRC(R->AF.B.h);break;
|
||||
|
||||
case RL_B: M_RL(R->BC.B.h);break; case RL_C: M_RL(R->BC.B.l);break;
|
||||
case RL_D: M_RL(R->DE.B.h);break; case RL_E: M_RL(R->DE.B.l);break;
|
||||
case RL_H: M_RL(R->HL.B.h);break; case RL_L: M_RL(R->HL.B.l);break;
|
||||
case RL_xHL: I=RdZ80(R->HL.W);M_RL(I);WrZ80(R->HL.W,I);break;
|
||||
case RL_A: M_RL(R->AF.B.h);break;
|
||||
|
||||
case RR_B: M_RR(R->BC.B.h);break; case RR_C: M_RR(R->BC.B.l);break;
|
||||
case RR_D: M_RR(R->DE.B.h);break; case RR_E: M_RR(R->DE.B.l);break;
|
||||
case RR_H: M_RR(R->HL.B.h);break; case RR_L: M_RR(R->HL.B.l);break;
|
||||
case RR_xHL: I=RdZ80(R->HL.W);M_RR(I);WrZ80(R->HL.W,I);break;
|
||||
case RR_A: M_RR(R->AF.B.h);break;
|
||||
|
||||
case SLA_B: M_SLA(R->BC.B.h);break; case SLA_C: M_SLA(R->BC.B.l);break;
|
||||
case SLA_D: M_SLA(R->DE.B.h);break; case SLA_E: M_SLA(R->DE.B.l);break;
|
||||
case SLA_H: M_SLA(R->HL.B.h);break; case SLA_L: M_SLA(R->HL.B.l);break;
|
||||
case SLA_xHL: I=RdZ80(R->HL.W);M_SLA(I);WrZ80(R->HL.W,I);break;
|
||||
case SLA_A: M_SLA(R->AF.B.h);break;
|
||||
|
||||
case SRA_B: M_SRA(R->BC.B.h);break; case SRA_C: M_SRA(R->BC.B.l);break;
|
||||
case SRA_D: M_SRA(R->DE.B.h);break; case SRA_E: M_SRA(R->DE.B.l);break;
|
||||
case SRA_H: M_SRA(R->HL.B.h);break; case SRA_L: M_SRA(R->HL.B.l);break;
|
||||
case SRA_xHL: I=RdZ80(R->HL.W);M_SRA(I);WrZ80(R->HL.W,I);break;
|
||||
case SRA_A: M_SRA(R->AF.B.h);break;
|
||||
|
||||
case SLL_B: M_SLL(R->BC.B.h);break; case SLL_C: M_SLL(R->BC.B.l);break;
|
||||
case SLL_D: M_SLL(R->DE.B.h);break; case SLL_E: M_SLL(R->DE.B.l);break;
|
||||
case SLL_H: M_SLL(R->HL.B.h);break; case SLL_L: M_SLL(R->HL.B.l);break;
|
||||
case SLL_xHL: I=RdZ80(R->HL.W);M_SLL(I);WrZ80(R->HL.W,I);break;
|
||||
case SLL_A: M_SLL(R->AF.B.h);break;
|
||||
|
||||
case SRL_B: M_SRL(R->BC.B.h);break; case SRL_C: M_SRL(R->BC.B.l);break;
|
||||
case SRL_D: M_SRL(R->DE.B.h);break; case SRL_E: M_SRL(R->DE.B.l);break;
|
||||
case SRL_H: M_SRL(R->HL.B.h);break; case SRL_L: M_SRL(R->HL.B.l);break;
|
||||
case SRL_xHL: I=RdZ80(R->HL.W);M_SRL(I);WrZ80(R->HL.W,I);break;
|
||||
case SRL_A: M_SRL(R->AF.B.h);break;
|
||||
|
||||
case BIT0_B: M_BIT(0,R->BC.B.h);break; case BIT0_C: M_BIT(0,R->BC.B.l);break;
|
||||
case BIT0_D: M_BIT(0,R->DE.B.h);break; case BIT0_E: M_BIT(0,R->DE.B.l);break;
|
||||
case BIT0_H: M_BIT(0,R->HL.B.h);break; case BIT0_L: M_BIT(0,R->HL.B.l);break;
|
||||
case BIT0_xHL: I=RdZ80(R->HL.W);M_BIT(0,I);break;
|
||||
case BIT0_A: M_BIT(0,R->AF.B.h);break;
|
||||
|
||||
case BIT1_B: M_BIT(1,R->BC.B.h);break; case BIT1_C: M_BIT(1,R->BC.B.l);break;
|
||||
case BIT1_D: M_BIT(1,R->DE.B.h);break; case BIT1_E: M_BIT(1,R->DE.B.l);break;
|
||||
case BIT1_H: M_BIT(1,R->HL.B.h);break; case BIT1_L: M_BIT(1,R->HL.B.l);break;
|
||||
case BIT1_xHL: I=RdZ80(R->HL.W);M_BIT(1,I);break;
|
||||
case BIT1_A: M_BIT(1,R->AF.B.h);break;
|
||||
|
||||
case BIT2_B: M_BIT(2,R->BC.B.h);break; case BIT2_C: M_BIT(2,R->BC.B.l);break;
|
||||
case BIT2_D: M_BIT(2,R->DE.B.h);break; case BIT2_E: M_BIT(2,R->DE.B.l);break;
|
||||
case BIT2_H: M_BIT(2,R->HL.B.h);break; case BIT2_L: M_BIT(2,R->HL.B.l);break;
|
||||
case BIT2_xHL: I=RdZ80(R->HL.W);M_BIT(2,I);break;
|
||||
case BIT2_A: M_BIT(2,R->AF.B.h);break;
|
||||
|
||||
case BIT3_B: M_BIT(3,R->BC.B.h);break; case BIT3_C: M_BIT(3,R->BC.B.l);break;
|
||||
case BIT3_D: M_BIT(3,R->DE.B.h);break; case BIT3_E: M_BIT(3,R->DE.B.l);break;
|
||||
case BIT3_H: M_BIT(3,R->HL.B.h);break; case BIT3_L: M_BIT(3,R->HL.B.l);break;
|
||||
case BIT3_xHL: I=RdZ80(R->HL.W);M_BIT(3,I);break;
|
||||
case BIT3_A: M_BIT(3,R->AF.B.h);break;
|
||||
|
||||
case BIT4_B: M_BIT(4,R->BC.B.h);break; case BIT4_C: M_BIT(4,R->BC.B.l);break;
|
||||
case BIT4_D: M_BIT(4,R->DE.B.h);break; case BIT4_E: M_BIT(4,R->DE.B.l);break;
|
||||
case BIT4_H: M_BIT(4,R->HL.B.h);break; case BIT4_L: M_BIT(4,R->HL.B.l);break;
|
||||
case BIT4_xHL: I=RdZ80(R->HL.W);M_BIT(4,I);break;
|
||||
case BIT4_A: M_BIT(4,R->AF.B.h);break;
|
||||
|
||||
case BIT5_B: M_BIT(5,R->BC.B.h);break; case BIT5_C: M_BIT(5,R->BC.B.l);break;
|
||||
case BIT5_D: M_BIT(5,R->DE.B.h);break; case BIT5_E: M_BIT(5,R->DE.B.l);break;
|
||||
case BIT5_H: M_BIT(5,R->HL.B.h);break; case BIT5_L: M_BIT(5,R->HL.B.l);break;
|
||||
case BIT5_xHL: I=RdZ80(R->HL.W);M_BIT(5,I);break;
|
||||
case BIT5_A: M_BIT(5,R->AF.B.h);break;
|
||||
|
||||
case BIT6_B: M_BIT(6,R->BC.B.h);break; case BIT6_C: M_BIT(6,R->BC.B.l);break;
|
||||
case BIT6_D: M_BIT(6,R->DE.B.h);break; case BIT6_E: M_BIT(6,R->DE.B.l);break;
|
||||
case BIT6_H: M_BIT(6,R->HL.B.h);break; case BIT6_L: M_BIT(6,R->HL.B.l);break;
|
||||
case BIT6_xHL: I=RdZ80(R->HL.W);M_BIT(6,I);break;
|
||||
case BIT6_A: M_BIT(6,R->AF.B.h);break;
|
||||
|
||||
case BIT7_B: M_BIT(7,R->BC.B.h);break; case BIT7_C: M_BIT(7,R->BC.B.l);break;
|
||||
case BIT7_D: M_BIT(7,R->DE.B.h);break; case BIT7_E: M_BIT(7,R->DE.B.l);break;
|
||||
case BIT7_H: M_BIT(7,R->HL.B.h);break; case BIT7_L: M_BIT(7,R->HL.B.l);break;
|
||||
case BIT7_xHL: I=RdZ80(R->HL.W);M_BIT(7,I);break;
|
||||
case BIT7_A: M_BIT(7,R->AF.B.h);break;
|
||||
|
||||
case RES0_B: M_RES(0,R->BC.B.h);break; case RES0_C: M_RES(0,R->BC.B.l);break;
|
||||
case RES0_D: M_RES(0,R->DE.B.h);break; case RES0_E: M_RES(0,R->DE.B.l);break;
|
||||
case RES0_H: M_RES(0,R->HL.B.h);break; case RES0_L: M_RES(0,R->HL.B.l);break;
|
||||
case RES0_xHL: I=RdZ80(R->HL.W);M_RES(0,I);WrZ80(R->HL.W,I);break;
|
||||
case RES0_A: M_RES(0,R->AF.B.h);break;
|
||||
|
||||
case RES1_B: M_RES(1,R->BC.B.h);break; case RES1_C: M_RES(1,R->BC.B.l);break;
|
||||
case RES1_D: M_RES(1,R->DE.B.h);break; case RES1_E: M_RES(1,R->DE.B.l);break;
|
||||
case RES1_H: M_RES(1,R->HL.B.h);break; case RES1_L: M_RES(1,R->HL.B.l);break;
|
||||
case RES1_xHL: I=RdZ80(R->HL.W);M_RES(1,I);WrZ80(R->HL.W,I);break;
|
||||
case RES1_A: M_RES(1,R->AF.B.h);break;
|
||||
|
||||
case RES2_B: M_RES(2,R->BC.B.h);break; case RES2_C: M_RES(2,R->BC.B.l);break;
|
||||
case RES2_D: M_RES(2,R->DE.B.h);break; case RES2_E: M_RES(2,R->DE.B.l);break;
|
||||
case RES2_H: M_RES(2,R->HL.B.h);break; case RES2_L: M_RES(2,R->HL.B.l);break;
|
||||
case RES2_xHL: I=RdZ80(R->HL.W);M_RES(2,I);WrZ80(R->HL.W,I);break;
|
||||
case RES2_A: M_RES(2,R->AF.B.h);break;
|
||||
|
||||
case RES3_B: M_RES(3,R->BC.B.h);break; case RES3_C: M_RES(3,R->BC.B.l);break;
|
||||
case RES3_D: M_RES(3,R->DE.B.h);break; case RES3_E: M_RES(3,R->DE.B.l);break;
|
||||
case RES3_H: M_RES(3,R->HL.B.h);break; case RES3_L: M_RES(3,R->HL.B.l);break;
|
||||
case RES3_xHL: I=RdZ80(R->HL.W);M_RES(3,I);WrZ80(R->HL.W,I);break;
|
||||
case RES3_A: M_RES(3,R->AF.B.h);break;
|
||||
|
||||
case RES4_B: M_RES(4,R->BC.B.h);break; case RES4_C: M_RES(4,R->BC.B.l);break;
|
||||
case RES4_D: M_RES(4,R->DE.B.h);break; case RES4_E: M_RES(4,R->DE.B.l);break;
|
||||
case RES4_H: M_RES(4,R->HL.B.h);break; case RES4_L: M_RES(4,R->HL.B.l);break;
|
||||
case RES4_xHL: I=RdZ80(R->HL.W);M_RES(4,I);WrZ80(R->HL.W,I);break;
|
||||
case RES4_A: M_RES(4,R->AF.B.h);break;
|
||||
|
||||
case RES5_B: M_RES(5,R->BC.B.h);break; case RES5_C: M_RES(5,R->BC.B.l);break;
|
||||
case RES5_D: M_RES(5,R->DE.B.h);break; case RES5_E: M_RES(5,R->DE.B.l);break;
|
||||
case RES5_H: M_RES(5,R->HL.B.h);break; case RES5_L: M_RES(5,R->HL.B.l);break;
|
||||
case RES5_xHL: I=RdZ80(R->HL.W);M_RES(5,I);WrZ80(R->HL.W,I);break;
|
||||
case RES5_A: M_RES(5,R->AF.B.h);break;
|
||||
|
||||
case RES6_B: M_RES(6,R->BC.B.h);break; case RES6_C: M_RES(6,R->BC.B.l);break;
|
||||
case RES6_D: M_RES(6,R->DE.B.h);break; case RES6_E: M_RES(6,R->DE.B.l);break;
|
||||
case RES6_H: M_RES(6,R->HL.B.h);break; case RES6_L: M_RES(6,R->HL.B.l);break;
|
||||
case RES6_xHL: I=RdZ80(R->HL.W);M_RES(6,I);WrZ80(R->HL.W,I);break;
|
||||
case RES6_A: M_RES(6,R->AF.B.h);break;
|
||||
|
||||
case RES7_B: M_RES(7,R->BC.B.h);break; case RES7_C: M_RES(7,R->BC.B.l);break;
|
||||
case RES7_D: M_RES(7,R->DE.B.h);break; case RES7_E: M_RES(7,R->DE.B.l);break;
|
||||
case RES7_H: M_RES(7,R->HL.B.h);break; case RES7_L: M_RES(7,R->HL.B.l);break;
|
||||
case RES7_xHL: I=RdZ80(R->HL.W);M_RES(7,I);WrZ80(R->HL.W,I);break;
|
||||
case RES7_A: M_RES(7,R->AF.B.h);break;
|
||||
|
||||
case SET0_B: M_SET(0,R->BC.B.h);break; case SET0_C: M_SET(0,R->BC.B.l);break;
|
||||
case SET0_D: M_SET(0,R->DE.B.h);break; case SET0_E: M_SET(0,R->DE.B.l);break;
|
||||
case SET0_H: M_SET(0,R->HL.B.h);break; case SET0_L: M_SET(0,R->HL.B.l);break;
|
||||
case SET0_xHL: I=RdZ80(R->HL.W);M_SET(0,I);WrZ80(R->HL.W,I);break;
|
||||
case SET0_A: M_SET(0,R->AF.B.h);break;
|
||||
|
||||
case SET1_B: M_SET(1,R->BC.B.h);break; case SET1_C: M_SET(1,R->BC.B.l);break;
|
||||
case SET1_D: M_SET(1,R->DE.B.h);break; case SET1_E: M_SET(1,R->DE.B.l);break;
|
||||
case SET1_H: M_SET(1,R->HL.B.h);break; case SET1_L: M_SET(1,R->HL.B.l);break;
|
||||
case SET1_xHL: I=RdZ80(R->HL.W);M_SET(1,I);WrZ80(R->HL.W,I);break;
|
||||
case SET1_A: M_SET(1,R->AF.B.h);break;
|
||||
|
||||
case SET2_B: M_SET(2,R->BC.B.h);break; case SET2_C: M_SET(2,R->BC.B.l);break;
|
||||
case SET2_D: M_SET(2,R->DE.B.h);break; case SET2_E: M_SET(2,R->DE.B.l);break;
|
||||
case SET2_H: M_SET(2,R->HL.B.h);break; case SET2_L: M_SET(2,R->HL.B.l);break;
|
||||
case SET2_xHL: I=RdZ80(R->HL.W);M_SET(2,I);WrZ80(R->HL.W,I);break;
|
||||
case SET2_A: M_SET(2,R->AF.B.h);break;
|
||||
|
||||
case SET3_B: M_SET(3,R->BC.B.h);break; case SET3_C: M_SET(3,R->BC.B.l);break;
|
||||
case SET3_D: M_SET(3,R->DE.B.h);break; case SET3_E: M_SET(3,R->DE.B.l);break;
|
||||
case SET3_H: M_SET(3,R->HL.B.h);break; case SET3_L: M_SET(3,R->HL.B.l);break;
|
||||
case SET3_xHL: I=RdZ80(R->HL.W);M_SET(3,I);WrZ80(R->HL.W,I);break;
|
||||
case SET3_A: M_SET(3,R->AF.B.h);break;
|
||||
|
||||
case SET4_B: M_SET(4,R->BC.B.h);break; case SET4_C: M_SET(4,R->BC.B.l);break;
|
||||
case SET4_D: M_SET(4,R->DE.B.h);break; case SET4_E: M_SET(4,R->DE.B.l);break;
|
||||
case SET4_H: M_SET(4,R->HL.B.h);break; case SET4_L: M_SET(4,R->HL.B.l);break;
|
||||
case SET4_xHL: I=RdZ80(R->HL.W);M_SET(4,I);WrZ80(R->HL.W,I);break;
|
||||
case SET4_A: M_SET(4,R->AF.B.h);break;
|
||||
|
||||
case SET5_B: M_SET(5,R->BC.B.h);break; case SET5_C: M_SET(5,R->BC.B.l);break;
|
||||
case SET5_D: M_SET(5,R->DE.B.h);break; case SET5_E: M_SET(5,R->DE.B.l);break;
|
||||
case SET5_H: M_SET(5,R->HL.B.h);break; case SET5_L: M_SET(5,R->HL.B.l);break;
|
||||
case SET5_xHL: I=RdZ80(R->HL.W);M_SET(5,I);WrZ80(R->HL.W,I);break;
|
||||
case SET5_A: M_SET(5,R->AF.B.h);break;
|
||||
|
||||
case SET6_B: M_SET(6,R->BC.B.h);break; case SET6_C: M_SET(6,R->BC.B.l);break;
|
||||
case SET6_D: M_SET(6,R->DE.B.h);break; case SET6_E: M_SET(6,R->DE.B.l);break;
|
||||
case SET6_H: M_SET(6,R->HL.B.h);break; case SET6_L: M_SET(6,R->HL.B.l);break;
|
||||
case SET6_xHL: I=RdZ80(R->HL.W);M_SET(6,I);WrZ80(R->HL.W,I);break;
|
||||
case SET6_A: M_SET(6,R->AF.B.h);break;
|
||||
|
||||
case SET7_B: M_SET(7,R->BC.B.h);break; case SET7_C: M_SET(7,R->BC.B.l);break;
|
||||
case SET7_D: M_SET(7,R->DE.B.h);break; case SET7_E: M_SET(7,R->DE.B.l);break;
|
||||
case SET7_H: M_SET(7,R->HL.B.h);break; case SET7_L: M_SET(7,R->HL.B.l);break;
|
||||
case SET7_xHL: I=RdZ80(R->HL.W);M_SET(7,I);WrZ80(R->HL.W,I);break;
|
||||
case SET7_A: M_SET(7,R->AF.B.h);break;
|
|
@ -0,0 +1,282 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesED.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the ED table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
/** This is a special patch for emulating BIOS calls: ********/
|
||||
case DB_FE: PatchZ80(R);break;
|
||||
/*************************************************************/
|
||||
|
||||
case ADC_HL_BC: M_ADCW(BC);break;
|
||||
case ADC_HL_DE: M_ADCW(DE);break;
|
||||
case ADC_HL_HL: M_ADCW(HL);break;
|
||||
case ADC_HL_SP: M_ADCW(SP);break;
|
||||
|
||||
case SBC_HL_BC: M_SBCW(BC);break;
|
||||
case SBC_HL_DE: M_SBCW(DE);break;
|
||||
case SBC_HL_HL: M_SBCW(HL);break;
|
||||
case SBC_HL_SP: M_SBCW(SP);break;
|
||||
|
||||
case LD_xWORDe_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->HL.B.l);
|
||||
WrZ80(J.W,R->HL.B.h);
|
||||
break;
|
||||
case LD_xWORDe_DE:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->DE.B.l);
|
||||
WrZ80(J.W,R->DE.B.h);
|
||||
break;
|
||||
case LD_xWORDe_BC:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->BC.B.l);
|
||||
WrZ80(J.W,R->BC.B.h);
|
||||
break;
|
||||
case LD_xWORDe_SP:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->SP.B.l);
|
||||
WrZ80(J.W,R->SP.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->HL.B.l=RdZ80(J.W++);
|
||||
R->HL.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_DE_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->DE.B.l=RdZ80(J.W++);
|
||||
R->DE.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_BC_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->BC.B.l=RdZ80(J.W++);
|
||||
R->BC.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_SP_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->SP.B.l=RdZ80(J.W++);
|
||||
R->SP.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case RRD:
|
||||
I=RdZ80(R->HL.W);
|
||||
J.B.l=(I>>4)|(R->AF.B.h<<4);
|
||||
WrZ80(R->HL.W,J.B.l);
|
||||
R->AF.B.h=(I&0x0F)|(R->AF.B.h&0xF0);
|
||||
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||
break;
|
||||
case RLD:
|
||||
I=RdZ80(R->HL.W);
|
||||
J.B.l=(I<<4)|(R->AF.B.h&0x0F);
|
||||
WrZ80(R->HL.W,J.B.l);
|
||||
R->AF.B.h=(I>>4)|(R->AF.B.h&0xF0);
|
||||
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||
break;
|
||||
|
||||
case LD_A_I:
|
||||
R->AF.B.h=R->I;
|
||||
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||
break;
|
||||
|
||||
case LD_A_R:
|
||||
R->R++;
|
||||
R->AF.B.h=(byte)(R->R-R->ICount);
|
||||
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||
break;
|
||||
|
||||
case LD_I_A: R->I=R->AF.B.h;break;
|
||||
case LD_R_A: break;
|
||||
|
||||
case IM_0: R->IFF&=0xF9;break;
|
||||
case IM_1: R->IFF=(R->IFF&0xF9)|2;break;
|
||||
case IM_2: R->IFF=(R->IFF&0xF9)|4;break;
|
||||
|
||||
case RETI: M_RET;break;
|
||||
case RETN: if(R->IFF&0x40) R->IFF|=0x01; else R->IFF&=0xFE;
|
||||
M_RET;break;
|
||||
|
||||
case NEG: I=R->AF.B.h;R->AF.B.h=0;M_SUB(I);break;
|
||||
|
||||
case IN_B_xC: M_IN(R->BC.B.h);break;
|
||||
case IN_C_xC: M_IN(R->BC.B.l);break;
|
||||
case IN_D_xC: M_IN(R->DE.B.h);break;
|
||||
case IN_E_xC: M_IN(R->DE.B.l);break;
|
||||
case IN_H_xC: M_IN(R->HL.B.h);break;
|
||||
case IN_L_xC: M_IN(R->HL.B.l);break;
|
||||
case IN_A_xC: M_IN(R->AF.B.h);break;
|
||||
case IN_F_xC: M_IN(J.B.l);break;
|
||||
|
||||
case OUT_xC_B: OutZ80(R->BC.B.l,R->BC.B.h);break;
|
||||
case OUT_xC_C: OutZ80(R->BC.B.l,R->BC.B.l);break;
|
||||
case OUT_xC_D: OutZ80(R->BC.B.l,R->DE.B.h);break;
|
||||
case OUT_xC_E: OutZ80(R->BC.B.l,R->DE.B.l);break;
|
||||
case OUT_xC_H: OutZ80(R->BC.B.l,R->HL.B.h);break;
|
||||
case OUT_xC_L: OutZ80(R->BC.B.l,R->HL.B.l);break;
|
||||
case OUT_xC_A: OutZ80(R->BC.B.l,R->AF.B.h);break;
|
||||
|
||||
case INI:
|
||||
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case INIR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case IND:
|
||||
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case INDR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case OUTI:
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W++));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case OTIR:
|
||||
do
|
||||
{
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W++));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case OUTD:
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W--));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case OTDR:
|
||||
do
|
||||
{
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W--));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case LDI:
|
||||
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||
R->BC.W--;
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case LDIR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&(R->ICount>0));
|
||||
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||
else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case LDD:
|
||||
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||
R->BC.W--;
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case LDDR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&(R->ICount>0));
|
||||
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||
else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case CPI:
|
||||
I=RdZ80(R->HL.W++);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case CPIR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W++);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&J.B.l&&(R->ICount>0));
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case CPD:
|
||||
I=RdZ80(R->HL.W--);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case CPDR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W--);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&J.B.l);
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||
break;
|
|
@ -0,0 +1,64 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesXCB.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for FD/DD-CB tables **/
|
||||
/** of Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case RLC_xHL: I=RdZ80(J.W);M_RLC(I);WrZ80(J.W,I);break;
|
||||
case RRC_xHL: I=RdZ80(J.W);M_RRC(I);WrZ80(J.W,I);break;
|
||||
case RL_xHL: I=RdZ80(J.W);M_RL(I);WrZ80(J.W,I);break;
|
||||
case RR_xHL: I=RdZ80(J.W);M_RR(I);WrZ80(J.W,I);break;
|
||||
case SLA_xHL: I=RdZ80(J.W);M_SLA(I);WrZ80(J.W,I);break;
|
||||
case SRA_xHL: I=RdZ80(J.W);M_SRA(I);WrZ80(J.W,I);break;
|
||||
case SLL_xHL: I=RdZ80(J.W);M_SLL(I);WrZ80(J.W,I);break;
|
||||
case SRL_xHL: I=RdZ80(J.W);M_SRL(I);WrZ80(J.W,I);break;
|
||||
|
||||
case BIT0_B: case BIT0_C: case BIT0_D: case BIT0_E:
|
||||
case BIT0_H: case BIT0_L: case BIT0_A:
|
||||
case BIT0_xHL: I=RdZ80(J.W);M_BIT(0,I);break;
|
||||
case BIT1_B: case BIT1_C: case BIT1_D: case BIT1_E:
|
||||
case BIT1_H: case BIT1_L: case BIT1_A:
|
||||
case BIT1_xHL: I=RdZ80(J.W);M_BIT(1,I);break;
|
||||
case BIT2_B: case BIT2_C: case BIT2_D: case BIT2_E:
|
||||
case BIT2_H: case BIT2_L: case BIT2_A:
|
||||
case BIT2_xHL: I=RdZ80(J.W);M_BIT(2,I);break;
|
||||
case BIT3_B: case BIT3_C: case BIT3_D: case BIT3_E:
|
||||
case BIT3_H: case BIT3_L: case BIT3_A:
|
||||
case BIT3_xHL: I=RdZ80(J.W);M_BIT(3,I);break;
|
||||
case BIT4_B: case BIT4_C: case BIT4_D: case BIT4_E:
|
||||
case BIT4_H: case BIT4_L: case BIT4_A:
|
||||
case BIT4_xHL: I=RdZ80(J.W);M_BIT(4,I);break;
|
||||
case BIT5_B: case BIT5_C: case BIT5_D: case BIT5_E:
|
||||
case BIT5_H: case BIT5_L: case BIT5_A:
|
||||
case BIT5_xHL: I=RdZ80(J.W);M_BIT(5,I);break;
|
||||
case BIT6_B: case BIT6_C: case BIT6_D: case BIT6_E:
|
||||
case BIT6_H: case BIT6_L: case BIT6_A:
|
||||
case BIT6_xHL: I=RdZ80(J.W);M_BIT(6,I);break;
|
||||
case BIT7_B: case BIT7_C: case BIT7_D: case BIT7_E:
|
||||
case BIT7_H: case BIT7_L: case BIT7_A:
|
||||
case BIT7_xHL: I=RdZ80(J.W);M_BIT(7,I);break;
|
||||
|
||||
case RES0_xHL: I=RdZ80(J.W);M_RES(0,I);WrZ80(J.W,I);break;
|
||||
case RES1_xHL: I=RdZ80(J.W);M_RES(1,I);WrZ80(J.W,I);break;
|
||||
case RES2_xHL: I=RdZ80(J.W);M_RES(2,I);WrZ80(J.W,I);break;
|
||||
case RES3_xHL: I=RdZ80(J.W);M_RES(3,I);WrZ80(J.W,I);break;
|
||||
case RES4_xHL: I=RdZ80(J.W);M_RES(4,I);WrZ80(J.W,I);break;
|
||||
case RES5_xHL: I=RdZ80(J.W);M_RES(5,I);WrZ80(J.W,I);break;
|
||||
case RES6_xHL: I=RdZ80(J.W);M_RES(6,I);WrZ80(J.W,I);break;
|
||||
case RES7_xHL: I=RdZ80(J.W);M_RES(7,I);WrZ80(J.W,I);break;
|
||||
|
||||
case SET0_xHL: I=RdZ80(J.W);M_SET(0,I);WrZ80(J.W,I);break;
|
||||
case SET1_xHL: I=RdZ80(J.W);M_SET(1,I);WrZ80(J.W,I);break;
|
||||
case SET2_xHL: I=RdZ80(J.W);M_SET(2,I);WrZ80(J.W,I);break;
|
||||
case SET3_xHL: I=RdZ80(J.W);M_SET(3,I);WrZ80(J.W,I);break;
|
||||
case SET4_xHL: I=RdZ80(J.W);M_SET(4,I);WrZ80(J.W,I);break;
|
||||
case SET5_xHL: I=RdZ80(J.W);M_SET(5,I);WrZ80(J.W,I);break;
|
||||
case SET6_xHL: I=RdZ80(J.W);M_SET(6,I);WrZ80(J.W,I);break;
|
||||
case SET7_xHL: I=RdZ80(J.W);M_SET(7,I);WrZ80(J.W,I);break;
|
|
@ -0,0 +1,388 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesXX.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for FD/DD tables of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { M_JR; } break;
|
||||
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { M_JR; } break;
|
||||
case JR_Z: if(R->AF.B.l&Z_FLAG) { M_JR; } else R->PC.W++; break;
|
||||
case JR_C: if(R->AF.B.l&C_FLAG) { M_JR; } else R->PC.W++; break;
|
||||
|
||||
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
|
||||
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { M_RET; } break;
|
||||
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { M_RET; } break;
|
||||
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { M_RET; } break;
|
||||
case RET_P: if(!(R->AF.B.l&S_FLAG)) { M_RET; } break;
|
||||
case RET_Z: if(R->AF.B.l&Z_FLAG) { M_RET; } break;
|
||||
case RET_C: if(R->AF.B.l&C_FLAG) { M_RET; } break;
|
||||
case RET_PE: if(R->AF.B.l&P_FLAG) { M_RET; } break;
|
||||
case RET_M: if(R->AF.B.l&S_FLAG) { M_RET; } break;
|
||||
|
||||
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_Z: if(R->AF.B.l&Z_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_C: if(R->AF.B.l&C_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_PE: if(R->AF.B.l&P_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_M: if(R->AF.B.l&S_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
|
||||
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||
case ADD_H: M_ADD(R->XX.B.h);break;
|
||||
case ADD_L: M_ADD(R->XX.B.l);break;
|
||||
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||
case ADD_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_ADD(I);break;
|
||||
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||
|
||||
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||
case SUB_H: M_SUB(R->XX.B.h);break;
|
||||
case SUB_L: M_SUB(R->XX.B.l);break;
|
||||
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case SUB_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_SUB(I);break;
|
||||
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||
|
||||
case AND_B: M_AND(R->BC.B.h);break;
|
||||
case AND_C: M_AND(R->BC.B.l);break;
|
||||
case AND_D: M_AND(R->DE.B.h);break;
|
||||
case AND_E: M_AND(R->DE.B.l);break;
|
||||
case AND_H: M_AND(R->XX.B.h);break;
|
||||
case AND_L: M_AND(R->XX.B.l);break;
|
||||
case AND_A: M_AND(R->AF.B.h);break;
|
||||
case AND_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_AND(I);break;
|
||||
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||
|
||||
case OR_B: M_OR(R->BC.B.h);break;
|
||||
case OR_C: M_OR(R->BC.B.l);break;
|
||||
case OR_D: M_OR(R->DE.B.h);break;
|
||||
case OR_E: M_OR(R->DE.B.l);break;
|
||||
case OR_H: M_OR(R->XX.B.h);break;
|
||||
case OR_L: M_OR(R->XX.B.l);break;
|
||||
case OR_A: M_OR(R->AF.B.h);break;
|
||||
case OR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_OR(I);break;
|
||||
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||
|
||||
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||
case ADC_H: M_ADC(R->XX.B.h);break;
|
||||
case ADC_L: M_ADC(R->XX.B.l);break;
|
||||
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||
case ADC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_ADC(I);break;
|
||||
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||
|
||||
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||
case SBC_H: M_SBC(R->XX.B.h);break;
|
||||
case SBC_L: M_SBC(R->XX.B.l);break;
|
||||
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||
case SBC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_SBC(I);break;
|
||||
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||
|
||||
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||
case XOR_H: M_XOR(R->XX.B.h);break;
|
||||
case XOR_L: M_XOR(R->XX.B.l);break;
|
||||
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||
case XOR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_XOR(I);break;
|
||||
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||
|
||||
case CP_B: M_CP(R->BC.B.h);break;
|
||||
case CP_C: M_CP(R->BC.B.l);break;
|
||||
case CP_D: M_CP(R->DE.B.h);break;
|
||||
case CP_E: M_CP(R->DE.B.l);break;
|
||||
case CP_H: M_CP(R->XX.B.h);break;
|
||||
case CP_L: M_CP(R->XX.B.l);break;
|
||||
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case CP_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_CP(I);break;
|
||||
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||
|
||||
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||
case LD_HL_WORD: M_LDWORD(XX);break;
|
||||
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||
|
||||
case LD_PC_HL: R->PC.W=R->XX.W;break;
|
||||
case LD_SP_HL: R->SP.W=R->XX.W;break;
|
||||
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||
|
||||
case ADD_HL_BC: M_ADDW(XX,BC);break;
|
||||
case ADD_HL_DE: M_ADDW(XX,DE);break;
|
||||
case ADD_HL_HL: M_ADDW(XX,XX);break;
|
||||
case ADD_HL_SP: M_ADDW(XX,SP);break;
|
||||
|
||||
case DEC_BC: R->BC.W--;break;
|
||||
case DEC_DE: R->DE.W--;break;
|
||||
case DEC_HL: R->XX.W--;break;
|
||||
case DEC_SP: R->SP.W--;break;
|
||||
|
||||
case INC_BC: R->BC.W++;break;
|
||||
case INC_DE: R->DE.W++;break;
|
||||
case INC_HL: R->XX.W++;break;
|
||||
case INC_SP: R->SP.W++;break;
|
||||
|
||||
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||
case DEC_H: M_DEC(R->XX.B.h);break;
|
||||
case DEC_L: M_DEC(R->XX.B.l);break;
|
||||
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||
case DEC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_DEC(I);
|
||||
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||
break;
|
||||
|
||||
case INC_B: M_INC(R->BC.B.h);break;
|
||||
case INC_C: M_INC(R->BC.B.l);break;
|
||||
case INC_D: M_INC(R->DE.B.h);break;
|
||||
case INC_E: M_INC(R->DE.B.l);break;
|
||||
case INC_H: M_INC(R->XX.B.h);break;
|
||||
case INC_L: M_INC(R->XX.B.l);break;
|
||||
case INC_A: M_INC(R->AF.B.h);break;
|
||||
case INC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_INC(I);
|
||||
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||
break;
|
||||
|
||||
case RLCA:
|
||||
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RLA:
|
||||
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRCA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
|
||||
case RST00: M_RST(0x0000);break;
|
||||
case RST08: M_RST(0x0008);break;
|
||||
case RST10: M_RST(0x0010);break;
|
||||
case RST18: M_RST(0x0018);break;
|
||||
case RST20: M_RST(0x0020);break;
|
||||
case RST28: M_RST(0x0028);break;
|
||||
case RST30: M_RST(0x0030);break;
|
||||
case RST38: M_RST(0x0038);break;
|
||||
|
||||
case PUSH_BC: M_PUSH(BC);break;
|
||||
case PUSH_DE: M_PUSH(DE);break;
|
||||
case PUSH_HL: M_PUSH(XX);break;
|
||||
case PUSH_AF: M_PUSH(AF);break;
|
||||
|
||||
case POP_BC: M_POP(BC);break;
|
||||
case POP_DE: M_POP(DE);break;
|
||||
case POP_HL: M_POP(XX);break;
|
||||
case POP_AF: M_POP(AF);break;
|
||||
|
||||
case DJNZ: if(--R->BC.B.h) { M_JR; } else R->PC.W++;break;
|
||||
case JP: M_JP;break;
|
||||
case JR: M_JR;break;
|
||||
case CALL: M_CALL;break;
|
||||
case RET: M_RET;break;
|
||||
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||
case NOP: break;
|
||||
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||
|
||||
case DI:
|
||||
R->IFF&=0xFE;
|
||||
break;
|
||||
case EI:
|
||||
R->IFF|=0x01;
|
||||
if(R->IRequest!=INT_NONE)
|
||||
{
|
||||
R->IFF|=0x20;
|
||||
R->IBackup=R->ICount;
|
||||
R->ICount=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCF:
|
||||
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||
break;
|
||||
|
||||
case EXX:
|
||||
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||
break;
|
||||
|
||||
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||
|
||||
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||
case LD_H_B: R->XX.B.h=R->BC.B.h;break;
|
||||
case LD_L_B: R->XX.B.l=R->BC.B.h;break;
|
||||
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||
case LD_xHL_B: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->BC.B.h);break;
|
||||
|
||||
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||
case LD_H_C: R->XX.B.h=R->BC.B.l;break;
|
||||
case LD_L_C: R->XX.B.l=R->BC.B.l;break;
|
||||
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||
case LD_xHL_C: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->BC.B.l);break;
|
||||
|
||||
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||
case LD_H_D: R->XX.B.h=R->DE.B.h;break;
|
||||
case LD_L_D: R->XX.B.l=R->DE.B.h;break;
|
||||
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||
case LD_xHL_D: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->DE.B.h);break;
|
||||
|
||||
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||
case LD_H_E: R->XX.B.h=R->DE.B.l;break;
|
||||
case LD_L_E: R->XX.B.l=R->DE.B.l;break;
|
||||
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||
case LD_xHL_E: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->DE.B.l);break;
|
||||
|
||||
case LD_B_H: R->BC.B.h=R->XX.B.h;break;
|
||||
case LD_C_H: R->BC.B.l=R->XX.B.h;break;
|
||||
case LD_D_H: R->DE.B.h=R->XX.B.h;break;
|
||||
case LD_E_H: R->DE.B.l=R->XX.B.h;break;
|
||||
case LD_H_H: R->XX.B.h=R->XX.B.h;break;
|
||||
case LD_L_H: R->XX.B.l=R->XX.B.h;break;
|
||||
case LD_A_H: R->AF.B.h=R->XX.B.h;break;
|
||||
case LD_xHL_H: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->HL.B.h);break;
|
||||
|
||||
case LD_B_L: R->BC.B.h=R->XX.B.l;break;
|
||||
case LD_C_L: R->BC.B.l=R->XX.B.l;break;
|
||||
case LD_D_L: R->DE.B.h=R->XX.B.l;break;
|
||||
case LD_E_L: R->DE.B.l=R->XX.B.l;break;
|
||||
case LD_H_L: R->XX.B.h=R->XX.B.l;break;
|
||||
case LD_L_L: R->XX.B.l=R->XX.B.l;break;
|
||||
case LD_A_L: R->AF.B.h=R->XX.B.l;break;
|
||||
case LD_xHL_L: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->HL.B.l);break;
|
||||
|
||||
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||
case LD_H_A: R->XX.B.h=R->AF.B.h;break;
|
||||
case LD_L_A: R->XX.B.l=R->AF.B.h;break;
|
||||
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||
case LD_xHL_A: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);break;
|
||||
|
||||
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||
|
||||
case LD_B_xHL: R->BC.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_C_xHL: R->BC.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_D_xHL: R->DE.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_E_xHL: R->DE.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_H_xHL: R->HL.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_L_xHL: R->HL.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_A_xHL: R->AF.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_H_BYTE: R->XX.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_L_BYTE: R->XX.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_xHL_BYTE: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_xWORD_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->XX.B.l);
|
||||
WrZ80(J.W,R->XX.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->XX.B.l=RdZ80(J.W++);
|
||||
R->XX.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_A_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->AF.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_xWORD_A:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);
|
||||
break;
|
||||
|
||||
case EX_HL_xSP:
|
||||
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->XX.B.l);
|
||||
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->XX.B.h);
|
||||
R->XX.W=J.W;
|
||||
break;
|
||||
|
||||
case DAA:
|
||||
J.W=R->AF.B.h;
|
||||
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||
R->AF.W=DAATable[J.W];
|
||||
break;
|
|
@ -0,0 +1,969 @@
|
|||
#include "options.h"
|
||||
|
||||
#include "Z80.h" /* Z80 CPU emulation */
|
||||
#include "SN76489.h" /* SN76489 PSG emulation */
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "emuapi.h"
|
||||
|
||||
|
||||
/**************************************
|
||||
* Local macros/typedef
|
||||
**************************************/
|
||||
#define WIDTH 256
|
||||
#define HEIGHT 192
|
||||
|
||||
#define MAXSCREEN 3 /* Highest screen mode supported */
|
||||
#define NORAM 0xFF /* Byte to be returned from */
|
||||
/* non-existing pages and ports */
|
||||
|
||||
/***** Following are macros to be used in screen drivers *****/
|
||||
#define BigSprites (VDP[1]&0x01) /* Zoomed sprites */
|
||||
#define Sprites16x16 (VDP[1]&0x02) /* 16x16/8x8 sprites */
|
||||
#define ScreenON (VDP[1]&0x40) /* Show screen */
|
||||
|
||||
/***************************************
|
||||
* Local procedures definition
|
||||
***************************************/
|
||||
static void snd_Reset(void);
|
||||
static void snd_Sound(int C, int F, int V);
|
||||
static void SetColor(byte N,byte R,byte G,byte B);
|
||||
static void RefreshSprites(byte Y);
|
||||
static void RefreshBorder(byte Y);
|
||||
static void RefreshLine0(byte Y);
|
||||
static void RefreshLine1(byte Y);
|
||||
static void RefreshLine2(byte Y);
|
||||
static void RefreshLine3(byte Y);
|
||||
static void RefreshScreen(void);
|
||||
static void VDPOut(byte Reg,byte Value); /* Write value into VDP */
|
||||
static void CheckSprites(void); /* Collisions/5th spr. */
|
||||
static void Play(int C,int F,int V); /* Log and play sound */
|
||||
|
||||
/***************************************
|
||||
* Local data
|
||||
***************************************/
|
||||
static byte * XBuf=0; // = (byte *)XBuf32;
|
||||
static byte XPal[16],XPal0;
|
||||
|
||||
|
||||
/*** TMS9918/9928 Palette *******************************************/
|
||||
struct { byte R,G,B; } Palette[16] =
|
||||
{
|
||||
{0x00,0x00,0x00},{0x00,0x00,0x00},{0x20,0xC0,0x20},{0x60,0xE0,0x60},
|
||||
{0x20,0x20,0xE0},{0x40,0x60,0xE0},{0xA0,0x20,0x20},{0x40,0xC0,0xE0},
|
||||
{0xE0,0x20,0x20},{0xE0,0x60,0x60},{0xC0,0xC0,0x20},{0xC0,0xC0,0x80},
|
||||
{0x20,0x80,0x20},{0xC0,0x40,0xA0},{0xA0,0xA0,0xA0},{0xE0,0xE0,0xE0}
|
||||
};
|
||||
|
||||
byte Verbose = 1; /* Debug msgs ON/OFF */
|
||||
byte UPeriod = 2; /* Interrupts/scr. update */
|
||||
int VPeriod = 60000; /* Number of cycles per VBlank */
|
||||
int HPeriod = 215; /* Number of cycles per HBlank */
|
||||
byte AutoA=0,AutoB=0; /* 1: Autofire for A,B buttons */
|
||||
byte Adam = 0; /* 1: Emulate Coleco Adam */
|
||||
|
||||
#define MEMRELOC -0x4000
|
||||
|
||||
#define VRAMSIZE 0x4000
|
||||
#define RAMSIZE 0xC000
|
||||
|
||||
|
||||
/* Main and Video RAMs */
|
||||
static byte * VRAM=0; //[VRAMSIZE];
|
||||
static byte * RAM=0; //RAM[RAMSIZE];
|
||||
//static byte VRAM[VRAMSIZE];
|
||||
//static byte RAM[RAMSIZE];
|
||||
|
||||
Z80 ccpu; /* Z80 CPU registers and state */
|
||||
SN76489 PSG; /* SN76489 PSG state */
|
||||
|
||||
byte *ChrGen,*ChrTab,*ColTab; /* VDP tables (screens) */
|
||||
byte *SprGen,*SprTab; /* VDP tables (sprites) */
|
||||
pair WVAddr,RVAddr; /* Storage for VRAM addresses */
|
||||
byte VKey; /* VDP address latch key */
|
||||
byte FGColor,BGColor; /* Colors */
|
||||
byte ScrMode; /* Current screen mode */
|
||||
byte CurLine; /* Current scanline */
|
||||
byte VDP[8],VDPStatus; /* VDP registers */
|
||||
|
||||
byte JoyMode; /* Joystick controller mode */
|
||||
word JoyState[2]; /* Joystick states */
|
||||
|
||||
/*** Screen handlers and masks for VDP table address registers ******/
|
||||
struct
|
||||
{
|
||||
void (*Refresh)(byte Y);
|
||||
byte R2,R3,R4,R5;
|
||||
} SCR[MAXSCREEN+1] =
|
||||
{
|
||||
{ RefreshLine0,0x7F,0x00,0x3F,0x00 }, /* SCREEN 0:TEXT 40x24 */
|
||||
{ RefreshLine1,0x7F,0xFF,0x3F,0xFF }, /* SCREEN 1:TEXT 32x24 */
|
||||
{ RefreshLine2,0x7F,0x80,0x3C,0xFF }, /* SCREEN 2:BLOCK 256x192 */
|
||||
{ RefreshLine3,0x7F,0x00,0x3F,0xFF } /* SCREEN 3:GFX 64x48x16 */
|
||||
};
|
||||
|
||||
/***************************************
|
||||
* Global data
|
||||
***************************************/
|
||||
|
||||
/***************************************
|
||||
* Exported procedures
|
||||
***************************************/
|
||||
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) + 0x7f;
|
||||
}
|
||||
else {
|
||||
keyCode = key & 0x7f;
|
||||
}
|
||||
|
||||
//Serial.println(keyCode);
|
||||
|
||||
if (keyCode != -1) {
|
||||
iusbhk = keyCode;
|
||||
}
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
iusbhk = 0;
|
||||
}
|
||||
|
||||
void coc_Input(int click) {
|
||||
ik = emu_GetPad();
|
||||
ihk = emu_ReadI2CKeyboard();
|
||||
}
|
||||
|
||||
void coc_Init(void)
|
||||
{
|
||||
int J;
|
||||
|
||||
/* Set up the palette */
|
||||
for(J=0;J<16;J++)
|
||||
SetColor(J,Palette[J].R,Palette[J].G,Palette[J].B);
|
||||
|
||||
if (VRAM == 0) VRAM = (byte *)emu_Malloc(VRAMSIZE);
|
||||
if (RAM == 0) RAM = (byte *)emu_Malloc(RAMSIZE);
|
||||
#if SINGLELINE_RENDERING
|
||||
if (XBuf == 0) XBuf = (byte *)emu_Malloc(WIDTH);
|
||||
#else
|
||||
if (XBuf == 0) XBuf = (byte *)emu_Malloc(WIDTH*HEIGHT);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int coc_Start(char * Cartridge)
|
||||
{
|
||||
int *T,I,J;
|
||||
char *P;
|
||||
|
||||
/*** VDP control register states: ***/
|
||||
static byte VDPInit[8] =
|
||||
{ 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
|
||||
/*** STARTUP CODE starts here: ***/
|
||||
T=(int *)"\01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
#ifdef LSB_FIRST
|
||||
if(*T!=1)
|
||||
{
|
||||
emu_printf("********** This machine is high-endian. **********\n");
|
||||
emu_printf("Take #define LSB_FIRST out and compile ColEm again.\n");
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
if(*T==1)
|
||||
{
|
||||
emu_printf("********** This machine is low-endian. **********\n");
|
||||
emu_printf("Insert #define LSB_FIRST and compile ColEm again.\n");
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Calculate IPeriod from VPeriod */
|
||||
if(UPeriod<1) UPeriod=1;
|
||||
if(VPeriod/HPeriod<256) VPeriod=256*HPeriod;
|
||||
ccpu.IPeriod=HPeriod;
|
||||
ccpu.TrapBadOps=Verbose&0x04;
|
||||
ccpu.IAutoReset=0;
|
||||
|
||||
memset(RAM,NORAM,RAMSIZE);
|
||||
memset(VRAM,NORAM,VRAMSIZE);
|
||||
|
||||
if(Verbose) emu_printf("OK\nLoading ROMs:\nOpening COLECO.ROM...");
|
||||
P=NULL;
|
||||
if (emu_LoadFile(ROMSDIR "/" "coleco.rom", (unsigned char *)RAM, 0x2000) != 0x2000)
|
||||
P="NOT FOUND OR SHORT FILE";
|
||||
|
||||
//if(P) { if(Verbose) puts(P);return(0); }
|
||||
if(Verbose) emu_printf("OK\nOpening ROM");
|
||||
if(Verbose) emu_printf(Cartridge);
|
||||
|
||||
P=NULL;
|
||||
J= emu_LoadFile(Cartridge, (unsigned char *)RAM+0x8000+MEMRELOC, 0x8000);
|
||||
|
||||
if(J<0x1000) P="SHORT FILE";
|
||||
I=RAM[0x8000+MEMRELOC];J=RAM[0x8001+MEMRELOC];
|
||||
if( !( ((I==0x55)&&(J==0xAA))||((I==0xAA)&&(J==0x55)) ) )
|
||||
P="INVALID IMAGE";
|
||||
|
||||
//if(P) { if(Verbose) puts(P);return(0); }
|
||||
if(Verbose) emu_printf("bytes loaded\n");
|
||||
|
||||
if(Verbose)
|
||||
{
|
||||
emu_printf("Initializing CPU and System Hardware:\n");
|
||||
//emu_printf(" VBlank = %d cycles\n HBlank = %d cycles\n",VPeriod,HPeriod);
|
||||
}
|
||||
|
||||
#ifdef HAS_SND
|
||||
snd_Reset();
|
||||
#endif
|
||||
#ifdef SOUND_PRESENT
|
||||
snd_Open(44100/*22050*/, 2, 4096/*16384*/,(void*)snd_Mixer);
|
||||
#endif
|
||||
|
||||
/* Initialize VDP registers */
|
||||
memcpy(VDP,VDPInit,sizeof(VDP));
|
||||
|
||||
/* Initialize internal variables */
|
||||
VKey=1; /* VDP address latch key */
|
||||
VDPStatus=0x9F; /* VDP status register */
|
||||
FGColor=BGColor=0; /* Fore/Background color */
|
||||
ScrMode=0; /* Current screenmode */
|
||||
CurLine=0; /* Current scanline */
|
||||
ChrTab=ColTab=ChrGen=VRAM; /* VDP tables (screen) */
|
||||
SprTab=SprGen=VRAM; /* VDP tables (sprites) */
|
||||
JoyMode=0; /* Joystick mode key */
|
||||
JoyState[0]=JoyState[1]=0xFFFF; /* Joystick states */
|
||||
Reset76489(&PSG,Play); /* Reset SN76489 PSG */
|
||||
Sync76489(&PSG,PSG_SYNC); /* Make it synchronous */
|
||||
ResetZ80(&ccpu); /* Reset Z80 registers */
|
||||
|
||||
if(Verbose) emu_printf("RUNNING ROM CODE...\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
void coc_Step(void)
|
||||
{
|
||||
//emu_printf("s");
|
||||
RunZ80(&ccpu);
|
||||
RunZ80(&ccpu);
|
||||
}
|
||||
|
||||
void coc_Stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
static void snd_Reset(void)
|
||||
{
|
||||
emu_sndInit();
|
||||
}
|
||||
|
||||
static void snd_Sound(int C, int F, int V)
|
||||
{
|
||||
emu_sndPlaySound(C, V, F);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Joysticks ************************************************/
|
||||
/** Check for keyboard events, parse them, and modify **/
|
||||
/** joystick controller status **/
|
||||
/*************************************************************/
|
||||
|
||||
void SetColor(byte N,byte R,byte G,byte B)
|
||||
{
|
||||
unsigned char val = R;
|
||||
XPal[N] = N; //(R&0xe0) | ((G>>3) & 0x1c) | ((B>>6) & 0x3); // RGBVAL(R,G,B); //(byte)lld_SetPaletteEntry(-1, R,G,B,0);
|
||||
emu_SetPaletteEntry(R,G,B,N);
|
||||
}
|
||||
|
||||
void Joysticks(void)
|
||||
{
|
||||
int N=0;
|
||||
word JS[2] = { 0xFFFF,0xFFFF };
|
||||
|
||||
int k = ik & 0x7fff;
|
||||
int hk = ihk;
|
||||
if (iusbhk) hk = iusbhk;
|
||||
|
||||
//if (k & 0x8000) N = 1;
|
||||
//else N = 0;
|
||||
|
||||
if(k)
|
||||
JS[N]=(JS[N]&0xFFF0)|(k-1);
|
||||
|
||||
switch(hk) {
|
||||
case 'q':
|
||||
case '1':
|
||||
hk = 2;
|
||||
break;
|
||||
case 'w':
|
||||
case '2':
|
||||
hk = 3;
|
||||
break;
|
||||
case 'e':
|
||||
case '3':
|
||||
hk = 4;
|
||||
break;
|
||||
case 'r':
|
||||
case '4':
|
||||
hk = 5;
|
||||
break;
|
||||
case 't':
|
||||
case '5':
|
||||
hk = 6;
|
||||
break;
|
||||
case 'y':
|
||||
case '6':
|
||||
hk = 7;
|
||||
break;
|
||||
case 'u':
|
||||
case '7':
|
||||
hk = 8;
|
||||
break;
|
||||
case 'i':
|
||||
case '8':
|
||||
hk = 9;
|
||||
break;
|
||||
case 'o':
|
||||
case '9':
|
||||
hk = 10;
|
||||
case 'p':
|
||||
case '0':
|
||||
hk = 1;
|
||||
break;
|
||||
default:
|
||||
hk = 0;
|
||||
break;
|
||||
};
|
||||
|
||||
if(hk)
|
||||
JS[N]=(JS[N]&0xFFF0)|(hk-1);
|
||||
|
||||
if (k & MASK_JOY2_BTN)
|
||||
{
|
||||
JS[N]&=0xBFFF; //Fire 1
|
||||
}
|
||||
if (k & MASK_KEY_USER1)
|
||||
{
|
||||
JS[N]&=0xFFBF; //Fire 2
|
||||
}
|
||||
if (k & MASK_KEY_USER2)
|
||||
{
|
||||
JS[0]=(JS[0]&0xFFF0)|(2); //1
|
||||
}
|
||||
// JS[0]=(JS[0]&0xFFF0)|(12);
|
||||
// JS[0]=(JS[0]&0xFFF0)|(13);
|
||||
|
||||
if (k & MASK_JOY2_DOWN)
|
||||
JS[N]&=0xFBFF; //Down
|
||||
if (k & MASK_JOY2_UP)
|
||||
JS[N]&=0xFEFF; //Up
|
||||
if (k & MASK_JOY2_RIGHT)
|
||||
JS[N]&=0xF7FF; //Right
|
||||
if (k & MASK_JOY2_LEFT)
|
||||
JS[N]&=0xFDFF; //Left
|
||||
|
||||
JoyState[0]=JS[0];JoyState[1]=JS[1];
|
||||
}
|
||||
|
||||
/** WrZ80() **************************************************/
|
||||
/** Z80 emulation calls this function to write byte V to **/
|
||||
/** address A of Z80 address space. **/
|
||||
/*************************************************************/
|
||||
void WrZ80(register word A,register byte V)
|
||||
{
|
||||
if((A>0x5FFF)&&(A<0x8000))
|
||||
{
|
||||
A&=0x03FF;
|
||||
RAM[0x6000+A+MEMRELOC]=RAM[0x6400+A+MEMRELOC]=RAM[0x6800+A+MEMRELOC]=RAM[0x6C00+A+MEMRELOC]=
|
||||
RAM[0x7000+A+MEMRELOC]=RAM[0x7400+A+MEMRELOC]=RAM[0x7800+A+MEMRELOC]=RAM[0x7C00+A+MEMRELOC]=V;
|
||||
}
|
||||
}
|
||||
|
||||
/** RdZ80() **************************************************/
|
||||
/** Z80 emulation calls this function to read a byte from **/
|
||||
/** address A of Z80 address space. Now moved to z80.c and **/
|
||||
/** made inlined to speed things up. **/
|
||||
/*************************************************************/
|
||||
|
||||
byte RdZ80(register word A) {
|
||||
if ( (A>=0x6000) && (A<0x10000) )
|
||||
return(RAM[A+MEMRELOC]);
|
||||
else
|
||||
return(RAM[A]);
|
||||
}
|
||||
|
||||
|
||||
/** PatchZ80() ***********************************************/
|
||||
/** Z80 emulation calls this function when it encounters a **/
|
||||
/** special patch command (ED FE) provided for user needs. **/
|
||||
/*************************************************************/
|
||||
void PatchZ80(Z80 *R) {}
|
||||
|
||||
/** InZ80() **************************************************/
|
||||
/** Z80 emulation calls this function to read a byte from **/
|
||||
/** a given I/O port. **/
|
||||
/*************************************************************/
|
||||
byte InZ80(register word Port)
|
||||
{
|
||||
static byte KeyCodes[16] =
|
||||
{
|
||||
0x0A,0x0D,0x07,0x0C,0x02,0x03,0x0E,0x05,
|
||||
0x01,0x0B,0x06,0x09,0x08,0x04,0x0F,0x0F,
|
||||
};
|
||||
|
||||
switch(Port&0xE0)
|
||||
{
|
||||
|
||||
case 0x40: /* Printer Status */
|
||||
if(Adam&&(Port==0x40)) return(0xFF);
|
||||
break;
|
||||
|
||||
case 0xE0: /* Joysticks Data */
|
||||
Port=(Port>>1)&0x01;
|
||||
Port=JoyMode?
|
||||
(JoyState[Port]>>8):
|
||||
(JoyState[Port]&0xF0)|KeyCodes[JoyState[Port]&0x0F];
|
||||
return((Port|0xB0)&0x7F);
|
||||
|
||||
case 0xA0: /* VDP Status/Data */
|
||||
if(Port&0x01) { Port=VDPStatus;VDPStatus&=0x5F;VKey=1; }
|
||||
else { Port=VRAM[RVAddr.W];RVAddr.W=(RVAddr.W+1)&0x3FFF; }
|
||||
return(Port);
|
||||
}
|
||||
|
||||
/* No such port */
|
||||
return(NORAM);
|
||||
}
|
||||
|
||||
/** OutZ80() *************************************************/
|
||||
/** Z80 emulation calls this function to write a byte to a **/
|
||||
/** given I/O port. **/
|
||||
/*************************************************************/
|
||||
void OutZ80(register word Port,register byte Value)
|
||||
{
|
||||
static byte SR,VR; /* Sound and VDP register storage */
|
||||
|
||||
switch(Port&0xE0)
|
||||
{
|
||||
|
||||
case 0x80: JoyMode=0;return;
|
||||
case 0xC0: JoyMode=1;return;
|
||||
case 0xE0: Write76489(&PSG,Value);return;
|
||||
|
||||
case 0x40:
|
||||
// if(Adam&&(Port==0x40)) fputc(Value,PrnStream);
|
||||
return;
|
||||
|
||||
case 0xA0:
|
||||
if(Port&0x01)
|
||||
if(VKey) { VR=Value;VKey--; }
|
||||
else
|
||||
{
|
||||
VKey++;
|
||||
switch(Value&0xC0)
|
||||
{
|
||||
case 0x80: VDPOut(Value&0x07,VR);break;
|
||||
case 0x40: WVAddr.B.l=VR;WVAddr.B.h=Value&0x3F;break;
|
||||
case 0x00: RVAddr.B.l=VR;RVAddr.B.h=Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(VKey)
|
||||
{ VRAM[WVAddr.W]=Value;WVAddr.W=(WVAddr.W+1)&0x3FFF; }
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** LoopZ80() ************************************************/
|
||||
/** Z80 emulation calls this function periodically to check **/
|
||||
/** if the system hardware requires any interrupts. **/
|
||||
/*************************************************************/
|
||||
word LoopZ80(Z80 *R, int * ras)
|
||||
{
|
||||
static byte UCount=0;
|
||||
static byte ACount=0;
|
||||
|
||||
/* Next scanline */
|
||||
CurLine=(CurLine+1)%193;
|
||||
|
||||
/* Refresh scanline if needed */
|
||||
if(CurLine<192)
|
||||
{
|
||||
if(!UCount) {
|
||||
(SCR[ScrMode].Refresh)(CurLine);
|
||||
#if SINGLELINE_RENDERING
|
||||
emu_DrawLine(XBuf, WIDTH, HEIGHT, CurLine);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
R->IPeriod=HPeriod;
|
||||
return(INT_NONE);
|
||||
}
|
||||
|
||||
/* End of screen reached... */
|
||||
|
||||
/* Set IPeriod to the beginning of next screen */
|
||||
R->IPeriod=VPeriod-HPeriod*192;
|
||||
|
||||
/* Check joysticks */
|
||||
Joysticks();
|
||||
|
||||
/* Autofire emulation */
|
||||
ACount=(ACount+1)&0x07;
|
||||
if(ACount>3)
|
||||
{
|
||||
if(AutoA) { JoyState[0]|=0x0040;JoyState[1]|=0x0040; }
|
||||
if(AutoB) { JoyState[0]|=0x4000;JoyState[1]|=0x4000; }
|
||||
}
|
||||
|
||||
|
||||
/* Flush any accumulated sound changes */
|
||||
Sync76489(&PSG,PSG_FLUSH);
|
||||
|
||||
/* Refresh screen if needed */
|
||||
if(UCount)
|
||||
UCount--;
|
||||
else
|
||||
{
|
||||
UCount=UPeriod-1;
|
||||
RefreshScreen();
|
||||
}
|
||||
|
||||
/* Setting VDPStatus flags */
|
||||
VDPStatus=(VDPStatus&0xDF)|0x80;
|
||||
|
||||
/* Checking sprites: */
|
||||
if(ScrMode) CheckSprites();
|
||||
|
||||
/* If exit requested, return INT_QUIT */
|
||||
// if(ExitNow) return(INT_QUIT);
|
||||
*ras = 1;
|
||||
/* Generate VDP interrupt */
|
||||
return(VKey&&(VDP[1]&0x20)? INT_NMI:INT_NONE);
|
||||
}
|
||||
|
||||
/** VDPOut() *************************************************/
|
||||
/** Emulator calls this function to write byte V into a VDP **/
|
||||
/** register R. **/
|
||||
/*************************************************************/
|
||||
void VDPOut(register byte R,register byte V)
|
||||
{
|
||||
register byte J;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0: switch(((V&0x0E)>>1)|(VDP[1]&0x18))
|
||||
{
|
||||
case 0x10: J=0;break;
|
||||
case 0x00: J=1;break;
|
||||
case 0x01: J=2;break;
|
||||
case 0x08: J=3;break;
|
||||
default: J=ScrMode;
|
||||
}
|
||||
if(J!=ScrMode)
|
||||
{
|
||||
ChrTab=VRAM+((long)(VDP[2]&SCR[J].R2)<<10);
|
||||
ChrGen=VRAM+((long)(VDP[4]&SCR[J].R4)<<11);
|
||||
ColTab=VRAM+((long)(VDP[3]&SCR[J].R3)<<6);
|
||||
SprTab=VRAM+((long)(VDP[5]&SCR[J].R5)<<7);
|
||||
SprGen=VRAM+((long)VDP[6]<<11);
|
||||
ScrMode=J;
|
||||
}
|
||||
break;
|
||||
case 1: switch(((VDP[0]&0x0E)>>1)|(V&0x18))
|
||||
{
|
||||
case 0x10: J=0;break;
|
||||
case 0x00: J=1;break;
|
||||
case 0x01: J=2;break;
|
||||
case 0x08: J=3;break;
|
||||
default: J=ScrMode;
|
||||
}
|
||||
if(J!=ScrMode)
|
||||
{
|
||||
ChrTab=VRAM+((long)(VDP[2]&SCR[J].R2)<<10);
|
||||
ChrGen=VRAM+((long)(VDP[4]&SCR[J].R4)<<11);
|
||||
ColTab=VRAM+((long)(VDP[3]&SCR[J].R3)<<6);
|
||||
SprTab=VRAM+((long)(VDP[5]&SCR[J].R5)<<7);
|
||||
SprGen=VRAM+((long)VDP[6]<<11);
|
||||
ScrMode=J;
|
||||
}
|
||||
break;
|
||||
case 2: ChrTab=VRAM+((long)(V&SCR[ScrMode].R2)<<10);break;
|
||||
case 3: ColTab=VRAM+((long)(V&SCR[ScrMode].R3)<<6);break;
|
||||
case 4: ChrGen=VRAM+((long)(V&SCR[ScrMode].R4)<<11);break;
|
||||
case 5: SprTab=VRAM+((long)(V&SCR[ScrMode].R5)<<7);break;
|
||||
case 6: V&=0x3F;SprGen=VRAM+((long)V<<11);break;
|
||||
case 7: FGColor=V>>4;BGColor=V&0x0F;break;
|
||||
|
||||
}
|
||||
VDP[R]=V;return;
|
||||
}
|
||||
|
||||
/** CheckSprites() *******************************************/
|
||||
/** This function is periodically called to check for the **/
|
||||
/** sprite collisions and 5th sprite, and set appropriate **/
|
||||
/** bits in the VDP status register. **/
|
||||
/*************************************************************/
|
||||
void CheckSprites(void)
|
||||
{
|
||||
register word LS,LD;
|
||||
register byte DH,DV,*PS,*PD,*T;
|
||||
byte I,J,N,*S,*D;
|
||||
|
||||
VDPStatus=(VDPStatus&0x9F)|0x1F;
|
||||
for(N=0,S=SprTab;(N<32)&&(S[0]!=208);N++,S+=4);
|
||||
|
||||
if(Sprites16x16)
|
||||
{
|
||||
for(J=0,S=SprTab;J<N;J++,S+=4)
|
||||
if(S[3]&0x0F)
|
||||
for(I=J+1,D=S+4;I<N;I++,D+=4)
|
||||
if(D[3]&0x0F)
|
||||
{
|
||||
DV=S[0]-D[0];
|
||||
if((DV<16)||(DV>240))
|
||||
{
|
||||
DH=S[1]-D[1];
|
||||
if((DH<16)||(DH>240))
|
||||
{
|
||||
PS=SprGen+((long)(S[2]&0xFC)<<3);
|
||||
PD=SprGen+((long)(D[2]&0xFC)<<3);
|
||||
if(DV<16) PD+=DV; else { DV=256-DV;PS+=DV; }
|
||||
if(DH>240) { DH=256-DH;T=PS;PS=PD;PD=T; }
|
||||
while(DV<16)
|
||||
{
|
||||
LS=((word)*PS<<8)+*(PS+16);
|
||||
LD=((word)*PD<<8)+*(PD+16);
|
||||
if(LD&(LS>>DH)) break;
|
||||
else { DV++;PS++;PD++; }
|
||||
}
|
||||
if(DV<16) { VDPStatus|=0x20;return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(J=0,S=SprTab;J<N;J++,S+=4)
|
||||
if(S[3]&0x0F)
|
||||
for(I=J+1,D=S+4;I<N;I++,D+=4)
|
||||
if(D[3]&0x0F)
|
||||
{
|
||||
DV=S[0]-D[0];
|
||||
if((DV<8)||(DV>248))
|
||||
{
|
||||
DH=S[1]-D[1];
|
||||
if((DH<8)||(DH>248))
|
||||
{
|
||||
PS=SprGen+((long)S[2]<<3);
|
||||
PD=SprGen+((long)D[2]<<3);
|
||||
if(DV<8) PD+=DV; else { DV=256-DV;PS+=DV; }
|
||||
if(DH>248) { DH=256-DH;T=PS;PS=PD;PD=T; }
|
||||
while((DV<8)&&!(*PD&(*PS>>DH))) { DV++;PS++;PD++; }
|
||||
if(DV<8) { VDPStatus|=0x20;return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Play() ***************************************************/
|
||||
/** Log and play sound of given frequency (Hz) and volume **/
|
||||
/** (0..255) via given channel (0..3). **/
|
||||
/*************************************************************/
|
||||
void Play(int C,int F,int V)
|
||||
{
|
||||
/* Play actual sound */
|
||||
#ifdef HAS_SND
|
||||
snd_Sound(C,F,V);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** RefreshScreen() ******************************************/
|
||||
/** Refresh screen. This function is called in the end of **/
|
||||
/** refresh cycle to show the entire screen. **/
|
||||
/*************************************************************/
|
||||
void RefreshScreen(void)
|
||||
{
|
||||
#if SINGLELINE_RENDERING
|
||||
#else
|
||||
emu_DrawScreen(XBuf, WIDTH, HEIGHT, WIDTH);
|
||||
#endif
|
||||
emu_DrawVsync();
|
||||
}
|
||||
|
||||
/** RefreshBorder() ******************************************/
|
||||
/** This function is called from RefreshLine#() to refresh **/
|
||||
/** the screen border. **/
|
||||
/*************************************************************/
|
||||
void RefreshBorder(register byte Y)
|
||||
{
|
||||
// if(!Y)
|
||||
// memset(XBuf,XPal[BGColor],WIDTH*(HEIGHT-192)/2);
|
||||
// if(Y==191)
|
||||
// memset(XBuf+WIDTH*(HEIGHT+192)/2,XPal[BGColor],WIDTH*(HEIGHT-192)/2);
|
||||
}
|
||||
|
||||
/** RefreshSprites() *****************************************/
|
||||
/** This function is called from RefreshLine#() to refresh **/
|
||||
/** sprites. **/
|
||||
/*************************************************************/
|
||||
void RefreshSprites(register byte Y)
|
||||
{
|
||||
register byte C,H;
|
||||
register byte *P,*PT,*AT;
|
||||
register int L,K;
|
||||
register unsigned int M;
|
||||
|
||||
H=Sprites16x16? 16:8;
|
||||
C=0;M=0;L=0;AT=SprTab-4;
|
||||
do
|
||||
{
|
||||
M<<=1;AT+=4;L++; /* Iterating through SprTab */
|
||||
K=AT[0]; /* K = sprite Y coordinate */
|
||||
if(K==208) break; /* Iteration terminates if Y=208 */
|
||||
if(K>256-H) K-=256; /* Y coordinate may be negative */
|
||||
|
||||
/* Mark all valid sprites with 1s, break at 4 sprites */
|
||||
if((Y>K)&&(Y<=K+H)) { M|=1;if(++C==4) break; }
|
||||
}
|
||||
while(L<32);
|
||||
|
||||
for(;M;M>>=1,AT-=4)
|
||||
if(M&1)
|
||||
{
|
||||
C=AT[3]; /* C = sprite attributes */
|
||||
L=C&0x80? AT[1]-32:AT[1]; /* Sprite may be shifted left by 32 */
|
||||
C&=0x0F; /* C = sprite color */
|
||||
|
||||
if((L<256)&&(L>-H)&&C)
|
||||
{
|
||||
K=AT[0]; /* K = sprite Y coordinate */
|
||||
if(K>256-H) K-=256; /* Y coordinate may be negative */
|
||||
|
||||
#if SINGLELINE_RENDERING
|
||||
P=XBuf+L;
|
||||
#else
|
||||
P=XBuf+WIDTH*(HEIGHT-192)/2+(WIDTH-256)/2+WIDTH*Y+L;
|
||||
#endif
|
||||
PT=SprGen+((int)(H>8? AT[2]&0xFC:AT[2])<<3)+Y-K-1;
|
||||
C=XPal[C];
|
||||
|
||||
/* Mask 1: clip left sprite boundary */
|
||||
K=L>=0? 0x0FFFF:(0x10000>>-L)-1;
|
||||
/* Mask 2: clip right sprite boundary */
|
||||
if(L>256-H) K^=((0x00200>>(H-8))<<(L-257+H))-1;
|
||||
/* Get and clip the sprite data */
|
||||
K&=((int)PT[0]<<8)|(H>8? PT[16]:0x00);
|
||||
|
||||
/* Draw left 8 pixels of the sprite */
|
||||
if(K&0xFF00)
|
||||
{
|
||||
if(K&0x8000) P[0]=C;if(K&0x4000) P[1]=C;
|
||||
if(K&0x2000) P[2]=C;if(K&0x1000) P[3]=C;
|
||||
if(K&0x0800) P[4]=C;if(K&0x0400) P[5]=C;
|
||||
if(K&0x0200) P[6]=C;if(K&0x0100) P[7]=C;
|
||||
}
|
||||
|
||||
/* Draw right 8 pixels of the sprite */
|
||||
if(K&0x00FF)
|
||||
{
|
||||
if(K&0x0080) P[8]=C; if(K&0x0040) P[9]=C;
|
||||
if(K&0x0020) P[10]=C;if(K&0x0010) P[11]=C;
|
||||
if(K&0x0008) P[12]=C;if(K&0x0004) P[13]=C;
|
||||
if(K&0x0002) P[14]=C;if(K&0x0001) P[15]=C;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** RefreshLine0() *******************************************/
|
||||
/** Refresh line Y (0..191) of SCREEN0, including sprites **/
|
||||
/** in this line. **/
|
||||
/*************************************************************/
|
||||
void RefreshLine0(register byte Y)
|
||||
{
|
||||
register byte X,K,Offset,FC,BC;
|
||||
register byte *P,*T;
|
||||
#if SINGLELINE_RENDERING
|
||||
P=XBuf;
|
||||
#else
|
||||
P=XBuf+WIDTH*(HEIGHT-192)/2+WIDTH*Y;
|
||||
#endif
|
||||
XPal[0]=BGColor? XPal[BGColor]:XPal0;
|
||||
|
||||
if(!ScreenON) memset(P,XPal[BGColor],WIDTH);
|
||||
else
|
||||
{
|
||||
BC=XPal[BGColor];
|
||||
FC=XPal[FGColor];
|
||||
T=ChrTab+(Y>>3)*40;
|
||||
Offset=Y&0x07;
|
||||
|
||||
//memset(P,BC,(WIDTH-240)/2);
|
||||
//P+=(WIDTH-240)/2;
|
||||
|
||||
for(X=0;X<40;X++)
|
||||
{
|
||||
K=ChrGen[((int)*T<<3)+Offset];
|
||||
P[0]=K&0x80? FC:BC;P[1]=K&0x40? FC:BC;
|
||||
P[2]=K&0x20? FC:BC;P[3]=K&0x10? FC:BC;
|
||||
P[4]=K&0x08? FC:BC;P[5]=K&0x04? FC:BC;
|
||||
P+=6;T++;
|
||||
}
|
||||
|
||||
//memset(P,BC,(WIDTH-240)/2);
|
||||
}
|
||||
|
||||
//RefreshBorder(Y);
|
||||
}
|
||||
|
||||
/** RefreshLine1() *******************************************/
|
||||
/** Refresh line Y (0..191) of SCREEN1, including sprites **/
|
||||
/** in this line. **/
|
||||
/*************************************************************/
|
||||
void RefreshLine1(register byte Y)
|
||||
{
|
||||
register byte X,K,Offset,FC,BC;
|
||||
register byte *P,*T;
|
||||
|
||||
#if SINGLELINE_RENDERING
|
||||
P=XBuf;
|
||||
#else
|
||||
P=XBuf+WIDTH*(HEIGHT-192)/2+WIDTH*Y;
|
||||
#endif
|
||||
XPal[0]=BGColor? XPal[BGColor]:XPal0;
|
||||
|
||||
if(!ScreenON) memset(P,XPal[BGColor],WIDTH);
|
||||
else
|
||||
{
|
||||
T=ChrTab+(Y>>3)*32;
|
||||
Offset=Y&0x07;
|
||||
|
||||
//memset(P,XPal[BGColor],(WIDTH-256)/2);
|
||||
//P+=(WIDTH-256)/2;
|
||||
|
||||
for(X=0;X<32;X++)
|
||||
{
|
||||
K=*T;
|
||||
BC=ColTab[K>>3];
|
||||
K=ChrGen[((int)K<<3)+Offset];
|
||||
FC=XPal[BC>>4];
|
||||
BC=XPal[BC&0x0F];
|
||||
P[0]=K&0x80? FC:BC;P[1]=K&0x40? FC:BC;
|
||||
P[2]=K&0x20? FC:BC;P[3]=K&0x10? FC:BC;
|
||||
P[4]=K&0x08? FC:BC;P[5]=K&0x04? FC:BC;
|
||||
P[6]=K&0x02? FC:BC;P[7]=K&0x01? FC:BC;
|
||||
P+=8;T++;
|
||||
}
|
||||
|
||||
//memset(P,XPal[BGColor],(WIDTH-256)/2);
|
||||
RefreshSprites(Y);
|
||||
}
|
||||
|
||||
RefreshBorder(Y);
|
||||
}
|
||||
|
||||
/** RefreshLine2() *******************************************/
|
||||
/** Refresh line Y (0..191) of SCREEN2, including sprites **/
|
||||
/** in this line. **/
|
||||
/*************************************************************/
|
||||
void RefreshLine2(register byte Y)
|
||||
{
|
||||
register byte X,K,FC,BC,Offset;
|
||||
register byte *P,*T,*PGT,*CLT;
|
||||
register int I;
|
||||
|
||||
#if SINGLELINE_RENDERING
|
||||
P=XBuf;
|
||||
#else
|
||||
P=XBuf+WIDTH*(HEIGHT-192)/2+WIDTH*Y;
|
||||
#endif
|
||||
XPal[0]=BGColor? XPal[BGColor]:XPal0;
|
||||
|
||||
if(!ScreenON) memset(P,XPal[BGColor],WIDTH);
|
||||
else
|
||||
{
|
||||
I=(int)(Y&0xC0)<<5;
|
||||
PGT=ChrGen+I;
|
||||
CLT=ColTab+I;
|
||||
T=ChrTab+(Y>>3)*32;
|
||||
Offset=Y&0x07;
|
||||
|
||||
//memset(P,XPal[BGColor],(WIDTH-256)/2);
|
||||
//P+=(WIDTH-256)/2;
|
||||
|
||||
for(X=0;X<32;X++)
|
||||
{
|
||||
I=((int)*T<<3)+Offset;
|
||||
K=PGT[I];
|
||||
BC=CLT[I];
|
||||
FC=XPal[BC>>4];
|
||||
BC=XPal[BC&0x0F];
|
||||
P[0]=K&0x80? FC:BC;P[1]=K&0x40? FC:BC;
|
||||
P[2]=K&0x20? FC:BC;P[3]=K&0x10? FC:BC;
|
||||
P[4]=K&0x08? FC:BC;P[5]=K&0x04? FC:BC;
|
||||
P[6]=K&0x02? FC:BC;P[7]=K&0x01? FC:BC;
|
||||
P+=8;T++;
|
||||
}
|
||||
|
||||
//memset(P,XPal[BGColor],(WIDTH-256)/2);
|
||||
RefreshSprites(Y);
|
||||
}
|
||||
|
||||
RefreshBorder(Y);
|
||||
}
|
||||
|
||||
/** RefreshLine3() *******************************************/
|
||||
/** Refresh line Y (0..191) of SCREEN3, including sprites **/
|
||||
/** in this line. **/
|
||||
/*************************************************************/
|
||||
void RefreshLine3(register byte Y)
|
||||
{
|
||||
register byte X,K,Offset;
|
||||
register byte *P,*T;
|
||||
|
||||
#if SINGLELINE_RENDERING
|
||||
P=XBuf;
|
||||
#else
|
||||
P=XBuf+WIDTH*(HEIGHT-192)/2+WIDTH*Y;
|
||||
#endif
|
||||
XPal[0]=BGColor? XPal[BGColor]:XPal0;
|
||||
|
||||
if(!ScreenON) memset(P,XPal[BGColor],WIDTH);
|
||||
else
|
||||
{
|
||||
T=ChrTab+(Y>>3)*32;
|
||||
Offset=(Y&0x1C)>>2;
|
||||
|
||||
//memset(P,XPal[BGColor],(WIDTH-256)/2);
|
||||
//P+=(WIDTH-256)/2;
|
||||
|
||||
for(X=0;X<32;X++)
|
||||
{
|
||||
K=ChrGen[((int)*T<<3)+Offset];
|
||||
P[0]=P[1]=P[2]=P[3]=XPal[K>>4];
|
||||
P[4]=P[5]=P[6]=P[7]=XPal[K&0x0F];
|
||||
P+=8;T++;
|
||||
}
|
||||
|
||||
//memset(P,XPal[BGColor],(WIDTH-256)/2);
|
||||
RefreshSprites(Y);
|
||||
}
|
||||
|
||||
RefreshBorder(Y);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
extern void coc_Init(void);
|
||||
extern void coc_Start(char * CartName);
|
||||
extern void coc_Step(void);
|
||||
extern void coc_Stop(void);
|
||||
extern void coc_Input(int click);
|
|
@ -0,0 +1,98 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** SN76489.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the SN76489 sound chip **/
|
||||
/** produced by Intel. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "SN76489.h"
|
||||
|
||||
/** Reset76489() *********************************************/
|
||||
/** Reset the sound chip. The user has to provide a pointer **/
|
||||
/** to a function Sound(Channel,Freq,Volume) used to make **/
|
||||
/** actual sound. **/
|
||||
/*************************************************************/
|
||||
void Reset76489(SN76489 *D,void (*Sound)(int,int,int))
|
||||
{
|
||||
register int J;
|
||||
|
||||
for(J=0;J<4;J++) D->Volume[J]=D->Freq[J]=0;
|
||||
D->NoiseMode=D->Buf=D->Changed=0x00;
|
||||
D->Sync=PSG_ASYNC;D->Sound=Sound;
|
||||
}
|
||||
|
||||
/** Sync76489() **********************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls, **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be PSG_SYNC, PSG_ASYNC to set/reset sync, or **/
|
||||
/** PSG_FLUSH to leave sync mode as it is. **/
|
||||
/*************************************************************/
|
||||
void Sync76489(SN76489 *D,unsigned char Sync)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
if(D->Sync&&D->Changed)
|
||||
{
|
||||
for(J=0,I=1;J<4;J++,I<<=1)
|
||||
if(D->Changed&I)
|
||||
D->Sound(J,D->Freq[J],D->Volume[J]);
|
||||
}
|
||||
D->Changed=0x00;
|
||||
if(Sync!=PSG_FLUSH) D->Sync=Sync;
|
||||
}
|
||||
|
||||
/** Write76489() *********************************************/
|
||||
/** Call this function to output a value V into the sound **/
|
||||
/** chip. **/
|
||||
/*************************************************************/
|
||||
void Write76489(SN76489 *D,unsigned char V)
|
||||
{
|
||||
register unsigned char N,J;
|
||||
register long L;
|
||||
|
||||
switch(V&0xF0)
|
||||
{
|
||||
case 0xE0:
|
||||
J=V&0x03;
|
||||
if(J==D->NoiseMode) return;
|
||||
switch(J)
|
||||
{
|
||||
case 0: D->Freq[3]=20000;break;
|
||||
case 1: D->Freq[3]=10000;break;
|
||||
case 2: D->Freq[3]=5000;break;
|
||||
case 3: D->Freq[3]=D->Freq[2];break;
|
||||
}
|
||||
N=3;break;
|
||||
case 0x80: case 0xA0: case 0xC0:
|
||||
D->Buf=V;return;
|
||||
case 0x90: case 0xB0: case 0xD0: case 0xF0:
|
||||
N=(V-0x90)>>5;
|
||||
J=(~V&0x0F)*16;
|
||||
if(J==D->Volume[N]) return;
|
||||
D->Volume[N]=J;
|
||||
break;
|
||||
default:
|
||||
if(!(D->Buf&0xC0)) return;
|
||||
N=(D->Buf-0x80)>>5;
|
||||
L=PSG_BASE/((V&0x3F)*16+(D->Buf&0x0F)+1);
|
||||
if(L>15000) L=0;
|
||||
if(L==D->Freq[N]) return;
|
||||
if((N==2)&&(D->NoiseMode==3))
|
||||
{
|
||||
D->Freq[3]=L;
|
||||
if(D->Sync) D->Changed|=0x08;
|
||||
else D->Sound(3,D->Freq[3],D->Volume[3]);
|
||||
}
|
||||
D->Freq[N]=L;
|
||||
break;
|
||||
}
|
||||
|
||||
if(D->Sync) D->Changed|=1<<N;
|
||||
else D->Sound(N,D->Freq[N],D->Volume[N]);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** SN76489.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the SN76489 sound chip **/
|
||||
/** produced by Intel. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef SN76489_H
|
||||
#define SN76489_H
|
||||
|
||||
#define PSG_BASE 131072 /* Base frequency for SN76489 */
|
||||
|
||||
#define PSG_ASYNC 0 /* Asynchronous emulation */
|
||||
#define PSG_SYNC 1 /* Synchronous emulation mode */
|
||||
#define PSG_FLUSH 2 /* Flush buffers only */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Channel,Freq[4],Volume[4],Sync;
|
||||
unsigned char NoiseMode,Buf,Changed;
|
||||
void (*Sound)(int,int,int);
|
||||
} SN76489;
|
||||
|
||||
/** Reset76489() *********************************************/
|
||||
/** Reset the sound chip. The user has to provide a pointer **/
|
||||
/** to a function Sound(Channel,Freq,Volume) used to make **/
|
||||
/** actual sound. **/
|
||||
/*************************************************************/
|
||||
void Reset76489(register SN76489 *D,void (*Sound)(int,int,int));
|
||||
|
||||
/** Sync76489() **********************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls, **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be PSG_SYNC, PSG_ASYNC to set/reset sync, or **/
|
||||
/** PSG_FLUSH to leave sync mode as it is. **/
|
||||
/*************************************************************/
|
||||
void Sync76489(register SN76489 *D,register unsigned char Sync);
|
||||
|
||||
/** Write76489() *********************************************/
|
||||
/** Call this function to output a value V into the sound **/
|
||||
/** chip. **/
|
||||
/*************************************************************/
|
||||
void Write76489(register SN76489 *D,register unsigned char V);
|
||||
|
||||
#endif /* SN76489_H */
|
|
@ -0,0 +1,447 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** Tables.h **/
|
||||
/** **/
|
||||
/** This file contains tables of used by Z80 emulation to **/
|
||||
/** compute SIGN,ZERO, PARITY flags, and decimal correction **/
|
||||
/** There are also timing tables for Z80 opcodes. This file **/
|
||||
/** is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
static byte Cycles[256] =
|
||||
{
|
||||
4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
|
||||
8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
|
||||
7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
|
||||
7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
|
||||
5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
|
||||
5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
|
||||
5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11
|
||||
};
|
||||
|
||||
static byte CyclesCB[256] =
|
||||
{
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8
|
||||
};
|
||||
|
||||
static byte CyclesED[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
12,12,15,20, 8,14, 8, 9,12,12,15,20, 0,14, 0, 9,
|
||||
12,12,15,20, 0, 0, 8, 9,12,12,15,20, 0, 0, 8, 9,
|
||||
12,12,15,20, 0, 0, 0,18,12,12,15,20, 0, 0, 0,18,
|
||||
12, 0,15,20, 0, 0, 0, 0,12,12,15,20, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
16,16,16,16, 0, 0, 0, 0,16,16,16,16, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static byte CyclesXX[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||
0,14,20,10, 9, 9, 9, 0, 0,15,20,10, 9, 9, 9, 0,
|
||||
0, 0, 0, 0,23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
19,19,19,19,19,19,19,19, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static byte CyclesXXCB[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0
|
||||
};
|
||||
|
||||
static byte ZSTable[256] =
|
||||
{
|
||||
Z_FLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG
|
||||
};
|
||||
|
||||
static byte PZSTable[256] =
|
||||
{
|
||||
Z_FLAG|P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||
P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||
P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||
P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
|
||||
0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
|
||||
S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG
|
||||
};
|
||||
|
||||
static word DAATable[2048] =
|
||||
{
|
||||
0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
|
||||
0x0808,0x090C,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,
|
||||
0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
|
||||
0x180C,0x1908,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,
|
||||
0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
|
||||
0x282C,0x2928,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,
|
||||
0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
|
||||
0x3828,0x392C,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,
|
||||
0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
|
||||
0x480C,0x4908,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,
|
||||
0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
|
||||
0x5808,0x590C,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,
|
||||
0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
|
||||
0x6828,0x692C,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,
|
||||
0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
|
||||
0x782C,0x7928,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,
|
||||
0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
|
||||
0x888C,0x8988,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,
|
||||
0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
|
||||
0x9888,0x998C,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||
0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,
|
||||
0x0809,0x090D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||
0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,
|
||||
0x180D,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||
0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,
|
||||
0x282D,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||
0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,
|
||||
0x3829,0x392D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||
0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,
|
||||
0x480D,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||
0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,
|
||||
0x5809,0x590D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||
0x6025,0x6121,0x6221,0x6325,0x6421,0x6525,0x6625,0x6721,
|
||||
0x6829,0x692D,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531,
|
||||
0x7021,0x7125,0x7225,0x7321,0x7425,0x7521,0x7621,0x7725,
|
||||
0x782D,0x7929,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591,
|
||||
0x8081,0x8185,0x8285,0x8381,0x8485,0x8581,0x8681,0x8785,
|
||||
0x888D,0x8989,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595,
|
||||
0x9085,0x9181,0x9281,0x9385,0x9481,0x9585,0x9685,0x9781,
|
||||
0x9889,0x998D,0xA0B5,0xA1B1,0xA2B1,0xA3B5,0xA4B1,0xA5B5,
|
||||
0xA0A5,0xA1A1,0xA2A1,0xA3A5,0xA4A1,0xA5A5,0xA6A5,0xA7A1,
|
||||
0xA8A9,0xA9AD,0xB0B1,0xB1B5,0xB2B5,0xB3B1,0xB4B5,0xB5B1,
|
||||
0xB0A1,0xB1A5,0xB2A5,0xB3A1,0xB4A5,0xB5A1,0xB6A1,0xB7A5,
|
||||
0xB8AD,0xB9A9,0xC095,0xC191,0xC291,0xC395,0xC491,0xC595,
|
||||
0xC085,0xC181,0xC281,0xC385,0xC481,0xC585,0xC685,0xC781,
|
||||
0xC889,0xC98D,0xD091,0xD195,0xD295,0xD391,0xD495,0xD591,
|
||||
0xD081,0xD185,0xD285,0xD381,0xD485,0xD581,0xD681,0xD785,
|
||||
0xD88D,0xD989,0xE0B1,0xE1B5,0xE2B5,0xE3B1,0xE4B5,0xE5B1,
|
||||
0xE0A1,0xE1A5,0xE2A5,0xE3A1,0xE4A5,0xE5A1,0xE6A1,0xE7A5,
|
||||
0xE8AD,0xE9A9,0xF0B5,0xF1B1,0xF2B1,0xF3B5,0xF4B1,0xF5B5,
|
||||
0xF0A5,0xF1A1,0xF2A1,0xF3A5,0xF4A1,0xF5A5,0xF6A5,0xF7A1,
|
||||
0xF8A9,0xF9AD,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||
0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,
|
||||
0x0809,0x090D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||
0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,
|
||||
0x180D,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||
0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,
|
||||
0x282D,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||
0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,
|
||||
0x3829,0x392D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||
0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,
|
||||
0x480D,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||
0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,
|
||||
0x5809,0x590D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||
0x0604,0x0700,0x0808,0x090C,0x0A0C,0x0B08,0x0C0C,0x0D08,
|
||||
0x0E08,0x0F0C,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,
|
||||
0x1600,0x1704,0x180C,0x1908,0x1A08,0x1B0C,0x1C08,0x1D0C,
|
||||
0x1E0C,0x1F08,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,
|
||||
0x2620,0x2724,0x282C,0x2928,0x2A28,0x2B2C,0x2C28,0x2D2C,
|
||||
0x2E2C,0x2F28,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,
|
||||
0x3624,0x3720,0x3828,0x392C,0x3A2C,0x3B28,0x3C2C,0x3D28,
|
||||
0x3E28,0x3F2C,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,
|
||||
0x4600,0x4704,0x480C,0x4908,0x4A08,0x4B0C,0x4C08,0x4D0C,
|
||||
0x4E0C,0x4F08,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,
|
||||
0x5604,0x5700,0x5808,0x590C,0x5A0C,0x5B08,0x5C0C,0x5D08,
|
||||
0x5E08,0x5F0C,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,
|
||||
0x6624,0x6720,0x6828,0x692C,0x6A2C,0x6B28,0x6C2C,0x6D28,
|
||||
0x6E28,0x6F2C,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,
|
||||
0x7620,0x7724,0x782C,0x7928,0x7A28,0x7B2C,0x7C28,0x7D2C,
|
||||
0x7E2C,0x7F28,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,
|
||||
0x8680,0x8784,0x888C,0x8988,0x8A88,0x8B8C,0x8C88,0x8D8C,
|
||||
0x8E8C,0x8F88,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,
|
||||
0x9684,0x9780,0x9888,0x998C,0x9A8C,0x9B88,0x9C8C,0x9D88,
|
||||
0x9E88,0x9F8C,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||
0x0605,0x0701,0x0809,0x090D,0x0A0D,0x0B09,0x0C0D,0x0D09,
|
||||
0x0E09,0x0F0D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||
0x1601,0x1705,0x180D,0x1909,0x1A09,0x1B0D,0x1C09,0x1D0D,
|
||||
0x1E0D,0x1F09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||
0x2621,0x2725,0x282D,0x2929,0x2A29,0x2B2D,0x2C29,0x2D2D,
|
||||
0x2E2D,0x2F29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||
0x3625,0x3721,0x3829,0x392D,0x3A2D,0x3B29,0x3C2D,0x3D29,
|
||||
0x3E29,0x3F2D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||
0x4601,0x4705,0x480D,0x4909,0x4A09,0x4B0D,0x4C09,0x4D0D,
|
||||
0x4E0D,0x4F09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||
0x5605,0x5701,0x5809,0x590D,0x5A0D,0x5B09,0x5C0D,0x5D09,
|
||||
0x5E09,0x5F0D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||
0x6625,0x6721,0x6829,0x692D,0x6A2D,0x6B29,0x6C2D,0x6D29,
|
||||
0x6E29,0x6F2D,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531,
|
||||
0x7621,0x7725,0x782D,0x7929,0x7A29,0x7B2D,0x7C29,0x7D2D,
|
||||
0x7E2D,0x7F29,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591,
|
||||
0x8681,0x8785,0x888D,0x8989,0x8A89,0x8B8D,0x8C89,0x8D8D,
|
||||
0x8E8D,0x8F89,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595,
|
||||
0x9685,0x9781,0x9889,0x998D,0x9A8D,0x9B89,0x9C8D,0x9D89,
|
||||
0x9E89,0x9F8D,0xA0B5,0xA1B1,0xA2B1,0xA3B5,0xA4B1,0xA5B5,
|
||||
0xA6A5,0xA7A1,0xA8A9,0xA9AD,0xAAAD,0xABA9,0xACAD,0xADA9,
|
||||
0xAEA9,0xAFAD,0xB0B1,0xB1B5,0xB2B5,0xB3B1,0xB4B5,0xB5B1,
|
||||
0xB6A1,0xB7A5,0xB8AD,0xB9A9,0xBAA9,0xBBAD,0xBCA9,0xBDAD,
|
||||
0xBEAD,0xBFA9,0xC095,0xC191,0xC291,0xC395,0xC491,0xC595,
|
||||
0xC685,0xC781,0xC889,0xC98D,0xCA8D,0xCB89,0xCC8D,0xCD89,
|
||||
0xCE89,0xCF8D,0xD091,0xD195,0xD295,0xD391,0xD495,0xD591,
|
||||
0xD681,0xD785,0xD88D,0xD989,0xDA89,0xDB8D,0xDC89,0xDD8D,
|
||||
0xDE8D,0xDF89,0xE0B1,0xE1B5,0xE2B5,0xE3B1,0xE4B5,0xE5B1,
|
||||
0xE6A1,0xE7A5,0xE8AD,0xE9A9,0xEAA9,0xEBAD,0xECA9,0xEDAD,
|
||||
0xEEAD,0xEFA9,0xF0B5,0xF1B1,0xF2B1,0xF3B5,0xF4B1,0xF5B5,
|
||||
0xF6A5,0xF7A1,0xF8A9,0xF9AD,0xFAAD,0xFBA9,0xFCAD,0xFDA9,
|
||||
0xFEA9,0xFFAD,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
|
||||
0x0605,0x0701,0x0809,0x090D,0x0A0D,0x0B09,0x0C0D,0x0D09,
|
||||
0x0E09,0x0F0D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
|
||||
0x1601,0x1705,0x180D,0x1909,0x1A09,0x1B0D,0x1C09,0x1D0D,
|
||||
0x1E0D,0x1F09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
|
||||
0x2621,0x2725,0x282D,0x2929,0x2A29,0x2B2D,0x2C29,0x2D2D,
|
||||
0x2E2D,0x2F29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
|
||||
0x3625,0x3721,0x3829,0x392D,0x3A2D,0x3B29,0x3C2D,0x3D29,
|
||||
0x3E29,0x3F2D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
|
||||
0x4601,0x4705,0x480D,0x4909,0x4A09,0x4B0D,0x4C09,0x4D0D,
|
||||
0x4E0D,0x4F09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
|
||||
0x5605,0x5701,0x5809,0x590D,0x5A0D,0x5B09,0x5C0D,0x5D09,
|
||||
0x5E09,0x5F0D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
|
||||
0x0046,0x0102,0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,
|
||||
0x080A,0x090E,0x0402,0x0506,0x0606,0x0702,0x080A,0x090E,
|
||||
0x1002,0x1106,0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,
|
||||
0x180E,0x190A,0x1406,0x1502,0x1602,0x1706,0x180E,0x190A,
|
||||
0x2022,0x2126,0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,
|
||||
0x282E,0x292A,0x2426,0x2522,0x2622,0x2726,0x282E,0x292A,
|
||||
0x3026,0x3122,0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,
|
||||
0x382A,0x392E,0x3422,0x3526,0x3626,0x3722,0x382A,0x392E,
|
||||
0x4002,0x4106,0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,
|
||||
0x480E,0x490A,0x4406,0x4502,0x4602,0x4706,0x480E,0x490A,
|
||||
0x5006,0x5102,0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,
|
||||
0x580A,0x590E,0x5402,0x5506,0x5606,0x5702,0x580A,0x590E,
|
||||
0x6026,0x6122,0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,
|
||||
0x682A,0x692E,0x6422,0x6526,0x6626,0x6722,0x682A,0x692E,
|
||||
0x7022,0x7126,0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,
|
||||
0x782E,0x792A,0x7426,0x7522,0x7622,0x7726,0x782E,0x792A,
|
||||
0x8082,0x8186,0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,
|
||||
0x888E,0x898A,0x8486,0x8582,0x8682,0x8786,0x888E,0x898A,
|
||||
0x9086,0x9182,0x9282,0x9386,0x9482,0x9586,0x9686,0x9782,
|
||||
0x988A,0x998E,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||
0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,
|
||||
0x480F,0x490B,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||
0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,
|
||||
0x580B,0x590F,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||
0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,
|
||||
0x682B,0x692F,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||
0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,
|
||||
0x782F,0x792B,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||
0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,
|
||||
0x888F,0x898B,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||
0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,
|
||||
0x988B,0x998F,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
|
||||
0xA0A7,0xA1A3,0xA2A3,0xA3A7,0xA4A3,0xA5A7,0xA6A7,0xA7A3,
|
||||
0xA8AB,0xA9AF,0xA4A3,0xA5A7,0xA6A7,0xA7A3,0xA8AB,0xA9AF,
|
||||
0xB0A3,0xB1A7,0xB2A7,0xB3A3,0xB4A7,0xB5A3,0xB6A3,0xB7A7,
|
||||
0xB8AF,0xB9AB,0xB4A7,0xB5A3,0xB6A3,0xB7A7,0xB8AF,0xB9AB,
|
||||
0xC087,0xC183,0xC283,0xC387,0xC483,0xC587,0xC687,0xC783,
|
||||
0xC88B,0xC98F,0xC483,0xC587,0xC687,0xC783,0xC88B,0xC98F,
|
||||
0xD083,0xD187,0xD287,0xD383,0xD487,0xD583,0xD683,0xD787,
|
||||
0xD88F,0xD98B,0xD487,0xD583,0xD683,0xD787,0xD88F,0xD98B,
|
||||
0xE0A3,0xE1A7,0xE2A7,0xE3A3,0xE4A7,0xE5A3,0xE6A3,0xE7A7,
|
||||
0xE8AF,0xE9AB,0xE4A7,0xE5A3,0xE6A3,0xE7A7,0xE8AF,0xE9AB,
|
||||
0xF0A7,0xF1A3,0xF2A3,0xF3A7,0xF4A3,0xF5A7,0xF6A7,0xF7A3,
|
||||
0xF8AB,0xF9AF,0xF4A3,0xF5A7,0xF6A7,0xF7A3,0xF8AB,0xF9AF,
|
||||
0x0047,0x0103,0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,
|
||||
0x080B,0x090F,0x0403,0x0507,0x0607,0x0703,0x080B,0x090F,
|
||||
0x1003,0x1107,0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,
|
||||
0x180F,0x190B,0x1407,0x1503,0x1603,0x1707,0x180F,0x190B,
|
||||
0x2023,0x2127,0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,
|
||||
0x282F,0x292B,0x2427,0x2523,0x2623,0x2727,0x282F,0x292B,
|
||||
0x3027,0x3123,0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,
|
||||
0x382B,0x392F,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||
0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,
|
||||
0x480F,0x490B,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||
0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,
|
||||
0x580B,0x590F,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||
0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,
|
||||
0x682B,0x692F,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||
0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,
|
||||
0x782F,0x792B,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||
0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,
|
||||
0x888F,0x898B,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||
0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,
|
||||
0x988B,0x998F,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
|
||||
0xFABE,0xFBBA,0xFCBE,0xFDBA,0xFEBA,0xFFBE,0x0046,0x0102,
|
||||
0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,0x080A,0x090E,
|
||||
0x0A1E,0x0B1A,0x0C1E,0x0D1A,0x0E1A,0x0F1E,0x1002,0x1106,
|
||||
0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,0x180E,0x190A,
|
||||
0x1A1A,0x1B1E,0x1C1A,0x1D1E,0x1E1E,0x1F1A,0x2022,0x2126,
|
||||
0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,0x282E,0x292A,
|
||||
0x2A3A,0x2B3E,0x2C3A,0x2D3E,0x2E3E,0x2F3A,0x3026,0x3122,
|
||||
0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,0x382A,0x392E,
|
||||
0x3A3E,0x3B3A,0x3C3E,0x3D3A,0x3E3A,0x3F3E,0x4002,0x4106,
|
||||
0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,0x480E,0x490A,
|
||||
0x4A1A,0x4B1E,0x4C1A,0x4D1E,0x4E1E,0x4F1A,0x5006,0x5102,
|
||||
0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,0x580A,0x590E,
|
||||
0x5A1E,0x5B1A,0x5C1E,0x5D1A,0x5E1A,0x5F1E,0x6026,0x6122,
|
||||
0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,0x682A,0x692E,
|
||||
0x6A3E,0x6B3A,0x6C3E,0x6D3A,0x6E3A,0x6F3E,0x7022,0x7126,
|
||||
0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,0x782E,0x792A,
|
||||
0x7A3A,0x7B3E,0x7C3A,0x7D3E,0x7E3E,0x7F3A,0x8082,0x8186,
|
||||
0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,0x888E,0x898A,
|
||||
0x8A9A,0x8B9E,0x8C9A,0x8D9E,0x8E9E,0x8F9A,0x9086,0x9182,
|
||||
0x9282,0x9386,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||
0x3A3F,0x3B3B,0x3C3F,0x3D3B,0x3E3B,0x3F3F,0x4003,0x4107,
|
||||
0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||
0x4A1B,0x4B1F,0x4C1B,0x4D1F,0x4E1F,0x4F1B,0x5007,0x5103,
|
||||
0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||
0x5A1F,0x5B1B,0x5C1F,0x5D1B,0x5E1B,0x5F1F,0x6027,0x6123,
|
||||
0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||
0x6A3F,0x6B3B,0x6C3F,0x6D3B,0x6E3B,0x6F3F,0x7023,0x7127,
|
||||
0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||
0x7A3B,0x7B3F,0x7C3B,0x7D3F,0x7E3F,0x7F3B,0x8083,0x8187,
|
||||
0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||
0x8A9B,0x8B9F,0x8C9B,0x8D9F,0x8E9F,0x8F9B,0x9087,0x9183,
|
||||
0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
|
||||
0x9A9F,0x9B9B,0x9C9F,0x9D9B,0x9E9B,0x9F9F,0xA0A7,0xA1A3,
|
||||
0xA2A3,0xA3A7,0xA4A3,0xA5A7,0xA6A7,0xA7A3,0xA8AB,0xA9AF,
|
||||
0xAABF,0xABBB,0xACBF,0xADBB,0xAEBB,0xAFBF,0xB0A3,0xB1A7,
|
||||
0xB2A7,0xB3A3,0xB4A7,0xB5A3,0xB6A3,0xB7A7,0xB8AF,0xB9AB,
|
||||
0xBABB,0xBBBF,0xBCBB,0xBDBF,0xBEBF,0xBFBB,0xC087,0xC183,
|
||||
0xC283,0xC387,0xC483,0xC587,0xC687,0xC783,0xC88B,0xC98F,
|
||||
0xCA9F,0xCB9B,0xCC9F,0xCD9B,0xCE9B,0xCF9F,0xD083,0xD187,
|
||||
0xD287,0xD383,0xD487,0xD583,0xD683,0xD787,0xD88F,0xD98B,
|
||||
0xDA9B,0xDB9F,0xDC9B,0xDD9F,0xDE9F,0xDF9B,0xE0A3,0xE1A7,
|
||||
0xE2A7,0xE3A3,0xE4A7,0xE5A3,0xE6A3,0xE7A7,0xE8AF,0xE9AB,
|
||||
0xEABB,0xEBBF,0xECBB,0xEDBF,0xEEBF,0xEFBB,0xF0A7,0xF1A3,
|
||||
0xF2A3,0xF3A7,0xF4A3,0xF5A7,0xF6A7,0xF7A3,0xF8AB,0xF9AF,
|
||||
0xFABF,0xFBBB,0xFCBF,0xFDBB,0xFEBB,0xFFBF,0x0047,0x0103,
|
||||
0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,0x080B,0x090F,
|
||||
0x0A1F,0x0B1B,0x0C1F,0x0D1B,0x0E1B,0x0F1F,0x1003,0x1107,
|
||||
0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,0x180F,0x190B,
|
||||
0x1A1B,0x1B1F,0x1C1B,0x1D1F,0x1E1F,0x1F1B,0x2023,0x2127,
|
||||
0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,0x282F,0x292B,
|
||||
0x2A3B,0x2B3F,0x2C3B,0x2D3F,0x2E3F,0x2F3B,0x3027,0x3123,
|
||||
0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
|
||||
0x3A3F,0x3B3B,0x3C3F,0x3D3B,0x3E3B,0x3F3F,0x4003,0x4107,
|
||||
0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
|
||||
0x4A1B,0x4B1F,0x4C1B,0x4D1F,0x4E1F,0x4F1B,0x5007,0x5103,
|
||||
0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
|
||||
0x5A1F,0x5B1B,0x5C1F,0x5D1B,0x5E1B,0x5F1F,0x6027,0x6123,
|
||||
0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
|
||||
0x6A3F,0x6B3B,0x6C3F,0x6D3B,0x6E3B,0x6F3F,0x7023,0x7127,
|
||||
0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
|
||||
0x7A3B,0x7B3F,0x7C3B,0x7D3F,0x7E3F,0x7F3B,0x8083,0x8187,
|
||||
0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
|
||||
0x8A9B,0x8B9F,0x8C9B,0x8D9F,0x8E9F,0x8F9B,0x9087,0x9183,
|
||||
0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F
|
||||
};
|
|
@ -0,0 +1,583 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** Z80.c **/
|
||||
/** **/
|
||||
/** This file contains implementation for Z80 CPU. Don't **/
|
||||
/** forget to provide RdZ80(), WrZ80(), InZ80(), OutZ80(), **/
|
||||
/** LoopZ80(), and PatchZ80() functions to accomodate the **/
|
||||
/** emulated machine's architecture. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#include "options.h"
|
||||
#include "Z80.h"
|
||||
#include "Tables.h"
|
||||
//#include <stdio.h>
|
||||
#define printf(...)
|
||||
|
||||
/** INLINE ***************************************************/
|
||||
/** Different compilers inline C functions differently. **/
|
||||
/*************************************************************/
|
||||
#ifdef __GNUC__
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define INLINE static
|
||||
#endif
|
||||
|
||||
/** System-Dependent Stuff ***********************************/
|
||||
/** This is system-dependent code put here to speed things **/
|
||||
/** up. It has to stay inlined to be fast. **/
|
||||
/*************************************************************/
|
||||
#ifdef COLEM
|
||||
extern byte *RAM;
|
||||
INLINE byte RdZ80(word A) { return(RAM[A]); }
|
||||
#endif
|
||||
#ifdef MG
|
||||
extern byte *Page[];
|
||||
INLINE byte RdZ80(word A) { return(Page[A>>13][A&0x1FFF]); }
|
||||
#endif
|
||||
#ifdef FMSX
|
||||
extern byte *RAM[],PSL[],SSLReg;
|
||||
INLINE byte RdZ80(word A)
|
||||
{
|
||||
if(A!=0xFFFF) return(RAM[A>>13][A&0x1FFF]);
|
||||
else return((PSL[3]==3)? ~SSLReg:RAM[7][0x1FFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define S(Fl) R->AF.B.l|=Fl
|
||||
#define R(Fl) R->AF.B.l&=~(Fl)
|
||||
#define FLAGS(Rg,Fl) R->AF.B.l=Fl|ZSTable[Rg]
|
||||
|
||||
#define M_RLC(Rg) \
|
||||
R->AF.B.l=Rg>>7;Rg=(Rg<<1)|R->AF.B.l;R->AF.B.l|=PZSTable[Rg]
|
||||
#define M_RRC(Rg) \
|
||||
R->AF.B.l=Rg&0x01;Rg=(Rg>>1)|(R->AF.B.l<<7);R->AF.B.l|=PZSTable[Rg]
|
||||
#define M_RL(Rg) \
|
||||
if(Rg&0x80) \
|
||||
{ \
|
||||
Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
|
||||
R->AF.B.l=PZSTable[Rg]|C_FLAG; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
|
||||
R->AF.B.l=PZSTable[Rg]; \
|
||||
}
|
||||
#define M_RR(Rg) \
|
||||
if(Rg&0x01) \
|
||||
{ \
|
||||
Rg=(Rg>>1)|(R->AF.B.l<<7); \
|
||||
R->AF.B.l=PZSTable[Rg]|C_FLAG; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Rg=(Rg>>1)|(R->AF.B.l<<7); \
|
||||
R->AF.B.l=PZSTable[Rg]; \
|
||||
}
|
||||
|
||||
#define M_SLA(Rg) \
|
||||
R->AF.B.l=Rg>>7;Rg<<=1;R->AF.B.l|=PZSTable[Rg]
|
||||
#define M_SRA(Rg) \
|
||||
R->AF.B.l=Rg&C_FLAG;Rg=(Rg>>1)|(Rg&0x80);R->AF.B.l|=PZSTable[Rg]
|
||||
|
||||
#define M_SLL(Rg) \
|
||||
R->AF.B.l=Rg>>7;Rg=(Rg<<1)|0x01;R->AF.B.l|=PZSTable[Rg]
|
||||
#define M_SRL(Rg) \
|
||||
R->AF.B.l=Rg&0x01;Rg>>=1;R->AF.B.l|=PZSTable[Rg]
|
||||
|
||||
#define M_BIT(Bit,Rg) \
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|Z_FLAG))|H_FLAG|(Rg&(1<<Bit)? 0:Z_FLAG)
|
||||
|
||||
#define M_SET(Bit,Rg) Rg|=1<<Bit
|
||||
#define M_RES(Bit,Rg) Rg&=~(1<<Bit)
|
||||
|
||||
#define M_POP(Rg) \
|
||||
R->Rg.B.l=RdZ80(R->SP.W++);R->Rg.B.h=RdZ80(R->SP.W++)
|
||||
#define M_PUSH(Rg) \
|
||||
WrZ80(--R->SP.W,R->Rg.B.h);WrZ80(--R->SP.W,R->Rg.B.l)
|
||||
|
||||
#define M_CALL \
|
||||
J.B.l=RdZ80(R->PC.W++);J.B.h=RdZ80(R->PC.W++); \
|
||||
WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l); \
|
||||
R->PC.W=J.W
|
||||
|
||||
#define M_JP J.B.l=RdZ80(R->PC.W++);J.B.h=RdZ80(R->PC.W);R->PC.W=J.W
|
||||
#define M_JR R->PC.W+=(offset)RdZ80(R->PC.W)+1
|
||||
#define M_RET R->PC.B.l=RdZ80(R->SP.W++);R->PC.B.h=RdZ80(R->SP.W++)
|
||||
|
||||
#define M_RST(Ad) \
|
||||
WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l);R->PC.W=Ad
|
||||
|
||||
#define M_LDWORD(Rg) \
|
||||
R->Rg.B.l=RdZ80(R->PC.W++);R->Rg.B.h=RdZ80(R->PC.W++)
|
||||
|
||||
#define M_ADD(Rg) \
|
||||
J.W=R->AF.B.h+Rg; \
|
||||
R->AF.B.l= \
|
||||
(~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
|
||||
J.B.h|ZSTable[J.B.l]| \
|
||||
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||
R->AF.B.h=J.B.l
|
||||
|
||||
#define M_SUB(Rg) \
|
||||
J.W=R->AF.B.h-Rg; \
|
||||
R->AF.B.l= \
|
||||
((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
|
||||
N_FLAG|-J.B.h|ZSTable[J.B.l]| \
|
||||
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||
R->AF.B.h=J.B.l
|
||||
|
||||
#define M_ADC(Rg) \
|
||||
J.W=R->AF.B.h+Rg+(R->AF.B.l&C_FLAG); \
|
||||
R->AF.B.l= \
|
||||
(~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
|
||||
J.B.h|ZSTable[J.B.l]| \
|
||||
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||
R->AF.B.h=J.B.l
|
||||
|
||||
#define M_SBC(Rg) \
|
||||
J.W=R->AF.B.h-Rg-(R->AF.B.l&C_FLAG); \
|
||||
R->AF.B.l= \
|
||||
((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
|
||||
N_FLAG|-J.B.h|ZSTable[J.B.l]| \
|
||||
((R->AF.B.h^Rg^J.B.l)&H_FLAG); \
|
||||
R->AF.B.h=J.B.l
|
||||
|
||||
#define M_CP(Rg) \
|
||||
J.W=R->AF.B.h-Rg; \
|
||||
R->AF.B.l= \
|
||||
((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
|
||||
N_FLAG|-J.B.h|ZSTable[J.B.l]| \
|
||||
((R->AF.B.h^Rg^J.B.l)&H_FLAG)
|
||||
|
||||
#define M_AND(Rg) R->AF.B.h&=Rg;R->AF.B.l=H_FLAG|PZSTable[R->AF.B.h]
|
||||
#define M_OR(Rg) R->AF.B.h|=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
|
||||
#define M_XOR(Rg) R->AF.B.h^=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
|
||||
#define M_IN(Rg) Rg=InZ80(R->BC.B.l);R->AF.B.l=PZSTable[Rg]|(R->AF.B.l&C_FLAG)
|
||||
|
||||
#define M_INC(Rg) \
|
||||
Rg++; \
|
||||
R->AF.B.l= \
|
||||
(R->AF.B.l&C_FLAG)|ZSTable[Rg]| \
|
||||
(Rg==0x80? V_FLAG:0)|(Rg&0x0F? 0:H_FLAG)
|
||||
|
||||
#define M_DEC(Rg) \
|
||||
Rg--; \
|
||||
R->AF.B.l= \
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[Rg]| \
|
||||
(Rg==0x7F? V_FLAG:0)|((Rg&0x0F)==0x0F? H_FLAG:0)
|
||||
|
||||
#define M_ADDW(Rg1,Rg2) \
|
||||
J.W=(R->Rg1.W+R->Rg2.W)&0xFFFF; \
|
||||
R->AF.B.l= \
|
||||
(R->AF.B.l&~(H_FLAG|N_FLAG|C_FLAG))| \
|
||||
((R->Rg1.W^R->Rg2.W^J.W)&0x1000? H_FLAG:0)| \
|
||||
(((long)R->Rg1.W+(long)R->Rg2.W)&0x10000? C_FLAG:0); \
|
||||
R->Rg1.W=J.W
|
||||
|
||||
#define M_ADCW(Rg) \
|
||||
I=R->AF.B.l&C_FLAG;J.W=(R->HL.W+R->Rg.W+I)&0xFFFF; \
|
||||
R->AF.B.l= \
|
||||
(((long)R->HL.W+(long)R->Rg.W+(long)I)&0x10000? C_FLAG:0)| \
|
||||
(~(R->HL.W^R->Rg.W)&(R->Rg.W^J.W)&0x8000? V_FLAG:0)| \
|
||||
((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)| \
|
||||
(J.W? 0:Z_FLAG)|(J.B.h&S_FLAG); \
|
||||
R->HL.W=J.W
|
||||
|
||||
#define M_SBCW(Rg) \
|
||||
I=R->AF.B.l&C_FLAG;J.W=(R->HL.W-R->Rg.W-I)&0xFFFF; \
|
||||
R->AF.B.l= \
|
||||
N_FLAG| \
|
||||
(((long)R->HL.W-(long)R->Rg.W-(long)I)&0x10000? C_FLAG:0)| \
|
||||
((R->HL.W^R->Rg.W)&(R->HL.W^J.W)&0x8000? V_FLAG:0)| \
|
||||
((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)| \
|
||||
(J.W? 0:Z_FLAG)|(J.B.h&S_FLAG); \
|
||||
R->HL.W=J.W
|
||||
|
||||
enum Codes
|
||||
{
|
||||
NOP,LD_BC_WORD,LD_xBC_A,INC_BC,INC_B,DEC_B,LD_B_BYTE,RLCA,
|
||||
EX_AF_AF,ADD_HL_BC,LD_A_xBC,DEC_BC,INC_C,DEC_C,LD_C_BYTE,RRCA,
|
||||
DJNZ,LD_DE_WORD,LD_xDE_A,INC_DE,INC_D,DEC_D,LD_D_BYTE,RLA,
|
||||
JR,ADD_HL_DE,LD_A_xDE,DEC_DE,INC_E,DEC_E,LD_E_BYTE,RRA,
|
||||
JR_NZ,LD_HL_WORD,LD_xWORD_HL,INC_HL,INC_H,DEC_H,LD_H_BYTE,DAA,
|
||||
JR_Z,ADD_HL_HL,LD_HL_xWORD,DEC_HL,INC_L,DEC_L,LD_L_BYTE,CPL,
|
||||
JR_NC,LD_SP_WORD,LD_xWORD_A,INC_SP,INC_xHL,DEC_xHL,LD_xHL_BYTE,SCF,
|
||||
JR_C,ADD_HL_SP,LD_A_xWORD,DEC_SP,INC_A,DEC_A,LD_A_BYTE,CCF,
|
||||
LD_B_B,LD_B_C,LD_B_D,LD_B_E,LD_B_H,LD_B_L,LD_B_xHL,LD_B_A,
|
||||
LD_C_B,LD_C_C,LD_C_D,LD_C_E,LD_C_H,LD_C_L,LD_C_xHL,LD_C_A,
|
||||
LD_D_B,LD_D_C,LD_D_D,LD_D_E,LD_D_H,LD_D_L,LD_D_xHL,LD_D_A,
|
||||
LD_E_B,LD_E_C,LD_E_D,LD_E_E,LD_E_H,LD_E_L,LD_E_xHL,LD_E_A,
|
||||
LD_H_B,LD_H_C,LD_H_D,LD_H_E,LD_H_H,LD_H_L,LD_H_xHL,LD_H_A,
|
||||
LD_L_B,LD_L_C,LD_L_D,LD_L_E,LD_L_H,LD_L_L,LD_L_xHL,LD_L_A,
|
||||
LD_xHL_B,LD_xHL_C,LD_xHL_D,LD_xHL_E,LD_xHL_H,LD_xHL_L,HALT,LD_xHL_A,
|
||||
LD_A_B,LD_A_C,LD_A_D,LD_A_E,LD_A_H,LD_A_L,LD_A_xHL,LD_A_A,
|
||||
ADD_B,ADD_C,ADD_D,ADD_E,ADD_H,ADD_L,ADD_xHL,ADD_A,
|
||||
ADC_B,ADC_C,ADC_D,ADC_E,ADC_H,ADC_L,ADC_xHL,ADC_A,
|
||||
SUB_B,SUB_C,SUB_D,SUB_E,SUB_H,SUB_L,SUB_xHL,SUB_A,
|
||||
SBC_B,SBC_C,SBC_D,SBC_E,SBC_H,SBC_L,SBC_xHL,SBC_A,
|
||||
AND_B,AND_C,AND_D,AND_E,AND_H,AND_L,AND_xHL,AND_A,
|
||||
XOR_B,XOR_C,XOR_D,XOR_E,XOR_H,XOR_L,XOR_xHL,XOR_A,
|
||||
OR_B,OR_C,OR_D,OR_E,OR_H,OR_L,OR_xHL,OR_A,
|
||||
CP_B,CP_C,CP_D,CP_E,CP_H,CP_L,CP_xHL,CP_A,
|
||||
RET_NZ,POP_BC,JP_NZ,JP,CALL_NZ,PUSH_BC,ADD_BYTE,RST00,
|
||||
RET_Z,RET,JP_Z,PFX_CB,CALL_Z,CALL,ADC_BYTE,RST08,
|
||||
RET_NC,POP_DE,JP_NC,OUTA,CALL_NC,PUSH_DE,SUB_BYTE,RST10,
|
||||
RET_C,EXX,JP_C,INA,CALL_C,PFX_DD,SBC_BYTE,RST18,
|
||||
RET_PO,POP_HL,JP_PO,EX_HL_xSP,CALL_PO,PUSH_HL,AND_BYTE,RST20,
|
||||
RET_PE,LD_PC_HL,JP_PE,EX_DE_HL,CALL_PE,PFX_ED,XOR_BYTE,RST28,
|
||||
RET_P,POP_AF,JP_P,DI,CALL_P,PUSH_AF,OR_BYTE,RST30,
|
||||
RET_M,LD_SP_HL,JP_M,EI,CALL_M,PFX_FD,CP_BYTE,RST38
|
||||
};
|
||||
|
||||
enum CodesCB
|
||||
{
|
||||
RLC_B,RLC_C,RLC_D,RLC_E,RLC_H,RLC_L,RLC_xHL,RLC_A,
|
||||
RRC_B,RRC_C,RRC_D,RRC_E,RRC_H,RRC_L,RRC_xHL,RRC_A,
|
||||
RL_B,RL_C,RL_D,RL_E,RL_H,RL_L,RL_xHL,RL_A,
|
||||
RR_B,RR_C,RR_D,RR_E,RR_H,RR_L,RR_xHL,RR_A,
|
||||
SLA_B,SLA_C,SLA_D,SLA_E,SLA_H,SLA_L,SLA_xHL,SLA_A,
|
||||
SRA_B,SRA_C,SRA_D,SRA_E,SRA_H,SRA_L,SRA_xHL,SRA_A,
|
||||
SLL_B,SLL_C,SLL_D,SLL_E,SLL_H,SLL_L,SLL_xHL,SLL_A,
|
||||
SRL_B,SRL_C,SRL_D,SRL_E,SRL_H,SRL_L,SRL_xHL,SRL_A,
|
||||
BIT0_B,BIT0_C,BIT0_D,BIT0_E,BIT0_H,BIT0_L,BIT0_xHL,BIT0_A,
|
||||
BIT1_B,BIT1_C,BIT1_D,BIT1_E,BIT1_H,BIT1_L,BIT1_xHL,BIT1_A,
|
||||
BIT2_B,BIT2_C,BIT2_D,BIT2_E,BIT2_H,BIT2_L,BIT2_xHL,BIT2_A,
|
||||
BIT3_B,BIT3_C,BIT3_D,BIT3_E,BIT3_H,BIT3_L,BIT3_xHL,BIT3_A,
|
||||
BIT4_B,BIT4_C,BIT4_D,BIT4_E,BIT4_H,BIT4_L,BIT4_xHL,BIT4_A,
|
||||
BIT5_B,BIT5_C,BIT5_D,BIT5_E,BIT5_H,BIT5_L,BIT5_xHL,BIT5_A,
|
||||
BIT6_B,BIT6_C,BIT6_D,BIT6_E,BIT6_H,BIT6_L,BIT6_xHL,BIT6_A,
|
||||
BIT7_B,BIT7_C,BIT7_D,BIT7_E,BIT7_H,BIT7_L,BIT7_xHL,BIT7_A,
|
||||
RES0_B,RES0_C,RES0_D,RES0_E,RES0_H,RES0_L,RES0_xHL,RES0_A,
|
||||
RES1_B,RES1_C,RES1_D,RES1_E,RES1_H,RES1_L,RES1_xHL,RES1_A,
|
||||
RES2_B,RES2_C,RES2_D,RES2_E,RES2_H,RES2_L,RES2_xHL,RES2_A,
|
||||
RES3_B,RES3_C,RES3_D,RES3_E,RES3_H,RES3_L,RES3_xHL,RES3_A,
|
||||
RES4_B,RES4_C,RES4_D,RES4_E,RES4_H,RES4_L,RES4_xHL,RES4_A,
|
||||
RES5_B,RES5_C,RES5_D,RES5_E,RES5_H,RES5_L,RES5_xHL,RES5_A,
|
||||
RES6_B,RES6_C,RES6_D,RES6_E,RES6_H,RES6_L,RES6_xHL,RES6_A,
|
||||
RES7_B,RES7_C,RES7_D,RES7_E,RES7_H,RES7_L,RES7_xHL,RES7_A,
|
||||
SET0_B,SET0_C,SET0_D,SET0_E,SET0_H,SET0_L,SET0_xHL,SET0_A,
|
||||
SET1_B,SET1_C,SET1_D,SET1_E,SET1_H,SET1_L,SET1_xHL,SET1_A,
|
||||
SET2_B,SET2_C,SET2_D,SET2_E,SET2_H,SET2_L,SET2_xHL,SET2_A,
|
||||
SET3_B,SET3_C,SET3_D,SET3_E,SET3_H,SET3_L,SET3_xHL,SET3_A,
|
||||
SET4_B,SET4_C,SET4_D,SET4_E,SET4_H,SET4_L,SET4_xHL,SET4_A,
|
||||
SET5_B,SET5_C,SET5_D,SET5_E,SET5_H,SET5_L,SET5_xHL,SET5_A,
|
||||
SET6_B,SET6_C,SET6_D,SET6_E,SET6_H,SET6_L,SET6_xHL,SET6_A,
|
||||
SET7_B,SET7_C,SET7_D,SET7_E,SET7_H,SET7_L,SET7_xHL,SET7_A
|
||||
};
|
||||
|
||||
enum CodesED
|
||||
{
|
||||
DB_00,DB_01,DB_02,DB_03,DB_04,DB_05,DB_06,DB_07,
|
||||
DB_08,DB_09,DB_0A,DB_0B,DB_0C,DB_0D,DB_0E,DB_0F,
|
||||
DB_10,DB_11,DB_12,DB_13,DB_14,DB_15,DB_16,DB_17,
|
||||
DB_18,DB_19,DB_1A,DB_1B,DB_1C,DB_1D,DB_1E,DB_1F,
|
||||
DB_20,DB_21,DB_22,DB_23,DB_24,DB_25,DB_26,DB_27,
|
||||
DB_28,DB_29,DB_2A,DB_2B,DB_2C,DB_2D,DB_2E,DB_2F,
|
||||
DB_30,DB_31,DB_32,DB_33,DB_34,DB_35,DB_36,DB_37,
|
||||
DB_38,DB_39,DB_3A,DB_3B,DB_3C,DB_3D,DB_3E,DB_3F,
|
||||
IN_B_xC,OUT_xC_B,SBC_HL_BC,LD_xWORDe_BC,NEG,RETN,IM_0,LD_I_A,
|
||||
IN_C_xC,OUT_xC_C,ADC_HL_BC,LD_BC_xWORDe,DB_4C,RETI,DB_,LD_R_A,
|
||||
IN_D_xC,OUT_xC_D,SBC_HL_DE,LD_xWORDe_DE,DB_54,DB_55,IM_1,LD_A_I,
|
||||
IN_E_xC,OUT_xC_E,ADC_HL_DE,LD_DE_xWORDe,DB_5C,DB_5D,IM_2,LD_A_R,
|
||||
IN_H_xC,OUT_xC_H,SBC_HL_HL,LD_xWORDe_HL,DB_64,DB_65,DB_66,RRD,
|
||||
IN_L_xC,OUT_xC_L,ADC_HL_HL,LD_HL_xWORDe,DB_6C,DB_6D,DB_6E,RLD,
|
||||
IN_F_xC,DB_71,SBC_HL_SP,LD_xWORDe_SP,DB_74,DB_75,DB_76,DB_77,
|
||||
IN_A_xC,OUT_xC_A,ADC_HL_SP,LD_SP_xWORDe,DB_7C,DB_7D,DB_7E,DB_7F,
|
||||
DB_80,DB_81,DB_82,DB_83,DB_84,DB_85,DB_86,DB_87,
|
||||
DB_88,DB_89,DB_8A,DB_8B,DB_8C,DB_8D,DB_8E,DB_8F,
|
||||
DB_90,DB_91,DB_92,DB_93,DB_94,DB_95,DB_96,DB_97,
|
||||
DB_98,DB_99,DB_9A,DB_9B,DB_9C,DB_9D,DB_9E,DB_9F,
|
||||
LDI,CPI,INI,OUTI,DB_A4,DB_A5,DB_A6,DB_A7,
|
||||
LDD,CPD,IND,OUTD,DB_AC,DB_AD,DB_AE,DB_AF,
|
||||
LDIR,CPIR,INIR,OTIR,DB_B4,DB_B5,DB_B6,DB_B7,
|
||||
LDDR,CPDR,INDR,OTDR,DB_BC,DB_BD,DB_BE,DB_BF,
|
||||
DB_C0,DB_C1,DB_C2,DB_C3,DB_C4,DB_C5,DB_C6,DB_C7,
|
||||
DB_C8,DB_C9,DB_CA,DB_CB,DB_CC,DB_CD,DB_CE,DB_CF,
|
||||
DB_D0,DB_D1,DB_D2,DB_D3,DB_D4,DB_D5,DB_D6,DB_D7,
|
||||
DB_D8,DB_D9,DB_DA,DB_DB,DB_DC,DB_DD,DB_DE,DB_DF,
|
||||
DB_E0,DB_E1,DB_E2,DB_E3,DB_E4,DB_E5,DB_E6,DB_E7,
|
||||
DB_E8,DB_E9,DB_EA,DB_EB,DB_EC,DB_ED,DB_EE,DB_EF,
|
||||
DB_F0,DB_F1,DB_F2,DB_F3,DB_F4,DB_F5,DB_F6,DB_F7,
|
||||
DB_F8,DB_F9,DB_FA,DB_FB,DB_FC,DB_FD,DB_FE,DB_FF
|
||||
};
|
||||
|
||||
static void CodesCB(register Z80 *R)
|
||||
{
|
||||
register byte I;
|
||||
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=CyclesCB[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "CodesCB.h"
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: CB %02X at PC=%04X\n",
|
||||
(long)(R->User),RdZ80(R->PC.W-1),R->PC.W-2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void CodesDDCB(register Z80 *R)
|
||||
{
|
||||
register pair J;
|
||||
register byte I;
|
||||
|
||||
#define XX IX
|
||||
J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=CyclesXXCB[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "CodesXCB.h"
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: DD CB %02X %02X at PC=%04X\n",
|
||||
(long)(R->User),RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4
|
||||
);
|
||||
}
|
||||
#undef XX
|
||||
}
|
||||
|
||||
static void CodesFDCB(register Z80 *R)
|
||||
{
|
||||
register pair J;
|
||||
register byte I;
|
||||
|
||||
#define XX IY
|
||||
J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=CyclesXXCB[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "CodesXCB.h"
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: FD CB %02X %02X at PC=%04X\n",
|
||||
(long)R->User,RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4
|
||||
);
|
||||
}
|
||||
#undef XX
|
||||
}
|
||||
|
||||
static void CodesED(register Z80 *R)
|
||||
{
|
||||
register byte I;
|
||||
register pair J;
|
||||
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=CyclesED[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "CodesED.h"
|
||||
case PFX_ED:
|
||||
R->PC.W--;break;
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: ED %02X at PC=%04X\n",
|
||||
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void CodesDD(register Z80 *R)
|
||||
{
|
||||
register byte I;
|
||||
register pair J;
|
||||
|
||||
#define XX IX
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=CyclesXX[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "CodesXX.h"
|
||||
case PFX_FD:
|
||||
case PFX_DD:
|
||||
R->PC.W--;break;
|
||||
case PFX_CB:
|
||||
CodesDDCB(R);break;
|
||||
case HALT:
|
||||
R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: DD %02X at PC=%04X\n",
|
||||
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-2
|
||||
);
|
||||
}
|
||||
#undef XX
|
||||
}
|
||||
|
||||
static void CodesFD(register Z80 *R)
|
||||
{
|
||||
register byte I;
|
||||
register pair J;
|
||||
|
||||
#define XX IY
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=CyclesXX[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "CodesXX.h"
|
||||
case PFX_FD:
|
||||
case PFX_DD:
|
||||
R->PC.W--;break;
|
||||
case PFX_CB:
|
||||
CodesFDCB(R);break;
|
||||
case HALT:
|
||||
R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||
default:
|
||||
printf
|
||||
(
|
||||
"Unrecognized instruction: FD %02X at PC=%04X\n",
|
||||
RdZ80(R->PC.W-1),R->PC.W-2
|
||||
);
|
||||
}
|
||||
#undef XX
|
||||
}
|
||||
|
||||
/** ResetZ80() ***********************************************/
|
||||
/** This function can be used to reset the register struct **/
|
||||
/** before starting execution with Z80(). It sets the **/
|
||||
/** registers to their supposed initial values. **/
|
||||
/*************************************************************/
|
||||
void ResetZ80(Z80 *R)
|
||||
{
|
||||
R->PC.W=0x0000;R->SP.W=0xF000;
|
||||
R->AF.W=R->BC.W=R->DE.W=R->HL.W=0x0000;
|
||||
R->AF1.W=R->BC1.W=R->DE1.W=R->HL1.W=0x0000;
|
||||
R->IX.W=R->IY.W=0x0000;
|
||||
R->I=0x00;R->IFF=0x00;
|
||||
R->ICount=R->IPeriod;
|
||||
R->IRequest=INT_NONE;
|
||||
}
|
||||
|
||||
/** ExecZ80() ************************************************/
|
||||
/** This function will execute a single Z80 opcode. It will **/
|
||||
/** then return next PC, and current register values in R. **/
|
||||
/*************************************************************/
|
||||
word ExecZ80(Z80 *R)
|
||||
{
|
||||
register byte I;
|
||||
register pair J;
|
||||
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=Cycles[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "Codes.h"
|
||||
case PFX_CB: CodesCB(R);break;
|
||||
case PFX_ED: CodesED(R);break;
|
||||
case PFX_FD: CodesFD(R);break;
|
||||
case PFX_DD: CodesDD(R);break;
|
||||
}
|
||||
|
||||
/* We are done */
|
||||
return(R->PC.W);
|
||||
}
|
||||
|
||||
/** IntZ80() *************************************************/
|
||||
/** This function will generate interrupt of given vector. **/
|
||||
/*************************************************************/
|
||||
void IntZ80(Z80 *R,word Vector)
|
||||
{
|
||||
if((R->IFF&0x01)||(Vector==INT_NMI))
|
||||
{
|
||||
/* Experimental V Shouldn't disable all interrupts? */
|
||||
R->IFF=(R->IFF&0x9E)|((R->IFF&0x01)<<6);
|
||||
if(R->IFF&0x80) { R->PC.W++;R->IFF&=0x7F; }
|
||||
M_PUSH(PC);
|
||||
|
||||
/* Automatically reset IRequest if needed */
|
||||
if(R->IAutoReset&&(Vector==R->IRequest)) R->IRequest=INT_NONE;
|
||||
|
||||
if(Vector==INT_NMI) R->PC.W=INT_NMI;
|
||||
else
|
||||
if(R->IFF&0x04)
|
||||
{
|
||||
Vector=(Vector&0xFF)|((word)(R->I)<<8);
|
||||
R->PC.B.l=RdZ80(Vector++);
|
||||
R->PC.B.h=RdZ80(Vector);
|
||||
}
|
||||
else
|
||||
if(R->IFF&0x02) R->PC.W=INT_IRQ;
|
||||
else R->PC.W=Vector;
|
||||
}
|
||||
}
|
||||
|
||||
/** RunZ80() *************************************************/
|
||||
/** This function will run Z80 code until an LoopZ80() call **/
|
||||
/** returns INT_QUIT. It will return the PC at which **/
|
||||
/** emulation stopped, and current register values in R. **/
|
||||
/*************************************************************/
|
||||
static byte I;
|
||||
static pair J;
|
||||
|
||||
word RunZ80(Z80 *R)
|
||||
{
|
||||
// register byte I;
|
||||
// register pair J;
|
||||
int ras=0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//#ifdef DEBUG
|
||||
// /* Turn tracing on when reached trap address */
|
||||
// if(R->PC.W==R->Trap) R->Trace=1;
|
||||
// /* Call single-step debugger, exit if requested */
|
||||
// if(R->Trace)
|
||||
// if(!DebugZ80(R)) return(R->PC.W);
|
||||
//#endif
|
||||
|
||||
I=RdZ80(R->PC.W++);
|
||||
R->ICount-=Cycles[I];
|
||||
switch(I)
|
||||
{
|
||||
#include "Codes.h"
|
||||
case PFX_CB: CodesCB(R);break;
|
||||
case PFX_ED: CodesED(R);break;
|
||||
case PFX_FD: CodesFD(R);break;
|
||||
case PFX_DD: CodesDD(R);break;
|
||||
}
|
||||
|
||||
/* If cycle counter expired... */
|
||||
if(R->ICount<=0)
|
||||
{
|
||||
/* If we have come after EI, get address from IRequest */
|
||||
/* Otherwise, get it from the loop handler */
|
||||
if(R->IFF&0x20)
|
||||
{
|
||||
J.W=R->IRequest; /* Get pending interrupt */
|
||||
R->ICount+=R->IBackup-1; /* Restore the ICount */
|
||||
R->IFF&=0xDF; /* Done with AfterEI state */
|
||||
}
|
||||
else
|
||||
{
|
||||
J.W=LoopZ80(R, &ras); /* Call periodic handler */
|
||||
R->ICount=R->IPeriod; /* Reset the cycle counter */
|
||||
if(J.W==INT_NONE) I=R->IRequest; /* Pending int-rupt */
|
||||
}
|
||||
|
||||
if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */
|
||||
if(J.W!=INT_NONE) IntZ80(R,J.W); /* Int-pt if needed */
|
||||
}
|
||||
if (ras == 1) break;
|
||||
}
|
||||
|
||||
/* Execution stopped */
|
||||
return(R->PC.W);
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** Z80.h **/
|
||||
/** **/
|
||||
/** This file contains declarations relevant to emulation **/
|
||||
/** of Z80 CPU. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef Z80_H
|
||||
#define Z80_H
|
||||
|
||||
/* Compilation options: */
|
||||
/* #define DEBUG */ /* Compile debugging version */
|
||||
/* #define LSB_FIRST */ /* Compile for low-endian CPU */
|
||||
/* #define MSB_FIRST */ /* Compile for hi-endian CPU */
|
||||
|
||||
/* LoopZ80() may return: */
|
||||
#define INT_IRQ 0x0038 /* Standard RST 38h interrupt */
|
||||
#define INT_NMI 0x0066 /* Non-maskable interrupt */
|
||||
#define INT_NONE 0xFFFF /* No interrupt required */
|
||||
#define INT_QUIT 0xFFFE /* Exit the emulation */
|
||||
|
||||
/* Bits in Z80 F register: */
|
||||
#define S_FLAG 0x80 /* 1: Result negative */
|
||||
#define Z_FLAG 0x40 /* 1: Result is zero */
|
||||
#define H_FLAG 0x10 /* 1: Halfcarry/Halfborrow */
|
||||
#define P_FLAG 0x04 /* 1: Result is even */
|
||||
#define V_FLAG 0x04 /* 1: Overflow occured */
|
||||
#define N_FLAG 0x02 /* 1: Subtraction occured */
|
||||
#define C_FLAG 0x01 /* 1: Carry/Borrow occured */
|
||||
|
||||
/** Simple Datatypes *****************************************/
|
||||
/** NOTICE: sizeof(byte)=1 and sizeof(word)=2 **/
|
||||
/*************************************************************/
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef signed char offset;
|
||||
|
||||
/** Structured Datatypes *************************************/
|
||||
/** NOTICE: #define LSB_FIRST for machines where least **/
|
||||
/** signifcant byte goes first. **/
|
||||
/*************************************************************/
|
||||
typedef union
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
struct { byte l,h; } B;
|
||||
#else
|
||||
struct { byte h,l; } B;
|
||||
#endif
|
||||
word W;
|
||||
} pair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pair AF,BC,DE,HL,IX,IY,PC,SP; /* Main registers */
|
||||
pair AF1,BC1,DE1,HL1; /* Shadow registers */
|
||||
byte IFF,I; /* Interrupt registers */
|
||||
byte R; /* Refresh register */
|
||||
|
||||
int IPeriod,ICount; /* Set IPeriod to number of CPU cycles */
|
||||
/* between calls to LoopZ80() */
|
||||
int IBackup; /* Private, don't touch */
|
||||
word IRequest; /* Set to address of pending IRQ */
|
||||
byte IAutoReset; /* Set to 1 to autom. reset IRequest */
|
||||
byte TrapBadOps; /* Set to 1 to warn of illegal opcodes */
|
||||
word Trap; /* Set Trap to address to trace from */
|
||||
byte Trace; /* Set Trace=1 to start tracing */
|
||||
void *User; /* Arbitrary user data (ID,RAM*,etc.) */
|
||||
} Z80;
|
||||
|
||||
/** ResetZ80() ***********************************************/
|
||||
/** This function can be used to reset the registers before **/
|
||||
/** starting execution with RunZ80(). It sets registers to **/
|
||||
/** their initial values. **/
|
||||
/*************************************************************/
|
||||
void ResetZ80(register Z80 *R);
|
||||
|
||||
/** ExecZ80() ************************************************/
|
||||
/** This function will execute a single Z80 opcode. It will **/
|
||||
/** then return next PC, and current register values in R. **/
|
||||
/*************************************************************/
|
||||
word ExecZ80(register Z80 *R);
|
||||
|
||||
/** IntZ80() *************************************************/
|
||||
/** This function will generate interrupt of given vector. **/
|
||||
/*************************************************************/
|
||||
void IntZ80(register Z80 *R,register word Vector);
|
||||
|
||||
/** RunZ80() *************************************************/
|
||||
/** This function will run Z80 code until an LoopZ80() call **/
|
||||
/** returns INT_QUIT. It will return the PC at which **/
|
||||
/** emulation stopped, and current register values in R. **/
|
||||
/*************************************************************/
|
||||
word RunZ80(register Z80 *R);
|
||||
|
||||
/** RdZ80()/WrZ80() ******************************************/
|
||||
/** These functions are called when access to RAM occurs. **/
|
||||
/** They allow to control memory access. **/
|
||||
/************************************ TO BE WRITTEN BY USER **/
|
||||
void WrZ80(register word Addr,register byte Value);
|
||||
byte RdZ80(register word Addr);
|
||||
|
||||
/** InZ80()/OutZ80() *****************************************/
|
||||
/** Z80 emulation calls these functions to read/write from **/
|
||||
/** I/O ports. There can be 65536 I/O ports, but only first **/
|
||||
/** 256 are usually used **/
|
||||
/************************************ TO BE WRITTEN BY USER **/
|
||||
void OutZ80(register word Port,register byte Value);
|
||||
byte InZ80(register word Port);
|
||||
|
||||
/** PatchZ80() ***********************************************/
|
||||
/** Z80 emulation calls this function when it encounters a **/
|
||||
/** special patch command (ED FE) provided for user needs. **/
|
||||
/** For example, it can be called to emulate BIOS calls, **/
|
||||
/** such as disk and tape access. Replace it with an empty **/
|
||||
/** macro for no patching. **/
|
||||
/************************************ TO BE WRITTEN BY USER **/
|
||||
void PatchZ80(register Z80 *R);
|
||||
|
||||
/** DebugZ80() ***********************************************/
|
||||
/** This function should exist if DEBUG is #defined. When **/
|
||||
/** Trace!=0, it is called after each command executed by **/
|
||||
/** the CPU, and given the Z80 registers. Emulation exits **/
|
||||
/** if DebugZ80() returns 0. **/
|
||||
/*************************************************************/
|
||||
byte DebugZ80(register Z80 *R);
|
||||
|
||||
/** LoopZ80() ************************************************/
|
||||
/** Z80 emulation calls this function periodically to check **/
|
||||
/** if the system hardware requires any interrupts. This **/
|
||||
/** function must return an address of the interrupt vector **/
|
||||
/** (0x0038, 0x0066, etc.) or INT_NONE for no interrupt. **/
|
||||
/** Return INT_QUIT to exit the emulation loop. **/
|
||||
/************************************ TO BE WRITTEN BY USER **/
|
||||
word LoopZ80(register Z80 *R, int * ras);
|
||||
|
||||
#endif /* Z80_H */
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,214 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
#define TITLE " Coleco Emulator"
|
||||
#define ROMSDIR "coleco"
|
||||
|
||||
#define emu_Init(ROM) {coc_Init();coc_Start(ROM);}
|
||||
#define emu_Step() {coc_Step();}
|
||||
#define emu_Input(x) {coc_Input(x);}
|
||||
|
||||
#define MAX_FILENAME_PATH 64
|
||||
#define NB_FILE_HANDLER 4
|
||||
#define PALETTE_SIZE 16
|
||||
#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',157, //lowecase
|
||||
0,'a','s','d','f','g','h','j','k','l',0x0D,
|
||||
0,'z','x','c','v','b','n','m',',','.',';','/',
|
||||
145,157,29,17,
|
||||
0,'+',' ','-'
|
||||
};
|
||||
|
||||
#define keylables_map1_0 (char *)"QWERTYUIOP@"
|
||||
#define keylables_map1_1 (char *)" ASDFGHJKL\x19"
|
||||
#define keylables_map1_2 (char *)" ZXCVBNM<>:?"
|
||||
#define keylables_map1_3 (char *)" =\x10_"
|
||||
const unsigned short key_map1[] = {
|
||||
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
|
||||
0,'A','S','D','F','G','H','J','K','L',0x0D,
|
||||
0,'Z','X','C','V','B','N','M','<','>',':','?',
|
||||
145,157,29,17,
|
||||
0,'=',' ','_'
|
||||
};
|
||||
|
||||
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
|
||||
#define keylables_map2_1 (char *)" |\\[]{} "
|
||||
#define keylables_map2_2 (char *)" <>:?"
|
||||
#define keylables_map2_3 (char *)" =\x10_"
|
||||
const unsigned short key_map2[] = {
|
||||
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
|
||||
0, '|','\\','[',']','{','}','\'',0,0,0,
|
||||
0, 0,0,0,0,0,0,0,'<','>',':','?',
|
||||
0,0,0,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,
|
||||
0,0,0,0,
|
||||
0,0,' ',0
|
||||
};
|
||||
|
||||
#define keylables_map4_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
|
||||
#define keylables_map4_1 (char *)" "
|
||||
#define keylables_map4_2 (char *)" "
|
||||
#define keylables_map4_3 (char *)" "
|
||||
|
||||
const unsigned short key_map4[] = {
|
||||
133,134,135,136,137,138,139,140,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,
|
||||
0,0,0,0,
|
||||
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,
|
||||
0,0,0,0,
|
||||
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
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
@ -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
|
|
@ -0,0 +1,132 @@
|
|||
/****************************************************************************
|
||||
* Purpose : Keyboard input driver.
|
||||
* Module : Keyboard
|
||||
* Author : J-M Harvengt
|
||||
* History : 10/08/97 Creation
|
||||
****************************************************************************/
|
||||
#ifndef _KEYBOARD
|
||||
#define _KEYBOARD
|
||||
|
||||
/****************************************************************************
|
||||
* Macros / typedefs
|
||||
****************************************************************************/
|
||||
#define SOURCE_REM 0x01
|
||||
#define SOURCE_PAD 0x02
|
||||
#define SOURCE_KEYB 0x03
|
||||
|
||||
/* keys id */
|
||||
#define KEY_UNKNOWN 0x00
|
||||
#define KEY_LEFT 0x01
|
||||
#define KEY_RIGHT 0x02
|
||||
#define KEY_UP 0x03
|
||||
#define KEY_DOWN 0x04
|
||||
#define KEY_SPACE 0x05
|
||||
|
||||
#define KEY_FONE 0x06
|
||||
#define KEY_FTWO 0x07
|
||||
#define KEY_FTHREE 0x08
|
||||
#define KEY_FFOUR 0x09
|
||||
#define KEY_FFIVE 0x0a
|
||||
#define KEY_FSIX 0x0b
|
||||
#define KEY_FSEVEN 0x0c
|
||||
#define KEY_FEIGHT 0x0d
|
||||
#define KEY_FNINE 0x0e
|
||||
#define KEY_FZERO 0x0f
|
||||
|
||||
#define KEY_ONE 0x10
|
||||
#define KEY_TWO 0x11
|
||||
#define KEY_THREE 0x12
|
||||
#define KEY_FOUR 0x13
|
||||
#define KEY_FIVE 0x14
|
||||
#define KEY_SIX 0x15
|
||||
#define KEY_SEVEN 0x16
|
||||
#define KEY_EIGHT 0x17
|
||||
#define KEY_NINE 0x18
|
||||
#define KEY_ZERO 0x19
|
||||
|
||||
#define KEY_OK KEY_SPACE
|
||||
#define KEY_BUT KEY_SPACE
|
||||
#define KEY_BACK KEY_FONE
|
||||
#define KEY_MENU KEY_FTWO
|
||||
#define KEY_TELEWEB KEY_FTHREE
|
||||
#define KEY_TELETEXT KEY_FFOUR
|
||||
#define KEY_COIN KEY_FTHREE
|
||||
#define KEY_ONEUP KEY_FFOUR
|
||||
|
||||
/* Bit mask for pad keys */
|
||||
#define JKEY_PLEFT 0x0001
|
||||
#define JKEY_PRIGHT 0x0002
|
||||
#define JKEY_PUP 0x0004
|
||||
#define JKEY_PDOWN 0x0008
|
||||
#define JKEY_PSPACE 0x0010
|
||||
#define JKEY_PONE 0x0020
|
||||
#define JKEY_PTWO 0x0040
|
||||
#define JKEY_PTHREE 0x0080
|
||||
#define JKEY_PFOUR 0x0100
|
||||
#define JKEY_PFIVE 0x0200
|
||||
#define JKEY_PSIX 0x0400
|
||||
#define JKEY_PSEVEN 0x0800
|
||||
#define JKEY_PEIGHT 0x1000
|
||||
#define JKEY_PNINE 0x2000
|
||||
#define JKEY_PZERO 0x4000
|
||||
|
||||
#define JKEY_LEFT 0x00010000
|
||||
#define JKEY_RIGHT 0x00020000
|
||||
#define JKEY_UP 0x00040000
|
||||
#define JKEY_DOWN 0x00080000
|
||||
#define JKEY_SPACE 0x00100000
|
||||
#define JKEY_ONE 0x00200000
|
||||
#define JKEY_TWO 0x00400000
|
||||
#define JKEY_THREE 0x00800000
|
||||
#define JKEY_FOUR 0x01000000
|
||||
#define JKEY_FIVE 0x02000000
|
||||
#define JKEY_SIX 0x04000000
|
||||
#define JKEY_SEVEN 0x08000000
|
||||
#define JKEY_EIGHT 0x10000000
|
||||
#define JKEY_NINE 0x20000000
|
||||
#define JKEY_ZERO 0x40000000
|
||||
|
||||
#define JKEY_OK JKEY_SPACE
|
||||
#define JKEY_BUT JKEY_SPACE
|
||||
#define JKEY_BACK JKEY_ONE
|
||||
#define JKEY_MENU JKEY_TWO
|
||||
#define JKEY_TELEWEB JKEY_THREE
|
||||
#define JKEY_TELETEXT JKEY_FOUR
|
||||
#define JKEY_COIN JKEY_THREE
|
||||
#define JKEY_ONEUP JKEY_FOUR
|
||||
#define JKEY_PPLUS JKEY_EIGHT
|
||||
#define JKEY_PMINUS JKEY_NINE
|
||||
|
||||
#define JKEY_POK JKEY_PSPACE
|
||||
#define JKEY_PBUT JKEY_PSPACE
|
||||
#define JKEY_PBACK JKEY_PONE
|
||||
#define JKEY_PMENU JKEY_PTWO
|
||||
#define JKEY_PTELEWEB JKEY_PTHREE
|
||||
#define JKEY_PTELETEXT JKEY_PFOUR
|
||||
#define JKEY_PEPG JKEY_PFIVE
|
||||
#define JKEY_PCOIN JKEY_PTHREE
|
||||
#define JKEY_PONEUP JKEY_PFOUR
|
||||
#define JKEY_PPPLUS JKEY_PEIGHT
|
||||
#define JKEY_PPMINUS JKEY_PNINE
|
||||
|
||||
/* Bit mask for mouse button */
|
||||
#define LMOUSEDOWN 0x40
|
||||
#define LMOUSEUP 0x80
|
||||
|
||||
/****************************************************************************
|
||||
* Exported procedures
|
||||
****************************************************************************/
|
||||
extern void key_Init(void);
|
||||
extern void key_TurnOn(void);
|
||||
extern void key_TurnOff(void);
|
||||
|
||||
extern void key_OnKeyDown(int aSource, int aKey);
|
||||
extern void key_OnKeyUp(int aSource, int aKey);
|
||||
extern void key_SubscribeKeyUp(void * callback);
|
||||
extern void key_SubscribeKeyDown(void * callback);
|
||||
extern void key_OnKeyTimer(void);
|
||||
extern int key_GetKeyPad(void);
|
||||
|
||||
extern void key_OnMouseMove(int x, int y, int b);
|
||||
extern void key_GetMouseMove(int *x, int *y, int *b);
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#define LSB_FIRST 1
|
|
@ -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
|
|
@ -0,0 +1,205 @@
|
|||
extern "C" {
|
||||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#include "Colem.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, 20000); //to run every 20ms
|
||||
myTimer.begin(vblCount, 16666); //to run every 16.6666ms
|
||||
}
|
||||
delay(20);
|
||||
}
|
||||
else {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
emu_Step();
|
||||
//delay(20);
|
||||
delay(16);
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
Plik diff jest za duży
Load Diff
|
@ -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 256
|
||||
#define TFT_REALWIDTH 320
|
||||
#endif
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_REALHEIGHT 240
|
||||
|
||||
//#define WIDTH 272
|
||||
//#define HEIGHT 228
|
||||
|
||||
#define LINES_PER_BLOCK 64
|
||||
#define NR_OF_BLOCK 4
|
||||
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
|
||||
|
||||
|
||||
#ifdef ILI9341
|
||||
|
||||
#define ILI9341_NOP 0x00
|
||||
#define ILI9341_SWRESET 0x01
|
||||
#define ILI9341_RDDID 0x04
|
||||
#define ILI9341_RDDST 0x09
|
||||
|
||||
#define ILI9341_SLPIN 0x10
|
||||
#define ILI9341_SLPOUT 0x11
|
||||
#define ILI9341_PTLON 0x12
|
||||
#define ILI9341_NORON 0x13
|
||||
|
||||
#define ILI9341_RDMODE 0x0A
|
||||
#define ILI9341_RDMADCTL 0x0B
|
||||
#define ILI9341_RDPIXFMT 0x0C
|
||||
#define ILI9341_RDIMGFMT 0x0D
|
||||
#define ILI9341_RDSELFDIAG 0x0F
|
||||
|
||||
#define ILI9341_INVOFF 0x20
|
||||
#define ILI9341_INVON 0x21
|
||||
#define ILI9341_GAMMASET 0x26
|
||||
#define ILI9341_DISPOFF 0x28
|
||||
#define ILI9341_DISPON 0x29
|
||||
|
||||
#define ILI9341_CASET 0x2A
|
||||
#define ILI9341_PASET 0x2B
|
||||
#define ILI9341_RAMWR 0x2C
|
||||
#define ILI9341_RAMRD 0x2E
|
||||
|
||||
#define ILI9341_PTLAR 0x30
|
||||
#define ILI9341_MADCTL 0x36
|
||||
#define ILI9341_VSCRSADD 0x37
|
||||
#define ILI9341_PIXFMT 0x3A
|
||||
|
||||
#define ILI9341_FRMCTR1 0xB1
|
||||
#define ILI9341_FRMCTR2 0xB2
|
||||
#define ILI9341_FRMCTR3 0xB3
|
||||
#define ILI9341_INVCTR 0xB4
|
||||
#define ILI9341_DFUNCTR 0xB6
|
||||
|
||||
#define ILI9341_PWCTR1 0xC0
|
||||
#define ILI9341_PWCTR2 0xC1
|
||||
#define ILI9341_PWCTR3 0xC2
|
||||
#define ILI9341_PWCTR4 0xC3
|
||||
#define ILI9341_PWCTR5 0xC4
|
||||
#define ILI9341_VMCTR1 0xC5
|
||||
#define ILI9341_VMCTR2 0xC7
|
||||
|
||||
#define ILI9341_RDID1 0xDA
|
||||
#define ILI9341_RDID2 0xDB
|
||||
#define ILI9341_RDID3 0xDC
|
||||
#define ILI9341_RDID4 0xDD
|
||||
|
||||
#define ILI9341_GMCTRP1 0xE0
|
||||
#define ILI9341_GMCTRN1 0xE1
|
||||
|
||||
#define ILI9341_MADCTL_MY 0x80
|
||||
#define ILI9341_MADCTL_MX 0x40
|
||||
#define ILI9341_MADCTL_MV 0x20
|
||||
#define ILI9341_MADCTL_ML 0x10
|
||||
#define ILI9341_MADCTL_RGB 0x00
|
||||
#define ILI9341_MADCTL_BGR 0x08
|
||||
#define ILI9341_MADCTL_MH 0x04
|
||||
|
||||
#define TFT_CASET ILI9341_CASET
|
||||
#define TFT_PASET ILI9341_PASET
|
||||
#define TFT_RAMWR ILI9341_RAMWR
|
||||
#define TFT_MADCTL ILI9341_MADCTL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ST7789
|
||||
|
||||
#define ST7735_NOP 0x00
|
||||
#define ST7735_SWRESET 0x01
|
||||
#define ST7735_RDDID 0x04
|
||||
#define ST7735_RDDST 0x09
|
||||
|
||||
#define ST7735_SLPIN 0x10
|
||||
#define ST7735_SLPOUT 0x11
|
||||
#define ST7735_PTLON 0x12
|
||||
#define ST7735_NORON 0x13
|
||||
|
||||
#define ST7735_INVOFF 0x20
|
||||
#define ST7735_INVON 0x21
|
||||
#define ST7735_DISPOFF 0x28
|
||||
#define ST7735_DISPON 0x29
|
||||
#define ST7735_CASET 0x2A
|
||||
#define ST7735_RASET 0x2B
|
||||
#define ST7735_RAMWR 0x2C
|
||||
#define ST7735_RAMRD 0x2E
|
||||
|
||||
#define ST7735_PTLAR 0x30
|
||||
#define ST7735_COLMOD 0x3A
|
||||
#define ST7735_MADCTL 0x36
|
||||
|
||||
#define ST7735_FRMCTR1 0xB1
|
||||
#define ST7735_FRMCTR2 0xB2
|
||||
#define ST7735_FRMCTR3 0xB3
|
||||
#define ST7735_INVCTR 0xB4
|
||||
#define ST7735_DISSET5 0xB6
|
||||
|
||||
#define ST7735_PWCTR1 0xC0
|
||||
#define ST7735_PWCTR2 0xC1
|
||||
#define ST7735_PWCTR3 0xC2
|
||||
#define ST7735_PWCTR4 0xC3
|
||||
#define ST7735_PWCTR5 0xC4
|
||||
#define ST7735_VMCTR1 0xC5
|
||||
|
||||
#define ST7735_RDID1 0xDA
|
||||
#define ST7735_RDID2 0xDB
|
||||
#define ST7735_RDID3 0xDC
|
||||
#define ST7735_RDID4 0xDD
|
||||
|
||||
#define ST7735_PWCTR6 0xFC
|
||||
|
||||
#define ST7735_GMCTRP1 0xE0
|
||||
#define ST7735_GMCTRN1 0xE1
|
||||
|
||||
#define ST77XX_MADCTL_MY 0x80
|
||||
#define ST77XX_MADCTL_MX 0x40
|
||||
#define ST77XX_MADCTL_MV 0x20
|
||||
#define ST77XX_MADCTL_ML 0x10
|
||||
#define ST77XX_MADCTL_RGB 0x00
|
||||
#define ST77XX_MADCTL_BGR 0x08
|
||||
#define ST77XX_MADCTL_MH 0x04
|
||||
|
||||
#define TFT_CASET ST7735_CASET
|
||||
#define TFT_PASET ST7735_RASET
|
||||
#define TFT_RAMWR ST7735_RAMWR
|
||||
#define TFT_MADCTL ST7735_MADCTL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class TFT_T_DMA
|
||||
{
|
||||
public:
|
||||
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
|
||||
|
||||
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
|
||||
void begin(void);
|
||||
void flipscreen(bool flip);
|
||||
boolean isflipped(void);
|
||||
void startDMA(void);
|
||||
void stopDMA();
|
||||
int get_frame_buffer_size(int *width, int *height);
|
||||
|
||||
// Touch screen functions
|
||||
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
|
||||
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
|
||||
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
|
||||
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
|
||||
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
|
||||
|
||||
// NoDMA functions
|
||||
void writeScreenNoDma(const uint16_t *pcolors);
|
||||
void fillScreenNoDma(uint16_t color);
|
||||
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
|
||||
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
|
||||
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
|
||||
|
||||
// DMA functions
|
||||
uint16_t * getLineBuffer(int j);
|
||||
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
|
||||
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
|
||||
void writeLine(int width, int height, int y, uint16_t *buf);
|
||||
void fillScreen(uint16_t color);
|
||||
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
|
||||
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
|
||||
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
|
||||
|
||||
protected:
|
||||
uint8_t _rst, _cs, _dc;
|
||||
uint8_t _miso, _mosi, _sclk;
|
||||
uint8_t _touch_irq=255, _touch_cs=255;
|
||||
bool flipped=false;
|
||||
|
||||
void wait(void);
|
||||
void enableTouchIrq();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -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
|
|
@ -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
|
|
@ -146,7 +146,7 @@ void loop(void)
|
|||
emu_Init(filename);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
myTimer.begin(vblCount, 16666); //to run every 16.6666ms
|
||||
}
|
||||
delay(20);
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
/****************************************************************************
|
||||
* Module name : oddemu
|
||||
* Description : Library SMSEMU
|
||||
* Author : J-M Harvengt
|
||||
* History : 14-07-97 Creation
|
||||
****************************************************************************/
|
||||
#include "vmachine.h"
|
||||
#include "vdc.h"
|
||||
#include "oddemu.h"
|
||||
|
||||
#include "emuapi.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Local macros / typedefs
|
||||
****************************************************************************/
|
||||
#define MAX_ROM_SIZE 8192 //16384
|
||||
|
||||
/****************************************************************************
|
||||
* Local procedures definition
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Local data
|
||||
****************************************************************************/
|
||||
#define MAXC 1024
|
||||
static char * bios=0; //[MAXC];
|
||||
static char * scshot=0; //[MAXC];
|
||||
static char * lorom=0; //[MAX_ROM_SIZE];
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Global data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Local procedures
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Exported procedures
|
||||
****************************************************************************/
|
||||
void odd_Init(void)
|
||||
{
|
||||
if (bios == 0) bios = (char *)emu_Malloc(MAXC);
|
||||
if (scshot == 0) scshot = (char *)emu_Malloc(MAXC);
|
||||
if (lorom == 0) lorom = (char *)emu_Malloc(MAX_ROM_SIZE);
|
||||
|
||||
app_data.debug = 0;
|
||||
app_data.stick[0] = 0;
|
||||
app_data.stick[1] = 1;
|
||||
app_data.bank = 0;
|
||||
app_data.limit = 1;
|
||||
app_data.sound_en = 1;
|
||||
app_data.speed = 100;
|
||||
app_data.wsize = 1;
|
||||
app_data.fullscreen = 1;
|
||||
app_data.scanlines = 0;
|
||||
app_data.voice = 1;
|
||||
app_data.window_title = "O2EM v";
|
||||
app_data.svolume = 200;
|
||||
app_data.vvolume = 100;
|
||||
app_data.filter = 0;
|
||||
app_data.exrom = 0;
|
||||
app_data.crc = 0;
|
||||
app_data.scshot = scshot;
|
||||
app_data.euro = 1;
|
||||
app_data.openb = 0;
|
||||
}
|
||||
|
||||
|
||||
static void load_bios( char *biosname)
|
||||
{
|
||||
static char s[MAXC+10];
|
||||
unsigned long crc;
|
||||
|
||||
emu_LoadFile(biosname,&rom1[0],1024);
|
||||
|
||||
memcpy(&rom2[0],&rom1[0],1024);
|
||||
memcpy(&rom3[0],&rom1[0],1024);
|
||||
memcpy(&rom4[0],&rom1[0],1024);
|
||||
|
||||
crc = crc32_buf(rom1,1024);
|
||||
|
||||
if (crc==0x8016A315)
|
||||
emu_printf("Odyssey2 bios ROM loaded\n");
|
||||
else if (crc==0xE20A9F41)
|
||||
emu_printf("Videopac+ G7400 bios ROM loaded\n");
|
||||
else
|
||||
emu_printf("Bios ROM loaded (unknown version)\n");
|
||||
}
|
||||
|
||||
|
||||
static void load_cart(char *file)
|
||||
{
|
||||
long l;
|
||||
|
||||
l = emu_LoadFile(file,&lorom[0],MAX_ROM_SIZE);
|
||||
|
||||
app_data.crc = crc32_buf(lorom, l); // crc32_file(file);
|
||||
|
||||
if (app_data.crc == 0xAFB23F89) app_data.exrom = 1; /* Musician */
|
||||
if (app_data.crc == 0x3BFEF56B) app_data.exrom = 1; /* Four in 1 Row! */
|
||||
|
||||
if (((app_data.crc == 0x975AB8DA) || (app_data.crc == 0xE246A812)) && (!app_data.debug)) {
|
||||
emu_printf("Error: file is an incomplete ROM dump\n");
|
||||
}
|
||||
|
||||
if (l < 2049) {
|
||||
app_data.bank=1;
|
||||
memcpy(&rom1[1024],&lorom[0],l);
|
||||
memcpy(&rom1[3072],&rom1[2048],1024); /* simulate missing A10 */
|
||||
rom=rom1;
|
||||
emu_printf("2K");
|
||||
} else if (l == 3072) {
|
||||
app_data.bank=1;
|
||||
memcpy(&rom1[1024],&lorom[0],3072);
|
||||
rom=rom1;
|
||||
emu_printf("3K");
|
||||
} else if (l == 4096) {
|
||||
if (app_data.exrom) {
|
||||
app_data.bank=1;
|
||||
memcpy(&extROM[0],&lorom[0],1024);
|
||||
memcpy(&rom1[1024],&lorom[1024],3072);
|
||||
rom=rom1;
|
||||
emu_printf("3K EXROM");
|
||||
} else {
|
||||
app_data.bank=2;
|
||||
memcpy(&rom1[1024],&lorom[0],2048);
|
||||
memcpy(&rom2[1024],&lorom[2048],2048);
|
||||
memcpy(&rom1[3072],&rom1[2048],1024); /* simulate missing A10 */
|
||||
memcpy(&rom2[3072],&rom2[2048],1024); /* simulate missing A10 */
|
||||
rom=rom2;
|
||||
emu_printf("4K");
|
||||
}
|
||||
} else if (l == 6144) {
|
||||
app_data.bank=2;
|
||||
memcpy(&rom1[1024],&lorom[0],3072);
|
||||
memcpy(&rom2[1024],&lorom[3072],3072);
|
||||
rom=rom2;
|
||||
emu_printf("6K");
|
||||
} else if (l == 8192) {
|
||||
app_data.bank=3;
|
||||
memcpy(&rom1[1024],&lorom[0],2048);
|
||||
memcpy(&rom2[1024],&lorom[2048],2048);
|
||||
memcpy(&rom3[1024],&lorom[2*2048],2048);
|
||||
memcpy(&rom4[1024],&lorom[3*2048],2048);
|
||||
memcpy(&rom1[3072],&rom1[2048],1024); /* simulate missing A10 */
|
||||
memcpy(&rom2[3072],&rom2[2048],1024); /* simulate missing A10 */
|
||||
memcpy(&rom3[3072],&rom3[2048],1024); /* simulate missing A10 */
|
||||
memcpy(&rom4[3072],&rom4[2048],1024); /* simulate missing A10 */
|
||||
rom=rom4;
|
||||
emu_printf("8K");
|
||||
} else if (l == 12288) {
|
||||
app_data.bank=3;
|
||||
memcpy(&rom1[1024],&lorom[0],3072);
|
||||
memcpy(&rom2[1024],&lorom[3072],3072);
|
||||
memcpy(&rom3[1024],&lorom[2*3072],3072);
|
||||
memcpy(&rom4[1024],&lorom[3*3072],3072);
|
||||
rom=rom4;
|
||||
emu_printf("12K");
|
||||
} else {
|
||||
emu_printf("Invalid ROM size");
|
||||
}
|
||||
if ((rom1[1024+12]=='O') && (rom1[1024+13]=='P') && (rom1[1024+14]=='N') && (rom1[1024+15]=='B')) app_data.openb=1;
|
||||
orom=rom;
|
||||
//printf("CRC: %08lX\n",app_data.crc);
|
||||
}
|
||||
|
||||
void odd_Start(char * filename)
|
||||
{
|
||||
load_bios(ROMSDIR "/" "o2rom.bin");
|
||||
load_cart(filename);
|
||||
init_display();
|
||||
init_cpu();
|
||||
init_system();
|
||||
}
|
||||
|
||||
|
||||
//static void snd_Mixer(short * stream, int len )
|
||||
//{
|
||||
// audio_process(stream, len>>2);
|
||||
//}
|
||||
|
||||
void odd_Stop(void)
|
||||
{
|
||||
close_audio();
|
||||
close_display();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void odd_Step(void)
|
||||
{
|
||||
run();
|
||||
|
||||
//emu_printf("s");
|
||||
emu_DrawScreen((unsigned char *)getGBuf()+BORDERW/2, BMPW-BORDERW, BMPH, BMPW);
|
||||
emu_DrawVsync();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
extern void odd_Init(void);
|
||||
extern void odd_Start(char * filename);
|
||||
extern void odd_Stop(void);
|
||||
extern void odd_Step(void);
|
||||
extern void odd_Input(int click);
|
|
@ -0,0 +1,183 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* O2 audio emulation
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cpu.h"
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
#include "vmachine.h"
|
||||
#include "audio.h"
|
||||
|
||||
//#define SAMPLE_RATE 44100
|
||||
#define PERIOD1 11 //11
|
||||
#define PERIOD2 44 //44
|
||||
|
||||
#define SOUND_BUFFER_LEN 1056
|
||||
|
||||
#define AUD_CTRL 0xAA
|
||||
#define AUD_D0 0xA7
|
||||
#define AUD_D1 0xA8
|
||||
#define AUD_D2 0xA9
|
||||
|
||||
|
||||
int sound_IRQ;
|
||||
//static short *stream=NULL;
|
||||
//static AUDIOSTREAM *stream=NULL;
|
||||
//FILE *sndlog=NULL;
|
||||
|
||||
static double flt_a=0.0, flt_b=0.0;
|
||||
static unsigned char flt_prv = 0;
|
||||
|
||||
|
||||
static void filter(unsigned char *buf, unsigned long len);
|
||||
|
||||
|
||||
//void audio_process(unsigned char *buffer){
|
||||
#ifdef GP32
|
||||
void audio_process(unsigned short *buffer, int len)
|
||||
#else
|
||||
void audio_process(short *buffer, int len)
|
||||
#endif
|
||||
{
|
||||
unsigned long aud_data;
|
||||
#ifdef GP32
|
||||
unsigned short s;
|
||||
#else
|
||||
short s;
|
||||
#endif
|
||||
int volume, re_circ, noise, enabled, intena, period, pnt, cnt, rndbit, pos;
|
||||
|
||||
aud_data = (VDCwrite[AUD_D2] | (VDCwrite[AUD_D1] << 8) | (VDCwrite[AUD_D0] << 16));
|
||||
|
||||
intena = VDCwrite[0xA0] & 0x04;
|
||||
|
||||
pnt = cnt = 0;
|
||||
|
||||
noise = VDCwrite[AUD_CTRL] & 0x10;
|
||||
enabled = VDCwrite[AUD_CTRL] & 0x80;
|
||||
rndbit = (enabled && noise) ? (rand()%2) : 0;
|
||||
|
||||
while (pnt < len/*SOUND_BUFFER_LEN*/) {
|
||||
pos = (tweakedaudio) ? (pnt/3) : (MAXLINES-1);
|
||||
volume = AudioVector[pos] & 0x0F;
|
||||
enabled = AudioVector[pos] & 0x80;
|
||||
period = (AudioVector[pos] & 0x20) ? PERIOD1 : PERIOD2;
|
||||
re_circ = AudioVector[pos] & 0x40;
|
||||
|
||||
#ifdef GP32
|
||||
s= ( (enabled) ? ((aud_data & 0x01)^rndbit) * (0x10 * volume) : 0) << 8;
|
||||
#else
|
||||
s= (( (enabled) ? ((aud_data & 0x01)^rndbit) * (0x10 * volume) : 0) - 128) << 8 ;
|
||||
#endif
|
||||
*buffer++ = s;
|
||||
*buffer++ = s;
|
||||
pnt++;
|
||||
cnt++;
|
||||
|
||||
if (cnt >= period) {
|
||||
cnt=0;
|
||||
aud_data = (re_circ) ? ((aud_data >> 1) | ((aud_data & 1) << 23)) : (aud_data >>= 1);
|
||||
rndbit = (enabled && noise) ? (rand()%2) : 0;
|
||||
|
||||
if (enabled && intena && (!sound_IRQ)) {
|
||||
sound_IRQ = 1;
|
||||
ext_IRQ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (app_data.filter) filter(buffer, SOUND_BUFFER_LEN);
|
||||
}
|
||||
|
||||
|
||||
void update_audio(void) {
|
||||
// unsigned char *p;
|
||||
if (app_data.sound_en) {
|
||||
// p = (unsigned char *)get_audio_stream_buffer(stream);
|
||||
// if (p) {
|
||||
// audio_process(p);
|
||||
// if (sndlog) fwrite(p,1,SOUND_BUFFER_LEN,sndlog);
|
||||
// free_audio_stream_buffer(stream);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_audio(void) {
|
||||
// int i;
|
||||
|
||||
sound_IRQ=0;
|
||||
// set_volume(255,255);
|
||||
init_sound_stream();
|
||||
|
||||
// sndlog = NULL;
|
||||
}
|
||||
|
||||
|
||||
void init_sound_stream(void){
|
||||
int vol;
|
||||
if (app_data.sound_en){
|
||||
if (app_data.filter)
|
||||
vol = (255*app_data.svolume)/100;
|
||||
else
|
||||
vol = (255*app_data.svolume)/200;
|
||||
// stream = play_audio_stream(SOUND_BUFFER_LEN,8,0,SAMPLE_RATE,vol,128);
|
||||
// if (!stream) {
|
||||
// printf("Error creating audio stream!\n");
|
||||
// app_data.sound_en=0;
|
||||
// }
|
||||
flt_a = flt_b = 0.0;
|
||||
flt_prv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mute_audio(void){
|
||||
if (app_data.sound_en /*&& stream*/){
|
||||
// stop_audio_stream(stream);
|
||||
// stream=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void close_audio(void) {
|
||||
if (app_data.sound_en /*&& stream*/) {
|
||||
// stop_audio_stream(stream);
|
||||
}
|
||||
app_data.sound_en=0;
|
||||
}
|
||||
|
||||
|
||||
static void filter(unsigned char *buffer, unsigned long len){
|
||||
static unsigned char buf[SOUND_BUFFER_LEN];
|
||||
int t;
|
||||
unsigned long i;
|
||||
if (len>SOUND_BUFFER_LEN) return;
|
||||
memcpy(buf,buffer,len);
|
||||
for (i=0; i<len; i++){
|
||||
t = (i==0)?(buf[0]-flt_prv):(buf[i]-buf[i-1]);
|
||||
if (t) flt_b = (double)t;
|
||||
flt_a += flt_b/4.0 - flt_a/80.0;
|
||||
flt_b -= flt_b/4.0;
|
||||
if ((flt_a>255.0)||(flt_a<-255.0)) flt_a=0.0;
|
||||
buffer[i] = (unsigned char)((flt_a+255.0)/2.0);
|
||||
}
|
||||
flt_prv = buf[len-1];
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef __AUDIO_H
|
||||
#define __AUDIO_H
|
||||
|
||||
void update_audio(void);
|
||||
void init_audio(void);
|
||||
void close_audio(void);
|
||||
void init_sound_stream(void);
|
||||
void mute_audio(void);
|
||||
#ifdef GP32
|
||||
void audio_process(unsigned short *buffer, int len);
|
||||
#else
|
||||
void audio_process(short *buffer, int len);
|
||||
#endif
|
||||
extern int sound_IRQ;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define O2EM_VERSION "1.01"
|
||||
#define RELEASE_DATE "(October/2002)"
|
||||
|
||||
#endif
|
||||
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,34 @@
|
|||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern Byte acc; /* Accumulator */
|
||||
extern ADDRESS pc; /* Program counter */
|
||||
extern long clk; /* clock */
|
||||
|
||||
extern Byte itimer; /* Internal timer */
|
||||
extern Byte reg_pnt; /* pointer to register bank */
|
||||
extern Byte timer_on; /* 0=timer off/1=timer on */
|
||||
extern Byte count_on; /* 0=count off/1=count on */
|
||||
|
||||
extern Byte t_flag; /* Timer flag */
|
||||
|
||||
extern Byte psw; /* Processor status word */
|
||||
extern Byte sp; /* Stack pointer (part of psw) */
|
||||
|
||||
extern Byte p1; /* I/O port 1 */
|
||||
extern Byte p2; /* I/O port 2 */
|
||||
|
||||
extern Byte xirq_pend;
|
||||
extern Byte tirq_pend;
|
||||
|
||||
void init_cpu(void);
|
||||
void cpu_exec(void);
|
||||
void ext_IRQ(void);
|
||||
void tim_IRQ(void);
|
||||
void make_psw_debug(void);
|
||||
|
||||
|
||||
#endif /* CPU_H */
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* CRC32 functions used to identify files
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "crc32.h"
|
||||
//#include "pgmspace.h"
|
||||
|
||||
static const unsigned long crc32tab[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
|
||||
};
|
||||
|
||||
|
||||
unsigned long crc32_buf(const void *buf, long len){
|
||||
unsigned long crc = ~0;
|
||||
unsigned char *p = (unsigned char*)buf;
|
||||
|
||||
while (len--) crc = (crc >> 8) ^ crc32tab[(crc ^ (*p++)) & 0xff];
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
|
||||
unsigned long crc32_file(const char *filename){
|
||||
unsigned long crc = ~0;
|
||||
FILE *f;
|
||||
int c;
|
||||
|
||||
f = fopen(filename,"rb");
|
||||
if (f){
|
||||
while ((c=fgetc(f)) != EOF) crc = (crc >> 8) ^ crc32tab[(crc ^ c) & 0xff];
|
||||
fclose(f);
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __CRC32_H
|
||||
#define __CRC32_H
|
||||
|
||||
unsigned long crc32_buf(const void *buf, long len);
|
||||
unsigned long crc32_file(const char *filename);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* O2 character table
|
||||
*/
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "cset.h"
|
||||
|
||||
|
||||
const Byte cset[512]= {
|
||||
0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
|
||||
0x18,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,
|
||||
0x3C,0x66,0x0C,0x18,0x30,0x60,0x7E,0x00,
|
||||
0x7C,0xC6,0x06,0x3C,0x06,0xC6,0x7C,0x00,
|
||||
0xCC,0xCC,0xCC,0xFE,0x0C,0x0C,0x0C,0x00,
|
||||
0xFE,0xC0,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
|
||||
0x7C,0xC6,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,
|
||||
0xFE,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,
|
||||
0x7C,0xC6,0xC6,0x7C,0xC6,0xC6,0x7C,0x00,
|
||||
0x7C,0xC6,0xC6,0x7E,0x06,0xC6,0x7C,0x00,
|
||||
0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,
|
||||
0x18,0x7E,0x58,0x7E,0x1A,0x7E,0x18,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x3C,0x66,0x0C,0x18,0x18,0x00,0x18,0x00,
|
||||
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFE,0x00,
|
||||
0xFC,0xC6,0xC6,0xFC,0xC0,0xC0,0xC0,0x00,
|
||||
0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
|
||||
0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00,
|
||||
0xFE,0xC0,0xC0,0xF8,0xC0,0xC0,0xFE,0x00,
|
||||
0xFC,0xC6,0xC6,0xFC,0xD8,0xCC,0xC6,0x00,
|
||||
0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,
|
||||
0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
|
||||
0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,
|
||||
0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
|
||||
0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x76,0x00,
|
||||
0x7C,0xC6,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
|
||||
0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0xFC,0x00,
|
||||
0xFE,0xC0,0xC0,0xF8,0xC0,0xC0,0xC0,0x00,
|
||||
0x7C,0xC6,0xC0,0xC0,0xCE,0xC6,0x7E,0x00,
|
||||
0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,
|
||||
0x06,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,
|
||||
0xC6,0xCC,0xD8,0xF0,0xD8,0xCC,0xC6,0x00,
|
||||
0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00,
|
||||
0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,
|
||||
0xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0x00,
|
||||
0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,
|
||||
0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,
|
||||
0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,
|
||||
0xC6,0xEE,0xFE,0xD6,0xC6,0xC6,0xC6,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,
|
||||
0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
|
||||
0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,
|
||||
0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00,
|
||||
0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00,
|
||||
0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
|
||||
0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,
|
||||
0x03,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
|
||||
0xCE,0xDB,0xDB,0xDB,0xDB,0xDB,0xCE,0x00,
|
||||
0x00,0x00,0x3C,0x7E,0x7E,0x7E,0x3C,0x00,
|
||||
0x1C,0x1C,0x18,0x1E,0x18,0x18,0x1C,0x00,
|
||||
0x1C,0x1C,0x18,0x1E,0x18,0x34,0x26,0x00,
|
||||
0x38,0x38,0x18,0x78,0x18,0x2C,0x64,0x00,
|
||||
0x38,0x38,0x18,0x78,0x18,0x18,0x38,0x00,
|
||||
0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,
|
||||
0x18,0x3C,0x7E,0xFF,0xFF,0x18,0x18,0x00,
|
||||
0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x00,
|
||||
0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x00,
|
||||
0x38,0x38,0x12,0xFE,0xB8,0x28,0x6C,0x00,
|
||||
0xC0,0x60,0x30,0x18,0x0C,0x06,0x03,0x00,
|
||||
0x00,0x00,0x0C,0x08,0x08,0x7F,0x3E,0x00,
|
||||
0x00,0x03,0x63,0xFF,0xFF,0x18,0x08,0x00,
|
||||
0x00,0x00,0x00,0x10,0x38,0xFF,0x7E,0x00,
|
||||
0x00,0x00,0x00,0x06,0x6E,0xFF,0x7E,0x00};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __CSET_H
|
||||
#define __CSET_H
|
||||
|
||||
extern const Byte cset[512];
|
||||
|
||||
#endif
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,214 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
#define TITLE " Oddysey Emulator"
|
||||
#define ROMSDIR "o2em"
|
||||
|
||||
|
||||
#define emu_Init(ROM) {odd_Init();odd_Start(ROM);}
|
||||
#define emu_Step() {odd_Step();}
|
||||
#define emu_Input(x) {odd_Input(x);}
|
||||
|
||||
#define MAX_FILENAME_PATH 64
|
||||
#define NB_FILE_HANDLER 4
|
||||
#define VID_FRAME_SKIP 0x0
|
||||
#define PALETTE_SIZE 256
|
||||
#define TFT_VBUFFER_YCROP 20
|
||||
|
||||
#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',157, //lowecase
|
||||
0,'a','s','d','f','g','h','j','k','l',0x0D,
|
||||
0,'z','x','c','v','b','n','m',',','.',';','/',
|
||||
145,157,29,17,
|
||||
0,'+',' ','-'
|
||||
};
|
||||
|
||||
#define keylables_map1_0 (char *)"QWERTYUIOP@"
|
||||
#define keylables_map1_1 (char *)" ASDFGHJKL\x19"
|
||||
#define keylables_map1_2 (char *)" ZXCVBNM<>:?"
|
||||
#define keylables_map1_3 (char *)" =\x10_"
|
||||
const unsigned short key_map1[] = {
|
||||
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
|
||||
0,'A','S','D','F','G','H','J','K','L',0x0D,
|
||||
0,'Z','X','C','V','B','N','M','<','>',':','?',
|
||||
145,157,29,17,
|
||||
0,'=',' ','_'
|
||||
};
|
||||
|
||||
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
|
||||
#define keylables_map2_1 (char *)" |\\[]{} "
|
||||
#define keylables_map2_2 (char *)" <>:?"
|
||||
#define keylables_map2_3 (char *)" =\x10_"
|
||||
const unsigned short key_map2[] = {
|
||||
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
|
||||
0, '|','\\','[',']','{','}','\'',0,0,0,
|
||||
0, 0,0,0,0,0,0,0,'<','>',':','?',
|
||||
0,0,0,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,
|
||||
0,0,0,0,
|
||||
0,0,' ',0
|
||||
};
|
||||
|
||||
#define keylables_map4_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
|
||||
#define keylables_map4_1 (char *)" "
|
||||
#define keylables_map4_2 (char *)" "
|
||||
#define keylables_map4_3 (char *)" "
|
||||
|
||||
const unsigned short key_map4[] = {
|
||||
133,134,135,136,137,138,139,140,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,
|
||||
0,0,0,0,
|
||||
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,
|
||||
0,0,0,0,
|
||||
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
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,341 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* 8048 Mnemonics
|
||||
*/
|
||||
|
||||
|
||||
#include "cpu.h"
|
||||
#include "table.h"
|
||||
|
||||
|
||||
struct lookup_tag lookup[] = {
|
||||
|
||||
/* 00 */ {"NOP",1,0},
|
||||
/* 01 */ {"ILL",1,0},
|
||||
/* 02 */ {"OUTL BUS,A",1,0},
|
||||
/* 03 */ {"ADD A,",2,1},
|
||||
|
||||
/* 04 */ {"JMP",2,2},
|
||||
/* 05 */ {"EN I",1,0},
|
||||
/* 06 */ {"ILL",1,0},
|
||||
/* 07 */ {"DEC A",1,0},
|
||||
|
||||
/* 08 */ {"INS A,BUS",1,0},
|
||||
/* 09 */ {"IN A,P1",1,0},
|
||||
/* 0A */ {"IN A,P2",1,0},
|
||||
/* 0B */ {"ILL",1,0},
|
||||
|
||||
/* 0C */ {"MOVD A,P4",1,0},
|
||||
/* 0D */ {"MOVD A,P5",1,0},
|
||||
/* 0E */ {"MOVD A,P6",1,0},
|
||||
/* 0F */ {"MOVD A,P7",1,0},
|
||||
|
||||
/* 10 */ {"INC @R0",1,0},
|
||||
/* 11 */ {"INC @R1",1,0},
|
||||
/* 12 */ {"JB0",2,3},
|
||||
/* 13 */ {"ADDC A,",2,1},
|
||||
|
||||
/* 14 */ {"CALL",2,2},
|
||||
/* 15 */ {"DIS I",1,0},
|
||||
/* 16 */ {"JTF",2,3},
|
||||
/* 17 */ {"INC A",1,0},
|
||||
|
||||
/* 18 */ {"INC R0",1,0},
|
||||
/* 19 */ {"INC R1",1,0},
|
||||
/* 1A */ {"INC R2",1,0},
|
||||
/* 1B */ {"INC R3",1,0},
|
||||
|
||||
/* 1C */ {"INC R4",1,0},
|
||||
/* 1D */ {"INC R5",1,0},
|
||||
/* 1E */ {"INC R6",1,0},
|
||||
/* 1F */ {"INC R7",1,0},
|
||||
|
||||
/* 20 */ {"XCH A,@R0",1,0},
|
||||
/* 21 */ {"XCH A,@R1",1,0},
|
||||
/* 22 */ {"ILL",1,0},
|
||||
/* 23 */ {"MOV A,",2,1},
|
||||
|
||||
/* 24 */ {"JMP",2,2},
|
||||
/* 25 */ {"EN TCNTI",1,0},
|
||||
/* 26 */ {"JNT0",2,3},
|
||||
/* 27 */ {"CLR A",1,0},
|
||||
|
||||
/* 28 */ {"XCH A,R0",1,0},
|
||||
/* 29 */ {"XCH A,R1",1,0},
|
||||
/* 2A */ {"XCH A,R2",1,0},
|
||||
/* 2B */ {"XCH A,R3",1,0},
|
||||
|
||||
/* 2C */ {"XCH A,R4",1,0},
|
||||
/* 2D */ {"XCH A,R5",1,0},
|
||||
/* 2E */ {"XCH A,R6",1,0},
|
||||
/* 2F */ {"XCH A,R7",1,0},
|
||||
|
||||
/* 30 */ {"XCHD A,@R0",1,0},
|
||||
/* 31 */ {"XCHD A,@R1",1,0},
|
||||
/* 32 */ {"JB1",2,3},
|
||||
/* 33 */ {"ILL",1,0},
|
||||
|
||||
/* 34 */ {"CALL",2,2},
|
||||
/* 35 */ {"DIS TCNTI",1,0},
|
||||
/* 36 */ {"JT0",2,3},
|
||||
/* 37 */ {"CPL A",1,0},
|
||||
|
||||
/* 38 */ {"ILL",1,0},
|
||||
/* 39 */ {"OUTL P1,A",1,0},
|
||||
/* 3A */ {"OUTL P2,A",1,0},
|
||||
/* 3B */ {"ILL",1,0},
|
||||
|
||||
/* 3C */ {"MOVD P4,A",1,0},
|
||||
/* 3D */ {"MOVD P5,A",1,0},
|
||||
/* 3E */ {"MOVD P6,A",1,0},
|
||||
/* 3F */ {"MOVD P7,A",1,0},
|
||||
|
||||
/* 40 */ {"ORL A,@R0",1,0},
|
||||
/* 41 */ {"ORL A,@R1",1,0},
|
||||
/* 42 */ {"MOV A,T",1,0},
|
||||
/* 43 */ {"ORL A,",2,1},
|
||||
|
||||
/* 44 */ {"JMP",2,2},
|
||||
/* 45 */ {"STRT CNT",1,0},
|
||||
/* 46 */ {"JNT1",2,3},
|
||||
/* 47 */ {"SWAP",1,0},
|
||||
|
||||
/* 48 */ {"ORL A,R0",1,0},
|
||||
/* 49 */ {"ORL A,R1",1,0},
|
||||
/* 4A */ {"ORL A,R2",1,0},
|
||||
/* 4B */ {"ORL A,R3",1,0},
|
||||
|
||||
/* 4C */ {"ORL A,R4",1,0},
|
||||
/* 4D */ {"ORL A,R5",1,0},
|
||||
/* 4E */ {"ORL A,R6",1,0},
|
||||
/* 4F */ {"ORL A,R7",1,0},
|
||||
|
||||
/* 50 */ {"ANL A,@R0",1,0},
|
||||
/* 51 */ {"ANL A,@R1",1,0},
|
||||
/* 52 */ {"JB2",2,3},
|
||||
/* 53 */ {"ANL A,",2,1},
|
||||
|
||||
/* 54 */ {"CALL",2,2},
|
||||
/* 55 */ {"STRT T",1,0},
|
||||
/* 56 */ {"JT1",2,3},
|
||||
/* 57 */ {"ILL",1,0},
|
||||
|
||||
/* 58 */ {"ANL A,R0",1,0},
|
||||
/* 59 */ {"ANL A,R1",1,0},
|
||||
/* 5A */ {"ANL A,R2",1,0},
|
||||
/* 5B */ {"ANL A,R3",1,0},
|
||||
|
||||
/* 5C */ {"ANL A,R4",1,0},
|
||||
/* 5D */ {"ANL A,R5",1,0},
|
||||
/* 5E */ {"ANL A,R6",1,0},
|
||||
/* 5F */ {"ANL A,R7",1,0},
|
||||
|
||||
/* 60 */ {"ADD A,@R0",1,0},
|
||||
/* 61 */ {"ADD A,@R1",1,0},
|
||||
/* 62 */ {"MOV T,A",1,0},
|
||||
/* 63 */ {"ILL",1,0},
|
||||
|
||||
/* 64 */ {"JMP",2,2},
|
||||
/* 65 */ {"STOP TCNT",1,0},
|
||||
/* 66 */ {"ILL",1,0},
|
||||
/* 67 */ {"RRC A",1,0},
|
||||
|
||||
/* 68 */ {"ADD A,R0",1,0},
|
||||
/* 69 */ {"ADD A,R1",1,0},
|
||||
/* 6A */ {"ADD A,R2",1,0},
|
||||
/* 6B */ {"ADD A,R3",1,0},
|
||||
|
||||
/* 6C */ {"ADD A,R4",1,0},
|
||||
/* 6D */ {"ADD A,R5",1,0},
|
||||
/* 6E */ {"ADD A,R6",1,0},
|
||||
/* 6F */ {"ADD A,R7",1,0},
|
||||
|
||||
/* 70 */ {"ADDC A,@R0",1,0},
|
||||
/* 71 */ {"ADDC A,@R1",1,0},
|
||||
/* 72 */ {"JB3",2,3},
|
||||
/* 73 */ {"ILL",1,0},
|
||||
|
||||
/* 74 */ {"CALL",2,2},
|
||||
/* 75 */ {"ENT0 CLK",1,0},
|
||||
/* 76 */ {"JF1",2,3},
|
||||
/* 77 */ {"RR A",1,0},
|
||||
|
||||
/* 78 */ {"ADDC A,R0",1,0},
|
||||
/* 79 */ {"ADDC A,R1",1,0},
|
||||
/* 7A */ {"ADDC A,R2",1,0},
|
||||
/* 7B */ {"ADDC A,R3",1,0},
|
||||
|
||||
/* 7C */ {"ADDC A,R4",1,0},
|
||||
/* 7D */ {"ADDC A,R5",1,0},
|
||||
/* 7E */ {"ADDC A,R6",1,0},
|
||||
/* 7F */ {"ADDC A,R7",1,0},
|
||||
|
||||
/* 80 */ {"MOVX A,@R0",1,0},
|
||||
/* 81 */ {"MOVX A,@R1",1,0},
|
||||
/* 82 */ {"ILL",1,0},
|
||||
/* 83 */ {"RET",1,0},
|
||||
|
||||
/* 84 */ {"JMP",2,2},
|
||||
/* 85 */ {"CLR F0",1,0},
|
||||
/* 86 */ {"JNI",2,3},
|
||||
/* 87 */ {"ILL",1,0},
|
||||
|
||||
/* 88 */ {"ORL BUS,",2,1},
|
||||
/* 89 */ {"ORL P1,",2,1},
|
||||
/* 8A */ {"ORL P2,",2,1},
|
||||
/* 8B */ {"ILL",1,0},
|
||||
|
||||
/* 8C */ {"ORLD P4,A",1,0},
|
||||
/* 8D */ {"ORLD P5,A",1,0},
|
||||
/* 8E */ {"ORLD P6,A",1,0},
|
||||
/* 8F */ {"ORLD P7,A",1,0},
|
||||
|
||||
/* 90 */ {"MOVX @R0,A",1,0},
|
||||
/* 91 */ {"MOVX @R1,A",1,0},
|
||||
/* 92 */ {"JB4",2,3},
|
||||
/* 93 */ {"RETR",1,0},
|
||||
|
||||
/* 94 */ {"CALL",2,2},
|
||||
/* 95 */ {"CPL F0",1,0},
|
||||
/* 96 */ {"JNZ",2,3},
|
||||
/* 97 */ {"CLR C",1,0},
|
||||
|
||||
/* 98 */ {"ANL BUS,",2,1},
|
||||
/* 99 */ {"ANL P1,",2,1},
|
||||
/* 9A */ {"ANL P2,",2,1},
|
||||
/* 9B */ {"ILL",1,0},
|
||||
|
||||
/* 9C */ {"ANLD P4,A",1,0},
|
||||
/* 9D */ {"ANLD P5,A",1,0},
|
||||
/* 9E */ {"ANLD P6,A",1,0},
|
||||
/* 9F */ {"ANLD P7,A",1,0},
|
||||
|
||||
/* A0 */ {"MOV @R0,A",1,0},
|
||||
/* A1 */ {"MOV @R1,A",1,0},
|
||||
/* A2 */ {"ILL",1,0},
|
||||
/* A3 */ {"MOVP A,@A",1,0},
|
||||
|
||||
/* A4 */ {"JMP",2,2},
|
||||
/* A5 */ {"CLR F1",1,0},
|
||||
/* A6 */ {"ILL",1,0},
|
||||
/* A7 */ {"CPL C",1,0},
|
||||
|
||||
/* A8 */ {"MOV R0,A",1,0},
|
||||
/* A9 */ {"MOV R1,A",1,0},
|
||||
/* AA */ {"MOV R2,A",1,0},
|
||||
/* AB */ {"MOV R3,A",1,0},
|
||||
/* AC */ {"MOV R4,A",1,0},
|
||||
/* AD */ {"MOV R5,A",1,0},
|
||||
/* AE */ {"MOV R6,A",1,0},
|
||||
/* AF */ {"MOV R7,A",1,0},
|
||||
|
||||
/* B0 */ {"MOV @R0,",2,1},
|
||||
/* B1 */ {"MOV @R1,",2,1},
|
||||
/* B2 */ {"JB5",2,3},
|
||||
/* B3 */ {"JMPP @A",1,0},
|
||||
|
||||
/* B4 */ {"CALL",2,2},
|
||||
/* B5 */ {"CPL F1",1,0},
|
||||
/* B6 */ {"JF0",2,3},
|
||||
/* B7 */ {"ILL",1,0},
|
||||
|
||||
/* B8 */ {"MOV R0,",2,1},
|
||||
/* B9 */ {"MOV R1,",2,1},
|
||||
/* BA */ {"MOV R2,",2,1},
|
||||
/* BB */ {"MOV R3,",2,1},
|
||||
|
||||
/* BC */ {"MOV R4,",2,1},
|
||||
/* BD */ {"MOV R5,",2,1},
|
||||
/* BE */ {"MOV R6,",2,1},
|
||||
/* BF */ {"MOV R7,",2,1},
|
||||
|
||||
/* C0 */ {"ILL",1,0},
|
||||
/* C1 */ {"ILL",1,0},
|
||||
/* C2 */ {"ILL",1,0},
|
||||
/* C3 */ {"ILL",1,0},
|
||||
|
||||
/* C4 */ {"JMP",2,2},
|
||||
/* C5 */ {"SEL RB0",1,0},
|
||||
/* C6 */ {"JZ",2,3},
|
||||
/* C7 */ {"MOV A,PSW",1,0},
|
||||
|
||||
/* C8 */ {"DEC R0",1,0},
|
||||
/* C9 */ {"DEC R1",1,0},
|
||||
/* CA */ {"DEC R2",1,0},
|
||||
/* CB */ {"DEC R3",1,0},
|
||||
|
||||
/* CC */ {"DEC R4",1,0},
|
||||
/* CD */ {"DEC R5",1,0},
|
||||
/* CE */ {"DEC R6",1,0},
|
||||
/* CF */ {"DEC R7",1,0},
|
||||
|
||||
/* D0 */ {"XRL A,@R0",1,0},
|
||||
/* D1 */ {"XRL A,@R1",1,0},
|
||||
/* D2 */ {"JB6",2,3},
|
||||
/* D3 */ {"XRL A,",2,1},
|
||||
|
||||
/* D4 */ {"CALL",2,2},
|
||||
/* D5 */ {"SEL RB1",1,0},
|
||||
/* D6 */ {"ILL",1,0},
|
||||
/* D7 */ {"MOV PSW,A",1,0},
|
||||
|
||||
/* D8 */ {"XRL A,R0",1,0},
|
||||
/* D9 */ {"XRL A,R1",1,0},
|
||||
/* DA */ {"XRL A,R2",1,0},
|
||||
/* DB */ {"XRL A,R3",1,0},
|
||||
/* DC */ {"XRL A,R4",1,0},
|
||||
/* DD */ {"XRL A,R5",1,0},
|
||||
/* DE */ {"XRL A,R6",1,0},
|
||||
/* DF */ {"XRL A,R7",1,0},
|
||||
|
||||
/* E0 */ {"ILL",1,0},
|
||||
/* E1 */ {"ILL",1,0},
|
||||
/* E2 */ {"ILL",1,0},
|
||||
/* E3 */ {"MOVP3 A,@A",1,0},
|
||||
|
||||
/* E4 */ {"JMP",2,2},
|
||||
/* E5 */ {"SEL MB0",1,0},
|
||||
/* E6 */ {"JNC",2,3},
|
||||
/* E7 */ {"RL A",1,0},
|
||||
|
||||
/* E8 */ {"DJNZ R0,",2,3},
|
||||
/* E9 */ {"DJNZ R1,",2,3},
|
||||
/* EA */ {"DJNZ R2,",2,3},
|
||||
/* EB */ {"DJNZ R3,",2,3},
|
||||
/* EC */ {"DJNZ R4,",2,3},
|
||||
/* ED */ {"DJNZ R5,",2,3},
|
||||
/* EE */ {"DJNZ R6,",2,3},
|
||||
/* EF */ {"DJNZ R7,",2,3},
|
||||
|
||||
/* F0 */ {"MOV A,@R0",1,0},
|
||||
/* F1 */ {"MOV A,@R1",1,0},
|
||||
/* F2 */ {"JB7",2,3},
|
||||
/* F3 */ {"ILL",1,0},
|
||||
|
||||
/* F4 */ {"CALL",2,2},
|
||||
/* F5 */ {"SEL MB1",1,0},
|
||||
/* F6 */ {"JC",2,3},
|
||||
/* F7 */ {"RLC A",1,0},
|
||||
|
||||
/* F8 */ {"MOV A,R0",1,0},
|
||||
/* F9 */ {"MOV A,R1",1,0},
|
||||
/* FA */ {"MOV A,R2",1,0},
|
||||
/* FB */ {"MOV A,R3",1,0},
|
||||
/* FC */ {"MOV A,R4",1,0},
|
||||
/* FD */ {"MOV A,R5",1,0},
|
||||
/* FE */ {"MOV A,R6",1,0},
|
||||
/* FF */ {"MOV A,R7",1,0}
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __TABLE_H
|
||||
#define __TABLE_H
|
||||
|
||||
extern struct lookup_tag {
|
||||
signed char *mnemonic; //JMH
|
||||
unsigned char bytes;
|
||||
unsigned char type;
|
||||
} lookup[];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,204 @@
|
|||
extern "C" {
|
||||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#include "Oddemu.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, 20000); //to run every 20ms
|
||||
myTimer.begin(vblCount, 16666); //to run every 16.6666ms
|
||||
}
|
||||
delay(20);
|
||||
}
|
||||
else {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
emu_Step();
|
||||
//delay(20);
|
||||
//delay(16);
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
Plik diff jest za duży
Load Diff
|
@ -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 240
|
||||
#define TFT_REALHEIGHT 240
|
||||
|
||||
//#define WIDTH 272
|
||||
//#define HEIGHT 228
|
||||
|
||||
#define LINES_PER_BLOCK 64
|
||||
#define NR_OF_BLOCK 4
|
||||
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
|
||||
|
||||
|
||||
#ifdef ILI9341
|
||||
|
||||
#define ILI9341_NOP 0x00
|
||||
#define ILI9341_SWRESET 0x01
|
||||
#define ILI9341_RDDID 0x04
|
||||
#define ILI9341_RDDST 0x09
|
||||
|
||||
#define ILI9341_SLPIN 0x10
|
||||
#define ILI9341_SLPOUT 0x11
|
||||
#define ILI9341_PTLON 0x12
|
||||
#define ILI9341_NORON 0x13
|
||||
|
||||
#define ILI9341_RDMODE 0x0A
|
||||
#define ILI9341_RDMADCTL 0x0B
|
||||
#define ILI9341_RDPIXFMT 0x0C
|
||||
#define ILI9341_RDIMGFMT 0x0D
|
||||
#define ILI9341_RDSELFDIAG 0x0F
|
||||
|
||||
#define ILI9341_INVOFF 0x20
|
||||
#define ILI9341_INVON 0x21
|
||||
#define ILI9341_GAMMASET 0x26
|
||||
#define ILI9341_DISPOFF 0x28
|
||||
#define ILI9341_DISPON 0x29
|
||||
|
||||
#define ILI9341_CASET 0x2A
|
||||
#define ILI9341_PASET 0x2B
|
||||
#define ILI9341_RAMWR 0x2C
|
||||
#define ILI9341_RAMRD 0x2E
|
||||
|
||||
#define ILI9341_PTLAR 0x30
|
||||
#define ILI9341_MADCTL 0x36
|
||||
#define ILI9341_VSCRSADD 0x37
|
||||
#define ILI9341_PIXFMT 0x3A
|
||||
|
||||
#define ILI9341_FRMCTR1 0xB1
|
||||
#define ILI9341_FRMCTR2 0xB2
|
||||
#define ILI9341_FRMCTR3 0xB3
|
||||
#define ILI9341_INVCTR 0xB4
|
||||
#define ILI9341_DFUNCTR 0xB6
|
||||
|
||||
#define ILI9341_PWCTR1 0xC0
|
||||
#define ILI9341_PWCTR2 0xC1
|
||||
#define ILI9341_PWCTR3 0xC2
|
||||
#define ILI9341_PWCTR4 0xC3
|
||||
#define ILI9341_PWCTR5 0xC4
|
||||
#define ILI9341_VMCTR1 0xC5
|
||||
#define ILI9341_VMCTR2 0xC7
|
||||
|
||||
#define ILI9341_RDID1 0xDA
|
||||
#define ILI9341_RDID2 0xDB
|
||||
#define ILI9341_RDID3 0xDC
|
||||
#define ILI9341_RDID4 0xDD
|
||||
|
||||
#define ILI9341_GMCTRP1 0xE0
|
||||
#define ILI9341_GMCTRN1 0xE1
|
||||
|
||||
#define ILI9341_MADCTL_MY 0x80
|
||||
#define ILI9341_MADCTL_MX 0x40
|
||||
#define ILI9341_MADCTL_MV 0x20
|
||||
#define ILI9341_MADCTL_ML 0x10
|
||||
#define ILI9341_MADCTL_RGB 0x00
|
||||
#define ILI9341_MADCTL_BGR 0x08
|
||||
#define ILI9341_MADCTL_MH 0x04
|
||||
|
||||
#define TFT_CASET ILI9341_CASET
|
||||
#define TFT_PASET ILI9341_PASET
|
||||
#define TFT_RAMWR ILI9341_RAMWR
|
||||
#define TFT_MADCTL ILI9341_MADCTL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ST7789
|
||||
|
||||
#define ST7735_NOP 0x00
|
||||
#define ST7735_SWRESET 0x01
|
||||
#define ST7735_RDDID 0x04
|
||||
#define ST7735_RDDST 0x09
|
||||
|
||||
#define ST7735_SLPIN 0x10
|
||||
#define ST7735_SLPOUT 0x11
|
||||
#define ST7735_PTLON 0x12
|
||||
#define ST7735_NORON 0x13
|
||||
|
||||
#define ST7735_INVOFF 0x20
|
||||
#define ST7735_INVON 0x21
|
||||
#define ST7735_DISPOFF 0x28
|
||||
#define ST7735_DISPON 0x29
|
||||
#define ST7735_CASET 0x2A
|
||||
#define ST7735_RASET 0x2B
|
||||
#define ST7735_RAMWR 0x2C
|
||||
#define ST7735_RAMRD 0x2E
|
||||
|
||||
#define ST7735_PTLAR 0x30
|
||||
#define ST7735_COLMOD 0x3A
|
||||
#define ST7735_MADCTL 0x36
|
||||
|
||||
#define ST7735_FRMCTR1 0xB1
|
||||
#define ST7735_FRMCTR2 0xB2
|
||||
#define ST7735_FRMCTR3 0xB3
|
||||
#define ST7735_INVCTR 0xB4
|
||||
#define ST7735_DISSET5 0xB6
|
||||
|
||||
#define ST7735_PWCTR1 0xC0
|
||||
#define ST7735_PWCTR2 0xC1
|
||||
#define ST7735_PWCTR3 0xC2
|
||||
#define ST7735_PWCTR4 0xC3
|
||||
#define ST7735_PWCTR5 0xC4
|
||||
#define ST7735_VMCTR1 0xC5
|
||||
|
||||
#define ST7735_RDID1 0xDA
|
||||
#define ST7735_RDID2 0xDB
|
||||
#define ST7735_RDID3 0xDC
|
||||
#define ST7735_RDID4 0xDD
|
||||
|
||||
#define ST7735_PWCTR6 0xFC
|
||||
|
||||
#define ST7735_GMCTRP1 0xE0
|
||||
#define ST7735_GMCTRN1 0xE1
|
||||
|
||||
#define ST77XX_MADCTL_MY 0x80
|
||||
#define ST77XX_MADCTL_MX 0x40
|
||||
#define ST77XX_MADCTL_MV 0x20
|
||||
#define ST77XX_MADCTL_ML 0x10
|
||||
#define ST77XX_MADCTL_RGB 0x00
|
||||
#define ST77XX_MADCTL_BGR 0x08
|
||||
#define ST77XX_MADCTL_MH 0x04
|
||||
|
||||
#define TFT_CASET ST7735_CASET
|
||||
#define TFT_PASET ST7735_RASET
|
||||
#define TFT_RAMWR ST7735_RAMWR
|
||||
#define TFT_MADCTL ST7735_MADCTL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class TFT_T_DMA
|
||||
{
|
||||
public:
|
||||
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
|
||||
|
||||
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
|
||||
void begin(void);
|
||||
void flipscreen(bool flip);
|
||||
boolean isflipped(void);
|
||||
void startDMA(void);
|
||||
void stopDMA();
|
||||
int get_frame_buffer_size(int *width, int *height);
|
||||
|
||||
// Touch screen functions
|
||||
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
|
||||
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
|
||||
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
|
||||
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
|
||||
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
|
||||
|
||||
// NoDMA functions
|
||||
void writeScreenNoDma(const uint16_t *pcolors);
|
||||
void fillScreenNoDma(uint16_t color);
|
||||
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
|
||||
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
|
||||
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
|
||||
|
||||
// DMA functions
|
||||
uint16_t * getLineBuffer(int j);
|
||||
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
|
||||
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
|
||||
void writeLine(int width, int height, int y, uint16_t *buf);
|
||||
void fillScreen(uint16_t color);
|
||||
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
|
||||
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
|
||||
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
|
||||
|
||||
protected:
|
||||
uint8_t _rst, _cs, _dc;
|
||||
uint8_t _miso, _mosi, _sclk;
|
||||
uint8_t _touch_irq=255, _touch_cs=255;
|
||||
bool flipped=false;
|
||||
|
||||
void wait(void);
|
||||
void enableTouchIrq();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -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
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned short ADDRESS;
|
||||
#define INLINE
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* O2 Video Display Controller emulation
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "types.h"
|
||||
#include "vmachine.h"
|
||||
#include "config.h"
|
||||
#include "cset.h"
|
||||
#include "cpu.h"
|
||||
#include "vpp.h"
|
||||
#include "vdc.h"
|
||||
|
||||
#include "emuapi.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
} PALETTE_ENTRY;
|
||||
|
||||
|
||||
#define COL_SP0 0x01
|
||||
#define COL_SP1 0x02
|
||||
#define COL_SP2 0x04
|
||||
#define COL_SP3 0x08
|
||||
#define COL_VGRID 0x10
|
||||
#define COL_HGRID 0x20
|
||||
#define COL_VPP 0x40
|
||||
#define COL_CHAR 0x80
|
||||
|
||||
#define X_START 8
|
||||
#define Y_START 24
|
||||
|
||||
static const long colortable[16]={
|
||||
0x000000,
|
||||
0x0e3dd4,
|
||||
0x00981b,
|
||||
0x00bbd9,
|
||||
0xc70008,
|
||||
0xcc16b3,
|
||||
0x9d8710,
|
||||
0xe1dee1,
|
||||
0x5f6e6b,
|
||||
0x6aa1ff,
|
||||
0x3df07a,
|
||||
0x31ffff,
|
||||
0xff4255,
|
||||
0xff98ff,
|
||||
0xd9ad5d,
|
||||
0xffffff
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* The pointer to the graphics buffer And palette */
|
||||
|
||||
static PALETTE_ENTRY colors[256];
|
||||
static Byte * vscreen=0; //[BMPW*BMPH];
|
||||
|
||||
/* Collision buffer */
|
||||
static Byte * colbuf=0; //[BMPW*BMPH];
|
||||
|
||||
Byte coltab[256];
|
||||
|
||||
long clip_low;
|
||||
long clip_high;
|
||||
|
||||
|
||||
static void create_cmap(void);
|
||||
static void draw_char(Byte ypos,Byte xpos,Byte chr,Byte col);
|
||||
static void draw_grid(void);
|
||||
INLINE extern void mputvid(unsigned int ad, unsigned int len, Byte d, Byte c);
|
||||
|
||||
|
||||
unsigned char * getGBuf(void)
|
||||
{
|
||||
return(vscreen);
|
||||
}
|
||||
|
||||
void draw_region(void){
|
||||
int i;
|
||||
|
||||
//emu_printi(last_line);
|
||||
|
||||
if (regionoff == 0xffff)
|
||||
i = master_clk/(LINECNT-1)-5;
|
||||
else
|
||||
i = master_clk/22+regionoff;
|
||||
//i = snapline(i, VDCwrite[0xA0], 0);
|
||||
|
||||
if (i<0) i=0;
|
||||
|
||||
#ifdef HALFHEIGHT
|
||||
i = i>>1;
|
||||
#else
|
||||
#endif
|
||||
|
||||
clip_low = last_line * (long)BMPW;
|
||||
clip_high = i * (long)BMPW;
|
||||
if (clip_high > BMPW*BMPH) clip_high = BMPW*BMPH;
|
||||
if (clip_low < 0) clip_low=0;
|
||||
if (clip_low < clip_high) draw_display();
|
||||
last_line=i;
|
||||
}
|
||||
|
||||
|
||||
#define fastmputvid1(ad,d,c) if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high)) { vscreen[ad]=d; colbuf[ad] |= c; coltab[c] |= colbuf[ad];}
|
||||
#define fastmputvid2(ad,d,c) if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high)) { vscreen[ad]=d; colbuf[ad] |= c; coltab[c] |= colbuf[ad];vscreen[ad+1]=d; colbuf[ad+1] |= c; coltab[c] |= colbuf[ad+1];}
|
||||
//#define fastmputvid1(ad,d,c) mputvid(ad,1,d,c);
|
||||
//#define fastmputvid2(ad,d,c) mputvid(ad,2,d,c);
|
||||
|
||||
|
||||
INLINE void mputvid(unsigned int ad, unsigned int len, Byte d, Byte c){
|
||||
if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high)) {
|
||||
unsigned int i;
|
||||
// JMH
|
||||
Byte d1;
|
||||
d1 = d;
|
||||
if ( ((len & 3)==0) && (sizeof(unsigned long) == 4) && ((ad & 3) == 0) )
|
||||
{
|
||||
unsigned long dddd = (((unsigned long)d1) & 0xff) | ((((unsigned long)d1) & 0xff) << 8) | ((((unsigned long)d1) & 0xff) << 16) | ((((unsigned long)d1) & 0xff) << 24);
|
||||
unsigned long cccc = (((unsigned long)c) & 0xff) | ((((unsigned long)c) & 0xff) << 8) | ((((unsigned long)c) & 0xff) << 16) | ((((unsigned long)c) & 0xff) << 24);
|
||||
for (i=0; i<len>>2; i++) {
|
||||
*((unsigned long*)(vscreen+ad)) = dddd;
|
||||
cccc |= *((unsigned long*)(colbuf+ad));
|
||||
*((unsigned long*)(colbuf+ad)) = cccc;
|
||||
coltab[c] |= ((cccc | (cccc >> 8) | (cccc >> 16) | (cccc >> 24)) & 0xff);
|
||||
ad += 4;
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (i=0; i<len; i++) {
|
||||
vscreen[ad]=d1;
|
||||
colbuf[ad] |= c;
|
||||
coltab[c] |= colbuf[ad++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void create_cmap(void){
|
||||
int i;
|
||||
|
||||
/* Initialise parts of the colors array */
|
||||
for (i = 0; i < 16; i++) {
|
||||
/* Use the color values from the color table */
|
||||
colors[i+32].r = colors[i].r = (colortable[i] & 0xff0000) >> 16; //18;
|
||||
colors[i+32].g = colors[i].g = (colortable[i] & 0x00ff00) >> 8; //10;
|
||||
colors[i+32].b = colors[i].b = (colortable[i] & 0x0000ff) >> 0; //2;
|
||||
}
|
||||
|
||||
for (i = 16; i < 32; i++) {
|
||||
/* Half-bright colors for the 50% scanlines */
|
||||
colors[i+32].r = colors[i].r = colors[i-16].r/2;
|
||||
colors[i+32].g = colors[i].g = colors[i-16].g/2;
|
||||
colors[i+32].b = colors[i].b = colors[i-16].b/2;
|
||||
}
|
||||
|
||||
for (i = 64; i < 256; i++) colors[i].r = colors[i].g = colors[i].b = 0;
|
||||
|
||||
for (i=0;i<256;i++)
|
||||
{
|
||||
emu_SetPaletteEntry(colors[i].r, colors[i].g, colors[i].b, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void draw_char(Byte ypos,Byte xpos,Byte chr,Byte col){
|
||||
int j,c;
|
||||
Byte cl,d1;
|
||||
int y,b,n;
|
||||
unsigned int pnt;
|
||||
|
||||
#ifdef HALFHEIGHT
|
||||
y = ypos>>1;
|
||||
#else
|
||||
y=(ypos & 0xFE);
|
||||
#endif
|
||||
pnt = y * BMPW + (xpos-8)+BORDERW;
|
||||
|
||||
ypos = ypos >> 1;
|
||||
n = 8 - (ypos % 8) - (chr % 8);
|
||||
if (n < 3) n = n + 7;
|
||||
|
||||
#ifdef HALFHEIGHT
|
||||
if ((pnt+BMPW*n >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high)) {
|
||||
#else
|
||||
if ((pnt+BMPW*2*n >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high)) {
|
||||
#endif
|
||||
|
||||
c=(int)chr + ypos;
|
||||
if (col & 0x01) c+=256;
|
||||
if (c > 511) c=c-512;
|
||||
|
||||
cl = ((col & 0x0E) >> 1);
|
||||
cl = ((cl&2) | ((cl&1)<<2) | ((cl&4)>>2)) + 8;
|
||||
|
||||
#ifdef HALFHEIGHT
|
||||
if ((y>0) && (y<112) && (xpos<157)) {
|
||||
#else
|
||||
if ((y>0) && (y<232) && (xpos<157)) {
|
||||
#endif
|
||||
for (j=0; j<n; j++) {
|
||||
d1 = cset[c+j];
|
||||
for (b=0; b<8; b++) {
|
||||
if (d1 & 0x80) {
|
||||
#ifdef HALFHEIGHT
|
||||
if ((xpos-8+b < 160) && (y+j < 120)) {
|
||||
#else
|
||||
if ((xpos-8+b < 160) && (y+j < 240)) {
|
||||
#endif
|
||||
fastmputvid1(pnt,cl,COL_CHAR);
|
||||
#ifdef HALFHEIGHT
|
||||
#else
|
||||
fastmputvid1(pnt+BMPW,cl,COL_CHAR);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
pnt+=1;
|
||||
d1 = d1 << 1;
|
||||
}
|
||||
#ifdef HALFHEIGHT
|
||||
pnt += BMPW-8;
|
||||
#else
|
||||
pnt += BMPW*2-8;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_grid(void){
|
||||
unsigned int pnt, pn1;
|
||||
Byte mask,d;
|
||||
int j,i,x,w;
|
||||
Byte color;
|
||||
|
||||
if (VDCwrite[0xA0] & 0x40) {
|
||||
for(j=0; j<9; j++) {
|
||||
#ifdef HALFHEIGHT
|
||||
pnt = (((j*12)+12) * BMPW);
|
||||
#else
|
||||
pnt = (((j*24)+24) * BMPW);
|
||||
#endif
|
||||
for (i=0; i<9; i++) {
|
||||
pn1 = pnt + (i * 16) + BORDERW;
|
||||
color = ColorVector[j*24+24];
|
||||
fastmputvid2(pn1, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||
color = ColorVector[j*24+25];
|
||||
fastmputvid2(pn1+BMPW, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||
#ifdef HALFHEIGHT
|
||||
#else
|
||||
color = ColorVector[j*24+26];
|
||||
fastmputvid2(pn1+BMPW*2, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// horizontal
|
||||
mask=0x01;
|
||||
for(j=0; j<9; j++) {
|
||||
#ifdef HALFHEIGHT
|
||||
pnt = (((j*12)+12) * BMPW);
|
||||
#else
|
||||
pnt = (((j*24)+24) * BMPW);
|
||||
#endif
|
||||
for (i=0; i<9; i++) {
|
||||
pn1 = pnt + (i * 16) + BORDERW;
|
||||
#ifdef HALFHEIGHT
|
||||
if ((pn1+BMPW*2 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high)) {
|
||||
#else
|
||||
if ((pn1+BMPW*3 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high)) {
|
||||
#endif
|
||||
d=VDCwrite[0xC0 + i];
|
||||
if (j == 8) {
|
||||
d=VDCwrite[0xD0+i];
|
||||
mask=1;
|
||||
}
|
||||
if (d & mask) {
|
||||
color = ColorVector[j*24+24];
|
||||
mputvid(pn1, 18, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||
color = ColorVector[j*24+25];
|
||||
mputvid(pn1+BMPW, 18, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||
#ifdef HALFHEIGHT
|
||||
#else
|
||||
color = ColorVector[j*24+26];
|
||||
mputvid(pn1+BMPW*2, 18, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
mask = mask << 1;
|
||||
}
|
||||
|
||||
// vertical
|
||||
mask=0x01;
|
||||
w=2;
|
||||
if (VDCwrite[0xA0] & 0x80) w=16;
|
||||
for(j=0; j<10; j++) {
|
||||
pnt=(j*16);
|
||||
mask=0x01;
|
||||
d=VDCwrite[0xE0+j];
|
||||
for (x=0; x<8; x++) {
|
||||
#ifdef HALFHEIGHT
|
||||
pn1 = pnt + (((x*12)+12) * BMPW) + BORDERW;
|
||||
#else
|
||||
pn1 = pnt + (((x*24)+24) * BMPW) + BORDERW;
|
||||
#endif
|
||||
if (d & mask) {
|
||||
#ifdef HALFHEIGHT
|
||||
for(i=0; i<12; i++) {
|
||||
#else
|
||||
for(i=0; i<24; i++) {
|
||||
#endif
|
||||
if ((pn1 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high)) {
|
||||
color = ColorVector[x*24+24+i];
|
||||
mputvid(pn1, w, (color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_VGRID);
|
||||
}
|
||||
pn1+=BMPW;
|
||||
}
|
||||
}
|
||||
mask = mask << 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void finish_display(void){
|
||||
vpp_finish_bmp(vscreen, 9, 5, BMPW-9, BMPH-5, BMPW, BMPH);
|
||||
}
|
||||
|
||||
|
||||
void clear_collision(void){
|
||||
load_colplus(colbuf);
|
||||
coltab[0x01]=coltab[0x02]=0;
|
||||
coltab[0x04]=coltab[0x08]=0;
|
||||
coltab[0x10]=coltab[0x20]=0;
|
||||
coltab[0x40]=coltab[0x80]=0;
|
||||
}
|
||||
|
||||
|
||||
void draw_display(void){
|
||||
int i,j,x,sm,t;
|
||||
Byte y,xt,yt,b,d1,cl,c;
|
||||
unsigned int pnt,pnt2;
|
||||
|
||||
#ifdef HALFHEIGHT
|
||||
for (i=clip_low/BMPW; i<clip_high/BMPW; i++) {
|
||||
memset(vscreen+i*BMPW, ((ColorVector[i<<1] & 0x38) >> 3) | (ColorVector[i<<1] & 0x80 ? 0 : 8), BMPW);
|
||||
}
|
||||
#else
|
||||
for (i=clip_low/BMPW; i<clip_high/BMPW; i++) {
|
||||
memset(vscreen+i*BMPW, ((ColorVector[i] & 0x38) >> 3) | (ColorVector[i] & 0x80 ? 0 : 8), BMPW);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (VDCwrite[0xA0] & 0x08) draw_grid();
|
||||
|
||||
if (useforen && (!(VDCwrite[0xA0] & 0x20))) return;
|
||||
|
||||
for(i=0x10; i<0x40; i+=4) draw_char(VDCwrite[i],VDCwrite[i+1],VDCwrite[i+2],VDCwrite[i+3]);
|
||||
|
||||
pnt=0x40;
|
||||
for(i=0; i<4; i++) {
|
||||
x=y=248;
|
||||
for (j=0; j<4; j++){
|
||||
xt = VDCwrite[pnt+j*4+1];
|
||||
yt = VDCwrite[pnt+j*4];
|
||||
if ((xt<240) && (yt<240)){
|
||||
x=xt;
|
||||
y=yt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(j=0; j<4; j++) {
|
||||
draw_char(y,x,VDCwrite[pnt+2],VDCwrite[pnt+3]);
|
||||
x+=16;
|
||||
pnt+=4;
|
||||
}
|
||||
}
|
||||
|
||||
c=8;
|
||||
for (i=12; i>=0; i -=4) {
|
||||
pnt2 = 0x80 + (i * 2);
|
||||
#ifdef HALFHEIGHT
|
||||
y = VDCwrite[i]>>1;
|
||||
#else
|
||||
y = VDCwrite[i];
|
||||
#endif
|
||||
x = VDCwrite[i+1]-8;
|
||||
t = VDCwrite[i+2];
|
||||
cl = ((t & 0x38) >> 3);
|
||||
cl = ((cl&2) | ((cl&1)<<2) | ((cl&4)>>2)) + 8;
|
||||
//#ifdef HALFHEIGHT
|
||||
// if ((x<164) && (y>0) && (y<112)) {
|
||||
//#else
|
||||
if ((x<164) && (y>0) && (y<232)) {
|
||||
//#endif
|
||||
pnt = y * BMPW + x + BORDERW + sproff;
|
||||
if ((pnt+BMPW*16 >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high)) {
|
||||
for (j=0; j<8; j++) {
|
||||
sm = (((j%2==0) && (((t>>1) & 1) != (t & 1))) || ((j%2==1) && (t & 1))) ? 1 : 0;
|
||||
d1 = VDCwrite[pnt2++];
|
||||
for (b=0; b<8; b++) {
|
||||
if (d1 & 0x01) {
|
||||
#ifdef HALFHEIGHT
|
||||
if ((x+b+sm<160) && (y+j<129)) {
|
||||
#else
|
||||
if ((x+b+sm<160) && (y+j<249)) {
|
||||
#endif
|
||||
fastmputvid1(sm+pnt,cl,c);
|
||||
#ifdef HALFHEIGHT
|
||||
#else
|
||||
fastmputvid1(sm+pnt+BMPW,cl,c);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
pnt += 1;
|
||||
d1 = d1 >> 1;
|
||||
}
|
||||
#ifdef HALFHEIGHT
|
||||
pnt += BMPW-8;
|
||||
#else
|
||||
pnt += BMPW*2-8;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
c = c >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void close_display(void)
|
||||
{
|
||||
}
|
||||
|
||||
void init_display(void)
|
||||
{
|
||||
if (vscreen==0) vscreen = (Byte *)emu_Malloc(BMPW*BMPH);
|
||||
if (colbuf == 0) colbuf = (Byte *)emu_Malloc(BMPW*BMPH);
|
||||
|
||||
create_cmap();
|
||||
memset(colbuf,0,BMPW*BMPH);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __VDC_H
|
||||
#define __VDC_H
|
||||
|
||||
//#define HALFHEIGHT 1
|
||||
|
||||
#define BORDERW 8
|
||||
#define BMPW (160+BORDERW) // 320
|
||||
#ifdef HALFHEIGHT
|
||||
#define BMPH 120
|
||||
#else
|
||||
#define BMPH 240
|
||||
#endif
|
||||
|
||||
|
||||
extern Byte coltab[];
|
||||
extern long clip_low;
|
||||
extern long clip_high;
|
||||
|
||||
extern unsigned char * getGBuf(void);
|
||||
|
||||
void init_display(void);
|
||||
void draw_display(void);
|
||||
void draw_region(void);
|
||||
void finish_display();
|
||||
void close_display(void);
|
||||
void clear_collision(void);
|
||||
|
||||
#endif
|
|
@ -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
|
|
@ -0,0 +1,680 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* Main O2 machine emulation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "audio.h"
|
||||
#include "types.h"
|
||||
#include "cpu.h"
|
||||
#include "config.h"
|
||||
#include "vdc.h"
|
||||
//#include "vpp.h"
|
||||
#include "vmachine.h"
|
||||
|
||||
#include "emuapi.h"
|
||||
|
||||
static Byte x_latch,y_latch;
|
||||
static Byte line_count;
|
||||
static int fps=FPS_NTSC;
|
||||
|
||||
//static Byte snapedlines[MAXLINES+2*MAXSNAP][256][2]; //500+2*50 *256*2 600*512
|
||||
|
||||
int evblclk=EVBLCLK_NTSC;
|
||||
|
||||
struct resource app_data;
|
||||
int frame=0;
|
||||
Byte dbstick1,dbstick2;
|
||||
|
||||
int int_clk; /* counter for length of /INT pulses */
|
||||
int master_clk; /* Master clock */
|
||||
int h_clk; /* horizontal clock */
|
||||
unsigned long clk_counter;
|
||||
int last_line;
|
||||
int key2vcnt=0;
|
||||
int mstate;
|
||||
int ccolflag=0;
|
||||
|
||||
int pendirq=0;
|
||||
int enahirq=1;
|
||||
int useforen=0;
|
||||
long regionoff=0xffff;
|
||||
int mxsnap=2;
|
||||
int sproff=0;
|
||||
int tweakedaudio=0;
|
||||
|
||||
Byte rom1[5120];
|
||||
Byte rom2[5120];
|
||||
Byte rom3[5120];
|
||||
Byte rom4[5120];
|
||||
|
||||
Byte intRAM[64];
|
||||
Byte extRAM[256];
|
||||
Byte extROM[1024];
|
||||
Byte VDCwrite[256];
|
||||
Byte ColorVector[MAXLINES];
|
||||
Byte AudioVector[MAXLINES];
|
||||
Byte *rom, *orom;
|
||||
|
||||
int key2[128];
|
||||
|
||||
#define KEY_0 0
|
||||
#define KEY_1 1
|
||||
#define KEY_2 2
|
||||
#define KEY_3 3
|
||||
#define KEY_4 4
|
||||
#define KEY_5 5
|
||||
#define KEY_6 6
|
||||
#define KEY_7 7
|
||||
#define KEY_8 8
|
||||
#define KEY_9 9
|
||||
#define KEY_A 10
|
||||
#define KEY_B 11
|
||||
#define KEY_C 12
|
||||
#define KEY_D 13
|
||||
#define KEY_E 14
|
||||
#define KEY_F 15
|
||||
#define KEY_G 16
|
||||
#define KEY_H 17
|
||||
#define KEY_I 18
|
||||
#define KEY_J 19
|
||||
#define KEY_K 20
|
||||
#define KEY_L 21
|
||||
#define KEY_M 22
|
||||
#define KEY_N 23
|
||||
#define KEY_O 24
|
||||
#define KEY_P 25
|
||||
#define KEY_Q 26
|
||||
#define KEY_R 27
|
||||
#define KEY_S 28
|
||||
#define KEY_T 29
|
||||
#define KEY_U 30
|
||||
#define KEY_V 31
|
||||
#define KEY_W 32
|
||||
#define KEY_X 33
|
||||
#define KEY_Y 34
|
||||
#define KEY_Z 35
|
||||
#define KEY_PLUS 35
|
||||
#define KEY_MINUS 36
|
||||
#define KEY_SLASH 38
|
||||
#define KEY_ASTERISK 39
|
||||
|
||||
#define KEY_SPACE 40
|
||||
#define KEY_EQUALS 41
|
||||
#define KEY_DEL 42
|
||||
#define KEY_ENTER 43
|
||||
#define KEY_STOP 44
|
||||
#define KEY_SLASH_PAD 45
|
||||
#define KEY_PLUS_PAD 46
|
||||
|
||||
static unsigned int key_map[6][8]= {
|
||||
{KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7},
|
||||
{KEY_8,KEY_9,0,0,KEY_SPACE,KEY_SLASH,KEY_L,KEY_P},
|
||||
{KEY_PLUS_PAD,KEY_W,KEY_E,KEY_R,KEY_T,KEY_U,KEY_I,KEY_O},
|
||||
{KEY_Q,KEY_S,KEY_D,KEY_F,KEY_G,KEY_H,KEY_J,KEY_K},
|
||||
{KEY_A,KEY_Z,KEY_X,KEY_C,KEY_V,KEY_B,KEY_M,KEY_STOP},
|
||||
{KEY_MINUS,KEY_ASTERISK,KEY_SLASH_PAD,KEY_EQUALS,KEY_Y,KEY_N,KEY_DEL,KEY_ENTER}
|
||||
};
|
||||
|
||||
|
||||
static void do_kluges(void);
|
||||
static void setvideomode(int t);
|
||||
|
||||
void run(void){
|
||||
cpu_exec();
|
||||
}
|
||||
|
||||
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) + 0x7f;
|
||||
}
|
||||
else {
|
||||
keyCode = key & 0x7f;
|
||||
}
|
||||
|
||||
//Serial.println(keyCode);
|
||||
|
||||
if (keyCode != -1) {
|
||||
iusbhk = keyCode;
|
||||
}
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
iusbhk = 0;
|
||||
}
|
||||
|
||||
void odd_Input(int click) {
|
||||
ik = emu_GetPad();
|
||||
ihk = emu_ReadI2CKeyboard();
|
||||
}
|
||||
|
||||
void handle_vbl(void){
|
||||
update_audio();
|
||||
// update_voice();
|
||||
// }
|
||||
if (!ccolflag) {
|
||||
clear_collision();
|
||||
ccolflag=1;
|
||||
}
|
||||
draw_region();
|
||||
ext_IRQ();
|
||||
mstate = 1;
|
||||
}
|
||||
|
||||
|
||||
void handle_evbl(void){
|
||||
static long last=0;
|
||||
static int rest_cnt=0;
|
||||
int i;
|
||||
|
||||
i = (15*app_data.speed/100);
|
||||
rest_cnt = (rest_cnt+1)%(i<5?5:i);
|
||||
last_line=0;
|
||||
master_clk -= evblclk;
|
||||
frame++;
|
||||
ccolflag=0;
|
||||
if (!app_data.debug) {
|
||||
finish_display();
|
||||
}
|
||||
|
||||
for (i=0; i<MAXLINES; i++) {
|
||||
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
||||
AudioVector[i] = VDCwrite[0xAA];
|
||||
}
|
||||
|
||||
if (key2vcnt++ > 10) {
|
||||
key2vcnt=0;
|
||||
for (i=0; i<128; i++) key2[i] = 0;
|
||||
dbstick1 = dbstick2 = 0;
|
||||
}
|
||||
mstate=0;
|
||||
}
|
||||
|
||||
|
||||
void init_system(void){
|
||||
int i,j,k;
|
||||
|
||||
last_line=0;
|
||||
dbstick1=0x00;
|
||||
dbstick2=0x00;
|
||||
mstate=0;
|
||||
master_clk=0;
|
||||
h_clk=0;
|
||||
line_count=0;
|
||||
itimer=0;
|
||||
clk_counter=0;
|
||||
for(i=0; i<256; i++) {
|
||||
VDCwrite[i]=0;
|
||||
extRAM[i]=0;
|
||||
}
|
||||
for(i=0; i<64; i++) {
|
||||
intRAM[i]=0;
|
||||
}
|
||||
for (i=0; i<MAXLINES; i++) AudioVector[i] = ColorVector[i] = 0;
|
||||
ccolflag=0;
|
||||
/*
|
||||
for (i=0; i<MAXLINES+2*MAXSNAP; i++)
|
||||
for (j=0; j<256; j++)
|
||||
for (k=0; k<2; k++)
|
||||
snapedlines[i][j][k]=0;
|
||||
*/
|
||||
for (i=0; i<128; i++) key2[i] = 0;
|
||||
key2vcnt=0;
|
||||
if (app_data.euro)
|
||||
setvideomode(1);
|
||||
else
|
||||
setvideomode(0);
|
||||
do_kluges();
|
||||
//init_vpp();
|
||||
}
|
||||
|
||||
|
||||
Byte read_t1(void){
|
||||
if ((h_clk > 16) || (master_clk > VBLCLK))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void write_p1(Byte d){
|
||||
if ((d & 0x80) != (p1 & 0x80)) {
|
||||
int i,l;
|
||||
//l = snapline((int)((float)master_clk/22.0+0.5), VDCwrite[0xA3], 1);
|
||||
for (i=l; i<MAXLINES; i++) ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (d & 0x80);
|
||||
}
|
||||
p1 = d;
|
||||
if (app_data.bank == 2) {
|
||||
if (p1 & 0x01)
|
||||
rom=rom2;
|
||||
else
|
||||
rom=rom1;
|
||||
}
|
||||
if (app_data.bank == 3) {
|
||||
switch(p1 & 0x03) {
|
||||
case 0:
|
||||
rom=rom1;
|
||||
break;
|
||||
case 1:
|
||||
rom=rom2;
|
||||
break;
|
||||
case 2:
|
||||
rom=rom3;
|
||||
break;
|
||||
case 3:
|
||||
rom=rom4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Byte read_P2(void){
|
||||
int i,si,so,km;
|
||||
|
||||
int k=ik&0x7f;
|
||||
int hk = ihk; //&0x7f;
|
||||
if (iusbhk) hk = iusbhk;
|
||||
|
||||
if (k & MASK_KEY_USER1) { // 1
|
||||
k = 1;
|
||||
}
|
||||
|
||||
switch(hk) {
|
||||
case 'q':
|
||||
case '1':
|
||||
hk = 2;
|
||||
break;
|
||||
case 'w':
|
||||
case '2':
|
||||
hk = 3;
|
||||
break;
|
||||
case 'e':
|
||||
case '3':
|
||||
hk = 4;
|
||||
break;
|
||||
case 'r':
|
||||
case '4':
|
||||
hk = 5;
|
||||
break;
|
||||
case 't':
|
||||
case '5':
|
||||
hk = 6;
|
||||
break;
|
||||
case 'y':
|
||||
case '6':
|
||||
hk = 7;
|
||||
break;
|
||||
case 'u':
|
||||
case '7':
|
||||
hk = 8;
|
||||
break;
|
||||
case 'i':
|
||||
case '8':
|
||||
hk = 9;
|
||||
break;
|
||||
case 'o':
|
||||
case '9':
|
||||
hk = 10;
|
||||
case 'p':
|
||||
case '0':
|
||||
hk = 1;
|
||||
break;
|
||||
default:
|
||||
hk = 0;
|
||||
break;
|
||||
};
|
||||
|
||||
if (!(p1 & 0x04)) {
|
||||
si = (p2 & 7);
|
||||
so=0xff;
|
||||
if (si<6) {
|
||||
for (i=0; i<8; i++) {
|
||||
km = key_map[si][i];
|
||||
if ( (km == (k-1)) && (k) )
|
||||
{
|
||||
so = i ^ 0x07;
|
||||
}
|
||||
else if ( (km == (hk-1)) && (hk) )
|
||||
{
|
||||
so = i ^ 0x07;
|
||||
}
|
||||
// if ((key[km] && ((!joykeystab[km]) || (key_shifts & KB_CAPSLOCK_FLAG))) || (key2[km])) {
|
||||
// so = i ^ 0x07;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if (so != 0xff) {
|
||||
p2 = p2 & 0x0F;
|
||||
p2 = p2 | (so << 5);
|
||||
} else {
|
||||
p2 = p2 | 0xF0;
|
||||
}
|
||||
} else {
|
||||
p2 = p2 | 0xF0;
|
||||
}
|
||||
return(p2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Byte ext_read(ADDRESS adr){
|
||||
Byte d;
|
||||
Byte si;
|
||||
Byte m;
|
||||
int i;
|
||||
|
||||
if (!(p1 & 0x08) && !(p1 & 0x40)) {
|
||||
/* Handle VDC Read */
|
||||
switch(adr) {
|
||||
case 0xA1:
|
||||
d = VDCwrite[0xA0] & 0x02;
|
||||
if (master_clk > VBLCLK) d = d | 0x08;
|
||||
if (h_clk < (LINECNT-7)) d = d | 0x01;
|
||||
if (sound_IRQ) d = d | 0x04;
|
||||
sound_IRQ=0;
|
||||
return d;
|
||||
case 0xA2:
|
||||
si = VDCwrite[0xA2];
|
||||
m=0x01;
|
||||
d=0;
|
||||
for(i=0; i<8; i++) {
|
||||
if (si & m) {
|
||||
if (coltab[1] & m) d = d | (coltab[1] & (m ^ 0xFF));
|
||||
if (coltab[2] & m) d = d | (coltab[2] & (m ^ 0xFF));
|
||||
if (coltab[4] & m) d = d | (coltab[4] & (m ^ 0xFF));
|
||||
if (coltab[8] & m) d = d | (coltab[8] & (m ^ 0xFF));
|
||||
if (coltab[0x10] & m) d = d | (coltab[0x10] & (m ^ 0xFF));
|
||||
if (coltab[0x20] & m) d = d | (coltab[0x20] & (m ^ 0xFF));
|
||||
if (coltab[0x80] & m) d = d | (coltab[0x80] & (m ^ 0xFF));
|
||||
}
|
||||
m = m << 1;
|
||||
}
|
||||
return d;
|
||||
case 0xA5:
|
||||
if (!(VDCwrite[0xA0] & 0x02)) {
|
||||
return x_latch;
|
||||
}
|
||||
else {
|
||||
x_latch = h_clk * 12;
|
||||
return x_latch;
|
||||
}
|
||||
case 0xA4:
|
||||
if (!(VDCwrite[0xA0] & 0x02)) {
|
||||
return y_latch;
|
||||
}
|
||||
else {
|
||||
y_latch = master_clk/22;
|
||||
if (y_latch > 241) y_latch=0xFF;
|
||||
return y_latch;
|
||||
}
|
||||
default:
|
||||
return VDCwrite[adr];
|
||||
}
|
||||
} else if (!(p1 & 0x10)) {
|
||||
/* Handle ext RAM Read */
|
||||
return extRAM[adr & 0xFF];
|
||||
//} else if (!(p1 & 0x20)) {
|
||||
// /* Read a Videopac+ register */
|
||||
// return vpp_read(adr);
|
||||
} else if (app_data.exrom && (p1 & 0x02)) {
|
||||
/* Handle read from exrom */
|
||||
return extROM[(p2 << 8) | (adr & 0xFF)];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Byte in_bus(void){
|
||||
Byte si=0,d=0,mode=0,jn=0;
|
||||
int key;
|
||||
|
||||
|
||||
if ((p1 & 0x08) && (p1 & 0x10)) {
|
||||
/* Handle joystick read */
|
||||
if (!(p1 & 0x04)) {
|
||||
si = (p2 & 7);
|
||||
}
|
||||
d=0xFF;
|
||||
/* Get current input */
|
||||
key = ik;
|
||||
|
||||
app_data.stick[0]=0;
|
||||
app_data.stick[1]=1;
|
||||
/*
|
||||
if ( emu_GetPad() & 0x80 )
|
||||
{
|
||||
app_data.stick[0]=1;
|
||||
app_data.stick[1]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
app_data.stick[0]=0;
|
||||
app_data.stick[1]=1;
|
||||
}
|
||||
|
||||
|
||||
if (si == 1) {
|
||||
mode = app_data.stick[0];
|
||||
jn = 0;
|
||||
} else {
|
||||
mode = app_data.stick[1];
|
||||
jn = 1;
|
||||
}
|
||||
*/
|
||||
mode=1;
|
||||
//if (key & 0x8000) jn=1;
|
||||
//else jn=0;
|
||||
|
||||
switch(mode) {
|
||||
case 1:
|
||||
if (key & MASK_JOY2_RIGHT) d &= 0xF7;
|
||||
if (key & MASK_JOY2_LEFT) d &= 0xFD;
|
||||
if (key & MASK_JOY2_UP) d &= 0xFE;
|
||||
if (key & MASK_JOY2_DOWN) d &= 0xFB;
|
||||
if (key & MASK_JOY2_BTN) d &= 0xEF;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Get current input */
|
||||
// key = emu_GetPad();
|
||||
// if (key & JKEY_PLEFT) d &= 0xF7;
|
||||
// if (key & JKEY_PRIGHT) d &= 0xFD;
|
||||
// if (key & JKEY_PUP) d &= 0xFE;
|
||||
// if (key & JKEY_PDOWN) d &= 0xFB;
|
||||
// if (key & JKEY_PSPACE) d &= 0xEF;
|
||||
break;
|
||||
}
|
||||
if (si == 1) {
|
||||
if (dbstick1) d = dbstick1;
|
||||
} else {
|
||||
if (dbstick2) d = dbstick2;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
void ext_write(Byte dat, ADDRESS adr){
|
||||
int i;
|
||||
|
||||
if (!(p1 & 0x08)) {
|
||||
/* Handle VDC Write */
|
||||
if (adr == 0xA0){
|
||||
if ((VDCwrite[0xA0] & 0x02) && !(dat & 0x02)) {
|
||||
y_latch = master_clk/22;
|
||||
x_latch = h_clk * 12;
|
||||
if (y_latch > 241) y_latch=0xFF;
|
||||
}
|
||||
if ((master_clk <= VBLCLK) && (VDCwrite[0xA0] != dat)) {
|
||||
if (!ccolflag) {
|
||||
clear_collision();
|
||||
ccolflag=1;
|
||||
}
|
||||
draw_region();
|
||||
}
|
||||
} else if (adr == 0xA2) {
|
||||
clear_collision();
|
||||
ccolflag=1;
|
||||
} else if (adr == 0xA3){
|
||||
int l;
|
||||
//l = snapline((int)((float)master_clk/22.0+0.5), dat, 1);
|
||||
for (i=l; i<MAXLINES; i++) ColorVector[i] = (dat & 0x7f) | (p1 & 0x80);
|
||||
} else if (adr == 0xAA) {
|
||||
for (i=master_clk/22; i<MAXLINES; i++) AudioVector[i]=dat;
|
||||
}
|
||||
VDCwrite[adr]=dat;
|
||||
} else if (!(p1 & 0x10) && !(p1 & 0x40)) {
|
||||
adr = adr & 0xFF;
|
||||
if (adr < 0x80) {
|
||||
/* Handle ext RAM Write */
|
||||
extRAM[adr] = dat;
|
||||
} else {
|
||||
/* Handle The Voice */
|
||||
if (!(dat & 0x20))
|
||||
{
|
||||
//JMH reset_voice();
|
||||
}
|
||||
else {
|
||||
//JMH
|
||||
// if (adr == 0xE4)
|
||||
// set_voice_bank(0);
|
||||
// else if ((adr >= 0xE8) && (adr <= 0xEF))
|
||||
// set_voice_bank(adr-0xE7);
|
||||
// else if (((adr >= 0x80) && (adr <= 0xDF)) || ((adr >= 0xF0) && (adr <= 0xFF)))
|
||||
// trigger_voice(adr);
|
||||
}
|
||||
}
|
||||
//} else if (!(p1 & 0x20)) {
|
||||
// /* Write to a Videopac+ register */
|
||||
// vpp_write(dat,adr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void do_kluges(void){
|
||||
if (app_data.crc == 0xA7344D1F) pendirq=1; /* Atlantis */
|
||||
if (app_data.crc == 0xFB83171E) pendirq=1; /* Blockout*/
|
||||
if (app_data.crc == 0x881CEAE4) pendirq=1; /* Wall Street */
|
||||
|
||||
if (app_data.crc == 0x9E42E766) useforen=1; /* Turtles */
|
||||
if (app_data.crc == 0x1C750349) useforen=1; /* Turtles (European version) */
|
||||
if (app_data.crc == 0x202F2749) useforen=1; /* Q*bert */
|
||||
|
||||
if (app_data.crc == 0xFB83171E) enahirq=0; /* Blockout*/
|
||||
|
||||
if (app_data.crc == 0xFB83171E) regionoff=1; /* Blockout*/
|
||||
if (app_data.crc == 0x202F2749) regionoff=1; /* Q*bert */
|
||||
if (app_data.crc == 0x5216771A) regionoff=1; /* Popeye */
|
||||
if (app_data.crc == 0x0C2E4811) regionoff=12; /* Out of this World! / Helicopter Rescue! */
|
||||
if (app_data.crc == 0x67069924) regionoff=11; /* Smithereens! */
|
||||
if (app_data.crc == 0x44D1A8A5) regionoff=11; /* Smithereens! (European version) */
|
||||
if (app_data.crc == 0xB936BD78) regionoff=12; /* Type & Tell */
|
||||
if (app_data.crc == 0xDC30AD3D) regionoff=10; /* Dynasty! */
|
||||
if (app_data.crc == 0x7810BAD5) regionoff=10; /* Dynasty! (European) */
|
||||
if (app_data.crc == 0xA7344D1F) regionoff=0; /* Atlantis */
|
||||
if (app_data.crc == 0xD0BC4EE6) regionoff=12; /* Frogger */
|
||||
if (app_data.crc == 0x825976A9) regionoff=0; /* Mousing Cat 8kb */
|
||||
if (app_data.crc == 0xF390BFEC) regionoff=0; /* Mousing Cat 4kb */
|
||||
if (app_data.crc == 0x3BFEF56B) regionoff=1; /* Four in 1 Row! */
|
||||
if (app_data.crc == 0x9BFC3E01) regionoff=10; /* Demon Attack */
|
||||
if (app_data.crc == 0x6CEBAB74) regionoff=12; /* P.T. Barnum's Acrobats! (European version) */
|
||||
if (app_data.crc == 0xE7B26A56) regionoff=12; /* P.T. Barnum's Acrobats! (European version - Extra keys) */
|
||||
|
||||
if (app_data.crc == 0xFB83171E) mxsnap=3; /* Blockout*/
|
||||
if (app_data.crc == 0xA57E1724) mxsnap=12; /* Catch the Ball / Noughts and Crosses */
|
||||
if (app_data.crc == 0xFD179F6D) mxsnap=3; /* Clay Pigeon! */
|
||||
if (app_data.crc == 0x9BFC3E01) mxsnap=0; /* Demon Attack */
|
||||
if (app_data.crc == 0x9C9DDDF9) mxsnap=3; /* Verkehr */
|
||||
if (app_data.crc == 0x95936B07) mxsnap=3; /* Super Cobra */
|
||||
if (app_data.crc == 0x881CEAE4) mxsnap=3; /* Wall Street */
|
||||
if (app_data.crc == 0x9E42E766) mxsnap=0; /* Turtles */
|
||||
if (app_data.crc == 0x1C750349) mxsnap=0; /* Turtles (European version) */
|
||||
if (app_data.crc == 0xD0BC4EE6) mxsnap=3; /* Frogger */
|
||||
if (app_data.crc == 0x3BFEF56B) mxsnap=6; /* Four in 1 Row! */
|
||||
|
||||
if (app_data.crc == 0xA7344D1F) setvideomode(1); /* Atlantis */
|
||||
if (app_data.crc == 0x39E31BF0) setvideomode(1); /* Jake */
|
||||
if (app_data.crc == 0x3351FEDA) setvideomode(1); /* Power Lords */
|
||||
if (app_data.crc == 0x40AE062D) setvideomode(1); /* Power Lords (alternate) */
|
||||
if (app_data.crc == 0xD158EEBA) setvideomode(1); /* Labirinth */
|
||||
if (app_data.crc == 0x26B0FF5B) setvideomode(1); /* Nightmare */
|
||||
if (app_data.crc == 0xDF36683F) setvideomode(1); /* Shark Hunter */
|
||||
if (app_data.crc == 0xAF307559) setvideomode(1); /* Super Bee 8Kb */
|
||||
if (app_data.crc == 0x9585D511) setvideomode(1); /* Super Bee 4Kb */
|
||||
if (app_data.crc == 0x58FA6766) setvideomode(1); /* War of the Nerves */
|
||||
if (app_data.crc == 0x58FA6766) setvideomode(1); /* War of the Nerves */
|
||||
if (app_data.crc == 0x39989464) setvideomode(1); /* Hockey! / Soccer! */
|
||||
if (app_data.crc == 0xB47F3E0B) setvideomode(1); /* Kill the Attacking Aliens Demo */
|
||||
if (app_data.crc == 0x3BFEF56B) setvideomode(1); /* Four in 1 Row! */
|
||||
if (app_data.crc == 0x68560DC7) setvideomode(1); /* Jopac Moto Crash */
|
||||
if (app_data.crc == 0x202F2749) setvideomode(0); /* Q*bert */
|
||||
if (app_data.crc == 0xFB83171E) setvideomode(0); /* Blockout*/
|
||||
if (app_data.crc == 0x9BFC3E01) setvideomode(0); /* Demon Attack */
|
||||
if (app_data.crc == 0x239DF97D) setvideomode(0); /* Pachinko! */
|
||||
if ((app_data.crc == 0xF390BFEC) || (app_data.crc == 0x825976A9)){ /* Mousing Cat */
|
||||
setvideomode(1);
|
||||
evblclk=7642;
|
||||
}
|
||||
if (app_data.crc == 0xD0BC4EE6) { /* Frogger */
|
||||
setvideomode(1);
|
||||
evblclk=7642;
|
||||
}
|
||||
if ((app_data.crc == 0x2DCB77F0) || (app_data.crc == 0xF6882734)) { /* Depth Charge / Marksman */
|
||||
setvideomode(1);
|
||||
evblclk=9000;
|
||||
}
|
||||
if (app_data.crc == 0x881CEAE4) { /* Wall Street */
|
||||
setvideomode(1);
|
||||
evblclk=6100;
|
||||
}
|
||||
|
||||
if (app_data.crc == 0xD0BC4EE6) tweakedaudio=1; /* Frogger */
|
||||
if (app_data.crc == 0x5216771A) tweakedaudio=1; /* Popeye */
|
||||
if (app_data.crc == 0xAFB23F89) tweakedaudio=1; /* Musician */
|
||||
|
||||
if (app_data.crc == 0xD3B09FEC) sproff=1; /* Volleyball! */
|
||||
}
|
||||
|
||||
/*
|
||||
int snapline(int pos, Byte reg, int t){
|
||||
int i;
|
||||
for (i=0; i<mxsnap; i++){
|
||||
if (snapedlines[pos+MAXSNAP-i][reg][t]) return pos-i;
|
||||
if (snapedlines[pos+MAXSNAP+i][reg][t]) return pos+i;
|
||||
}
|
||||
snapedlines[pos+MAXSNAP][reg][t]=1;
|
||||
return pos;
|
||||
}
|
||||
*/
|
||||
|
||||
static void setvideomode(int t){
|
||||
if (t) {
|
||||
evblclk = EVBLCLK_PAL;
|
||||
fps = FPS_PAL;
|
||||
} else {
|
||||
evblclk = EVBLCLK_NTSC;
|
||||
fps = FPS_NTSC;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
#ifndef VMACHINE_H
|
||||
#define VMACHINE_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define LINECNT 21
|
||||
#define MAXLINES 500
|
||||
#define MAXSNAP 50
|
||||
|
||||
#define VBLCLK 5493
|
||||
#define EVBLCLK_NTSC 5964
|
||||
#define EVBLCLK_PAL 7259
|
||||
|
||||
#define FPS_NTSC 60
|
||||
#define FPS_PAL 50
|
||||
|
||||
extern Byte dbstick1, dbstick2;
|
||||
extern int last_line;
|
||||
|
||||
extern int evblclk;
|
||||
|
||||
extern int master_clk; /* Master clock */
|
||||
extern int int_clk; /* counter for length of /INT pulses for JNI */
|
||||
extern int h_clk; /* horizontal clock */
|
||||
extern int mstate;
|
||||
|
||||
extern Byte rom1[];
|
||||
extern Byte rom2[];
|
||||
extern Byte rom3[];
|
||||
extern Byte rom4[];
|
||||
|
||||
extern Byte intRAM[];
|
||||
extern Byte extRAM[];
|
||||
extern Byte extROM[];
|
||||
extern Byte VDCwrite[256];
|
||||
extern Byte ColorVector[MAXLINES];
|
||||
extern Byte AudioVector[MAXLINES];
|
||||
extern Byte *rom;
|
||||
extern Byte *orom;
|
||||
|
||||
extern int frame;
|
||||
extern int key2[128];
|
||||
extern int key2vcnt;
|
||||
extern unsigned long clk_counter;
|
||||
extern int ccolflag;
|
||||
|
||||
extern int enahirq;
|
||||
extern int pendirq;
|
||||
extern int useforen;
|
||||
extern long regionoff;
|
||||
extern int sproff;
|
||||
extern int tweakedaudio;
|
||||
|
||||
Byte read_P2(void);
|
||||
int snapline(int pos, Byte reg, int t);
|
||||
void ext_write(Byte dat, ADDRESS adr);
|
||||
Byte ext_read(ADDRESS adr);
|
||||
void handle_vbl(void);
|
||||
void handle_evbl(void);
|
||||
Byte in_bus(void);
|
||||
void write_p1(Byte d);
|
||||
Byte read_t1(void);
|
||||
void init_system(void);
|
||||
void run(void);
|
||||
|
||||
|
||||
extern struct resource {
|
||||
int bank;
|
||||
int debug;
|
||||
int stick[2];
|
||||
int limit;
|
||||
int sound_en;
|
||||
int speed;
|
||||
int wsize;
|
||||
int fullscreen;
|
||||
int scanlines;
|
||||
int voice;
|
||||
int svolume;
|
||||
int vvolume;
|
||||
int exrom;
|
||||
int filter;
|
||||
int euro;
|
||||
int openb;
|
||||
unsigned long crc;
|
||||
char *window_title;
|
||||
char *scshot;
|
||||
} app_data;
|
||||
|
||||
|
||||
#endif /* VMACHINE_H */
|
||||
|
|
@ -0,0 +1,488 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* Videopac+ G7400 emulation
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "types.h"
|
||||
#include "vmachine.h"
|
||||
#include "vdc.h"
|
||||
#include "vpp_cset.h"
|
||||
#include "vpp.h"
|
||||
|
||||
#include "emuapi.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int w;
|
||||
int h;
|
||||
unsigned char * line;
|
||||
// unsigned char line[320][250];
|
||||
} BITMAP;
|
||||
|
||||
static void clear(BITMAP * bmp)
|
||||
{
|
||||
int i,j;
|
||||
bmp->line = (unsigned char *)emu_Malloc(BMPW*(BMPH+10));
|
||||
|
||||
|
||||
for(i=0;i<bmp->h;i++)
|
||||
for(j=0;j<bmp->w;j++)
|
||||
//bmp->line[i][j] = 0;
|
||||
*bmp->line++ = 0;
|
||||
}
|
||||
|
||||
|
||||
static void vpp_draw_char(int x, int y, Byte ch, Byte c0, Byte c1, Byte ext, Byte dw, Byte dh, Byte ul);
|
||||
static void vpp_update_screen(void);
|
||||
|
||||
|
||||
static Byte LumReg = 0xff, TraReg = 0xff;
|
||||
static BITMAP svppbmp;
|
||||
static BITMAP * vppbmp = &svppbmp;
|
||||
//static Byte *colplus = NULL;
|
||||
//static Byte colplus[BMPW*BMPH];
|
||||
static int vppon = 1;
|
||||
static int vpp_cx = 0;
|
||||
static int vpp_cy = 0;
|
||||
static Byte vpp_data = 0;
|
||||
static int inc_curs=1;
|
||||
static int slice=0;
|
||||
static int vpp_y0=0;
|
||||
static Byte vpp_r=0;
|
||||
static Byte dchars[2][960];
|
||||
static Byte vpp_mem[40][32][4];
|
||||
static int frame_cnt=0;
|
||||
static int blink_st=0;
|
||||
static int slicemode=0;
|
||||
static int need_update=0;
|
||||
|
||||
|
||||
|
||||
|
||||
Byte read_PB(Byte p){
|
||||
p &= 0x3;
|
||||
switch (p) {
|
||||
case 0:
|
||||
return LumReg >> 4;
|
||||
break;
|
||||
case 1:
|
||||
return LumReg & 0xf;
|
||||
break;
|
||||
case 2:
|
||||
return TraReg >> 4;
|
||||
break;
|
||||
case 3:
|
||||
return TraReg & 0xf;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void write_PB(Byte p, Byte val){
|
||||
p &= 0x3;
|
||||
val &= 0xf;
|
||||
|
||||
switch (p) {
|
||||
case 0:
|
||||
LumReg = (val<<4) | (LumReg & 0xf);
|
||||
break;
|
||||
case 1:
|
||||
LumReg = (LumReg & 0xf0) | val;
|
||||
break;
|
||||
case 2:
|
||||
TraReg = (val<<4) | (TraReg & 0xf);
|
||||
break;
|
||||
case 3:
|
||||
TraReg = (TraReg & 0xf0) | val;
|
||||
break;
|
||||
}
|
||||
need_update = 1;
|
||||
}
|
||||
|
||||
|
||||
Byte vpp_read(ADDRESS adr){
|
||||
Byte t;
|
||||
switch (adr){
|
||||
case 4:
|
||||
return vpp_mem[vpp_cx][vpp_cy][1];
|
||||
case 5:
|
||||
if (slicemode) {
|
||||
Byte ext, chr;
|
||||
chr = vpp_mem[vpp_cx][vpp_cy][0];
|
||||
ext = (vpp_mem[vpp_cx][vpp_cy][1] & 0x80) ? 1 : 0;
|
||||
if (chr < 0xA0)
|
||||
t = 0;
|
||||
else {
|
||||
t = dchars[ext][(chr-0xA0)*10+slice];
|
||||
t = ((t&0x80)>>7) | ((t&0x40)>>5) | ((t&0x20)>>3) | ((t&0x10)>>1) | ((t&0x08)<<1) | ((t&0x04)<<3) | ((t&0x02)<<5) | ((t&0x01)<<7);
|
||||
}
|
||||
slice = (slice+1) % 10;
|
||||
} else {
|
||||
t = vpp_mem[vpp_cx][vpp_cy][0];
|
||||
if (inc_curs) {
|
||||
vpp_cx++;
|
||||
if (vpp_cx >= 40) {
|
||||
vpp_cx = 0;
|
||||
vpp_cy++;
|
||||
if (vpp_cy >= 24) vpp_cy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
case 6:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void vpp_write(Byte dat, ADDRESS adr){
|
||||
switch (adr) {
|
||||
case 0:
|
||||
if (!slicemode) vpp_mem[vpp_cx][vpp_cy][1] = dat;
|
||||
break;
|
||||
case 1:
|
||||
if (slicemode) {
|
||||
Byte ext, chr;
|
||||
chr = vpp_mem[vpp_cx][vpp_cy][0];
|
||||
ext = (vpp_mem[vpp_cx][vpp_cy][1] & 0x80) ? 1 : 0;
|
||||
if (chr >= 0xA0) dchars[ext][(chr-0xA0)*10+slice] = ((dat&0x80)>>7) | ((dat&0x40)>>5) | ((dat&0x20)>>3) | ((dat&0x10)>>1) | ((dat&0x08)<<1) | ((dat&0x04)<<3) | ((dat&0x02)<<5) | ((dat&0x01)<<7);
|
||||
slice = (slice+1) % 10;
|
||||
} else {
|
||||
vpp_mem[vpp_cx][vpp_cy][0] = dat;
|
||||
if ((dat>0x7f) && (dat<0xa0) && (!(vpp_mem[vpp_cx][vpp_cy][1] & 0x80))) {
|
||||
vpp_mem[vpp_cx][vpp_cy][2] = dat;
|
||||
vpp_mem[vpp_cx][vpp_cy][3] = vpp_mem[vpp_cx][vpp_cy][1];
|
||||
} else {
|
||||
vpp_mem[vpp_cx][vpp_cy][2] = vpp_mem[vpp_cx][vpp_cy][3] = 0;
|
||||
}
|
||||
if (inc_curs) {
|
||||
vpp_cx++;
|
||||
if (vpp_cx >= 40) {
|
||||
vpp_cx = 0;
|
||||
vpp_cy++;
|
||||
if (vpp_cy >= 24) vpp_cy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
vpp_data = dat;
|
||||
break;
|
||||
case 3:
|
||||
switch (dat & 0xe0) {
|
||||
case 0x00: /* plus_cmd_brow */
|
||||
vpp_cy = vpp_data & 0x1f;
|
||||
vpp_cx = 0;
|
||||
break;
|
||||
case 0x20: /* plus_cmd_loady */
|
||||
vpp_cy = vpp_data & 0x1f;
|
||||
break;
|
||||
case 0x40: /* plus_cmd_loadx */
|
||||
vpp_cx = vpp_data % 40;
|
||||
break;
|
||||
case 0x60: /* plus_cmd_incc */
|
||||
vpp_cx++;
|
||||
if (vpp_cx >= 40) {
|
||||
vpp_cx = 0;
|
||||
vpp_cy++;
|
||||
if (vpp_cy >= 24) vpp_cy = 0;
|
||||
}
|
||||
break;
|
||||
case 0x80: /* plus_cmd_loadm */
|
||||
slicemode = 0;
|
||||
slice = (vpp_data & 0x1f) % 10;
|
||||
switch (vpp_data & 0xe0) {
|
||||
case 0x00: /* plus_loadm_wr */
|
||||
inc_curs = 1;
|
||||
break;
|
||||
case 0x20: /* plus_loadm_rd */
|
||||
inc_curs = 1;
|
||||
break;
|
||||
case 0x40: /* plus_loadm_wrni */
|
||||
inc_curs = 0;
|
||||
break;
|
||||
case 0x60: /* plus_loadm_rdni */
|
||||
inc_curs = 0;
|
||||
break;
|
||||
case 0x80: /* plus_loadm_wrsl */
|
||||
slicemode = 1;
|
||||
break;
|
||||
case 0xA0: /* plus_loadm_rdsl */
|
||||
slicemode = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xA0: /* plus_cmd_loadr */
|
||||
vpp_r = vpp_data;
|
||||
break;
|
||||
case 0xC0: /* plus_cmd_loady0 */
|
||||
vpp_y0 = (vpp_data & 0x1f) % 24;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
need_update = 1;
|
||||
}
|
||||
|
||||
|
||||
void vpp_finish_bmp(Byte *vmem, int offx, int offy, int w, int h, int totw, int toth){
|
||||
int i, x, y, t, c, nc, clrx, clry;
|
||||
int tcol[16], m[8] = {0x01, 0x10, 0x04, 0x40, 0x02, 0x20, 0x08, 0x80};
|
||||
Byte *pnt, *pnt2, *pnt3;
|
||||
|
||||
if (vppon) {
|
||||
//memset(colplus,0,BMPW*BMPH);
|
||||
vppon=0;
|
||||
}
|
||||
|
||||
if (TraReg == 0xff) return;
|
||||
|
||||
vppon=1;
|
||||
|
||||
frame_cnt--;
|
||||
if (frame_cnt<=0) {
|
||||
frame_cnt = 100;
|
||||
blink_st = 1-blink_st;
|
||||
need_update = 1;
|
||||
}
|
||||
|
||||
if (need_update) vpp_update_screen();
|
||||
|
||||
for (i=0; i<8; i++) tcol[i] = tcol[i+8] = !(TraReg & m[i]);
|
||||
|
||||
if (w > totw-offx) w = totw-offx;
|
||||
if (h > toth-offy) h = toth-offy;
|
||||
|
||||
if (w > vppbmp->w) w = vppbmp->w;
|
||||
if (h > vppbmp->h) h = vppbmp->h;
|
||||
|
||||
clrx = clry = 0;
|
||||
for (i=0; (!clrx) && (i<totw); i++) if (tcol[vmem[offy*totw+i]&7]) clrx=1;
|
||||
for (i=0; (!clry) && (i<toth); i++) if (tcol[vmem[i*totw+offx]&7]) clry=1;
|
||||
if (clrx) for (y=0; y<offy; y++) for (x=0; x<totw; x++) vmem[y*totw+x]=0;
|
||||
if (clry) for (y=0; y<toth; y++) for (x=0; x<offx; x++) vmem[y*totw+x]=0;
|
||||
|
||||
for (y=0; y<h; y++){
|
||||
pnt = vmem+(offy+y)*totw + offx;
|
||||
// pnt2 = (Byte *)vppbmp->line[y];
|
||||
pnt2 = (Byte *)&vppbmp->line[y*320];
|
||||
|
||||
x=0;
|
||||
while (x < w) {
|
||||
pnt3 = pnt;
|
||||
c = *pnt++;
|
||||
t = x++;
|
||||
|
||||
if ((((x+offx) & 3) == 0) && (sizeof(unsigned long)==4)) {
|
||||
unsigned long cccc, dddd, *p = (unsigned long*) pnt;
|
||||
int t2=x, w2=w-4;
|
||||
cccc = (((unsigned long)c) & 0xff) | ((((unsigned long)c) & 0xff) << 8) | ((((unsigned long)c) & 0xff) << 16) | ((((unsigned long)c) & 0xff) << 24);
|
||||
dddd = *p++;
|
||||
while ((x<w2) && (dddd == cccc)) {
|
||||
x += 4;
|
||||
dddd = *p++;
|
||||
}
|
||||
pnt += x-t2;
|
||||
}
|
||||
|
||||
if (c<16) {
|
||||
if (tcol[c]){
|
||||
if (app_data.openb)
|
||||
for (i=0; i<x-t; i++) *pnt3++ = *pnt2++ & 0xf;
|
||||
else {
|
||||
memcpy(pnt3, pnt2, x-t);
|
||||
pnt2 += x-t;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<x-t; i++) {
|
||||
nc = *pnt2++;
|
||||
if ((nc & 0x10) && app_data.openb) {
|
||||
*pnt3++ = nc & 0xf;
|
||||
} else if (nc & 8) {
|
||||
//colplus[pnt3++ - vmem] = 0x40;
|
||||
} else {
|
||||
pnt3++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void vpp_draw_char(int x, int y, Byte ch, Byte c0, Byte c1, Byte ext, Byte dw, Byte dh, Byte ul){
|
||||
int xx, yy, d, m, k;
|
||||
|
||||
if ((x>39) || (y>24) || (ext>1)) return;
|
||||
|
||||
d = (dh==2) ? 5 : 0;
|
||||
|
||||
for (yy=0; yy<10; yy++) {
|
||||
if (ul && (d==9))
|
||||
k = 255;
|
||||
else if (ch >= 0xA0)
|
||||
k = dchars[ext][(ch-0xA0)*10 + d];
|
||||
else if (ch >= 0x80)
|
||||
k = 255;
|
||||
else
|
||||
k = vpp_cset[ext][ch * 10 + d];
|
||||
|
||||
m = (dw==2) ? 0x08 : 0x80;
|
||||
|
||||
for (xx=0; xx<8; xx++) {
|
||||
//vppbmp->line[y*10+yy][x*8+xx] = (k & m) ? c1 : c0;
|
||||
vppbmp->line[(y*10+yy)*320+ x*8+xx] = (k & m) ? c1 : c0;
|
||||
if ((xx%2) || (dw==0)) m >>= 1;
|
||||
}
|
||||
if ((yy%2) || (dh==0)) d++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void vpp_update_screen(void){
|
||||
int i,x,y,l,chr,attr,ext,c0,c1,dw,dh,hpar,vpar,lvd,lhd,ser_chr,ser_atr,ul,conc,box;
|
||||
int tlum[8], m[8] = {0x01, 0x10, 0x04, 0x40, 0x02, 0x20, 0x08, 0x80};
|
||||
|
||||
clear(vppbmp);
|
||||
|
||||
for (i=0; i<8; i++) tlum[i] = (LumReg & m[i]) ? 0 : 8;
|
||||
|
||||
vpar = lvd = 0;
|
||||
for (y=0; y<25; y++) {
|
||||
|
||||
vpar = (lvd==0) ? 0 : 1-vpar;
|
||||
|
||||
l = (y==0) ? 31 : (y-1+vpp_y0)%24;
|
||||
c0 = ul = conc = box = 0;
|
||||
|
||||
hpar = lhd = 0;
|
||||
for (x=0; x<40; x++) {
|
||||
hpar = (lhd==0) ? 0 : 1-hpar;
|
||||
|
||||
chr = vpp_mem[x][l][0];
|
||||
attr = vpp_mem[x][l][1];
|
||||
c1 = attr & 0x7;
|
||||
c1 = ((c1&2) | ((c1&1)<<2) | ((c1&4)>>2));
|
||||
ext = (attr & 0x80) ? 1 : 0;
|
||||
|
||||
ser_chr = vpp_mem[x][l][2];
|
||||
ser_atr = vpp_mem[x][l][3];
|
||||
if (ser_chr) {
|
||||
c0 = (ser_atr>>4) & 0x7;
|
||||
c0 = ((c0&2) | ((c0&1)<<2) | ((c0&4)>>2));
|
||||
ul = ser_chr & 4;
|
||||
conc = ser_chr & 1;
|
||||
box = ser_chr & 2;
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
c0 = (attr>>4) & 0x7;
|
||||
c0 = ((c0&2) | ((c0&1)<<2) | ((c0&4)>>2));
|
||||
dw = dh = 0;
|
||||
} else {
|
||||
dw = (attr & 0x20) ? (hpar ? 2 : 1) : 0;
|
||||
dh = (attr & 0x10) ? (vpar ? 2 : 1) : 0;
|
||||
if (dw) lhd=1;
|
||||
if (dh) lvd=1;
|
||||
}
|
||||
|
||||
if ((vpp_r & 0x80) && (!(attr & 8)) && (!blink_st)) c1=c0;
|
||||
|
||||
if (((y == 0) && (vpp_r & 8)) || ((y != 0) && (vpp_r & 1))) {
|
||||
if ((!conc) || (!(vpp_r & 4))) {
|
||||
if (box || (!(vpp_r & 2))) {
|
||||
if ((!ext) && (attr & 0x40))
|
||||
vpp_draw_char(x, y, chr, c1|tlum[c1], c0|tlum[c0], ext, dw, dh, ul);
|
||||
else
|
||||
vpp_draw_char(x, y, chr, c0|tlum[c0], c1|tlum[c1], ext, dw, dh, ul);
|
||||
} else {
|
||||
vpp_draw_char(x, y, 255, (app_data.openb) ? 16 : 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (vpp_r & 0x20) {
|
||||
for (y = vppbmp->h-1; y >= 10; y--)
|
||||
// for (x = 0; x < vppbmp->w; x++) vppbmp->line[y][x] = vppbmp->line[(y-10)/2+10][x];
|
||||
for (x = 0; x < vppbmp->w; x++) vppbmp->line[y*320+x] = vppbmp->line[((y-10)/2+10)*320 + x];
|
||||
}
|
||||
|
||||
need_update=0;
|
||||
}
|
||||
|
||||
|
||||
void load_colplus(Byte *col){
|
||||
if (vppon) {
|
||||
//memcpy(col,colplus,BMPW*BMPH);
|
||||
}
|
||||
else
|
||||
memset(col,0,BMPW*BMPH);
|
||||
}
|
||||
|
||||
void init_vpp(void){
|
||||
int i,j,k;
|
||||
|
||||
vppbmp->w = 320;
|
||||
vppbmp->h = 250;
|
||||
|
||||
// if ((!vppbmp) || (!colplus)) {
|
||||
// fprintf(stderr,"Could not allocate memory for Videopac+ screen buffer.\n");
|
||||
// exit(EXIT_FAILURE);
|
||||
// }
|
||||
|
||||
clear(vppbmp);
|
||||
//memset(colplus,0,BMPW*BMPH);
|
||||
|
||||
LumReg = TraReg = 0xff;
|
||||
vpp_cx = 0;
|
||||
vpp_cy = 0;
|
||||
vpp_y0 = 0;
|
||||
vpp_r = 0;
|
||||
inc_curs = 1;
|
||||
vpp_data = 0;
|
||||
frame_cnt=0;
|
||||
blink_st=0;
|
||||
slice = 0;
|
||||
slicemode=0;
|
||||
need_update = 1;
|
||||
vppon = 1;
|
||||
|
||||
for (i=0; i<2; i++)
|
||||
for (j=0; j<960; j++) dchars[i][j] = 0;
|
||||
|
||||
for (i=0; i<40; i++)
|
||||
for (j=0; j<32; j++)
|
||||
for (k=0; k<4; k++) vpp_mem[i][j][k] = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef __VPP_H
|
||||
#define __VPP_H
|
||||
|
||||
Byte read_PB(Byte p);
|
||||
void write_PB(Byte p, Byte val);
|
||||
Byte vpp_read(ADDRESS adr);
|
||||
void vpp_write(Byte dat, ADDRESS adr);
|
||||
void vpp_finish_bmp(Byte *vmem, int offx, int offy, int w, int h, int totw, int toth);
|
||||
void init_vpp(void);
|
||||
void load_colplus(Byte *col);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,284 @@
|
|||
|
||||
/*
|
||||
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
||||
*
|
||||
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||
*
|
||||
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||
*
|
||||
* http://o2em.sourceforge.net
|
||||
*
|
||||
*
|
||||
*
|
||||
* Videopac+ character table
|
||||
*/
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "vpp_cset.h"
|
||||
|
||||
|
||||
const Byte vpp_cset[2][1280] = {
|
||||
{
|
||||
/* Alphanumeric */
|
||||
0x00,0x38,0x44,0x40,0x20,0x10,0x00,0x10,0x00,0x00,
|
||||
0x00,0x10,0x28,0x00,0x38,0x44,0x7c,0x44,0x00,0x00,
|
||||
0x00,0x08,0x10,0x3c,0x20,0x30,0x20,0x3c,0x00,0x00,
|
||||
0x00,0x08,0x14,0x10,0x38,0x10,0x24,0x3c,0x00,0x00,
|
||||
0x00,0x10,0x38,0x50,0x38,0x14,0x54,0x38,0x10,0x00,
|
||||
0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x10,0x20,
|
||||
0x00,0x28,0x28,0x7c,0x28,0x7c,0x28,0x28,0x00,0x00,
|
||||
0x00,0x20,0x18,0x00,0x38,0x44,0x7c,0x44,0x00,0x00,
|
||||
0x00,0x20,0x18,0x00,0x44,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x10,0x08,0x3c,0x20,0x30,0x20,0x3c,0x00,0x00,
|
||||
0x00,0x3c,0x50,0x50,0x58,0x50,0x50,0x3c,0x00,0x00,
|
||||
0x00,0x08,0x14,0x3c,0x20,0x30,0x20,0x3c,0x00,0x00,
|
||||
0x00,0x00,0x10,0x20,0x7f,0x20,0x10,0x00,0x00,0x00,
|
||||
0x00,0x10,0x38,0x54,0x10,0x10,0x10,0x10,0x10,0x10,
|
||||
0x00,0x00,0x08,0x04,0xfe,0x04,0x08,0x00,0x00,0x00,
|
||||
0x10,0x10,0x10,0x10,0x10,0x10,0x54,0x38,0x10,0x00,
|
||||
0x00,0x18,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x7c,0x00,0x00,
|
||||
0x00,0x08,0x10,0x38,0x44,0x7c,0x40,0x38,0x00,0x00,
|
||||
0x00,0x28,0x00,0x38,0x44,0x7c,0x40,0x38,0x00,0x00,
|
||||
0x00,0x28,0x00,0x30,0x10,0x10,0x10,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x40,0x40,0x40,0x38,0x10,0x20,
|
||||
0x00,0x10,0x28,0x00,0x44,0x44,0x4c,0x34,0x00,0x00,
|
||||
0x00,0x20,0x10,0x34,0x4c,0x44,0x4c,0x34,0x00,0x00,
|
||||
0x00,0x00,0x10,0x00,0x7c,0x00,0x10,0x00,0x00,0x00,
|
||||
0x00,0x20,0x10,0x38,0x44,0x7c,0x40,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x3c,0x52,0x5e,0x50,0x3e,0x00,0x00,
|
||||
0x00,0x10,0x28,0x38,0x44,0x7c,0x40,0x38,0x00,0x00,
|
||||
0x00,0x40,0xc0,0x40,0x44,0x4c,0x14,0x3e,0x04,0x00,
|
||||
0x00,0x40,0xc0,0x40,0x4c,0x52,0x04,0x08,0x1e,0x00,
|
||||
0x00,0xe0,0x20,0x40,0x24,0xcc,0x14,0x3e,0x04,0x00,
|
||||
0x00,0x10,0x28,0x00,0x38,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00,
|
||||
0x00,0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x28,0x00,0x3c,0x20,0x30,0x20,0x3c,0x00,0x00,
|
||||
0x00,0x10,0x28,0x34,0x4c,0x44,0x4c,0x34,0x00,0x00,
|
||||
0x00,0x60,0x64,0x08,0x10,0x20,0x4c,0x0c,0x00,0x00,
|
||||
0x00,0x20,0x50,0x50,0x20,0x54,0x48,0x34,0x00,0x00,
|
||||
0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x08,0x10,0x20,0x20,0x20,0x10,0x08,0x00,0x00,
|
||||
0x00,0x20,0x10,0x08,0x08,0x08,0x10,0x20,0x00,0x00,
|
||||
0x00,0x10,0x54,0x38,0x10,0x38,0x54,0x10,0x00,0x00,
|
||||
0x00,0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
|
||||
0x01,0x02,0x02,0x04,0x08,0x10,0x20,0x20,0x40,0x80,
|
||||
0x00,0x10,0x28,0x44,0x44,0x44,0x28,0x10,0x00,0x00,
|
||||
0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
|
||||
0x00,0x38,0x44,0x04,0x18,0x20,0x40,0x7c,0x00,0x00,
|
||||
0x00,0x7c,0x04,0x08,0x18,0x04,0x44,0x38,0x00,0x00,
|
||||
0x00,0x08,0x18,0x28,0x48,0x7c,0x08,0x08,0x00,0x00,
|
||||
0x00,0x7c,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00,
|
||||
0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x7c,0x04,0x08,0x10,0x20,0x20,0x20,0x00,0x00,
|
||||
0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x38,0x44,0x44,0x3c,0x04,0x04,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,
|
||||
0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40,0x00,
|
||||
0x00,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00,0x00,
|
||||
0x00,0x00,0x00,0x7c,0x00,0x7c,0x00,0x00,0x00,0x00,
|
||||
0x00,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x00,
|
||||
0x00,0x38,0x44,0x04,0x08,0x10,0x00,0x10,0x00,0x00,
|
||||
0x00,0x38,0x44,0x5c,0x54,0x5c,0x40,0x38,0x00,0x00,
|
||||
0x00,0x38,0x44,0x44,0x44,0x7c,0x44,0x44,0x00,0x00,
|
||||
0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x78,0x00,0x00,
|
||||
0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00,
|
||||
0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,
|
||||
0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x7c,0x00,0x00,
|
||||
0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x00,0x00,
|
||||
0x00,0x38,0x44,0x40,0x40,0x4c,0x44,0x3c,0x00,0x00,
|
||||
0x00,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x00,0x00,
|
||||
0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,
|
||||
0x00,0x1c,0x08,0x08,0x08,0x08,0x48,0x30,0x00,0x00,
|
||||
0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,
|
||||
0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,
|
||||
0x00,0x44,0x6c,0x54,0x44,0x44,0x44,0x44,0x00,0x00,
|
||||
0x00,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x00,0x00,
|
||||
0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x78,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,
|
||||
0x00,0x38,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,
|
||||
0x00,0x78,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00,
|
||||
0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00,
|
||||
0x00,0x7c,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
|
||||
0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,
|
||||
0x00,0x44,0x44,0x44,0x54,0x54,0x54,0x28,0x00,0x00,
|
||||
0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,
|
||||
0x00,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,
|
||||
0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x7c,0x00,0x00,
|
||||
0x00,0x1c,0x10,0x10,0x10,0x10,0x10,0x1c,0x00,0x00,
|
||||
0x80,0x40,0x40,0x20,0x10,0x08,0x04,0x04,0x02,0x01,
|
||||
0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00,
|
||||
0x00,0x10,0x28,0x00,0x30,0x10,0x10,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
|
||||
0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x34,0x4c,0x44,0x4c,0x34,0x00,0x00,
|
||||
0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x78,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x40,0x40,0x40,0x38,0x00,0x00,
|
||||
0x00,0x04,0x04,0x3c,0x44,0x44,0x44,0x3c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x44,0x7c,0x40,0x38,0x00,0x00,
|
||||
0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x00,0x00,
|
||||
0x00,0x00,0x00,0x3c,0x44,0x44,0x3c,0x04,0x24,0x18,
|
||||
0x00,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x00,0x00,
|
||||
0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x38,0x00,0x00,
|
||||
0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30,
|
||||
0x00,0x20,0x20,0x24,0x28,0x30,0x28,0x24,0x00,0x00,
|
||||
0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x68,0x54,0x54,0x54,0x54,0x00,0x00,
|
||||
0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00,
|
||||
0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,
|
||||
0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x3c,0x04,0x04,
|
||||
0x00,0x00,0x00,0x58,0x64,0x40,0x40,0x40,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x40,0x38,0x04,0x78,0x00,0x00,
|
||||
0x00,0x20,0x20,0x38,0x20,0x20,0x20,0x18,0x00,0x00,
|
||||
0x00,0x00,0x00,0x44,0x44,0x44,0x4c,0x34,0x00,0x00,
|
||||
0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x00,0x00,
|
||||
0x00,0x00,0x00,0x44,0x44,0x54,0x54,0x28,0x00,0x00,
|
||||
0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00,
|
||||
0x00,0x00,0x00,0x44,0x44,0x4c,0x34,0x04,0x44,0x38,
|
||||
0x00,0x00,0x00,0x7c,0x08,0x10,0x20,0x7c,0x00,0x00,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
|
||||
{
|
||||
/* Separated semi-graphic */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x77,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,
|
||||
0x70,0x70,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,
|
||||
0x07,0x07,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,
|
||||
0x77,0x77,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x70,0x70,0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x77,0x77,0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x77,0x77,0x77,0x00,0x00,0x00,0x00,
|
||||
0x70,0x70,0x00,0x77,0x77,0x77,0x00,0x00,0x00,0x00,
|
||||
0x07,0x07,0x00,0x77,0x77,0x77,0x00,0x00,0x00,0x00,
|
||||
0x77,0x77,0x00,0x77,0x77,0x77,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x00,
|
||||
0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x00,
|
||||
0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x00,
|
||||
0x77,0x77,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x00,
|
||||
0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x70,0x70,0x00,
|
||||
0x70,0x70,0x00,0x70,0x70,0x70,0x00,0x70,0x70,0x00,
|
||||
0x07,0x07,0x00,0x70,0x70,0x70,0x00,0x70,0x70,0x00,
|
||||
0x77,0x77,0x00,0x70,0x70,0x70,0x00,0x70,0x70,0x00,
|
||||
0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x70,0x70,0x00,
|
||||
0x70,0x70,0x00,0x07,0x07,0x07,0x00,0x70,0x70,0x00,
|
||||
0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x70,0x70,0x00,
|
||||
0x77,0x77,0x00,0x07,0x07,0x07,0x00,0x70,0x70,0x00,
|
||||
0x00,0x00,0x00,0x77,0x77,0x77,0x00,0x70,0x70,0x00,
|
||||
0x70,0x70,0x00,0x77,0x77,0x77,0x00,0x70,0x70,0x00,
|
||||
0x07,0x07,0x00,0x77,0x77,0x77,0x00,0x70,0x70,0x00,
|
||||
0x77,0x77,0x00,0x77,0x77,0x77,0x00,0x70,0x70,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
|
||||
0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
|
||||
0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
|
||||
0x77,0x77,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
|
||||
0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x07,0x07,0x00,
|
||||
0x70,0x70,0x00,0x70,0x70,0x70,0x00,0x07,0x07,0x00,
|
||||
0x07,0x07,0x00,0x70,0x70,0x70,0x00,0x07,0x07,0x00,
|
||||
0x77,0x77,0x00,0x70,0x70,0x70,0x00,0x07,0x07,0x00,
|
||||
0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
|
||||
0x70,0x70,0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
|
||||
0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
|
||||
0x77,0x77,0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
|
||||
0x00,0x00,0x00,0x77,0x77,0x77,0x00,0x07,0x07,0x00,
|
||||
0x70,0x70,0x00,0x77,0x77,0x77,0x00,0x07,0x07,0x00,
|
||||
0x07,0x07,0x00,0x77,0x77,0x77,0x00,0x07,0x07,0x00,
|
||||
0x77,0x77,0x00,0x77,0x77,0x77,0x00,0x07,0x07,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x77,0x00,
|
||||
0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x77,0x77,0x00,
|
||||
0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x77,0x77,0x00,
|
||||
0x77,0x77,0x00,0x00,0x00,0x00,0x00,0x77,0x77,0x00,
|
||||
0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x77,0x77,0x00,
|
||||
0x70,0x70,0x00,0x70,0x70,0x70,0x00,0x77,0x77,0x00,
|
||||
0x07,0x07,0x00,0x70,0x70,0x70,0x00,0x77,0x77,0x00,
|
||||
0x77,0x77,0x00,0x70,0x70,0x70,0x00,0x77,0x77,0x00,
|
||||
0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x77,0x77,0x00,
|
||||
0x70,0x70,0x00,0x07,0x07,0x07,0x00,0x77,0x77,0x00,
|
||||
0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x77,0x77,0x00,
|
||||
0x77,0x77,0x00,0x07,0x07,0x07,0x00,0x77,0x77,0x00,
|
||||
0x00,0x00,0x00,0x77,0x77,0x77,0x00,0x77,0x77,0x00,
|
||||
0x70,0x70,0x00,0x77,0x77,0x77,0x00,0x77,0x77,0x00,
|
||||
0x07,0x07,0x00,0x77,0x77,0x77,0x00,0x77,0x77,0x00,
|
||||
0x77,0x77,0x00,0x77,0x77,0x77,0x00,0x77,0x77,0x00,
|
||||
/* Mosaic semi-graphic */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,
|
||||
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,
|
||||
0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,
|
||||
0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,
|
||||
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
|
||||
0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
|
||||
0x0f,0x0f,0x0f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,
|
||||
0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,
|
||||
0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,
|
||||
0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,
|
||||
0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
|
||||
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
|
||||
0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
|
||||
0xff,0xff,0xff,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
|
||||
0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,
|
||||
0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,
|
||||
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,
|
||||
0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,
|
||||
0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xf0,0xf0,0xf0,
|
||||
0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0xf0,0xf0,0xf0,
|
||||
0x0f,0x0f,0x0f,0xff,0xff,0xff,0xff,0xf0,0xf0,0xf0,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xf0,0xf0,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,
|
||||
0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,
|
||||
0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,
|
||||
0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,
|
||||
0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,
|
||||
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,
|
||||
0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,
|
||||
0xff,0xff,0xff,0xf0,0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,
|
||||
0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
|
||||
0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
|
||||
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
|
||||
0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
|
||||
0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,
|
||||
0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,
|
||||
0x0f,0x0f,0x0f,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
|
||||
0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
|
||||
0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
|
||||
0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,
|
||||
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,
|
||||
0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,
|
||||
0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f,0xff,0xff,0xff,
|
||||
0xf0,0xf0,0xf0,0x0f,0x0f,0x0f,0x0f,0xff,0xff,0xff,
|
||||
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0xff,0xff,0xff,
|
||||
0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x0f,0x0f,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __VPP_CSET_H
|
||||
#define __VPP_CSET_H
|
||||
|
||||
extern const Byte vpp_cset[2][1280];
|
||||
|
||||
#endif
|
|
@ -5,7 +5,6 @@ extern "C" {
|
|||
|
||||
#include "emu.h"
|
||||
|
||||
#include "emu.h"
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
TFT_T_DMA tft;
|
||||
|
|
Ładowanie…
Reference in New Issue