mirror of
https://github.com/libretro/beetle-pce-fast-libretro.git
synced 2025-02-21 07:41:29 +00:00
171 lines
3.4 KiB
C
171 lines
3.4 KiB
C
#ifndef _HuC6280H
|
|
#define _HuC6280H
|
|
|
|
#define HUC6280_CRAZY_VERSION
|
|
//#define HUC6280_EXTRA_CRAZY
|
|
|
|
#define HUC6280_LAZY_FLAGS
|
|
|
|
#include <retro_inline.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct HuC6280
|
|
{
|
|
#ifdef HUC6280_CRAZY_VERSION
|
|
uintptr_t PC, PC_base;
|
|
#else
|
|
uint16 PC;
|
|
#endif
|
|
|
|
uint8 A,X,Y,S,P,mooPI;
|
|
uint8 IRQMask, IRQMaskDelay;
|
|
#ifdef HUC6280_LAZY_FLAGS
|
|
uint32 ZNFlags;
|
|
#endif
|
|
uint8 MPR[9]; // 8, + 1 for PC overflow from $ffff to $10000
|
|
uint8 timer_status;
|
|
uintptr_t FastPageR[9];
|
|
uint8 *Page1;
|
|
//uint8 *PAGE1_W;
|
|
//const uint8 *PAGE1_R;
|
|
|
|
uint32 IRQlow; /* Simulated IRQ pin held low(or is it high?).
|
|
And other junk hooked on for speed reasons.*/
|
|
int32 timestamp;
|
|
|
|
int32 timer_value, timer_load;
|
|
int32 timer_next_timestamp;
|
|
|
|
uint32 in_block_move;
|
|
uint16 bmt_src, bmt_dest, bmt_length;
|
|
uint32 bmt_alternate;
|
|
#define IBM_TIA 1
|
|
#define IBM_TAI 2
|
|
#define IBM_TDD 3
|
|
#define IBM_TII 4
|
|
#define IBM_TIN 5
|
|
|
|
int32 previous_next_user_event;
|
|
|
|
uint8 *FastMap[0x100];
|
|
|
|
readfunc PCERead[0x100];
|
|
writefunc PCEWrite[0x100];
|
|
};
|
|
|
|
void HuC6280_Run(int32 cycles);
|
|
void HuC6280_ResetTS(void);
|
|
|
|
extern struct HuC6280 HuCPU;
|
|
|
|
#define N_FLAG 0x80
|
|
#define V_FLAG 0x40
|
|
#define T_FLAG 0x20
|
|
#define B_FLAG 0x10
|
|
#define D_FLAG 0x08
|
|
#define I_FLAG 0x04
|
|
#define Z_FLAG 0x02
|
|
#define C_FLAG 0x01
|
|
|
|
#define NTSC_CPU 1789772.7272727272727272
|
|
#define PAL_CPU 1662607.125
|
|
|
|
#define MDFN_IQIRQ1 0x002
|
|
#define MDFN_IQIRQ2 0x001
|
|
#define MDFN_IQTIMER 0x004
|
|
#define MDFN_IQRESET 0x020
|
|
|
|
void HuC6280_Init(void) MDFN_COLD;
|
|
void HuC6280_Reset(void) MDFN_COLD;
|
|
void HuC6280_Power(void) MDFN_COLD;
|
|
|
|
static INLINE void HuC6280_IRQBegin(int w)
|
|
{
|
|
HuCPU.IRQlow |= w;
|
|
}
|
|
|
|
static INLINE void HuC6280_IRQEnd(int w)
|
|
{
|
|
HuCPU.IRQlow &= ~w;
|
|
}
|
|
|
|
int HuC6280_StateAction(StateMem *sm, int load, int data_only);
|
|
|
|
static INLINE void HuC6280_StealCycle(void)
|
|
{
|
|
HuCPU.timestamp++;
|
|
}
|
|
|
|
static INLINE uint8 HuC6280_TimerRead(unsigned int A)
|
|
{
|
|
#if 0
|
|
return(HuCPU.timer_value | (PCEIODataBuffer & 0x80));
|
|
#endif
|
|
|
|
uint8 tvr = HuCPU.timer_value;
|
|
|
|
if(HuCPU.timer_next_timestamp == HuCPU.timestamp)
|
|
tvr = (tvr - 1) & 0x7F;
|
|
|
|
return(tvr | (PCEIODataBuffer & 0x80));
|
|
}
|
|
|
|
static INLINE void HuC6280_TimerWrite(unsigned int A, uint8 V)
|
|
{
|
|
switch(A & 1)
|
|
{
|
|
case 0: HuCPU.timer_load = (V & 0x7F); break;
|
|
case 1: if(V & 1) // Enable counter
|
|
{
|
|
if(HuCPU.timer_status == 0)
|
|
{
|
|
HuCPU.timer_next_timestamp = HuCPU.timestamp + 1024;
|
|
HuCPU.timer_value = HuCPU.timer_load;
|
|
}
|
|
}
|
|
HuCPU.timer_status = V & 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static INLINE uint8 HuC6280_IRQStatusRead(unsigned int A)
|
|
{
|
|
if(!(A & 2))
|
|
return(PCEIODataBuffer);
|
|
|
|
switch(A & 1)
|
|
{
|
|
case 0:
|
|
HuC6280_IRQEnd(MDFN_IQTIMER);
|
|
return(HuCPU.IRQMask ^ 0x7);
|
|
case 1:
|
|
{
|
|
int status = 0;
|
|
if(HuCPU.IRQlow & MDFN_IQIRQ1) status |= 2;
|
|
if(HuCPU.IRQlow & MDFN_IQIRQ2) status |= 1;
|
|
if(HuCPU.IRQlow & MDFN_IQTIMER) status |= 4;
|
|
return(status | (PCEIODataBuffer & ~(1 | 2 | 4)));
|
|
}
|
|
}
|
|
return(PCEIODataBuffer);
|
|
}
|
|
|
|
static INLINE void HuC6280_IRQStatusWrite(unsigned int A, uint8 V)
|
|
{
|
|
if(!(A & 2)) return;
|
|
switch(A & 1)
|
|
{
|
|
case 0: HuCPU.IRQMask = (V & 0x7) ^ 0x7; break;
|
|
case 1: HuC6280_IRQEnd(MDFN_IQTIMER); break;
|
|
}
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|