kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
add PCE emu to T-COMPUTER
rodzic
0a299294cc
commit
d35010f31d
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -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,27 @@
|
|||
|
||||
#ifndef _BITFLIP_H_
|
||||
#define _BITFLIP_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
PROGMEM const uint8 bitflip[0x100] =
|
||||
{
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
||||
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
||||
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
||||
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
||||
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
||||
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
||||
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
||||
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
||||
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
||||
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF,
|
||||
};
|
||||
|
||||
#endif /* _BITFLIP_H_ */
|
||||
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef CPUINTRF_H
|
||||
#define CPUINTRF_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
#define CLEAR_LINE 0
|
||||
#define ASSERT_LINE 1
|
||||
#define REG_PREVIOUSPC -1
|
||||
#define REG_SP_CONTENTS -2
|
||||
|
||||
#endif /* CPUINTRF_H */
|
|
@ -0,0 +1,119 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "emuapi.h"
|
||||
#include "tft_t_dma.h"
|
||||
#include "iopins.h"
|
||||
|
||||
extern "C" {
|
||||
#include "shared.h"
|
||||
#include "system.h"
|
||||
}
|
||||
|
||||
|
||||
EXTMEM static unsigned char MemPool[8*1024*1024];
|
||||
|
||||
extern "C" uint8 read_rom(int address) {
|
||||
return (MemPool[address]);
|
||||
}
|
||||
|
||||
extern "C" void write_rom(int address, uint8 val) {
|
||||
MemPool[address]=val;
|
||||
}
|
||||
|
||||
|
||||
void pce_Init(void)
|
||||
{
|
||||
emu_printf("Allocating MEM");
|
||||
mem_init();
|
||||
emu_printf("Allocating MEM done");
|
||||
}
|
||||
|
||||
|
||||
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 pce_Input(int click) {
|
||||
ik = emu_GetPad();
|
||||
ihk = emu_ReadI2CKeyboard();
|
||||
}
|
||||
|
||||
|
||||
void pce_Start(char * filename)
|
||||
{
|
||||
emu_printf("init started");
|
||||
load_rom(filename, 0,0);
|
||||
|
||||
#ifdef SOUND_PRESENT
|
||||
system_init(22050);
|
||||
#ifdef HAS_SND
|
||||
emu_sndInit();
|
||||
#endif
|
||||
#else
|
||||
system_init(0);
|
||||
#endif
|
||||
system_reset();
|
||||
|
||||
emu_printf("init done");
|
||||
}
|
||||
|
||||
void pce_Step(void) {
|
||||
|
||||
input.pad[0] = 0;
|
||||
|
||||
int k = ik;
|
||||
int hk = ihk;
|
||||
if (iusbhk) hk = iusbhk;
|
||||
|
||||
if (( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT)) {
|
||||
input.pad[0] |= INPUT_RIGHT;
|
||||
}
|
||||
if (( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT)) {
|
||||
input.pad[0] |= INPUT_LEFT;
|
||||
}
|
||||
if (( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP)) {
|
||||
input.pad[0] |= INPUT_UP;
|
||||
}
|
||||
if (( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN)) {
|
||||
input.pad[0] |= INPUT_DOWN;
|
||||
}
|
||||
if ( k & MASK_JOY2_BTN) {
|
||||
input.pad[0] |= INPUT_B2;
|
||||
}
|
||||
|
||||
if (k & MASK_KEY_USER1) input.pad[0] |= INPUT_B1;
|
||||
if ( (k & MASK_KEY_USER2) || (hk == 'q') ) input.pad[0] |= INPUT_RUN;
|
||||
//if (k & MASK_KEY_USER3) input.pad[0] |= INPUT_SELECT;
|
||||
|
||||
prevhk = hk;
|
||||
|
||||
//emu_printi(emu_FrameSkip());
|
||||
|
||||
system_frame((emu_FrameSkip()==0)?0:1);
|
||||
emu_DrawVsync();
|
||||
}
|
||||
|
||||
void SND_Process(void *stream, int len) {
|
||||
psg_update(stream, 0, len);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
extern void pce_Init(void);
|
||||
extern void pce_Step(void);
|
||||
extern void pce_Start(char * filename);
|
||||
extern void pce_Input(int click);
|
||||
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,216 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
#define CUSTOM_SND 1
|
||||
//#define TIMER_REND 1
|
||||
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
#define TITLE " PC Engine Emulator"
|
||||
#define ROMSDIR "/pce"
|
||||
|
||||
#define emu_Init(ROM) {pce_Init(); pce_Start(ROM);}
|
||||
#define emu_Step(x) {pce_Step();}
|
||||
#define emu_Input(x) {pce_Input(x);}
|
||||
|
||||
#define MAX_FILENAME_PATH 64
|
||||
#define NB_FILE_HANDLER 4
|
||||
#define PALETTE_SIZE 1
|
||||
#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,356 @@
|
|||
/*****************************************************************************
|
||||
|
||||
h6280.c - Portable HuC6280 emulator
|
||||
|
||||
Copyright (c) 1999, 2000 Bryan McPhail, mish@tendril.co.uk
|
||||
|
||||
This source code is based (with permission!) on the 6502 emulator by
|
||||
Juergen Buchmueller. It is released as part of the Mame emulator project.
|
||||
Let me know if you intend to use this code in any other project.
|
||||
|
||||
|
||||
NOTICE:
|
||||
|
||||
This code is around 99% complete! Several things are unimplemented,
|
||||
some due to lack of time, some due to lack of documentation, mainly
|
||||
due to lack of programs using these features.
|
||||
|
||||
csh, csl opcodes are not supported.
|
||||
set opcode and T flag behaviour are not supported.
|
||||
|
||||
I am unsure if instructions like SBC take an extra cycle when used in
|
||||
decimal mode. I am unsure if flag B is set upon execution of rti.
|
||||
|
||||
Cycle counts should be quite accurate, illegal instructions are assumed
|
||||
to take two cycles.
|
||||
|
||||
|
||||
Changelog, version 1.02:
|
||||
JMP + indirect X (0x7c) opcode fixed.
|
||||
SMB + RMB opcodes fixed in disassembler.
|
||||
change_pc function calls removed.
|
||||
TSB & TRB now set flags properly.
|
||||
BIT opcode altered.
|
||||
|
||||
Changelog, version 1.03:
|
||||
Swapped IRQ mask for IRQ1 & IRQ2 (thanks Yasuhiro)
|
||||
|
||||
Changelog, version 1.04, 28/9/99-22/10/99:
|
||||
Adjusted RTI (thanks Karl)
|
||||
TST opcodes fixed in disassembler (missing break statements in a case!).
|
||||
TST behaviour fixed.
|
||||
SMB/RMB/BBS/BBR fixed in disassembler.
|
||||
|
||||
Changelog, version 1.05, 8/12/99-16/12/99:
|
||||
Added CAB's timer implementation (note: irq ack & timer reload are changed).
|
||||
Fixed STA IDX.
|
||||
Fixed B flag setting on BRK.
|
||||
Assumed CSH & CSL to take 2 cycles each.
|
||||
|
||||
Todo: Performance could be improved by precalculating timer fire position.
|
||||
|
||||
Changelog, version 1.06, 4/5/00 - last opcode bug found?
|
||||
JMP indirect was doing a EAL++; instead of EAD++; - Obviously causing
|
||||
a corrupt read when L = 0xff! This fixes Bloody Wolf and Trio The Punch!
|
||||
|
||||
Changelog, version 1.07, 3/9/00:
|
||||
Changed timer to be single shot - fixes Crude Buster music in level 1.
|
||||
|
||||
Changelog, version 1.08, 1/18/01: (Charles MacDonald)
|
||||
Added h6280_speed to reflect current CPU speed set by CSL/CSH.
|
||||
Added implementation of SET opcode.
|
||||
Changed INLINE in tblh6280.h to 'static __inline__' (Allegro conflict)
|
||||
Added FAST_MEM routines for quicker ROM/RAM access.
|
||||
|
||||
******************************************************************************/
|
||||
#include "shared.h"
|
||||
|
||||
#include "cpuintrf.h"
|
||||
#include "h6280.h"
|
||||
|
||||
/* Default state of HuC6280 clock (1=7.16MHz, 0=3.58MHz) */
|
||||
int h6280_speed = 1;
|
||||
int h6280_ICount = 0;
|
||||
static h6280_Regs h6280;
|
||||
|
||||
#include "h6280ops.h"
|
||||
#include "tblh6280.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void h6280_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* wipe out the h6280 structure */
|
||||
memset(&h6280, 0, sizeof(h6280_Regs));
|
||||
|
||||
/* set I and Z flags */
|
||||
P = _fI | _fZ;
|
||||
|
||||
/* stack starts at 0x01ff */
|
||||
h6280.sp.d = 0x1ff;
|
||||
|
||||
/* read the reset vector into PC */
|
||||
PCL = RDMEM(H6280_RESET_VEC);
|
||||
PCH = RDMEM((H6280_RESET_VEC+1));
|
||||
|
||||
/* timer off by default */
|
||||
h6280.timer_status=0;
|
||||
h6280.timer_ack=1;
|
||||
|
||||
/* clear pending interrupts */
|
||||
for (i = 0; i < 3; i++)
|
||||
h6280.irq_state[i] = CLEAR_LINE;
|
||||
|
||||
h6280_speed = 1; /* default = 7.16MHz (?) */
|
||||
}
|
||||
|
||||
void h6280_exit(void)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
int h6280_execute(int cycles)
|
||||
{
|
||||
int in,lastcycle,deltacycle;
|
||||
h6280_ICount = cycles;
|
||||
|
||||
/* Subtract cycles used for taking an interrupt */
|
||||
h6280_ICount -= h6280.extra_cycles;
|
||||
h6280.extra_cycles = 0;
|
||||
lastcycle = h6280_ICount;
|
||||
|
||||
// DEBUGLOG("h6280_execute 1\n");
|
||||
|
||||
/* Execute instructions */
|
||||
do
|
||||
{
|
||||
h6280.ppc = h6280.pc;
|
||||
// DEBUGLOG("h6280_execute 2 PC[%08X]\n",PCW );
|
||||
|
||||
/* Execute 1 instruction */
|
||||
in=RDOP();
|
||||
PCW++;
|
||||
// DEBUGLOG("h6280_execute 2.5 in=[%d]\n",in);
|
||||
insnh6280[in]();
|
||||
|
||||
// DEBUGLOG("h6280_execute 3\n");
|
||||
|
||||
/* Check internal timer */
|
||||
if(h6280.timer_status)
|
||||
{
|
||||
deltacycle = lastcycle - h6280_ICount;
|
||||
h6280.timer_value -= deltacycle;
|
||||
if(h6280.timer_value<=0 && h6280.timer_ack==1)
|
||||
{
|
||||
h6280.timer_ack=h6280.timer_status=0;
|
||||
h6280_set_irq_line(2,ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
lastcycle = h6280_ICount;
|
||||
// DEBUGLOG("h6280_execute 4\n");
|
||||
|
||||
/* If PC has not changed we are stuck in a tight loop, may as well finish */
|
||||
if( h6280.pc.d == h6280.ppc.d )
|
||||
{
|
||||
if (h6280_ICount > 0) h6280_ICount=0;
|
||||
h6280.extra_cycles = 0;
|
||||
return cycles;
|
||||
}
|
||||
// DEBUGLOG("h6280_execute 5\n");
|
||||
|
||||
} while (h6280_ICount > 0);
|
||||
|
||||
/* Subtract cycles used for taking an interrupt */
|
||||
h6280_ICount -= h6280.extra_cycles;
|
||||
h6280.extra_cycles = 0;
|
||||
|
||||
return cycles - h6280_ICount;
|
||||
}
|
||||
|
||||
unsigned h6280_get_context (void *dst)
|
||||
{
|
||||
if( dst )
|
||||
*(h6280_Regs*)dst = h6280;
|
||||
return sizeof(h6280_Regs);
|
||||
}
|
||||
|
||||
void h6280_set_context (void *src)
|
||||
{
|
||||
if( src )
|
||||
h6280 = *(h6280_Regs*)src;
|
||||
}
|
||||
|
||||
unsigned h6280_get_pc (void)
|
||||
{
|
||||
return PCD;
|
||||
}
|
||||
|
||||
void h6280_set_pc (unsigned val)
|
||||
{
|
||||
PCW = val;
|
||||
}
|
||||
|
||||
unsigned h6280_get_sp (void)
|
||||
{
|
||||
return S;
|
||||
}
|
||||
|
||||
void h6280_set_sp (unsigned val)
|
||||
{
|
||||
S = val;
|
||||
}
|
||||
|
||||
unsigned h6280_get_reg (int regnum)
|
||||
{
|
||||
switch( regnum )
|
||||
{
|
||||
case H6280_PC: return PCD;
|
||||
case H6280_S: return S;
|
||||
case H6280_P: return P;
|
||||
case H6280_A: return A;
|
||||
case H6280_X: return X;
|
||||
case H6280_Y: return Y;
|
||||
case H6280_IRQ_MASK: return h6280.irq_mask;
|
||||
case H6280_TIMER_STATE: return h6280.timer_status;
|
||||
case H6280_NMI_STATE: return h6280.nmi_state;
|
||||
case H6280_IRQ1_STATE: return h6280.irq_state[0];
|
||||
case H6280_IRQ2_STATE: return h6280.irq_state[1];
|
||||
case H6280_IRQT_STATE: return h6280.irq_state[2];
|
||||
case REG_PREVIOUSPC: return h6280.ppc.d;
|
||||
default:
|
||||
if( regnum <= REG_SP_CONTENTS )
|
||||
{
|
||||
unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
|
||||
if( offset < 0x1ff )
|
||||
return RDMEM( offset ) | ( RDMEM( offset+1 ) << 8 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h6280_set_reg (int regnum, unsigned val)
|
||||
{
|
||||
switch( regnum )
|
||||
{
|
||||
case H6280_PC: PCW = val; break;
|
||||
case H6280_S: S = val; break;
|
||||
case H6280_P: P = val; break;
|
||||
case H6280_A: A = val; break;
|
||||
case H6280_X: X = val; break;
|
||||
case H6280_Y: Y = val; break;
|
||||
case H6280_IRQ_MASK: h6280.irq_mask = val; CHECK_IRQ_LINES; break;
|
||||
case H6280_TIMER_STATE: h6280.timer_status = val; break;
|
||||
case H6280_NMI_STATE: h6280_set_nmi_line( val ); break;
|
||||
case H6280_IRQ1_STATE: h6280_set_irq_line( 0, val ); break;
|
||||
case H6280_IRQ2_STATE: h6280_set_irq_line( 1, val ); break;
|
||||
case H6280_IRQT_STATE: h6280_set_irq_line( 2, val ); break;
|
||||
default:
|
||||
if( regnum <= REG_SP_CONTENTS )
|
||||
{
|
||||
unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
|
||||
if( offset < 0x1ff )
|
||||
{
|
||||
WRMEM( offset, val & 0xff );
|
||||
WRMEM( offset+1, (val >> 8) & 0xff );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void h6280_set_nmi_line(int state)
|
||||
{
|
||||
if (h6280.nmi_state == state) return;
|
||||
h6280.nmi_state = state;
|
||||
if (state != CLEAR_LINE)
|
||||
{
|
||||
DO_INTERRUPT(H6280_NMI_VEC);
|
||||
}
|
||||
}
|
||||
|
||||
void h6280_set_irq_line(int irqline, int state)
|
||||
{
|
||||
h6280.irq_state[irqline] = state;
|
||||
|
||||
/* If line is cleared, just exit */
|
||||
if (state == CLEAR_LINE) return;
|
||||
|
||||
/* Check if interrupts are enabled and the IRQ mask is clear */
|
||||
CHECK_IRQ_LINES;
|
||||
}
|
||||
|
||||
void h6280_set_irq_callback(int (*callback)(int irqline))
|
||||
{
|
||||
h6280.irq_callback = callback;
|
||||
}
|
||||
|
||||
int H6280_irq_status_r (int offset)
|
||||
{
|
||||
int status;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0: /* Read irq mask */
|
||||
return h6280.irq_mask;
|
||||
|
||||
case 1: /* Read irq status */
|
||||
status=0;
|
||||
if(h6280.irq_state[1]!=CLEAR_LINE) status|=1; /* IRQ 2 */
|
||||
if(h6280.irq_state[0]!=CLEAR_LINE) status|=2; /* IRQ 1 */
|
||||
if(h6280.irq_state[2]!=CLEAR_LINE) status|=4; /* TIMER */
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void H6280_irq_status_w (int offset, int data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0: /* Write irq mask */
|
||||
h6280.irq_mask=data&0x7;
|
||||
CHECK_IRQ_LINES;
|
||||
break;
|
||||
|
||||
case 1: /* Timer irq ack - timer is reloaded here */
|
||||
h6280.timer_value = h6280.timer_load;
|
||||
h6280.timer_ack=1; /* Timer can't refire until ack'd */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int H6280_timer_r (int offset)
|
||||
{
|
||||
switch (offset) {
|
||||
case 0: /* Counter value */
|
||||
return (h6280.timer_value/1024)&127;
|
||||
|
||||
case 1: /* Read counter status */
|
||||
return h6280.timer_status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void H6280_timer_w (int offset, int data)
|
||||
{
|
||||
switch (offset) {
|
||||
case 0: /* Counter preload */
|
||||
h6280.timer_load=h6280.timer_value=((data&127)+1)*1024;
|
||||
return;
|
||||
|
||||
case 1: /* Counter enable */
|
||||
if(data&1)
|
||||
{ /* stop -> start causes reload */
|
||||
if(h6280.timer_status==0) h6280.timer_value=h6280.timer_load;
|
||||
}
|
||||
h6280.timer_status=data&1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
|
@ -0,0 +1,98 @@
|
|||
/*****************************************************************************
|
||||
|
||||
h6280.h Portable Hu6280 emulator interface
|
||||
|
||||
Copyright (c) 1999 Bryan McPhail, mish@tendril.co.uk
|
||||
|
||||
This source code is based (with permission!) on the 6502 emulator by
|
||||
Juergen Buchmueller. It is released as part of the Mame emulator project.
|
||||
Let me know if you intend to use this code in any other project.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _H6280_H
|
||||
#define _H6280_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
enum {
|
||||
H6280_PC=1, H6280_S, H6280_P, H6280_A, H6280_X, H6280_Y,
|
||||
H6280_IRQ_MASK, H6280_TIMER_STATE,
|
||||
H6280_NMI_STATE, H6280_IRQ1_STATE, H6280_IRQ2_STATE, H6280_IRQT_STATE
|
||||
};
|
||||
|
||||
extern int h6280_speed;
|
||||
|
||||
//#define LAZY_FLAGS 1
|
||||
|
||||
#define H6280_INT_NONE 0
|
||||
#define H6280_INT_NMI 1
|
||||
#define H6280_INT_TIMER 2
|
||||
#define H6280_INT_IRQ1 3
|
||||
#define H6280_INT_IRQ2 4
|
||||
|
||||
#define H6280_RESET_VEC 0xfffe
|
||||
#define H6280_NMI_VEC 0xfffc
|
||||
#define H6280_TIMER_VEC 0xfffa
|
||||
#define H6280_IRQ1_VEC 0xfff8
|
||||
#define H6280_IRQ2_VEC 0xfff6 /* Aka BRK vector */
|
||||
|
||||
extern int h6280_ICount; /* cycle count */
|
||||
|
||||
extern void h6280_reset(void); /* Reset registers to the initial values */
|
||||
extern void h6280_exit(void); /* Shut down CPU */
|
||||
extern int h6280_execute(int cycles); /* Execute cycles - returns number of cycles actually run */
|
||||
extern unsigned h6280_get_context(void *dst); /* Get registers, return context size */
|
||||
extern void h6280_set_context(void *src); /* Set registers */
|
||||
extern unsigned h6280_get_pc(void); /* Get program counter */
|
||||
extern void h6280_set_pc(unsigned val); /* Set program counter */
|
||||
extern unsigned h6280_get_sp(void); /* Get stack pointer */
|
||||
extern void h6280_set_sp(unsigned val); /* Set stack pointer */
|
||||
extern unsigned h6280_get_reg (int regnum);
|
||||
extern void h6280_set_reg (int regnum, unsigned val);
|
||||
extern void h6280_set_nmi_line(int state);
|
||||
extern void h6280_set_irq_line(int irqline, int state);
|
||||
extern void h6280_set_irq_callback(int (*callback)(int irqline));
|
||||
|
||||
int H6280_irq_status_r(int offset);
|
||||
void H6280_irq_status_w(int offset, int data);
|
||||
int H6280_timer_r(int offset);
|
||||
void H6280_timer_w(int offset, int data);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* The 6280 registers.
|
||||
****************************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
PAIR ppc; /* previous program counter */
|
||||
PAIR pc; /* program counter */
|
||||
PAIR sp; /* stack pointer (always 100 - 1FF) */
|
||||
PAIR zp; /* zero page address */
|
||||
PAIR ea; /* effective address */
|
||||
UINT8 a; /* Accumulator */
|
||||
UINT8 x; /* X index register */
|
||||
UINT8 y; /* Y index register */
|
||||
UINT8 p; /* Processor status */
|
||||
UINT8 mmr[8]; /* Hu6280 memory mapper registers */
|
||||
UINT8 irq_mask; /* interrupt enable/disable */
|
||||
UINT8 timer_status; /* timer status */
|
||||
UINT8 timer_ack; /* timer acknowledge */
|
||||
int timer_value; /* timer interrupt */
|
||||
int timer_load; /* reload value */
|
||||
int extra_cycles; /* cycles used taking an interrupt */
|
||||
int nmi_state;
|
||||
int irq_state[3];
|
||||
int (*irq_callback)(int irqline);
|
||||
|
||||
#if LAZY_FLAGS
|
||||
int NZ; /* last value (lazy N and Z flag) */
|
||||
#endif
|
||||
} h6280_Regs;
|
||||
|
||||
/* Function prototypes */
|
||||
void cpu_writeport16(int port, int data);
|
||||
void cpu_writemem21(int address, int data);
|
||||
int cpu_readmem21(int address);
|
||||
|
||||
#endif /* _H6280_H */
|
Plik diff jest za duży
Load Diff
|
@ -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,53 @@
|
|||
#include "shared.h"
|
||||
|
||||
//static uint8 lpceram[0x8000];
|
||||
static uint8 lvram[0x10000];
|
||||
static uint8 lobjram[0x200];
|
||||
static uint8 lbram[0x2000];
|
||||
|
||||
static uint8 lbg_name_dirty[0x800];
|
||||
static uint16 lbg_name_list[0x800];
|
||||
static uint16 lobj_name_dirty[0x200];
|
||||
static uint16 lobj_name_list[0x200];
|
||||
static uint8 lbg_pattern_cache[BG_CACHE_SIZE];
|
||||
//static uint8 lobj_pattern_cache[OBJ_CACHE_SIZE];
|
||||
|
||||
|
||||
uint8 * vram=&lvram[0];
|
||||
uint16 * vramw = (uint16 *)&lvram[0];
|
||||
uint8 * objram = &lobjram[0];
|
||||
uint16 *objramw = (uint16 *)&lobjram[0];
|
||||
uint8 * pceram;// = &lpceram[0];
|
||||
#ifdef CDRAM
|
||||
uint8 * cdram;
|
||||
#endif
|
||||
uint8 * bram=&lbram[0];
|
||||
|
||||
uint8 * bg_name_dirty=&lbg_name_dirty[0];
|
||||
uint16 * bg_name_list=&lbg_name_list[0];
|
||||
uint16 * obj_name_dirty=&lobj_name_dirty[0];
|
||||
uint16 * obj_name_list=&lobj_name_list[0];
|
||||
uint8 * bg_pattern_cache;
|
||||
uint8 * obj_pattern_cache;
|
||||
uint8 * bg_pattern_cache=&lbg_pattern_cache[0];
|
||||
//uint8 * obj_pattern_cache=&lobj_pattern_cache[0];
|
||||
|
||||
#include "emuapi.h"
|
||||
|
||||
void mem_init(void) {
|
||||
//bg_pattern_cache = emu_Malloc(BG_CACHE_SIZE);
|
||||
obj_pattern_cache = emu_Malloc(OBJ_CACHE_SIZE); //0x20200000;
|
||||
pceram = emu_Malloc(0x8000);
|
||||
#ifdef CDRAM
|
||||
cdram = emu_Malloc(0x10000);
|
||||
#endif
|
||||
//emu_printh(obj_pattern_cache);
|
||||
}
|
||||
|
||||
|
||||
void memcpy_rom(int dst, int src, int size) {
|
||||
while (size > 0) {
|
||||
write_rom(dst++, read_rom(src++));
|
||||
size--;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef _MEMORY_H_
|
||||
#define _MEMORY_H_
|
||||
|
||||
extern uint8 * vram;
|
||||
extern uint16 * vramw;
|
||||
extern uint8 * pceram;
|
||||
extern uint8 * cdram;
|
||||
extern uint8 * bram;
|
||||
|
||||
extern uint8 * objram;
|
||||
extern uint16 *objramw;
|
||||
|
||||
|
||||
#define BG_CACHE_SIZE 0x20000
|
||||
#define OBJ_CACHE_SIZE 0x40000 //0x60000 //0x7E800 //0x80000
|
||||
|
||||
extern uint8 * bg_pattern_cache;
|
||||
extern uint8 * obj_pattern_cache;
|
||||
extern uint8 * bg_name_dirty;
|
||||
extern uint16 * bg_name_list;
|
||||
extern uint16 * obj_name_dirty;
|
||||
extern uint16 * obj_name_list;
|
||||
|
||||
|
||||
|
||||
|
||||
extern void mem_init(void);
|
||||
extern uint8 read_rom(int address);
|
||||
extern void write_rom(int address, uint8 val);
|
||||
extern void memcpy_rom(int dst, int src, int size);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,79 @@
|
|||
/*******************************************************************************
|
||||
* *
|
||||
* Define size independent data types and operations. *
|
||||
* *
|
||||
* The following types must be supported by all platforms: *
|
||||
* *
|
||||
* UINT8 - Unsigned 8-bit Integer INT8 - Signed 8-bit integer *
|
||||
* UINT16 - Unsigned 16-bit Integer INT16 - Signed 16-bit integer *
|
||||
* UINT32 - Unsigned 32-bit Integer INT32 - Signed 32-bit integer *
|
||||
* UINT64 - Unsigned 64-bit Integer INT64 - Signed 64-bit integer *
|
||||
* *
|
||||
* *
|
||||
* The macro names for the artithmatic operations are composed as follows: *
|
||||
* *
|
||||
* XXX_R_A_B, where XXX - 3 letter operation code (ADD, SUB, etc.) *
|
||||
* R - The type of the result *
|
||||
* A - The type of operand 1 *
|
||||
* B - The type of operand 2 (if binary operation) *
|
||||
* *
|
||||
* Each type is one of: U8,8,U16,16,U32,32,U64,64 *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef OSD_CPU_H
|
||||
#define OSD_CPU_H
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
//__extension__ typedef unsigned long long UINT64;
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
//__extension__ typedef signed long long INT64;
|
||||
|
||||
/* Combine two 32-bit integers into a 64-bit integer */
|
||||
#define COMBINE_64_32_32(A,B) ((((UINT64)(A))<<32) | (UINT32)(B))
|
||||
#define COMBINE_U64_U32_U32(A,B) COMBINE_64_32_32(A,B)
|
||||
|
||||
/* Return upper 32 bits of a 64-bit integer */
|
||||
#define HI32_32_64(A) (((UINT64)(A)) >> 32)
|
||||
#define HI32_U32_U64(A) HI32_32_64(A)
|
||||
|
||||
/* Return lower 32 bits of a 64-bit integer */
|
||||
#define LO32_32_64(A) ((A) & 0xffffffff)
|
||||
#define LO32_U32_U64(A) LO32_32_64(A)
|
||||
|
||||
#define DIV_64_64_32(A,B) ((A)/(B))
|
||||
#define DIV_U64_U64_U32(A,B) ((A)/(UINT32)(B))
|
||||
|
||||
#define MOD_32_64_32(A,B) ((A)%(B))
|
||||
#define MOD_U32_U64_U32(A,B) ((A)%(UINT32)(B))
|
||||
|
||||
#define MUL_64_32_32(A,B) ((A)*(INT64)(B))
|
||||
#define MUL_U64_U32_U32(A,B) ((A)*(UINT64)(UINT32)(B))
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Union of UINT8, UINT16 and UINT32 in native endianess of the target
|
||||
* This is used to access bytes and words in a machine independent manner.
|
||||
* The upper bytes h2 and h3 normally contain zero (16 bit CPU cores)
|
||||
* thus PAIR.d can be used to pass arguments to the memory system
|
||||
* which expects 'int' really.
|
||||
******************************************************************************/
|
||||
typedef union {
|
||||
#ifdef LSB_FIRST
|
||||
struct { UINT8 l,h,h2,h3; } b;
|
||||
struct { UINT16 l,h; } w;
|
||||
#else
|
||||
struct { UINT8 h3,h2,h,l; } b;
|
||||
struct { UINT16 h,l; } w;
|
||||
#endif
|
||||
UINT32 d;
|
||||
} PAIR;
|
||||
|
||||
#endif /* defined OSD_CPU_H */
|
|
@ -0,0 +1,429 @@
|
|||
#include "shared.h"
|
||||
|
||||
/* System memory */
|
||||
//uint8 * pceram; /* Work RAM */
|
||||
//uint8 * cdram; /* CD unit RAM (64k) */
|
||||
//uint8 * bram; /* Backup RAM (8K) */
|
||||
//static uint8 pcerom[0x100000*2]; /* HuCard ROM (1MB) */
|
||||
uint8 save_bram; /* 1= BRAM registers were accessed */
|
||||
|
||||
/* I/O port data */
|
||||
uint8 joy_sel = 0;
|
||||
uint8 joy_clr = 0;
|
||||
uint8 joy_cnt = 0;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int pce_init(void)
|
||||
{
|
||||
h6280_reset();
|
||||
h6280_set_irq_callback(&pce_irq_callback);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void pce_reset(void)
|
||||
{
|
||||
joy_sel = joy_clr = joy_cnt = 0;
|
||||
memset(pceram, 0, 0x8000);
|
||||
#ifdef CDRAM
|
||||
memset(cdram, 0, 0x10000);
|
||||
#endif
|
||||
h6280_reset();
|
||||
h6280_set_irq_callback(&pce_irq_callback);
|
||||
}
|
||||
|
||||
void pce_shutdown(void)
|
||||
{
|
||||
// char buf[256];
|
||||
// strcpy(buf, GetModulePath());
|
||||
// strcat(buf,"\\pce.brm");
|
||||
// if(save_bram) save_file(buf, bram, 0x2000);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Memory handlers */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void cpu_writeport16(int port, int data)
|
||||
{
|
||||
vdc_w(port, data);
|
||||
}
|
||||
|
||||
void cpu_writemem21(int address, int data)
|
||||
{
|
||||
uint8 page = (address >> 13) & 0xFF;
|
||||
|
||||
/* RAM (F8) */
|
||||
if(page == 0xF8 || page == 0xF9 || page == 0xFA || page == 0xFB) {
|
||||
pceram[(address & 0x7FFF)] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
/* I/O (FF) */
|
||||
if(page == 0xFF) {
|
||||
io_page_w(address & 0x1FFF, data);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CDRAM
|
||||
/* CD RAM */
|
||||
if((page >= 0x80) && (page <= 0x87)) {
|
||||
cdram[(address & 0xFFFF)] = data;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Backup RAM (F7) */
|
||||
if(page == 0xF7) {
|
||||
bram[(address & 0x1FFF)] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
// DEBUGLOG("write %02X to %02X:%04X (%08X)\n", data, page, address & 0x1fff, h6280_get_reg(H6280_PC));
|
||||
}
|
||||
|
||||
int cpu_readmem21(int address)
|
||||
{
|
||||
uint8 page;
|
||||
|
||||
if(address <= 0x0FFFFF) return (read_rom(address));
|
||||
|
||||
page = (address >> 13) & 0xFF;
|
||||
|
||||
/* ROM (00-7F) */
|
||||
if(page <= 0x7F) return (read_rom(address));
|
||||
|
||||
/* RAM (F8) */
|
||||
if(page == 0xF8 || page == 0xF9 || page == 0xFA || page == 0xFB) return (pceram[(address & 0x7FFF)]);
|
||||
|
||||
/* I/O (FF) */
|
||||
if(page == 0xFF) return (io_page_r(address & 0x1FFF));
|
||||
|
||||
#ifdef CDRAM
|
||||
/* CD RAM */
|
||||
if((page >= 0x80) && (page <= 0x87)) return (cdram[(address & 0xFFFF)]);
|
||||
#endif
|
||||
|
||||
/* Backup RAM (F7) */
|
||||
if(page == 0xF7) return (bram[(address & 0x1FFF)]);
|
||||
|
||||
// DEBUGLOG("read %02X:%04X (%08X)\n", page, address & 0x1fff, h6280_get_reg(H6280_PC));
|
||||
return (0xFF);
|
||||
}
|
||||
|
||||
|
||||
int pce_irq_callback(int irqline)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Hardware page handlers */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void io_page_w(int address, int data)
|
||||
{
|
||||
switch(address & 0x1C00)
|
||||
{
|
||||
case 0x0000: /* VDC */
|
||||
if(address <= 0x0003) { vdc_w(address, data); return; }
|
||||
break;
|
||||
|
||||
case 0x0400: /* VCE */
|
||||
if(address <= 0x0405) { vce_w(address, data); return; }
|
||||
break;
|
||||
|
||||
case 0x0800: /* PSG */
|
||||
if(address <= 0x0809) { psg_w(address, data); return; };
|
||||
break;
|
||||
|
||||
case 0x0C00: /* Timer */
|
||||
if(address == 0x0C00 || address == 0x0C01) { H6280_timer_w(address & 1, data); return; };
|
||||
break;
|
||||
|
||||
case 0x1000: /* I/O */
|
||||
if(address == 0x1000) { input_w(data); return; }
|
||||
break;
|
||||
|
||||
case 0x1400: /* IRQ control */
|
||||
if(address == 0x1402 || address == 0x1403) { H6280_irq_status_w(address & 1, data); return; };
|
||||
break;
|
||||
|
||||
case 0x1800: /* CD-ROM */
|
||||
// DEBUGLOG("cdrom %04X = %02X\n", address, data);
|
||||
if(address == 0x1807) save_bram = 1;
|
||||
break;
|
||||
|
||||
case 0x1C00: /* Expansion */
|
||||
break;
|
||||
}
|
||||
|
||||
// DEBUGLOG("write %02X to IO %04X (%08X)\n", data, address, h6280_get_reg(H6280_PC));
|
||||
}
|
||||
|
||||
|
||||
int io_page_r(int address)
|
||||
{
|
||||
switch(address & 0x1C00)
|
||||
{
|
||||
case 0x0000: /* VDC */
|
||||
if(address <= 0x0003) return (vdc_r(address));
|
||||
break;
|
||||
|
||||
case 0x0400: /* VCE */
|
||||
if(address <= 0x0405) return (vce_r(address));
|
||||
break;
|
||||
|
||||
case 0x0800: /* PSG */
|
||||
break;
|
||||
|
||||
case 0x0C00: /* Timer */
|
||||
if(address == 0x0C00 || address == 0x0C01) return (H6280_timer_r(address & 1));
|
||||
break;
|
||||
|
||||
case 0x1000: /* I/O */
|
||||
if(address == 0x1000) return (input_r());
|
||||
break;
|
||||
|
||||
case 0x1400: /* IRQ control */
|
||||
if(address == 0x1402 || address == 0x1403) return (H6280_irq_status_r(address & 1));
|
||||
break;
|
||||
|
||||
case 0x1800: /* CD-ROM */
|
||||
// DEBUGLOG("cdrom %04X\n", address);
|
||||
break;
|
||||
|
||||
case 0x1C00: /* Expansion */
|
||||
break;
|
||||
}
|
||||
|
||||
// DEBUGLOG("read IO %04X (%08X)\n", address, h6280_get_reg(H6280_PC));
|
||||
return (0x00);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Input routines */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void input_w(uint8 data)
|
||||
{
|
||||
joy_sel = (data & 1);
|
||||
joy_clr = (data >> 1) & 1;
|
||||
}
|
||||
|
||||
uint8 input_r(void)
|
||||
{
|
||||
uint8 temp = 0xFF;
|
||||
|
||||
if(input.pad[joy_cnt] & INPUT_LEFT) temp &= ~0x80;
|
||||
if(input.pad[joy_cnt] & INPUT_DOWN) temp &= ~0x40;
|
||||
if(input.pad[joy_cnt] & INPUT_RIGHT) temp &= ~0x20;
|
||||
if(input.pad[joy_cnt] & INPUT_UP) temp &= ~0x10;
|
||||
if(input.pad[joy_cnt] & INPUT_RUN) temp &= ~0x08;
|
||||
if(input.pad[joy_cnt] & INPUT_SELECT) temp &= ~0x04;
|
||||
if(input.pad[joy_cnt] & INPUT_B2) temp &= ~0x02;
|
||||
if(input.pad[joy_cnt] & INPUT_B1) temp &= ~0x01;
|
||||
|
||||
if(joy_sel & 1) temp >>= 4;
|
||||
temp &= 0x0F;
|
||||
|
||||
/* Set D6 for TurboGrafx-16, clear for PC-Engine */
|
||||
if(input.system & SYSTEM_TGX) temp |= 0x40;
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
PROGMEM static const unsigned long crc_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define DO1(pt) crc = crc_table[((int)crc ^ (read_rom(pt++))) & 0xff] ^ (crc >> 8);
|
||||
#define DO2(pt) DO1(pt); DO1(pt);
|
||||
#define DO4(pt) DO2(pt); DO2(pt);
|
||||
#define DO8(pt) DO4(pt); DO4(pt);
|
||||
|
||||
#include "pcecrc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* split : 1= Split image (only needed for 512k versions of 384k images)
|
||||
flip : 1= Bit-flip image (only for some TurboGrafx-16 images) */
|
||||
#include "bitflip.h"
|
||||
|
||||
int load_rom(char *file, int split, int flip)
|
||||
{
|
||||
uint32 crc;
|
||||
int size, n;
|
||||
int pos = 0x100000;
|
||||
//char * filename="Galaga88.pce";
|
||||
//char * filename="BONKIII.pce";
|
||||
//char * filename="NEWZEAL.pce";
|
||||
char * filename=file;
|
||||
|
||||
size = emu_FileSize(filename);
|
||||
|
||||
uint8 * buf = obj_pattern_cache;
|
||||
|
||||
/*
|
||||
size = emu_LoadFile(filename,buf,size);
|
||||
emu_printf("file loaded");
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
write_rom(pos++,buf[i]);
|
||||
}
|
||||
emu_printf("File written to psram");
|
||||
*/
|
||||
|
||||
|
||||
size = 0;
|
||||
int f = emu_FileOpen(filename, "r+b");
|
||||
if (f) {
|
||||
while ( (n = emu_FileRead(buf,262144,f) ) ) {
|
||||
size += n;
|
||||
for (int i=0; i<n; i++) {
|
||||
write_rom(pos++,buf[i]);
|
||||
}
|
||||
emu_printi(size);
|
||||
//emu_printi(n);
|
||||
}
|
||||
emu_FileClose(f);
|
||||
}
|
||||
|
||||
/* Check for 512-byte header */
|
||||
int offset = 0;
|
||||
if((size / 512) & 1)
|
||||
{
|
||||
size -= 0x200;
|
||||
offset += 0x200;
|
||||
}
|
||||
|
||||
/* Generate CRC and print information */
|
||||
int pt = 0x100000 + offset;
|
||||
int len = size;
|
||||
crc = 0 ^ 0xffffffffL;
|
||||
while (len >= 8)
|
||||
{
|
||||
DO8(pt);
|
||||
len -= 8;
|
||||
}
|
||||
if (len) do {
|
||||
DO1(pt);
|
||||
} while (--len);
|
||||
crc = crc ^ 0xffffffffL;
|
||||
|
||||
emu_printh(crc);
|
||||
|
||||
/* Look up game CRC in the CRC database, and set up flip and
|
||||
split options accordingly */
|
||||
for(n = 0; n < (sizeof(pcecrc_list) / sizeof(t_pcecrc)); n += 1)
|
||||
{
|
||||
if(crc == pcecrc_list[n].crc)
|
||||
{
|
||||
if(pcecrc_list[n].flag & FLAG_BITFLIP) flip = 1;
|
||||
if(pcecrc_list[n].flag & FLAG_SPLIT) split = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//flip=1;
|
||||
//split=1;
|
||||
|
||||
/* Bit-flip image */
|
||||
if(flip)
|
||||
{
|
||||
uint8 temp;
|
||||
int count;
|
||||
|
||||
pt = 0x100000 + offset;
|
||||
for(count = 0; count < size; count += 1)
|
||||
{
|
||||
temp = read_rom(pt+count);
|
||||
write_rom(pt+count,bitflip[temp]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Always split 384K images */
|
||||
if(size == 0x60000)
|
||||
{
|
||||
memcpy_rom(0x00000, 0x100000 + offset + 0x00000, 0x40000);
|
||||
memcpy_rom(0x80000, 0x100000 + offset + 0x40000, 0x20000);
|
||||
}
|
||||
else /* Split 512K images if requested */
|
||||
if(split && (size == 0x80000))
|
||||
{
|
||||
memcpy_rom(0x00000, 0x100000 + offset + 0x00000, 0x40000);
|
||||
memcpy_rom(0x80000, 0x100000 + offset + 0x40000, 0x40000);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy_rom(0, 0x100000 + offset, (size > 0x100000) ? 0x100000 : size);
|
||||
}
|
||||
emu_printf("done");
|
||||
return (1);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _PCE_H_
|
||||
#define _PCE_H_
|
||||
|
||||
/* Global data */
|
||||
extern uint8 joy_sel;
|
||||
extern uint8 joy_clr;
|
||||
extern uint8 joy_cnt;
|
||||
|
||||
/* Function prototypes */
|
||||
int pce_init(void);
|
||||
void pce_reset(void);
|
||||
void pce_shutdown(void);
|
||||
void cpu_writeport16(int port, int data);
|
||||
void cpu_writemem21(int address, int data);
|
||||
int pce_irq_callback(int irqline);
|
||||
void io_page_w(int address, int data);
|
||||
int io_page_r(int address);
|
||||
void input_w(uint8 data);
|
||||
uint8 input_r(void);
|
||||
void bank_reset(void);
|
||||
void bank_set(int bank, int value);
|
||||
|
||||
int load_rom(char *filename, int split, int flip);
|
||||
|
||||
#endif /* _PCE_H_ */
|
|
@ -0,0 +1,442 @@
|
|||
/* File generated by pcecrc.exe */
|
||||
|
||||
#define FLAG_BITFLIP (0x01)
|
||||
#define FLAG_SPLIT (0x02)
|
||||
#define FLAG_TGX (0x04)
|
||||
#define FLAG_BADDUMP (0x08)
|
||||
#define FLAG_SGX (0x10)
|
||||
|
||||
typedef struct {
|
||||
unsigned long int crc;
|
||||
unsigned char flag;
|
||||
char *name;
|
||||
} t_pcecrc;
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
PROGMEM const t_pcecrc pcecrc_list[] = {
|
||||
{0x8597B9D8, 0x00, "15 in 1 Mega Collection (J) (alt).PCE"},
|
||||
{0x6C30F0AC, 0x00, "15 in 1 Mega Collection (J).pce"},
|
||||
// {0x8C4588E2, 0x10, "1941 Counter Attack (SGX) (J).pce"},
|
||||
{0xD206E241, 0x10, "1941 Counter Attack (SGX) (J).pce"},
|
||||
{0xFDE08D6D, 0x00, "1943 Kai (J) (alt 1).pce"},
|
||||
{0x79362389, 0x00, "1943 Kai (J).pce"},
|
||||
{0x73614660, 0x00, "21-Emon (J).pce"},
|
||||
{0x637BA71D, 0x00, "5 in 1 Fami Collection (J).pce"},
|
||||
{0xE86249A4, 0x08, "Adventure Island (J) (bad dump).pce"},
|
||||
{0x8E71D4F3, 0x00, "Adventure Island (J).pce"},
|
||||
{0x5C507421, 0x00, "Aero Blasters (J) (alt 1).pce"},
|
||||
{0x25BE2B81, 0x00, "Aero Blasters (J).pce"},
|
||||
{0xC02B1B59, 0x04, "Aero Blasters (U).pce"},
|
||||
{0xCA72A828, 0x00, "After Burner II (J).pce"},
|
||||
{0xE3284BA7, 0x04, "Air Zonk (U).pce"},
|
||||
{0x4C2126B0, 0x10, "Aldynes (SGX) (J).pce"},
|
||||
{0x05453628, 0x02, "Alice in Wonderdream (J) (512K).pce"},
|
||||
{0x12C4E6FD, 0x00, "Alice in Wonderdream (J).pce"},
|
||||
{0x60EDF4E1, 0x00, "Alien Crush (J).pce"},
|
||||
{0xB64DE6FD, 0x04, "Alien Crush (U).pce"},
|
||||
{0x7F421A1C, 0x0C, "Andre Panza Kick Boxing (U) (bad dump 2).pce"},
|
||||
{0x3920105A, 0x04, "Andre Panza Kick Boxing (U).pce"},
|
||||
{0xCACC06FB, 0x00, "Ankoko Densetsu (J).pce"},
|
||||
{0x25DE250A, 0x02, "Aoi Blink (J) (512K).pce"},
|
||||
{0x08A09B9A, 0x00, "Aoi Blink (J).pce"},
|
||||
{0x2B54CBA2, 0x00, "Appare! Gateball (J).pce"},
|
||||
{0x5E4FA713, 0x00, "Artist Tool (J).pce"},
|
||||
{0xDD175EFD, 0x00, "Atomic Robokid Special (J).pce"},
|
||||
{0xB866D282, 0x00, "Av Poker World Gambler (J).pce"},
|
||||
{0x8ACFC8AA, 0x00, "Ballistix (J).pce"},
|
||||
{0x9693D259, 0x04, "Ballistix (U).pce"},
|
||||
{0xE13A6CE8, 0x0A, "Bari Bari Densetsu (J) (512K) (bad dump).pce"},
|
||||
{0x72A2C22C, 0x02, "Bari Bari Densetsu (J) (512K).pce"},
|
||||
{0xC267E25D, 0x00, "Bari Bari Densetsu (J).pce"},
|
||||
{0x4A3DF3CA, 0x00, "Barunba (J).pce"},
|
||||
{0x92C919EA, 0x02, "Batman (J) (512K).pce"},
|
||||
{0x106BB7B2, 0x00, "Batman (J).pce"},
|
||||
{0x3B13AF61, 0x10, "Battle Ace (SGX) (J).pce"},
|
||||
{0x59E44F45, 0x00, "Battle Lode Runner (J).pce"},
|
||||
{0xDA9A2DC9, 0x04, "Battle Royale (U).pce"},
|
||||
{0xE439F299, 0x00, "Be Ball (J) (hacked).pce"},
|
||||
{0x261F1013, 0x00, "Be Ball (J).pce"},
|
||||
{0x968770F6, 0x00, "Be Ball - Taisang Version (J).pce"},
|
||||
{0xC42B6D76, 0x02, "Benkei Gaiden (J) (512K).pce"},
|
||||
{0xE1A73797, 0x00, "Benkei Gaiden (J).pce"},
|
||||
{0x7AA9D4DC, 0x00, "Blazing Lazers (J).pce"},
|
||||
{0x958BCD09, 0x00, "Blodia (J).pce"},
|
||||
{0x47AFE6D7, 0x04, "Bloody Wolf (U).pce"},
|
||||
{0xFFD92458, 0x00, "Body Conquest 2 (J).pce"},
|
||||
{0xB300C5D0, 0x00, "Bomberman '93 (J).pce"},
|
||||
{0x26020C77, 0x04, "Bomberman '93 (U).pce"},
|
||||
{0x05362516, 0x00, "Bomberman '94 (J).pce"},
|
||||
{0x87FD22AD, 0x00, "Bomberman (J) (Pirate).pce"},
|
||||
{0x9ABB4D1F, 0x00, "Bomberman (J).pce"},
|
||||
{0x8BF34FFA, 0x04, "Bomberman (U).pce"},
|
||||
{0x9913A9DE, 0x04, "Bonk 3 - Bonk's Big Adventure (U).pce"},
|
||||
{0xD5C782F2, 0x06, "Bonk's Adventure (U) (512K).pce"},
|
||||
{0x64301FF1, 0x04, "Bonk's Revenge (U).pce"},
|
||||
{0xCC7D3EEB, 0x00, "Bonze Adventure (J).pce"},
|
||||
{0x8F4D9F94, 0x00, "Bouken Danshakan Don Sunheart Hen (J).pce"},
|
||||
{0x98850F62, 0x00, "Bouncing Ball Demo (PD).PCE"},
|
||||
{0x2E5AC9C0, 0x04, "Boxy Boy (U).pce"},
|
||||
{0x2BBF3090, 0x04, "Bravoman (U) (hacked).pce"},
|
||||
{0xC9D7426A, 0x00, "Break in (J).pce"},
|
||||
{0x0D766139, 0x00, "Bubblegum Crash (J).pce"},
|
||||
{0x3E4EAF98, 0x02, "Bullfight Ring no Haja (J) (512K).pce"},
|
||||
{0x5C4D1991, 0x00, "Bullfight Ring no Haja (J).pce"},
|
||||
{0x17A47D0D, 0x02, "Burning Angels (J) (512K).pce"},
|
||||
{0xD233C05A, 0x00, "Burning Angels (J).pce"},
|
||||
{0x2A121F03, 0x08, "CD-ROM System Ver. 1.00 (J) (bad dump).PCE"},
|
||||
{0x3F9F95A4, 0x00, "CD-ROM System Ver. 1.00 (J).pce"},
|
||||
{0x52520BC6, 0x00, "CD-ROM System Ver. 2.00 (J).pce"},
|
||||
{0xD634D931, 0x04, "CD-ROM System Ver. 2.00 (U).pce"},
|
||||
{0x833E05F9, 0x08, "CD-ROM System Ver. 2.10 (J) (bad dump).PCE"},
|
||||
{0xC6ADDAA1, 0x00, "CD-ROM System Ver. 2.10 (J) (hacked to report V1).pce"},
|
||||
{0x283B74E0, 0x00, "CD-ROM System Ver. 2.10 (J).pce"},
|
||||
{0x7D48D2FC, 0x02, "Cadash (J) (512K).pce"},
|
||||
{0x8DC0D85F, 0x00, "Cadash (J).pce"},
|
||||
{0xF45AFBCA, 0x04, "Cadash (U).pce"},
|
||||
{0x3C33E016, 0x00, "Cart (maybe demo) (PD).pce"},
|
||||
{0x76164593, 0x02, "Champion Wrestler (J) (512K).pce"},
|
||||
{0x9EDC0AEA, 0x00, "Champion Wrestler (J).pce"},
|
||||
{0x2CEE30EE, 0x04, "Champions Forever Boxing (U).pce"},
|
||||
{0x033E8C4A, 0x02, "Chase HQ (J) (512K).pce"},
|
||||
{0x6F4FD790, 0x00, "Chase HQ (J).pce"},
|
||||
{0xE84890A5, 0x04, "Chase HQ (U).pce"},
|
||||
{0x88796264, 0x04, "Chew-man-fu (U).pce"},
|
||||
{0x951ED380, 0x00, "Chibi Marukochan Quiz De Pihyara (J).pce"},
|
||||
{0xCAB21B2E, 0x00, "Chikudenya Toubee (J).pce"},
|
||||
{0xDC268242, 0x00, "China Warrior (J) (trained).pce"},
|
||||
{0xB552C906, 0x00, "China Warrior (J).pce"},
|
||||
{0x767245CD, 0x04, "China Warrior (U).pce"},
|
||||
{0x0DF57C90, 0x00, "Chouzetsu Rinjin (BravoMan) (J).PCE"},
|
||||
{0xC3212C24, 0x00, "Circus Lido (J).pce"},
|
||||
{0xDF804DC7, 0x02, "City Hunter (J) (512K).pce"},
|
||||
{0xF91B055F, 0x00, "City Hunter (J).pce"},
|
||||
{0x44F60137, 0x00, "College Pro Baseball '89 (J).pce"},
|
||||
{0x1772B229, 0x00, "College Pro Baseball '90 (J).pce"},
|
||||
{0x99F7A572, 0x00, "Columns (J).pce"},
|
||||
{0xB4D29E3B, 0x00, "Coryoon Child of Dragon (J).pce"},
|
||||
{0x44AF9BEA, 0x04, "Cratermaze (U).pce"},
|
||||
{0x2DF97BD0, 0x00, "Cross Wiber - Cyber Combat Police (J).pce"},
|
||||
{0xA0C97557, 0x02, "Cyber Core (J) (512K).pce"},
|
||||
{0xF82CED24, 0x00, "Cyber Core (J) (alt 2).pce"},
|
||||
{0xA98D276A, 0x00, "Cyber Core (J).pce"},
|
||||
{0x390710EC, 0x04, "Cyber Core (U).pce"},
|
||||
{0xDCD3E602, 0x02, "Cyber Cross (J) (512K).pce"},
|
||||
{0xD0C250CA, 0x00, "Cyber Cross (J).pce"},
|
||||
{0xB5326B16, 0x00, "Cyber Dodge (J).pce"},
|
||||
{0xA594FAC0, 0x00, "Cyber Knight (J).pce"},
|
||||
{0xB486A8ED, 0x10, "Dai Makai Mura (SGX) (Ghouls and Ghosts) (J).pce"},
|
||||
{0xA326334A, 0x00, "Daichikun Crisis Do Natural (J).pce"},
|
||||
{0xB0BA689F, 0x00, "Darius Alpha (J).pce"},
|
||||
{0x1E1D0319, 0x10, "Darius Plus (SGX) (J) (1024K).pce"},
|
||||
{0xBEBFE042, 0x10, "Darius Plus (SGX) (J).pce"},
|
||||
{0xE1A88CC3, 0x0C, "Darkwing Duck (U) (bad dump 1).pce"},
|
||||
{0x4A135429, 0x04, "Darkwing Duck (U).pce"},
|
||||
{0xEECFA5FD, 0x04, "Davis Cup Tennis (U).pce"},
|
||||
{0x56739BC7, 0x00, "Dead Moon (J).pce"},
|
||||
{0x85CC9B60, 0x04, "Dead Moon (U).pce"},
|
||||
{0x053A0F83, 0x00, "Deep Blue (J).pce"},
|
||||
{0xC2287894, 0x04, "Deep Blue (U).pce"},
|
||||
{0x5CF59D80, 0x00, "Detana!! Twinbee (J).pce"},
|
||||
{0x166A0E44, 0x02, "Devil Crash (J) (512K).pce"},
|
||||
{0x2762792B, 0x06, "Devil's Crush (U) (512K).pce"},
|
||||
{0x1B5B1CB1, 0x00, "Die Hard (J).pce"},
|
||||
{0x17BA3032, 0x00, "Digital Champ (J).pce"},
|
||||
{0x633A3D48, 0x02, "Don Doko Don (J) (512K).pce"},
|
||||
{0xF42AA73E, 0x00, "Don Doko Don (J).pce"},
|
||||
{0xDC760A07, 0x00, "Doraemon Meikyu Daisakusen (J).pce"},
|
||||
{0x013A747F, 0x00, "Doraemon Nobita no Dorabian Night (J).pce"},
|
||||
{0x86087B39, 0x00, "Double Dungeons (J).pce"},
|
||||
{0x9E86FFB0, 0x04, "Double Dungeons (U).pce"},
|
||||
{0x85101C20, 0x00, "Download (J).pce"},
|
||||
{0x442405D5, 0x00, "Dragon Egg! (J).pce"},
|
||||
{0xEEB6DD43, 0x00, "Dragon Fighter (J).pce"},
|
||||
{0x3219849C, 0x00, "Dragon Saber (J).pce"},
|
||||
{0x01A76935, 0x00, "Dragon Spirit (J).pce"},
|
||||
{0xDCF3675C, 0x04, "Dragon Spirit (U).pce"},
|
||||
{0x0BE0E0A8, 0x04, "Dragon's Curse (U).pce"},
|
||||
{0x67EC5EC4, 0x00, "Drop Rock Hora Hora (J).pce"},
|
||||
{0x2A3E08E2, 0x04, "Drop off (U).pce"},
|
||||
{0xF79657DD, 0x02, "Dungeon Explorer (J) (512K).pce"},
|
||||
{0x1B1A80A2, 0x00, "Dungeon Explorer (J).PCE"},
|
||||
{0x1E2CBCF8, 0x06, "Dungeon Explorer (U) (512K).pce"},
|
||||
{0xB18D102D, 0x00, "Eternal City Toshi Tenso Keikaku (J).pce"},
|
||||
{0xD50FF730, 0x00, "F-1 Dream (J).pce"},
|
||||
{0x020DC2DF, 0x02, "F-1 Pilot (J) (512K).pce"},
|
||||
{0x09048174, 0x00, "F-1 Pilot (J).pce"},
|
||||
{0xD7CFD70F, 0x00, "F1 Circus '91 - World Championship (J).pce"},
|
||||
{0xB268F2A2, 0x00, "F1 Circus '92 - The Speed of Sound (J).pce"},
|
||||
{0xE14DEE08, 0x00, "F1 Circus (J).pce"},
|
||||
{0x13BF0409, 0x00, "F1 Triple Battle (J).pce"},
|
||||
{0x7424452E, 0x04, "Falcon (U).pce"},
|
||||
{0x72CB0F9D, 0x00, "Fantasy Zone (J).pce"},
|
||||
{0xDCA24A76, 0x04, "Fantasy Zone (U).pce"},
|
||||
{0x1828D2E5, 0x00, "Fighting Run (J).pce"},
|
||||
{0xC90971BA, 0x00, "Final Blaster (J).pce"},
|
||||
{0xC8C084E3, 0x00, "Final Lap Twin (J).pce"},
|
||||
{0x854C37B3, 0x05, "Final Lap Twin (U) (bit-flipped).pce"},
|
||||
{0x560D2305, 0x00, "Final Match Tennis (J).pce"},
|
||||
{0xAF2DD2AF, 0x00, "Final Soldier (J).PCE"},
|
||||
{0x02A578C5, 0x00, "Final Soldier Special Version (J).pce"},
|
||||
{0xE88987BB, 0x00, "Fire Pro Wrestling 2nd Bout (J).pce"},
|
||||
{0x534E8808, 0x00, "Fire Pro Wrestling 3 - Legend Bout (J).pce"},
|
||||
{0x90ED6575, 0x00, "Fire Pro Wrestling Combination Tag (J).pce"},
|
||||
{0x20EF87FD, 0x00, "Formation Armed F (J).pce"},
|
||||
{0x85A1E7B6, 0x00, "Formation Soccer Human Cup '90 (J).pce"},
|
||||
{0x7146027C, 0x00, "Formation Soccer on J.league (J).pce"},
|
||||
{0x95F90DEC, 0x00, "Gai Flame (J).pce"},
|
||||
{0x6FD6827C, 0x00, "Gaia no Monsho (J).pce"},
|
||||
{0x1A8393C6, 0x00, "Galaga '88 (J).pce"},
|
||||
{0x6273A9D4, 0x04, "Galaga '90 (U).pce"},
|
||||
{0x22365252, 0x00, "Game of Life (PD).PCE"},
|
||||
{0x51A12D90, 0x04, "Games Express CD Card 1993 (U).pce"},
|
||||
{0x27A4D11A, 0x00, "Ganbare! Golf Boys (J).pce"},
|
||||
{0xAD450DFC, 0x00, "Genji Tsushin Agedama (Hero Agent) (J).pce"},
|
||||
{0xB926C682, 0x00, "Genpei Touma Den (J).pce"},
|
||||
{0x8793758C, 0x00, "Genpei Touma Den 2 (J).PCE"},
|
||||
{0x2DB4C1FD, 0x04, "Ghost Manor (U).pce"},
|
||||
{0x19FF94E5, 0x02, "Gokuraku Chuka Taisen (J) (512K).pce"},
|
||||
{0x4BD38F17, 0x00, "Gomola Speed (J).pce"},
|
||||
{0x0517DA65, 0x00, "Gradius (J).pce"},
|
||||
{0x1F041166, 0x10, "Grandzort (SGX) (J).pce"},
|
||||
{0xF370B58E, 0x04, "Gunboat (U).pce"},
|
||||
{0x113DD5F0, 0x02, "Gunhed (J) (512K).pce"},
|
||||
{0xA17D4D7E, 0x00, "Gunhed (J).pce"},
|
||||
{0x57F183AE, 0x00, "Gunhed Hudson Gunhed Taikai (J).pce"},
|
||||
{0xBA4D0DD4, 0x00, "Hana Tahka Daka (J).pce"},
|
||||
{0xBF3E2CC7, 0x00, "Hani in the Sky (J).pce"},
|
||||
{0x9897FA86, 0x00, "Hani on the Road (J).pce"},
|
||||
{0xCC799D92, 0x00, "Hatris (J) (256K).pce"},
|
||||
{0x44E7DF53, 0x00, "Hatris (J).pce"},
|
||||
{0xEB923DE5, 0x00, "Heavy Unit (J).pce"},
|
||||
{0xC7327632, 0x00, "Hisou Kihei Serd Gai Shadow (J).pce"},
|
||||
{0x7ACB60C8, 0x00, "Hit the Ice (J).pce"},
|
||||
{0xB01EE703, 0x00, "Hono no Tataka Tamako Dodge Danpei (J).pce"},
|
||||
{0xF84AE70B, 0x08, "Hyperdyne Sidearms (J) (bad dump).pce"},
|
||||
{0xE5E7B8B7, 0x00, "Hyperdyne Sidearms (J).pce"},
|
||||
{0x4F2BD39F, 0x00, "Hyperdyne Sidearms - Taisang Version (J).pce"},
|
||||
{0x9EC6FC6C, 0x00, "Idol Hanafuda Fan Club (J).pce"},
|
||||
{0xA80C565F, 0x00, "Image Fight (J).pce"},
|
||||
{0x92521F34, 0x04, "Impossamole (U).pce"},
|
||||
{0x0AD97B04, 0x00, "J. League Greatest Eleven Soccer (J).pce"},
|
||||
{0x348022F7, 0x04, "JJ & Jeff (U).pce"},
|
||||
{0xEA751E82, 0x00, "Jack Nicklaus' Greatest 18 Holes of Championship Golf (J).pce"},
|
||||
{0x57A436A2, 0x04, "Jack Nicklaus' Turbo Golf (U).pce"},
|
||||
{0xC6FA6373, 0x00, "Jackie Chan's Action Kung Fu (J).pce"},
|
||||
{0xED3A71F8, 0x04, "Jackie Chan's Action Kung Fu (U).pce"},
|
||||
{0x9BB8D362, 0x00, "Jamanoid (version unknown) (PD).PCE"},
|
||||
{0xC150637A, 0x00, "Jimmu Densho Yaksa (J).pce"},
|
||||
{0x6A628982, 0x00, "Jyuohki (Altered Beast) (J).pce"},
|
||||
{0xC8C7D63E, 0x00, "Jyuohki (J).pce"},
|
||||
{0xC0AF0947, 0x00, "Kaizou Ningen Shubibiman (J) (pirate).pce"},
|
||||
{0x109BA474, 0x00, "Kaizou Ningen Shubibiman 2 (J).pce"},
|
||||
{0x6069C5E7, 0x00, "Kato Chan & Ken Chan (J).pce"},
|
||||
{0x4F2844B0, 0x00, "Katutobi Takuhai Kun (J).pce"},
|
||||
{0xB54DEBD1, 0x04, "Keith Courage in Alpha Zones (U) (hacked 1).pce"},
|
||||
{0x73593F61, 0x02, "KickBall (J) (512K).pce"},
|
||||
{0x8E25DC77, 0x02, "Kiki Kai Kai (J) (512K).pce"},
|
||||
{0xC0CB5ADD, 0x00, "Kiki Kai Kai (J).pce"},
|
||||
{0xBF52788E, 0x00, "King of Casino (J).pce"},
|
||||
{0x589D33EB, 0x04, "King of Casino (U).pce"},
|
||||
{0xC74FFBC9, 0x00, "Klax (J).pce"},
|
||||
{0xDB872A64, 0x04, "Klax (U).pce"},
|
||||
{0xC614116C, 0x00, "Knight Rider Special (J) (alt).pce"},
|
||||
{0x61B80005, 0x00, "Knight Rider Special (J).pce"},
|
||||
{0xA586D190, 0x08, "Kyuukyoku Tiger (Ultimate Tiger) (J) (bad dump 3).pce"},
|
||||
{0x09509315, 0x00, "Kyuukyoku Tiger (Ultimate Tiger) (J).pce"},
|
||||
{0xC6F764EC, 0x00, "Lady Sword (J).pce"},
|
||||
{0xC28B0D8A, 0x00, "Legend of Hero Tonma (J).pce"},
|
||||
{0x0258ACCB, 0x04, "Legend of Hero Tonma (U).pce"},
|
||||
{0x088D896D, 0x04, "Legendary Axe II, The (U).PCE"},
|
||||
{0x07A226FB, 0x04, "Legendary Axe, The (U).pce"},
|
||||
{0xB2EF558D, 0x00, "Liquid Kids (J).pce"},
|
||||
{0xE6EE1468, 0x00, "Lode Runner Ushina Wareta Maikyuu (J).pce"},
|
||||
{0xA15A1F37, 0x00, "Maerchen Maze (J).PCE"},
|
||||
{0x0C8E99AB, 0x00, "Magic PCE Demo (PD).PCE"},
|
||||
{0xE8D01ED8, 0x00, "Magic Team Demo 2 (PD).PCE"},
|
||||
{0xDD0EBF8C, 0x00, "Magical Chase (J).PCE"},
|
||||
{0xF4148600, 0x00, "Mahjong Gakuen Mild (J).pce"},
|
||||
{0xF5B90D55, 0x00, "Mahjong Gakuen Touma Shiro Tojo (J).pce"},
|
||||
{0x2F8935AA, 0x00, "Majin Eiyu Wataru (J).pce"},
|
||||
{0xBE62EEF5, 0x00, "Makai Hakkenden Shada (J).pce"},
|
||||
{0xD4C5AF46, 0x00, "Makyo Densetsu (J).pce"},
|
||||
{0xE87190F1, 0x00, "Mesopotamia (J).PCE"},
|
||||
{0x25A02BEE, 0x00, "Metal Stoker (J).PCE"},
|
||||
{0x93F316F7, 0x04, "Military Madness (U).pce"},
|
||||
{0x7B96317C, 0x02, "Momo Tarou Densetsu Turbo (J) (512K).pce"},
|
||||
{0xF2E46D25, 0x00, "Monster Pro Wrestling (J).pce"},
|
||||
{0x745408AE, 0x00, "Moto Roader (J) (alt).pce"},
|
||||
{0x364508DA, 0x02, "Moto Roader II (J) (512K).pce"},
|
||||
{0x0B7F6E5F, 0x00, "Moto Roader II (J).pce"},
|
||||
{0x2CB92290, 0x00, "Mr. Heli no Dai Bouken (J).pce"},
|
||||
{0xB01F70C2, 0x00, "Narazumo no Sentou Butai (Bloody Wolf) (J).pce"},
|
||||
{0x60ECAE22, 0x00, "Naxat Open (J).pce"},
|
||||
{0xFBA3A1A4, 0x00, "Naxat Stadium - Taisang Version (J).pce"},
|
||||
{0x65FDB863, 0x00, "Nekketsu Koukou Dodgeball Bu Pc Bangai Hen (J).pce"},
|
||||
{0x9C49EF11, 0x00, "Neutopia (J).pce"},
|
||||
{0xA9A94E1B, 0x04, "Neutopia (U).pce"},
|
||||
{0x2B94AEDC, 0x00, "Neutopia II (J).pce"},
|
||||
{0xAE26F30F, 0x04, "Neutopia II (U) (1024K).pce"},
|
||||
{0xC4ED4307, 0x04, "Neutopia II (U).pce"},
|
||||
{0x8E4D75A8, 0x00, "New Zealand Story, The (J).pce"},
|
||||
|
||||
{0xC159761B, 0x04, "Night Creatures (U) (alt).PCE"},
|
||||
{0xA9FAB7D2, 0x04, "Night Creatures (U).pce"},
|
||||
{0x67573BAC, 0x00, "Ninja Gaiden (J).pce"},
|
||||
{0xAE9FE1AA, 0x04, "Ninja Spirit (U) (hacked).pce"},
|
||||
{0x96E0CD9D, 0x00, "Ninja Warriors, The (J).pce"},
|
||||
{0xFF898F87, 0x00, "Operation Wolf (J).pce"},
|
||||
{0xFAE0FC60, 0x04, "Order of the Griffon (U).pce"},
|
||||
{0x8C565CB6, 0x00, "Ordyne (J).pce"},
|
||||
{0xE203F223, 0x00, "OutRun (J).pce"},
|
||||
|
||||
{0xB74EC562, 0x00, "Override (J).PCE"},
|
||||
{0x14FAD3BA, 0x00, "Pac-Land (J).pce"},
|
||||
{0x73E994A0, 0x00, "Paranoia (J) (alt 1).pce"},
|
||||
{0x9893E0E6, 0x00, "Paranoia (J) (alt 2).pce"},
|
||||
{0x43EFC974, 0x00, "Paranoia (J) (trained).pce"},
|
||||
{0x51E86451, 0x00, "Parasol Stars (J).pce"},
|
||||
{0xE6458212, 0x04, "Parasol Stars (U).PCE"},
|
||||
{0x647718F9, 0x00, "Parodius (J).pce"},
|
||||
{0x740491C2, 0x00, "Pc Denjin - Punkic Cyborgs (J).pce"},
|
||||
{0xB630AB25, 0x02, "Pc Genjin (J) (512K) (alt).pce"},
|
||||
{0x2CB5CD55, 0x00, "Pc Genjin (J).pce"},
|
||||
{0x3028F7CA, 0x00, "Pc Genjin 2 (J).pce"},
|
||||
{0xA170B60E, 0x00, "Pc Genjin 3 (J).PCE"},
|
||||
{0xE8702D51, 0x00, "Photograph Boy (J).pce"},
|
||||
{0x4938B8BB, 0x00, "Populous (J) (1024K) (overdumped 1).PCE"},
|
||||
// {0x25E0F6E9, 0x00, "Power Drift (J).pce"},
|
||||
{0x5E17AC2A, 0x00, "Power Drift (J).pce"},
|
||||
|
||||
{0x3E647D8B, 0x00, "Power Eleven (J).pce"},
|
||||
{0xBE8B6E3B, 0x00, "Power Gate (J).pce"},
|
||||
{0x8F02FD20, 0x02, "Power Golf (J) (512K).pce"},
|
||||
{0xEA324F07, 0x00, "Power Golf (J).pce"},
|
||||
{0x69180984, 0x04, "Power League Baseball (U).PCE"},
|
||||
{0xBB654D1C, 0x00, "Power League V (J).pce"},
|
||||
{0x29EEC024, 0x00, "Power Sports (J).PCE"},
|
||||
{0x8DEF5AA1, 0x00, "Power Tennis (J).pce"},
|
||||
{0x66B167A9, 0x00, "Pro Yakyuu World Stadium '91 (J) (alt).pce"},
|
||||
{0x34E089A9, 0x00, "Pro Yakyuu World Stadium (J).pce"},
|
||||
{0x03883EE8, 0x00, "Psycho Chaser (J).pce"},
|
||||
{0x8672717C, 0x08, "Puzzle Boy (J) (bad dump).pce"},
|
||||
{0xFAA6E187, 0x00, "Puzzle Boy (J).pce"},
|
||||
{0x965C95B3, 0x00, "Puzznic (J).pce"},
|
||||
{0xF2E6856D, 0x00, "Quiz Toukou Shashin (J).pce"},
|
||||
{0xCEC3D28A, 0x00, "R-Type (J) (alt).pce"},
|
||||
{0x149D0511, 0x00, "R-Type - Taisang Version (J).PCE"},
|
||||
{0x9E2CF932, 0x04, "R-Type Complete (U).pce"},
|
||||
{0xF207ECAE, 0x00, "R-Type II (J).pce"},
|
||||
{0x6EAB778C, 0x00, "R-Type II - Taisang Version (J).pce"},
|
||||
{0xD8373DE6, 0x00, "Rabio Lepus Special (J).pce"},
|
||||
{0x3E79734C, 0x00, "Racing Spirits (J).pce"},
|
||||
{0xB99A85B6, 0x00, "Raiden (J) (1024K).PCE"},
|
||||
{0x850829F2, 0x00, "Raiden (J).pce"},
|
||||
{0xC7847DF7, 0x04, "Raiden (U).pce"},
|
||||
{0x85B85FF9, 0x02, "Rastan Saga II (J) (512K).PCE"},
|
||||
{0x00C38E69, 0x00, "Rastan Saga II (J).pce"},
|
||||
{0x462256FB, 0x02, "Rock on (J) (512K).pce"},
|
||||
{0x2FD65312, 0x00, "Rock on (J).pce"},
|
||||
{0x91E6896F, 0x00, "Ryukyu (J).pce"},
|
||||
{0xFAECCE20, 0x00, "Salamander (J).PCE"},
|
||||
{0x07BC34DC, 0x04, "Samurai-Ghost (U).pce"},
|
||||
{0x6923D736, 0x00, "Shanghai (J).pce"},
|
||||
{0xBC655CF3, 0x00, "Shinobi (J).pce"},
|
||||
// {0x471903C6, 0x02, "Shinobi (J).pce"},
|
||||
|
||||
{0x57615647, 0x04, "Shockman (U).pce"},
|
||||
{0x23EC8970, 0x00, "Shogi Shodan Icchokusen (J).pce"},
|
||||
{0x457F2BC4, 0x00, "Shogi Shoshinsha Muyo (J).pce"},
|
||||
{0x616EA179, 0x00, "Silent Debuggers, The (J).pce"},
|
||||
{0x4CAA6BE9, 0x05, "Silent Debuggers, The (U) (bit flipped).PCE"},
|
||||
{0xFA7E5D66, 0x04, "Silent Debuggers, The (U).pce"},
|
||||
{0x85AA49D0, 0x06, "Sinistron (U) (512K).PCE"},
|
||||
{0x05C20DE5, 0x00, "SlideShow (PD).PCE"},
|
||||
{0x8420B12B, 0x00, "Soldier Blade (J).PCE"},
|
||||
{0xF0227837, 0x04, "Somer Assault (U).pce"},
|
||||
{0xD7921DF2, 0x00, "Son Son II (J).pce"},
|
||||
{0x23D22D63, 0x04, "Sonic Spike (U).pce"},
|
||||
{0xFB37DDC4, 0x00, "Soukoban World (Boxy Boy) (J).pce"},
|
||||
{0x64580427, 0x00, "Space Harrier (J).pce"},
|
||||
{0x99496DB3, 0x00, "Space Invaders Fukkatsu no Hi (J).pce"},
|
||||
{0x1C6FF459, 0x00, "Spin Pair (J).pce"},
|
||||
{0x6B319457, 0x00, "Splatterhouse (J).PCE"},
|
||||
{0x727F4656, 0x00, "Stratego (J).pce"},
|
||||
{0xD15CB6BB, 0x00, "Street Fighter II Champion Edition (J).pce"},
|
||||
{0xD6FC51CE, 0x00, "Strip Fighter II (J).pce"},
|
||||
{0xDD35451D, 0x00, "Super CD-ROM2 System Ver. 3.00 (J) (384K) (overdumped 1).pce"},
|
||||
{0xE5D91815, 0x00, "Super CD-ROM2 System Ver. 3.00 (J) (384K) (overdumped 3).pce"},
|
||||
{0x9759A20D, 0x01, "Super CD-ROM2 System Ver. 3.00 (J) (bit-flipped for USA).pce"},
|
||||
{0x56488B36, 0x00, "Super Metal Crusher (J).pce"},
|
||||
{0x5D0E3105, 0x00, "Super Star Soldier (J).pce"},
|
||||
{0xAB3C5804, 0x04, "Super Star Soldier (U).PCE"},
|
||||
{0x10B60601, 0x00, "TV Sports Basketball (J).pce"},
|
||||
{0x9A41C638, 0x04, "TV Sports Basketball (U).pce"},
|
||||
{0xDA059C9B, 0x02, "TV Sports Football (J) (512K).pce"},
|
||||
{0x968D908A, 0x00, "TV Sports Football (J).pce"},
|
||||
{0x14DAF737, 0x04, "TV Sports Football (U).pce"},
|
||||
{0x4DF54B81, 0x04, "TV Sports Hockey (U) (alt).pce"},
|
||||
{0x04BF5EAF, 0x04, "TV Sports Hockey (U).pce"},
|
||||
{0xE7529890, 0x00, "TV Sports Ice Hockey (J).pce"},
|
||||
{0xE415EA19, 0x00, "Takahashi Meijin no Shin Boukenjima (New Adventure Island) (J).pce"},
|
||||
{0xC356216B, 0x04, "Takin it to the Hoop (U).pce"},
|
||||
{0x24C82EBE, 0x0C, "Talespin (U) (bad dump 2).pce"},
|
||||
{0xEDA32D95, 0x04, "Talespin (U).pce"},
|
||||
{0xA6088275, 0x00, "Tatsujin (J) (alt).PCE"},
|
||||
{0x4052FFAB, 0x08, "Tatsujin (J) (bad dump).pce"},
|
||||
{0x231B1535, 0x00, "Tatsujin (J).pce"},
|
||||
{0x320F5018, 0x00, "Tennokoe Memory Bank (J) (384k).pce"},
|
||||
{0xCA12AFBA, 0x02, "Tenseiryu Saint Dragon (J) (512K).PCE"},
|
||||
{0x2E278CCB, 0x00, "Tenseiryu Saint Dragon (J).pce"},
|
||||
{0x1B2D0077, 0x00, "Terra Cresta II (J).pce"},
|
||||
{0x5C3D477A, 0x00, "Text Sample 1 (PD).PCE"},
|
||||
{0x7964A966, 0x00, "Text Sample 2 (PD).PCE"},
|
||||
{0xDDC3E809, 0x00, "Thunder Blade (J).pce"},
|
||||
{0x72D6860B, 0x04, "Time Cruise (U).pce"},
|
||||
{0xCFEC1D6A, 0x00, "Time Cruise 2 (J).pce"},
|
||||
{0x05A4B72E, 0x04, "Timeball (U).pce"},
|
||||
{0xD20F382F, 0x00, "Titan (J).pce"},
|
||||
{0x53B7784B, 0x00, "Toilet Kids (J).PCE"},
|
||||
{0xBF797067, 0x02, "Tora E no Michi (J) (512K).pce"},
|
||||
{0x82AE3B16, 0x00, "Tora E no Michi (J).pce"},
|
||||
{0x72E00BC4, 0x00, "Tower of Druaga, The (J).pce"},
|
||||
{0x97C5EE9A, 0x00, "Toy Shop Boys (J).pce"},
|
||||
{0x3AEA2F8F, 0x00, "Tricky (J).pce"},
|
||||
{0x3D30D358, 0x04, "Tricky Kick (U) (alt).pce"},
|
||||
{0x3F982D0F, 0x04, "Turrican (U).pce"},
|
||||
{0xA3303978, 0x00, "Valkyrie no Densetsu (J).pce"},
|
||||
{0x04188C5C, 0x00, "Veigues Tactical Gladiator (J).pce"},
|
||||
{0xAD6E0376, 0x04, "Veigues Tactical Gladiator (U).PCE"},
|
||||
{0x03E28CFF, 0x00, "Victory Run (J).pce"},
|
||||
{0x5157A395, 0x04, "Victory Run (U).pce"},
|
||||
{0xE4124FE0, 0x04, "Vigilante (U) (alt).pce"},
|
||||
{0xC8A412E1, 0x04, "Vigilante (U).pce"},
|
||||
{0x34FD4EF2, 0x02, "Violent Soldier (J) (512K).pce"},
|
||||
{0x1BC36B36, 0x00, "Violent Soldier (J).pce"},
|
||||
{0xAD226F30, 0x00, "Volfied (J).pce"},
|
||||
{0xBE990010, 0x00, "W-ring the Double Rings (J).pce"},
|
||||
{0x661E475B, 0x00, "Walker Demo (PD).PCE"},
|
||||
{0x0112D0C7, 0x00, "Wallaby!! (J).pce"},
|
||||
{0x9B5EBC58, 0x00, "Winning Shot (J).pce"},
|
||||
{0x59D07314, 0x00, "Wonder Momo (J).PCE"},
|
||||
{0x38E2917D, 0x00, "Wonderboy in Monsterland (J) (alt 1).pce"},
|
||||
{0x02DB6FE5, 0x00, "Wonderboy in Monsterland (J) (partial English Translation).pce"},
|
||||
{0x2841FD1E, 0x00, "Wonderboy in Monsterland (J).pce"},
|
||||
{0xBE850530, 0x00, "World Beach Volley (J).pce"},
|
||||
{0xB3EEEA2E, 0x00, "World Circuit (J).pce"},
|
||||
{0x951AA310, 0x04, "World Class Baseball (U) (hacked).pce"},
|
||||
{0x11A36745, 0x00, "World Court Tennis (J).pce"},
|
||||
{0xC4EB68A5, 0x05, "World Court Tennis (U) (bit flipped).pce"},
|
||||
{0x70D90E20, 0x04, "World Court Tennis (U).pce"},
|
||||
{0xA9AB2954, 0x00, "World Jockey (J).pce"},
|
||||
{0x4161F202, 0x04, "World Sports Competition (U).pce"},
|
||||
{0xF8F85EEC, 0x00, "Xevious (J).pce"},
|
||||
{0x931B601F, 0x05, "Yo' Bro (U) (bit flipped).pce"},
|
||||
{0xB24E6504, 0x04, "Yo' Bro (U).pce"},
|
||||
{0xF131B706, 0x00, "Youkai Douchuuki (J).pce"},
|
||||
{0xC0905CA9, 0x00, "Yuu Yuu Jinsei (J).pce"},
|
||||
{0xEE156721, 0x00, "Zero 4 Champ (J) (alt 1).pce"},
|
||||
{0x2E6D9712, 0x00, "Zero 4 Champ (J) (alt 2).pce"},
|
||||
{0x67AAB7A1, 0x00, "Zipang (J).pce"},
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef _PCE_TYPES_H_
|
||||
#define _PCE_TYPES_H_
|
||||
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short int uint16;
|
||||
typedef unsigned long int uint32;
|
||||
|
||||
typedef signed char int8;
|
||||
typedef signed short int int16;
|
||||
typedef signed long int int32;
|
||||
|
||||
#define NULL 0
|
||||
|
||||
#endif /* _TYPES_H_ */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef _PLATFORM_CONFIG_H_
|
||||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
#define TEECOMPUTER 1
|
||||
|
||||
#ifdef TEECOMPUTER
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define TFTSPI1 1
|
||||
#define HAS_T4_VGA 1
|
||||
#define HAS_SND 1
|
||||
#define HAS_USBKEY 1
|
||||
//#define INVX 1
|
||||
#else
|
||||
|
||||
#define HAS_T4_VGA 1
|
||||
//#define INVX 1
|
||||
#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
//#define USE_SDFS 1
|
||||
//#define SDFSDEV "1:"
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,150 @@
|
|||
#include "shared.h"
|
||||
|
||||
t_psg psg;
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown routines */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int psg_init(void)
|
||||
{
|
||||
memset(&psg, 0, sizeof(psg));
|
||||
return (0);
|
||||
}
|
||||
|
||||
void psg_reset(void)
|
||||
{
|
||||
memset(&psg, 0, sizeof(psg));
|
||||
}
|
||||
|
||||
void psg_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PSG emulation */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void psg_w(uint16 address, uint8 data)
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
case 0x0800: /* Channel select */
|
||||
psg.select = (data & 7);
|
||||
break;
|
||||
|
||||
case 0x0801: /* Global sound balance */
|
||||
psg.globalbalance = data;
|
||||
break;
|
||||
|
||||
case 0x0802: /* Channel frequency (LSB) */
|
||||
PSGCH.frequency = (PSGCH.frequency & 0x0F00) | (data);
|
||||
break;
|
||||
|
||||
case 0x0803: /* Channel frequency (MSB) */
|
||||
PSGCH.frequency = (PSGCH.frequency & 0x00FF) | ((data & 0x0F) << 8);
|
||||
break;
|
||||
|
||||
case 0x0804: /* Channel enable, DDA, volume */
|
||||
PSGCH.control = data;
|
||||
if((data & 0xC0) == 0x40) PSGCH.waveform_index = 0;
|
||||
break;
|
||||
|
||||
case 0x0805: /* Channel balance */
|
||||
PSGCH.balance = data;
|
||||
break;
|
||||
|
||||
case 0x0806: /* Channel waveform data */
|
||||
PSGCH.waveform[PSGCH.waveform_index] = data;
|
||||
PSGCH.waveform_index = ((PSGCH.waveform_index + 1) & 0x1F);
|
||||
break;
|
||||
|
||||
case 0x0807: /* Noise enable and frequency */
|
||||
psg.noisectrl = data;
|
||||
break;
|
||||
|
||||
case 0x0808: /* LFO frequency */
|
||||
psg.lfofreq = data;
|
||||
break;
|
||||
|
||||
case 0x0809: /* LFO trigger and control */
|
||||
psg.lfoctrl = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void psg_update(int16 *bufl, int16 *bufr, int length)
|
||||
{
|
||||
/* Fill as many samples as needed */
|
||||
while(length > 0)
|
||||
{
|
||||
int ch; /* Channel index */
|
||||
int sample[2] = {0, 0}; /* Left and right samples */
|
||||
int start; /* Skip channels 0, 1 if LFO is enabled */
|
||||
int stop; /* Skip channels 4, 5 if noise is enabled */
|
||||
|
||||
start = ((psg.lfoctrl & 3) == 0) ? 0 : 2;
|
||||
stop = (psg.noisectrl & 0x80) ? 4 : 6;
|
||||
|
||||
for(ch = start; ch < stop; ch += 1)
|
||||
{
|
||||
/* If channel is ON and DDA is OFF, play waveform data */
|
||||
if((psg.channel[ch].control & 0xC0) == 0x80)
|
||||
{
|
||||
/* Global sound balance (left and right, all channels) */
|
||||
int lbal = (psg.globalbalance >> 4) & 0x0F;
|
||||
int rbal = (psg.globalbalance >> 0) & 0x0F;
|
||||
|
||||
/* Balance (left and right, this channel) */
|
||||
int lchb = (psg.channel[ch].balance >> 4) & 0x0F;
|
||||
int rchb = (psg.channel[ch].balance >> 0) & 0x0F;
|
||||
|
||||
/* Volume level (this channel) */
|
||||
int chvl = (psg.channel[ch].control & 0x1F);
|
||||
|
||||
/* Total volume levels for left and right
|
||||
(volume sounds too soft - not sure how to combine these) */
|
||||
int lvol = (lbal + lchb + chvl);
|
||||
int rvol = (rbal + rchb + chvl);
|
||||
|
||||
int base, step, offset, data;
|
||||
|
||||
/* This is the largest possible step value which is divided
|
||||
by the channel frequency used to increment the counter,
|
||||
which in turn is used to traverse the waveform buffer.
|
||||
3580000 (PSG clock) / 32 (length of waveform) = 111875 (base step value)
|
||||
That doesn't work right but multiplying it by three sounds better. */
|
||||
base = (3580000 / 32) * 3;
|
||||
|
||||
/* Calculate the value to add to the counter for each sample,
|
||||
but don't divide by zero if the frequency is zero */
|
||||
step = (psg.channel[ch].frequency) ? base / psg.channel[ch].frequency : 0;
|
||||
|
||||
/* Use upper 5 bits of 12-bit frequency as wave index */
|
||||
offset = (psg.channel[ch].counter >> 12) & 0x1F;
|
||||
|
||||
/* Bump waveform index */
|
||||
psg.channel[ch].counter += step;
|
||||
|
||||
/* Data is 5 bits */
|
||||
data = (psg.channel[ch].waveform[offset] & 0x1F);
|
||||
|
||||
/* Add new sample to old one */
|
||||
sample[0] = (sample[0] + (lvol * data));
|
||||
sample[1] = (sample[1] + (rvol * data));
|
||||
}
|
||||
}
|
||||
|
||||
/* Make samples signed */
|
||||
if(sample[0] & 0x8000) sample[0] ^= 0x8000;
|
||||
if(sample[1] & 0x8000) sample[1] ^= 0x8000;
|
||||
|
||||
/* Store samples in buffer */
|
||||
*bufl++ = sample[0]; //(sample[0]+sample[1])/2;
|
||||
//*bufl++ = sample[1];
|
||||
//*bufr++ = sample[1];
|
||||
|
||||
/* Do next sample pair */
|
||||
--length;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#ifndef _PSG_H_
|
||||
#define _PSG_H_
|
||||
|
||||
/* Macro to access currently selected PSG channel */
|
||||
#define PSGCH psg.channel[psg.select]
|
||||
|
||||
/* PSG structure */
|
||||
typedef struct {
|
||||
uint8 select; /* Selected channel (0-5) */
|
||||
uint8 globalbalance; /* Global sound balance */
|
||||
uint8 noisectrl; /* Noise enable and frequency */
|
||||
uint8 lfofreq; /* LFO frequency */
|
||||
uint8 lfoctrl; /* LFO control */
|
||||
struct {
|
||||
int counter; /* Waveform index counter */
|
||||
uint16 frequency; /* Channel frequency */
|
||||
uint8 control; /* Channel enable, DDA, volume */
|
||||
uint8 balance; /* Channel balance */
|
||||
uint8 waveform[32]; /* Waveform data */
|
||||
uint8 waveform_index; /* Waveform data index */
|
||||
} channel[8];
|
||||
}t_psg;
|
||||
|
||||
/* Global variables */
|
||||
extern t_psg psg;
|
||||
|
||||
/* Function prototypes */
|
||||
int psg_init(void);
|
||||
void psg_reset(void);
|
||||
void psg_shutdown(void);
|
||||
void psg_w(uint16 address, uint8 data);
|
||||
void psg_update(int16 *bufl, int16 *bufr, int length);
|
||||
|
||||
#endif /* _PSG_H_ */
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
#include "shared.h"
|
||||
|
||||
|
||||
/* Bit 0 : BG enable, Bit 1 : OBJ enable */
|
||||
int plane_enable = -1;
|
||||
|
||||
/* VCE color data to 16-bit pixel table */
|
||||
uint16 pixel[2][0x100];
|
||||
|
||||
/* Precalculated 16-bit pixel values */
|
||||
uint16 pixel_lut[0x200];
|
||||
|
||||
/* Pointer to 8 or 16-bit version of render_line() */
|
||||
void (*render_line)(int line) = NULL;
|
||||
|
||||
/* List of precalculated sprite data */
|
||||
t_sprite sprite_list[0x40];
|
||||
|
||||
/* Bitplane to packed pixel lookup table */
|
||||
//uint32 bp_lut[0x10000];
|
||||
#include "bp_lut.h"
|
||||
|
||||
/* Used sprite data */
|
||||
uint8 used_sprite_list[0x40];
|
||||
uint8 used_sprite_index;
|
||||
|
||||
|
||||
extern void emu_DrawLine16(unsigned short *src, int width , int height, int line);
|
||||
extern void emu_printf(char * text);
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int render_init(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* Make VCE data to raw pixel look-up table */
|
||||
for(i = 0; i < 0x200; i += 1)
|
||||
{
|
||||
int r = (i >> 3) & 7;
|
||||
int g = (i >> 6) & 7;
|
||||
int b = (i >> 0) & 7;
|
||||
pixel_lut[i] = (r << 13 | g << 8 | b << 2) & 0xE71C;
|
||||
}
|
||||
|
||||
render_line = render_line_generic;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
void render_reset(void)
|
||||
{
|
||||
render_line = render_line_generic;
|
||||
}
|
||||
|
||||
|
||||
void render_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int make_sprite_list(void)
|
||||
{
|
||||
uint16 *sat = &objramw[0];
|
||||
int xpos, ypos, name, attr;
|
||||
int cgx, xflip, cgy, yflip;
|
||||
int width, height;
|
||||
int i;
|
||||
uint32 flip;
|
||||
|
||||
used_sprite_index = 0;
|
||||
memset(&used_sprite_list, 0, sizeof(used_sprite_list));
|
||||
|
||||
memset(&sprite_list, 0, sizeof(sprite_list));
|
||||
|
||||
for(i = 0; i < 0x40; i += 1)
|
||||
{
|
||||
ypos = sat[(i << 2) | (0)];
|
||||
xpos = sat[(i << 2) | (1)];
|
||||
name = sat[(i << 2) | (2)];
|
||||
attr = sat[(i << 2) | (3)];
|
||||
|
||||
ypos &= 0x3FF;
|
||||
xpos &= 0x3FF;
|
||||
|
||||
if(xpos && ypos)
|
||||
{
|
||||
ypos -= 64;
|
||||
if(ypos >= 0x100) continue;
|
||||
cgy = (attr >> 12) & 3;
|
||||
cgy |= (cgy >> 1);
|
||||
height = (cgy + 1) << 4;
|
||||
if((ypos + height) < 0) continue;
|
||||
|
||||
xpos -= 32;
|
||||
if(xpos >= 0x200) continue;
|
||||
cgx = (attr >> 8) & 1;
|
||||
width = (cgx) ? 32 : 16;
|
||||
if((xpos + width) < 0) continue;
|
||||
|
||||
xflip = (attr >> 11) & 1;
|
||||
yflip = (attr >> 15) & 1;
|
||||
flip = ((xflip << 9) /*| (yflip << 10)*/) & 0x600;
|
||||
|
||||
name = (name >> 1) & 0x1FF;
|
||||
name &= ~((cgy << 1) | cgx);
|
||||
name |= flip;
|
||||
if(xflip && cgx) name ^= 1;
|
||||
|
||||
sprite_list[i].top = ypos;
|
||||
sprite_list[i].bottom = ypos + height;
|
||||
sprite_list[i].xpos = xpos;
|
||||
sprite_list[i].name_left = name;
|
||||
sprite_list[i].name_right = name ^ 1;
|
||||
sprite_list[i].height = (height - 1);
|
||||
sprite_list[i].palette = (attr & 0x0F) << 4;
|
||||
|
||||
if(yflip)
|
||||
sprite_list[i].flags |= FLAG_YFLIP;
|
||||
|
||||
if(cgx)
|
||||
sprite_list[i].flags |= FLAG_CGX;
|
||||
|
||||
if(!(attr & 0x80))
|
||||
sprite_list[i].flags |= FLAG_PRIORITY;
|
||||
|
||||
used_sprite_list[used_sprite_index] = (i);
|
||||
used_sprite_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (used_sprite_index);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Pattern and object cache update routines */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void update_bg_pattern_cache(void)
|
||||
{
|
||||
int i;
|
||||
uint8 x, y, c;
|
||||
uint16 name, index1, index2;
|
||||
uint32 temp;
|
||||
|
||||
if(!bg_list_index) return;
|
||||
|
||||
for(i = 0; i < bg_list_index; i += 1)
|
||||
{
|
||||
name = bg_name_list[i];
|
||||
bg_name_list[i] = 0;
|
||||
|
||||
for(y = 0; y < 8; y += 1)
|
||||
{
|
||||
if(bg_name_dirty[name] & (1 << y))
|
||||
{
|
||||
index1 = vramw[(name << 4) | (y)];
|
||||
index2 = vramw[(name << 4) | (y) | (8)];
|
||||
|
||||
temp = (bp_lut[index1] >> 2) | bp_lut[index2];
|
||||
|
||||
for(x = 0; x < 8; x += 1)
|
||||
{
|
||||
c = (temp >> (x << 2)) & 0x0F;
|
||||
bg_pattern_cache[(name << 6) | (y << 3) | (x)] = (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
bg_name_dirty[name] = 0;
|
||||
}
|
||||
|
||||
bg_list_index = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void update_obj_pattern_cache(void)
|
||||
{
|
||||
int i;
|
||||
uint16 name;
|
||||
uint16 b0, b1, b2, b3;
|
||||
uint8 i0, i1, i2, i3;
|
||||
uint8 x, y, c;
|
||||
|
||||
if(!obj_list_index) return;
|
||||
|
||||
for(i = 0; i < obj_list_index; i += 1)
|
||||
{
|
||||
name = obj_name_list[i];
|
||||
obj_name_list[i] = 0;
|
||||
|
||||
for(y = 0; y < 0x10; y += 1)
|
||||
{
|
||||
if(obj_name_dirty[name] & (1 << y))
|
||||
{
|
||||
b0 = vramw[(name << 6) + (y) + (0x00)];
|
||||
b1 = vramw[(name << 6) + (y) + (0x10)];
|
||||
b2 = vramw[(name << 6) + (y) + (0x20)];
|
||||
b3 = vramw[(name << 6) + (y) + (0x30)];
|
||||
|
||||
for(x = 0; x < 0x10; x += 1)
|
||||
{
|
||||
i0 = (b0 >> (x ^ 0x0F)) & 1;
|
||||
i1 = (b1 >> (x ^ 0x0F)) & 1;
|
||||
i2 = (b2 >> (x ^ 0x0F)) & 1;
|
||||
i3 = (b3 >> (x ^ 0x0F)) & 1;
|
||||
|
||||
c = (i3 << 3 | i2 << 2 | i1 << 1 | i0);
|
||||
|
||||
obj_pattern_cache[(name << 8) | (y << 4) | (x)] = (c);
|
||||
//if (OBJ_CACHE_SIZE > 0x20000)
|
||||
obj_pattern_cache[0x20000 | (name << 8) | (y << 4) | (x ^ 0x0F)] = (c);
|
||||
//if (OBJ_CACHE_SIZE > 0x40000)
|
||||
// obj_pattern_cache[0x40000 | (name << 8) | ((y ^ 0x0F) << 4) | (x)] = (c);
|
||||
//if (OBJ_CACHE_SIZE > 0x60000)
|
||||
// obj_pattern_cache[0x60000 | (name << 8) | ((y ^ 0x0F) << 4) | (x ^ 0x0F)] = (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
obj_name_dirty[name] = 0;
|
||||
}
|
||||
obj_list_index = 0;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Render functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// 16 bits line rendering
|
||||
static unsigned short linebuf[1024];
|
||||
|
||||
#define MIN(a,b) (a<b?a:b)
|
||||
void render_line_generic(int line)
|
||||
{
|
||||
if((reg[0x05] & 0x80) && (plane_enable & 1))
|
||||
{
|
||||
update_bg_pattern_cache();
|
||||
render_bg(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
uint16 *ptr = (uint16 *)&linebuf[XOFFSET]; //&bitmap.data[(line * bitmap.pitch) + (XOFFSET * bitmap.granularity)];
|
||||
for(i = 0; i < disp_width; i += 1) ptr[i] = pixel[0][0];
|
||||
}
|
||||
|
||||
if((reg[0x05] & 0x40) && (plane_enable & 2))
|
||||
{
|
||||
update_obj_pattern_cache();
|
||||
render_obj(line);
|
||||
}
|
||||
|
||||
emu_DrawLine16(&linebuf[XOFFSET], MIN(disp_width,256) , 240, line);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void render_bg(int line)
|
||||
{
|
||||
uint16 *nt;
|
||||
uint8 *src, palette;
|
||||
uint16 *dst;
|
||||
int column, name, attr, x, shift, v_line, nt_scroll;
|
||||
int xscroll = (reg[7] & 0x03FF);
|
||||
int end = disp_nt_width;
|
||||
|
||||
/* Offset in pattern, in lines */
|
||||
v_line = (y_offset & 7);
|
||||
|
||||
/* Offset in name table, in columns */
|
||||
nt_scroll = (xscroll >> 3);
|
||||
|
||||
/* Offset in column, in pixels */
|
||||
shift = (xscroll & 7);
|
||||
|
||||
/* Draw an extra tile for the last column */
|
||||
if(shift) end += 1;
|
||||
|
||||
/* Point to current offset within name table */
|
||||
nt = (uint16 *)&vram[(y_offset >> 3) << playfield_shift];
|
||||
|
||||
/* Point to start in line buffer */
|
||||
dst = (uint16 *)&linebuf[XOFFSET - shift]; //&bitmap.data[(line * bitmap.pitch) + ((XOFFSET + (0 - shift)) << 1)];
|
||||
|
||||
/* Draw columns */
|
||||
for(column = 0; column < end; column += 1)
|
||||
{
|
||||
/* Get attribute */
|
||||
attr = nt[(column + nt_scroll) & playfield_row_mask];
|
||||
|
||||
/* Extract name and palette bits */
|
||||
name = (attr & 0x07FF);
|
||||
palette = (attr >> 8) & 0xF0;
|
||||
|
||||
/* Point to current pattern line */
|
||||
src = &bg_pattern_cache[(name << 6) + (v_line << 3)];
|
||||
|
||||
/* Draw column */
|
||||
for(x = 0; x < 8; x += 1)
|
||||
{
|
||||
dst[(column << 3) | (x)] = pixel[0][(src[x] | palette)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void render_obj(int line)
|
||||
{
|
||||
t_sprite *p;
|
||||
int j, i, x, c;
|
||||
int name, name_mask;
|
||||
int v_line;
|
||||
uint8 *src;
|
||||
int nt_line;
|
||||
uint16 *dst;
|
||||
|
||||
for(j = (used_sprite_index - 1); j >= 0; j -= 1)
|
||||
{
|
||||
i = used_sprite_list[j];
|
||||
p = &sprite_list[i];
|
||||
|
||||
if( (line >= p->top) && (line < p->bottom))
|
||||
{
|
||||
v_line = (line - p->top) & p->height;
|
||||
nt_line = v_line;
|
||||
if(p->flags & FLAG_YFLIP) nt_line = (p->height - nt_line);
|
||||
name_mask = ((nt_line >> 4) & 3) << 1;
|
||||
name = (p->name_left | name_mask);
|
||||
v_line &= 0x0F;
|
||||
//src = &obj_pattern_cache[(name << 8) | ((v_line & 0x0f) << 4)];
|
||||
src = &obj_pattern_cache[(name << 8) | ( (p->flags & FLAG_YFLIP?v_line ^ 0x0F:v_line) << 4)];
|
||||
dst = (uint16 *)&linebuf[((XOFFSET+p->xpos) & 0x1ff)]; //&bitmap.data[(line * bitmap.pitch) + (((XOFFSET+p->xpos) & 0x1ff) * (bitmap.granularity))];
|
||||
for(x = 0; x < 0x10; x += 1)
|
||||
{
|
||||
c = src[x];
|
||||
//if ((unsigned int)&dst[x] < (unsigned int)&linebuf[400])
|
||||
if(c) dst[x] = pixel[1][((c) | p->palette)];
|
||||
}
|
||||
|
||||
if(p->flags & FLAG_CGX)
|
||||
{
|
||||
name = (p->name_right | name_mask);
|
||||
//src = &obj_pattern_cache[(name << 8) | ((v_line & 0x0f) << 4)];
|
||||
src = &obj_pattern_cache[(name << 8) | ( (p->flags & FLAG_YFLIP?v_line^ 0x0F:v_line) << 4)];
|
||||
dst += 0x10;
|
||||
|
||||
for(x = 0; x < 0x10; x += 1)
|
||||
{
|
||||
c = src[x];
|
||||
//if ((unsigned int)&dst[x] < (unsigned int)&linebuf[400])
|
||||
if(c) dst[x] = pixel[1][((c) | p->palette)];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
#ifndef _RENDER_H_
|
||||
#define _RENDER_H_
|
||||
|
||||
#define FLAG_ENABLE 0x80 /* 1= Sprite is enabled */
|
||||
#define FLAG_PRIORITY 0x01 /* 1= Sprite behind background */
|
||||
#define FLAG_CGX 0x02 /* 1= Sprite is two patterns wide */
|
||||
#define FLAG_YFLIP 0x04 /* 1= Sprite is vertically flipped */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32 top; /* 0x00 */
|
||||
int32 bottom; /* 0x04 */
|
||||
int32 xpos; /* 0x08 */
|
||||
uint32 name_left; /* 0x0C */
|
||||
uint32 name_right; /* 0x10 */
|
||||
uint32 height; /* 0x14 */
|
||||
uint8 palette; /* 0x18 */
|
||||
uint8 flags; /* 0x19 */
|
||||
uint8 filler[6]; /* 0x1A */
|
||||
} t_sprite;
|
||||
|
||||
/* Global data */
|
||||
extern int plane_enable;
|
||||
extern uint16 pixel[2][0x100];
|
||||
extern uint16 pixel_lut[0x200];
|
||||
extern void (*render_line)(int line);
|
||||
extern t_sprite sprite_list[0x40];
|
||||
//extern uint32 bp_lut[0x10000];
|
||||
extern const uint32 bp_lut[0x10000];
|
||||
extern uint8 used_sprite_list[0x40];
|
||||
extern uint8 used_sprite_index;
|
||||
|
||||
/* Function prototypes */
|
||||
int render_init(void);
|
||||
void render_reset(void);
|
||||
void render_shutdown(void);
|
||||
int make_sprite_list(void);
|
||||
void update_bg_pattern_cache(void);
|
||||
void update_obj_pattern_cache(void);
|
||||
void render_line_generic(int line);
|
||||
void render_bg(int line);
|
||||
void render_obj(int line);
|
||||
|
||||
#endif /* _RENDER_H_ */
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#ifndef _SHARED_H_
|
||||
#define _SHARED_H_
|
||||
|
||||
#define XOFFSET 0x20
|
||||
#define LSB_FIRST 1
|
||||
#define SOUND_PRESENT 1
|
||||
|
||||
|
||||
#include "pcetypes.h"
|
||||
#include "h6280.h"
|
||||
#include "pce.h"
|
||||
#include "vdc.h"
|
||||
#include "vce.h"
|
||||
#include "render.h"
|
||||
#include "system.h"
|
||||
#include "psg.h"
|
||||
#include "cpuintrf.h"
|
||||
#include "memory.h"
|
||||
|
||||
#endif /* _SHARED_H_ */
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
Copyright (C) 2000, 2001 Charles MacDonald
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "shared.h"
|
||||
|
||||
t_bitmap bitmap;
|
||||
t_input input;
|
||||
t_snd pcesnd;
|
||||
|
||||
|
||||
/* Pass 0 for no sound, or 8000-44100 for desired sample rate */
|
||||
/* No error checking at the moment... */
|
||||
int system_init(int sample_rate)
|
||||
{
|
||||
pce_init();
|
||||
vdc_init();
|
||||
psg_init();
|
||||
render_init();
|
||||
#ifdef SOUND_PRESENT
|
||||
audio_init(sample_rate);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef SOUND_PRESENT
|
||||
void audio_init(int rate)
|
||||
{
|
||||
memset(&pcesnd, 0, sizeof(pcesnd));
|
||||
|
||||
/* Exit if no sound or invalid sample rate */
|
||||
if(!rate || ((rate < 8000) || (rate > 44100))) return;
|
||||
else
|
||||
{
|
||||
/* Buffer size = sample rate / frames per second */
|
||||
//pcesnd.buffer_size = (rate / 60);
|
||||
|
||||
/* Keep local copy of sample rate for sound emulation */
|
||||
//pcesnd.sample_rate = rate;
|
||||
|
||||
/* Allocate left channel buffer */
|
||||
//pcesnd.buffer[0] = emu_Malloc(pcesnd.buffer_size * sizeof(int16));
|
||||
//if(!pcesnd.buffer[0]) return;
|
||||
/* Allocate right channel buffer */
|
||||
//pcesnd.buffer[1] = emu_Malloc(pcesnd.buffer_size * sizeof(int16));
|
||||
//if(!pcesnd.buffer[1]) return;
|
||||
|
||||
/* Set audio enable flag */
|
||||
pcesnd.enabled = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void system_frame(int skip)
|
||||
{
|
||||
int line;
|
||||
|
||||
for(y_offset = byr, line = 0; line < 262; line += 1)
|
||||
{
|
||||
// DEBUGLOG("system_frame 1\n");
|
||||
if((line + 64) == (reg[6] & 0x3FF))
|
||||
{
|
||||
if(reg[5] & 0x04)
|
||||
{
|
||||
status |= STATUS_RR;
|
||||
h6280_set_irq_line(0, ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
// DEBUGLOG("system_frame 2\n");
|
||||
|
||||
/* VBlank */
|
||||
if(line == 240)
|
||||
{
|
||||
if(dvssr_trigger || (reg[0x0F] & 0x10))
|
||||
{
|
||||
/* Clear DVSSR write trigger */
|
||||
dvssr_trigger = 0;
|
||||
|
||||
/* Copy VRAM to object RAM */
|
||||
memcpy(objram, &vram[(reg[0x13] << 1) & 0xFFFE], 0x200);
|
||||
|
||||
/* Cause transfer complete interrupt if necessary */
|
||||
if(reg[0x0F] & 0x01)
|
||||
{
|
||||
status |= STATUS_DS;
|
||||
h6280_set_irq_line(0, ASSERT_LINE);
|
||||
}
|
||||
|
||||
/* Precalculate sprite data for the next frame */
|
||||
make_sprite_list();
|
||||
}
|
||||
|
||||
/* Cause VBlank interrupt if necessary */
|
||||
if(reg[5] & 0x0008)
|
||||
{
|
||||
status |= STATUS_VD;
|
||||
h6280_set_irq_line(0, ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
// DEBUGLOG("system_frame 3\n");
|
||||
|
||||
/* 7.16 MHz = 455 cycles per line */
|
||||
h6280_execute(455);
|
||||
// DEBUGLOG("system_frame 4\n");
|
||||
|
||||
/* Render a line of the display */
|
||||
if((line < disp_height) && (!skip)) {
|
||||
|
||||
render_line(line);
|
||||
}
|
||||
|
||||
// DEBUGLOG("system_frame 5\n");
|
||||
|
||||
/* Update internal line counter and wrap */
|
||||
y_offset = (y_offset + 1) & playfield_col_mask;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void pce_sound(void)
|
||||
{
|
||||
/* Update audio */
|
||||
if(pcesnd.enabled) psg_update(pcesnd.buffer[0], pcesnd.buffer[1], pcesnd.buffer_size);
|
||||
}
|
||||
|
||||
void system_reset(void)
|
||||
{
|
||||
pce_reset();
|
||||
vdc_reset();
|
||||
psg_reset();
|
||||
render_reset();
|
||||
}
|
||||
|
||||
|
||||
void system_shutdown(void)
|
||||
{
|
||||
pce_shutdown();
|
||||
vdc_shutdown();
|
||||
psg_shutdown();
|
||||
render_shutdown();
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
#ifndef _SYSTEM_H_
|
||||
#define _SYSTEM_H_
|
||||
|
||||
/* Input devices */
|
||||
#define MAX_DEVICES (5) /* 1, or 5 with the MultiTap */
|
||||
#define DEVICE_2BUTTON (0) /* Standard 2-button pad */
|
||||
#define DEVICE_3BUTTON (1) /* 3-button pad */
|
||||
#define DEVICE_6BUTTON (2) /* 6-button pad */
|
||||
#define DEVICE_MULTITAP (3) /* MultiTap device */
|
||||
|
||||
/* Input bitmasks */
|
||||
#define INPUT_B6 (0x00000800) /* 6 button pad only */
|
||||
#define INPUT_B5 (0x00000400) /* 6 button pad only */
|
||||
#define INPUT_B4 (0x00000200) /* 6 button pad only */
|
||||
#define INPUT_B3 (0x00000100) /* 3/6 button pad only */
|
||||
#define INPUT_B2 (0x00000080)
|
||||
#define INPUT_B1 (0x00000040)
|
||||
#define INPUT_RUN (0x00000020)
|
||||
#define INPUT_SELECT (0x00000010)
|
||||
#define INPUT_LEFT (0x00000008)
|
||||
#define INPUT_RIGHT (0x00000004)
|
||||
#define INPUT_DOWN (0x00000002)
|
||||
#define INPUT_UP (0x00000001)
|
||||
|
||||
/* System input bitmasks */
|
||||
#define SYSTEM_TGX (0x00000001) /* System is 1=TGX, 0=PCE */
|
||||
|
||||
typedef struct
|
||||
|
||||
{
|
||||
uint8 *data; /* Bitmap data */
|
||||
int width; /* Bitmap width (32+512+32) */
|
||||
int height; /* Bitmap height (256) */
|
||||
int depth; /* Color depth (8 bits) */
|
||||
int pitch; /* Width of bitmap in bytes */
|
||||
int granularity; /* Size of each pixel in bytes */
|
||||
struct {
|
||||
int x; /* X offset of viewport within bitmap */
|
||||
int y; /* Y offset of viewport within bitmap */
|
||||
int w; /* Width of viewport */
|
||||
int h; /* Height of viewport */
|
||||
int ow; /* Previous width of viewport */
|
||||
int oh; /* Previous height of viewport */
|
||||
int changed; /* 1= Viewport width or height have changed */
|
||||
}viewport;
|
||||
}t_bitmap;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 dev[5]; /* Can be any of the DEVICE_* values */
|
||||
uint32 pad[5]; /* Can be any of the INPUT_* bitmasks */
|
||||
uint32 system; /* Can be any of the SYSTEM_* bitmasks */
|
||||
}t_input;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int sample_rate; /* Sample rate (8000-44100) */
|
||||
int enabled; /* 1= sound emulation is enabled */
|
||||
int buffer_size; /* Size of sound buffer (in bytes) */
|
||||
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
|
||||
}t_snd;
|
||||
|
||||
/* Global variables */
|
||||
//extern t_bitmap bitmap;
|
||||
extern t_input input;
|
||||
extern t_snd pcesnd;
|
||||
|
||||
/* Function prototypes */
|
||||
int system_init(int sample_rate);
|
||||
void audio_init(int rate);
|
||||
void system_frame(int skip);
|
||||
void system_reset(void);
|
||||
void system_shutdown(void);
|
||||
|
||||
#endif /* _SYSTEM_H_ */
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
/*****************************************************************************
|
||||
|
||||
tblh6280.c
|
||||
|
||||
Copyright (c) 1999 Bryan McPhail, mish@tendril.co.uk
|
||||
|
||||
This source code is based (with permission!) on the 6502 emulator by
|
||||
Juergen Buchmueller. It is released as part of the Mame emulator project.
|
||||
Let me know if you intend to use this code in any other project.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#undef OP
|
||||
//#define OP(nnn) static __inline__ void h6280_##nnn(void)
|
||||
#define OP(nnn) static void h6280_##nnn(void)
|
||||
|
||||
/*****************************************************************************
|
||||
*****************************************************************************
|
||||
*
|
||||
* Hu6280 opcodes
|
||||
*
|
||||
*****************************************************************************
|
||||
* op temp cycles rdmem opc wrmem ******************/
|
||||
OP(000) { h6280_ICount -= 8; BRK; } // 8 BRK
|
||||
OP(020) { h6280_ICount -= 7; EA_ABS; JSR; } // 7 JSR ABS
|
||||
OP(040) { h6280_ICount -= 7; RTI; } // 7 RTI
|
||||
OP(060) { h6280_ICount -= 7; RTS; } // 7 RTS
|
||||
OP(080) { int tmp; BRA(1); } // 4 BRA REL
|
||||
OP(0a0) { int tmp; h6280_ICount -= 2; RD_IMM; LDY; } // 2 LDY IMM
|
||||
OP(0c0) { int tmp; h6280_ICount -= 2; RD_IMM; CPY; } // 2 CPY IMM
|
||||
OP(0e0) { int tmp; h6280_ICount -= 2; RD_IMM; CPX; } // 2 CPX IMM
|
||||
|
||||
OP(010) { int tmp; BPL; } // 2/4 BPL REL
|
||||
OP(030) { int tmp; BMI; } // 2/4 BMI REL
|
||||
OP(050) { int tmp; BVC; } // 2/4 BVC REL
|
||||
OP(070) { int tmp; BVS; } // 2/4 BVS REL
|
||||
OP(090) { int tmp; BCC; } // 2/4 BCC REL
|
||||
OP(0b0) { int tmp; BCS; } // 2/4 BCS REL
|
||||
OP(0d0) { int tmp; BNE; } // 2/4 BNE REL
|
||||
OP(0f0) { int tmp; BEQ; } // 2/4 BEQ REL
|
||||
|
||||
OP(001) { int tmp; h6280_ICount -= 7; RD_IDX; ORA; } // 7 ORA IDX
|
||||
OP(021) { int tmp; h6280_ICount -= 7; RD_IDX; AND; } // 7 AND IDX
|
||||
OP(041) { int tmp; h6280_ICount -= 7; RD_IDX; EOR; } // 7 EOR IDX
|
||||
OP(061) { int tmp; h6280_ICount -= 7; RD_IDX; ADC; } // 7 ADC IDX
|
||||
OP(081) { int tmp; h6280_ICount -= 7; STA; WR_IDX; } // 7 STA IDX
|
||||
OP(0a1) { int tmp; h6280_ICount -= 7; RD_IDX; LDA; } // 7 LDA IDX
|
||||
OP(0c1) { int tmp; h6280_ICount -= 7; RD_IDX; CMP; } // 7 CMP IDX
|
||||
OP(0e1) { int tmp; h6280_ICount -= 7; RD_IDX; SBC; } // 7 SBC IDX
|
||||
|
||||
OP(011) { int tmp; h6280_ICount -= 7; RD_IDY; ORA; } // 7 ORA IDY
|
||||
OP(031) { int tmp; h6280_ICount -= 7; RD_IDY; AND; } // 7 AND IDY
|
||||
OP(051) { int tmp; h6280_ICount -= 7; RD_IDY; EOR; } // 7 EOR IDY
|
||||
OP(071) { int tmp; h6280_ICount -= 7; RD_IDY; ADC; } // 7 ADC AZP
|
||||
OP(091) { int tmp; h6280_ICount -= 7; STA; WR_IDY; } // 7 STA IDY
|
||||
OP(0b1) { int tmp; h6280_ICount -= 7; RD_IDY; LDA; } // 7 LDA IDY
|
||||
OP(0d1) { int tmp; h6280_ICount -= 7; RD_IDY; CMP; } // 7 CMP IDY
|
||||
OP(0f1) { int tmp; h6280_ICount -= 7; RD_IDY; SBC; } // 7 SBC IDY
|
||||
|
||||
OP(002) { int tmp; h6280_ICount -= 3; SXY; } // 3 SXY
|
||||
OP(022) { int tmp; h6280_ICount -= 3; SAX; } // 3 SAX
|
||||
OP(042) { int tmp; h6280_ICount -= 3; SAY; } // 3 SAY
|
||||
OP(062) { h6280_ICount -= 2; CLA; } // 2 CLA
|
||||
OP(082) { h6280_ICount -= 2; CLX; } // 2 CLX
|
||||
OP(0a2) { int tmp; h6280_ICount -= 2; RD_IMM; LDX; } // 2 LDX IMM
|
||||
OP(0c2) { h6280_ICount -= 2; CLY; } // 2 CLY
|
||||
OP(0e2) { ILL; } // 2 ???
|
||||
|
||||
OP(012) { int tmp; h6280_ICount -= 7; RD_ZPI; ORA; } // 7 ORA ZPI
|
||||
OP(032) { int tmp; h6280_ICount -= 7; RD_ZPI; AND; } // 7 AND ZPI
|
||||
OP(052) { int tmp; h6280_ICount -= 7; RD_ZPI; EOR; } // 7 EOR ZPI
|
||||
OP(072) { int tmp; h6280_ICount -= 7; RD_ZPI; ADC; } // 7 ADC ZPI
|
||||
OP(092) { int tmp; h6280_ICount -= 7; STA; WR_ZPI; } // 7 STA ZPI
|
||||
OP(0b2) { int tmp; h6280_ICount -= 7; RD_ZPI; LDA; } // 7 LDA ZPI
|
||||
OP(0d2) { int tmp; h6280_ICount -= 7; RD_ZPI; CMP; } // 7 CMP ZPI
|
||||
OP(0f2) { int tmp; h6280_ICount -= 7; RD_ZPI; SBC; } // 7 SBC ZPI
|
||||
|
||||
OP(003) { int tmp; h6280_ICount -= 4; RD_IMM; ST0; } // 4 ST0 IMM
|
||||
OP(023) { int tmp; h6280_ICount -= 4; RD_IMM; ST2; } // 4 ST2 IMM
|
||||
OP(043) { int tmp; h6280_ICount -= 4; RD_IMM; TMA; } // 4 TMA
|
||||
OP(063) { ILL; } // 2 ???
|
||||
OP(083) { int tmp,tmp2; h6280_ICount -= 7; RD_IMM2; RD_ZPG; TST; } // 7 TST IMM,ZPG
|
||||
OP(0a3) { int tmp,tmp2; h6280_ICount -= 7; RD_IMM2; RD_ZPX; TST; } // 7 TST IMM,ZPX
|
||||
OP(0c3) { int to,from,length; TDD; } // 6*l+17 TDD XFER
|
||||
OP(0e3) { int to,from,length,alternate; TIA; } // 6*l+17 TIA XFER
|
||||
|
||||
OP(013) { int tmp; h6280_ICount -= 4; RD_IMM; ST1; } // 4 ST1
|
||||
OP(033) { ILL; } // 2 ???
|
||||
OP(053) { int tmp; h6280_ICount -= 5; RD_IMM; TAM; } // 5 TAM IMM
|
||||
OP(073) { int to,from,length; TII; } // 6*l+17 TII XFER
|
||||
OP(093) { int tmp,tmp2; h6280_ICount -= 8; RD_IMM2; RD_ABS; TST; } // 8 TST IMM,ABS
|
||||
OP(0b3) { int tmp,tmp2; h6280_ICount -= 8; RD_IMM2; RD_ABX; TST; } // 8 TST IMM,ABX
|
||||
OP(0d3) { int to,from,length; TIN; } // 6*l+17 TIN XFER
|
||||
OP(0f3) { int to,from,length,alternate; TAI; } // 6*l+17 TAI XFER
|
||||
|
||||
OP(004) { int tmp; h6280_ICount -= 6; RD_ZPG; TSB; WB_EAZ; } // 6 TSB ZPG
|
||||
OP(024) { int tmp; h6280_ICount -= 4; RD_ZPG; BIT; } // 4 BIT ZPG
|
||||
OP(044) { int tmp; BSR; } // 8 BSR REL
|
||||
OP(064) { int tmp; h6280_ICount -= 4; STZ; WR_ZPG; } // 4 STZ ZPG
|
||||
OP(084) { int tmp; h6280_ICount -= 4; STY; WR_ZPG; } // 4 STY ZPG
|
||||
OP(0a4) { int tmp; h6280_ICount -= 4; RD_ZPG; LDY; } // 4 LDY ZPG
|
||||
OP(0c4) { int tmp; h6280_ICount -= 4; RD_ZPG; CPY; } // 4 CPY ZPG
|
||||
OP(0e4) { int tmp; h6280_ICount -= 4; RD_ZPG; CPX; } // 4 CPX ZPG
|
||||
|
||||
OP(014) { int tmp; h6280_ICount -= 6; RD_ZPG; TRB; WB_EAZ; } // 6 TRB ZPG
|
||||
OP(034) { int tmp; h6280_ICount -= 4; RD_ZPX; BIT; } // 4 BIT ZPX
|
||||
OP(054) { h6280_ICount -= 2; CSL; } // 2 CSL
|
||||
OP(074) { int tmp; h6280_ICount -= 4; STZ; WR_ZPX; } // 4 STZ ZPX
|
||||
OP(094) { int tmp; h6280_ICount -= 4; STY; WR_ZPX; } // 4 STY ZPX
|
||||
OP(0b4) { int tmp; h6280_ICount -= 4; RD_ZPX; LDY; } // 4 LDY ZPX
|
||||
OP(0d4) { h6280_ICount -= 2; CSH; } // 2 CSH
|
||||
OP(0f4) { h6280_ICount -= 2; SET; } // 2 SET
|
||||
|
||||
OP(005) { int tmp; h6280_ICount -= 4; RD_ZPG; ORA; } // 4 ORA ZPG
|
||||
OP(025) { int tmp; h6280_ICount -= 4; RD_ZPG; AND; } // 4 AND ZPG
|
||||
OP(045) { int tmp; h6280_ICount -= 4; RD_ZPG; EOR; } // 4 EOR ZPG
|
||||
OP(065) { int tmp; h6280_ICount -= 4; RD_ZPG; ADC; } // 4 ADC ZPG
|
||||
OP(085) { int tmp; h6280_ICount -= 4; STA; WR_ZPG; } // 4 STA ZPG
|
||||
OP(0a5) { int tmp; h6280_ICount -= 4; RD_ZPG; LDA; } // 4 LDA ZPG
|
||||
OP(0c5) { int tmp; h6280_ICount -= 4; RD_ZPG; CMP; } // 4 CMP ZPG
|
||||
OP(0e5) { int tmp; h6280_ICount -= 4; RD_ZPG; SBC; } // 4 SBC ZPG
|
||||
|
||||
OP(015) { int tmp; h6280_ICount -= 4; RD_ZPX; ORA; } // 4 ORA ZPX
|
||||
OP(035) { int tmp; h6280_ICount -= 4; RD_ZPX; AND; } // 4 AND ZPX
|
||||
OP(055) { int tmp; h6280_ICount -= 4; RD_ZPX; EOR; } // 4 EOR ZPX
|
||||
OP(075) { int tmp; h6280_ICount -= 4; RD_ZPX; ADC; } // 4 ADC ZPX
|
||||
OP(095) { int tmp; h6280_ICount -= 4; STA; WR_ZPX; } // 4 STA ZPX
|
||||
OP(0b5) { int tmp; h6280_ICount -= 4; RD_ZPX; LDA; } // 4 LDA ZPX
|
||||
OP(0d5) { int tmp; h6280_ICount -= 4; RD_ZPX; CMP; } // 4 CMP ZPX
|
||||
OP(0f5) { int tmp; h6280_ICount -= 4; RD_ZPX; SBC; } // 4 SBC ZPX
|
||||
|
||||
OP(006) { int tmp; h6280_ICount -= 6; RD_ZPG; ASL; WB_EAZ; } // 6 ASL ZPG
|
||||
OP(026) { int tmp; h6280_ICount -= 6; RD_ZPG; ROL; WB_EAZ; } // 6 ROL ZPG
|
||||
OP(046) { int tmp; h6280_ICount -= 6; RD_ZPG; LSR; WB_EAZ; } // 6 LSR ZPG
|
||||
OP(066) { int tmp; h6280_ICount -= 6; RD_ZPG; ROR; WB_EAZ; } // 6 ROR ZPG
|
||||
OP(086) { int tmp; h6280_ICount -= 4; STX; WR_ZPG; } // 4 STX ZPG
|
||||
OP(0a6) { int tmp; h6280_ICount -= 4; RD_ZPG; LDX; } // 4 LDX ZPG
|
||||
OP(0c6) { int tmp; h6280_ICount -= 6; RD_ZPG; DEC; WB_EAZ; } // 6 DEC ZPG
|
||||
OP(0e6) { int tmp; h6280_ICount -= 6; RD_ZPG; INC; WB_EAZ; } // 6 INC ZPG
|
||||
|
||||
OP(016) { int tmp; h6280_ICount -= 6; RD_ZPX; ASL; WB_EAZ } // 6 ASL ZPX
|
||||
OP(036) { int tmp; h6280_ICount -= 6; RD_ZPX; ROL; WB_EAZ } // 6 ROL ZPX
|
||||
OP(056) { int tmp; h6280_ICount -= 6; RD_ZPX; LSR; WB_EAZ } // 6 LSR ZPX
|
||||
OP(076) { int tmp; h6280_ICount -= 6; RD_ZPX; ROR; WB_EAZ } // 6 ROR ZPX
|
||||
OP(096) { int tmp; h6280_ICount -= 4; STX; WR_ZPY; } // 4 STX ZPY
|
||||
OP(0b6) { int tmp; h6280_ICount -= 4; RD_ZPY; LDX; } // 4 LDX ZPY
|
||||
OP(0d6) { int tmp; h6280_ICount -= 6; RD_ZPX; DEC; WB_EAZ; } // 6 DEC ZPX
|
||||
OP(0f6) { int tmp; h6280_ICount -= 6; RD_ZPX; INC; WB_EAZ; } // 6 INC ZPX
|
||||
|
||||
OP(007) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(0);WB_EAZ;} // 7 RMB0 ZPG
|
||||
OP(027) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(2);WB_EAZ;} // 7 RMB2 ZPG
|
||||
OP(047) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(4);WB_EAZ;} // 7 RMB4 ZPG
|
||||
OP(067) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(6);WB_EAZ;} // 7 RMB6 ZPG
|
||||
OP(087) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(0);WB_EAZ;} // 7 SMB0 ZPG
|
||||
OP(0a7) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(2);WB_EAZ;} // 7 SMB2 ZPG
|
||||
OP(0c7) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(4);WB_EAZ;} // 7 SMB4 ZPG
|
||||
OP(0e7) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(6);WB_EAZ;} // 7 SMB6 ZPG
|
||||
|
||||
OP(017) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(1);WB_EAZ;} // 7 RMB1 ZPG
|
||||
OP(037) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(3);WB_EAZ;} // 7 RMB3 ZPG
|
||||
OP(057) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(5);WB_EAZ;} // 7 RMB5 ZPG
|
||||
OP(077) { int tmp; h6280_ICount -= 7; RD_ZPG; RMB(7);WB_EAZ;} // 7 RMB7 ZPG
|
||||
OP(097) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(1);WB_EAZ;} // 7 SMB1 ZPG
|
||||
OP(0b7) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(3);WB_EAZ;} // 7 SMB3 ZPG
|
||||
OP(0d7) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(5);WB_EAZ;} // 7 SMB5 ZPG
|
||||
OP(0f7) { int tmp; h6280_ICount -= 7; RD_ZPG; SMB(7);WB_EAZ;} // 7 SMB7 ZPG
|
||||
|
||||
OP(008) { h6280_ICount -= 3; PHP; } // 3 PHP
|
||||
OP(028) { h6280_ICount -= 4; PLP; } // 4 PLP
|
||||
OP(048) { h6280_ICount -= 3; PHA; } // 3 PHA
|
||||
OP(068) { h6280_ICount -= 4; PLA; } // 4 PLA
|
||||
OP(088) { h6280_ICount -= 2; DEY; } // 2 DEY
|
||||
OP(0a8) { h6280_ICount -= 2; TAY; } // 2 TAY
|
||||
OP(0c8) { h6280_ICount -= 2; INY; } // 2 INY
|
||||
OP(0e8) { h6280_ICount -= 2; INX; } // 2 INX
|
||||
|
||||
OP(018) { h6280_ICount -= 2; CLC; } // 2 CLC
|
||||
OP(038) { h6280_ICount -= 2; SEC; } // 2 SEC
|
||||
OP(058) { h6280_ICount -= 2; CLI; } // 2 CLI
|
||||
OP(078) { h6280_ICount -= 2; SEI; } // 2 SEI
|
||||
OP(098) { h6280_ICount -= 2; TYA; } // 2 TYA
|
||||
OP(0b8) { h6280_ICount -= 2; CLV; } // 2 CLV
|
||||
OP(0d8) { h6280_ICount -= 2; CLD; } // 2 CLD
|
||||
OP(0f8) { h6280_ICount -= 2; SED; } // 2 SED
|
||||
|
||||
OP(009) { int tmp; h6280_ICount -= 2; RD_IMM; ORA; } // 2 ORA IMM
|
||||
OP(029) { int tmp; h6280_ICount -= 2; RD_IMM; AND; } // 2 AND IMM
|
||||
OP(049) { int tmp; h6280_ICount -= 2; RD_IMM; EOR; } // 2 EOR IMM
|
||||
OP(069) { int tmp; h6280_ICount -= 2; RD_IMM; ADC; } // 2 ADC IMM
|
||||
OP(089) { int tmp; h6280_ICount -= 2; RD_IMM; BIT; } // 2 BIT IMM
|
||||
OP(0a9) { int tmp; h6280_ICount -= 2; RD_IMM; LDA; } // 2 LDA IMM
|
||||
OP(0c9) { int tmp; h6280_ICount -= 2; RD_IMM; CMP; } // 2 CMP IMM
|
||||
OP(0e9) { int tmp; h6280_ICount -= 2; RD_IMM; SBC; } // 2 SBC IMM
|
||||
|
||||
OP(019) { int tmp; h6280_ICount -= 5; RD_ABY; ORA; } // 5 ORA ABY
|
||||
OP(039) { int tmp; h6280_ICount -= 5; RD_ABY; AND; } // 5 AND ABY
|
||||
OP(059) { int tmp; h6280_ICount -= 5; RD_ABY; EOR; } // 5 EOR ABY
|
||||
OP(079) { int tmp; h6280_ICount -= 5; RD_ABY; ADC; } // 5 ADC ABY
|
||||
OP(099) { int tmp; h6280_ICount -= 5; STA; WR_ABY; } // 5 STA ABY
|
||||
OP(0b9) { int tmp; h6280_ICount -= 5; RD_ABY; LDA; } // 5 LDA ABY
|
||||
OP(0d9) { int tmp; h6280_ICount -= 5; RD_ABY; CMP; } // 5 CMP ABY
|
||||
OP(0f9) { int tmp; h6280_ICount -= 5; RD_ABY; SBC; } // 5 SBC ABY
|
||||
|
||||
OP(00a) { int tmp; h6280_ICount -= 2; RD_ACC; ASL; WB_ACC; } // 2 ASL A
|
||||
OP(02a) { int tmp; h6280_ICount -= 2; RD_ACC; ROL; WB_ACC; } // 2 ROL A
|
||||
OP(04a) { int tmp; h6280_ICount -= 2; RD_ACC; LSR; WB_ACC; } // 2 LSR A
|
||||
OP(06a) { int tmp; h6280_ICount -= 2; RD_ACC; ROR; WB_ACC; } // 2 ROR A
|
||||
OP(08a) { h6280_ICount -= 2; TXA; } // 2 TXA
|
||||
OP(0aa) { h6280_ICount -= 2; TAX; } // 2 TAX
|
||||
OP(0ca) { h6280_ICount -= 2; DEX; } // 2 DEX
|
||||
OP(0ea) { h6280_ICount -= 2; NOP; } // 2 NOP
|
||||
|
||||
OP(01a) { h6280_ICount -= 2; INA; } // 2 INC A
|
||||
OP(03a) { h6280_ICount -= 2; DEA; } // 2 DEC A
|
||||
OP(05a) { h6280_ICount -= 3; PHY; } // 3 PHY
|
||||
OP(07a) { h6280_ICount -= 4; PLY; } // 4 PLY
|
||||
OP(09a) { h6280_ICount -= 2; TXS; } // 2 TXS
|
||||
OP(0ba) { h6280_ICount -= 2; TSX; } // 2 TSX
|
||||
OP(0da) { h6280_ICount -= 3; PHX; } // 3 PHX
|
||||
OP(0fa) { h6280_ICount -= 4; PLX; } // 4 PLX
|
||||
|
||||
OP(00b) { ILL; } // 2 ???
|
||||
OP(02b) { ILL; } // 2 ???
|
||||
OP(04b) { ILL; } // 2 ???
|
||||
OP(06b) { ILL; } // 2 ???
|
||||
OP(08b) { ILL; } // 2 ???
|
||||
OP(0ab) { ILL; } // 2 ???
|
||||
OP(0cb) { ILL; } // 2 ???
|
||||
OP(0eb) { ILL; } // 2 ???
|
||||
|
||||
OP(01b) { ILL; } // 2 ???
|
||||
OP(03b) { ILL; } // 2 ???
|
||||
OP(05b) { ILL; } // 2 ???
|
||||
OP(07b) { ILL; } // 2 ???
|
||||
OP(09b) { ILL; } // 2 ???
|
||||
OP(0bb) { ILL; } // 2 ???
|
||||
OP(0db) { ILL; } // 2 ???
|
||||
OP(0fb) { ILL; } // 2 ???
|
||||
|
||||
OP(00c) { int tmp; h6280_ICount -= 7; RD_ABS; TSB; WB_EA; } // 7 TSB ABS
|
||||
OP(02c) { int tmp; h6280_ICount -= 5; RD_ABS; BIT; } // 5 BIT ABS
|
||||
OP(04c) { h6280_ICount -= 4; EA_ABS; JMP; } // 4 JMP ABS
|
||||
OP(06c) { int tmp; h6280_ICount -= 7; EA_IND; JMP; } // 7 JMP IND
|
||||
OP(08c) { int tmp; h6280_ICount -= 5; STY; WR_ABS; } // 5 STY ABS
|
||||
OP(0ac) { int tmp; h6280_ICount -= 5; RD_ABS; LDY; } // 5 LDY ABS
|
||||
OP(0cc) { int tmp; h6280_ICount -= 5; RD_ABS; CPY; } // 5 CPY ABS
|
||||
OP(0ec) { int tmp; h6280_ICount -= 5; RD_ABS; CPX; } // 5 CPX ABS
|
||||
|
||||
OP(01c) { int tmp; h6280_ICount -= 7; RD_ABS; TRB; WB_EA; } // 7 TRB ABS
|
||||
OP(03c) { int tmp; h6280_ICount -= 5; RD_ABX; BIT; } // 5 BIT ABX
|
||||
OP(05c) { ILL; } // 2 ???
|
||||
OP(07c) { int tmp; h6280_ICount -= 7; EA_IAX; JMP; } // 7 JMP IAX
|
||||
OP(09c) { int tmp; h6280_ICount -= 5; STZ; WR_ABS; } // 5 STZ ABS
|
||||
OP(0bc) { int tmp; h6280_ICount -= 5; RD_ABX; LDY; } // 5 LDY ABX
|
||||
OP(0dc) { ILL; } // 2 ???
|
||||
OP(0fc) { ILL; } // 2 ???
|
||||
|
||||
OP(00d) { int tmp; h6280_ICount -= 5; RD_ABS; ORA; } // 5 ORA ABS
|
||||
OP(02d) { int tmp; h6280_ICount -= 5; RD_ABS; AND; } // 4 AND ABS
|
||||
OP(04d) { int tmp; h6280_ICount -= 5; RD_ABS; EOR; } // 4 EOR ABS
|
||||
OP(06d) { int tmp; h6280_ICount -= 5; RD_ABS; ADC; } // 4 ADC ABS
|
||||
OP(08d) { int tmp; h6280_ICount -= 5; STA; WR_ABS; } // 4 STA ABS
|
||||
OP(0ad) { int tmp; h6280_ICount -= 5; RD_ABS; LDA; } // 4 LDA ABS
|
||||
OP(0cd) { int tmp; h6280_ICount -= 5; RD_ABS; CMP; } // 4 CMP ABS
|
||||
OP(0ed) { int tmp; h6280_ICount -= 5; RD_ABS; SBC; } // 4 SBC ABS
|
||||
|
||||
OP(01d) { int tmp; h6280_ICount -= 5; RD_ABX; ORA; } // 5 ORA ABX
|
||||
OP(03d) { int tmp; h6280_ICount -= 5; RD_ABX; AND; } // 4 AND ABX
|
||||
OP(05d) { int tmp; h6280_ICount -= 5; RD_ABX; EOR; } // 4 EOR ABX
|
||||
OP(07d) { int tmp; h6280_ICount -= 5; RD_ABX; ADC; } // 4 ADC ABX
|
||||
OP(09d) { int tmp; h6280_ICount -= 5; STA; WR_ABX; } // 5 STA ABX
|
||||
OP(0bd) { int tmp; h6280_ICount -= 5; RD_ABX; LDA; } // 5 LDA ABX
|
||||
OP(0dd) { int tmp; h6280_ICount -= 5; RD_ABX; CMP; } // 4 CMP ABX
|
||||
OP(0fd) { int tmp; h6280_ICount -= 5; RD_ABX; SBC; } // 4 SBC ABX
|
||||
|
||||
OP(00e) { int tmp; h6280_ICount -= 7; RD_ABS; ASL; WB_EA; } // 6 ASL ABS
|
||||
OP(02e) { int tmp; h6280_ICount -= 7; RD_ABS; ROL; WB_EA; } // 6 ROL ABS
|
||||
OP(04e) { int tmp; h6280_ICount -= 7; RD_ABS; LSR; WB_EA; } // 6 LSR ABS
|
||||
OP(06e) { int tmp; h6280_ICount -= 7; RD_ABS; ROR; WB_EA; } // 6 ROR ABS
|
||||
OP(08e) { int tmp; h6280_ICount -= 5; STX; WR_ABS; } // 4 STX ABS
|
||||
OP(0ae) { int tmp; h6280_ICount -= 5; RD_ABS; LDX; } // 5 LDX ABS
|
||||
OP(0ce) { int tmp; h6280_ICount -= 7; RD_ABS; DEC; WB_EA; } // 6 DEC ABS
|
||||
OP(0ee) { int tmp; h6280_ICount -= 7; RD_ABS; INC; WB_EA; } // 6 INC ABS
|
||||
|
||||
OP(01e) { int tmp; h6280_ICount -= 7; RD_ABX; ASL; WB_EA; } // 7 ASL ABX
|
||||
OP(03e) { int tmp; h6280_ICount -= 7; RD_ABX; ROL; WB_EA; } // 7 ROL ABX
|
||||
OP(05e) { int tmp; h6280_ICount -= 7; RD_ABX; LSR; WB_EA; } // 7 LSR ABX
|
||||
OP(07e) { int tmp; h6280_ICount -= 7; RD_ABX; ROR; WB_EA; } // 7 ROR ABX
|
||||
OP(09e) { int tmp; h6280_ICount -= 5; STZ; WR_ABX; } // 5 STZ ABX
|
||||
OP(0be) { int tmp; h6280_ICount -= 5; RD_ABY; LDX; } // 4 LDX ABY
|
||||
OP(0de) { int tmp; h6280_ICount -= 7; RD_ABX; DEC; WB_EA; } // 7 DEC ABX
|
||||
OP(0fe) { int tmp; h6280_ICount -= 7; RD_ABX; INC; WB_EA; } // 7 INC ABX
|
||||
|
||||
OP(00f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(0); } // 6/8 BBR0 ZPG,REL
|
||||
OP(02f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(2); } // 6/8 BBR2 ZPG,REL
|
||||
OP(04f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(4); } // 6/8 BBR4 ZPG,REL
|
||||
OP(06f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(6); } // 6/8 BBR6 ZPG,REL
|
||||
OP(08f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(0); } // 6/8 BBS0 ZPG,REL
|
||||
OP(0af) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(2); } // 6/8 BBS2 ZPG,REL
|
||||
OP(0cf) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(4); } // 6/8 BBS4 ZPG,REL
|
||||
OP(0ef) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(6); } // 6/8 BBS6 ZPG,REL
|
||||
|
||||
OP(01f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(1); } // 6/8 BBR1 ZPG,REL
|
||||
OP(03f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(3); } // 6/8 BBR3 ZPG,REL
|
||||
OP(05f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(5); } // 6/8 BBR5 ZPG,REL
|
||||
OP(07f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBR(7); } // 6/8 BBR7 ZPG,REL
|
||||
OP(09f) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(1); } // 6/8 BBS1 ZPG,REL
|
||||
OP(0bf) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(3); } // 6/8 BBS3 ZPG,REL
|
||||
OP(0df) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(5); } // 6/8 BBS5 ZPG,REL
|
||||
OP(0ff) { int tmp; h6280_ICount -= 4; RD_ZPG; BBS(7); } // 6/8 BBS7 ZPG,REL
|
||||
|
||||
static void (*insnh6280[0x100])(void) = {
|
||||
h6280_000,h6280_001,h6280_002,h6280_003,h6280_004,h6280_005,h6280_006,h6280_007,
|
||||
h6280_008,h6280_009,h6280_00a,h6280_00b,h6280_00c,h6280_00d,h6280_00e,h6280_00f,
|
||||
h6280_010,h6280_011,h6280_012,h6280_013,h6280_014,h6280_015,h6280_016,h6280_017,
|
||||
h6280_018,h6280_019,h6280_01a,h6280_01b,h6280_01c,h6280_01d,h6280_01e,h6280_01f,
|
||||
h6280_020,h6280_021,h6280_022,h6280_023,h6280_024,h6280_025,h6280_026,h6280_027,
|
||||
h6280_028,h6280_029,h6280_02a,h6280_02b,h6280_02c,h6280_02d,h6280_02e,h6280_02f,
|
||||
h6280_030,h6280_031,h6280_032,h6280_033,h6280_034,h6280_035,h6280_036,h6280_037,
|
||||
h6280_038,h6280_039,h6280_03a,h6280_03b,h6280_03c,h6280_03d,h6280_03e,h6280_03f,
|
||||
h6280_040,h6280_041,h6280_042,h6280_043,h6280_044,h6280_045,h6280_046,h6280_047,
|
||||
h6280_048,h6280_049,h6280_04a,h6280_04b,h6280_04c,h6280_04d,h6280_04e,h6280_04f,
|
||||
h6280_050,h6280_051,h6280_052,h6280_053,h6280_054,h6280_055,h6280_056,h6280_057,
|
||||
h6280_058,h6280_059,h6280_05a,h6280_05b,h6280_05c,h6280_05d,h6280_05e,h6280_05f,
|
||||
h6280_060,h6280_061,h6280_062,h6280_063,h6280_064,h6280_065,h6280_066,h6280_067,
|
||||
h6280_068,h6280_069,h6280_06a,h6280_06b,h6280_06c,h6280_06d,h6280_06e,h6280_06f,
|
||||
h6280_070,h6280_071,h6280_072,h6280_073,h6280_074,h6280_075,h6280_076,h6280_077,
|
||||
h6280_078,h6280_079,h6280_07a,h6280_07b,h6280_07c,h6280_07d,h6280_07e,h6280_07f,
|
||||
h6280_080,h6280_081,h6280_082,h6280_083,h6280_084,h6280_085,h6280_086,h6280_087,
|
||||
h6280_088,h6280_089,h6280_08a,h6280_08b,h6280_08c,h6280_08d,h6280_08e,h6280_08f,
|
||||
h6280_090,h6280_091,h6280_092,h6280_093,h6280_094,h6280_095,h6280_096,h6280_097,
|
||||
h6280_098,h6280_099,h6280_09a,h6280_09b,h6280_09c,h6280_09d,h6280_09e,h6280_09f,
|
||||
h6280_0a0,h6280_0a1,h6280_0a2,h6280_0a3,h6280_0a4,h6280_0a5,h6280_0a6,h6280_0a7,
|
||||
h6280_0a8,h6280_0a9,h6280_0aa,h6280_0ab,h6280_0ac,h6280_0ad,h6280_0ae,h6280_0af,
|
||||
h6280_0b0,h6280_0b1,h6280_0b2,h6280_0b3,h6280_0b4,h6280_0b5,h6280_0b6,h6280_0b7,
|
||||
h6280_0b8,h6280_0b9,h6280_0ba,h6280_0bb,h6280_0bc,h6280_0bd,h6280_0be,h6280_0bf,
|
||||
h6280_0c0,h6280_0c1,h6280_0c2,h6280_0c3,h6280_0c4,h6280_0c5,h6280_0c6,h6280_0c7,
|
||||
h6280_0c8,h6280_0c9,h6280_0ca,h6280_0cb,h6280_0cc,h6280_0cd,h6280_0ce,h6280_0cf,
|
||||
h6280_0d0,h6280_0d1,h6280_0d2,h6280_0d3,h6280_0d4,h6280_0d5,h6280_0d6,h6280_0d7,
|
||||
h6280_0d8,h6280_0d9,h6280_0da,h6280_0db,h6280_0dc,h6280_0dd,h6280_0de,h6280_0df,
|
||||
h6280_0e0,h6280_0e1,h6280_0e2,h6280_0e3,h6280_0e4,h6280_0e5,h6280_0e6,h6280_0e7,
|
||||
h6280_0e8,h6280_0e9,h6280_0ea,h6280_0eb,h6280_0ec,h6280_0ed,h6280_0ee,h6280_0ef,
|
||||
h6280_0f0,h6280_0f1,h6280_0f2,h6280_0f3,h6280_0f4,h6280_0f5,h6280_0f6,h6280_0f7,
|
||||
h6280_0f8,h6280_0f9,h6280_0fa,h6280_0fb,h6280_0fc,h6280_0fd,h6280_0fe,h6280_0ff
|
||||
};
|
|
@ -0,0 +1,205 @@
|
|||
extern "C" {
|
||||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "emu.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
|
||||
}
|
||||
delay(20);
|
||||
}
|
||||
else {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
emu_Step();
|
||||
delay(10);
|
||||
//uint16_t bClick = emu_DebounceLocalKeys();
|
||||
//if (bClick & MASK_KEY_USER1) {
|
||||
// emu_Input(bClick);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include "AudioPlaySystem.h"
|
||||
|
||||
AudioPlaySystem mymixer;
|
||||
|
||||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin_audio(256, mymixer.snd_Mixer);
|
||||
#else
|
||||
mymixer.begin_audio(256, mymixer.snd_Mixer);
|
||||
#endif
|
||||
// sgtl5000_1.enable();
|
||||
// sgtl5000_1.volume(0.6);
|
||||
mymixer.start();
|
||||
}
|
||||
|
||||
void emu_sndPlaySound(int chan, int volume, int freq)
|
||||
{
|
||||
if (chan < 6) {
|
||||
mymixer.sound(chan, freq, volume);
|
||||
}
|
||||
/*
|
||||
Serial.print(chan);
|
||||
Serial.print(":" );
|
||||
Serial.print(volume);
|
||||
Serial.print(":" );
|
||||
Serial.println(freq);
|
||||
*/
|
||||
}
|
||||
|
||||
void emu_sndPlayBuzz(int size, int val) {
|
||||
mymixer.buzz(size,val);
|
||||
//Serial.print((val==1)?1:0);
|
||||
//Serial.print(":");
|
||||
//Serial.println(size);
|
||||
}
|
||||
#endif
|
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,79 @@
|
|||
|
||||
#include "shared.h"
|
||||
|
||||
t_vce vce;
|
||||
|
||||
void vce_w(int address, int data)
|
||||
{
|
||||
int msb = (address & 1);
|
||||
|
||||
switch(address & ~1)
|
||||
{
|
||||
case 0x404: /* Data */
|
||||
{
|
||||
if(data != vce.data[((vce.addr & 0x1FF) << 1) | (msb)])
|
||||
{
|
||||
vce.data[((vce.addr & 0x1FF) << 1) | (msb)] = data;
|
||||
|
||||
if((vce.addr & 0x0F) != 0x00)
|
||||
{
|
||||
// uint16 temp = *(uint16 *)&vce.data[(vce.addr << 1)]; // Execute error.
|
||||
uint8 temp1 = vce.data[(vce.addr << 1)];
|
||||
uint8 temp2 = vce.data[(vce.addr << 1)+1];
|
||||
uint16 temp;
|
||||
#ifndef LSB_FIRST
|
||||
// temp = (temp >> 8) | (temp << 8);
|
||||
temp = (((uint16)temp1) << 8) + (uint16)temp2;
|
||||
#else
|
||||
temp = (((uint16)temp2) << 8) + (uint16)temp1;
|
||||
#endif
|
||||
pixel[(vce.addr >> 8) & 1][(vce.addr & 0xFF)] = pixel_lut[temp];
|
||||
temp = (temp >> 1) & 0xFF;
|
||||
}
|
||||
|
||||
/* Update overscan color */
|
||||
if((vce.addr & 0x0F) == 0x00)
|
||||
{
|
||||
int n;
|
||||
uint16 temp = *(uint16 *)&vce.data[0];
|
||||
#ifndef LSB_FIRST
|
||||
temp = (temp >> 8) | (temp << 8);
|
||||
#endif
|
||||
for(n = 0; n < 0x10; n += 1)
|
||||
pixel[0][(n << 4)] = pixel_lut[temp];
|
||||
temp = (temp >> 1) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment VCE address on access to the MSB data port */
|
||||
if(msb) vce.addr += 1;
|
||||
break;
|
||||
|
||||
case 0x402: /* Address */
|
||||
if(msb)
|
||||
vce.addr = (vce.addr & 0x00FF) | ((data & 1) << 8);
|
||||
else
|
||||
vce.addr = (vce.addr & 0x0100) | (data);
|
||||
break;
|
||||
|
||||
case 0x0400: /* Control */
|
||||
if(!msb) vce.ctrl = (data & 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int vce_r(int address)
|
||||
{
|
||||
int msb = (address & 1);
|
||||
|
||||
if((address & ~1) == 0x0404)
|
||||
{
|
||||
uint8 temp = vce.data[((vce.addr & 0x1FF) << 1) | (msb)];
|
||||
if(msb) vce.addr += 1;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
return (0xFF);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef _VCE_H_
|
||||
#define _VCE_H_
|
||||
|
||||
/* Macros and defines */
|
||||
typedef struct
|
||||
{
|
||||
uint8 ctrl;
|
||||
uint8 data[0x400];
|
||||
uint16 addr;
|
||||
}t_vce;
|
||||
|
||||
/* Global data */
|
||||
extern t_vce vce;
|
||||
|
||||
/* Function prototypes */
|
||||
void vce_w(int address, int data);
|
||||
int vce_r(int address);
|
||||
|
||||
#endif /* _VCE_H_ */
|
|
@ -0,0 +1,271 @@
|
|||
|
||||
#include "shared.h"
|
||||
|
||||
#define LOG_DMA 0
|
||||
|
||||
uint32 y_offset=0;
|
||||
uint32 byr=0;
|
||||
//uint8 vram[0x10000];
|
||||
//uint16 *vramw = (uint16 *)&vram[0];
|
||||
//uint8 objram[0x200];
|
||||
//uint16 *objramw = (uint16 *)&objram[0];
|
||||
uint16 reg[0x20];
|
||||
uint8 status;
|
||||
uint8 latch;
|
||||
uint8 addr_inc;
|
||||
uint8 vram_data_latch = 0;
|
||||
uint8 dvssr_trigger = 0;
|
||||
int playfield_shift = 6;
|
||||
uint32 playfield_col_mask = 0xFF;
|
||||
uint32 playfield_row_mask = 0x1F;
|
||||
int disp_width;
|
||||
int disp_height;
|
||||
uint32 disp_nt_width;
|
||||
int old_width = 0;
|
||||
int old_height = 0;
|
||||
int playfield_shift_table[] = {6, 7, 8, 8};
|
||||
int playfield_row_mask_table[] = {0x1F, 0x3F, 0x7F, 0x7F};
|
||||
|
||||
|
||||
//uint8 bg_name_dirty[0x800];
|
||||
//uint16 bg_name_list[0x800];
|
||||
uint16 bg_list_index;
|
||||
//uint8 * bg_pattern_cache;
|
||||
|
||||
//uint16 obj_name_dirty[0x200];
|
||||
//uint16 obj_name_list[0x200];
|
||||
uint16 obj_list_index;
|
||||
//uint8 * obj_pattern_cache;
|
||||
|
||||
#define MARK_BG_DIRTY(addr) \
|
||||
{ \
|
||||
int name = (addr >> 4) & 0x7FF; \
|
||||
if(bg_name_dirty[name] == 0) \
|
||||
{ \
|
||||
bg_name_list[bg_list_index] = name; \
|
||||
bg_list_index += 1; \
|
||||
} \
|
||||
bg_name_dirty[name] |= (1 << (addr & 0x07)); \
|
||||
}
|
||||
|
||||
#define MARK_OBJ_DIRTY(addr) \
|
||||
{ \
|
||||
int name = (addr >> 6) & 0x1FF; \
|
||||
if(obj_name_dirty[name] == 0) \
|
||||
{ \
|
||||
obj_name_list[obj_list_index] = name; \
|
||||
obj_list_index += 1; \
|
||||
} \
|
||||
obj_name_dirty[name] |= (1 << (addr & 0x0F)); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Memory handlers */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int vdc_r(int offset)
|
||||
{
|
||||
uint8 temp;
|
||||
uint8 msb = (offset & 1);
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 0x0000: /* Register latch / status flags */
|
||||
temp = status;
|
||||
status = 0;
|
||||
h6280_set_irq_line(0, CLEAR_LINE);
|
||||
return (temp);
|
||||
|
||||
case 0x0002: /* Data port (LSB) */
|
||||
case 0x0003: /* Data port (MSB) */
|
||||
if(latch == 0x02)
|
||||
{
|
||||
temp = (vram[((reg[1] << 1) | (msb)) & 0xFFFF]);
|
||||
if(msb) reg[1] += addr_inc;
|
||||
return (temp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (0xFF);
|
||||
}
|
||||
|
||||
void vdc_w(int offset, int data)
|
||||
{
|
||||
uint8 msb = (offset & 1);
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 0x0000: /* Register latch / status flags */
|
||||
latch = (data & 0x1F);
|
||||
break;
|
||||
|
||||
case 0x0002: /* Data port (LSB) */
|
||||
case 0x0003: /* Data port (MSB) */
|
||||
|
||||
if(msb)
|
||||
reg[latch] = (reg[latch] & 0x00FF) | (data << 8);
|
||||
else
|
||||
reg[latch] = (reg[latch] & 0xFF00) | (data);
|
||||
|
||||
switch(latch)
|
||||
{
|
||||
case 0x02:
|
||||
if(msb)
|
||||
{
|
||||
/* Form complete VRAM word */
|
||||
uint16 vram_word = (data << 8 | vram_data_latch);
|
||||
|
||||
/* Check if data is new or not */
|
||||
if(vram_word != vramw[(reg[0] & 0x7FFF)])
|
||||
{
|
||||
/* Write data to VRAM */
|
||||
vramw[(reg[0] & 0x7FFF)] = vram_word;
|
||||
|
||||
/* Mark pattern dirty tables */
|
||||
MARK_BG_DIRTY(reg[0]);
|
||||
MARK_OBJ_DIRTY(reg[0]);
|
||||
}
|
||||
|
||||
reg[0] += addr_inc;
|
||||
}
|
||||
else
|
||||
{
|
||||
vram_data_latch = data;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
y_offset = byr = (reg[0x08] & 0x1FF);
|
||||
y_offset &= playfield_col_mask;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
if(msb) {
|
||||
static uint8 add_tbl[] = {1, 32, 64, 128};
|
||||
addr_inc = add_tbl[(data >> 3) & 3];
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
if(!msb) {
|
||||
playfield_shift = playfield_shift_table[(data >> 4) & 3];
|
||||
playfield_row_mask = playfield_row_mask_table[(data >> 4) & 3];
|
||||
playfield_col_mask = ((data >> 6) & 1) ? 0x01FF : 0x00FF;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0B:
|
||||
disp_width = (1+(reg[0x0B] & 0x3F)) << 3;
|
||||
disp_nt_width = (disp_width >> 3);
|
||||
|
||||
// if(disp_width != old_width) {
|
||||
// bitmap.viewport.ow = bitmap.viewport.w;
|
||||
// bitmap.viewport.w = old_width = disp_width;
|
||||
// bitmap.viewport.changed = 1;
|
||||
// }
|
||||
|
||||
break;
|
||||
|
||||
case 0x0D:
|
||||
disp_height = 1+(reg[0x0D] & 0x01FF);
|
||||
|
||||
// if(disp_height != old_height) {
|
||||
// bitmap.viewport.oh = bitmap.viewport.h;
|
||||
// bitmap.viewport.h = old_height = disp_height;
|
||||
// bitmap.viewport.changed = 1;
|
||||
// }
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
if(msb) vdc_do_dma();
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
if(msb) dvssr_trigger = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown routines */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int vdc_init(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void vdc_reset(void)
|
||||
{
|
||||
memset(vram, 0, 0x10000);
|
||||
memset(reg, 0, 0x20);
|
||||
status = latch = 0;
|
||||
addr_inc = 1;
|
||||
dvssr_trigger = 0;
|
||||
|
||||
playfield_shift = 6;
|
||||
playfield_row_mask = 0x1f;
|
||||
playfield_col_mask = 0xff;
|
||||
|
||||
memset(bg_name_dirty, 0, 0x800);
|
||||
memset(bg_name_list, 0, 0x800*2);
|
||||
memset(bg_pattern_cache, 0, BG_CACHE_SIZE);
|
||||
bg_list_index = 0;
|
||||
|
||||
memset(obj_name_dirty, 0, 0x200*2);
|
||||
memset(obj_name_list, 0, 0x200*2);
|
||||
memset(obj_pattern_cache, 0, OBJ_CACHE_SIZE);
|
||||
obj_list_index = 0;
|
||||
}
|
||||
|
||||
|
||||
void vdc_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void vdc_do_dma(void)
|
||||
{
|
||||
int did = (reg[0x0F] >> 3) & 1;
|
||||
int sid = (reg[0x0F] >> 2) & 1;
|
||||
int dvc = (reg[0x0F] >> 1) & 1;
|
||||
int sour = (reg[0x10] & 0x7FFF);
|
||||
int desr = (reg[0x11] & 0x7FFF);
|
||||
int lenr = (reg[0x12] & 0x7FFF);
|
||||
|
||||
#if LOG_DMA
|
||||
error("DMA S:%04X%c D:%04X%c L:%04X\n", sour, (sid) ? '-' : '+', desr, (did) ? '-' : '+', lenr);
|
||||
#endif
|
||||
|
||||
/* Do VRAM -> VRAM transfer and update pattern caches */
|
||||
do {
|
||||
uint16 temp = vramw[(sour & 0x7FFF)];
|
||||
|
||||
if(temp != vramw[(desr & 0x7FFF)])
|
||||
{
|
||||
vramw[(desr & 0x7FFF)] = temp;
|
||||
MARK_BG_DIRTY(desr);
|
||||
MARK_OBJ_DIRTY(desr);
|
||||
}
|
||||
|
||||
sour = (sid) ? (sour - 1) : (sour + 1);
|
||||
desr = (did) ? (desr - 1) : (desr + 1);
|
||||
} while (lenr--);
|
||||
|
||||
/* Set VRAM -> VRAM transfer completed flag */
|
||||
status |= STATUS_DV;
|
||||
|
||||
/* Cause IRQ1 if enabled */
|
||||
if(dvc)
|
||||
{
|
||||
h6280_set_irq_line(0, ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#ifndef _VDC_H_
|
||||
#define _VDC_H_
|
||||
|
||||
/* Status register flags */
|
||||
#define STATUS_BSY (0x40) /* Memory access busy */
|
||||
#define STATUS_VD (0x20) /* Vertical blanking */
|
||||
#define STATUS_DV (0x10) /* VRAM -> VRAM DMA */
|
||||
#define STATUS_DS (0x08) /* VRAM -> SATB DMA */
|
||||
#define STATUS_RR (0x04) /* Line interrupt */
|
||||
#define STATUS_OR (0x02) /* Sprite overflow */
|
||||
#define STATUS_CR (0x01) /* Sprite collision */
|
||||
|
||||
|
||||
/* Global data */
|
||||
extern uint32 y_offset;
|
||||
extern uint32 byr;
|
||||
//extern uint8 vram[0x10000];
|
||||
//extern uint16 *vramw;
|
||||
//extern uint8 objram[0x200];
|
||||
//extern uint16 *objramw;
|
||||
extern uint16 reg[0x20];
|
||||
extern uint8 status;
|
||||
extern uint8 latch;
|
||||
extern uint8 addr_inc;
|
||||
extern uint8 vram_data_latch;
|
||||
extern uint8 dvssr_trigger;
|
||||
extern int playfield_shift;
|
||||
extern uint32 playfield_col_mask;
|
||||
extern uint32 playfield_row_mask;
|
||||
extern int disp_width;
|
||||
extern int disp_height;
|
||||
extern uint32 disp_nt_width;
|
||||
extern int old_width;
|
||||
extern int old_height;
|
||||
extern int playfield_shift_table[];
|
||||
extern int playfield_row_mask_table[];
|
||||
//extern uint8 bg_name_dirty[0x800];
|
||||
//extern uint16 bg_name_list[0x800];
|
||||
extern uint16 bg_list_index;
|
||||
//extern uint8 * bg_pattern_cache;
|
||||
//extern uint16 obj_name_dirty[0x200];
|
||||
//extern uint16 obj_name_list[0x200];
|
||||
extern uint16 obj_list_index;
|
||||
//extern uint8 * obj_pattern_cache;
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
int vdc_r(int offset);
|
||||
void vdc_w(int offset, int data);
|
||||
int vdc_init(void);
|
||||
void vdc_reset(void);
|
||||
void vdc_shutdown(void);
|
||||
void vdc_do_dma(void);
|
||||
void vdc_ctrl_w(int data);
|
||||
int vdc_ctrl_r(void);
|
||||
void vdc_data_w(int offset, int data);
|
||||
int vdc_data_r(int offset);
|
||||
|
||||
#endif /* _VDC_H_ */
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Wrapping class to extend VGA_T4 to TFT_T_DMA
|
||||
*/
|
||||
|
||||
#ifndef _VGA_T_DMAH_
|
||||
#define _VGA_T_DMAH_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <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
|
Ładowanie…
Reference in New Issue