Removed dead PPC code (nw)

This commit is contained in:
Miodrag Milanovic 2015-12-09 10:25:40 +01:00
parent 9ce2bd4f15
commit 700683468a
11 changed files with 0 additions and 10987 deletions

View File

@ -1463,17 +1463,7 @@ if (CPUS["POWERPC"]~=null) then
MAME_DIR .. "src/devices/cpu/powerpc/ppcfe.cpp",
MAME_DIR .. "src/devices/cpu/powerpc/ppcfe.h",
MAME_DIR .. "src/devices/cpu/powerpc/ppcdrc.cpp",
--MAME_DIR .. "src/devices/cpu/powerpc/drc_ops.cpp",
MAME_DIR .. "src/devices/cpu/powerpc/drc_ops.h",
--MAME_DIR .. "src/devices/cpu/powerpc/ppc.cpp",
MAME_DIR .. "src/devices/cpu/powerpc/ppc.h",
MAME_DIR .. "src/devices/cpu/powerpc/ppc403.inc",
MAME_DIR .. "src/devices/cpu/powerpc/ppc602.inc",
MAME_DIR .. "src/devices/cpu/powerpc/ppc603.inc",
MAME_DIR .. "src/devices/cpu/powerpc/ppc_mem.inc",
MAME_DIR .. "src/devices/cpu/powerpc/ppc_ops.h",
MAME_DIR .. "src/devices/cpu/powerpc/ppc_ops.inc",
}
end

File diff suppressed because it is too large Load Diff

View File

@ -1,145 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
static const PPC_OPCODE ppcdrc_opcode_common[] =
{
/*code subcode handler */
{ 31, 266, recompile_addx },
{ 31, 266 | 512, recompile_addx },
{ 31, 10, recompile_addcx },
{ 31, 10 | 512, recompile_addcx },
{ 31, 138, recompile_addex },
{ 31, 138 | 512, recompile_addex },
{ 14, -1, recompile_addi },
{ 12, -1, recompile_addic },
{ 13, -1, recompile_addic_rc },
{ 15, -1, recompile_addis },
{ 31, 234, recompile_addmex },
{ 31, 234 | 512, recompile_addmex },
{ 31, 202, recompile_addzex },
{ 31, 202 | 512, recompile_addzex },
{ 31, 28, recompile_andx },
{ 31, 28 | 512, recompile_andx },
{ 31, 60, recompile_andcx },
{ 28, -1, recompile_andi_rc },
{ 29, -1, recompile_andis_rc },
{ 18, -1, recompile_bx },
{ 16, -1, recompile_bcx },
{ 19, 528, recompile_bcctrx },
{ 19, 16, recompile_bclrx },
{ 31, 0, recompile_cmp },
{ 11, -1, recompile_cmpi },
{ 31, 32, recompile_cmpl },
{ 10, -1, recompile_cmpli },
{ 31, 26, recompile_cntlzw },
{ 19, 257, recompile_crand },
{ 19, 129, recompile_crandc },
{ 19, 289, recompile_creqv },
{ 19, 225, recompile_crnand },
{ 19, 33, recompile_crnor },
{ 19, 449, recompile_cror },
{ 19, 417, recompile_crorc },
{ 19, 193, recompile_crxor },
{ 31, 86, recompile_dcbf },
{ 31, 470, recompile_dcbi },
{ 31, 54, recompile_dcbst },
{ 31, 278, recompile_dcbt },
{ 31, 246, recompile_dcbtst },
{ 31, 1014, recompile_dcbz },
{ 31, 491, recompile_divwx },
{ 31, 491 | 512, recompile_divwx },
{ 31, 459, recompile_divwux },
{ 31, 459 | 512, recompile_divwux },
{ 31, 854, recompile_eieio },
{ 31, 284, recompile_eqvx },
{ 31, 954, recompile_extsbx },
{ 31, 922, recompile_extshx },
{ 31, 982, recompile_icbi },
{ 19, 150, recompile_isync },
{ 34, -1, recompile_lbz },
{ 35, -1, recompile_lbzu },
{ 31, 119, recompile_lbzux },
{ 31, 87, recompile_lbzx },
{ 42, -1, recompile_lha },
{ 43, -1, recompile_lhau },
{ 31, 375, recompile_lhaux },
{ 31, 343, recompile_lhax },
{ 31, 790, recompile_lhbrx },
{ 40, -1, recompile_lhz },
{ 41, -1, recompile_lhzu },
{ 31, 311, recompile_lhzux },
{ 31, 279, recompile_lhzx },
{ 46, -1, recompile_lmw },
{ 31, 597, recompile_lswi },
{ 31, 533, recompile_lswx },
{ 31, 20, recompile_lwarx },
{ 31, 534, recompile_lwbrx },
{ 32, -1, recompile_lwz },
{ 33, -1, recompile_lwzu },
{ 31, 55, recompile_lwzux },
{ 31, 23, recompile_lwzx },
{ 19, 0, recompile_mcrf },
{ 31, 512, recompile_mcrxr },
{ 31, 19, recompile_mfcr },
{ 31, 83, recompile_mfmsr },
{ 31, 339, recompile_mfspr },
{ 31, 144, recompile_mtcrf },
{ 31, 146, recompile_mtmsr },
{ 31, 467, recompile_mtspr },
{ 31, 75, recompile_mulhwx },
{ 31, 11, recompile_mulhwux },
{ 7, -1, recompile_mulli },
{ 31, 235, recompile_mullwx },
{ 31, 235 | 512, recompile_mullwx },
{ 31, 476, recompile_nandx },
{ 31, 104, recompile_negx },
{ 31, 104 | 512, recompile_negx },
{ 31, 124, recompile_norx },
{ 31, 444, recompile_orx },
{ 31, 412, recompile_orcx },
{ 24, -1, recompile_ori },
{ 25, -1, recompile_oris },
{ 19, 50, recompile_rfi },
{ 20, -1, recompile_rlwimix },
{ 21, -1, recompile_rlwinmx },
{ 23, -1, recompile_rlwnmx },
{ 17, -1, recompile_sc },
{ 31, 24, recompile_slwx },
{ 31, 792, recompile_srawx },
{ 31, 824, recompile_srawix },
{ 31, 536, recompile_srwx },
{ 38, -1, recompile_stb },
{ 39, -1, recompile_stbu },
{ 31, 247, recompile_stbux },
{ 31, 215, recompile_stbx },
{ 44, -1, recompile_sth },
{ 31, 918, recompile_sthbrx },
{ 45, -1, recompile_sthu },
{ 31, 439, recompile_sthux },
{ 31, 407, recompile_sthx },
{ 47, -1, recompile_stmw },
{ 31, 725, recompile_stswi },
{ 31, 661, recompile_stswx },
{ 36, -1, recompile_stw },
{ 31, 662, recompile_stwbrx },
{ 31, 150, recompile_stwcx_rc },
{ 37, -1, recompile_stwu },
{ 31, 183, recompile_stwux },
{ 31, 151, recompile_stwx },
{ 31, 40, recompile_subfx },
{ 31, 40 | 512, recompile_subfx },
{ 31, 8, recompile_subfcx },
{ 31, 8 | 512, recompile_subfcx },
{ 31, 136, recompile_subfex },
{ 31, 136 | 512, recompile_subfex },
{ 8, -1, recompile_subfic },
{ 31, 232, recompile_subfmex },
{ 31, 232 | 512, recompile_subfmex },
{ 31, 200, recompile_subfzex },
{ 31, 200 | 512, recompile_subfzex },
{ 31, 598, recompile_sync },
{ 31, 4, recompile_tw },
{ 3, -1, recompile_twi },
{ 31, 316, recompile_xorx },
{ 26, -1, recompile_xori },
{ 27, -1, recompile_xoris }
};

File diff suppressed because it is too large Load Diff

View File

@ -14,9 +14,6 @@
#ifndef __PPC_H__
#define __PPC_H__
#ifdef PPC_H_INCLUDED_FROM_PPC_C
#include <setjmp.h>
#endif
#include "cpu/vtlb.h"
#include "cpu/drcfe.h"
#include "cpu/drcuml.h"

View File

@ -1,947 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/* PowerPC 403 specific functions */
static void ppc403_dma_exec(int ch);
#define DMA_CE 0x80000000
#define DMA_CIE 0x40000000
#define DMA_TD 0x20000000
#define DMA_PL 0x10000000
#define DMA_DAI 0x02000000
#define DMA_SAI 0x01000000
#define DMA_CP 0x00800000
#define DMA_ETD 0x00000200
#define DMA_TCE 0x00000100
#define DMA_CH 0x00000080
#define DMA_BME 0x00000040
#define DMA_ECE 0x00000020
#define DMA_TCD 0x00000010
#define DMA_PCE 0x00000008
static SPU_RX_HANDLER spu_rx_handler;
static SPU_TX_HANDLER spu_tx_handler;
static TIMER_CALLBACK( ppc403_spu_rx_callback );
static TIMER_CALLBACK( ppc403_spu_tx_callback );
static PPC_DMA_HANDLER spu_rx_dma_handler;
static PPC_DMA_HANDLER spu_tx_dma_handler;
static UINT8 *spu_rx_dma_ptr;
static UINT8 *spu_tx_dma_ptr;
static PPC_DMA_HANDLER dma_read_handler[4];
static PPC_DMA_HANDLER dma_write_handler[4];
static UINT8 *dma_read_ptr[4];
static UINT8 *dma_write_ptr[4];
INLINE void ppc_set_dcr(int dcr, UINT32 value)
{
switch(dcr)
{
case DCR_BEAR: ppc.bear = value; break;
case DCR_BESR: ppc.besr = value; break;
case DCR_BR0: ppc.br[0] = value; break;
case DCR_BR1: ppc.br[1] = value; break;
case DCR_BR2: ppc.br[2] = value; break;
case DCR_BR3: ppc.br[3] = value; break;
case DCR_BR4: ppc.br[4] = value; break;
case DCR_BR5: ppc.br[5] = value; break;
case DCR_BR6: ppc.br[6] = value; break;
case DCR_BR7: ppc.br[7] = value; break;
case DCR_EXISR: ppc.exisr &= ~value; break;
case DCR_EXIER: EXIER = value; ppc.exisr &= EXIER; break;
case DCR_IOCR: ppc.iocr = value; break;
case DCR_DMASR: break; /* TODO */
case DCR_DMADA0: ppc.dma[0].da = value; break;
case DCR_DMADA1: ppc.dma[1].da = value; break;
case DCR_DMADA2: ppc.dma[2].da = value; break;
case DCR_DMADA3: ppc.dma[3].da = value; break;
case DCR_DMASA0: ppc.dma[0].sa = value; break;
case DCR_DMASA1: ppc.dma[1].sa = value; break;
case DCR_DMASA2: ppc.dma[2].sa = value; break;
case DCR_DMASA3: ppc.dma[3].sa = value; break;
case DCR_DMACT0: ppc.dma[0].ct = value; break;
case DCR_DMACT1: ppc.dma[1].ct = value; break;
case DCR_DMACT2: ppc.dma[2].ct = value; break;
case DCR_DMACT3: ppc.dma[3].ct = value; break;
case DCR_DMACR0: ppc.dma[0].cr = value; ppc403_dma_exec(0); break;
case DCR_DMACR1: ppc.dma[1].cr = value; ppc403_dma_exec(1); break;
case DCR_DMACR2: ppc.dma[2].cr = value; ppc403_dma_exec(2); break;
case DCR_DMACR3: ppc.dma[3].cr = value; ppc403_dma_exec(3); break;
default:
fatalerror("ppc: set_dcr: Unimplemented DCR %X\n", dcr);
break;
}
}
INLINE UINT32 ppc_get_dcr(int dcr)
{
switch(dcr)
{
case DCR_BEAR: return ppc.bear;
case DCR_BESR: return ppc.besr;
case DCR_BR0: return ppc.br[0];
case DCR_BR1: return ppc.br[1];
case DCR_BR2: return ppc.br[2];
case DCR_BR3: return ppc.br[3];
case DCR_BR4: return ppc.br[4];
case DCR_BR5: return ppc.br[5];
case DCR_BR6: return ppc.br[6];
case DCR_BR7: return ppc.br[7];
case DCR_EXISR: return EXISR;
case DCR_EXIER: return EXIER;
case DCR_IOCR: return ppc.iocr;
case DCR_DMASR: return ppc.dmasr;
case DCR_DMADA0: return ppc.dma[0].da;
case DCR_DMADA1: return ppc.dma[1].da;
case DCR_DMADA2: return ppc.dma[2].da;
case DCR_DMADA3: return ppc.dma[3].da;
case DCR_DMASA0: return ppc.dma[0].sa;
case DCR_DMASA1: return ppc.dma[1].sa;
case DCR_DMASA2: return ppc.dma[2].sa;
case DCR_DMASA3: return ppc.dma[3].sa;
case DCR_DMACT0: return ppc.dma[0].ct;
case DCR_DMACT1: return ppc.dma[1].ct;
case DCR_DMACT2: return ppc.dma[2].ct;
case DCR_DMACT3: return ppc.dma[3].ct;
case DCR_DMACR0: return ppc.dma[0].cr;
case DCR_DMACR1: return ppc.dma[1].cr;
case DCR_DMACR2: return ppc.dma[2].cr;
case DCR_DMACR3: return ppc.dma[3].cr;
default:
fatalerror("ppc: get_dcr: Unimplemented DCR %X\n", dcr);
break;
}
}
#ifndef PPC_DRC
INLINE void ppc403_check_interrupts(void)
{
if (MSR & MSR_EE)
{
if (ppc.interrupt_pending != 0)
{
if (ppc.interrupt_pending & 0x1)
{
ppc403_exception(EXCEPTION_IRQ);
}
else if (ppc.interrupt_pending & 0x2)
{
ppc403_exception(EXCEPTION_PROGRAMMABLE_INTERVAL_TIMER);
}
else if (ppc.interrupt_pending & 0x4)
{
ppc403_exception(EXCEPTION_FIXED_INTERVAL_TIMER);
}
}
}
}
static CPU_RESET( ppc403 )
{
ppc.pc = ppc.npc = 0xfffffffc;
ppc_set_msr(0);
}
static CPU_EXECUTE( ppc403 )
{
UINT32 fit_trigger_cycle;
ppc_tb_base_icount = cycles;
fit_trigger_cycle = 0x7fffffff;
if (ppc.fit_int_enable)
{
UINT32 tb = (UINT32)ppc.tb;
UINT32 fit_cycles = 0;
if (ppc.tb & ppc.fit_bit)
{
fit_cycles += ppc.fit_bit;
tb += fit_cycles;
}
fit_cycles += ppc.fit_bit - (tb & (ppc.fit_bit-1));
fit_trigger_cycle = ppc_icount - fit_cycles;
}
while( ppc_icount > 0 )
{
UINT32 opcode;
debugger_instruction_hook(device, ppc.pc);
ppc.pc = ppc.npc;
ppc.npc += 4;
opcode = ROPCODE(ppc.pc);
switch(opcode >> 26)
{
case 19: ppc.optable19[(opcode >> 1) & 0x3ff](opcode); break;
case 31: ppc.optable31[(opcode >> 1) & 0x3ff](opcode); break;
case 59: ppc.optable59[(opcode >> 1) & 0x3ff](opcode); break;
case 63: ppc.optable63[(opcode >> 1) & 0x3ff](opcode); break;
default: ppc.optable[opcode >> 26](opcode); break;
}
ppc_icount--;
/* Programmable Interval Timer (PIT) */
if (ppc.pit_counter > 0)
{
ppc.pit_counter--;
if (ppc.pit_counter == 0)
{
if (ppc.pit_int_enable) {
ppc.interrupt_pending |= 0x2;
}
if (ppc.tcr & 0x00400000) // Automatic reload
{
ppc.pit_counter = ppc.pit;
}
}
}
/* Fixed Interval Timer */
if (fit_trigger_cycle != 0x7fffffff)
{
if (ppc_icount == fit_trigger_cycle)
{
if (ppc.fit_int_enable)
{
fit_trigger_cycle -= ppc.fit_bit;
ppc.interrupt_pending |= 0x4;
}
}
}
#if 0
/* Watchdog Timer */
if (((UINT32)(ppc.tb) & ppc.wdt_bit) && (tblo & ppc.wdt_bit) == 0) {
switch((ppc.tsr >> 28) & 0x3)
{
case 0: ppc.tsr |= TSR_ENW; break;
case 1: ppc.tsr |= TSR_ENW; break;
case 2:
if (ppc.wdt_int_enable && (ppc.msr & MSR_CE)) {
ppc403_exception(EXCEPTION_WATCHDOG_TIMER);
}
break;
case 3:
fatalerror("PPC: Watchdog Timer caused reset\n");
break;
}
}
#endif
ppc403_check_interrupts();
}
// update timebase
ppc.tb += (ppc_tb_base_icount - ppc_icount);
}
void ppc403_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;
msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR
if( msr & MSR_LE )
msr |= MSR_ILE;
else
msr &= ~MSR_ILE;
ppc_set_msr(msr);
ppc.npc = EVPR | 0x0500;
ppc.interrupt_pending &= ~0x1;
}
break;
}
case EXCEPTION_TRAP: /* Program exception / Trap */
{
UINT32 msr = ppc_get_msr();
SRR0 = ppc.pc;
SRR1 = msr;
msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR
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 = EVPR | 0x0700;
break;
}
case EXCEPTION_SYSTEM_CALL: /* System call */
{
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr;
msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR
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 = EVPR | 0x0c00;
break;
}
case EXCEPTION_PROGRAMMABLE_INTERVAL_TIMER:
{
if( ppc_get_msr() & MSR_EE ) {
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr;
msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR
if( msr & MSR_LE )
msr |= MSR_ILE;
else
msr &= ~MSR_ILE;
ppc_set_msr(msr);
ppc.npc = EVPR | 0x1000;
ppc.tsr |= 0x08000000; // PIT interrupt
ppc.interrupt_pending &= ~0x2;
}
break;
}
case EXCEPTION_FIXED_INTERVAL_TIMER: /* Fixed Interval Timer */
{
if( ppc_get_msr() & MSR_EE ) {
UINT32 msr = ppc_get_msr();
SRR0 = ppc.npc;
SRR1 = msr;
msr &= ~(MSR_WE | MSR_PR | MSR_EE | MSR_PE); // Clear WE, PR, EE, PR
if( msr & MSR_LE )
msr |= MSR_ILE;
else
msr &= ~MSR_ILE;
ppc_set_msr(msr);
ppc.npc = EVPR | 0x1010;
ppc.interrupt_pending &= ~0x4;
}
break;
}
case EXCEPTION_WATCHDOG_TIMER: /* Watchdog Timer */
{
UINT32 msr = ppc_get_msr();
SRR2 = ppc.npc;
SRR3 = msr;
msr &= ~(MSR_WE | MSR_PR | MSR_CE | MSR_EE | MSR_DE | MSR_PE | MSR_DR | MSR_IR);
if (msr & MSR_LE)
msr |= MSR_ILE;
else
msr &= ~MSR_ILE;
ppc_set_msr(msr);
ppc.npc = EVPR | 0x1020;
break;
}
case EXCEPTION_CRITICAL_INTERRUPT:
{
UINT32 msr = ppc_get_msr();
SRR2 = ppc.npc;
SRR3 = msr;
msr &= ~(MSR_WE | MSR_PR | MSR_CE | MSR_EE | MSR_DE | MSR_PE | MSR_DR | MSR_IR);
if (msr & MSR_LE)
msr |= MSR_ILE;
else
msr &= ~MSR_ILE;
ppc_set_msr(msr);
EXISR |= 0x80000000;
ppc.npc = EVPR | 0x100;
break;
}
default:
fatalerror("ppc: Unhandled exception %d\n", exception);
break;
}
}
static void ppc403_set_irq_line(int irqline, int state)
{
if (irqline >= INPUT_LINE_IRQ0 && irqline <= INPUT_LINE_IRQ4)
{
UINT32 mask = (1 << (4 - irqline));
if( state == ASSERT_LINE) {
if( EXIER & mask ) {
ppc.exisr |= mask;
ppc.interrupt_pending |= 0x1;
if (ppc.irq_callback)
{
ppc.irq_callback(ppc.device, irqline);
}
}
}
// clear line is used to clear the interrupt when the interrupts are level-sensitive
else if (state == CLEAR_LINE)
{
ppc.exisr &= ~mask;
}
}
else if (irqline == PPC_IRQ_SPU_RX)
{
UINT32 mask = 0x08000000;
if (state) {
if( EXIER & mask ) {
ppc.exisr |= mask;
ppc.interrupt_pending |= 0x1;
}
}
}
else if (irqline == PPC_IRQ_SPU_TX)
{
UINT32 mask = 0x04000000;
if (state) {
if( EXIER & mask ) {
ppc.exisr |= mask;
ppc.interrupt_pending |= 0x1;
}
}
}
else if (irqline == PPC_IRQ_CRITICAL)
{
if (state) {
if (EXIER & 0x80000000) {
ppc403_exception(EXCEPTION_CRITICAL_INTERRUPT);
}
}
}
else
{
fatalerror("PPC: Unknown IRQ line %d\n", irqline);
}
}
static void ppc403_dma_set_irq_line(int dma, int state)
{
UINT32 mask = (1 << (3 - dma)) << 20;
if( state ) {
if( EXIER & mask ) {
ppc.exisr |= mask;
ppc.interrupt_pending |= 0x1;
}
}
}
#endif
#ifdef PPC_DRC
static void ppc403_dma_set_irq_line(int dma, int state)
{
UINT32 mask = (1 << (3 - dma)) << 20;
if( state ) {
if( EXIER & mask ) {
ppc.exisr |= mask;
ppc.exception_pending |= 0x1;
}
}
}
#endif
#ifndef PPC_DRC
static void ppc_dccci(UINT32 op)
{
}
static void ppc_dcread(UINT32 op)
{
}
static void ppc_icbt(UINT32 op)
{
}
static void ppc_iccci(UINT32 op)
{
}
static void ppc_icread(UINT32 op)
{
}
static void ppc_rfci(UINT32 op)
{
UINT32 msr;
ppc.npc = ppc.srr2;
msr = ppc.srr3;
ppc_set_msr( msr );
}
#endif
static void ppc_mfdcr(UINT32 op)
{
REG(RT) = ppc_get_dcr(SPR);
}
static void ppc_mtdcr(UINT32 op)
{
ppc_set_dcr(SPR, REG(RS));
}
static void ppc_wrtee(UINT32 op)
{
if( REG(RS) & 0x8000 )
ppc_set_msr( ppc_get_msr() | MSR_EE);
else
ppc_set_msr( ppc_get_msr() & ~MSR_EE);
}
static void ppc_wrteei(UINT32 op)
{
if( op & 0x8000 )
ppc_set_msr( ppc_get_msr() | MSR_EE);
else
ppc_set_msr( ppc_get_msr() & ~MSR_EE);
}
/**************************************************************************/
/* PPC403 Serial Port */
static UINT8 ppc403_spu_r(UINT32 a)
{
switch(a & 0xf)
{
case 0x0: return ppc.spu.spls | 0x6; /* transmit buffer is always empty */
case 0x2: return ppc.spu.sphs;
case 0x4: return (ppc.spu.brd >> 8) & 0xf;
case 0x5: return (ppc.spu.brd & 0xff);
case 0x6: return ppc.spu.spctl;
case 0x7: return ppc.spu.sprc;
case 0x8: return ppc.spu.sptc;
case 0x9: return ppc.spu.sprb;
default: fatalerror("ppc: spu_r: %02X\n", a & 0xf);
}
}
static void ppc403_spu_w(UINT32 a, UINT8 d)
{
switch(a & 0xf)
{
case 0x0:
if( d & 0x80 ) ppc.spu.spls &= ~0x80;
if( d & 0x40 ) ppc.spu.spls &= ~0x40;
if( d & 0x20 ) ppc.spu.spls &= ~0x20;
if( d & 0x10 ) ppc.spu.spls &= ~0x10;
if( d & 0x08 ) ppc.spu.spls &= ~0x08;
break;
case 0x2:
ppc.spu.sphs = d;
break;
case 0x4:
ppc.spu.brd &= 0xff;
ppc.spu.brd |= (d << 8);
break;
case 0x5:
ppc.spu.brd &= 0xff00;
ppc.spu.brd |= d;
if (ppc.iocr & 0x2) {
osd_printf_debug("ppc: SPU Baud rate: %d\n", (3686400 / (ppc.spu.brd + 1)) / 16);
} else {
osd_printf_debug("ppc: SPU Baud rate: %d\n", (33333333 / (ppc.spu.brd + 1)) / 16);
}
break;
case 0x6:
ppc.spu.spctl = d;
break;
case 0x7:
ppc.spu.sprc = d;
if (ppc.spu.sprc & 0x80) /* enable RX */
{
/*
int baud_rate;
if (ppc.iocr & 0x2) {
baud_rate = (3686400 / (ppc.spu.brd + 1)) / 16;
} else {
baud_rate = (33333333 / (ppc.spu.brd + 1)) / 16;
}
*/
/* check if serial port is hooked to a DMA channel */
/* if so, do a DMA operation */
if( ((((ppc.spu.sprc >> 5) & 0x3) == 2) && (ppc.dma[2].cr & DMA_CE)) ||
((((ppc.spu.sprc >> 5) & 0x3) == 3) && (ppc.dma[3].cr & DMA_CE)) )
{
int i;
int ch = (ppc.spu.sprc >> 5) & 0x3;
// osd_printf_debug("ppc: DMA from serial port on channel %d (DA: %08X)\n", ch, ppc.dma[ch].da);
if (spu_rx_dma_handler)
{
int length = ppc.dma[ch].ct;
spu_rx_dma_handler(length);
for (i=0; i < length; i++)
{
ppc.program->write_byte(ppc.dma[ch].da++, spu_rx_dma_ptr[i]);
}
}
ppc.dmasr |= (1 << (27 - ch));
/* generate interrupts */
if( ppc.dma[ch].cr & DMA_CIE )
{
ppc403_dma_set_irq_line( ch, PULSE_LINE );
}
/* set receive buffer full */
ppc.spu.spls = 0x80;
#ifndef PPC_DRC
ppc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
#else
ppcdrc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
#endif
}
}
else /* disable RX */
{
}
break;
case 0x8:
ppc.spu.sptc = d;
break;
case 0x9:
ppc.spu.sptb = d;
ppc403_spu_tx_callback(NULL/* Machine */, NULL, cpunum_get_active());
break;
default:
fatalerror("ppc: spu_w: %02X, %02X\n", a & 0xf, d);
break;
}
//osd_printf_debug("spu_w: %02X, %02X at %08X\n", a & 0xf, d, ppc.pc);
}
void ppc403_spu_rx(UINT8 data)
{
ppc.spu.sprb = data;
/* set receive buffer full */
ppc.spu.spls = 0x80;
/* generate interrupt if DMA is disabled and RBR interrupt is enabled */
if (((ppc.spu.sprc >> 5) & 0x3) == 0x01) {
#ifndef PPC_DRC
ppc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
#else
ppcdrc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
#endif
}
}
static TIMER_CALLBACK( ppc403_spu_rx_callback )
{
if (spu_rx_handler != NULL)
{
ppc403_spu_rx(spu_rx_handler());
}
}
static TIMER_CALLBACK( ppc403_spu_tx_callback )
{
if (spu_tx_handler != NULL)
{
spu_tx_handler(ppc.spu.sptb);
/* generate interrupt if DMA is disabled and TBR interrupt is enabled */
if (((ppc.spu.sptc >> 5) & 0x3) == 0x01) {
#ifndef PPC_DRC
ppc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
#else
ppcdrc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
#endif
}
}
}
void ppc403_install_spu_rx_handler(SPU_RX_HANDLER rx_handler)
{
spu_rx_handler = rx_handler;
}
void ppc403_install_spu_tx_handler(SPU_TX_HANDLER tx_handler)
{
spu_tx_handler = tx_handler;
}
void ppc403_spu_rx_dma(UINT8 *data, int length)
{
}
void ppc403_install_spu_rx_dma_handler(PPC_DMA_HANDLER rx_dma_handler, UINT8 *buffer)
{
spu_rx_dma_handler = rx_dma_handler;
spu_rx_dma_ptr = buffer;
}
void ppc403_install_spu_tx_dma_handler(PPC_DMA_HANDLER tx_dma_handler, UINT8 *buffer)
{
spu_tx_dma_handler = tx_dma_handler;
spu_tx_dma_ptr = buffer;
}
/*********************************************************************************/
/* PPC 403 DMA */
static const int dma_transfer_width[4] = { 1, 2, 4, 16 };
void ppc403_install_dma_read_handler(int ch, PPC_DMA_HANDLER dma_handler, UINT8 *buffer)
{
dma_read_handler[ch] = dma_handler;
dma_read_ptr[ch] = buffer;
}
void ppc403_install_dma_write_handler(int ch, PPC_DMA_HANDLER dma_handler, UINT8 *buffer)
{
dma_write_handler[ch] = dma_handler;
dma_write_ptr[ch] = buffer;
}
static void ppc403_dma_exec(int ch)
{
int i;
int dai, sai, width;
/* Is the DMA channel enabled ? */
if( ppc.dma[ch].cr & DMA_CE )
{
/* transfer width */
width = dma_transfer_width[(ppc.dma[ch].cr >> 26) & 0x3];
if( ppc.dma[ch].cr & DMA_DAI )
dai = width;
else
dai = 0; /* DA not incremented */
if( ppc.dma[ch].cr & DMA_SAI )
sai = width;
else
sai = 0; /* SA not incremented */
/* transfer mode */
switch( (ppc.dma[ch].cr >> 21) & 0x3 )
{
case 0: /* buffered DMA */
if( ppc.dma[ch].cr & DMA_TD ) /* peripheral to mem */
{
// nothing to do for now */
}
else /* mem to peripheral */
{
/* check if the serial port is hooked to channel 2 or 3 */
if( (ch == 2 && ((ppc.spu.sptc >> 5) & 0x3) == 2) ||
(ch == 3 && ((ppc.spu.sptc >> 5) & 0x3) == 3) )
{
osd_printf_debug("ppc: dma_exec: DMA to serial port on channel %d (DA: %08X)\n", ch, ppc.dma[ch].da);
if (spu_tx_dma_handler)
{
int length = ppc.dma[ch].ct;
for( i=0; i < length; i++ ) {
spu_tx_dma_ptr[i] = ppc.program->read_byte(ppc.dma[ch].da++);
}
spu_tx_dma_handler(length);
}
#ifndef PPC_DRC
ppc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
#else
ppcdrc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
#endif
}
else {
fatalerror("ppc: dma_exec: buffered DMA to unknown peripheral ! (channel %d)\n", ch);
}
}
break;
case 1: /* fly-by DMA */
fatalerror("ppc: dma_exec: fly-by DMA not implemented\n");
break;
case 2: /* software initiated mem-to-mem DMA */
//osd_printf_debug("ppc: DMA (%d, SW mem-to-mem): SA = %08X, DA = %08X, CT = %08X\n", ch, ppc.dma[ch].sa, ppc.dma[ch].da, ppc.dma[ch].ct);
switch(width)
{
case 1: /* Byte transfer */
for (i=0; i < ppc.dma[ch].ct; i++)
{
UINT8 b = READ8(ppc.dma[ch].sa);
WRITE8(ppc.dma[ch].da, b);
ppc.dma[ch].sa += sai;
ppc.dma[ch].da += dai;
}
break;
case 2: /* Word transfer */
for (i=0; i < ppc.dma[ch].ct; i++)
{
UINT16 w = READ16(ppc.dma[ch].sa);
WRITE16(ppc.dma[ch].da, w);
ppc.dma[ch].sa += sai;
ppc.dma[ch].da += dai;
}
break;
case 4: /* Double word transfer */
for (i=0; i < ppc.dma[ch].ct; i++)
{
UINT32 d = READ32(ppc.dma[ch].sa);
WRITE32(ppc.dma[ch].da, d);
ppc.dma[ch].sa += sai;
ppc.dma[ch].da += dai;
}
break;
case 16: /* 16-byte transfer */
for (i=0; i < ppc.dma[ch].ct; i++)
{
UINT32 d1 = READ32(ppc.dma[ch].sa+0);
UINT32 d2 = READ32(ppc.dma[ch].sa+4);
UINT32 d3 = READ32(ppc.dma[ch].sa+8);
UINT32 d4 = READ32(ppc.dma[ch].sa+12);
WRITE32(ppc.dma[ch].da+0, d1);
WRITE32(ppc.dma[ch].da+4, d2);
WRITE32(ppc.dma[ch].da+8, d3);
WRITE32(ppc.dma[ch].da+12, d4);
ppc.dma[ch].sa += 16;
ppc.dma[ch].da += 16;
}
break;
default:
fatalerror("dma: dma_exec: SW mem-to-mem DMA, width = %d\n", width);
}
break;
case 3: /* hardware initiated mem-to-mem DMA */
fatalerror("ppc: dma_exec: HW mem-to-mem DMA not implemented\n");
break;
}
ppc.dmasr |= (1 << (27 - ch));
/* DEBUG: check for not yet supported features */
if( (ppc.dma[ch].cr & DMA_TCE) == 0 )
fatalerror("ppc: dma_exec: DMA_TCE == 0\n");
if( ppc.dma[ch].cr & DMA_CH )
fatalerror("ppc: dma_exec: DMA chaining not implemented\n");
/* generate interrupts */
if( ppc.dma[ch].cr & DMA_CIE )
ppc403_dma_set_irq_line( ch, PULSE_LINE );
}
}
/*********************************************************************************/
static UINT8 ppc403_read8(address_space &space, UINT32 a)
{
if(a >= 0x40000000 && a <= 0x4000000f) /* Serial Port */
return ppc403_spu_r(a);
return space.read_byte(a);
}
#define ppc403_read16 memory_read_word_32be
#define ppc403_read32 memory_read_dword_32be
static void ppc403_write8(address_space &space, UINT32 a, UINT8 d)
{
if( a >= 0x40000000 && a <= 0x4000000f ) /* Serial Port */
{
ppc403_spu_w(a, d);
return;
}
space.write_byte(a, d);
}
#define ppc403_write16 memory_write_word_32be
#define ppc403_write32 memory_write_dword_32be
static UINT16 ppc403_read16_unaligned(address_space &space, UINT32 a)
{
fatalerror("ppc: Unaligned read16 %08X at %08X\n", a, ppc.pc);
return 0;
}
static UINT32 ppc403_read32_unaligned(address_space &space, UINT32 a)
{
fatalerror("ppc: Unaligned read32 %08X at %08X\n", a, ppc.pc);
return 0;
}
static void ppc403_write16_unaligned(address_space &space, UINT32 a, UINT16 d)
{
fatalerror("ppc: Unaligned write16 %08X, %04X at %08X\n", a, d, ppc.pc);
}
static void ppc403_write32_unaligned(address_space &space, UINT32 a, UINT32 d)
{
fatalerror("ppc: Unaligned write32 %08X, %08X at %08X\n", a, d, ppc.pc);
}

View File

@ -1,279 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
static void ppc_dsa(UINT32 op)
{
UINT32 msr = ppc_get_msr();
msr &= ~(MSR_SA | MSR_EE | MSR_PR | MSR_AP);
if (ppc.esasrr & 0x8) msr |= MSR_PR;
if (ppc.esasrr & 0x4) msr |= MSR_AP;
if (ppc.esasrr & 0x2) msr |= MSR_SA;
if (ppc.esasrr & 0x1) msr |= MSR_EE;
ppc_set_msr(msr);
}
static void ppc_esa(UINT32 op)
{
int sa, ee, pr, ap;
UINT32 msr = ppc_get_msr();
sa = (msr & MSR_SA) ? 1 : 0;
ee = (msr & MSR_EE) ? 1 : 0;
pr = (msr & MSR_PR) ? 1 : 0;
ap = (msr & MSR_AP) ? 1 : 0;
ppc.esasrr = (pr << 3) | (ap << 2) | (sa << 1) | (ee);
msr &= ~(MSR_EE | MSR_PR | MSR_AP);
msr |= MSR_SA;
ppc_set_msr(msr);
}
#ifndef PPC_DRC
static void ppc_tlbli(UINT32 op)
{
}
static void ppc_tlbld(UINT32 op)
{
}
#endif
#ifndef PPC_DRC
void ppc602_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 = ppc.ibr | 0x0500;
ppc.interrupt_pending &= ~0x1;
}
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 = ppc.ibr | 0x0900;
ppc.interrupt_pending &= ~0x2;
}
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;
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0700;
else
ppc.npc = ppc.ibr | 0x0700;
}
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;
if( msr & MSR_IP )
ppc.npc = 0xfff00000 | 0x0c00;
else
ppc.npc = ppc.ibr | 0x0c00;
}
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 = ppc.ibr | 0x1400;
ppc.interrupt_pending &= ~0x4;
}
break;
default:
fatalerror("ppc: Unhandled exception %d\n", exception);
break;
}
}
static void ppc602_set_irq_line(int irqline, int state)
{
if( state ) {
ppc.interrupt_pending |= 0x1;
if (ppc.irq_callback)
{
ppc.irq_callback(ppc.device, irqline);
}
}
}
static void ppc602_set_smi_line(int state)
{
if( state ) {
ppc.interrupt_pending |= 0x4;
}
}
INLINE void ppc602_check_interrupts(void)
{
if (MSR & MSR_EE)
{
if (ppc.interrupt_pending != 0)
{
if (ppc.interrupt_pending & 0x1)
{
ppc602_exception(EXCEPTION_IRQ);
}
else if (ppc.interrupt_pending & 0x2)
{
ppc602_exception(EXCEPTION_DECREMENTER);
}
else if (ppc.interrupt_pending & 0x4)
{
ppc602_exception(EXCEPTION_SMI);
}
}
}
}
static CPU_RESET( ppc602 )
{
ppc.pc = ppc.npc = 0xfff00100;
ppc_set_msr(0x40);
ppc.hid0 = 1;
ppc.interrupt_pending = 0;
}
static CPU_EXECUTE( ppc602 )
{
int exception_type;
UINT32 opcode;
ppc_tb_base_icount = ppc_icount;
ppc_dec_base_icount = ppc_icount;
// check if decrementer exception occurs during execution
if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
{
ppc_dec_trigger_cycle = ppc_icount - DEC;
}
else
{
ppc_dec_trigger_cycle = 0x7fffffff;
}
// MinGW's optimizer kills setjmp()/longjmp()
SETJMP_GNUC_PROTECT();
exception_type = setjmp(ppc.exception_jmpbuf);
if (exception_type)
{
ppc.npc = ppc.pc;
ppc602_exception(exception_type);
}
while( ppc_icount > 0 )
{
ppc.pc = ppc.npc;
debugger_instruction_hook(device, ppc.pc);
if (MSR & MSR_IR)
opcode = ppc_readop_translated(ppc.program, ppc.pc);
else
opcode = ROPCODE64(ppc.pc);
ppc.npc = ppc.pc + 4;
switch(opcode >> 26)
{
case 19: ppc.optable19[(opcode >> 1) & 0x3ff](opcode); break;
case 31: ppc.optable31[(opcode >> 1) & 0x3ff](opcode); break;
case 59: ppc.optable59[(opcode >> 1) & 0x3ff](opcode); break;
case 63: ppc.optable63[(opcode >> 1) & 0x3ff](opcode); break;
default: ppc.optable[opcode >> 26](opcode); break;
}
ppc_icount--;
if(ppc_icount == ppc_dec_trigger_cycle) {
ppc.interrupt_pending |= 0x2;
}
ppc602_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
DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2));
}
#endif // PPC_DRC

View File

@ -1,285 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
break;
default:
fatalerror("ppc: Unhandled exception %d\n", exception);
break;
}
}
static void ppc603_set_irq_line(int irqline, int state)
{
if( state ) {
ppc.interrupt_pending |= 0x1;
if (ppc.irq_callback)
{
ppc.irq_callback(ppc.device, irqline);
}
}
}
static void ppc603_set_smi_line(int state)
{
if( state ) {
ppc.interrupt_pending |= 0x4;
}
}
INLINE 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);
}
}
}
}
static CPU_RESET( ppc603 )
{
ppc.pc = ppc.npc = 0xfff00100;
ppc_set_msr(0x40);
ppc.hid0 = 1;
ppc.interrupt_pending = 0;
}
static CPU_EXECUTE( ppc603 )
{
int exception_type;
UINT32 opcode;
ppc_tb_base_icount = ppc_icount;
ppc_dec_base_icount = ppc_icount + ppc.dec_frac;
// check if decrementer exception occurs during execution
if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
{
ppc_dec_trigger_cycle = ppc_icount - DEC;
}
else
{
ppc_dec_trigger_cycle = 0x7fffffff;
}
// MinGW's optimizer kills setjmp()/longjmp()
SETJMP_GNUC_PROTECT();
exception_type = setjmp(ppc.exception_jmpbuf);
if (exception_type)
{
ppc.npc = ppc.pc;
ppc603_exception(exception_type);
}
while( ppc_icount > 0 )
{
ppc.pc = ppc.npc;
debugger_instruction_hook(device, ppc.pc);
if (MSR & MSR_IR)
opcode = ppc_readop_translated(ppc.program, ppc.pc);
else
opcode = ROPCODE64(ppc.pc);
ppc.npc = ppc.pc + 4;
switch(opcode >> 26)
{
case 19: ppc.optable19[(opcode >> 1) & 0x3ff](opcode); break;
case 31: ppc.optable31[(opcode >> 1) & 0x3ff](opcode); break;
case 59: ppc.optable59[(opcode >> 1) & 0x3ff](opcode); break;
case 63: ppc.optable63[(opcode >> 1) & 0x3ff](opcode); break;
default: ppc.optable[opcode >> 26](opcode); break;
}
ppc_icount--;
if(ppc_icount == ppc_dec_trigger_cycle) {
ppc.interrupt_pending |= 0x2;
}
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));
}

View File

@ -1,421 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
#define DUMP_PAGEFAULTS 0
INLINE UINT8 READ8(UINT32 a)
{
return ppc.read8(ppc.program, a);
}
INLINE UINT16 READ16(UINT32 a)
{
if( a & 0x1 )
return ppc.read16_unaligned(ppc.program, a);
else
return ppc.read16(ppc.program, a);
}
INLINE UINT32 READ32(UINT32 a)
{
if( a & 0x3 )
return ppc.read32_unaligned(ppc.program, a);
else
return ppc.read32(ppc.program, a);
}
INLINE UINT64 READ64(UINT32 a)
{
if( a & 0x7 )
return ppc.read64_unaligned(ppc.program, a);
else
return ppc.read64(ppc.program, a);
}
INLINE void WRITE8(UINT32 a, UINT8 d)
{
ppc.write8(ppc.program, a, d);
}
INLINE void WRITE16(UINT32 a, UINT16 d)
{
if( a & 0x1 )
ppc.write16_unaligned(ppc.program, a, d);
else
ppc.write16(ppc.program, a, d);
}
INLINE void WRITE32(UINT32 a, UINT32 d)
{
if( ppc.reserved ) {
if( a == ppc.reserved_address ) {
ppc.reserved = 0;
}
}
if( a & 0x3 )
ppc.write32_unaligned(ppc.program, a, d);
else
ppc.write32(ppc.program, a, d);
}
INLINE void WRITE64(UINT32 a, UINT64 d)
{
if( a & 0x7 )
ppc.write64_unaligned(ppc.program, a, d);
else
ppc.write64(ppc.program, a, d);
}
/***********************************************************************/
static UINT16 ppc_read16_unaligned(address_space &space, UINT32 a)
{
return ((UINT16)ppc.read8(space, a+0) << 8) | ((UINT16)ppc.read8(space, a+1) << 0);
}
static UINT32 ppc_read32_unaligned(address_space &space, UINT32 a)
{
return ((UINT32)ppc.read8(space, a+0) << 24) | ((UINT32)ppc.read8(space, a+1) << 16) |
((UINT32)ppc.read8(space, a+2) << 8) | ((UINT32)ppc.read8(space, a+3) << 0);
}
static UINT64 ppc_read64_unaligned(address_space &space, UINT32 a)
{
return ((UINT64)READ32(space, a+0) << 32) | (UINT64)(READ32(space, a+4));
}
static void ppc_write16_unaligned(address_space &space, UINT32 a, UINT16 d)
{
ppc.write8(space, a+0, (UINT8)(d >> 8));
ppc.write8(space, a+1, (UINT8)(d));
}
static void ppc_write32_unaligned(address_space &space, UINT32 a, UINT32 d)
{
ppc.write8(space, a+0, (UINT8)(d >> 24));
ppc.write8(space, a+1, (UINT8)(d >> 16));
ppc.write8(space, a+2, (UINT8)(d >> 8));
ppc.write8(space, a+3, (UINT8)(d >> 0));
}
static void ppc_write64_unaligned(address_space &space, UINT32 a, UINT64 d)
{
ppc.write32(space, a+0, (UINT32)(d >> 32));
ppc.write32(space, a+4, (UINT32)(d));
}
/***********************************************************************/
#define DSISR_PAGE 0x40000000
#define DSISR_PROT 0x08000000
#define DSISR_STORE 0x02000000
enum
{
PPC_TRANSLATE_DATA = 0x0000,
PPC_TRANSLATE_CODE = 0x0001,
PPC_TRANSLATE_READ = 0x0000,
PPC_TRANSLATE_WRITE = 0x0002,
PPC_TRANSLATE_NOEXCEPTION = 0x0004
};
static int ppc_is_protected(UINT32 pp, int flags)
{
if (flags & PPC_TRANSLATE_WRITE)
{
if ((pp & 0x00000003) != 0x00000002)
return TRUE;
}
else
{
if ((pp & 0x00000003) == 0x00000000)
return TRUE;
}
return FALSE;
}
static int ppc_translate_address(offs_t *addr_ptr, int flags)
{
const BATENT *bat;
UINT32 address;
UINT32 sr, vsid, hash;
UINT32 pteg_address;
UINT32 target_pte, bl, mask;
UINT64 pte;
UINT64 *pteg_ptr[2];
int i, hash_type;
UINT32 dsisr = DSISR_PROT;
bat = (flags & PPC_TRANSLATE_CODE) ? ppc.ibat : ppc.dbat;
address = *addr_ptr;
/* first check the block address translation table */
for (i = 0; i < 4; i++)
{
if (bat[i].u & ((MSR & MSR_PR) ? 0x00000001 : 0x00000002))
{
bl = bat[i].u & 0x00001FFC;
mask = (~bl << 15) & 0xFFFE0000;
if ((address & mask) == (bat[i].u & 0xFFFE0000))
{
if (ppc_is_protected(bat[i].l, flags))
goto exception;
*addr_ptr = (bat[i].l & 0xFFFE0000)
| (address & ((bl << 15) | 0x0001FFFF));
return 1;
}
}
}
/* now try page address translation */
sr = ppc.sr[(address >> 28) & 0x0F];
if (sr & 0x80000000)
{
/* direct store translation */
if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0)
fatalerror("ppc: direct store translation not yet implemented\n");
return 0;
}
else
{
/* is no execute is set? */
if ((flags & PPC_TRANSLATE_CODE) && (sr & 0x10000000))
goto exception;
vsid = sr & 0x00FFFFFF;
hash = (vsid & 0x0007FFFF) ^ ((address >> 12) & 0xFFFF);
target_pte = (vsid << 7) | ((address >> 22) & 0x3F) | 0x80000000;
/* we have to try both types of hashes */
for (hash_type = 0; hash_type <= 1; hash_type++)
{
pteg_address = (ppc.sdr1 & 0xFFFF0000)
| (((ppc.sdr1 & 0x01FF) & (hash >> 10)) << 16)
| ((hash & 0x03FF) << 6);
pteg_ptr[hash_type] = ppc->program->get_read_ptr(pteg_address);
if (pteg_ptr[hash_type])
{
for (i = 0; i < 8; i++)
{
pte = pteg_ptr[hash_type][i];
/* is valid? */
if (((pte >> 32) & 0xFFFFFFFF) == target_pte)
{
if (ppc_is_protected((UINT32) pte, flags))
goto exception;
*addr_ptr = ((UINT32) (pte & 0xFFFFF000))
| (address & 0x0FFF);
return 1;
}
}
}
hash ^= 0x7FFFF;
target_pte ^= 0x40;
}
if (DUMP_PAGEFAULTS)
{
osd_printf_debug("PAGE FAULT: address=%08X PC=%08X SDR1=%08X MSR=%08X\n", address, ppc.pc, ppc.sdr1, ppc.msr);
osd_printf_debug("\n");
for (i = 0; i < 4; i++)
{
bl = bat[i].u & 0x00001FFC;
mask = (~bl << 15) & 0xFFFE0000;
osd_printf_debug(" BAT[%d]=%08X%08X (A & %08X = %08X)\n", i, bat[i].u, bat[i].l,
mask, bat[i].u & 0xFFFE0000);
}
osd_printf_debug("\n");
osd_printf_debug(" VSID=%06X HASH=%05X HASH\'=%05X\n", vsid, hash, hash ^ 0x7FFFF);
for (hash_type = 0; hash_type <= 1; hash_type++)
{
if (pteg_ptr[hash_type])
{
for (i = 0; i < 8; i++)
{
pte = pteg_ptr[hash_type][i];
osd_printf_debug(" PTE[%i%c]=%08X%08X\n",
i,
hash_type ? '\'' : ' ',
(unsigned) (pte >> 32),
(unsigned) (pte >> 0));
}
}
}
}
}
dsisr = DSISR_PAGE;
exception:
/* lookup failure - exception */
if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0)
{
if (flags & PPC_TRANSLATE_CODE)
{
ppc_exception(EXCEPTION_ISI);
}
else
{
ppc.dar = address;
if (flags & PPC_TRANSLATE_WRITE)
ppc.dsisr = dsisr | DSISR_STORE;
else
ppc.dsisr = dsisr;
ppc_exception(EXCEPTION_DSI);
}
}
return 0;
}
static int ppc_translate_address_cb(address_spacenum space, offs_t *addr)
{
int success = 1;
if (space == AS_PROGRAM)
{
if (MSR & MSR_DR)
success = ppc_translate_address(addr, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION);
}
return success;
}
static UINT8 ppc_read8_translated(address_space &space, offs_t address)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ);
return space.read_byte(address);
}
static UINT16 ppc_read16_translated(address_space &space, offs_t address)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ);
return space.read_word(address);
}
static UINT32 ppc_read32_translated(address_space &space, offs_t address)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ);
return space.read_dword(address);
}
static UINT64 ppc_read64_translated(address_space &space, offs_t address)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ);
return space.read_qword(address);
}
static void ppc_write8_translated(address_space &space, offs_t address, UINT8 data)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE);
space.write_byte(address, data);
}
static void ppc_write16_translated(address_space &space, offs_t address, UINT16 data)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE);
space.write_word(address, data);
}
static void ppc_write32_translated(address_space &space, offs_t address, UINT32 data)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE);
space.write_dword(address, data);
}
static void ppc_write64_translated(address_space &space, offs_t address, UINT64 data)
{
ppc_translate_address(&address, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE);
space.write_qword(address, data);
}
#ifndef PPC_DRC
static UINT32 ppc_readop_translated(address_space &space, offs_t address)
{
ppc_translate_address(&address, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ);
return space.read_dword(address);
}
#endif
/***********************************************************************/
static CPU_DISASSEMBLE( ppc )
{
UINT32 op;
op = BIG_ENDIANIZE_INT32(*((UINT32 *) oprom));
return ppc_dasm_one(buffer, pc, op);
}
/***********************************************************************/
static CPU_READOP( ppc )
{
if (!(ppc.msr & MSR_IR))
return 0;
*value = 0;
if (ppc_translate_address(&offset, PPC_TRANSLATE_CODE | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION))
{
switch(size)
{
case 1: *value = ppc.program->read_byte(offset); break;
case 2: *value = ppc.program->read_word(offset); break;
case 4: *value = ppc.program->read_dword(offset); break;
case 8: *value = ppc.program->read_qword(offset); break;
}
}
return 1;
}
static CPU_READ( ppc )
{
if (!(ppc.msr & MSR_DR))
return 0;
*value = 0;
if (ppc_translate_address(&offset, PPC_TRANSLATE_DATA | PPC_TRANSLATE_READ | PPC_TRANSLATE_NOEXCEPTION))
{
switch(size)
{
case 1: *value = ppc.program->read_byte(offset); break;
case 2: *value = ppc.program->read_word(offset); break;
case 4: *value = ppc.program->read_dword(offset); break;
case 8: *value = ppc.program->read_qword(offset); break;
}
}
return 1;
}
static CPU_WRITE( ppc )
{
if (!(ppc.msr & MSR_DR))
return 0;
if (ppc_translate_address(&offset, PPC_TRANSLATE_DATA | PPC_TRANSLATE_WRITE | PPC_TRANSLATE_NOEXCEPTION))
{
switch(size)
{
case 1: ppc.program->write_byte(offset, value); break;
case 2: ppc.program->write_word(offset, value); break;
case 4: ppc.program->write_dword(offset, value); break;
case 8: ppc.program->write_qword(offset, value); break;
}
}
return 1;
}

View File

@ -1,152 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
#pragma once
#ifndef __PPC_OPS_H__
#define __PPC_OPS_H__
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 }
};
#endif /* __PPC_OPS_H__ */

File diff suppressed because it is too large Load Diff