summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/konppc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/konppc.c')
-rw-r--r--src/mame/machine/konppc.c697
1 files changed, 697 insertions, 0 deletions
diff --git a/src/mame/machine/konppc.c b/src/mame/machine/konppc.c
new file mode 100644
index 00000000000..ba8625d632b
--- /dev/null
+++ b/src/mame/machine/konppc.c
@@ -0,0 +1,697 @@
+/* Konami PowerPC-based 3D games common functions */
+
+#include "driver.h"
+#include "cpu/sharc/sharc.h"
+#include "video/voodoo.h"
+#include "konppc.h"
+
+#define MAX_CG_BOARDS 2
+
+static UINT32 dsp_comm_ppc[MAX_CG_BOARDS][2];
+static UINT32 dsp_comm_sharc[MAX_CG_BOARDS][2];
+static int dsp_shared_ram_bank[MAX_CG_BOARDS];
+
+static int cgboard_id;
+static int cgboard_type;
+static int num_cgboards;
+
+static UINT32 *dsp_shared_ram[MAX_CG_BOARDS];
+
+#define DSP_BANK_SIZE 0x10000
+#define DSP_BANK_SIZE_WORD (DSP_BANK_SIZE / 4)
+
+static UINT32 dsp_state[MAX_CG_BOARDS];
+static UINT32 pci_bridge_enable[MAX_CG_BOARDS];
+static UINT32 nwk_device_sel[MAX_CG_BOARDS];
+static int texture_bank[MAX_CG_BOARDS];
+
+static int nwk_fifo_half_full_r;
+static int nwk_fifo_half_full_w;
+static int nwk_fifo_full;
+static int nwk_fifo_mask;
+
+
+static UINT32 *nwk_fifo[MAX_CG_BOARDS];
+static int nwk_fifo_read_ptr[MAX_CG_BOARDS];
+static int nwk_fifo_write_ptr[MAX_CG_BOARDS];
+
+static UINT32 *nwk_ram[MAX_CG_BOARDS];
+
+/*****************************************************************************/
+
+void init_konami_cgboard(int num_boards, int type)
+{
+ int i;
+ num_cgboards = num_boards;
+
+ for (i=0; i < num_boards; i++)
+ {
+ dsp_comm_ppc[i][0] = 0x00;
+ dsp_shared_ram[i] = auto_malloc(DSP_BANK_SIZE * 2);
+ dsp_shared_ram_bank[i] = 0;
+
+ dsp_state[i] = 0x80;
+ texture_bank[i] = -1;
+
+ pci_bridge_enable[i] = 0;
+ nwk_device_sel[i] = 0;
+ nwk_fifo_read_ptr[i] = 0;
+ nwk_fifo_write_ptr[i] = 0;
+
+ nwk_fifo[i] = auto_malloc(sizeof(UINT32) * 0x800);
+ nwk_ram[i] = auto_malloc(sizeof(UINT32) * 0x2000);
+ }
+ cgboard_type = type;
+
+ if (type == CGBOARD_TYPE_NWKTR)
+ {
+ nwk_fifo_half_full_r = 0x100;
+ nwk_fifo_half_full_w = 0xff;
+ nwk_fifo_full = 0x1ff;
+ nwk_fifo_mask = 0x1ff;
+ }
+ if (type == CGBOARD_TYPE_HANGPLT)
+ {
+ nwk_fifo_half_full_r = 0x3ff;
+ nwk_fifo_half_full_w = 0x400;
+ nwk_fifo_full = 0x7ff;
+ nwk_fifo_mask = 0x7ff;
+ }
+}
+
+void set_cgboard_id(int board_id)
+{
+ if (board_id > num_cgboards-1)
+ {
+ cgboard_id = MAX_CG_BOARDS;
+ }
+ else
+ {
+ cgboard_id = board_id;
+ }
+}
+
+int get_cgboard_id(void)
+{
+ if (cgboard_id > num_cgboards-1)
+ {
+ return 0;
+ }
+ else
+ {
+ return cgboard_id;
+ }
+}
+
+void set_cgboard_texture_bank(int board, int bank, UINT8 *rom)
+{
+ texture_bank[board] = bank;
+
+ memory_configure_bank(bank, 0, 2, rom, 0x800000);
+}
+
+/*****************************************************************************/
+
+/* CG Board DSP interface for PowerPC */
+
+READ32_HANDLER( cgboard_dsp_comm_r_ppc )
+{
+ if (cgboard_id < MAX_CG_BOARDS)
+ {
+// mame_printf_debug("dsp_cmd_r: (board %d) %08X, %08X at %08X\n", cgboard_id, offset, mem_mask, activecpu_get_pc());
+ return dsp_comm_sharc[cgboard_id][offset] | (dsp_state[cgboard_id] << 16);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+WRITE32_HANDLER( cgboard_dsp_comm_w_ppc )
+{
+ int dsp = (cgboard_id == 0) ? 2 : 3;
+// mame_printf_debug("dsp_cmd_w: (board %d) %08X, %08X, %08X at %08X\n", cgboard_id, data, offset, mem_mask, activecpu_get_pc());
+
+ if (cgboard_id < MAX_CG_BOARDS)
+ {
+ if (offset == 0)
+ {
+ if (!(mem_mask & 0xff000000))
+ {
+ dsp_shared_ram_bank[cgboard_id] = (data >> 24) & 0x1;
+
+ if (data & 0x80000000)
+ {
+ dsp_state[cgboard_id] |= 0x10;
+ }
+
+ pci_bridge_enable[cgboard_id] = (data & 0x20000000) ? 1 : 0;
+
+ if (data & 0x10000000)
+ {
+ cpunum_set_input_line(dsp, INPUT_LINE_RESET, CLEAR_LINE);
+ }
+ else
+ {
+ cpunum_set_input_line(dsp, INPUT_LINE_RESET, ASSERT_LINE);
+ }
+
+ if (data & 0x02000000)
+ {
+ cpunum_set_input_line(dsp, INPUT_LINE_IRQ0, ASSERT_LINE);
+ }
+ if (data & 0x04000000)
+ {
+ cpunum_set_input_line(dsp, INPUT_LINE_IRQ1, ASSERT_LINE);
+ }
+ }
+
+ if (!(mem_mask & 0x000000ff))
+ {
+ dsp_comm_ppc[cgboard_id][offset] = data & 0xff;
+ }
+ }
+ else
+ {
+ dsp_comm_ppc[cgboard_id][offset] = data;
+ }
+ }
+}
+
+
+
+READ32_HANDLER( cgboard_dsp_shared_r_ppc )
+{
+ if (cgboard_id < MAX_CG_BOARDS)
+ {
+ return dsp_shared_ram[cgboard_id][offset + (dsp_shared_ram_bank[cgboard_id] * DSP_BANK_SIZE_WORD)];
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+WRITE32_HANDLER( cgboard_dsp_shared_w_ppc )
+{
+ if (cgboard_id < MAX_CG_BOARDS)
+ {
+ cpu_trigger(10000); // Remove the timeout (a part of the GTI Club FIFO test workaround)
+ COMBINE_DATA(dsp_shared_ram[cgboard_id] + (offset + (dsp_shared_ram_bank[cgboard_id] * DSP_BANK_SIZE_WORD)));
+ }
+}
+
+/*****************************************************************************/
+
+/* CG Board DSP interface for SHARC */
+
+static UINT32 dsp_comm_sharc_r(int board, int offset)
+{
+ return dsp_comm_ppc[board][offset];
+}
+
+static void dsp_comm_sharc_w(int board, int offset, UINT32 data)
+{
+ if (offset >= 2)
+ {
+ fatalerror("dsp_comm_w: %08X, %08X", data, offset);
+ }
+
+ switch (cgboard_type)
+ {
+ case CGBOARD_TYPE_ZR107:
+ case CGBOARD_TYPE_GTICLUB:
+ {
+ //cpunum_set_input_line(2, SHARC_INPUT_FLAG0, ASSERT_LINE);
+ cpuintrf_push_context(2);
+ sharc_set_flag_input(0, ASSERT_LINE);
+ cpuintrf_pop_context();
+
+ if (offset == 1)
+ {
+ if (data & 0x03)
+ {
+ cpunum_set_input_line(2, INPUT_LINE_IRQ2, ASSERT_LINE);
+ }
+ }
+ break;
+ }
+
+ case CGBOARD_TYPE_NWKTR:
+ case CGBOARD_TYPE_HANGPLT:
+ {
+ if (offset == 1)
+ {
+ nwk_device_sel[board] = data;
+
+ if (data & 0x01 || data & 0x10)
+ {
+ cpuintrf_push_context((board == 0) ? 2 : 3);
+ sharc_set_flag_input(1, ASSERT_LINE);
+ cpuintrf_pop_context();
+ }
+
+ if (texture_bank[board] != -1)
+ {
+ int offset = (data & 0x08) ? 1 : 0;
+
+ memory_set_bank(texture_bank[board], offset);
+ }
+ }
+ break;
+ }
+
+ case CGBOARD_TYPE_HORNET:
+ {
+ if (offset == 1)
+ {
+ if (texture_bank[board] != -1)
+ {
+ int offset = (data & 0x08) ? 1 : 0;
+
+ memory_set_bank(texture_bank[board], offset);
+ }
+ }
+ break;
+ }
+ }
+
+// printf("cgboard_dsp_comm_w_sharc: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, activecpu_get_pc());
+
+ dsp_comm_sharc[board][offset] = data;
+}
+
+static UINT32 dsp_shared_ram_r_sharc(int board, int offset)
+{
+// printf("dsp_shared_r: (board %d) %08X, (%08X, %08X)\n", cgboard_id, offset, (UINT32)dsp_shared_ram[(offset >> 1)], (UINT32)dsp_shared_ram[offset]);
+
+ if (offset & 0x1)
+ {
+ return (dsp_shared_ram[board][(offset >> 1) + ((dsp_shared_ram_bank[board] ^ 1) * DSP_BANK_SIZE_WORD)] >> 0) & 0xffff;
+ }
+ else
+ {
+ return (dsp_shared_ram[board][(offset >> 1) + ((dsp_shared_ram_bank[board] ^ 1) * DSP_BANK_SIZE_WORD)] >> 16) & 0xffff;
+ }
+}
+
+static void dsp_shared_ram_w_sharc(int board, int offset, UINT32 data)
+{
+// printf("dsp_shared_w: (board %d) %08X, %08X\n", cgboard_id, offset, data);
+ if (offset & 0x1)
+ {
+ dsp_shared_ram[board][(offset >> 1) + ((dsp_shared_ram_bank[board] ^ 1) * DSP_BANK_SIZE_WORD)] &= 0xffff0000;
+ dsp_shared_ram[board][(offset >> 1) + ((dsp_shared_ram_bank[board] ^ 1) * DSP_BANK_SIZE_WORD)] |= (data & 0xffff);
+ }
+ else
+ {
+ dsp_shared_ram[board][(offset >> 1) + ((dsp_shared_ram_bank[board] ^ 1) * DSP_BANK_SIZE_WORD)] &= 0x0000ffff;
+ dsp_shared_ram[board][(offset >> 1) + ((dsp_shared_ram_bank[board] ^ 1) * DSP_BANK_SIZE_WORD)] |= ((data & 0xffff) << 16);
+ }
+}
+
+READ32_HANDLER( cgboard_0_comm_sharc_r )
+{
+ return dsp_comm_sharc_r(0, offset);
+}
+
+WRITE32_HANDLER( cgboard_0_comm_sharc_w )
+{
+ dsp_comm_sharc_w(0, offset, data);
+}
+
+READ32_HANDLER( cgboard_0_shared_sharc_r )
+{
+ return dsp_shared_ram_r_sharc(0, offset);
+}
+
+WRITE32_HANDLER( cgboard_0_shared_sharc_w )
+{
+ dsp_shared_ram_w_sharc(0, offset, data);
+}
+
+READ32_HANDLER( cgboard_1_comm_sharc_r )
+{
+ return dsp_comm_sharc_r(1, offset);
+}
+
+WRITE32_HANDLER( cgboard_1_comm_sharc_w )
+{
+ dsp_comm_sharc_w(1, offset, data);
+}
+
+READ32_HANDLER( cgboard_1_shared_sharc_r )
+{
+ return dsp_shared_ram_r_sharc(1, offset);
+}
+
+WRITE32_HANDLER( cgboard_1_shared_sharc_w )
+{
+ dsp_shared_ram_w_sharc(1, offset, data);
+}
+
+/*****************************************************************************/
+
+static UINT32 nwk_fifo_r(int board)
+{
+ int cpu = (board == 0) ? 2 : 3;
+ UINT32 data;
+
+ if (nwk_fifo_read_ptr[board] < nwk_fifo_half_full_r)
+ {
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(1, CLEAR_LINE);
+ cpuintrf_pop_context();
+ }
+ else
+ {
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(1, ASSERT_LINE);
+ cpuintrf_pop_context();
+ }
+
+ if (nwk_fifo_read_ptr[board] < nwk_fifo_full)
+ {
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(2, ASSERT_LINE);
+ cpuintrf_pop_context();
+ }
+ else
+ {
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(2, CLEAR_LINE);
+ cpuintrf_pop_context();
+ }
+
+ data = nwk_fifo[board][nwk_fifo_read_ptr[board]];
+ nwk_fifo_read_ptr[board]++;
+ nwk_fifo_read_ptr[board] &= nwk_fifo_mask;
+
+ return data;
+}
+
+static void nwk_fifo_w(int board, UINT32 data)
+{
+ int cpu = (board == 0) ? 2 : 3;
+
+ if (nwk_fifo_write_ptr[board] < nwk_fifo_half_full_w)
+ {
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(1, ASSERT_LINE);
+ cpuintrf_pop_context();
+ }
+ else
+ {
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(1, CLEAR_LINE);
+ cpuintrf_pop_context();
+ }
+
+ cpuintrf_push_context(cpu);
+ sharc_set_flag_input(2, ASSERT_LINE);
+ cpuintrf_pop_context();
+
+ nwk_fifo[board][nwk_fifo_write_ptr[board]] = data;
+ nwk_fifo_write_ptr[board]++;
+ nwk_fifo_write_ptr[board] &= nwk_fifo_mask;
+}
+
+/*****************************************************************************/
+
+/* Konami K033906 PCI bridge */
+
+#define MAX_K033906_CHIPS 2
+
+static UINT32 *K033906_reg[MAX_K033906_CHIPS];
+static UINT32 *K033906_ram[MAX_K033906_CHIPS];
+
+void K033906_init(void)
+{
+ int i;
+ for (i=0; i < MAX_K033906_CHIPS; i++)
+ {
+ K033906_reg[i] = auto_malloc(sizeof(UINT32) * 256);
+ K033906_ram[i] = auto_malloc(sizeof(UINT32) * 32768);
+ }
+}
+
+static UINT32 K033906_r(int chip, int reg)
+{
+ switch(reg)
+ {
+ case 0x00: return 0x0001121a; // PCI Vendor ID (0x121a = 3dfx), Device ID (0x0001 = Voodoo)
+ case 0x02: return 0x04000000; // Revision ID
+ case 0x04: return K033906_reg[chip][0x04]; // memBaseAddr
+ case 0x0f: return K033906_reg[chip][0x0f]; // interrupt_line, interrupt_pin, min_gnt, max_lat
+
+ default:
+ fatalerror("K033906_r: %d, %08X at %08X", chip, reg, activecpu_get_pc());
+ }
+ return 0;
+}
+
+static void K033906_w(int chip, int reg, UINT32 data)
+{
+ switch(reg)
+ {
+ case 0x00:
+ break;
+
+ case 0x01: // command register
+ break;
+
+ case 0x04: // memBaseAddr
+ {
+ if (data == 0xffffffff)
+ {
+ K033906_reg[chip][0x04] = 0xff000000;
+ }
+ else
+ {
+ K033906_reg[chip][0x04] = data & 0xff000000;
+ }
+ break;
+ }
+
+ case 0x0f: // interrupt_line, interrupt_pin, min_gnt, max_lat
+ {
+ K033906_reg[chip][0x0f] = data;
+ break;
+ }
+
+ case 0x10: // initEnable
+ {
+ voodoo_set_init_enable(chip, data);
+ break;
+ }
+
+ case 0x11: // busSnoop0
+ case 0x12: // busSnoop1
+ break;
+
+ case 0x38: // ???
+ break;
+
+ default:
+ fatalerror("K033906_w: %d, %08X, %08X at %08X", chip, data, reg, activecpu_get_pc());
+ }
+}
+
+READ32_HANDLER(K033906_0_r)
+{
+ if (nwk_device_sel[0] & 0x01)
+ {
+ return nwk_fifo_r(0);
+ }
+ else
+ {
+ if (pci_bridge_enable[0])
+ {
+ return K033906_r(0, offset);
+ }
+ else
+ {
+ return K033906_ram[0][offset];
+ }
+ }
+}
+
+WRITE32_HANDLER(K033906_0_w)
+{
+ if (pci_bridge_enable[0])
+ {
+ K033906_w(0, offset, data);
+ }
+ else
+ {
+ K033906_ram[0][offset] = data;
+ }
+}
+
+READ32_HANDLER(K033906_1_r)
+{
+ if (nwk_device_sel[1] & 0x01)
+ {
+ return nwk_fifo_r(1);
+ }
+ else
+ {
+ if (pci_bridge_enable[1])
+ {
+ return K033906_r(1, offset);
+ }
+ else
+ {
+ return K033906_ram[1][offset];
+ }
+ }
+}
+
+WRITE32_HANDLER(K033906_1_w)
+{
+ if (pci_bridge_enable[1])
+ {
+ K033906_w(1, offset, data);
+ }
+ else
+ {
+ K033906_ram[1][offset] = data;
+ }
+}
+
+/*****************************************************************************/
+
+WRITE32_HANDLER(nwk_fifo_0_w)
+{
+ if (nwk_device_sel[0] & 0x01)
+ {
+ nwk_fifo_w(0, data);
+ }
+ else if (nwk_device_sel[0] & 0x02)
+ {
+ int addr = ((offset >> 8) << 9) | (offset & 0xff);
+ nwk_ram[0][addr] = data;
+ }
+ else
+ {
+ voodoo_0_w(offset ^ 0x80000, data, mem_mask);
+ }
+}
+
+WRITE32_HANDLER(nwk_fifo_1_w)
+{
+ if (nwk_device_sel[1] & 0x01)
+ {
+ nwk_fifo_w(1, data);
+ }
+ else if (nwk_device_sel[1] & 0x02)
+ {
+ int addr = ((offset >> 8) << 9) | (offset & 0xff);
+ nwk_ram[1][addr] = data;
+ }
+ else
+ {
+ voodoo_1_w(offset ^ 0x80000, data, mem_mask);
+ }
+}
+
+READ32_HANDLER(nwk_voodoo_0_r)
+{
+ if ((nwk_device_sel[0] == 0x4) && offset >= 0x100000 && offset < 0x200000)
+ {
+ return nwk_ram[0][offset & 0x1fff];
+ }
+ else
+ {
+ return voodoo_0_r(offset, mem_mask);
+ }
+}
+
+READ32_HANDLER(nwk_voodoo_1_r)
+{
+ if ((nwk_device_sel[1] == 0x4) && offset >= 0x100000 && offset < 0x200000)
+ {
+ return nwk_ram[1][offset & 0x1fff];
+ }
+ else
+ {
+ return voodoo_1_r(offset, mem_mask);
+ }
+}
+
+WRITE32_HANDLER(nwk_voodoo_0_w)
+{
+ if (nwk_device_sel[0] & 0x01)
+ {
+ nwk_fifo_w(0, data);
+ }
+ else if (nwk_device_sel[0] & 0x02)
+ {
+ int addr = ((offset >> 8) << 9) | (offset & 0xff);
+ nwk_ram[0][addr] = data;
+ }
+ else
+ {
+ voodoo_0_w(offset, data, mem_mask);
+ }
+}
+
+WRITE32_HANDLER(nwk_voodoo_1_w)
+{
+ if (nwk_device_sel[1] & 0x01)
+ {
+ nwk_fifo_w(1, data);
+ }
+ else if (nwk_device_sel[1] & 0x02)
+ {
+ int addr = ((offset >> 8) << 9) | (offset & 0xff);
+ nwk_ram[1][addr] = data;
+ }
+ else
+ {
+ voodoo_1_w(offset, data, mem_mask);
+ }
+}
+
+/*****************************************************************************/
+
+#define LED_ON 0xff00ff00
+
+void draw_7segment_led(mame_bitmap *bitmap, int x, int y, UINT8 value)
+{
+ if ((value & 0x7f) == 0x7f)
+ {
+ return;
+ }
+
+ plot_box(bitmap, x-1, y-1, 7, 11, 0x00000000);
+
+ /* Top */
+ if( (value & 0x40) == 0 ) {
+ plot_box(bitmap, x+1, y+0, 3, 1, LED_ON);
+ }
+ /* Middle */
+ if( (value & 0x01) == 0 ) {
+ plot_box(bitmap, x+1, y+4, 3, 1, LED_ON);
+ }
+ /* Bottom */
+ if( (value & 0x08) == 0 ) {
+ plot_box(bitmap, x+1, y+8, 3, 1, LED_ON);
+ }
+ /* Top Left */
+ if( (value & 0x02) == 0 ) {
+ plot_box(bitmap, x+0, y+1, 1, 3, LED_ON);
+ }
+ /* Top Right */
+ if( (value & 0x20) == 0 ) {
+ plot_box(bitmap, x+4, y+1, 1, 3, LED_ON);
+ }
+ /* Bottom Left */
+ if( (value & 0x04) == 0 ) {
+ plot_box(bitmap, x+0, y+5, 1, 3, LED_ON);
+ }
+ /* Bottom Right */
+ if( (value & 0x10) == 0 ) {
+ plot_box(bitmap, x+4, y+5, 1, 3, LED_ON);
+ }
+}