add PCE emu to T-COMPUTER

pull/16/head
jean-marcharvengt 2022-03-06 16:01:24 +01:00
rodzic 0a299294cc
commit d35010f31d
41 zmienionych plików z 62450 dodań i 0 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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_ */

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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);
}
}
/*--------------------------------------------------------------------------*/

Wyświetl plik

@ -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_ */

Wyświetl plik

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