Original Supermodel code moved to tags/Original.

This commit is contained in:
Bart Trzynadlowski 2011-04-24 01:02:31 +00:00
parent ac14fc95e4
commit cfff37f170
5 changed files with 0 additions and 4270 deletions

View file

@ -1,808 +0,0 @@
/* IBM/Motorola PowerPC 4xx/6xx Emulator */
#include "model3.h"
#include "ppc.h"
void ppc603_exception(int exception);
void ppc603_check_interrupts(void);
#define RD ((op >> 21) & 0x1F)
#define RT ((op >> 21) & 0x1f)
#define RS ((op >> 21) & 0x1f)
#define RA ((op >> 16) & 0x1f)
#define RB ((op >> 11) & 0x1f)
#define RC ((op >> 6) & 0x1f)
#define MB ((op >> 6) & 0x1f)
#define ME ((op >> 1) & 0x1f)
#define SH ((op >> 11) & 0x1f)
#define BO ((op >> 21) & 0x1f)
#define BI ((op >> 16) & 0x1f)
#define CRFD ((op >> 23) & 0x7)
#define CRFA ((op >> 18) & 0x7)
#define FXM ((op >> 12) & 0xff)
#define SPR (((op >> 16) & 0x1f) | ((op >> 6) & 0x3e0))
#define SIMM16 (INT32)(INT16)(op & 0xffff)
#define UIMM16 (UINT32)(op & 0xffff)
#define RCBIT (op & 0x1)
#define OEBIT (op & 0x400)
#define AABIT (op & 0x2)
#define LKBIT (op & 0x1)
#define REG(x) (ppc.r[x])
#define LR (ppc.lr)
#define CTR (ppc.ctr)
#define XER (ppc.xer)
#define CR(x) (ppc.cr[x])
#define MSR (ppc.msr)
#define SRR0 (ppc.srr0)
#define SRR1 (ppc.srr1)
#define SRR2 (ppc.srr2)
#define SRR3 (ppc.srr3)
#define EVPR (ppc.evpr)
#define EXIER (ppc.exier)
#define EXISR (ppc.exisr)
#define DEC (ppc.dec)
// Stuff added for the 6xx
#define FPR(x) (ppc.fpr[x])
#define FM ((op >> 17) & 0xFF)
#define SPRF (((op >> 6) & 0x3E0) | ((op >> 16) & 0x1F))
#define CHECK_SUPERVISOR() \
if((ppc.msr & 0x4000) != 0){ \
}
#define CHECK_FPU_AVAILABLE() \
if((ppc.msr & 0x2000) == 0){ \
}
static UINT32 ppc_field_xlat[256];
#define FPSCR_FX 0x80000000
#define FPSCR_FEX 0x40000000
#define FPSCR_VX 0x20000000
#define FPSCR_OX 0x10000000
#define FPSCR_UX 0x08000000
#define FPSCR_ZX 0x04000000
#define FPSCR_XX 0x02000000
#define BITMASK_0(n) (UINT32)(((UINT64)1 << n) - 1)
#define CRBIT(x) ((ppc.cr[x / 4] & (1 << (3 - (x % 4)))) ? 1 : 0)
#define _BIT(n) (1 << (n))
#define GET_ROTATE_MASK(mb,me) (ppc_rotate_mask[mb][me])
#define ADD_CA(r,a,b) ((UINT32)r < (UINT32)a)
#define SUB_CA(r,a,b) (!((UINT32)a < (UINT32)b))
#define ADD_OV(r,a,b) ((~((a) ^ (b)) & ((a) ^ (r))) & 0x80000000)
#define SUB_OV(r,a,b) (( ((a) ^ (b)) & ((a) ^ (r))) & 0x80000000)
#define XER_SO 0x80000000
#define XER_OV 0x40000000
#define XER_CA 0x20000000
#define MSR_POW 0x00040000 /* Power Management Enable */
#define MSR_WE 0x00040000
#define MSR_CE 0x00020000
#define MSR_ILE 0x00010000 /* Interrupt Little Endian Mode */
#define MSR_EE 0x00008000 /* External Interrupt Enable */
#define MSR_PR 0x00004000 /* Problem State */
#define MSR_FP 0x00002000 /* Floating Point Available */
#define MSR_ME 0x00001000 /* Machine Check Enable */
#define MSR_FE0 0x00000800
#define MSR_SE 0x00000400 /* Single Step Trace Enable */
#define MSR_BE 0x00000200 /* Branch Trace Enable */
#define MSR_DE 0x00000200
#define MSR_FE1 0x00000100
#define MSR_IP 0x00000040 /* Interrupt Prefix */
#define MSR_IR 0x00000020 /* Instruction Relocate */
#define MSR_DR 0x00000010 /* Data Relocate */
#define MSR_PE 0x00000008
#define MSR_PX 0x00000004
#define MSR_RI 0x00000002 /* Recoverable Interrupt Enable */
#define MSR_LE 0x00000001
#define TSR_ENW 0x80000000
#define TSR_WIS 0x40000000
#define BYTE_REVERSE16(x) ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00))
#define BYTE_REVERSE32(x) ((((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
typedef union {
UINT64 id;
double fd;
} FPR;
typedef union {
UINT32 i;
float f;
} FPR32;
typedef struct {
UINT32 u;
UINT32 l;
} BATENT;
typedef struct {
UINT32 r[32];
UINT32 pc;
UINT32 npc;
UINT32 *op;
UINT32 lr;
UINT32 ctr;
UINT32 xer;
UINT32 msr;
UINT8 cr[8];
UINT32 pvr;
UINT32 srr0;
UINT32 srr1;
UINT32 srr2;
UINT32 srr3;
UINT32 hid0;
UINT32 hid1;
UINT32 hid2;
UINT32 sdr1;
UINT32 sprg[4];
UINT32 dsisr;
UINT32 dar;
UINT32 ear;
UINT32 dmiss;
UINT32 dcmp;
UINT32 hash1;
UINT32 hash2;
UINT32 imiss;
UINT32 icmp;
UINT32 rpa;
BATENT ibat[4];
BATENT dbat[4];
UINT32 evpr;
UINT32 exier;
UINT32 exisr;
UINT32 bear;
UINT32 besr;
UINT32 iocr;
UINT32 br[8];
UINT32 iabr;
UINT32 esr;
UINT32 iccr;
UINT32 dccr;
UINT32 pit;
UINT32 pit_counter;
UINT32 pit_int_enable;
UINT32 tsr;
UINT32 dbsr;
UINT32 sgr;
UINT32 pid;
int reserved;
UINT32 reserved_address;
int interrupt_pending;
int external_int;
UINT64 tb; /* 56-bit timebase register */
int (*irq_callback)(int irqline);
PPC_FETCH_REGION cur_fetch;
PPC_FETCH_REGION * fetch;
// STUFF added for the 6xx series
UINT32 dec, dec_frac;
UINT32 fpscr;
FPR fpr[32];
UINT32 sr[16];
#if HAS_PPC603
int is603;
#endif
#if HAS_PPC602
int is602;
#endif
} PPC_REGS;
typedef struct {
int code;
int subcode;
void (* handler)(UINT32);
} PPC_OPCODE;
static int ppc_icount;
static int ppc_tb_base_icount;
static int ppc_dec_base_icount;
static int ppc_dec_trigger_cycle;
static int bus_freq_multiplier = 1;
static PPC_REGS ppc;
static UINT32 ppc_rotate_mask[32][32];
static void ppc_change_pc(UINT32 newpc)
{
UINT i;
if (ppc.cur_fetch.start <= newpc && newpc <= ppc.cur_fetch.end)
{
ppc.op = (UINT32 *)((UINT32)ppc.cur_fetch.ptr + (UINT32)(newpc - ppc.cur_fetch.start));
return;
}
for(i = 0; ppc.fetch[i].ptr != NULL; i++)
{
if (ppc.fetch[i].start <= newpc && newpc <= ppc.fetch[i].end)
{
ppc.cur_fetch.start = ppc.fetch[i].start;
ppc.cur_fetch.end = ppc.fetch[i].end;
ppc.cur_fetch.ptr = ppc.fetch[i].ptr;
ppc.op = (UINT32 *)((UINT32)ppc.cur_fetch.ptr + (UINT32)(newpc - ppc.cur_fetch.start));
return;
}
}
error("Invalid PC %08X, previous PC %08X\n", newpc, ppc.pc);
}
INLINE UINT8 READ8(UINT32 address)
{
return m3_ppc_read_8(address);
}
INLINE UINT16 READ16(UINT32 address)
{
return m3_ppc_read_16(address);
}
INLINE UINT32 READ32(UINT32 address)
{
return m3_ppc_read_32(address);
}
INLINE UINT64 READ64(UINT32 address)
{
return m3_ppc_read_64(address);
}
INLINE void WRITE8(UINT32 address, UINT8 data)
{
m3_ppc_write_8(address, data);
}
INLINE void WRITE16(UINT32 address, UINT16 data)
{
m3_ppc_write_16(address, data);
}
INLINE void WRITE32(UINT32 address, UINT32 data)
{
m3_ppc_write_32(address, data);
}
INLINE void WRITE64(UINT32 address, UINT64 data)
{
m3_ppc_write_64(address, data);
}
/*********************************************************************/
INLINE void SET_CR0(INT32 rd)
{
if( rd < 0 ) {
CR(0) = 0x8;
} else if( rd > 0 ) {
CR(0) = 0x4;
} else {
CR(0) = 0x2;
}
if( XER & XER_SO )
CR(0) |= 0x1;
}
INLINE void SET_CR1(void)
{
CR(1) = (ppc.fpscr >> 28) & 0xf;
}
INLINE void SET_ADD_OV(UINT32 rd, UINT32 ra, UINT32 rb)
{
if( ADD_OV(rd, ra, rb) )
XER |= XER_SO | XER_OV;
else
XER &= ~XER_OV;
}
INLINE void SET_SUB_OV(UINT32 rd, UINT32 ra, UINT32 rb)
{
if( SUB_OV(rd, ra, rb) )
XER |= XER_SO | XER_OV;
else
XER &= ~XER_OV;
}
INLINE void SET_ADD_CA(UINT32 rd, UINT32 ra, UINT32 rb)
{
if( ADD_CA(rd, ra, rb) )
XER |= XER_CA;
else
XER &= ~XER_CA;
}
INLINE void SET_SUB_CA(UINT32 rd, UINT32 ra, UINT32 rb)
{
if( SUB_CA(rd, ra, rb) )
XER |= XER_CA;
else
XER &= ~XER_CA;
}
INLINE UINT32 check_condition_code(UINT32 bo, UINT32 bi)
{
UINT32 ctr_ok;
UINT32 condition_ok;
UINT32 bo0 = (bo & 0x10) ? 1 : 0;
UINT32 bo1 = (bo & 0x08) ? 1 : 0;
UINT32 bo2 = (bo & 0x04) ? 1 : 0;
UINT32 bo3 = (bo & 0x02) ? 1 : 0;
if( bo2 == 0 )
--CTR;
ctr_ok = bo2 | ((CTR != 0) ^ bo3);
condition_ok = bo0 | (CRBIT(bi) ^ (~bo1 & 0x1));
return ctr_ok && condition_ok;
}
INLINE UINT64 ppc_read_timebase(void)
{
int cycles = ppc_tb_base_icount - ppc_icount;
// timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
return ppc.tb + (cycles / 4);
}
INLINE void ppc_write_timebase_l(UINT32 tbl)
{
ppc_tb_base_icount = ppc_icount;
ppc.tb &= ~0xffffffff;
ppc.tb |= tbl;
}
INLINE void ppc_write_timebase_h(UINT32 tbh)
{
ppc_tb_base_icount = ppc_icount;
ppc.tb &= 0xffffffff;
ppc.tb |= (UINT64)(tbh) << 32;
}
INLINE UINT32 read_decrementer(void)
{
int cycles = ppc_dec_base_icount - ppc_icount;
// decrementer is decremented once every four bus clock cycles, so adjust the cycles accordingly
return DEC - (cycles / (bus_freq_multiplier * 2));
}
INLINE void write_decrementer(UINT32 value)
{
ppc_dec_base_icount = ppc_icount + (ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2);
DEC = value;
// check if decrementer exception occurs during execution
if ((UINT32)(DEC - (ppc_icount / (bus_freq_multiplier * 2))) > (UINT32)(DEC))
{
ppc_dec_trigger_cycle = ((ppc_icount / (bus_freq_multiplier * 2)) - DEC) * 4;
}
else
{
ppc_dec_trigger_cycle = 0x7fffffff;
}
printf("DEC = %08X at %08X\n", value, ppc.pc);
}
/*********************************************************************/
INLINE void ppc_set_spr(int spr, UINT32 value)
{
switch (spr)
{
case SPR_LR: LR = value; return;
case SPR_CTR: CTR = value; return;
case SPR_XER: XER = value; return;
case SPR_SRR0: ppc.srr0 = value; return;
case SPR_SRR1: ppc.srr1 = value; return;
case SPR_SPRG0: ppc.sprg[0] = value; return;
case SPR_SPRG1: ppc.sprg[1] = value; return;
case SPR_SPRG2: ppc.sprg[2] = value; return;
case SPR_SPRG3: ppc.sprg[3] = value; return;
case SPR_PVR: return;
case SPR603E_DEC:
if(((value & 0x80000000) && !(DEC & 0x80000000)) || value == 0)
{
/* trigger interrupt */
ppc.interrupt_pending |= 0x2;
ppc603_check_interrupts();
}
write_decrementer(value);
return;
case SPR603E_TBL_W:
case SPR603E_TBL_R: // special 603e case
ppc_write_timebase_l(value);
return;
case SPR603E_TBU_R:
case SPR603E_TBU_W: // special 603e case
ppc_write_timebase_h(value);
return;
case SPR603E_HID0: ppc.hid0 = value; return;
case SPR603E_HID1: ppc.hid1 = value; return;
case SPR603E_HID2: ppc.hid2 = value; return;
case SPR603E_DSISR: ppc.dsisr = value; return;
case SPR603E_DAR: ppc.dar = value; return;
case SPR603E_EAR: ppc.ear = value; return;
case SPR603E_DMISS: ppc.dmiss = value; return;
case SPR603E_DCMP: ppc.dcmp = value; return;
case SPR603E_HASH1: ppc.hash1 = value; return;
case SPR603E_HASH2: ppc.hash2 = value; return;
case SPR603E_IMISS: ppc.imiss = value; return;
case SPR603E_ICMP: ppc.icmp = value; return;
case SPR603E_RPA: ppc.rpa = value; return;
case SPR603E_IBAT0L: ppc.ibat[0].l = value; return;
case SPR603E_IBAT0U: ppc.ibat[0].u = value; return;
case SPR603E_IBAT1L: ppc.ibat[1].l = value; return;
case SPR603E_IBAT1U: ppc.ibat[1].u = value; return;
case SPR603E_IBAT2L: ppc.ibat[2].l = value; return;
case SPR603E_IBAT2U: ppc.ibat[2].u = value; return;
case SPR603E_IBAT3L: ppc.ibat[3].l = value; return;
case SPR603E_IBAT3U: ppc.ibat[3].u = value; return;
case SPR603E_DBAT0L: ppc.dbat[0].l = value; return;
case SPR603E_DBAT0U: ppc.dbat[0].u = value; return;
case SPR603E_DBAT1L: ppc.dbat[1].l = value; return;
case SPR603E_DBAT1U: ppc.dbat[1].u = value; return;
case SPR603E_DBAT2L: ppc.dbat[2].l = value; return;
case SPR603E_DBAT2U: ppc.dbat[2].u = value; return;
case SPR603E_DBAT3L: ppc.dbat[3].l = value; return;
case SPR603E_DBAT3U: ppc.dbat[3].u = value; return;
case SPR603E_SDR1:
ppc.sdr1 = value;
return;
case SPR603E_IABR: ppc.iabr = value; return;
}
error("ppc: set_spr: unknown spr %d (%03X) !", spr, spr);
}
INLINE UINT32 ppc_get_spr(int spr)
{
switch(spr)
{
case SPR_LR: return LR;
case SPR_CTR: return CTR;
case SPR_XER: return XER;
case SPR_SRR0: return ppc.srr0;
case SPR_SRR1: return ppc.srr1;
case SPR_SPRG0: return ppc.sprg[0];
case SPR_SPRG1: return ppc.sprg[1];
case SPR_SPRG2: return ppc.sprg[2];
case SPR_SPRG3: return ppc.sprg[3];
case SPR_PVR: return ppc.pvr;
case SPR603E_TBL_R:
error("ppc: get_spr: TBL_R ");
break;
case SPR603E_TBU_R:
error("ppc: get_spr: TBU_R ");
break;
case SPR603E_TBL_W: return (UINT32)(ppc_read_timebase());
case SPR603E_TBU_W: return (UINT32)(ppc_read_timebase() >> 32);
case SPR603E_HID0: return ppc.hid0;
case SPR603E_HID1: return ppc.hid1;
case SPR603E_HID2: return ppc.hid2;
case SPR603E_DEC: return read_decrementer();
case SPR603E_SDR1: return ppc.sdr1;
case SPR603E_DSISR: return ppc.dsisr;
case SPR603E_DAR: return ppc.dar;
case SPR603E_EAR: return ppc.ear;
case SPR603E_DMISS: return ppc.dmiss;
case SPR603E_DCMP: return ppc.dcmp;
case SPR603E_HASH1: return ppc.hash1;
case SPR603E_HASH2: return ppc.hash2;
case SPR603E_IMISS: return ppc.imiss;
case SPR603E_ICMP: return ppc.icmp;
case SPR603E_RPA: return ppc.rpa;
case SPR603E_IBAT0L: return ppc.ibat[0].l;
case SPR603E_IBAT0U: return ppc.ibat[0].u;
case SPR603E_IBAT1L: return ppc.ibat[1].l;
case SPR603E_IBAT1U: return ppc.ibat[1].u;
case SPR603E_IBAT2L: return ppc.ibat[2].l;
case SPR603E_IBAT2U: return ppc.ibat[2].u;
case SPR603E_IBAT3L: return ppc.ibat[3].l;
case SPR603E_IBAT3U: return ppc.ibat[3].u;
case SPR603E_DBAT0L: return ppc.dbat[0].l;
case SPR603E_DBAT0U: return ppc.dbat[0].u;
case SPR603E_DBAT1L: return ppc.dbat[1].l;
case SPR603E_DBAT1U: return ppc.dbat[1].u;
case SPR603E_DBAT2L: return ppc.dbat[2].l;
case SPR603E_DBAT2U: return ppc.dbat[2].u;
case SPR603E_DBAT3L: return ppc.dbat[3].l;
case SPR603E_DBAT3U: return ppc.dbat[3].u;
}
error("ppc: get_spr: unknown spr %d (%03X) !", spr, spr);
return 0;
}
INLINE void ppc_set_msr(UINT32 value)
{
if( value & (MSR_ILE | MSR_LE) )
error("ppc: set_msr: little_endian mode not supported !");
MSR = value;
ppc603_check_interrupts();
}
INLINE UINT32 ppc_get_msr(void)
{
return MSR;
}
INLINE void ppc_set_cr(UINT32 value)
{
CR(0) = (value >> 28) & 0xf;
CR(1) = (value >> 24) & 0xf;
CR(2) = (value >> 20) & 0xf;
CR(3) = (value >> 16) & 0xf;
CR(4) = (value >> 12) & 0xf;
CR(5) = (value >> 8) & 0xf;
CR(6) = (value >> 4) & 0xf;
CR(7) = (value >> 0) & 0xf;
}
INLINE UINT32 ppc_get_cr(void)
{
return CR(0) << 28 | CR(1) << 24 | CR(2) << 20 | CR(3) << 16 | CR(4) << 12 | CR(5) << 8 | CR(6) << 4 | CR(7);
}
/***********************************************************************/
static void (* optable19[1024])(UINT32);
static void (* optable31[1024])(UINT32);
static void (* optable59[1024])(UINT32);
static void (* optable63[1024])(UINT32);
static void (* optable[64])(UINT32);
#include "ppc603.c"
/********************************************************************/
#include "ppc_ops.c"
#include "ppc_ops.h"
/* Initialization and shutdown */
void ppc_base_init(void)
{
int i,j;
memset(&ppc, 0, sizeof(ppc));
for( i=0; i < 64; i++ ) {
optable[i] = ppc_invalid;
}
for( i=0; i < 1024; i++ ) {
optable19[i] = ppc_invalid;
optable31[i] = ppc_invalid;
optable59[i] = ppc_invalid;
optable63[i] = ppc_invalid;
}
/* Fill the opcode tables */
for( i=0; i < (sizeof(ppc_opcode_common) / sizeof(PPC_OPCODE)); i++ ) {
switch(ppc_opcode_common[i].code)
{
case 19:
optable19[ppc_opcode_common[i].subcode] = ppc_opcode_common[i].handler;
break;
case 31:
optable31[ppc_opcode_common[i].subcode] = ppc_opcode_common[i].handler;
break;
case 59:
case 63:
break;
default:
optable[ppc_opcode_common[i].code] = ppc_opcode_common[i].handler;
}
}
/* Calculate rotate mask table */
for( i=0; i < 32; i++ ) {
for( j=0; j < 32; j++ ) {
UINT32 mask;
int mb = i;
int me = j;
mask = ((UINT32)0xFFFFFFFF >> mb) ^ ((me >= 31) ? 0 : ((UINT32)0xFFFFFFFF >> (me + 1)));
if( mb > me )
mask = ~mask;
ppc_rotate_mask[i][j] = mask;
}
}
}
void ppc_init(const PPC_CONFIG *config)
{
int pll_config = 0;
float multiplier;
int i ;
ppc_base_init() ;
optable[48] = ppc_lfs;
optable[49] = ppc_lfsu;
optable[50] = ppc_lfd;
optable[51] = ppc_lfdu;
optable[52] = ppc_stfs;
optable[53] = ppc_stfsu;
optable[54] = ppc_stfd;
optable[55] = ppc_stfdu;
optable31[631] = ppc_lfdux;
optable31[599] = ppc_lfdx;
optable31[567] = ppc_lfsux;
optable31[535] = ppc_lfsx;
optable31[595] = ppc_mfsr;
optable31[659] = ppc_mfsrin;
optable31[371] = ppc_mftb;
optable31[210] = ppc_mtsr;
optable31[242] = ppc_mtsrin;
optable31[758] = ppc_dcba;
optable31[759] = ppc_stfdux;
optable31[727] = ppc_stfdx;
optable31[983] = ppc_stfiwx;
optable31[695] = ppc_stfsux;
optable31[663] = ppc_stfsx;
optable31[370] = ppc_tlbia;
optable31[306] = ppc_tlbie;
optable31[566] = ppc_tlbsync;
optable31[310] = ppc_eciwx;
optable31[438] = ppc_ecowx;
optable63[264] = ppc_fabsx;
optable63[21] = ppc_faddx;
optable63[32] = ppc_fcmpo;
optable63[0] = ppc_fcmpu;
optable63[14] = ppc_fctiwx;
optable63[15] = ppc_fctiwzx;
optable63[18] = ppc_fdivx;
optable63[72] = ppc_fmrx;
optable63[136] = ppc_fnabsx;
optable63[40] = ppc_fnegx;
optable63[12] = ppc_frspx;
optable63[26] = ppc_frsqrtex;
optable63[22] = ppc_fsqrtx;
optable63[20] = ppc_fsubx;
optable63[583] = ppc_mffsx;
optable63[70] = ppc_mtfsb0x;
optable63[38] = ppc_mtfsb1x;
optable63[711] = ppc_mtfsfx;
optable63[134] = ppc_mtfsfix;
optable63[64] = ppc_mcrfs;
optable59[21] = ppc_faddsx;
optable59[18] = ppc_fdivsx;
optable59[24] = ppc_fresx;
optable59[22] = ppc_fsqrtsx;
optable59[20] = ppc_fsubsx;
for(i = 0; i < 32; i++)
{
optable63[i * 32 | 29] = ppc_fmaddx;
optable63[i * 32 | 28] = ppc_fmsubx;
optable63[i * 32 | 25] = ppc_fmulx;
optable63[i * 32 | 31] = ppc_fnmaddx;
optable63[i * 32 | 30] = ppc_fnmsubx;
optable63[i * 32 | 23] = ppc_fselx;
optable59[i * 32 | 29] = ppc_fmaddsx;
optable59[i * 32 | 28] = ppc_fmsubsx;
optable59[i * 32 | 25] = ppc_fmulsx;
optable59[i * 32 | 31] = ppc_fnmaddsx;
optable59[i * 32 | 30] = ppc_fnmsubsx;
}
for(i = 0; i < 256; i++)
{
ppc_field_xlat[i] =
((i & 0x80) ? 0xF0000000 : 0) |
((i & 0x40) ? 0x0F000000 : 0) |
((i & 0x20) ? 0x00F00000 : 0) |
((i & 0x10) ? 0x000F0000 : 0) |
((i & 0x08) ? 0x0000F000 : 0) |
((i & 0x04) ? 0x00000F00 : 0) |
((i & 0x02) ? 0x000000F0 : 0) |
((i & 0x01) ? 0x0000000F : 0);
}
ppc.pvr = config->pvr;
multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
(float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
bus_freq_multiplier = (int)(multiplier * 2);
switch(config->pvr)
{
case PPC_MODEL_603E: pll_config = mpc603e_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
case PPC_MODEL_603EV: pll_config = mpc603ev_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
case PPC_MODEL_603R: pll_config = mpc603r_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
default: break;
}
if (pll_config == -1)
{
error("PPC: Invalid bus/multiplier combination (bus frequency = %d, multiplier = %1.1f)", config->bus_frequency, multiplier);
}
ppc.hid1 = pll_config << 28;
}
void ppc_shutdown(void)
{
}
void ppc_set_irq_line(int irqline)
{
ppc.interrupt_pending |= 0x1;
ppc603_check_interrupts();
}
UINT32 ppc_get_pc(void)
{
return ppc.pc;
}
void ppc_set_fetch(PPC_FETCH_REGION * fetch)
{
ppc.fetch = fetch;
}

View file

@ -1,314 +0,0 @@
#ifndef _PPC_H
#define _PPC_H
#define SPR_XER 1 /* Fixed Point Exception Register Read / Write */
#define SPR_LR 8 /* Link Register Read / Write */
#define SPR_CTR 9 /* Count Register Read / Write */
#define SPR_SRR0 26 /* Save/Restore Register 0 Read / Write */
#define SPR_SRR1 27 /* Save/Restore Register 1 Read / Write */
#define SPR_SPRG0 272 /* SPR General 0 Read / Write */
#define SPR_SPRG1 273 /* SPR General 1 Read / Write */
#define SPR_SPRG2 274 /* SPR General 2 Read / Write */
#define SPR_SPRG3 275 /* SPR General 3 Read / Write */
#define SPR_PVR 287 /* Processor Version Number Read Only */
#define SPR403_ICDBDR 0x3D3 /* 406GA Instruction Cache Debug Data Register Rad Only */
#define SPR403_ESR 0x3D4 /* 406GA Exception Syndrome Register Read / Write */
#define SPR403_DEAR 0x3D5 /* 406GA Data Exception Address Register Read Only */
#define SPR403_EVPR 0x3D6 /* 406GA Exception Vector Prefix Register Read / Write */
#define SPR403_CDBCR 0x3D7 /* 406GA Cache Debug Control Register Read/Write */
#define SPR403_TSR 0x3D8 /* 406GA Timer Status Register Read / Clear */
#define SPR403_TCR 0x3DA /* 406GA Timer Control Register Read / Write */
#define SPR403_PIT 0x3DB /* 406GA Programmable Interval Timer Read / Write */
#define SPR403_TBHI 988 /* 406GA Time Base High Read / Write */
#define SPR403_TBLO 989 /* 406GA Time Base Low Read / Write */
#define SPR403_SRR2 0x3DE /* 406GA Save/Restore Register 2 Read / Write */
#define SPR403_SRR3 0x3DF /* 406GA Save/Restore Register 3 Read / Write */
#define SPR403_DBSR 0x3F0 /* 406GA Debug Status Register Read / Clear */
#define SPR403_DBCR 0x3F2 /* 406GA Debug Control Register Read / Write */
#define SPR403_IAC1 0x3F4 /* 406GA Instruction Address Compare 1 Read / Write */
#define SPR403_IAC2 0x3F5 /* 406GA Instruction Address Compare 2 Read / Write */
#define SPR403_DAC1 0x3F6 /* 406GA Data Address Compare 1 Read / Write */
#define SPR403_DAC2 0x3F7 /* 406GA Data Address Compare 2 Read / Write */
#define SPR403_DCCR 0x3FA /* 406GA Data Cache Cacheability Register Read / Write */
#define SPR403_ICCR 0x3FB /* 406GA I Cache Cacheability Registe Read / Write */
#define SPR403_PBL1 0x3FC /* 406GA Protection Bound Lower 1 Read / Write */
#define SPR403_PBU1 0x3FD /* 406GA Protection Bound Upper 1 Read / Write */
#define SPR403_PBL2 0x3FE /* 406GA Protection Bound Lower 2 Read / Write */
#define SPR403_PBU2 0x3FF /* 406GA Protection Bound Upper 2 Read / Write */
#define SPR403_SGR 0x3b9 /* 403GCX Storage Guarded Register */
#define SPR403_DCWR 0x3ba /* 403GCX Data Cache Write Through */
#define SPR403_PID 0x3b1 /* 403GCX Process ID */
#define SPR403_TBHU 0x3cc /* 403GCX Time Base High User-mode */
#define SPR403_TBLU 0x3cd /* 403GCX Time Base Low User-mode */
#define SPR603E_DSISR 18 /* 603E */
#define SPR603E_DAR 19 /* 603E */
#define SPR603E_DEC 22 /* 603E */
#define SPR603E_SDR1 25 /* 603E */
#define SPR603E_TBL_R 268 /* 603E Time Base Low (Read-only) */
#define SPR603E_TBU_R 269 /* 603E Time Base High (Read-only) */
#define SPR603E_TBL_W 284 /* 603E Time Base Low (Write-only) */
#define SPR603E_TBU_W 285 /* 603E Time Base Hight (Write-only) */
#define SPR603E_EAR 282 /* 603E */
#define SPR603E_IBAT0U 528 /* 603E */
#define SPR603E_IBAT0L 529 /* 603E */
#define SPR603E_IBAT1U 530 /* 603E */
#define SPR603E_IBAT1L 531 /* 603E */
#define SPR603E_IBAT2U 532 /* 603E */
#define SPR603E_IBAT2L 533 /* 603E */
#define SPR603E_IBAT3U 534 /* 603E */
#define SPR603E_IBAT3L 535 /* 603E */
#define SPR603E_DBAT0U 536 /* 603E */
#define SPR603E_DBAT0L 537 /* 603E */
#define SPR603E_DBAT1U 538 /* 603E */
#define SPR603E_DBAT1L 539 /* 603E */
#define SPR603E_DBAT2U 540 /* 603E */
#define SPR603E_DBAT2L 541 /* 603E */
#define SPR603E_DBAT3U 542 /* 603E */
#define SPR603E_DBAT3L 543 /* 603E */
#define SPR603E_DABR 1013 /* 603E */
#define SPR603E_DMISS 0x3d0 /* 603E */
#define SPR603E_DCMP 0x3d1 /* 603E */
#define SPR603E_HASH1 0x3d2 /* 603E */
#define SPR603E_HASH2 0x3d3 /* 603E */
#define SPR603E_IMISS 0x3d4 /* 603E */
#define SPR603E_ICMP 0x3d5 /* 603E */
#define SPR603E_RPA 0x3d6 /* 603E */
#define SPR603E_HID0 1008 /* 603E */
#define SPR603E_HID1 1009 /* 603E */
#define SPR603E_IABR 1010 /* 603E */
#define SPR603E_HID2 1011 /* 603E */
#define SPR602_TCR 984 /* 602 */
#define SPR602_IBR 986 /* 602 */
#define SPR602_SP 1021 /* 602 */
#define SPR602_LT 1022 /* 602 */
#define DCR_BEAR 0x90 /* bus error address */
#define DCR_BESR 0x91 /* bus error syndrome */
#define DCR_BR0 0x80 /* bank */
#define DCR_BR1 0x81 /* bank */
#define DCR_BR2 0x82 /* bank */
#define DCR_BR3 0x83 /* bank */
#define DCR_BR4 0x84 /* bank */
#define DCR_BR5 0x85 /* bank */
#define DCR_BR6 0x86 /* bank */
#define DCR_BR7 0x87 /* bank */
#define DCR_DMACC0 0xc4 /* dma chained count */
#define DCR_DMACC1 0xcc /* dma chained count */
#define DCR_DMACC2 0xd4 /* dma chained count */
#define DCR_DMACC3 0xdc /* dma chained count */
#define DCR_DMACR0 0xc0 /* dma channel control */
#define DCR_DMACR1 0xc8 /* dma channel control */
#define DCR_DMACR2 0xd0 /* dma channel control */
#define DCR_DMACR3 0xd8 /* dma channel control */
#define DCR_DMACT0 0xc1 /* dma destination address */
#define DCR_DMACT1 0xc9 /* dma destination address */
#define DCR_DMACT2 0xd1 /* dma destination address */
#define DCR_DMACT3 0xd9 /* dma destination address */
#define DCR_DMADA0 0xc2 /* dma destination address */
#define DCR_DMADA1 0xca /* dma destination address */
#define DCR_DMADA2 0xd2 /* dma source address */
#define DCR_DMADA3 0xda /* dma source address */
#define DCR_DMASA0 0xc3 /* dma source address */
#define DCR_DMASA1 0xcb /* dma source address */
#define DCR_DMASA2 0xd3 /* dma source address */
#define DCR_DMASA3 0xdb /* dma source address */
#define DCR_DMASR 0xe0 /* dma status */
#define DCR_EXIER 0x42 /* external interrupt enable */
#define DCR_EXISR 0x40 /* external interrupt status */
#define DCR_IOCR 0xa0 /* io configuration */
enum {
EXCEPTION_IRQ = 1,
EXCEPTION_DECREMENTER = 2,
EXCEPTION_TRAP = 3,
EXCEPTION_SYSTEM_CALL = 4,
EXCEPTION_SMI = 5,
EXCEPTION_DSI = 6,
EXCEPTION_ISI = 7,
EXCEPTION_PROGRAMMABLE_INTERVAL_TIMER = 20,
EXCEPTION_FIXED_INTERVAL_TIMER = 21,
EXCEPTION_WATCHDOG_TIMER = 22,
EXCEPTION_CRITICAL_INTERRUPT = 23,
};
enum {
PPC_INPUT_LINE_SMI = 10,
PPC_INPUT_LINE_TLBISYNC
};
enum {
PPC_PC=1,
PPC_MSR,
PPC_CR,
PPC_LR,
PPC_CTR,
PPC_XER,
PPC_DEC,
PPC_SRR0,
PPC_SRR1,
PPC_R0,
PPC_R1,
PPC_R2,
PPC_R3,
PPC_R4,
PPC_R5,
PPC_R6,
PPC_R7,
PPC_R8,
PPC_R9,
PPC_R10,
PPC_R11,
PPC_R12,
PPC_R13,
PPC_R14,
PPC_R15,
PPC_R16,
PPC_R17,
PPC_R18,
PPC_R19,
PPC_R20,
PPC_R21,
PPC_R22,
PPC_R23,
PPC_R24,
PPC_R25,
PPC_R26,
PPC_R27,
PPC_R28,
PPC_R29,
PPC_R30,
PPC_R31
};
typedef enum {
PPC_MODEL_403GA = 0x00200000,
PPC_MODEL_403GB = 0x00200100,
PPC_MODEL_403GC = 0x00200200,
PPC_MODEL_403GCX = 0x00201400,
PPC_MODEL_405GP = 0x40110000,
PPC_MODEL_601 = 0x00010000,
PPC_MODEL_603 = 0x00030000, /* "Wart" */
PPC_MODEL_604 = 0x00040000, /* "Zephyr" */
PPC_MODEL_602 = 0x00050000, /* "Galahad" */
PPC_MODEL_603E = 0x00060103, /* "Stretch", version 1.3 */
PPC_MODEL_603EV = 0x00070000, /* "Valiant" */
PPC_MODEL_603R = 0x00071202, /* "Goldeneye", version 2.1 */
PPC_MODEL_740 = 0x00080301, /* "Arthur", version 3.1 */
PPC_MODEL_750 = PPC_MODEL_740,
PPC_MODEL_740P = 0x00080202, /* "Conan Doyle", version 1.2 */
PPC_MODEL_750P = PPC_MODEL_740P,
PPC_MODEL_755 = 0x00083203 /* "Goldfinger", version 2.3 */
} PPC_MODEL;
typedef enum {
BUS_FREQUENCY_16MHZ = 0,
BUS_FREQUENCY_20MHZ,
BUS_FREQUENCY_25MHZ,
BUS_FREQUENCY_33MHZ,
BUS_FREQUENCY_40MHZ,
BUS_FREQUENCY_50MHZ,
BUS_FREQUENCY_60MHZ,
BUS_FREQUENCY_66MHZ,
BUS_FREQUENCY_75MHZ,
} PPC_BUS_FREQUENCY;
// PLL Configuration based on the table in MPC603EUM page 7-31
static const int mpc603e_pll_config[12][9] =
{
// 16, 20, 25, 33, 40, 50, 60, 66, 75
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, -1, 0x0, -1 },
{ -1, -1, -1, -1, -1, 0xc, -1, 0xc, -1 },
{ 0x5, 0x5, 0x5, 0x4, 0x4, 0x4, -1, -1, -1 },
{ -1, -1, -1, 0x6, 0x6, -1, -1, -1, -1 },
{ -1, -1, 0x8, 0x8, -1, -1, -1, -1, -1 },
{ -1, 0xe, 0xe, -1, -1, -1, -1, -1, -1 },
{ 0xa, 0xa, 0xa, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
};
// PLL Configuration based on the table in MPC603E7VEC page 29
static const int mpc603ev_pll_config[12][9] =
{
// 16, 20, 25, 33, 40, 50, 60, 66, 75
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
// 2:1
{ -1, -1, -1, -1, -1, -1, -1, 0x4, 0x4 },
// 2.5:1
{ -1, -1, -1, -1, -1, 0x6, 0x6, 0x6, 0x6 },
// 3:1
{ -1, -1, -1, -1, 0x8, 0x8, 0x8, 0x8, 0x8 },
// 3.5:1
{ -1, -1, -1, -1, 0xe, 0xe, 0xe, 0xe, -1 },
// 4:1
{ -1, -1, -1, 0xa, 0xa, 0xa, 0xa, -1, -1 },
// 4.5:1
{ -1, -1, -1, 0x7, 0x7, 0x7, -1, -1, -1 },
// 5:1
{ -1, -1, 0xb, 0xb, 0xb, -1, -1, -1, -1 },
// 5.5:1
{ -1, -1, 0x9, 0x9, 0x9, -1, -1, -1, -1 },
// 6:1
{ -1, -1, 0xd, 0xd, 0xd, -1, -1, -1, -1 }
};
// PLL Configuration based on the table in MPC603E7TEC page 23
static const int mpc603r_pll_config[12][9] =
{
// 16, 20, 25, 33, 40, 50, 60, 66, 75
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 },
// 2:1
{ -1, -1, -1, -1, 0x5, 0x5, 0x5, 0x5, 0x5 },
// 2.5:1
{ -1, -1, -1, -1, -1, -1, 0x6, 0x6, 0x6 },
// 3:1
{ -1, -1, -1, -1, -1, 0x8, 0x8, 0x8, 0x8 },
// 3.5:1
{ -1, -1, -1, -1, -1, 0xe, 0xe, 0xe, 0xe },
// 4:1
{ -1, -1, -1, -1, 0xa, 0xa, 0xa, 0xa, 0xa },
// 4.5:1
{ -1, -1, -1, 0x7, 0x7, 0x7, 0x7, 0x7, -1 },
// 5:1
{ -1, -1, -1, 0xb, 0xb, 0xb, 0xb, -1, -1 },
// 5.5:1
{ -1, -1, -1, 0x9, 0x9, 0x9, -1, -1, -1 },
// 6:1
{ -1, -1, 0xd, 0xd, 0xd, 0xd, -1, -1, -1 },
};
typedef struct {
PPC_MODEL pvr;
int bus_frequency_multiplier;
PPC_BUS_FREQUENCY bus_frequency;
} PPC_CONFIG;
typedef struct
{
UINT32 start;
UINT32 end;
UINT32 * ptr;
} PPC_FETCH_REGION;
UINT32 ppc_get_pc(void);
void ppc_set_irq_line(int irqline);
int ppc_execute(int cycles);
void ppc_reset(void);
void ppc_shutdown(void);
void ppc_init(const PPC_CONFIG *config);
void ppc_set_fetch(PPC_FETCH_REGION * fetch);
#endif /* _PPC_H */

View file

@ -1,294 +0,0 @@
void ppc603_exception(int exception)
{
switch( exception )
{
case EXCEPTION_IRQ: /* External Interrupt */
if( ppc_get_msr() & MSR_EE ) {
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr & 0xff73;
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0500;
else
ppc.npc = 0x00000000 | 0x0500;
ppc.interrupt_pending &= ~0x1;
ppc_change_pc(ppc.npc);
}
break;
case EXCEPTION_DECREMENTER: /* Decrementer overflow exception */
if( ppc_get_msr() & MSR_EE ) {
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr & 0xff73;
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0900;
else
ppc.npc = 0x00000000 | 0x0900;
ppc.interrupt_pending &= ~0x2;
ppc_change_pc(ppc.npc);
}
break;
case EXCEPTION_TRAP: /* Program exception / Trap */
{
UINT32 msr = ppc_get_msr();
SRR0 = ppc.pc;
SRR1 = (msr & 0xff73) | 0x20000; /* 0x20000 = TRAP bit */
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0700;
else
ppc.npc = 0x00000000 | 0x0700;
ppc_change_pc(ppc.npc);
}
break;
case EXCEPTION_SYSTEM_CALL: /* System call */
{
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = (msr & 0xff73);
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0c00;
else
ppc.npc = 0x00000000 | 0x0c00;
ppc_change_pc(ppc.npc);
}
break;
case EXCEPTION_SMI:
if( ppc_get_msr() & MSR_EE ) {
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr & 0xff73;
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x1400;
else
ppc.npc = 0x00000000 | 0x1400;
ppc.interrupt_pending &= ~0x4;
ppc_change_pc(ppc.npc);
}
break;
case EXCEPTION_DSI:
{
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr & 0xff73;
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0300;
else
ppc.npc = 0x00000000 | 0x0300;
ppc.interrupt_pending &= ~0x4;
ppc_change_pc(ppc.npc);
}
break;
case EXCEPTION_ISI:
{
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr & 0xff73;
msr &= ~(MSR_POW | MSR_EE | MSR_PR | MSR_FP | MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1 | MSR_IR | MSR_DR | MSR_RI);
if( msr & MSR_ILE )
msr |= MSR_LE;
else
msr &= ~MSR_LE;
ppc_set_msr(msr);
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0400;
else
ppc.npc = 0x00000000 | 0x0400;
ppc.interrupt_pending &= ~0x4;
ppc_change_pc(ppc.npc);
}
break;
default:
error("ppc: Unhandled exception %d", exception);
break;
}
}
static void ppc603_set_smi_line(int state)
{
if( state ) {
ppc.interrupt_pending |= 0x4;
}
}
static void ppc603_check_interrupts(void)
{
if (MSR & MSR_EE)
{
if (ppc.interrupt_pending != 0)
{
if (ppc.interrupt_pending & 0x1)
{
ppc603_exception(EXCEPTION_IRQ);
}
else if (ppc.interrupt_pending & 0x2)
{
ppc603_exception(EXCEPTION_DECREMENTER);
}
else if (ppc.interrupt_pending & 0x4)
{
ppc603_exception(EXCEPTION_SMI);
}
}
}
}
void ppc_reset(void)
{
ppc.pc = ppc.npc = 0xfff00100;
ppc_set_msr(0x40);
ppc_change_pc(ppc.pc);
ppc.hid0 = 1;
ppc.interrupt_pending = 0;
}
int ppc_execute(int cycles)
{
UINT32 opcode;
ppc_icount = cycles;
ppc_tb_base_icount = cycles;
ppc_dec_base_icount = cycles + ppc.dec_frac;
// check if decrementer exception occurs during execution
if ((UINT32)(DEC - (cycles / (bus_freq_multiplier * 2))) > (UINT32)(DEC))
{
ppc_dec_trigger_cycle = ((cycles / (bus_freq_multiplier * 2)) - DEC) * 4;
}
else
{
ppc_dec_trigger_cycle = 0x7fffffff;
}
ppc_change_pc(ppc.npc);
/*{
char string1[200];
char string2[200];
opcode = BSWAP32(*ppc.op);
DisassemblePowerPC(opcode, ppc.npc, string1, string2, TRUE);
printf("%08X: %s %s\n", ppc.npc, string1, string2);
}*/
printf("trigger cycle %d (%08X)\n", ppc_dec_trigger_cycle, ppc_dec_trigger_cycle);
printf("tb = %08X %08X\n", (UINT32)(ppc.tb >> 32), (UINT32)(ppc.tb));
ppc603_check_interrupts();
while( ppc_icount > 0 )
{
ppc.pc = ppc.npc;
opcode = BSWAP32(*ppc.op++);
ppc.npc = ppc.pc + 4;
switch(opcode >> 26)
{
case 19: optable19[(opcode >> 1) & 0x3ff](opcode); break;
case 31: optable31[(opcode >> 1) & 0x3ff](opcode); break;
case 59: optable59[(opcode >> 1) & 0x3ff](opcode); break;
case 63: optable63[(opcode >> 1) & 0x3ff](opcode); break;
default: optable[opcode >> 26](opcode); break;
}
ppc_icount--;
if(ppc_icount == ppc_dec_trigger_cycle)
{
printf("dec int at %d\n", ppc_icount);
ppc.interrupt_pending |= 0x2;
ppc603_check_interrupts();
}
//ppc603_check_interrupts();
}
// update timebase
// timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4);
// update decrementer
ppc.dec_frac = ((ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2));
DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2));
/*
{
char string1[200];
char string2[200];
opcode = BSWAP32(*ppc.op);
DisassemblePowerPC(opcode, ppc.npc, string1, string2, TRUE);
printf("%08X: %s %s\n", ppc.npc, string1, string2);
}
*/
return cycles - ppc_icount;
}

File diff suppressed because it is too large Load diff

View file

@ -1,143 +0,0 @@
static PPC_OPCODE ppc_opcode_common[] =
{
/*code subcode handler */
{ 31, 266, ppc_addx },
{ 31, 266 | 512, ppc_addx },
{ 31, 10, ppc_addcx },
{ 31, 10 | 512, ppc_addcx },
{ 31, 138, ppc_addex },
{ 31, 138 | 512, ppc_addex },
{ 14, -1, ppc_addi },
{ 12, -1, ppc_addic },
{ 13, -1, ppc_addic_rc },
{ 15, -1, ppc_addis },
{ 31, 234, ppc_addmex },
{ 31, 234 | 512, ppc_addmex },
{ 31, 202, ppc_addzex },
{ 31, 202 | 512, ppc_addzex },
{ 31, 28, ppc_andx },
{ 31, 28 | 512, ppc_andx },
{ 31, 60, ppc_andcx },
{ 28, -1, ppc_andi_rc },
{ 29, -1, ppc_andis_rc },
{ 18, -1, ppc_bx },
{ 16, -1, ppc_bcx },
{ 19, 528, ppc_bcctrx },
{ 19, 16, ppc_bclrx },
{ 31, 0, ppc_cmp },
{ 11, -1, ppc_cmpi },
{ 31, 32, ppc_cmpl },
{ 10, -1, ppc_cmpli },
{ 31, 26, ppc_cntlzw },
{ 19, 257, ppc_crand },
{ 19, 129, ppc_crandc },
{ 19, 289, ppc_creqv },
{ 19, 225, ppc_crnand },
{ 19, 33, ppc_crnor },
{ 19, 449, ppc_cror },
{ 19, 417, ppc_crorc },
{ 19, 193, ppc_crxor },
{ 31, 86, ppc_dcbf },
{ 31, 470, ppc_dcbi },
{ 31, 54, ppc_dcbst },
{ 31, 278, ppc_dcbt },
{ 31, 246, ppc_dcbtst },
{ 31, 1014, ppc_dcbz },
{ 31, 491, ppc_divwx },
{ 31, 491 | 512, ppc_divwx },
{ 31, 459, ppc_divwux },
{ 31, 459 | 512, ppc_divwux },
{ 31, 854, ppc_eieio },
{ 31, 284, ppc_eqvx },
{ 31, 954, ppc_extsbx },
{ 31, 922, ppc_extshx },
{ 31, 982, ppc_icbi },
{ 19, 150, ppc_isync },
{ 34, -1, ppc_lbz },
{ 35, -1, ppc_lbzu },
{ 31, 119, ppc_lbzux },
{ 31, 87, ppc_lbzx },
{ 42, -1, ppc_lha },
{ 43, -1, ppc_lhau },
{ 31, 375, ppc_lhaux },
{ 31, 343, ppc_lhax },
{ 31, 790, ppc_lhbrx },
{ 40, -1, ppc_lhz },
{ 41, -1, ppc_lhzu },
{ 31, 311, ppc_lhzux },
{ 31, 279, ppc_lhzx },
{ 46, -1, ppc_lmw },
{ 31, 597, ppc_lswi },
{ 31, 533, ppc_lswx },
{ 31, 20, ppc_lwarx },
{ 31, 534, ppc_lwbrx },
{ 32, -1, ppc_lwz },
{ 33, -1, ppc_lwzu },
{ 31, 55, ppc_lwzux },
{ 31, 23, ppc_lwzx },
{ 19, 0, ppc_mcrf },
{ 31, 512, ppc_mcrxr },
{ 31, 19, ppc_mfcr },
{ 31, 83, ppc_mfmsr },
{ 31, 339, ppc_mfspr },
{ 31, 144, ppc_mtcrf },
{ 31, 146, ppc_mtmsr },
{ 31, 467, ppc_mtspr },
{ 31, 75, ppc_mulhwx },
{ 31, 11, ppc_mulhwux },
{ 7, -1, ppc_mulli },
{ 31, 235, ppc_mullwx },
{ 31, 235 | 512, ppc_mullwx },
{ 31, 476, ppc_nandx },
{ 31, 104, ppc_negx },
{ 31, 104 | 512, ppc_negx },
{ 31, 124, ppc_norx },
{ 31, 444, ppc_orx },
{ 31, 412, ppc_orcx },
{ 24, -1, ppc_ori },
{ 25, -1, ppc_oris },
{ 19, 50, ppc_rfi },
{ 20, -1, ppc_rlwimix },
{ 21, -1, ppc_rlwinmx },
{ 23, -1, ppc_rlwnmx },
{ 17, -1, ppc_sc },
{ 31, 24, ppc_slwx },
{ 31, 792, ppc_srawx },
{ 31, 824, ppc_srawix },
{ 31, 536, ppc_srwx },
{ 38, -1, ppc_stb },
{ 39, -1, ppc_stbu },
{ 31, 247, ppc_stbux },
{ 31, 215, ppc_stbx },
{ 44, -1, ppc_sth },
{ 31, 918, ppc_sthbrx },
{ 45, -1, ppc_sthu },
{ 31, 439, ppc_sthux },
{ 31, 407, ppc_sthx },
{ 47, -1, ppc_stmw },
{ 31, 725, ppc_stswi },
{ 31, 661, ppc_stswx },
{ 36, -1, ppc_stw },
{ 31, 662, ppc_stwbrx },
{ 31, 150, ppc_stwcx_rc },
{ 37, -1, ppc_stwu },
{ 31, 183, ppc_stwux },
{ 31, 151, ppc_stwx },
{ 31, 40, ppc_subfx },
{ 31, 40 | 512, ppc_subfx },
{ 31, 8, ppc_subfcx },
{ 31, 8 | 512, ppc_subfcx },
{ 31, 136, ppc_subfex },
{ 31, 136 | 512, ppc_subfex },
{ 8, -1, ppc_subfic },
{ 31, 232, ppc_subfmex },
{ 31, 232 | 512, ppc_subfmex },
{ 31, 200, ppc_subfzex },
{ 31, 200 | 512, ppc_subfzex },
{ 31, 598, ppc_sync },
{ 31, 4, ppc_tw },
{ 3, -1, ppc_twi },
{ 31, 316, ppc_xorx },
{ 26, -1, ppc_xori },
{ 27, -1, ppc_xoris }
};