// license:BSD-3-Clause // copyright-holders:Ryan Holtz /* Nintendo 64 Driver by Ville Linde Reformatted to share hardware by R. Belmont Additional work by Ryan Holtz Porting from Mupen64 by Ryan Holtz */ #include "emu.h" #include "includes/n64.h" #include "cpu/rsp/rsp.h" #include "cpu/mips/mips3.h" #include "sound/dmadac.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" #include "imagedev/harddriv.h" #include "screen.h" #include "softlist.h" #include "speaker.h" class n64_mess_state : public n64_state { public: n64_mess_state(const machine_config &mconfig, device_type type, const char *tag) : n64_state(mconfig, type, tag) { } DECLARE_READ32_MEMBER(dd_null_r); DECLARE_MACHINE_START(n64dd); INTERRUPT_GEN_MEMBER(n64_reset_poll); DECLARE_DEVICE_IMAGE_LOAD_MEMBER(n64_cart); void mempak_format(uint8_t* pak); image_init_result disk_load(device_image_interface &image); void disk_unload(device_image_interface &image); DECLARE_DEVICE_IMAGE_LOAD_MEMBER( n64dd ); DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER( n64dd ); void n64(machine_config &config); void n64dd(machine_config &config); void n64_map(address_map &map); void n64dd_map(address_map &map); void rsp_map(address_map &map); }; READ32_MEMBER(n64_mess_state::dd_null_r) { return 0xffffffff; } ADDRESS_MAP_START(n64_mess_state::n64_map) AM_RANGE(0x00000000, 0x007fffff) AM_RAM AM_SHARE("rdram") // RDRAM AM_RANGE(0x03f00000, 0x03f00027) AM_DEVREADWRITE("rcp", n64_periphs, rdram_reg_r, rdram_reg_w) AM_RANGE(0x04000000, 0x04000fff) AM_RAM AM_SHARE("rsp_dmem") // RSP DMEM AM_RANGE(0x04001000, 0x04001fff) AM_RAM AM_SHARE("rsp_imem") // RSP IMEM AM_RANGE(0x04040000, 0x040fffff) AM_DEVREADWRITE("rcp", n64_periphs, sp_reg_r, sp_reg_w) // RSP AM_RANGE(0x04100000, 0x041fffff) AM_DEVREADWRITE("rcp", n64_periphs, dp_reg_r, dp_reg_w) // RDP AM_RANGE(0x04300000, 0x043fffff) AM_DEVREADWRITE("rcp", n64_periphs, mi_reg_r, mi_reg_w) // MIPS Interface AM_RANGE(0x04400000, 0x044fffff) AM_DEVREADWRITE("rcp", n64_periphs, vi_reg_r, vi_reg_w) // Video Interface AM_RANGE(0x04500000, 0x045fffff) AM_DEVREADWRITE("rcp", n64_periphs, ai_reg_r, ai_reg_w) // Audio Interface AM_RANGE(0x04600000, 0x046fffff) AM_DEVREADWRITE("rcp", n64_periphs, pi_reg_r, pi_reg_w) // Peripheral Interface AM_RANGE(0x04700000, 0x047fffff) AM_DEVREADWRITE("rcp", n64_periphs, ri_reg_r, ri_reg_w) // RDRAM Interface AM_RANGE(0x04800000, 0x048fffff) AM_DEVREADWRITE("rcp", n64_periphs, si_reg_r, si_reg_w) // Serial Interface AM_RANGE(0x05000508, 0x0500050b) AM_READ(dd_null_r); AM_RANGE(0x08000000, 0x0801ffff) AM_RAM AM_SHARE("sram") // Cartridge SRAM AM_RANGE(0x10000000, 0x13ffffff) AM_ROM AM_REGION("user2", 0) // Cartridge AM_RANGE(0x1fc00000, 0x1fc007bf) AM_ROM AM_REGION("user1", 0) // PIF ROM AM_RANGE(0x1fc007c0, 0x1fc007ff) AM_DEVREADWRITE("rcp", n64_periphs, pif_ram_r, pif_ram_w) ADDRESS_MAP_END ADDRESS_MAP_START(n64_mess_state::n64dd_map) AM_RANGE(0x00000000, 0x007fffff) AM_RAM AM_SHARE("rdram") // RDRAM AM_RANGE(0x03f00000, 0x03f00027) AM_DEVREADWRITE("rcp", n64_periphs, rdram_reg_r, rdram_reg_w) AM_RANGE(0x04000000, 0x04000fff) AM_RAM AM_SHARE("rsp_dmem") // RSP DMEM AM_RANGE(0x04001000, 0x04001fff) AM_RAM AM_SHARE("rsp_imem") // RSP IMEM AM_RANGE(0x04040000, 0x040fffff) AM_DEVREADWRITE("rcp", n64_periphs, sp_reg_r, sp_reg_w) // RSP AM_RANGE(0x04100000, 0x041fffff) AM_DEVREADWRITE("rcp", n64_periphs, dp_reg_r, dp_reg_w) // RDP AM_RANGE(0x04300000, 0x043fffff) AM_DEVREADWRITE("rcp", n64_periphs, mi_reg_r, mi_reg_w) // MIPS Interface AM_RANGE(0x04400000, 0x044fffff) AM_DEVREADWRITE("rcp", n64_periphs, vi_reg_r, vi_reg_w) // Video Interface AM_RANGE(0x04500000, 0x045fffff) AM_DEVREADWRITE("rcp", n64_periphs, ai_reg_r, ai_reg_w) // Audio Interface AM_RANGE(0x04600000, 0x046fffff) AM_DEVREADWRITE("rcp", n64_periphs, pi_reg_r, pi_reg_w) // Peripheral Interface AM_RANGE(0x04700000, 0x047fffff) AM_DEVREADWRITE("rcp", n64_periphs, ri_reg_r, ri_reg_w) // RDRAM Interface AM_RANGE(0x04800000, 0x048fffff) AM_DEVREADWRITE("rcp", n64_periphs, si_reg_r, si_reg_w) // Serial Interface AM_RANGE(0x05000000, 0x05ffffff) AM_DEVREADWRITE("rcp", n64_periphs, dd_reg_r, dd_reg_w) // 64DD Interface AM_RANGE(0x06000000, 0x063fffff) AM_ROM AM_REGION("ddipl", 0) // 64DD IPL ROM AM_RANGE(0x08000000, 0x0801ffff) AM_RAM AM_SHARE("sram") // Cartridge SRAM AM_RANGE(0x10000000, 0x13ffffff) AM_ROM AM_REGION("user2", 0) // Cartridge AM_RANGE(0x1fc00000, 0x1fc007bf) AM_ROM AM_REGION("user1", 0) // PIF ROM AM_RANGE(0x1fc007c0, 0x1fc007ff) AM_DEVREADWRITE("rcp", n64_periphs, pif_ram_r, pif_ram_w) ADDRESS_MAP_END ADDRESS_MAP_START(n64_mess_state::rsp_map) AM_RANGE(0x00000000, 0x00000fff) AM_RAM AM_SHARE("rsp_dmem") AM_RANGE(0x00001000, 0x00001fff) AM_RAM AM_SHARE("rsp_imem") AM_RANGE(0x04000000, 0x04000fff) AM_RAM AM_SHARE("rsp_dmem") AM_RANGE(0x04001000, 0x04001fff) AM_RAM AM_SHARE("rsp_imem") ADDRESS_MAP_END static INPUT_PORTS_START( n64 ) PORT_START("input") PORT_CONFNAME(0x0003, 0x0001, "Controller Port 0 Device") PORT_CONFSETTING(0x00, "None") PORT_CONFSETTING(0x01, "Joypad") PORT_CONFSETTING(0x02, "Mouse") PORT_CONFNAME(0x000C, 0x0000, "Controller Port 1 Device") PORT_CONFSETTING(0x00, "None") PORT_CONFSETTING(0x04, "Joypad") PORT_CONFSETTING(0x08, "Mouse") PORT_CONFNAME(0x0030, 0x0000, "Controller Port 2 Device") PORT_CONFSETTING(0x00, "None") PORT_CONFSETTING(0x10, "Joypad") PORT_CONFSETTING(0x20, "Mouse") PORT_CONFNAME(0x00C0, 0x0000, "Controller Port 3 Device") PORT_CONFSETTING(0x00, "None") PORT_CONFSETTING(0x40, "Joypad") PORT_CONFSETTING(0x80, "Mouse") PORT_CONFNAME(0x0100, 0x0000, "Disk Drive") PORT_CONFSETTING(0x0000, "Retail") PORT_CONFSETTING(0x0100, "Development") PORT_CONFNAME(0xC000, 0x8000, "EEPROM Size") PORT_CONFSETTING(0x0000, "None") PORT_CONFSETTING(0x8000, "4KB") PORT_CONFSETTING(0xC000, "16KB") //Player 1 PORT_START("P1") PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Button A / Left Click") PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Button B / Right Click") PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Button Z") PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) PORT_NAME("P1 Start") PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_NAME("P1 Joypad \xE2\x86\x91") /* Up */ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_NAME("P1 Joypad \xE2\x86\x93") /* Down */ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_NAME("P1 Joypad \xE2\x86\x90") /* Left */ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_NAME("P1 Joypad \xE2\x86\x92") /* Right */ PORT_BIT( 0x00c0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Button L") PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("P1 Button R") PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_NAME("P1 Button C \xE2\x86\x91") /* Up */ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_PLAYER(1) PORT_NAME("P1 Button C \xE2\x86\x93") /* Down */ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_PLAYER(1) PORT_NAME("P1 Button C \xE2\x86\x90") /* Left */ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_PLAYER(1) PORT_NAME("P1 Button C \xE2\x86\x92") /* Right */ PORT_START("P1_ANALOG_X") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(1) PORT_START("P1_ANALOG_Y") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(1) PORT_REVERSE PORT_START("P1_MOUSE_X") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_X ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_START("P1_MOUSE_Y") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_Y ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_REVERSE //Player 2 PORT_START("P2") PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Button A / Left Click") PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Button B / Right Click") PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Button Z") PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(2) PORT_NAME("P2 Start") PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_NAME("P2 Joypad \xE2\x86\x91") /* Up */ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_NAME("P2 Joypad \xE2\x86\x93") /* Down */ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_NAME("P2 Joypad \xE2\x86\x90") /* Left */ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_NAME("P2 Joypad \xE2\x86\x92") /* Right */ PORT_BIT( 0x00c0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Button L") PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_NAME("P2 Button R") PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(2) PORT_NAME("P2 Button C \xE2\x86\x91") /* Up */ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_PLAYER(2) PORT_NAME("P2 Button C \xE2\x86\x93") /* Down */ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_PLAYER(2) PORT_NAME("P2 Button C \xE2\x86\x90") /* Left */ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_PLAYER(2) PORT_NAME("P2 Button C \xE2\x86\x92") /* Right */ PORT_START("P2_ANALOG_X") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(2) PORT_START("P2_ANALOG_Y") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(2) PORT_REVERSE PORT_START("P2_MOUSE_X") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_X ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(2) PORT_START("P2_MOUSE_Y") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_Y ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(2) PORT_REVERSE //Player 3 PORT_START("P3") PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 Button A / Left Click") PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 Button B / Right Click") PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 Button Z") PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(3) PORT_NAME("P3 Start") PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(3) PORT_NAME("P3 Joypad \xE2\x86\x91") /* Up */ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) PORT_NAME("P3 Joypad \xE2\x86\x93") /* Down */ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_NAME("P3 Joypad \xE2\x86\x90") /* Left */ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_NAME("P3 Joypad \xE2\x86\x92") /* Right */ PORT_BIT( 0x00c0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(3) PORT_NAME("P3 Button L") PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(3) PORT_NAME("P3 Button R") PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(3) PORT_NAME("P3 Button C \xE2\x86\x91") /* Up */ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_PLAYER(3) PORT_NAME("P3 Button C \xE2\x86\x93") /* Down */ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_PLAYER(3) PORT_NAME("P3 Button C \xE2\x86\x90") /* Left */ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_PLAYER(3) PORT_NAME("P3 Button C \xE2\x86\x92") /* Right */ PORT_START("P3_ANALOG_X") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(3) PORT_START("P3_ANALOG_Y") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(3) PORT_REVERSE PORT_START("P3_MOUSE_X") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_X ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(3) PORT_START("P3_MOUSE_Y") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_Y ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(3) PORT_REVERSE //Player 4 PORT_START("P4") PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 Button A / Left Click") PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 Button B / Right Click") PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 Button Z") PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(4) PORT_NAME("P4 Start") PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(4) PORT_NAME("P4 Joypad \xE2\x86\x91") /* Up */ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) PORT_NAME("P4 Joypad \xE2\x86\x93") /* Down */ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) PORT_NAME("P4 Joypad \xE2\x86\x90") /* Left */ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) PORT_NAME("P4 Joypad \xE2\x86\x92") /* Right */ PORT_BIT( 0x00c0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(4) PORT_NAME("P4 Button L") PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(4) PORT_NAME("P4 Button R") PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(4) PORT_NAME("P4 Button C \xE2\x86\x91") /* Up */ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_PLAYER(4) PORT_NAME("P4 Button C \xE2\x86\x93") /* Down */ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_PLAYER(4) PORT_NAME("P4 Button C \xE2\x86\x90") /* Left */ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_PLAYER(4) PORT_NAME("P4 Button C \xE2\x86\x92") /* Right */ PORT_START("P4_ANALOG_X") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(4) PORT_START("P4_ANALOG_Y") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(4) PORT_REVERSE PORT_START("P4_MOUSE_X") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_X ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(4) PORT_START("P4_MOUSE_Y") PORT_BIT( 0xffff, 0x0000, IPT_MOUSE_Y ) PORT_MINMAX(0x0000,0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(4) PORT_REVERSE PORT_START("RESET") PORT_BIT( 0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Warm Reset") PORT_CODE(KEYCODE_3) INPUT_PORTS_END void n64_mess_state::mempak_format(uint8_t* pak) { unsigned char pak_header[] = { 0x81,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00 }; unsigned char pak_inode_table[] = { 0x01,0x71,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03 }; memset(pak, 0, 0x8000); memcpy(pak, pak_header, 256); memcpy(pak+256, pak_inode_table, 256); // Main memcpy(pak+512, pak_inode_table, 256); // Mirror } DEVICE_IMAGE_LOAD_MEMBER(n64_mess_state,n64_cart) { int i, length; n64_periphs *periphs = machine().device("rcp"); uint8_t *cart = memregion("user2")->base(); if (!image.loaded_through_softlist()) { length = image.fread(cart, 0x4000000); } else { length = image.get_software_region_length("rom"); memcpy(cart, image.get_software_region("rom"), length); } periphs->cart_length = length; if (cart[0] == 0x37 && cart[1] == 0x80) { for (i = 0; i < length; i += 4) { uint8_t b1 = cart[i + 0]; uint8_t b2 = cart[i + 1]; uint8_t b3 = cart[i + 2]; uint8_t b4 = cart[i + 3]; cart[i + 0] = b3; cart[i + 1] = b4; cart[i + 2] = b1; cart[i + 3] = b2; } } else { for (i = 0; i < length; i += 4) { uint8_t b1 = cart[i + 0]; uint8_t b2 = cart[i + 1]; uint8_t b3 = cart[i + 2]; uint8_t b4 = cart[i + 3]; cart[i + 0] = b4; cart[i + 1] = b3; cart[i + 2] = b2; cart[i + 3] = b1; } } periphs->m_nvram_image = &image.device(); logerror("cart length = %d\n", length); device_image_interface *battery_image = dynamic_cast(periphs->m_nvram_image); if(battery_image) { //printf("Loading\n"); uint8_t data[0x30800]; battery_image->battery_load(data, 0x30800, 0x00); if (m_sram != nullptr) { memcpy(m_sram, data, 0x20000); } memcpy(periphs->m_save_data.eeprom, data + 0x20000, 0x800); memcpy(periphs->m_save_data.mempak[0], data + 0x20800, 0x8000); memcpy(periphs->m_save_data.mempak[1], data + 0x28800, 0x8000); } if(periphs->m_save_data.mempak[0][0] == 0) // Init if new { memset(periphs->m_save_data.eeprom, 0, 0x800); mempak_format(periphs->m_save_data.mempak[0]); mempak_format(periphs->m_save_data.mempak[1]); } return image_init_result::PASS; } MACHINE_START_MEMBER(n64_mess_state,n64dd) { machine_start(); machine().device("rcp")->dd_present = true; uint8_t *ipl = memregion("ddipl")->base(); for (int i = 0; i < 0x400000; i += 4) { uint8_t b1 = ipl[i + 0]; uint8_t b2 = ipl[i + 1]; uint8_t b3 = ipl[i + 2]; uint8_t b4 = ipl[i + 3]; ipl[i + 0] = b1; ipl[i + 1] = b2; ipl[i + 2] = b3; ipl[i + 3] = b4; } } DEVICE_IMAGE_LOAD_MEMBER(n64_mess_state,n64dd) { return disk_load(image); } DEVICE_IMAGE_UNLOAD_MEMBER(n64_mess_state,n64dd) { disk_unload(image); } image_init_result n64_mess_state::disk_load(device_image_interface &image) { image.fseek(0, SEEK_SET); image.fread(memregion("disk")->base(), image.length()); machine().device("rcp")->disk_present = true; return image_init_result::PASS; } void n64_mess_state::disk_unload(device_image_interface &image) { machine().device("rcp")->disk_present = false; } INTERRUPT_GEN_MEMBER(n64_mess_state::n64_reset_poll) { n64_periphs *periphs = machine().device("rcp"); periphs->poll_reset_button((ioport("RESET")->read() & 1) ? true : false); } MACHINE_CONFIG_START(n64_mess_state::n64) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", VR4300BE, 93750000) MCFG_CPU_FORCE_NO_DRC() //MCFG_MIPS3_ICACHE_SIZE(16384) /* ?? */ //MCFG_MIPS3_DCACHE_SIZE(8192) /* ?? */ //MCFG_MIPS3_SYSTEM_CLOCK(62500000) /* ?? */ MCFG_CPU_PROGRAM_MAP(n64_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", n64_mess_state, n64_reset_poll) MCFG_CPU_ADD("rsp", RSP, 62500000) MCFG_CPU_FORCE_NO_DRC() MCFG_RSP_DP_REG_R_CB(DEVREAD32("rcp",n64_periphs, dp_reg_r)) MCFG_RSP_DP_REG_W_CB(DEVWRITE32("rcp",n64_periphs, dp_reg_w)) MCFG_RSP_SP_REG_R_CB(DEVREAD32("rcp",n64_periphs, sp_reg_r)) MCFG_RSP_SP_REG_W_CB(DEVWRITE32("rcp",n64_periphs, sp_reg_w)) MCFG_RSP_SP_SET_STATUS_CB(DEVWRITE32("rcp",n64_periphs, sp_set_status)) MCFG_CPU_PROGRAM_MAP(rsp_map) MCFG_QUANTUM_TIME(attotime::from_hz(500000)) //MCFG_QUANTUM_TIME(attotime::from_hz(1200)) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) /* Video DACRATE is for quarter pixels, so the horizontal is also given in quarter pixels. However, the horizontal and vertical timing and sizing is adjustable by register and will be reset when the registers are written. */ MCFG_SCREEN_RAW_PARAMS(DACRATE_NTSC*2,3093,0,3093,525,0,525) //MCFG_SCREEN_REFRESH_RATE(60) //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) //MCFG_SCREEN_SIZE(640, 525) //MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479) MCFG_SCREEN_UPDATE_DRIVER(n64_state, screen_update_n64) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(n64_state, screen_vblank_n64)) MCFG_PALETTE_ADD("palette", 0x1000) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SOUND_ADD("dac2", DMADAC, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0) MCFG_SOUND_ADD("dac1", DMADAC, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0) MCFG_N64_PERIPHS_ADD("rcp"); /* cartridge */ MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "n64_cart") MCFG_GENERIC_EXTENSIONS("v64,z64,rom,n64,bin") MCFG_GENERIC_MANDATORY MCFG_GENERIC_LOAD(n64_mess_state, n64_cart) /* software lists */ MCFG_SOFTWARE_LIST_ADD("cart_list", "n64") MACHINE_CONFIG_END MACHINE_CONFIG_START(n64_mess_state::n64dd) n64(config); MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(n64dd_map) MCFG_MACHINE_START_OVERRIDE(n64_mess_state, n64dd) MCFG_DEVICE_REMOVE("cartslot") MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "n64_cart") MCFG_GENERIC_EXTENSIONS("v64,z64,rom,n64,bin") MCFG_GENERIC_LOAD(n64_mess_state, n64_cart) MCFG_HARDDISK_ADD("n64disk") MCFG_HARDDISK_LOAD(n64_mess_state,n64dd) MCFG_HARDDISK_UNLOAD(n64_mess_state,n64dd) MCFG_HARDDISK_INTERFACE("n64dd_disk") MCFG_SOFTWARE_LIST_ADD("dd_list", "n64dd") MACHINE_CONFIG_END ROM_START( n64 ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF ) /* dummy region for R4300 */ ROM_REGION32_BE( 0x800, "user1", 0 ) ROM_LOAD( "pifdata.bin", 0x0000, 0x0800, CRC(5ec82be9) SHA1(9174eadc0f0ea2654c95fd941406ab46b9dc9bdd) ) ROM_REGION32_BE( 0x4000000, "user2", ROMREGION_ERASEFF) ROM_REGION16_BE( 0x80, "normpoint", 0 ) ROM_LOAD( "normpnt.rom", 0x00, 0x80, CRC(e7f2a005) SHA1(c27b4a364a24daeee6e99fd286753fd6216362b4) ) ROM_REGION16_BE( 0x80, "normslope", 0 ) ROM_LOAD( "normslp.rom", 0x00, 0x80, CRC(4f2ae525) SHA1(eab43f8cc52c8551d9cff6fced18ef80eaba6f05) ) ROM_END ROM_START( n64dd ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF ) /* dummy region for R4300 */ ROM_REGION32_BE( 0x800, "user1", 0 ) ROM_LOAD( "pifdata.bin", 0x0000, 0x0800, CRC(5ec82be9) SHA1(9174eadc0f0ea2654c95fd941406ab46b9dc9bdd) ) ROM_REGION32_BE( 0x4000000, "user2", ROMREGION_ERASEFF) ROM_REGION32_BE( 0x400000, "ddipl", ROMREGION_ERASEFF) ROM_LOAD( "64ddipl.bin", 0x000000, 0x400000, CRC(7f933ce2) SHA1(bf861922dcb78c316360e3e742f4f70ff63c9bc3) ) ROM_REGION32_BE( 0x4400000, "disk", ROMREGION_ERASEFF) ROM_REGION16_BE( 0x80, "normpoint", 0 ) ROM_LOAD( "normpnt.rom", 0x00, 0x80, CRC(e7f2a005) SHA1(c27b4a364a24daeee6e99fd286753fd6216362b4) ) ROM_REGION16_BE( 0x80, "normslope", 0 ) ROM_LOAD( "normslp.rom", 0x00, 0x80, CRC(4f2ae525) SHA1(eab43f8cc52c8551d9cff6fced18ef80eaba6f05) ) ROM_END CONS(1996, n64, 0, 0, n64, n64, n64_mess_state, 0, "Nintendo", "Nintendo 64", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS ) CONS(1996, n64dd, n64, 0, n64dd, n64, n64_mess_state, 0, "Nintendo", "Nintendo 64DD", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS )