mirror of
https://github.com/holub/mame
synced 2025-05-04 21:43:05 +03:00
Various improvements to the Konami Viper driver [Ville Linde]
This commit is contained in:
parent
bf0a319991
commit
83a880a44f
@ -37,14 +37,79 @@ DASM code snippets:
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Software notes (as per Police 911)
|
||||
-- VL - 22.02.2010
|
||||
|
||||
IRQs:
|
||||
|
||||
IRQ0: ??? (Task 4)
|
||||
IRQ1: unused
|
||||
IRQ2: unused
|
||||
IRQ3: ??? (Task 5, sound?)
|
||||
IRQ4: Voodoo3 Currently only for User Interrupt Command, maybe a more extensive handler gets installed later?
|
||||
|
||||
I2C: ??? (no task switch) what drives this? network?
|
||||
DMA0: unused
|
||||
DMA1: unused
|
||||
IIVPR3: unused
|
||||
|
||||
Memory:
|
||||
|
||||
0x000001E0: Current task
|
||||
0x000001E1: Current FPU task
|
||||
0x000001E4: Scheduled tasks bitvector (bit 31 = task0, etc.)
|
||||
0x00000A00...BFF: Task structures
|
||||
0x00-03: unknown
|
||||
0x04: unknown
|
||||
0x05: if non-zero, this task uses FPU
|
||||
0x06-07: unknown
|
||||
0x08: unknown mem pointer, task stack pointer?
|
||||
0x0c: pointer to task PC (also top of stack?)
|
||||
|
||||
|
||||
0x00000310: Global timer 0 IRQ handler
|
||||
0x00000320: Global timer 1 IRQ handler
|
||||
0x00000330: Global timer 2 IRQ handler
|
||||
0x00000340: Global timer 3 IRQ handler
|
||||
0x00000350: IRQ0 handler
|
||||
0x00000360: IRQ1 handler
|
||||
0x00000370: IRQ2 handler
|
||||
0x00000380: IRQ3 handler
|
||||
0x00000390: IRQ4 handler
|
||||
0x000003a0: I2C IRQ handler
|
||||
0x000003b0: DMA0 IRQ handler
|
||||
0x000003c0: DMA1 IRQ handler
|
||||
0x000003d0: Message Unit IRQ handler
|
||||
|
||||
0x000004e4: Global timer 0 IRQ handler function ptr
|
||||
0x000004e8: Global timer 1 IRQ handler function ptr
|
||||
0x000004ec: Global timer 2 IRQ handler function ptr
|
||||
0x000004f0: Global timer 3 IRQ handler function ptr
|
||||
|
||||
|
||||
Functions of interest:
|
||||
|
||||
0x0000f7b4: SwitchTask()
|
||||
0x00009d00: LoadProgram(): R3 = ptr to filename
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/powerpc/ppc.h"
|
||||
#include "machine/pci.h"
|
||||
#include "memconv.h"
|
||||
#include "devconv.h"
|
||||
#include "machine/idectrl.h"
|
||||
#include "machine/timekpr.h"
|
||||
#include "video/voodoo.h"
|
||||
|
||||
#define VIPER_DEBUG_LOG
|
||||
|
||||
static SCREEN_UPDATE(viper)
|
||||
{
|
||||
device_t *device = screen->machine().device("voodoo");
|
||||
return voodoo_update(device, bitmap, cliprect) ? 0 : UPDATE_HAS_NOT_CHANGED;
|
||||
}
|
||||
|
||||
class viper_state : public driver_device
|
||||
{
|
||||
@ -57,25 +122,16 @@ public:
|
||||
int m_cf_card_ide;
|
||||
int m_unk1_bit;
|
||||
UINT32 m_voodoo3_pci_reg[0x100];
|
||||
|
||||
};
|
||||
|
||||
|
||||
//#define VIPER_DEBUG_LOG
|
||||
|
||||
static SCREEN_UPDATE(viper)
|
||||
{
|
||||
device_t *device = screen->machine().device("voodoo");
|
||||
return voodoo_update(device, bitmap, cliprect) ? 0 : UPDATE_HAS_NOT_CHANGED;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static UINT32 mpc8240_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
|
||||
{
|
||||
viper_state *state = device->machine().driver_data<viper_state>();
|
||||
#ifdef VIPER_DEBUG_LOG
|
||||
printf("MPC8240: PCI read %d, %02X, %08X\n", function, reg, mem_mask);
|
||||
// printf("MPC8240: PCI read %d, %02X, %08X\n", function, reg, mem_mask);
|
||||
#endif
|
||||
|
||||
switch (reg)
|
||||
@ -89,7 +145,7 @@ static void mpc8240_pci_w(device_t *busdevice, device_t *device, int function, i
|
||||
{
|
||||
viper_state *state = device->machine().driver_data<viper_state>();
|
||||
#ifdef VIPER_DEBUG_LOG
|
||||
printf("MPC8240: PCI write %d, %02X, %08X, %08X\n", function, reg, data, mem_mask);
|
||||
// printf("MPC8240: PCI write %d, %02X, %08X, %08X\n", function, reg, data, mem_mask);
|
||||
#endif
|
||||
|
||||
COMBINE_DATA(state->m_mpc8240_regs + (reg/4));
|
||||
@ -98,77 +154,319 @@ static void mpc8240_pci_w(device_t *busdevice, device_t *device, int function, i
|
||||
|
||||
static READ64_DEVICE_HANDLER( pci_config_addr_r )
|
||||
{
|
||||
return pci_64be_r(device, 0, U64(0x00000000ffffffff));
|
||||
return pci_64be_r(device, 0, U64(0xffffffff00000000));
|
||||
}
|
||||
|
||||
static WRITE64_DEVICE_HANDLER( pci_config_addr_w )
|
||||
{
|
||||
pci_64be_w(device, 0, data, U64(0x00000000ffffffff));
|
||||
pci_64be_w(device, 0, data, U64(0xffffffff00000000));
|
||||
}
|
||||
|
||||
static READ64_DEVICE_HANDLER( pci_config_data_r )
|
||||
{
|
||||
return pci_64be_r(device, 1, U64(0xffffffff00000000)) << 32;
|
||||
return pci_64be_r(device, 1, U64(0x00000000ffffffff)) << 32;
|
||||
}
|
||||
|
||||
static WRITE64_DEVICE_HANDLER( pci_config_data_w )
|
||||
{
|
||||
pci_64be_w(device, 1, data >> 32, U64(0xffffffff00000000));
|
||||
pci_64be_w(device, 1, data >> 32, U64(0x00000000ffffffff));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// MPC8240 Embedded Programmable Interrupt Controller (EPIC)
|
||||
|
||||
#define MPC8240_IRQ0 0
|
||||
#define MPC8240_IRQ1 1
|
||||
#define MPC8240_IRQ2 2
|
||||
#define MPC8240_IRQ3 3
|
||||
#define MPC8240_IRQ4 4
|
||||
#define MPC8240_IRQ5 5
|
||||
#define MPC8240_IRQ6 6
|
||||
#define MPC8240_IRQ7 7
|
||||
#define MPC8240_IRQ8 8
|
||||
#define MPC8240_IRQ9 9
|
||||
#define MPC8240_IRQ10 10
|
||||
#define MPC8240_IRQ11 11
|
||||
#define MPC8240_IRQ12 12
|
||||
#define MPC8240_IRQ13 13
|
||||
#define MPC8240_IRQ14 14
|
||||
#define MPC8240_IRQ15 15
|
||||
#define MPC8240_I2C_IRQ 16
|
||||
#define MPC8240_DMA0_IRQ 17
|
||||
#define MPC8240_DMA1_IRQ 18
|
||||
#define MPC8240_MSG_IRQ 19
|
||||
#define MPC8240_GTIMER0_IRQ 20
|
||||
#define MPC8240_GTIMER1_IRQ 21
|
||||
#define MPC8240_GTIMER2_IRQ 22
|
||||
#define MPC8240_GTIMER3_IRQ 23
|
||||
|
||||
#define MPC8240_NUM_INTERRUPTS 24
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 vector;
|
||||
int priority;
|
||||
int destination;
|
||||
int active;
|
||||
int pending;
|
||||
int mask;
|
||||
} MPC8240_IRQ;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 iack;
|
||||
UINT32 eicr;
|
||||
UINT32 svr;
|
||||
|
||||
int active_irq;
|
||||
|
||||
MPC8240_IRQ irq[MPC8240_NUM_INTERRUPTS];
|
||||
|
||||
} MPC8240_EPIC;
|
||||
|
||||
|
||||
static MPC8240_EPIC epic;
|
||||
|
||||
|
||||
static void epic_update_interrupts(running_machine &machine)
|
||||
{
|
||||
int i;
|
||||
|
||||
int irq = -1;
|
||||
int priority = -1;
|
||||
|
||||
// find the highest priority pending interrupt
|
||||
for (i=MPC8240_NUM_INTERRUPTS-1; i >= 0; i--)
|
||||
{
|
||||
if (epic.irq[i].pending)
|
||||
{
|
||||
if (epic.irq[i].priority > priority)
|
||||
{
|
||||
irq = i;
|
||||
priority = epic.irq[i].priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (irq >= 0 && epic.active_irq == -1)
|
||||
{
|
||||
printf("EPIC IRQ%d taken\n", irq);
|
||||
|
||||
epic.active_irq = irq;
|
||||
epic.irq[epic.active_irq].pending = 0;
|
||||
epic.irq[epic.active_irq].active = 1;
|
||||
|
||||
epic.iack = epic.irq[epic.active_irq].vector;
|
||||
|
||||
printf("vector = %02X\n", epic.iack);
|
||||
|
||||
cputag_set_input_line(machine, "maincpu", INPUT_LINE_IRQ0, ASSERT_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
cputag_set_input_line(machine, "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
static READ32_HANDLER( epic_r )
|
||||
{
|
||||
viper_state *state = space->machine().driver_data<viper_state>();
|
||||
int reg;
|
||||
reg = offset * 4;
|
||||
|
||||
#ifdef VIPER_DEBUG_LOG
|
||||
printf("EPIC: read %08X, %08X at %08X\n", reg, mem_mask, cpu_get_pc(&space->device()));
|
||||
#endif
|
||||
|
||||
|
||||
//printf("EPIC: read %08X, %08X at %08X\n", reg, mem_mask, activecpu_get_pc());
|
||||
|
||||
switch (reg >> 16)
|
||||
{
|
||||
// 0x50000 - 0x5FFFF
|
||||
case 0x5:
|
||||
{
|
||||
switch (reg & 0xffff)
|
||||
{
|
||||
case 0x0200: // Offset 0x50200 - IRQ0 vector/priority register
|
||||
case 0x0220: // Offset 0x50220 - IRQ1 vector/priority register
|
||||
case 0x0240: // Offset 0x50240 - IRQ2 vector/priority register
|
||||
case 0x0260: // Offset 0x50260 - IRQ3 vector/priority register
|
||||
case 0x0280: // Offset 0x50280 - IRQ4 vector/priority register
|
||||
case 0x02a0: // Offset 0x502a0 - IRQ5 vector/priority register
|
||||
case 0x02c0: // Offset 0x502c0 - IRQ6 vector/priority register
|
||||
case 0x02e0: // Offset 0x502e0 - IRQ7 vector/priority register
|
||||
case 0x0300: // Offset 0x50300 - IRQ8 vector/priority register
|
||||
case 0x0320: // Offset 0x50320 - IRQ9 vector/priority register
|
||||
case 0x0340: // Offset 0x50340 - IRQ10 vector/priority register
|
||||
case 0x0360: // Offset 0x50360 - IRQ11 vector/priority register
|
||||
case 0x0380: // Offset 0x50380 - IRQ12 vector/priority register
|
||||
case 0x03a0: // Offset 0x503a0 - IRQ13 vector/priority register
|
||||
case 0x03c0: // Offset 0x503c0 - IRQ14 vector/priority register
|
||||
case 0x03e0: // Offset 0x503e0 - IRQ15 vector/priority register
|
||||
{
|
||||
int irq = ((reg & 0xffff) - 0x200) >> 5;
|
||||
int value = 0;
|
||||
|
||||
value |= epic.irq[MPC8240_IRQ0 + irq].mask ? 0x80000000 : 0;
|
||||
value |= epic.irq[MPC8240_IRQ0 + irq].priority << 16;
|
||||
value |= epic.irq[MPC8240_IRQ0 + irq].vector;
|
||||
value |= epic.irq[MPC8240_IRQ0 + irq].active ? 0x40000000 : 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 0x60000 - 0x6FFFF
|
||||
case 0x6:
|
||||
{
|
||||
switch (reg & 0xffff)
|
||||
{
|
||||
case 0x00a0: // IACK
|
||||
return state->m_epic_iack;
|
||||
|
||||
case 0x00a0: // Offset 0x600A0 - IACK
|
||||
{
|
||||
epic_update_interrupts(space->machine());
|
||||
|
||||
if (epic.active_irq >= 0)
|
||||
{
|
||||
return epic.iack;
|
||||
}
|
||||
else
|
||||
{
|
||||
// spurious vector register is returned if no pending interrupts
|
||||
return epic.svr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( epic_w )
|
||||
{
|
||||
viper_state *state = space->machine().driver_data<viper_state>();
|
||||
int reg;
|
||||
reg = offset * 4;
|
||||
|
||||
#ifdef VIPER_DEBUG_LOG
|
||||
|
||||
printf("EPIC: write %08X, %08X, %08X at %08X\n", data, reg, mem_mask, cpu_get_pc(&space->device()));
|
||||
#endif
|
||||
|
||||
switch (reg >> 16)
|
||||
{
|
||||
// 0x40000 - 0x4FFFF
|
||||
case 4:
|
||||
{
|
||||
switch (reg & 0xffff)
|
||||
{
|
||||
case 0x1030: // Offset 0x41030 - EICR
|
||||
{
|
||||
epic.eicr = data;
|
||||
if (data & 0x08000000)
|
||||
fatalerror("EPIC: serial interrupts mode not implemented");
|
||||
break;
|
||||
}
|
||||
case 0x10e0: // Offset 0x410E0 - Spurious Vector Register
|
||||
{
|
||||
epic.svr = data;
|
||||
break;
|
||||
}
|
||||
case 0x1120: // Offset 0x41120 - Global timer 0 vector/priority register
|
||||
case 0x1160: // Offset 0x41160 - Global timer 1 vector/priority register
|
||||
case 0x11a0: // Offset 0x411A0 - Global timer 2 vector/priority register
|
||||
case 0x11e0: // Offset 0x411E0 - Global timer 3 vector/priority register
|
||||
{
|
||||
int timer = ((reg & 0xffff) - 0x1120) >> 6;
|
||||
|
||||
epic.irq[MPC8240_GTIMER0_IRQ + timer].mask = (data & 0x80000000) ? 1 : 0;
|
||||
epic.irq[MPC8240_GTIMER0_IRQ + timer].priority = (data >> 16) & 0xf;
|
||||
epic.irq[MPC8240_GTIMER0_IRQ + timer].vector = data & 0xff;
|
||||
break;
|
||||
}
|
||||
case 0x1130: // Offset 0x41130 - Global timer 0 destination register
|
||||
case 0x1170: // Offset 0x41170 - Global timer 1 destination register
|
||||
case 0x11b0: // Offset 0x411B0 - Global timer 2 destination register
|
||||
case 0x11f0: // Offset 0x411F0 - Global timer 3 destination register
|
||||
{
|
||||
int timer = ((reg & 0xffff) - 0x1130) >> 6;
|
||||
|
||||
epic.irq[MPC8240_GTIMER0_IRQ + timer].destination = data & 0x1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 0x50000 - 0x5FFFF
|
||||
case 0x5:
|
||||
{
|
||||
switch (reg & 0xffff)
|
||||
{
|
||||
case 0x0200: // Offset 0x50200 - IRQ0 vector/priority register
|
||||
case 0x0220: // Offset 0x50220 - IRQ1 vector/priority register
|
||||
case 0x0240: // Offset 0x50240 - IRQ2 vector/priority register
|
||||
case 0x0260: // Offset 0x50260 - IRQ3 vector/priority register
|
||||
case 0x0280: // Offset 0x50280 - IRQ4 vector/priority register
|
||||
case 0x02a0: // Offset 0x502a0 - IRQ5 vector/priority register
|
||||
case 0x02c0: // Offset 0x502c0 - IRQ6 vector/priority register
|
||||
case 0x02e0: // Offset 0x502e0 - IRQ7 vector/priority register
|
||||
case 0x0300: // Offset 0x50300 - IRQ8 vector/priority register
|
||||
case 0x0320: // Offset 0x50320 - IRQ9 vector/priority register
|
||||
case 0x0340: // Offset 0x50340 - IRQ10 vector/priority register
|
||||
case 0x0360: // Offset 0x50360 - IRQ11 vector/priority register
|
||||
case 0x0380: // Offset 0x50380 - IRQ12 vector/priority register
|
||||
case 0x03a0: // Offset 0x503a0 - IRQ13 vector/priority register
|
||||
case 0x03c0: // Offset 0x503c0 - IRQ14 vector/priority register
|
||||
case 0x03e0: // Offset 0x503e0 - IRQ15 vector/priority register
|
||||
{
|
||||
int irq = ((reg & 0xffff) - 0x200) >> 5;
|
||||
|
||||
epic.irq[MPC8240_IRQ0 + irq].mask = (data & 0x80000000) ? 1 : 0;
|
||||
epic.irq[MPC8240_IRQ0 + irq].priority = (data >> 16) & 0xf;
|
||||
epic.irq[MPC8240_IRQ0 + irq].vector = data & 0xff;
|
||||
break;
|
||||
}
|
||||
case 0x0210: // Offset 0x50210 - IRQ0 destination register
|
||||
case 0x0230: // Offset 0x50230 - IRQ1 destination register
|
||||
case 0x0250: // Offset 0x50250 - IRQ2 destination register
|
||||
case 0x0270: // Offset 0x50270 - IRQ3 destination register
|
||||
case 0x0290: // Offset 0x50290 - IRQ4 destination register
|
||||
case 0x02b0: // Offset 0x502b0 - IRQ5 destination register
|
||||
case 0x02d0: // Offset 0x502d0 - IRQ6 destination register
|
||||
case 0x02f0: // Offset 0x502f0 - IRQ7 destination register
|
||||
case 0x0310: // Offset 0x50310 - IRQ8 destination register
|
||||
case 0x0330: // Offset 0x50330 - IRQ9 destination register
|
||||
case 0x0350: // Offset 0x50350 - IRQ10 destination register
|
||||
case 0x0370: // Offset 0x50370 - IRQ11 destination register
|
||||
case 0x0390: // Offset 0x50390 - IRQ12 destination register
|
||||
case 0x03b0: // Offset 0x503b0 - IRQ13 destination register
|
||||
case 0x03d0: // Offset 0x503d0 - IRQ14 destination register
|
||||
case 0x03f0: // Offset 0x503f0 - IRQ15 destination register
|
||||
{
|
||||
int irq = ((reg & 0xffff) - 0x210) >> 5;
|
||||
|
||||
epic.irq[MPC8240_IRQ0 + irq].destination = data & 0x1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 0x60000 - 0x6FFFF
|
||||
case 0x6:
|
||||
{
|
||||
switch (reg & 0xffff)
|
||||
{
|
||||
case 0x00b0: // EOI
|
||||
state->m_epic_iack = 0xff;
|
||||
case 0x00b0: // Offset 0x600B0 - EOI
|
||||
printf("EPIC IRQ%d cleared.\n", epic.active_irq);
|
||||
epic.irq[epic.active_irq].active = 0;
|
||||
epic.active_irq = -1;
|
||||
|
||||
epic_update_interrupts(space->machine());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,6 +481,30 @@ static WRITE64_HANDLER(epic_64be_w)
|
||||
}
|
||||
|
||||
|
||||
static void mpc8240_interrupt(running_machine &machine, int irq)
|
||||
{
|
||||
if (epic.irq[irq].mask == 0 && epic.irq[irq].priority > 0)
|
||||
{
|
||||
epic.irq[irq].pending = 1;
|
||||
|
||||
epic_update_interrupts(machine);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc8240_epic_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < MPC8240_NUM_INTERRUPTS; i++)
|
||||
{
|
||||
epic.irq[i].mask = 1;
|
||||
}
|
||||
|
||||
epic.active_irq = -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
static const UINT8 cf_card_tuples[] =
|
||||
{
|
||||
@ -243,6 +565,7 @@ static WRITE64_DEVICE_HANDLER(cf_card_data_w)
|
||||
static READ64_DEVICE_HANDLER(cf_card_r)
|
||||
{
|
||||
viper_state *state = device->machine().driver_data<viper_state>();
|
||||
|
||||
UINT64 r = 0;
|
||||
|
||||
if (ACCESSING_BITS_16_31)
|
||||
@ -289,7 +612,7 @@ static READ64_DEVICE_HANDLER(cf_card_r)
|
||||
{
|
||||
int reg = offset;
|
||||
|
||||
//printf("cf_r: %04X\n", reg);
|
||||
printf("cf_r: %04X\n", reg);
|
||||
|
||||
if ((reg >> 1) < sizeof(cf_card_tuples))
|
||||
{
|
||||
@ -307,8 +630,9 @@ static READ64_DEVICE_HANDLER(cf_card_r)
|
||||
static WRITE64_DEVICE_HANDLER(cf_card_w)
|
||||
{
|
||||
viper_state *state = device->machine().driver_data<viper_state>();
|
||||
|
||||
#ifdef VIPER_DEBUG_LOG
|
||||
printf("%s:compact_flash_w: %08X%08X, %08X, %08X%08X\n", device->machine().describe_context(), (UINT32)(data>>32), (UINT32)(data), offset, (UINT32)(mem_mask >> 32), (UINT32)(mem_mask));
|
||||
//printf("%s:compact_flash_w: %08X%08X, %08X, %08X%08X\n", device->machine().describe_context(), (UINT32)(data>>32), (UINT32)(data), offset, (UINT32)(mem_mask >> 32), (UINT32)(mem_mask));
|
||||
#endif
|
||||
|
||||
if (ACCESSING_BITS_16_31)
|
||||
@ -368,6 +692,11 @@ static WRITE64_DEVICE_HANDLER(cf_card_w)
|
||||
// cylinder high register is set to 0x00
|
||||
|
||||
ide_bus_w(device, 1, 6, 0x04);
|
||||
|
||||
ide_bus_w(device, 0, 2, 0x01);
|
||||
ide_bus_w(device, 0, 3, 0x01);
|
||||
ide_bus_w(device, 0, 4, 0x00);
|
||||
ide_bus_w(device, 0, 5, 0x00);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -383,6 +712,7 @@ static WRITE64_DEVICE_HANDLER(cf_card_w)
|
||||
static WRITE64_HANDLER(unk2_w)
|
||||
{
|
||||
viper_state *state = space->machine().driver_data<viper_state>();
|
||||
|
||||
if (ACCESSING_BITS_56_63)
|
||||
{
|
||||
state->m_cf_card_ide = 0;
|
||||
@ -416,15 +746,18 @@ static WRITE64_DEVICE_HANDLER(ata_w)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static READ64_HANDLER(unk1_r)
|
||||
{
|
||||
viper_state *state = space->machine().driver_data<viper_state>();
|
||||
|
||||
UINT64 r = 0;
|
||||
//return 0;//U64(0x0000400000000000);
|
||||
|
||||
if (ACCESSING_BITS_40_47)
|
||||
{
|
||||
r |= (UINT64)(state->m_unk1_bit << 5) << 40;
|
||||
r |= U64(0x0000400000000000);
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -433,6 +766,7 @@ static READ64_HANDLER(unk1_r)
|
||||
static WRITE64_HANDLER(unk1a_w)
|
||||
{
|
||||
viper_state *state = space->machine().driver_data<viper_state>();
|
||||
|
||||
if (ACCESSING_BITS_56_63)
|
||||
{
|
||||
state->m_unk1_bit = 1;
|
||||
@ -442,15 +776,18 @@ static WRITE64_HANDLER(unk1a_w)
|
||||
static WRITE64_HANDLER(unk1b_w)
|
||||
{
|
||||
viper_state *state = space->machine().driver_data<viper_state>();
|
||||
|
||||
if (ACCESSING_BITS_56_63)
|
||||
{
|
||||
state->m_unk1_bit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static UINT32 voodoo3_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
|
||||
{
|
||||
viper_state *state = device->machine().driver_data<viper_state>();
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: // PCI Vendor ID (0x121a = 3dfx), Device ID (0x0005 = Voodoo 3)
|
||||
@ -491,6 +828,7 @@ static UINT32 voodoo3_pci_r(device_t *busdevice, device_t *device, int function,
|
||||
static void voodoo3_pci_w(device_t *busdevice, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
viper_state *state = device->machine().driver_data<viper_state>();
|
||||
|
||||
// printf("voodoo3_pci_w: %08X, %08X\n", reg, data);
|
||||
|
||||
switch (reg)
|
||||
@ -556,37 +894,44 @@ static void voodoo3_pci_w(device_t *busdevice, device_t *device, int function, i
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static READ64_HANDLER(voodoo3_io_r)
|
||||
{
|
||||
return read64be_with_32le_handler(banshee_io_0_r, space->machine(), offset, mem_mask);
|
||||
device_t *device = space->machine().device("voodoo");
|
||||
return read64be_with_32le_device_handler(banshee_io_r, device, offset, mem_mask);
|
||||
}
|
||||
static WRITE64_HANDLER(voodoo3_io_w)
|
||||
{
|
||||
// printf("voodoo3_io_w: %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), offset, cpu_get_pc(&space->device()));
|
||||
write64be_with_32le_handler(banshee_io_0_w, space->machine(), offset, data, mem_mask);
|
||||
|
||||
device_t *device = space->machine().device("voodoo");
|
||||
write64be_with_32le_device_handler(banshee_io_w, device, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
static READ64_HANDLER(voodoo3_r)
|
||||
{
|
||||
return read64be_with_32le_handler(banshee_0_r, space->machine(), offset, mem_mask);
|
||||
device_t *device = space->machine().device("voodoo");
|
||||
return read64be_with_32le_device_handler(banshee_r, device, offset, mem_mask);
|
||||
}
|
||||
static WRITE64_HANDLER(voodoo3_w)
|
||||
{
|
||||
// printf("voodoo3_w: %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), offset, cpu_get_pc(&space->device()));
|
||||
write64be_with_32le_handler(banshee_0_w, space->machine(), offset, data, mem_mask);
|
||||
|
||||
device_t *device = space->machine().device("voodoo");
|
||||
write64be_with_32le_device_handler(banshee_w, device, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
static READ64_HANDLER(voodoo3_lfb_r)
|
||||
{
|
||||
return read64be_with_32le_handler(banshee_fb_0_r, space->machine(), offset, mem_mask);
|
||||
device_t *device = space->machine().device("voodoo");
|
||||
return read64be_with_32le_device_handler(banshee_fb_r, device, offset, mem_mask);
|
||||
}
|
||||
static WRITE64_HANDLER(voodoo3_lfb_w)
|
||||
{
|
||||
// printf("voodoo3_lfb_w: %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), offset, cpu_get_pc(&space->device()));
|
||||
write64be_with_32le_handler(banshee_fb_0_w, space->machine(), offset, data, mem_mask);
|
||||
|
||||
device_t *device = space->machine().device("voodoo");
|
||||
write64be_with_32le_device_handler(banshee_fb_w, device, offset, data, mem_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -594,11 +939,16 @@ static WRITE64_HANDLER(voodoo3_lfb_w)
|
||||
static ADDRESS_MAP_START(viper_map, AS_PROGRAM, 64)
|
||||
AM_RANGE(0x00000000, 0x00ffffff) AM_MIRROR(0x1000000) AM_RAM
|
||||
AM_RANGE(0x80000000, 0x800fffff) AM_READWRITE(epic_64be_r, epic_64be_w)
|
||||
AM_RANGE(0x82000000, 0x83ffffff) AM_DEVREADWRITE32("voodoo", banshee_r, banshee_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x84000000, 0x85ffffff) AM_DEVREADWRITE32("voodoo", banshee_fb_r, banshee_fb_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0xfe800000, 0xfe8000ff) AM_DEVREADWRITE32("voodoo", banshee_io_r, banshee_io_w, U64(0xffffffffffffffff))
|
||||
// AM_RANGE(0x82000000, 0x83ffffff) AM_DEVREADWRITE32("voodoo", banshee_r, banshee_w, U64(0xffffffffffffffff))
|
||||
// AM_RANGE(0x84000000, 0x85ffffff) AM_DEVREADWRITE32("voodoo", banshee_fb_r, banshee_fb_w, U64(0xffffffffffffffff))
|
||||
// AM_RANGE(0xfe800000, 0xfe8000ff) AM_DEVREADWRITE32("voodoo", banshee_io_r, banshee_io_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x82000000, 0x83ffffff) AM_READWRITE(voodoo3_r, voodoo3_w)
|
||||
AM_RANGE(0x84000000, 0x85ffffff) AM_READWRITE(voodoo3_lfb_r, voodoo3_lfb_w)
|
||||
AM_RANGE(0xfe800000, 0xfe8000ff) AM_READWRITE(voodoo3_io_r, voodoo3_io_w)
|
||||
AM_RANGE(0xfec00000, 0xfedfffff) AM_DEVREADWRITE("pcibus", pci_config_addr_r, pci_config_addr_w)
|
||||
AM_RANGE(0xfee00000, 0xfeefffff) AM_DEVREADWRITE("pcibus", pci_config_data_r, pci_config_data_w)
|
||||
// 0xff000000, 0xff000fff - cf_card_data_r/w (installed in DRIVER_INIT(vipercf))
|
||||
// 0xff200000, 0xff200fff - cf_card_r/w (installed in DRIVER_INIT(vipercf))
|
||||
AM_RANGE(0xff300000, 0xff300fff) AM_DEVREADWRITE("ide", ata_r, ata_w)
|
||||
AM_RANGE(0xffe10000, 0xffe10007) AM_READ(unk1_r)
|
||||
AM_RANGE(0xffe30000, 0xffe31fff) AM_DEVREADWRITE8("m48t58",timekeeper_r, timekeeper_w, U64(0xffffffffffffffff))
|
||||
@ -624,7 +974,13 @@ static const powerpc_config viper_ppc_cfg =
|
||||
|
||||
static INTERRUPT_GEN(viper_vblank)
|
||||
{
|
||||
mpc8240_interrupt(device->machine(), MPC8240_IRQ0);
|
||||
//mpc8240_interrupt(device->machine, MPC8240_IRQ3);
|
||||
}
|
||||
|
||||
static void voodoo_vblank(const device_config *device, int param)
|
||||
{
|
||||
//mpc8240_interrupt(device->machine, MPC8240_IRQ4);
|
||||
}
|
||||
|
||||
static void ide_interrupt(device_t *device, int state)
|
||||
@ -634,8 +990,12 @@ static void ide_interrupt(device_t *device, int state)
|
||||
static MACHINE_RESET(viper)
|
||||
{
|
||||
devtag_reset(machine, "ide");
|
||||
mpc8240_epic_reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static MACHINE_CONFIG_START( viper, viper_state )
|
||||
|
||||
/* basic machine hardware */
|
||||
@ -653,6 +1013,7 @@ static MACHINE_CONFIG_START( viper, viper_state )
|
||||
MCFG_IDE_CONTROLLER_ADD("ide", ide_interrupt)
|
||||
MCFG_3DFX_VOODOO_3_ADD("voodoo", STD_VOODOO_3_CLOCK, 16, "screen")
|
||||
MCFG_3DFX_VOODOO_CPU("maincpu")
|
||||
MCFG_3DFX_VOODOO_VBLANK(voodoo_vblank)
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
@ -660,10 +1021,11 @@ static MACHINE_CONFIG_START( viper, viper_state )
|
||||
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
|
||||
MCFG_SCREEN_SIZE(800, 600)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 799, 0, 599)
|
||||
MCFG_SCREEN_UPDATE(viper)
|
||||
|
||||
MCFG_PALETTE_LENGTH(65536)
|
||||
|
||||
MCFG_SCREEN_UPDATE(viper)
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user