diff options
Diffstat (limited to 'src')
25 files changed, 2545 insertions, 552 deletions
diff --git a/src/devices/bus/megadrive/md_carts.cpp b/src/devices/bus/megadrive/md_carts.cpp index 4c9f1b9b2e0..5a8e1902d09 100644 --- a/src/devices/bus/megadrive/md_carts.cpp +++ b/src/devices/bus/megadrive/md_carts.cpp @@ -55,6 +55,7 @@ SLOT_INTERFACE_START(md_cart) SLOT_INTERFACE_INTERNAL("rom_lion3", MD_ROM_LION3) SLOT_INTERFACE_INTERNAL("rom_mcpir", MD_ROM_MCPIR) SLOT_INTERFACE_INTERNAL("rom_mjlov", MD_ROM_MJLOV) + SLOT_INTERFACE_INTERNAL("rom_cjmjclub", MD_ROM_CJMJCLUB) SLOT_INTERFACE_INTERNAL("rom_pokea", MD_ROM_POKEA) SLOT_INTERFACE_INTERNAL("rom_pokestad", MD_ROM_POKESTAD) SLOT_INTERFACE_INTERNAL("rom_realtec", MD_ROM_REALTEC) diff --git a/src/devices/bus/megadrive/md_slot.cpp b/src/devices/bus/megadrive/md_slot.cpp index 61e847eb6e9..55d80f8b64d 100644 --- a/src/devices/bus/megadrive/md_slot.cpp +++ b/src/devices/bus/megadrive/md_slot.cpp @@ -270,6 +270,7 @@ static const md_slot slot_list[] = { LIONK3, "rom_lion3" }, { MC_PIRATE, "rom_mcpir" }, { MJLOVER, "rom_mjlov" }, + { CJMJCLUB, "rom_cjmjclub" }, { POKEMONA, "rom_pokea" }, { REALTEC, "rom_realtec" }, { REDCL_EN, "rom_redcl" }, diff --git a/src/devices/bus/megadrive/md_slot.h b/src/devices/bus/megadrive/md_slot.h index a033daec607..b6cb59147d5 100644 --- a/src/devices/bus/megadrive/md_slot.h +++ b/src/devices/bus/megadrive/md_slot.h @@ -61,6 +61,7 @@ enum LIONK3, /* Lion King 3, Super Donkey Kong 99, Super King Kong 99 */ MC_PIRATE, /* Super 19 in 1, Super 15 in 1, 12 in 1 and a few more multicarts */ MJLOVER, /* Mahjong Lover */ + CJMJCLUB, /* Super Mahjong Club */ POKEMONA, /* Pocket Monster Alt Protection */ REALTEC, /* Whac a Critter/Mallet legend, Defend the Earth, Funnyworld/Ballonboy */ REDCLIFF, /* Romance of the Three Kingdoms - Battle of Red Cliffs, already decoded from .mdx format */ diff --git a/src/devices/bus/megadrive/rom.cpp b/src/devices/bus/megadrive/rom.cpp index 16b12561c8a..ed17cfff044 100644 --- a/src/devices/bus/megadrive/rom.cpp +++ b/src/devices/bus/megadrive/rom.cpp @@ -41,6 +41,7 @@ const device_type MD_ROM_SMB2 = &device_creator<md_rom_smb2_device>; const device_type MD_ROM_SBUBL = &device_creator<md_rom_sbubl_device>; const device_type MD_ROM_RX3 = &device_creator<md_rom_rx3_device>; const device_type MD_ROM_MJLOV = &device_creator<md_rom_mjlov_device>; +const device_type MD_ROM_CJMJCLUB = &device_creator<md_rom_cjmjclub_device>; const device_type MD_ROM_KOF98 = &device_creator<md_rom_kof98_device>; const device_type MD_ROM_KOF99 = &device_creator<md_rom_kof99_device>; const device_type MD_ROM_SOULB = &device_creator<md_rom_soulb_device>; @@ -141,6 +142,11 @@ md_rom_mjlov_device::md_rom_mjlov_device(const machine_config &mconfig, const ch { } +md_rom_cjmjclub_device::md_rom_cjmjclub_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_CJMJCLUB, "MD Chaoji Majiang Club / Super Mahjong Club", tag, owner, clock, "md_rom_cjmjclub", __FILE__) +{ +} + md_rom_kof98_device::md_rom_kof98_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : md_std_rom_device(mconfig, MD_ROM_KOF98, "MD KOF 98", tag, owner, clock, "md_rom_kof98", __FILE__) { @@ -917,6 +923,23 @@ READ16_MEMBER(md_rom_mjlov_device::read) /*------------------------------------------------- + CHAOJI MAJIANG CLUB + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_cjmjclub_device::read) +{ + if (offset == 0x400000/2) return 0x9000; + if (offset == 0x400002/2) return 0xd300; + + // non-protection accesses + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; +} + + +/*------------------------------------------------- SUPER BUBBLE BOBBLE MD -------------------------------------------------*/ diff --git a/src/devices/bus/megadrive/rom.h b/src/devices/bus/megadrive/rom.h index dcb1536f974..3bafead4346 100644 --- a/src/devices/bus/megadrive/rom.h +++ b/src/devices/bus/megadrive/rom.h @@ -263,6 +263,18 @@ public: virtual DECLARE_READ16_MEMBER(read) override; }; +// ======================> md_rom_cjmjclub_device + +class md_rom_cjmjclub_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_cjmjclub_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ16_MEMBER(read) override; +}; + // ======================> md_rom_pokea_device class md_rom_pokea_device : public md_std_rom_device @@ -585,6 +597,7 @@ extern const device_type MD_ROM_LION2; extern const device_type MD_ROM_LION3; extern const device_type MD_ROM_MCPIR; extern const device_type MD_ROM_MJLOV; +extern const device_type MD_ROM_CJMJCLUB; extern const device_type MD_ROM_POKEA; extern const device_type MD_ROM_POKESTAD; extern const device_type MD_ROM_REALTEC; diff --git a/src/devices/cpu/adsp2100/2100ops.hxx b/src/devices/cpu/adsp2100/2100ops.hxx index 31cae1ae59b..c52767bd9cf 100644 --- a/src/devices/cpu/adsp2100/2100ops.hxx +++ b/src/devices/cpu/adsp2100/2100ops.hxx @@ -380,7 +380,11 @@ void adsp21xx_device::write_reg1(int regnum, INT32 val) break; case 3: - logerror("ADSP %04x: Writing to an invalid register!\n", m_ppc); + // Check for DMOVLAY instruction callback + if (regnum == 0xf && !m_dmovlay_cb.isnull()) + m_dmovlay_cb(val & 0x3fff); + else + logerror("ADSP %04x: Writing to an invalid register! RGP=01 RegCode=%1X Val=%04X\n", m_ppc, regnum, val); break; } } @@ -505,7 +509,7 @@ INT32 adsp21xx_device::read_reg3(int regnum) case 0x08: if (!m_sport_rx_cb.isnull()) return m_sport_rx_cb(0); else return 0; case 0x0a: if (!m_sport_rx_cb.isnull()) return m_sport_rx_cb(1); else return 0; case 0x0f: return pc_stack_pop_val(); - default: logerror("ADSP %04x: Reading from an invalid register!\n", m_ppc); return 0; + default: logerror("ADSP %04x: Reading from an invalid register! RGP=b11 RegCode=%1X\n", m_ppc, regnum); return 0; } } diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp index 868303fde40..dd9bdb4209d 100644 --- a/src/devices/cpu/adsp2100/adsp2100.cpp +++ b/src/devices/cpu/adsp2100/adsp2100.cpp @@ -157,7 +157,8 @@ adsp21xx_device::adsp21xx_device(const machine_config &mconfig, device_type type (m_chip_type >= CHIP_TYPE_ADSP2101) ? 0x3f : 0x0f), m_sport_rx_cb(*this), m_sport_tx_cb(*this), - m_timer_fired_cb(*this) + m_timer_fired_cb(*this), + m_dmovlay_cb(*this) { // initialize remaining state memset(&m_core, 0, sizeof(m_core)); @@ -405,6 +406,7 @@ void adsp21xx_device::device_start() m_sport_rx_cb.resolve(); m_sport_tx_cb.resolve(); m_timer_fired_cb.resolve(); + m_dmovlay_cb.resolve(); // get our address spaces m_program = &space(AS_PROGRAM); diff --git a/src/devices/cpu/adsp2100/adsp2100.h b/src/devices/cpu/adsp2100/adsp2100.h index f2393f986d2..282a340e040 100644 --- a/src/devices/cpu/adsp2100/adsp2100.h +++ b/src/devices/cpu/adsp2100/adsp2100.h @@ -192,6 +192,9 @@ enum #define MCFG_ADSP21XX_TIMER_FIRED_CB(_devcb) \ devcb = &adsp21xx_device::set_timer_fired_callback(*device, DEVCB_##_devcb); +#define MCFG_ADSP21XX_DMOVLAY_CB(_devcb) \ + devcb = &adsp21xx_device::set_dmovlay_callback(*device, DEVCB_##_devcb); + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -220,6 +223,7 @@ public: template<class _Object> static devcb_base &set_sport_rx_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_sport_rx_cb.set_callback(object); } template<class _Object> static devcb_base &set_sport_tx_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_sport_tx_cb.set_callback(object); } template<class _Object> static devcb_base &set_timer_fired_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_timer_fired_cb.set_callback(object); } + template<class _Object> static devcb_base &set_dmovlay_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_dmovlay_cb.set_callback(object); } // public interfaces void load_boot_data(UINT8 *srcdata, UINT32 *dstdata); @@ -459,6 +463,7 @@ protected: devcb_read32 m_sport_rx_cb; // callback for serial receive devcb_write32 m_sport_tx_cb; // callback for serial transmit devcb_write_line m_timer_fired_cb; // callback for timer fired + devcb_write_line m_dmovlay_cb; // callback for DMOVLAY instruction // debugging #if ADSP_TRACK_HOTSPOTS diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp index 82bde76b7c2..382aa865522 100644 --- a/src/devices/cpu/sparc/mb86901.cpp +++ b/src/devices/cpu/sparc/mb86901.cpp @@ -165,6 +165,12 @@ void mb86901_device::device_stop() void mb86901_device::device_reset() { + m_queued_tt = 0; + m_queued_priority = 0; + m_asi = 0; + MAE = false; + HOLD_BUS = false; + PC = 0; nPC = 4; memset(m_r, 0, sizeof(UINT32) * 120); @@ -699,7 +705,7 @@ bool mb86901_device::execute_group2(UINT32 op) bool v = ((arg1 & 0x80000000) == (arg2 & 0x80000000) && (arg2 & 0x80000000) != (result & 0x80000000)) || ((arg1 & 3) != 0) || ((arg2 & 3) != 0); if (v) { - queue_trap(sparc_tag_overflow); + trap(SPARC_TAG_OVERFLOW); } else { @@ -716,7 +722,7 @@ bool mb86901_device::execute_group2(UINT32 op) bool v = ((arg1 & 0x80000000) == (arg2 & 0x80000000) && (arg2 & 0x80000000) != (result & 0x80000000)) || ((arg1 & 3) != 0) || ((arg2 & 3) != 0); if (v) { - queue_trap(sparc_tag_overflow); + trap(SPARC_TAG_OVERFLOW); } else { @@ -795,7 +801,7 @@ bool mb86901_device::execute_group2(UINT32 op) case 41: // rd psr if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { @@ -805,7 +811,7 @@ bool mb86901_device::execute_group2(UINT32 op) case 42: // rd wim if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { @@ -815,7 +821,7 @@ bool mb86901_device::execute_group2(UINT32 op) case 43: // rd tbr if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { @@ -837,14 +843,14 @@ bool mb86901_device::execute_group2(UINT32 op) case 49: // wr psr if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { UINT32 new_psr = (arg1 ^ arg2) & ~PSR_ZERO_MASK; if ((new_psr & PSR_CWP_MASK) >= WINDOW_COUNT) { - queue_trap(sparc_illegal_instruction); + trap(SPARC_ILLEGAL_INSTRUCTION); } else { @@ -856,7 +862,7 @@ bool mb86901_device::execute_group2(UINT32 op) case 50: // wr wim if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { @@ -866,7 +872,7 @@ bool mb86901_device::execute_group2(UINT32 op) case 51: // wr tbr if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { @@ -876,13 +882,13 @@ bool mb86901_device::execute_group2(UINT32 op) case 52: // FPop1 if (FPU_DISABLED) { - queue_trap(sparc_floating_point_disabled); + trap(SPARC_FLOATING_POINT_DISABLED); } break; case 53: // FPop2 if (FPU_DISABLED) { - queue_trap(sparc_floating_point_disabled); + trap(SPARC_FLOATING_POINT_DISABLED); } break; case 56: // jmpl @@ -891,7 +897,7 @@ bool mb86901_device::execute_group2(UINT32 op) m_icount--; if (addr & 3) { - queue_trap(sparc_mem_address_not_aligned); + trap(SPARC_MEM_ADDRESS_NOT_ALIGNED); } else { @@ -909,11 +915,11 @@ bool mb86901_device::execute_group2(UINT32 op) { if (IS_USER) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); } else { - queue_trap(sparc_illegal_instruction); + trap(SPARC_ILLEGAL_INSTRUCTION); } break; } @@ -921,17 +927,17 @@ bool mb86901_device::execute_group2(UINT32 op) { if (IS_USER) { - queue_trap(sparc_reset, sparc_privileged_instruction); + trap(SPARC_RESET, SPARC_PRIVILEGED_INSTRUCTION); break; } else if (m_wim & (1 << new_cwp)) { - queue_trap(sparc_reset, sparc_window_underflow); + trap(SPARC_RESET, SPARC_WINDOW_UNDERFLOW); break; } else if (ADDRESS & 3) { - queue_trap(sparc_reset, sparc_mem_address_not_aligned); + trap(SPARC_RESET, SPARC_MEM_ADDRESS_NOT_ALIGNED); break; } } @@ -963,7 +969,7 @@ bool mb86901_device::execute_group2(UINT32 op) UINT8 new_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT; if (m_wim & (1 << new_cwp)) { - queue_trap(sparc_window_overflow); + trap(SPARC_WINDOW_OVERFLOW); } else { @@ -976,7 +982,7 @@ bool mb86901_device::execute_group2(UINT32 op) UINT8 new_cwp = (m_cwp + 1) % WINDOW_COUNT; if (m_wim & (1 << new_cwp)) { - queue_trap(sparc_window_overflow); + trap(SPARC_WINDOW_UNDERFLOW); } else { @@ -985,7 +991,7 @@ bool mb86901_device::execute_group2(UINT32 op) break; } default: - queue_trap(sparc_illegal_instruction); + trap(SPARC_ILLEGAL_INSTRUCTION); break; } @@ -1014,17 +1020,17 @@ bool mb86901_device::check_main_traps(UINT32 op, bool privileged, UINT32 alignme bool trap_queued = false; if (privileged && !m_s) { - queue_trap(sparc_privileged_instruction); + trap(SPARC_PRIVILEGED_INSTRUCTION); trap_queued = true; } if (alignment & ADDRESS) { - queue_trap(sparc_mem_address_not_aligned); + trap(SPARC_MEM_ADDRESS_NOT_ALIGNED); trap_queued = true; } if ((registeralign & RD) || (noimmediate && USEIMM)) { - queue_trap(sparc_illegal_instruction); + trap(SPARC_ILLEGAL_INSTRUCTION); trap_queued = true; } return trap_queued; @@ -1051,21 +1057,44 @@ void mb86901_device::execute_group3(UINT32 op) switch (OP3) { case 0: // ld + { check_main_traps(op, false, 3, 0, false); - SET_RDREG(read_word(m_data_asi, ADDRESS)); + UINT32 result = read_word(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 1: // ldub - SET_RDREG(read_byte(m_data_asi, ADDRESS)); + { + UINT32 result = read_byte(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 2: // lduh + { check_main_traps(op, false, 1, 0, false); - SET_RDREG(read_half(m_data_asi, ADDRESS)); + UINT32 result = read_half(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 3: // ldd + { check_main_traps(op, false, 7, 1, false); - SET_RDREG(read_word(m_data_asi, ADDRESS)); - REG(RD+1) = read_word(m_data_asi, ADDRESS+4); + UINT32 result = read_word(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); + result = read_word(m_data_asi, ADDRESS+4); + if (MAE || HOLD_BUS) + break; + REG(RD+1) = result; break; + } case 4: // st check_main_traps(op, false, 3, 0, false); write_word(m_data_asi, ADDRESS, RDREG); @@ -1080,38 +1109,78 @@ void mb86901_device::execute_group3(UINT32 op) case 7: // std check_main_traps(op, false, 7, 1, false); write_word(m_data_asi, ADDRESS, RDREG); + if (MAE || HOLD_BUS) + break; write_word(m_data_asi, ADDRESS, REG(RD+1)); break; case 9: // ldsb - SET_RDREG(read_signed_byte(m_data_asi, ADDRESS)); + { + UINT32 result = read_signed_byte(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 10: // lsdh + { check_main_traps(op, false, 1, 0, false); - SET_RDREG(read_signed_half(m_data_asi, ADDRESS)); + UINT32 result = read_signed_half(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 13: // ldstub - SET_RDREG(read_byte(m_data_asi, ADDRESS)); + { + UINT32 result = read_byte(m_data_asi, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); write_byte(m_data_asi, ADDRESS, 0xff); break; + } case 15: // swap, SPARCv8 break; case 16: // lda + { check_main_traps(op, true, 3, 0, true); - SET_RDREG(read_word(ASI, ADDRESS)); + UINT32 result = read_word(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 17: // lduba + { check_main_traps(op, true, 0, 0, true); - SET_RDREG(read_byte(ASI, ADDRESS)); + UINT32 result = read_byte(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 18: // lduha + { check_main_traps(op, true, 1, 0, true); - SET_RDREG(read_half(ASI, ADDRESS)); + UINT32 result = read_half(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 19: // ldda + { check_main_traps(op, true, 7, 1, true); - SET_RDREG(read_word(ASI, ADDRESS)); - REG(RD+1) = read_word(ASI, ADDRESS+4); + UINT32 result = read_word(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); + result = read_word(ASI, ADDRESS+4); + if (MAE || HOLD_BUS) + break; + REG(RD+1) = result; break; + } case 20: // sta check_main_traps(op, true, 3, 0, true); write_word(ASI, ADDRESS, RDREG); @@ -1127,36 +1196,67 @@ void mb86901_device::execute_group3(UINT32 op) case 23: // stda check_main_traps(op, true, 7, 1, true); write_word(ASI, ADDRESS, RDREG); + if (MAE || HOLD_BUS) + break; write_word(ASI, ADDRESS+4, REG(RD+1)); break; case 25: // ldsba + { check_main_traps(op, true, 0, 0, true); - SET_RDREG(read_signed_byte(ASI, ADDRESS)); + UINT32 result = read_signed_byte(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 26: // ldsha + { check_main_traps(op, true, 1, 0, true); - SET_RDREG(read_signed_half(ASI, ADDRESS)); + UINT32 result = read_signed_half(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); break; + } case 29: // ldstuba + { check_main_traps(op, true, 0, 0, true); - SET_RDREG(read_byte(ASI, ADDRESS)); + UINT32 result = read_byte(ASI, ADDRESS); + if (MAE || HOLD_BUS) + break; + SET_RDREG(result); write_byte(ASI, ADDRESS, 0xff); break; + } case 31: // swapa, SPARCv8 break; case 32: // ld fpr + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 33: // ld fsr + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 35: // ldd fpr + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 36: // st fpr + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 37: // st fsr + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 38: // std fq, SPARCv8 + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 39: // std fpr + if (FPU_DISABLED) + trap(SPARC_FLOATING_POINT_DISABLED); break; case 40: // ld cpr, SPARCv8 break; @@ -1174,7 +1274,10 @@ void mb86901_device::execute_group3(UINT32 op) break; } - m_icount -= ldst_cycles[OP3]; + if (MAE || HOLD_BUS) + m_icount--; + else + m_icount -= ldst_cycles[OP3]; } @@ -1253,7 +1356,7 @@ bool mb86901_device::execute_ticc(UINT32 op) { UINT32 arg2 = USEIMM ? SIMM7 : RS2REG; UINT8 tt = 128 + ((RS1REG + arg2) & 0x7f); - queue_trap(sparc_trap_instruction, tt); + trap(SPARC_TRAP_INSTRUCTION, tt); m_icount -= 3; return false; } @@ -1263,24 +1366,32 @@ bool mb86901_device::execute_ticc(UINT32 op) //------------------------------------------------- -// queue_trap - flag an incoming trap of a given +// trap - flag an incoming trap of a given // type //------------------------------------------------- -void mb86901_device::queue_trap(UINT8 type, UINT8 tt_override) +void mb86901_device::trap(UINT8 type, UINT8 tt_override) { - if (type == sparc_reset) + if (type == SPARC_RESET) { m_queued_priority = m_trap_priorities[0]; m_queued_tt = tt_override; } else { - if (type == sparc_trap_instruction) + if (type == SPARC_TRAP_INSTRUCTION) { type = tt_override; } + if (type >= SPARC_INT1 && type <= SPARC_INT14) + { + if (!ET) + return; + int irl = (type - SPARC_INT1) + 1; + if (irl <= PIL) + return; + } if (m_trap_priorities[type] < m_queued_priority) { m_queued_priority = m_trap_priorities[type]; @@ -1302,6 +1413,7 @@ bool mb86901_device::invoke_queued_traps() if (m_queued_priority > 0) { m_queued_priority = 0; + m_queued_tt = 0; m_et = false; m_ps = m_s; @@ -1336,8 +1448,20 @@ void mb86901_device::execute_run() while (m_icount > 0) { + bool trap_was_queued = invoke_queued_traps(); + if (trap_was_queued) + { + m_icount -= 4; + continue; + } + debugger_instruction_hook(this, m_pc); + if (HOLD_BUS) + { + m_icount--; + continue; + } UINT32 op = GET_OPCODE; bool update_npc = true; @@ -1390,7 +1514,7 @@ void mb86901_device::execute_run() REG(0) = 0; bool trap_taken = invoke_queued_traps(); - if (!trap_taken && update_npc) + if (!trap_taken && update_npc && !HOLD_BUS) { PC = nPC; nPC = PC + 4; diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h index 0c23bdbe29c..324d46137a9 100644 --- a/src/devices/cpu/sparc/sparc.h +++ b/src/devices/cpu/sparc/sparc.h @@ -9,6 +9,34 @@ #ifndef __SPARC_H__ #define __SPARC_H__ +#define SPARC_RESET 0 +#define SPARC_INSTRUCTION_ACCESS_EXCEPTION 1 +#define SPARC_ILLEGAL_INSTRUCTION 2 +#define SPARC_PRIVILEGED_INSTRUCTION 3 +#define SPARC_FLOATING_POINT_DISABLED 4 +#define SPARC_WINDOW_OVERFLOW 5 +#define SPARC_WINDOW_UNDERFLOW 6 +#define SPARC_MEM_ADDRESS_NOT_ALIGNED 7 +#define SPARC_FLOATING_POINT_EXCEPTION 8 +#define SPARC_DATA_ACCESS_EXCEPTION 9 +#define SPARC_TAG_OVERFLOW 10 +#define SPARC_INT1 17 +#define SPARC_INT2 18 +#define SPARC_INT3 19 +#define SPARC_INT4 20 +#define SPARC_INT5 21 +#define SPARC_INT6 22 +#define SPARC_INT7 23 +#define SPARC_INT8 24 +#define SPARC_INT9 25 +#define SPARC_INT10 26 +#define SPARC_INT11 27 +#define SPARC_INT12 28 +#define SPARC_INT13 29 +#define SPARC_INT14 30 +#define SPARC_INT15 31 +#define SPARC_TRAP_INSTRUCTION 128 + class mb86901_device : public cpu_device { public: @@ -40,8 +68,12 @@ public: UINT8 get_asi() { return m_asi; } UINT32 pc() { return m_pc; } + void trap(UINT8 type, UINT8 tt_override = 0); + void set_mae() { m_mae = true; } + void hold_bus() { m_hold_bus = true; } + void release_bus() { m_hold_bus = false; } + protected: - void queue_trap(UINT8 type, UINT8 tt_override = 0); bool invoke_queued_traps(); bool check_main_traps(UINT32 op, bool privileged, UINT32 alignment, UINT8 registeralign, bool noimmediate); @@ -103,6 +135,8 @@ protected: UINT8 m_trap_priorities[256]; UINT8 m_queued_tt; UINT8 m_queued_priority; + bool m_mae; + bool m_hold_bus; int m_icount; // debugger helpers diff --git a/src/devices/cpu/sparc/sparcdefs.h b/src/devices/cpu/sparc/sparcdefs.h index dbc50fd4e00..185845c1d4f 100644 --- a/src/devices/cpu/sparc/sparcdefs.h +++ b/src/devices/cpu/sparc/sparcdefs.h @@ -114,35 +114,9 @@ #define Y m_y -enum sparc_trap_type -{ - sparc_reset = 0, - sparc_instruction_access_exception = 1, - sparc_illegal_instruction = 2, - sparc_privileged_instruction = 3, - sparc_floating_point_disabled = 4, - sparc_window_overflow = 5, - sparc_window_underflow = 6, - sparc_mem_address_not_aligned = 7, - sparc_floating_point_exception = 8, - sparc_data_access_exception = 9, - sparc_tag_overflow = 10, - sparc_int1 = 17, - sparc_int2 = 18, - sparc_int3 = 19, - sparc_int4 = 20, - sparc_int5 = 21, - sparc_int6 = 22, - sparc_int7 = 23, - sparc_int8 = 24, - sparc_int9 = 25, - sparc_int10 = 26, - sparc_int11 = 27, - sparc_int12 = 28, - sparc_int13 = 29, - sparc_int14 = 30, - sparc_int15 = 31, - sparc_trap_instruction = 128 -}; +#define ET m_et +#define PIL m_pil +#define MAE m_mae +#define HOLD_BUS m_hold_bus #endif // __MB86901_DEFS_H__
\ No newline at end of file diff --git a/src/devices/machine/8530scc.cpp b/src/devices/machine/8530scc.cpp index c618fd57004..25484798b36 100644 --- a/src/devices/machine/8530scc.cpp +++ b/src/devices/machine/8530scc.cpp @@ -447,7 +447,7 @@ void scc8530_t::set_reg_a(int reg, UINT8 data) /*------------------------------------------------- - scc8530_set_reg_a + scc8530_set_reg_b -------------------------------------------------*/ void scc8530_t::set_reg_b(int reg, UINT8 data) @@ -457,46 +457,41 @@ void scc8530_t::set_reg_b(int reg, UINT8 data) -/*------------------------------------------------- - scc8530_r --------------------------------------------------*/ +//------------------------------------------------- +// reg_r - read handler, trampolines into normal +// getter +//------------------------------------------------- -READ8_MEMBER( scc8530_t::reg_r) +READ8_MEMBER(scc8530_t::reg_r) { - UINT8 result = 0; + return read_reg(offset & 3); +} - offset %= 4; + +//------------------------------------------------- +// read_reg - reads either the control or data +// port for either SCC channel. +//------------------------------------------------- + +UINT8 scc8530_t::read_reg(int offset) +{ switch(offset) { - case 0: - /* Channel B (Printer Port) Control */ - if (mode == 1) - mode = 0; - else - reg = 0; - - result = getbreg(); - break; + case 0: /* Channel B (Printer Port) Control */ + case 1: /* Channel A (Modem Port) Control */ - case 1: - /* Channel A (Modem Port) Control */ if (mode == 1) mode = 0; else reg = 0; - result = getareg(); - break; - - case 2: - /* Channel B (Printer Port) Data */ - result = channel[1].rxData; + result = (offset == 0) ? getbreg(); : getareg() break; - case 3: - /* Channel A (Modem Port) Data */ - result = channel[0].rxData; + case 2: /* Channel B (Printer Port) Data */ + case 3:/* Channel A (Modem Port) Data */ + result = channel[offset == 2 ? 1 : 0].rxData; break; } return result; @@ -504,116 +499,85 @@ READ8_MEMBER( scc8530_t::reg_r) -/*------------------------------------------------- - scc8530_w --------------------------------------------------*/ +//------------------------------------------------- +// reg_w - write handler, trampolines into normal +// setter +//------------------------------------------------- WRITE8_MEMBER( scc8530_t::reg_w ) { - Chan *pChan; + write_reg(offset & 3, data); +} + - offset &= 3; + +//------------------------------------------------- +// write_reg - writes either the control or data +// port for either SCC channel. +//------------------------------------------------- + +void scc8530_t::write_reg(int offset, UINT8 data) +{ + offset & 3; // printf(" mode %d data %x offset %d \n", mode, data, offset); + Chan *pChan; switch(offset) { - case 0: - /* Channel B (Printer Port) Control */ - if (mode == 0) - { - if((data & 0xf0) == 0) // not a reset command - { - mode = 1; - reg = data & 0x0f; -// putbreg(data & 0xf0); - } - else if (data == 0x10) - { - pChan = &channel[1]; - // clear ext. interrupts - pChan->extIRQPending = 0; - pChan->baudIRQPending = 0; - updateirqs(); - } - } - else - { - mode = 0; - putreg(1, data); - } - break; - - case 1: - /* Channel A (Modem Port) Control */ + case 0: /* Channel B (Printer Port) Control */ + case 1: /* Channel A (Modem Port) Control */ + { + int chan = ((offset == 2) ? 1 : 0); if (mode == 0) { if((data & 0xf0) == 0) // not a reset command { mode = 1; reg = data & 0x0f; -// putareg(data & 0xf0); +// putbreg(data & 0xf0); } else if (data == 0x10) { - pChan = &channel[0]; // clear ext. interrupts - pChan->extIRQPending = 0; - pChan->baudIRQPending = 0; + channel[chan].extIRQPending = 0; + channel[chan].baudIRQPending = 0; updateirqs(); } } else { mode = 0; - putreg(0, data); + putreg(chan, data); } break; + } - case 2: - /* Channel B (Printer Port) Data */ - pChan = &channel[1]; - - if (pChan->txEnable) - { - pChan->txData = data; - // local loopback? - if (pChan->reg_val[14] & 0x10) - { - pChan->rxData = data; - pChan->reg_val[0] |= 0x01; // Rx character available - } - pChan->reg_val[1] |= 0x01; // All sent - pChan->reg_val[0] |= 0x04; // Tx empty - pChan->txUnderrun = 1; - pChan->txIRQPending = 1; - updateirqs(); - } - break; - - case 3: - /* Channel A (Modem Port) Data */ - pChan = &channel[0]; - - if (pChan->txEnable) + case 2: /* Channel B (Printer Port) Data */ + case 3: /* Channel A (Modem Port) Data */ + { + int chan = ((offset == 2) ? 1 : 0); + if (channel[chan].txEnable) { - pChan->txData = data; + channel[chan].txData = data; // local loopback? - if (pChan->reg_val[14] & 0x10) + if (channel[chan].reg_val[14] & 0x10) { - pChan->rxData = data; - pChan->reg_val[0] |= 0x01; // Rx character available + channel[chan].rxData = data; + channel[chan].reg_val[0] |= 0x01; // Rx character available } - pChan->reg_val[1] |= 0x01; // All sent - pChan->reg_val[0] |= 0x04; // Tx empty - pChan->txUnderrun = 1; - pChan->txIRQPending = 1; + channel[chan].reg_val[1] |= 0x01; // All sent + channel[chan].reg_val[0] |= 0x04; // Tx empty + channel[chan].txUnderrun = 1; + channel[chan].txIRQPending = 1; updateirqs(); } break; + } } } + /* AppleTalk check: diff --git a/src/devices/machine/8530scc.h b/src/devices/machine/8530scc.h index 2e6e703ceb8..b711f7cdabe 100644 --- a/src/devices/machine/8530scc.h +++ b/src/devices/machine/8530scc.h @@ -43,6 +43,9 @@ public: DECLARE_READ8_MEMBER(reg_r); DECLARE_WRITE8_MEMBER(reg_w); + void write_reg(int offset, UINT8 data); + UINT8 read_reg(int offset); + protected: virtual void device_start() override; virtual void device_reset() override; diff --git a/src/devices/video/zeus2.cpp b/src/devices/video/zeus2.cpp new file mode 100644 index 00000000000..02e9b9d9e52 --- /dev/null +++ b/src/devices/video/zeus2.cpp @@ -0,0 +1,1311 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/************************************************************************* + + Midway Zeus2 Video + +**************************************************************************/ +#include "zeus2.h" + +#define LOG_REGS 0 + +/************************************* +* Constructor +*************************************/ +zeus2_renderer::zeus2_renderer(zeus2_device *state) + : poly_manager<float, zeus2_poly_extra_data, 4, 10000>(state->machine()) + , m_state(state) +{ +} + +const device_type ZEUS2 = &device_creator<zeus2_device>; + +zeus2_device::zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ZEUS2, "Midway Zeus2", tag, owner, clock, "zeus2", __FILE__), + m_vblank(*this), m_irq(*this) +{ +} + +/************************************* +* Display interrupt generation +*************************************/ + +TIMER_CALLBACK_MEMBER(zeus2_device::display_irq_off) +{ + m_vblank(CLEAR_LINE); + + //attotime vblank_period = m_screen->time_until_pos(m_zeusbase[0x37] & 0xffff); + + ///* if zero, adjust to next frame, otherwise we may get stuck in an infinite loop */ + //if (vblank_period == attotime::zero) + // vblank_period = m_screen->frame_period(); + //vblank_timer->adjust(vblank_period); + vblank_timer->adjust(m_screen->time_until_vblank_start()); + //machine().scheduler().timer_set(attotime::from_hz(30000000), timer_expired_delegate(FUNC(zeus2_device::display_irq), this)); +} + +TIMER_CALLBACK_MEMBER(zeus2_device::display_irq) +{ + m_vblank(ASSERT_LINE); + /* set a timer for the next off state */ + //machine().scheduler().timer_set(m_screen->time_until_pos(0), timer_expired_delegate(FUNC(zeus2_device::display_irq_off), this), 0, this); + machine().scheduler().timer_set(m_screen->time_until_vblank_end(), timer_expired_delegate(FUNC(zeus2_device::display_irq_off), this), 0, this); + //machine().scheduler().timer_set(attotime::from_hz(30000000), timer_expired_delegate(FUNC(zeus2_device::display_irq_off), this)); +} + +TIMER_CALLBACK_MEMBER(zeus2_device::int_timer_callback) +{ + //m_maincpu->set_input_line(2, ASSERT_LINE); + m_irq(ASSERT_LINE); +} + +/************************************* + * Video startup + *************************************/ + + +void zeus2_device::device_start() +{ + + /* allocate memory for "wave" RAM */ + waveram[0] = auto_alloc_array(machine(), UINT32, WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8/4); + waveram[1] = auto_alloc_array(machine(), UINT32, WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12/4); + + /* initialize polygon engine */ + poly = auto_alloc(machine(), zeus2_renderer(this)); + + //m_screen = machine().first_screen(); + m_screen = downcast<screen_device *>(machine().device("screen")); + m_vblank.resolve_safe(); + m_irq.resolve_safe(); + + /* we need to cleanup on exit */ + //machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(zeus2_device::exit_handler2), this)); + + int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(zeus2_device::int_timer_callback), this)); + vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(zeus2_device::display_irq), this)); + + /* save states */ + save_pointer(NAME(waveram[0]), WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8 / sizeof(waveram[0][0])); + save_pointer(NAME(waveram[1]), WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0])); + save_pointer(NAME(m_zeusbase), sizeof(m_zeusbase[0])*0x80); + save_item(NAME(zeus_fifo)); + save_item(NAME(zeus_fifo_words)); + save_item(NAME(zeus_cliprect.min_x)); + save_item(NAME(zeus_cliprect.max_x)); + save_item(NAME(zeus_cliprect.min_y)); + save_item(NAME(zeus_cliprect.max_y)); + save_item(NAME(zeus_matrix)); + save_item(NAME(zeus_point)); + save_item(NAME(zeus_texbase)); + save_item(NAME(m_fill_color)); + save_item(NAME(m_fill_depth)); +} + +void zeus2_device::device_reset() +{ + memset(m_zeusbase, 0, sizeof(m_zeusbase)); + zbase = 2.0f; + m_yScale = 0; + yoffs = 0; + texel_width = 256; + zeus_renderbase = waveram[1]; + zeus_fifo_words = 0; + m_fill_color = 0; + m_fill_depth = 0; +} + +void zeus2_device::device_stop() +{ +#if DUMP_WAVE_RAM + FILE *f = fopen("waveram.dmp", "w"); + int i; + + for (i = 0; i < WAVERAM0_WIDTH * WAVERAM0_HEIGHT; i++) + { + if (i % 4 == 0) fprintf(f, "%03X%03X: ", i / WAVERAM0_WIDTH, i % WAVERAM0_WIDTH); + fprintf(f, " %08X %08X ", + WAVERAM_READ32(waveram[0], i*2+0), + WAVERAM_READ32(waveram[0], i*2+1)); + if (i % 4 == 3) fprintf(f, "\n"); + } + fclose(f); +#endif + +#if TRACK_REG_USAGE +{ + reg_info *info; + int regnum; + + for (regnum = 0; regnum < 0x80; regnum++) + { + printf("Register %02X\n", regnum); + if (regread_count[regnum] == 0) + printf("\tNever read\n"); + else + printf("\tRead %d times\n", regread_count[regnum]); + + if (regwrite_count[regnum] == 0) + printf("\tNever written\n"); + else + { + printf("\tWritten %d times\n", regwrite_count[regnum]); + for (info = regdata[regnum]; info != nullptr; info = info->next) + printf("\t%08X\n", info->value); + } + } + + for (regnum = 0; regnum < 0x100; regnum++) + if (subregwrite_count[regnum] != 0) + { + printf("Sub-Register %02X (%d writes)\n", regnum, subregwrite_count[regnum]); + for (info = subregdata[regnum]; info != nullptr; info = info->next) + printf("\t%08X\n", info->value); + } +} +#endif + +} + + + +/************************************* + * + * Video update + * + *************************************/ + +UINT32 zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + int x, y; + + poly->wait(); + +if (machine().input().code_pressed(KEYCODE_UP)) { zbase += 1.0f; popmessage("Zbase = %f", (double) zbase); } +if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Zbase = %f", (double) zbase); } + + /* normal update case */ + if (!machine().input().code_pressed(KEYCODE_W)) + { + const void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x38] >> m_yScale); + int xoffs = screen.visible_area().min_x; + for (y = cliprect.min_y; y <= cliprect.max_y; y++) + { + UINT32 *dest = &bitmap.pix32(y); + UINT32 bufY = y >> m_yScale; + UINT32 bufOffsX = (m_yScale && (y & 1)) ? 0x200 : 0; + for (x = cliprect.min_x; x <= cliprect.max_x; x++) { + UINT32 bufX = x - xoffs + bufOffsX; + dest[x] = WAVERAM_READPIX(base, bufY, bufX); + //dest[x] = WAVERAM_READPIX(base, y, x - xoffs); + } + } + } + + /* waveram drawing case */ + else + { + const UINT64 *base; + + if (machine().input().code_pressed(KEYCODE_DOWN)) yoffs += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; + if (machine().input().code_pressed(KEYCODE_UP)) yoffs -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; + if (machine().input().code_pressed(KEYCODE_LEFT) && texel_width > 4) { texel_width >>= 1; while (machine().input().code_pressed(KEYCODE_LEFT)) ; } + if (machine().input().code_pressed(KEYCODE_RIGHT) && texel_width < 512) { texel_width <<= 1; while (machine().input().code_pressed(KEYCODE_RIGHT)) ; } + + if (yoffs < 0) yoffs = 0; + if (0) + base = (const UINT64 *)waveram0_ptr_from_expanded_addr(yoffs << 16); + else + base = (const UINT64 *)waveram1_ptr_from_expanded_addr(yoffs << 16); + + int xoffs = screen.visible_area().min_x; + for (y = cliprect.min_y; y <= cliprect.max_y; y++) + { + UINT32 *dest = &bitmap.pix32(y); + for (x = cliprect.min_x; x <= cliprect.max_x; x++) + { + if (0) { + UINT8 tex = get_texel_8bit(base, y, x, texel_width); + dest[x] = (tex << 16) | (tex << 8) | tex; + } + else { + dest[x] = WAVERAM_READPIX(base, y, x - xoffs); + } + } + } + popmessage("offs = %06X", yoffs); + } + + return 0; +} + + + +/************************************* + * + * Core read handler + * + *************************************/ + +READ32_MEMBER( zeus2_device::zeus2_r ) +{ + int logit = (offset != 0x00 && offset != 0x01 && + offset != 0x48 && offset != 0x49 && + offset != 0x54 && offset != 0x58 && offset != 0x59 && offset != 0x5a); + logit &= LOG_REGS; + UINT32 result = m_zeusbase[offset]; +#if TRACK_REG_USAGE + regread_count[offset]++; +#endif + + switch (offset) + { + case 0x00: + result = 0x20; + break; + + case 0x01: + /* bit $000C0070 are tested in a loop until 0 */ + /* bits $00080000 is tested in a loop until 0 */ + /* bit $00000004 is tested for toggling; probably VBLANK */ + result = 0x00; + if (m_screen->vblank()) + result |= 0x04; + break; + + case 0x07: + /* this is needed to pass the self-test in thegrid */ + result = 0x10451998; + break; + + case 0x54: + /* both upper 16 bits and lower 16 bits seem to be used as vertical counters */ + result = (m_screen->vpos() << 16) | m_screen->vpos(); + break; + } + + if (logit) + logerror("%08X:zeus2_r(%02X) = %08X\n", machine().device("maincpu")->safe_pc(), offset, result); + + return result; +} + + + +/************************************* + * + * Core write handler + * + *************************************/ + +WRITE32_MEMBER( zeus2_device::zeus2_w ) +{ + int logit = (offset != 0x08 && + (offset != 0x20 || data != 0) && + offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e && + offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e); + logit &= LOG_REGS; + if (logit) + logerror("%08X:zeus2_w", machine().device("maincpu")->safe_pc()); + zeus2_register32_w(offset, data, logit); +} + + + +/************************************* + * + * Handle register writes + * + *************************************/ + +void zeus2_device::zeus2_register32_w(offs_t offset, UINT32 data, int logit) +{ + UINT32 oldval = m_zeusbase[offset]; + +#if TRACK_REG_USAGE +regwrite_count[offset]++; +if (regdata_count[offset] < 256) +{ + reg_info **tailptr; + + for (tailptr = ®data[offset]; *tailptr != nullptr; tailptr = &(*tailptr)->next) + if ((*tailptr)->value == data) + break; + if (*tailptr == nullptr) + { + *tailptr = alloc_or_die(reg_info); + (*tailptr)->next = nullptr; + (*tailptr)->value = data; + regdata_count[offset]++; + } +} +#endif + + /* writes to register $CC need to force a partial update */ +// if ((offset & ~1) == 0xcc) +// m_screen->update_partial(m_screen->vpos()); + + /* always write to low word? */ + m_zeusbase[offset] = data; + + /* log appropriately */ + if (logit) + logerror("(%02X) = %08X\n", offset, data); + + /* handle the update */ + zeus2_register_update(offset, oldval, logit); +} + + + +/************************************* + * + * Update state after a register write + * + *************************************/ + +void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit) +{ + /* handle the writes; only trigger on low accesses */ + switch (offset) + { + case 0x08: + zeus_fifo[zeus_fifo_words++] = m_zeusbase[0x08]; + if (zeus2_fifo_process(zeus_fifo, zeus_fifo_words)) + zeus_fifo_words = 0; + + /* set the interrupt signal to indicate we can handle more */ + int_timer->adjust(attotime::from_nsec(500)); + break; + + case 0x20: + /* toggles between two values based on the page: + + Page # m_zeusbase[0x20] m_zeusbase[0x38] + ------ -------------- -------------- + 0 $04000190 $00000000 + 1 $04000000 $01900000 + */ + zeus2_pointer_write(m_zeusbase[0x20] >> 24, m_zeusbase[0x20]); + break; + + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + m_screen->update_partial(m_screen->vpos()); + { + // Just a guess. Atlantis startup has two scanlines per physical ram row + if ((m_zeusbase[0x30] & 0xfff) <= 0x100) + m_yScale = 1; + else + m_yScale = 0; + int vtotal = (m_zeusbase[0x37] & 0xffff) << m_yScale; + int htotal = (m_zeusbase[0x34] >> 16); + + rectangle visarea((m_zeusbase[0x33] >> 16), htotal - 1, 0, (m_zeusbase[0x35] & 0xffff)<< m_yScale); + if (htotal > 0 && vtotal > 0 && visarea.min_x < visarea.max_x && visarea.max_y < vtotal) + { + m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS((double)ZEUS2_VIDEO_CLOCK / 4.0 / (htotal * vtotal))); + zeus_cliprect = visarea; + zeus_cliprect.max_x -= zeus_cliprect.min_x; + zeus_cliprect.min_x = 0; + // Startup vblank timer + vblank_timer->adjust(attotime::from_usec(100)); + } + } + break; + + case 0x38: + { + UINT32 temp = m_zeusbase[0x38]; + m_zeusbase[0x38] = oldval; + m_screen->update_partial(m_screen->vpos()); + log_fifo = machine().input().code_pressed(KEYCODE_L); + //log_fifo = 1; + m_zeusbase[0x38] = temp; + } + break; + + case 0x40: + /* in direct mode it latches values */ + if ((m_zeusbase[0x4e] & 0x20) && m_zeusbase[0x40] == 0x00820000) + { + const void *src = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); + m_zeusbase[0x48] = WAVERAM_READ32(src, 0); + m_zeusbase[0x49] = WAVERAM_READ32(src, 1); + + if (m_zeusbase[0x4e] & 0x40) + { + m_zeusbase[0x41]++; + m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; + m_zeusbase[0x41] &= ~0xfc00; + } + } + break; + case 0x41: + /* this is the address, except in read mode, where it latches values */ + if (m_zeusbase[0x4e] & 0x10) + { + const void *src = waveram0_ptr_from_expanded_addr(oldval); + m_zeusbase[0x41] = oldval; + m_zeusbase[0x48] = WAVERAM_READ32(src, 0); + m_zeusbase[0x49] = WAVERAM_READ32(src, 1); + + if (m_zeusbase[0x4e] & 0x40) + { + m_zeusbase[0x41]++; + m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; + m_zeusbase[0x41] &= ~0xfc00; + } + } else { + // mwskinsa (atlantis) writes 0xffffffff and expects 0x1fff03ff to be read back + m_zeusbase[0x41] &= 0x1fff03ff; + } + break; + + case 0x48: + case 0x49: + /* if we're in write mode, process it */ + if (m_zeusbase[0x40] == 0x00890000) + { + /* + m_zeusbase[0x4e]: + bit 0-1: which register triggers write through + bit 3: enable write through via these registers + bit 4: seems to be set during reads, when 0x41 is used for latching + bit 6: enable autoincrement on write through + */ + if ((m_zeusbase[0x4e] & 0x08) && (offset & 3) == (m_zeusbase[0x4e] & 3)) + { + void *dest = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); + WAVERAM_WRITE32(dest, 0, m_zeusbase[0x48]); + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x49]); + + if (m_zeusbase[0x4e] & 0x40) + { + m_zeusbase[0x41]++; + m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; + m_zeusbase[0x41] &= ~0xfc00; + } + } + } + + /* make sure we log anything else */ + else if (logit) + logerror("\t[40]=%08X [4E]=%08X\n", m_zeusbase[0x40], m_zeusbase[0x4e]); + break; + + case 0x50: + if (m_zeusbase[0x50] == 0x00510000) { + // SGRAM Special Mode Register Write + if (m_zeusbase[0x51] & 0x00400000) { + // SGRAM Mask Register + if ((m_zeusbase[0x58] & m_zeusbase[0x59] & m_zeusbase[0x5a]) != 0xffffffff) + logerror("zeus2_register_update: Warning! Mask Register not equal to 0xffffffff\n"); + } + if (m_zeusbase[0x51] & 0x00200000) { + // SGRAM Color Register + m_fill_color = m_zeusbase[0x58]; + m_fill_depth = m_zeusbase[0x5a] & 0xffff; + if (m_zeusbase[0x58] != m_zeusbase[0x59]) + logerror("zeus2_register_update: Warning! Different fill colors are set.\n"); + } + } + else if (1 && (m_zeusbase[0x50] & 0x00080000) && (m_zeusbase[0x50] & 0xffff)) { + // Fast fill + // Unknown what the exact bit fields are, this is a just a guess + // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame + // crusnexo: 0x007831FF => clear one frame + // thegrid: 0x008831FF => clear one frame + //UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x7; + UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x3; + UINT32 lastCol = (((m_zeusbase[0x50] >> 0) & 0xff) << 2) | 0x3; + // Not sure how to select + //void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); + void *base = (m_zeusbase[0x50] & 0x800000) ? waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]) : zeus_renderbase; + for (int y = 0; y <= lastRow; y++) + for (int x = 0; x <= lastCol; x++) { + WAVERAM_WRITEPIX(base, y, x, m_fill_color); + WAVERAM_WRITEDEPTH(base, y, x, m_fill_depth); + } + //waveram_plot_depth(y, x, m_fill_color, m_fill_depth); + } + else if ((m_zeusbase[0x5e] >> 16) != 0xF208) { + /* If 0x5e==0xf20a0000 (atlantis) or 0xf20d0000 (the grid) then process the read/write now */ + /* + m_zeusbase[0x5e]: + bit 0-1: which register triggers write through + bit 3: enable write through via these registers + bit 4: seems to be set during reads, when 0x51 is used for latching + bit 5: unknown, currently used to specify ordering, but this is suspect + bit 6: enable autoincrement on write through + */ + if (m_zeusbase[0x50] == 0x00890000) + { + void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); + WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]); + if (m_zeusbase[0x5e] & 0x20) + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]); + else + { + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]); + WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]); + } + + if (m_zeusbase[0x5e] & 0x40) + { + m_zeusbase[0x51]++; + m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + m_zeusbase[0x51] &= ~0xfe00; + } + } + else if (m_zeusbase[0x50] == 0x00720000) { + /* Do the read */ + const void *src = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); + m_zeusbase[0x58] = WAVERAM_READ32(src, 0); + m_zeusbase[0x59] = WAVERAM_READ32(src, 1); + m_zeusbase[0x5a] = WAVERAM_READ32(src, 2); + + if (m_zeusbase[0x5e] & 0x40) + { + m_zeusbase[0x51]++; + m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + m_zeusbase[0x51] &= ~0xfe00; + } + } + } + break; + case 0x51: + + /* in this mode, crusnexo expects the reads to immediately latch */ + //if ((m_zeusbase[0x50] == 0x00a20000) || (m_zeusbase[0x50] == 0x00720000)) + if (m_zeusbase[0x50] == 0x00a20000) + oldval = m_zeusbase[0x51]; + + /* this is the address, except in read mode, where it latches values */ + if ((m_zeusbase[0x5e] & 0x10) || (m_zeusbase[0x50] == 0x00a20000)) + { + const void *src = waveram1_ptr_from_expanded_addr(oldval); + m_zeusbase[0x51] = oldval; + m_zeusbase[0x58] = WAVERAM_READ32(src, 0); + m_zeusbase[0x59] = WAVERAM_READ32(src, 1); + m_zeusbase[0x5a] = WAVERAM_READ32(src, 2); + + if (m_zeusbase[0x5e] & 0x40) + { + m_zeusbase[0x51]++; + m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + m_zeusbase[0x51] &= ~0xfe00; + } + } + break; + + case 0x57: + /* thegrid uses this to write either left or right halves of pixels */ + if (m_zeusbase[0x50] == 0x00e90000) + { + void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); + if (m_zeusbase[0x57] & 1) + WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]); + if (m_zeusbase[0x57] & 4) + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]); + } + + /* make sure we log anything else */ + else if (logit) + logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]); + break; + + case 0x58: + case 0x59: + case 0x5a: + /* if we're in write mode, process it */ + if (m_zeusbase[0x50] == 0x00890000) + { + /* + m_zeusbase[0x5e]: + bit 0-1: which register triggers write through + bit 3: enable write through via these registers + bit 4: seems to be set during reads, when 0x51 is used for latching + bit 5: unknown, currently used to specify ordering, but this is suspect + bit 6: enable autoincrement on write through + */ + if ((m_zeusbase[0x5e] & 0x08) && (offset & 3) == (m_zeusbase[0x5e] & 3)) + { + void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); + WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]); + if (m_zeusbase[0x5e] & 0x20) + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]); + else + { + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]); + WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]); + } + + if (m_zeusbase[0x5e] & 0x40) + { + m_zeusbase[0x51]++; + m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + m_zeusbase[0x51] &= ~0xfe00; + } + } + } + + /* make sure we log anything else */ + else if (logit) + logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]); + break; + } +} + + + +/************************************* + * + * Process the FIFO + * + *************************************/ + +void zeus2_device::zeus2_pointer_write(UINT8 which, UINT32 value) +{ +#if TRACK_REG_USAGE +subregwrite_count[which]++; +if (subregdata_count[which] < 256) +{ + reg_info **tailptr; + + for (tailptr = &subregdata[which]; *tailptr != nullptr; tailptr = &(*tailptr)->next) + if ((*tailptr)->value == value) + break; + if (*tailptr == nullptr) + { + *tailptr = alloc_or_die(reg_info); + (*tailptr)->next = nullptr; + (*tailptr)->value = value; + subregdata_count[which]++; + } +} +#endif + + switch (which) + { + case 0x04: + zeus_renderbase = waveram1_ptr_from_expanded_addr(value << 16); + break; + + case 0x05: + zeus_texbase = value % (WAVERAM0_HEIGHT * WAVERAM0_WIDTH); + break; + + case 0x40: + zeus_unknown_40 = value & 0xffffff; + zeus_quad_size = (zeus_unknown_40 == 0) ? 10 : 14; + break; + +#if 0 + case 0x0c: + case 0x0d: + // These seem to have something to do with blending. + // There are fairly unique 0x0C,0x0D pairs for various things: + // Car reflection on initial screen: 0x40, 0x00 + // Additively-blended "flares": 0xFA, 0xFF + // Car windshields (and drivers, apparently): 0x82, 0x7D + // Other minor things: 0xA4, 0x100 + break; +#endif + } +} + +/************************************* + * Process the FIFO + *************************************/ + +int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords) +{ + int dataoffs = 0; + + /* handle logging */ + switch (data[0] >> 24) + { + // 0x00: write 32-bit value to low registers + case 0x00: + // Ignore the all zeros commmand + if (((data[0] >> 16) & 0x7f) == 0x0) + return TRUE; + // Drop through to 0x05 command + /* 0x05: write 32-bit value to low registers */ + case 0x05: + if (numwords < 2) + return FALSE; + if (log_fifo) + log_fifo_command(data, numwords, " -- reg32"); + if (((data[0] >> 16) & 0x7f) != 0x08) + zeus2_register32_w((data[0] >> 16) & 0x7f, data[1], log_fifo); + break; + + /* 0x08: set matrix and point (thegrid) */ + case 0x08: + if (numwords < 14) + return FALSE; + dataoffs = 1; + + /* 0x07: set matrix and point (crusnexo) */ + case 0x07: + if (numwords < 13) + return FALSE; + + /* extract the matrix from the raw data */ + zeus_matrix[0][0] = tms3203x_device::fp_to_float(data[dataoffs + 1]); + zeus_matrix[0][1] = tms3203x_device::fp_to_float(data[dataoffs + 2]); + zeus_matrix[0][2] = tms3203x_device::fp_to_float(data[dataoffs + 3]); + zeus_matrix[1][0] = tms3203x_device::fp_to_float(data[dataoffs + 4]); + zeus_matrix[1][1] = tms3203x_device::fp_to_float(data[dataoffs + 5]); + zeus_matrix[1][2] = tms3203x_device::fp_to_float(data[dataoffs + 6]); + zeus_matrix[2][0] = tms3203x_device::fp_to_float(data[dataoffs + 7]); + zeus_matrix[2][1] = tms3203x_device::fp_to_float(data[dataoffs + 8]); + zeus_matrix[2][2] = tms3203x_device::fp_to_float(data[dataoffs + 9]); + + /* extract the translation point from the raw data */ + zeus_point[0] = tms3203x_device::fp_to_float(data[dataoffs + 10]); + zeus_point[1] = tms3203x_device::fp_to_float(data[dataoffs + 11]); + zeus_point[2] = tms3203x_device::fp_to_float(data[dataoffs + 12]); + + if (log_fifo) + { + log_fifo_command(data, numwords, "\n"); + logerror("\t\tmatrix ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f )\n\t\tvector %8.2f %8.2f %8.5f\n", + (double) zeus_matrix[0][0], (double) zeus_matrix[0][1], (double) zeus_matrix[0][2], + (double) zeus_matrix[1][0], (double) zeus_matrix[1][1], (double) zeus_matrix[1][2], + (double) zeus_matrix[2][0], (double) zeus_matrix[2][1], (double) zeus_matrix[2][2], + (double) zeus_point[0], + (double) zeus_point[1], + (double) zeus_point[2]); + } + break; + + // 0x14: ?? atlantis + /* 0x15: set point only (thegrid) */ + /* 0x16: set point only (crusnexo) */ + case 0x14: + case 0x15: + case 0x16: + if (numwords < 4) + return FALSE; + + /* extract the translation point from the raw data */ + zeus_point[0] = tms3203x_device::fp_to_float(data[1]); + zeus_point[1] = tms3203x_device::fp_to_float(data[2]); + zeus_point[2] = tms3203x_device::fp_to_float(data[3]); + + if (log_fifo) + { + log_fifo_command(data, numwords, "\n"); + logerror("\t\tvector %8.2f %8.2f %8.5f\n", + (double) zeus_point[0], + (double) zeus_point[1], + (double) zeus_point[2]); + } + break; + + /* 0x1c: */ + case 0x1c: + if (numwords < 4) + return FALSE; + if (log_fifo) + { + log_fifo_command(data, numwords, " -- unknown control + hack clear screen\n"); + logerror("\t\tvector %8.2f %8.2f %8.5f\n", + (double) tms3203x_device::fp_to_float(data[1]), + (double) tms3203x_device::fp_to_float(data[2]), + (double) tms3203x_device::fp_to_float(data[3])); + + /* extract the translation point from the raw data */ + zeus_point2[0] = tms3203x_device::fp_to_float(data[1]); + zeus_point2[1] = tms3203x_device::fp_to_float(data[2]); + zeus_point2[2] = tms3203x_device::fp_to_float(data[3]); + } + { + /* not right -- just a hack */ + if (0) { + int x, y; + for (y = zeus_cliprect.min_y; y <= zeus_cliprect.max_y; y++) + for (x = zeus_cliprect.min_x; x <= zeus_cliprect.max_x; x++) + waveram_plot_depth(y, x, 0, 0x7fff); + } + } + break; + + /* 0x23: render model in waveram (thegrid) */ + /* 0x24: render model in waveram (crusnexo) */ + // 0x17: ??? (atlantis) + case 0x17: + case 0x23: + case 0x24: + if (numwords < 2) + return FALSE; + if (log_fifo) + log_fifo_command(data, numwords, ""); + //zeus2_draw_model(data[1], data[0] & 0xffff, log_fifo); + zeus2_draw_model(data[1], data[0] & 0x3fff, log_fifo); + break; + + // 0x2d; ??? (atlantis) + case 0x2d: + if (numwords < 2) + return FALSE; + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + //zeus2_draw_model(data[1], data[0] & 0xff, log_fifo); + break; + + /* 0x31: sync pipeline? (thegrid) */ + /* 0x32: sync pipeline? (crusnexo) */ + // 0x25 ?? (atlantis) + case 0x25: + case 0x31: + case 0x32: + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + zeus_quad_size = 10; + break; + + /* 0x38: direct render quad (crusnexo) */ + // 0x38: ?? (atlantis) + case 0x38: + if (numwords < 12) + return FALSE; + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + break; + + /* 0x40: ???? */ + case 0x40: + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + break; + + default: + if (data[0] != 0x2c0) + { + printf("Unknown command %08X\n", data[0]); + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + } + break; + } + return TRUE; +} + +/************************************* + * Draw a model in waveram + *************************************/ + +void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit) +{ + UINT32 databuffer[32]; + int databufcount = 0; + int model_done = FALSE; + UINT32 texoffs = 0; + int quadsize = zeus_quad_size; + + if (logit) + logerror(" -- model @ %08X, len %04X\n", baseaddr, count); + + if (count > 0x1000) + fatalerror("Extreme count\n"); + + while (baseaddr != 0 && !model_done) + { + const void *base = waveram0_ptr_from_expanded_addr(baseaddr); + int curoffs; + + /* reset the objdata address */ + baseaddr = 0; + + /* loop until we run out of data */ + for (curoffs = 0; curoffs <= count; curoffs++) + { + int countneeded = 2; + UINT8 cmd; + + /* accumulate 2 words of data */ + databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 0); + databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 1); + + /* if this is enough, process the command */ + cmd = databuffer[0] >> 24; + if (cmd == 0x38) + countneeded = quadsize; + if (databufcount == countneeded) + { + /* handle logging of the command */ + if (logit) + { + int offs; + logerror("\t"); + for (offs = 0; offs < databufcount; offs++) + logerror("%08X ", databuffer[offs]); + logerror("-- "); + } + + /* handle the command */ + switch (cmd) + { + case 0x21: /* thegrid */ + case 0x22: /* crusnexo */ + if (((databuffer[0] >> 16) & 0xff) == 0x9b) + { + texoffs = databuffer[1]; + if (logit) + logerror("texture offset\n"); + } + else if (logit) + logerror("unknown offset\n"); + break; + + case 0x31: /* thegrid */ + if (logit) + logerror("sync?\n"); + break; + + case 0x35: /* thegrid */ + case 0x36: /* crusnexo */ + if (logit) + logerror("reg32"); + zeus2_register32_w((databuffer[0] >> 16) & 0x7f, databuffer[1], logit); + break; + + case 0x38: /* crusnexo/thegrid */ + poly->zeus2_draw_quad(databuffer, texoffs, logit); + break; + + default: + if (quadsize == 10) + { + logerror("Correcting quad size\n"); + quadsize = 14; + } + if (logit) + logerror("unknown model data\n"); + break; + } + + /* reset the count */ + databufcount = 0; + } + } + } +} + +/************************************* + * Draw a quad + *************************************/ +void zeus2_renderer::zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit) +{ + z2_poly_vertex clipvert[8]; + z2_poly_vertex vert[4]; + // float uscale, vscale; + float maxy, maxx; + // int val1, val2, texwshift; + int numverts; + int i; + // INT16 normal[3]; + // INT32 rotnormal[3]; + int texmode = texoffs & 0xffff; + + if (logit) + m_state->logerror("quad\n"); + + if (machine().input().code_pressed(KEYCODE_Q) && (texoffs & 0xffff) == 0x119) return; + if (machine().input().code_pressed(KEYCODE_E) && (texoffs & 0xffff) == 0x01d) return; + if (machine().input().code_pressed(KEYCODE_R) && (texoffs & 0xffff) == 0x11d) return; + if (machine().input().code_pressed(KEYCODE_T) && (texoffs & 0xffff) == 0x05d) return; + if (machine().input().code_pressed(KEYCODE_Y) && (texoffs & 0xffff) == 0x0dd) return; + //if (machine().input().code_pressed(KEYCODE_U) && (texoffs & 0xffff) == 0x119) return; + //if (machine().input().code_pressed(KEYCODE_I) && (texoffs & 0xffff) == 0x119) return; + //if (machine().input().code_pressed(KEYCODE_O) && (texoffs & 0xffff) == 0x119) return; + //if (machine().input().code_pressed(KEYCODE_L) && (texoffs & 0x100)) return; + + /* + 0 38800000 + 1 x2 | x1 + 2 v1 | u1 + 3 y2 | y1 + 4 v2 | u2 + 5 z2 | z1 + 6 v3 | u3 + 7 v4 | u4 + 8 ??? + 9 x4 | x3 + 10 y4 | y3 + 11 z4 | z3 + + In memory: + +0 = ??? + +1 = set via $05410000/value + +2 = x1 + +3 = y1 + +4 = z1 + +5 = x2 + +6 = y2 + +7 = z2 + +8 = x3 + +9 = y3 + +10= z3 + +11= x4 + +12= y4 + +13= z4 + +14= uv1 + +15= uv2 + +16= uv3 + +17= uv4 + +18= set via $05200000/$05000000 | (value << 10) (uvoffset?) + +19= ??? + + + 38810000 00000000 00C7|FF38 FF5E|FF5E 15400154 11400114 00000000 00000000 FF38|00C7 00A3|00A3 -- quad + xxxx|xxxx yyyy|yyyy xxxx|xxxx yyyy|yyyy + */ + + /* extract raw x,y,z */ + vert[0].x = (INT16)databuffer[2]; + vert[0].y = (INT16)databuffer[3]; + vert[0].p[0] = (INT16)databuffer[6]; + vert[0].p[1] = (databuffer[1] >> 2) & 0xff; + vert[0].p[2] = (databuffer[1] >> 18) & 0xff; + + vert[1].x = (INT16)(databuffer[2] >> 16); + vert[1].y = (INT16)(databuffer[3] >> 16); + vert[1].p[0] = (INT16)(databuffer[6] >> 16); + vert[1].p[1] = (databuffer[4] >> 2) & 0xff; + vert[1].p[2] = (databuffer[4] >> 12) & 0xff; + + vert[2].x = (INT16)databuffer[8]; + vert[2].y = (INT16)databuffer[9]; + vert[2].p[0] = (INT16)databuffer[7]; + vert[2].p[1] = (databuffer[4] >> 22) & 0xff; + vert[2].p[2] = (databuffer[5] >> 2) & 0xff; + + vert[3].x = (INT16)(databuffer[8] >> 16); + vert[3].y = (INT16)(databuffer[9] >> 16); + vert[3].p[0] = (INT16)(databuffer[7] >> 16); + vert[3].p[1] = (databuffer[5] >> 12) & 0xff; + vert[3].p[2] = (databuffer[5] >> 22) & 0xff; + + /* + vert[0].x = (INT16)databuffer[1]; + vert[0].y = (INT16)databuffer[3]; + vert[0].p[0] = (INT16)databuffer[5]; + vert[0].p[1] = (UINT16)databuffer[2]; + vert[0].p[2] = (UINT16)(databuffer[2] >> 16); + + vert[1].x = (INT16)(databuffer[1] >> 16); + vert[1].y = (INT16)(databuffer[3] >> 16); + vert[1].p[0] = (INT16)(databuffer[5] >> 16); + vert[1].p[1] = (UINT16)databuffer[4]; + vert[1].p[2] = (UINT16)(databuffer[4] >> 16); + + vert[2].x = (INT16)databuffer[9]; + vert[2].y = (INT16)databuffer[10]; + vert[2].p[0] = (INT16)databuffer[11]; + vert[2].p[1] = (UINT16)databuffer[6]; + vert[2].p[2] = (UINT16)(databuffer[6] >> 16); + + vert[3].x = (INT16)(databuffer[9] >> 16); + vert[3].y = (INT16)(databuffer[10] >> 16); + vert[3].p[0] = (INT16)(databuffer[11] >> 16); + vert[3].p[1] = (UINT16)databuffer[7]; + vert[3].p[2] = (UINT16)(databuffer[7] >> 16); + */ + for (i = 0; i < 4; i++) + { + float x = vert[i].x; + float y = vert[i].y; + float z = vert[i].p[0]; + + vert[i].x = x * m_state->zeus_matrix[0][0] + y * m_state->zeus_matrix[0][1] + z * m_state->zeus_matrix[0][2] + m_state->zeus_point[0]; + vert[i].y = x * m_state->zeus_matrix[1][0] + y * m_state->zeus_matrix[1][1] + z * m_state->zeus_matrix[1][2] + m_state->zeus_point[1]; + vert[i].p[0] = x * m_state->zeus_matrix[2][0] + y * m_state->zeus_matrix[2][1] + z * m_state->zeus_matrix[2][2] + m_state->zeus_point[2]; + vert[i].p[0] += m_state->zbase; + vert[i].p[2] += texoffs >> 16; + vert[i].p[1] *= 256.0f; + vert[i].p[2] *= 256.0f; + + if (logit) + { + m_state->logerror("\t\t(%f,%f,%f) (%02X,%02X)\n", + (double)vert[i].x, (double)vert[i].y, (double)vert[i].p[0], + (int)(vert[i].p[1] / 256.0f), (int)(vert[i].p[2] / 256.0f)); + } + } + + numverts = this->zclip_if_less(4, &vert[0], &clipvert[0], 4, 1.0f / 512.0f / 4.0f); + if (numverts < 3) + return; + + maxx = maxy = -1000.0f; + for (i = 0; i < numverts; i++) + { + // 412.0f here works for crusnexo + float ooz = 512.0f / clipvert[i].p[0]; + + // ooz *= 1.0f / (512.0f * 512.0f); + + clipvert[i].x *= ooz; + clipvert[i].y *= ooz; + clipvert[i].x += 256.5f; + clipvert[i].y += 200.5f; + clipvert[i].p[0] *= 65536.0f * 16.0f; + + maxx = MAX(maxx, clipvert[i].x); + maxy = MAX(maxy, clipvert[i].y); + if (logit) + m_state->logerror("\t\t\tTranslated=(%f,%f)\n", (double)clipvert[i].x, (double)clipvert[i].y); + } + for (i = 0; i < numverts; i++) + { + if (clipvert[i].x == maxx) + clipvert[i].x += 0.0005f; + if (clipvert[i].y == maxy) + clipvert[i].y += 0.0005f; + } + + zeus2_poly_extra_data& extra = this->object_data_alloc(); + switch (texmode) + { + case 0x01d: /* crusnexo: RHS of score bar */ + case 0x05d: /* crusnexo: background, road */ + case 0x0dd: /* crusnexo: license plate letters */ + case 0x11d: /* crusnexo: LHS of score bar */ + case 0x15d: /* crusnexo */ + case 0x85d: /* crusnexo */ + case 0x95d: /* crusnexo */ + case 0xc1d: /* crusnexo */ + case 0xc5d: /* crusnexo */ + extra.texwidth = 256; + break; + + case 0x059: /* crusnexo */ + case 0x0d9: /* crusnexo */ + case 0x119: /* crusnexo: license plates */ + case 0x159: /* crusnexo */ + extra.texwidth = 128; + break; + + case 0x055: /* crusnexo */ + case 0x155: /* crusnexo */ + extra.texwidth = 64; + break; + + case 0x000: // thegrid guess + case 0x120: // thegrid guess + extra.texwidth = 32; + break; + + default: + { + static UINT8 hits[0x10000]; + if (!hits[(texoffs & 0xffff)]) + { + hits[(texoffs & 0xffff)] = 1; + printf("format = %04X\n", (texoffs & 0xffff)); + } + break; + } + } + + extra.solidcolor = 0;//m_zeusbase[0x00] & 0x7fff; + extra.zoffset = 0;//m_zeusbase[0x7e] >> 16; + extra.alpha = 0;//m_zeusbase[0x4e]; + extra.transcolor = 0x100;//((databuffer[1] >> 16) & 1) ? 0 : 0x100; + extra.texbase = WAVERAM_BLOCK0_EXT(m_state->zeus_texbase); + extra.palbase = m_state->waveram0_ptr_from_expanded_addr(m_state->m_zeusbase[0x41]); + + // Note: Before being converted to the "poly.h" interface, this used to call the polylgcy function + // poly_render_quad_fan. The behavior seems to be the same as it once was after a few short + // tests, but the (numverts == 5) statement below may actually be a quad fan instead of a 5-sided + // polygon. + if (numverts == 3) + render_triangle(m_state->zeus_cliprect, render_delegate(FUNC(zeus2_renderer::render_poly_8bit), this), 4, clipvert[0], clipvert[1], clipvert[2]); + else if (numverts == 4) + render_polygon<4>(m_state->zeus_cliprect, render_delegate(FUNC(zeus2_renderer::render_poly_8bit), this), 4, clipvert); + else if (numverts == 5) + render_polygon<5>(m_state->zeus_cliprect, render_delegate(FUNC(zeus2_renderer::render_poly_8bit), this), 4, clipvert); +} + + + +/************************************* +* Rasterizers +*************************************/ + +void zeus2_renderer::render_poly_8bit(INT32 scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid) +{ + INT32 curz = extent.param[0].start; + INT32 curu = extent.param[1].start; + INT32 curv = extent.param[2].start; + // INT32 curi = extent.param[3].start; + INT32 dzdx = extent.param[0].dpdx; + INT32 dudx = extent.param[1].dpdx; + INT32 dvdx = extent.param[2].dpdx; + // INT32 didx = extent.param[3].dpdx; + const void *texbase = object.texbase; + const void *palbase = object.palbase; + UINT16 transcolor = object.transcolor; + int texwidth = object.texwidth; + int x; + + for (x = extent.startx; x < extent.stopx; x++) + { + UINT16 *depthptr = WAVERAM_PTRDEPTH(m_state->zeus_renderbase, scanline, x); + INT32 depth = (curz >> 16) + object.zoffset; + //if (depth > 0x7fff) depth = 0x7fff; + if (depth > 0xffff) depth = 0xffff; + if (depth >= 0 && depth <= *depthptr) + { + int u0 = (curu >> 8);// & (texwidth - 1); + int v0 = (curv >> 8);// & 255; + int u1 = (u0 + 1); + int v1 = (v0 + 1); + UINT8 texel0 = m_state->get_texel_8bit(texbase, v0, u0, texwidth); + UINT8 texel1 = m_state->get_texel_8bit(texbase, v0, u1, texwidth); + UINT8 texel2 = m_state->get_texel_8bit(texbase, v1, u0, texwidth); + UINT8 texel3 = m_state->get_texel_8bit(texbase, v1, u1, texwidth); + if (texel0 != transcolor) + { + UINT32 color0 = WAVERAM_READ16(palbase, texel0); + UINT32 color1 = WAVERAM_READ16(palbase, texel1); + UINT32 color2 = WAVERAM_READ16(palbase, texel2); + UINT32 color3 = WAVERAM_READ16(palbase, texel3); + color0 = ((color0 & 0x7c00) << 9) | ((color0 & 0x3e0) << 6) | ((color0 & 0x1f) << 3); + color1 = ((color1 & 0x7c00) << 9) | ((color1 & 0x3e0) << 6) | ((color1 & 0x1f) << 3); + color2 = ((color2 & 0x7c00) << 9) | ((color2 & 0x3e0) << 6) | ((color2 & 0x1f) << 3); + color3 = ((color3 & 0x7c00) << 9) | ((color3 & 0x3e0) << 6) | ((color3 & 0x1f) << 3); + rgb_t filtered = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv); + WAVERAM_WRITEPIX(m_state->zeus_renderbase, scanline, x, filtered); + *depthptr = depth; + } + } + + curz += dzdx; + curu += dudx; + curv += dvdx; + // curi += didx; + } +} + +/************************************* + * Debugging tools + *************************************/ + +void zeus2_device::log_fifo_command(const UINT32 *data, int numwords, const char *suffix) +{ + int wordnum; + std::string errorStr; + logerror("Zeus cmd %02X :", data[0] >> 24); + for (wordnum = 0; wordnum < numwords; wordnum++) + logerror(" %08X", data[wordnum]); + logerror("%s", suffix); +} diff --git a/src/devices/video/zeus2.h b/src/devices/video/zeus2.h new file mode 100644 index 00000000000..cc147654e71 --- /dev/null +++ b/src/devices/video/zeus2.h @@ -0,0 +1,286 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/************************************************************************* + + Midway Zeus2 Video + +**************************************************************************/ +#ifndef __ZEUS2_H__ +#define __ZEUS2_H__ + +#include "emu.h" +#include "video/poly.h" +#include "video/rgbutil.h" +#include "cpu/tms32031/tms32031.h" + +#pragma once + +/************************************* +* Constants +*************************************/ +#define ZEUS2_VIDEO_CLOCK XTAL_66_6667MHz + +#define DUMP_WAVE_RAM 0 +#define TRACK_REG_USAGE 0 + +#define WAVERAM0_WIDTH 1024 +#define WAVERAM0_HEIGHT 2048 + +#define WAVERAM1_WIDTH 512 +#define WAVERAM1_HEIGHT 1024 + +/************************************* +* Type definitions +*************************************/ + +struct zeus2_poly_extra_data +{ + const void * palbase; + const void * texbase; + UINT16 solidcolor; + INT16 zoffset; + UINT16 transcolor; + UINT16 texwidth; + UINT16 color; + UINT32 alpha; +}; + +/************************************* +* Macros +*************************************/ + +#define WAVERAM_BLOCK0(blocknum) ((void *)((UINT8 *)waveram[0] + 8 * (blocknum))) +#define WAVERAM_BLOCK1(blocknum) ((void *)((UINT8 *)waveram[1] + 12 * (blocknum))) +#define WAVERAM_BLOCK0_EXT(blocknum) ((void *)((UINT8 *)m_state->waveram[0] + 8 * (blocknum))) +#define WAVERAM_BLOCK1_EXT(blocknum) ((void *)((UINT8 *)m_state->waveram[1] + 12 * (blocknum))) + +#define WAVERAM_PTR8(base, bytenum) ((UINT8 *)(base) + BYTE4_XOR_LE(bytenum)) +#define WAVERAM_READ8(base, bytenum) (*WAVERAM_PTR8(base, bytenum)) +#define WAVERAM_WRITE8(base, bytenum, data) do { *WAVERAM_PTR8(base, bytenum) = (data); } while (0) + +#define WAVERAM_PTR16(base, wordnum) ((UINT16 *)(base) + BYTE_XOR_LE(wordnum)) +#define WAVERAM_READ16(base, wordnum) (*WAVERAM_PTR16(base, wordnum)) +#define WAVERAM_WRITE16(base, wordnum, data) do { *WAVERAM_PTR16(base, wordnum) = (data); } while (0) + +#define WAVERAM_PTR32(base, dwordnum) ((UINT32 *)(base) + (dwordnum)) +#define WAVERAM_READ32(base, dwordnum) (*WAVERAM_PTR32(base, dwordnum)) +#define WAVERAM_WRITE32(base, dwordnum, data) do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0) + +#define PIXYX_TO_DWORDNUM(y, x) (((((y) & 0x1ff) << 8) | (((x) & 0x1fe) >> 1)) * 3 + ((x) & 1)) +#define DEPTHYX_TO_DWORDNUM(y, x) (PIXYX_TO_DWORDNUM(y, (x) & ~1) + 2) + +#define WAVERAM_PTRPIX(base, y, x) WAVERAM_PTR32(base, PIXYX_TO_DWORDNUM(y, x)) +#define WAVERAM_READPIX(base, y, x) (*WAVERAM_PTRPIX(base, y, x)) +#define WAVERAM_WRITEPIX(base, y, x, color) do { *WAVERAM_PTRPIX(base, y, x) = (color); } while (0) + +#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_DWORDNUM(y, x) * 2 + (x & 1)) +#define WAVERAM_READDEPTH(base, y, x) (*WAVERAM_PTRDEPTH(base, y, x)) +#define WAVERAM_WRITEDEPTH(base, y, x, color) do { *WAVERAM_PTRDEPTH(base, y, x) = (color); } while (0) + +/************************************* +* Polygon renderer +*************************************/ +class zeus2_device; + +class zeus2_renderer : public poly_manager<float, zeus2_poly_extra_data, 4, 10000> +{ +public: + zeus2_renderer(zeus2_device *state); + + void render_poly_8bit(INT32 scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid); + + void zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit); + +private: + zeus2_device* m_state; +}; +typedef zeus2_renderer::vertex_t z2_poly_vertex; +typedef zeus2_renderer::extent_t z2_poly_extent; + +/************************************* +* Zeus2 Video Device +*************************************/ +#define MCFG_ZEUS2_VBLANK_CB(_devcb) \ + devcb = &zeus2_device::set_vblank_callback(*device, DEVCB_##_devcb); + +#define MCFG_ZEUS2_IRQ_CB(_devcb) \ + devcb = &zeus2_device::set_irq_callback(*device, DEVCB_##_devcb); + +class zeus2_device : public device_t +{ +public: + zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + screen_device *m_screen; /* the screen we are acting on */ + + UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + DECLARE_READ32_MEMBER( zeus2_r ); + DECLARE_WRITE32_MEMBER( zeus2_w ); + TIMER_CALLBACK_MEMBER(display_irq_off); + TIMER_CALLBACK_MEMBER(display_irq); + + template<class _Object> static devcb_base &set_vblank_callback(device_t &device, _Object object) { return downcast<zeus2_device &>(device).m_vblank.set_callback(object); } + template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<zeus2_device &>(device).m_irq.set_callback(object); } + devcb_write_line m_vblank; + devcb_write_line m_irq; + + UINT32 m_zeusbase[0x80]; + + zeus2_renderer* poly; + + void *zeus_renderbase; + rectangle zeus_cliprect; + + float zeus_matrix[3][3]; + float zeus_point[3]; + float zeus_point2[3]; + UINT32 zeus_texbase; + UINT32 zeus_unknown_40; + int zeus_quad_size; + + UINT32 *waveram[2]; + emu_timer *int_timer; + emu_timer *vblank_timer; + int m_yScale; + int yoffs; + int texel_width; + float zbase; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_stop() override; + +private: + TIMER_CALLBACK_MEMBER(int_timer_callback); + void zeus2_register32_w(offs_t offset, UINT32 data, int logit); + void zeus2_register_update(offs_t offset, UINT32 oldval, int logit); + int zeus2_fifo_process(const UINT32 *data, int numwords); + void zeus2_pointer_write(UINT8 which, UINT32 value); + void zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit); + void log_fifo_command(const UINT32 *data, int numwords, const char *suffix); + + /************************************* + * Member variables + *************************************/ + + + UINT8 log_fifo; + + UINT32 zeus_fifo[20]; + UINT8 zeus_fifo_words; + + UINT32 m_fill_color; + UINT16 m_fill_depth; + +#if TRACK_REG_USAGE + struct reg_info + { + struct reg_info *next; + UINT32 value; + }; + + reg_info *regdata[0x80]; + int regdata_count[0x80]; + int regread_count[0x80]; + int regwrite_count[0x80]; + reg_info *subregdata[0x100]; + int subregdata_count[0x80]; + int subregwrite_count[0x100]; +#endif +public: + /************************************* + * Inlines for block addressing + *************************************/ + + inline void *waveram0_ptr_from_expanded_addr(UINT32 addr) + { + UINT32 blocknum = (addr % WAVERAM0_WIDTH) + ((addr >> 16) % WAVERAM0_HEIGHT) * WAVERAM0_WIDTH; + return WAVERAM_BLOCK0(blocknum); + } + + inline void *waveram1_ptr_from_expanded_addr(UINT32 addr) + { + UINT32 blocknum = (addr % WAVERAM1_WIDTH) + ((addr >> 16) % WAVERAM1_HEIGHT) * WAVERAM1_WIDTH; + return WAVERAM_BLOCK1(blocknum); + } + +#ifdef UNUSED_FUNCTION + inline void *waveram0_ptr_from_texture_addr(UINT32 addr, int width) + { + UINT32 blocknum = ((addr & ~1) * width) / 8; + return WAVERAM_BLOCK0(blocknum); + } +#endif + + /************************************* + * Inlines for rendering + *************************************/ + +#ifdef UNUSED_FUNCTION + inline void WAVERAM_plot(int y, int x, UINT32 color) + { + if (zeus_cliprect.contains(x, y)) + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + } +#endif + + inline void waveram_plot_depth(int y, int x, UINT32 color, UINT16 depth) + { + if (zeus_cliprect.contains(x, y)) + { + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth); + } + } + +#ifdef UNUSED_FUNCTION + inline void waveram_plot_check_depth(int y, int x, UINT32 color, UINT16 depth) + { + if (zeus_cliprect.contains(x, y)) + { + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x); + if (depth <= *depthptr) + { + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + *depthptr = depth; + } + } + } +#endif + +#ifdef UNUSED_FUNCTION + inline void waveram_plot_check_depth_nowrite(int y, int x, UINT32 color, UINT16 depth) + { + if (zeus_cliprect.contains(x, y)) + { + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x); + if (depth <= *depthptr) + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + } + } +#endif + /************************************* + * Inlines for texel accesses + *************************************/ + inline UINT8 get_texel_8bit(const void *base, int y, int x, int width) + { + UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 4) << 3) + ((y & 1) << 2) + (x & 3); + return WAVERAM_READ8(base, byteoffs); + } + +#ifdef UNUSED_FUNCTION + inline UINT8 get_texel_4bit(const void *base, int y, int x, int width) + { + UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 8) << 3) + ((y & 1) << 2) + ((x / 2) & 3); + return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f; + } +#endif + +}; + +// device type definition +extern const device_type ZEUS2; + +#endif diff --git a/src/mame/audio/dcs.cpp b/src/mame/audio/dcs.cpp index 75972ebf0cf..009722f77bb 100644 --- a/src/mame/audio/dcs.cpp +++ b/src/mame/audio/dcs.cpp @@ -557,6 +557,7 @@ MACHINE_CONFIG_FRAGMENT( dcs2_audio_denver ) MCFG_CPU_ADD("denver", ADSP2181, XTAL_33_333MHz) MCFG_ADSP21XX_SPORT_TX_CB(WRITE32(dcs_audio_device, sound_tx_callback)) /* callback for serial transmit */ MCFG_ADSP21XX_TIMER_FIRED_CB(WRITELINE(dcs_audio_device,timer_enable_callback)) /* callback for timer fired */ + MCFG_ADSP21XX_DMOVLAY_CB(WRITE32(dcs_audio_device, dmovlay_callback)) // callback for adsp 2181 dmovlay instruction MCFG_CPU_PROGRAM_MAP(denver_program_map) MCFG_CPU_DATA_MAP(denver_data_map) MCFG_CPU_IO_MAP(denver_io_map) @@ -688,6 +689,8 @@ TIMER_CALLBACK_MEMBER( dcs_audio_device::dcs_reset ) /* rev 4: reset the Denver ASIC */ case 4: + m_dmovlay_val = 0; + dmovlay_remap_memory(); denver_reset(); break; } @@ -752,6 +755,7 @@ void dcs_audio_device::dcs_register_state() save_item(NAME(m_control_regs)); save_item(NAME(m_sounddata_bank)); + save_item(NAME(m_dmovlay_val)); save_item(NAME(m_auto_ack)); save_item(NAME(m_latch_control)); @@ -786,6 +790,9 @@ void dcs_audio_device::dcs_register_state() if (m_rev == 2) machine().save().register_postload(save_prepost_delegate(FUNC(dcs_audio_device::sdrc_remap_memory), this)); + + if (m_rev == 4) + machine().save().register_postload(save_prepost_delegate(FUNC(dcs_audio_device::dmovlay_remap_memory), this)); } @@ -958,8 +965,12 @@ void dcs2_audio_device::device_start() /* supports both RAM and ROM variants */ if (m_dram_in_mb != 0) { - m_sounddata = auto_alloc_array(machine(), UINT16, m_dram_in_mb << (20-1)); - save_pointer(NAME(m_sounddata), m_dram_in_mb << (20-1)); + UINT32 ramSize = m_dram_in_mb << (20 - 1); + // Add one extra bank for internal ram in ADSP 2181 + if (m_rev == 4) + ramSize += soundbank_words; + m_sounddata = auto_alloc_array(machine(), UINT16, ramSize); + save_pointer(NAME(m_sounddata), ramSize); m_sounddata_words = (m_dram_in_mb << 20) / 2; } else @@ -973,6 +984,7 @@ void dcs2_audio_device::device_start() m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, soundbank_words*2); } + /* allocate memory for the SRAM */ m_sram = auto_alloc_array(machine(), UINT16, 0x8000*4/2); @@ -1330,7 +1342,7 @@ WRITE16_MEMBER( dcs_audio_device::dsio_w ) /* offset 2 controls RAM pages */ case 2: dsio.reg[2] = data; - m_data_bank->set_entry(DSIO_DM_PG % m_sounddata_banks); + dmovlay_remap_memory(); break; } } @@ -1388,7 +1400,7 @@ WRITE16_MEMBER( dcs_audio_device::denver_w ) m_dmadac[chan] = subdevice<dmadac_sound_device>(buffer); } dmadac_enable(&m_dmadac[0], m_channels, enable); - if (m_channels < 6) + if (m_channels <= 6) dmadac_enable(&m_dmadac[m_channels], 6 - m_channels, FALSE); recompute_sample_rate(); } @@ -1399,7 +1411,6 @@ WRITE16_MEMBER( dcs_audio_device::denver_w ) dsio.reg[2] = data; m_data_bank->set_entry(DENV_DM_PG % m_sounddata_banks); break; - /* offset 3 controls FIFO reset */ case 3: if (!m_fifo_reset_w.isnull()) @@ -1460,6 +1471,32 @@ READ32_MEMBER( dcs_audio_device::dsio_idma_data_r ) return result; } +void dcs_audio_device::dmovlay_remap_memory() +{ + // Switch banks + // Internal ram is bank 0 + int bankSel; + if (m_dmovlay_val == 0) { + bankSel = 0; + m_data_bank->set_entry(bankSel); + } else { + bankSel = 1 + (DSIO_DM_PG % m_sounddata_banks); + m_data_bank->set_entry(bankSel); + } + if (LOG_DCS_IO) + logerror("%s dmovlay_remap_memory: Switching data ram location bankSel = %i\n", machine().describe_context(), bankSel); +} + +WRITE32_MEMBER(dcs_audio_device::dmovlay_callback) +{ + // Do some checking first + if (data < 0 || data > 1) { + logerror("dmovlay_callback: Error! dmovlay called with value = %X\n", data); + } else { + m_dmovlay_val = data; + dmovlay_remap_memory(); + } +} /*************************************************************************** @@ -1872,10 +1909,10 @@ WRITE16_MEMBER(dcs_audio_device:: adsp_control_w ) switch (offset) { case SYSCONTROL_REG: - /* bit 9 forces a reset */ - if (data & 0x0200) + /* bit 9 forces a reset (not on 2181) */ + if ((data & 0x0200) && !(m_rev == 3 || m_rev == 4)) { - logerror("%04X:Rebooting DCS due to SYSCONTROL write\n", space.device().safe_pc()); + logerror("%04X:Rebooting DCS due to SYSCONTROL write = %04X\n", space.device().safe_pc(), data); m_cpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE); dcs_boot(); m_control_regs[SYSCONTROL_REG] = 0; @@ -1950,9 +1987,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq ) { int count = m_size / (2*(m_incs ? m_incs : 1)); // sf2049se was having overflow issues with fixed size of 0x400 buffer (m_size==0xb40, count=0x5a0). - //INT16 buffer[0x400]; - std::unique_ptr<INT16[]> buffer; - buffer = std::make_unique<INT16[]>(count); + INT16 buffer[0x800]; int i; for (i = 0; i < count; i++) @@ -1962,7 +1997,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq ) } if (m_channels) - dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer.get()); + dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer); } /* check for wrapping */ diff --git a/src/mame/audio/dcs.h b/src/mame/audio/dcs.h index 3d30e946604..5b84b994126 100644 --- a/src/mame/audio/dcs.h +++ b/src/mame/audio/dcs.h @@ -47,6 +47,8 @@ public: DECLARE_WRITE32_MEMBER( dsio_idma_addr_w ); DECLARE_WRITE32_MEMBER( dsio_idma_data_w ); DECLARE_READ32_MEMBER( dsio_idma_data_r ); + void dmovlay_remap_memory(); + WRITE32_MEMBER(dmovlay_callback); // non public void dcs_boot(); @@ -202,6 +204,8 @@ protected: UINT32 *m_internal_program_ram; UINT32 *m_external_program_ram; + int m_dmovlay_val; + sdrc_state m_sdrc; dsio_state m_dsio; hle_transfer_state m_transfer; diff --git a/src/mame/drivers/atlantis.cpp b/src/mame/drivers/atlantis.cpp index 65102eee960..802704b8e43 100644 --- a/src/mame/drivers/atlantis.cpp +++ b/src/mame/drivers/atlantis.cpp @@ -43,8 +43,7 @@ #include "machine/vrc4373.h" #include "machine/pci9050.h" #include "machine/pci-ide.h" -#include "includes/midzeus.h" -#include "includes/midzeus2.h" +#include "video/zeus2.h" #include "machine/nvram.h" #include "coreutil.h" @@ -62,19 +61,22 @@ // These need more verification #define IOASIC_IRQ_SHIFT 0 +#define GALILEO_IRQ_SHIFT 1 +#define ZEUS_IRQ_SHIFT 2 #define PARALLEL_IRQ_SHIFT 3 #define UART0_SHIFT 4 #define UART1_SHIFT 5 -#define ZEUS_IRQ_SHIFT 2 #define VBLANK_IRQ_SHIFT 7 -#define GALILEO_IRQ_SHIFT 0 /* static interrupts */ #define GALILEO_IRQ_NUM MIPS3_IRQ0 +#define VBLANK_IRQ_NUM MIPS3_IRQ3 #define IDE_IRQ_NUM MIPS3_IRQ4 -#define LOG_RTC (1) -#define LOG_ZEUS (0) +#define LOG_RTC (0) +#define LOG_RED (0) +#define LOG_PORT (0) +#define LOG_IRQ (0) class atlantis_state : public driver_device { @@ -83,6 +85,8 @@ public: : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_zeus(*this, "zeus2"), m_dcs(*this, "dcs"), m_ioasic(*this, "ioasic"), m_uart0(*this, "uart0"), @@ -95,14 +99,14 @@ public: UINT32 screen_update_mwskins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); required_device<mips3_device> m_maincpu; required_device<screen_device> m_screen; - //required_device<dcs2_audio_dsio_device> m_dcs; - //required_device<dcs2_audio_denver_device> m_dcs; + optional_device<palette_device> m_palette; + required_device<zeus2_device> m_zeus; required_device<dcs_audio_device> m_dcs; required_device<midway_ioasic_device> m_ioasic; required_device<ns16550_device> m_uart0; required_device<ns16550_device> m_uart1; required_device<nvram_device> m_rtc; - UINT8 m_rtc_data[0x800]; + UINT8 m_rtc_data[0x8000]; UINT32 m_last_offset; READ8_MEMBER(cmos_r); @@ -110,6 +114,7 @@ public: DECLARE_WRITE32_MEMBER(cmos_protect_w); DECLARE_READ32_MEMBER(cmos_protect_r); UINT32 m_cmos_write_enabled; + UINT32 m_serial_count; DECLARE_READ32_MEMBER(status_leds_r); DECLARE_WRITE32_MEMBER(status_leds_w); @@ -118,15 +123,6 @@ public: DECLARE_WRITE32_MEMBER(asic_fifo_w); DECLARE_WRITE32_MEMBER(dcs3_fifo_full_w); - DECLARE_WRITE32_MEMBER(zeus_w); - DECLARE_READ32_MEMBER(zeus_r); - UINT32 m_zeus_data[0x80]; - - READ8_MEMBER (red_r); - WRITE8_MEMBER(red_w); - UINT8 m_red_data[0x1000]; - int m_red_count; - READ32_MEMBER (green_r); WRITE32_MEMBER(green_w); READ8_MEMBER (blue_r); @@ -142,6 +138,8 @@ public: UINT8 board_ctrl[CTRL_SIZE]; void update_asic_irq(); + DECLARE_WRITE_LINE_MEMBER(vblank_irq); + DECLARE_WRITE_LINE_MEMBER(zeus_irq); DECLARE_WRITE_LINE_MEMBER(ide_irq); DECLARE_WRITE_LINE_MEMBER(ioasic_irq); @@ -154,37 +152,6 @@ public: UINT32 m_port_ctrl_reg[0x8]; }; -READ8_MEMBER (atlantis_state::red_r) -{ - UINT8 data = m_red_data[offset]; - logerror("%06X: red_r %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data); - m_last_offset = offset | 0x10000; - return data; -} - -WRITE8_MEMBER(atlantis_state::red_w) -{ - COMBINE_DATA(&m_red_data[offset]); - - switch (offset) { - case 0: - // User I/O 0 = Allow write to red[0]. Serial Write Enable? - if (m_user_io_state & 0x1) { - // Data written is shifted by 1 bit each time. Maybe a serial line output? - if (m_red_count == 0) - logerror("%06X: red_w start serial %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data); - m_red_count++; - if (m_red_count == 8) - m_red_count = 0; - break; - } // Fall through to default if not enabled - default: - logerror("%06X: red_w %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data); - break; - } - m_last_offset = offset | 0x10000; -} - READ32_MEMBER(atlantis_state::green_r) { // If not 0x80 cpu writes to 00e80000 = 0 @@ -222,10 +189,12 @@ READ32_MEMBER(atlantis_state::board_ctrl_r) if (1 && m_screen->vblank()) data |= 0x80; if (m_last_offset != (newOffset | 0x40000)) - logerror("%s:board_ctrl_r read from CTRL_STATUS offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); + if (LOG_IRQ) + logerror("%s:board_ctrl_r read from CTRL_STATUS offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); break; default: - logerror("%s:board_ctrl_r read from offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); + if (LOG_IRQ) + logerror("%s:board_ctrl_r read from offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); break; } m_last_offset = newOffset | 0x40000; @@ -251,66 +220,70 @@ WRITE32_MEMBER(atlantis_state::board_ctrl_w) m_dcs->reset_w(CLEAR_LINE); } } - logerror("%s:board_ctrl_w write to CTRL_POWER0 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); + if (LOG_IRQ) + logerror("%s:board_ctrl_w write to CTRL_POWER0 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); break; case CTRL_POWER1: - // 0x1 VBlank clear? + // 0x1 VBlank clear? if (changeData & 0x1) { if ((data & 0x0001) == 0) { + //UINT32 status_bit = (1 << VBLANK_IRQ_SHIFT); + UINT32 status_bit = (1 << 7); + board_ctrl[CTRL_CAUSE] &= ~status_bit; + board_ctrl[CTRL_STATUS] &= ~status_bit; + update_asic_irq(); } else { } } - logerror("%s:board_ctrl_w write to CTRL_POWER1 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); + if (LOG_IRQ) + logerror("%s:board_ctrl_w write to CTRL_POWER1 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); break; case CTRL_GLOBAL_EN: // Zero bit will clear cause board_ctrl[CTRL_CAUSE] &= data; update_asic_irq(); - logerror("%s:board_ctrl_w write to CTRL_GLOBAL_EN offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); + if (LOG_IRQ) + logerror("%s:board_ctrl_w write to CTRL_GLOBAL_EN offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); break; default: - logerror("%s:board_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); + if (LOG_IRQ) + logerror("%s:board_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); break; } } -WRITE32_MEMBER(atlantis_state::asic_fifo_w) -{ - m_ioasic->fifo_w(data); -} - READ8_MEMBER(atlantis_state::cmos_r) { UINT8 result = m_rtc_data[offset]; switch (offset) { - case 0x7F9: - case 0x7FA: - case 0x7FB: - case 0x7FC: - case 0x7FD: - case 0x7FE: - case 0x7FF: - if ((m_rtc_data[0x7F8] & 0x40)==0) { + case 0x7FF9: + case 0x7FFA: + case 0x7FFB: + case 0x7FFC: + case 0x7FFD: + case 0x7FFE: + case 0x7FFF: + if ((m_rtc_data[0x7FF8] & 0x40)==0) { system_time systime; // get the current date/time from the core machine().current_datetime(systime); - m_rtc_data[0x7F9] = dec_2_bcd(systime.local_time.second); - m_rtc_data[0x7FA] = dec_2_bcd(systime.local_time.minute); - m_rtc_data[0x7FB] = dec_2_bcd(systime.local_time.hour); - - m_rtc_data[0x7FC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7); - m_rtc_data[0x7FD] = dec_2_bcd(systime.local_time.mday); - m_rtc_data[0x7FE] = dec_2_bcd(systime.local_time.month + 1); - m_rtc_data[0x7FF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900 + m_rtc_data[0x7FF9] = dec_2_bcd(systime.local_time.second); + m_rtc_data[0x7FFA] = dec_2_bcd(systime.local_time.minute); + m_rtc_data[0x7FFB] = dec_2_bcd(systime.local_time.hour); + + m_rtc_data[0x7FFC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7); + m_rtc_data[0x7FFD] = dec_2_bcd(systime.local_time.mday); + m_rtc_data[0x7FFE] = dec_2_bcd(systime.local_time.month + 1); + m_rtc_data[0x7FFF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900 result = m_rtc_data[offset]; } break; default: if (LOG_RTC) - logerror("%s:RTC read from offset %04X = %08X m_rtc_data[0x7F8] %02X\n", machine().describe_context(), offset, result, m_rtc_data[0x7F8]); + logerror("%s:RTC read from offset %04X = %08X m_rtc_data[0x7FF8] %02X\n", machine().describe_context(), offset, result, m_rtc_data[0x7FF8]); break; } return result; @@ -319,23 +292,31 @@ READ8_MEMBER(atlantis_state::cmos_r) WRITE8_MEMBER(atlantis_state::cmos_w) { system_time systime; - - if (m_cmos_write_enabled) { + // User I/O 0 = Allow write to cmos[0]. Serial Write Enable? + if (offset == 0 && (m_user_io_state & 0x1)) { + // Data written is shifted by 1 bit each time. Maybe a serial line output? + if (LOG_RTC && m_serial_count == 0) + logerror("%06X: cmos_w[0] start serial %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data); + m_serial_count++; + if (m_serial_count == 8) + m_serial_count = 0; + } + else if (m_cmos_write_enabled) { COMBINE_DATA(&m_rtc_data[offset]); m_cmos_write_enabled = FALSE; switch (offset) { - case 0x7F8: // M48T02 time + case 0x7FF8: // M48T02 time if (data & 0x40) { // get the current date/time from the core machine().current_datetime(systime); - m_rtc_data[0x7F9] = dec_2_bcd(systime.local_time.second); - m_rtc_data[0x7FA] = dec_2_bcd(systime.local_time.minute); - m_rtc_data[0x7FB] = dec_2_bcd(systime.local_time.hour); - - m_rtc_data[0x7FC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7); - m_rtc_data[0x7FD] = dec_2_bcd(systime.local_time.mday); - m_rtc_data[0x7FE] = dec_2_bcd(systime.local_time.month + 1); - m_rtc_data[0x7FF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900 + m_rtc_data[0x7FF9] = dec_2_bcd(systime.local_time.second); + m_rtc_data[0x7FFA] = dec_2_bcd(systime.local_time.minute); + m_rtc_data[0x7FFB] = dec_2_bcd(systime.local_time.hour); + + m_rtc_data[0x7FFC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7); + m_rtc_data[0x7FFD] = dec_2_bcd(systime.local_time.mday); + m_rtc_data[0x7FFE] = dec_2_bcd(systime.local_time.month + 1); + m_rtc_data[0x7FFF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900 } if (LOG_RTC) logerror("%s:RTC write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask); @@ -396,40 +377,14 @@ WRITE32_MEMBER(atlantis_state::status_leds_w) } } -READ32_MEMBER(atlantis_state::zeus_r) -{ - UINT32 result = m_zeus_data[offset]; - switch (offset) { - case 0x1: - /* bit $000C0070 are tested in a loop until 0 */ - /* bits $00080000 is tested in a loop until 0 */ - /* bit $00000004 is tested for toggling; probably VBLANK */ - // zeus is reset if 0x80 is read - //if (m_screen->vblank()) - m_zeus_data[offset] = (m_zeus_data[offset] + 1) & 0xf; - break; - case 0x41: - // CPU resets map2, writes 0xffffffff here, and then expects this read - result &= 0x1fff03ff; - break; - } - if (LOG_ZEUS) - logerror("%s:zeus_r read from offset %04X = %08X & %08X\n", machine().describe_context(), offset, result, mem_mask); - return result; -} - -WRITE32_MEMBER(atlantis_state::zeus_w) +READ32_MEMBER(atlantis_state::cmos_protect_r) { - COMBINE_DATA(&m_zeus_data[offset]); - if (LOG_ZEUS) - logerror("%s:zeus_w write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask); - m_last_offset = offset | 0x30000; + return m_cmos_write_enabled; } - -READ32_MEMBER(atlantis_state::cmos_protect_r) +WRITE32_MEMBER(atlantis_state::asic_fifo_w) { - return m_cmos_write_enabled; + m_ioasic->fifo_w(data); } WRITE32_MEMBER(atlantis_state::dcs3_fifo_full_w) @@ -496,12 +451,48 @@ WRITE_LINE_MEMBER(atlantis_state::uart1_irq_callback) } /************************************* +* Video interrupts +*************************************/ +WRITE_LINE_MEMBER(atlantis_state::vblank_irq) +{ + //logerror("%s: atlantis_state::vblank state = %i\n", machine().describe_context(), state); + if (1) { + if (state) { + board_ctrl[CTRL_STATUS] |= (1 << VBLANK_IRQ_SHIFT); + update_asic_irq(); + } + else { + board_ctrl[CTRL_STATUS] &= ~(1 << VBLANK_IRQ_SHIFT); + board_ctrl[CTRL_CAUSE] &= ~(1 << VBLANK_IRQ_SHIFT); + update_asic_irq(); + } + } else { + m_maincpu->set_input_line(VBLANK_IRQ_NUM, state); + } +} + +WRITE_LINE_MEMBER(atlantis_state::zeus_irq) +{ + //logerror("%s: atlantis_state::zeus_irq state = %i\n", machine().describe_context(), state); + if (state) { + board_ctrl[CTRL_STATUS] |= (1 << ZEUS_IRQ_SHIFT); + update_asic_irq(); + } + else { + board_ctrl[CTRL_STATUS] &= ~(1 << ZEUS_IRQ_SHIFT); + board_ctrl[CTRL_CAUSE] &= ~(1 << ZEUS_IRQ_SHIFT); + update_asic_irq(); + } +} + +/************************************* * IDE interrupts *************************************/ WRITE_LINE_MEMBER(atlantis_state::ide_irq) { m_maincpu->set_input_line(IDE_IRQ_NUM, state); - logerror("%s: atlantis_state::ide_irq state = %i\n", machine().describe_context(), state); + if (LOG_IRQ) + logerror("%s: atlantis_state::ide_irq state = %i\n", machine().describe_context(), state); } /************************************* @@ -509,7 +500,8 @@ WRITE_LINE_MEMBER(atlantis_state::ide_irq) *************************************/ WRITE_LINE_MEMBER(atlantis_state::ioasic_irq) { - logerror("%s: atlantis_state::ioasic_irq state = %i\n", machine().describe_context(), state); + if (LOG_IRQ) + logerror("%s: atlantis_state::ioasic_irq state = %i\n", machine().describe_context(), state); if (state) { board_ctrl[CTRL_STATUS] |= (1 << IOASIC_IRQ_SHIFT); update_asic_irq(); @@ -535,13 +527,13 @@ void atlantis_state::update_asic_irq() if (irqBits && !currState) { m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, ASSERT_LINE); m_irq_state |= (1 << irqIndex); - if (1) + if (LOG_IRQ) logerror("atlantis_state::update_asic_irq Asserting IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]); } else if (!(causeBits) && currState) { m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, CLEAR_LINE); m_irq_state &= ~(1 << irqIndex); - if (1) + if (LOG_IRQ) logerror("atlantis_state::update_asic_irq Clearing IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]); } } @@ -553,7 +545,8 @@ READ32_MEMBER(atlantis_state::port_ctrl_r) { UINT32 newOffset = offset >> 17; UINT32 result = m_port_ctrl_reg[newOffset]; - logerror("%s: port_ctrl_r newOffset = %02X data = %08X\n", machine().describe_context(), newOffset, result); + if (LOG_PORT) + logerror("%s: port_ctrl_r newOffset = %02X data = %08X\n", machine().describe_context(), newOffset, result); return result; } @@ -562,22 +555,24 @@ WRITE32_MEMBER(atlantis_state::port_ctrl_w) UINT32 newOffset = offset >> 17; COMBINE_DATA(&m_port_ctrl_reg[newOffset]); - switch (newOffset) { - //case 1: - // m_port_ctrl_reg[newOffset] = 0; - // if (!(data & 0x8)) - // m_port_ctrl_reg[newOffset] = 0*3; // Row 0 - // else if (!(data & 0x10)) - // m_port_ctrl_reg[newOffset] = 1*3; // Row 1 - // else if (!(data & 0x20)) - // m_port_ctrl_reg[newOffset] = 2*3; // Row 2 - // else if (!(data & 0x40)) - // m_port_ctrl_reg[newOffset] = 3*3; // Row 3 - // logerror("%s: port_ctrl_w Keypad Row Sel = %04X data = %08X\n", machine().describe_context(), m_port_ctrl_reg[newOffset], data); - // break; - default: - logerror("%s: port_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); - break; + //switch (newOffset) { + if (newOffset == 1) { + UINT32 bits = ioport("KEYPAD")->read(); + m_port_ctrl_reg[2] = 0; + if (!(data & 0x8)) + m_port_ctrl_reg[2] = bits & 7; // Row 0 + else if (!(data & 0x10)) + m_port_ctrl_reg[2] = (bits >> 4) & 7; // Row 1 + else if (!(data & 0x20)) + m_port_ctrl_reg[2] = (bits >> 8) & 7; // Row 2 + else if (!(data & 0x40)) + m_port_ctrl_reg[2] = (bits >> 12) & 7; // Row 3 + if (LOG_PORT) + logerror("%s: port_ctrl_w Keypad Row Sel = %04X bits = %08X\n", machine().describe_context(), data, bits); + } + else { + if (LOG_PORT) + logerror("%s: port_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset); } } @@ -625,24 +620,17 @@ void atlantis_state::machine_reset() m_dcs->reset_w(0); m_user_io_state = 0; m_cmos_write_enabled = FALSE; - memset(m_zeus_data, 0, sizeof(m_zeus_data)); - m_red_count = 0; + m_serial_count = 0; m_irq_state = 0; memset(board_ctrl, 0, sizeof(board_ctrl)); memset(m_port_ctrl_reg, 0, sizeof(m_port_ctrl_reg)); } - - /************************************* - * - * Main CPU memory handlers - * + * Address Maps *************************************/ - static ADDRESS_MAP_START( map0, AS_PROGRAM, 32, atlantis_state ) - AM_RANGE(0x00000000, 0x00000fff) AM_READWRITE8(red_r, red_w, 0xff) - AM_RANGE(0x0001e000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff) + AM_RANGE(0x00000000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff) AM_RANGE(0x00100000, 0x0010001f) AM_DEVREADWRITE8("uart0", ns16550_device, ins8250_r, ins8250_w, 0xff) // Serial UART0 (TL16C552 CS0) AM_RANGE(0x00180000, 0x0018001f) AM_DEVREADWRITE8("uart1", ns16550_device, ins8250_r, ins8250_w, 0xff) // Serial UART1 (TL16C552 CS1) //AM_RANGE(0x00200000, 0x0020001f) // Parallel UART (TL16C552 CS2) @@ -666,21 +654,20 @@ static ADDRESS_MAP_START( map1, AS_PROGRAM, 32, atlantis_state ) AM_RANGE(0x00000000, 0x0000003f) AM_DEVREADWRITE("ioasic", midway_ioasic_device, read, write) // asic_fifo_w // dcs3_fifo_full_w - //AM_RANGE(0x00200000, 0x00200003) + AM_RANGE(0x00200000, 0x00200003) AM_WRITE(dcs3_fifo_full_w) AM_RANGE(0x00400000, 0x00400003) AM_DEVWRITE("dcs", dcs_audio_device, dsio_idma_addr_w) AM_RANGE(0x00600000, 0x00600003) AM_DEVREADWRITE("dcs", dcs_audio_device, dsio_idma_data_r, dsio_idma_data_w) - //AM_RANGE(0x00800000, 0x00800003) AM_WRITE(dcs3_fifo_full_w) - //AM_RANGE(0x00800000, 0x00800003) AM_WRITE(asic_fifo_w) - //AM_RANGE(0x00800000, 0x00a00003) AM_READWRITE(port_ctrl_r, port_ctrl_w) + AM_RANGE(0x00800000, 0x00900003) AM_READWRITE(port_ctrl_r, port_ctrl_w) //AM_RANGE(0x00800000, 0x00800003) // Written once = 0000fff8 //AM_RANGE(0x00880000, 0x00880003) // Initial write 0000fff0, follow by sequence ffef, ffdf, ffbf, fff7. Row Select? //AM_RANGE(0x00900000, 0x00900003) // Read once before each sequence write to 0x00880000. Code checks bits 0,1,2. Keypad? //AM_RANGE(0x00980000, 0x00980003) // Read / Write. Bytes written 0x8f, 0xcf. Code if read 0x1 then read 00a00000. POTs? //AM_RANGE(0x00a00000, 0x00a00003) - ADDRESS_MAP_END + AM_RANGE(0x00980000, 0x00980003) AM_NOP // AM_WRITE(asic_fifo_w) +ADDRESS_MAP_END static ADDRESS_MAP_START(map2, AS_PROGRAM, 32, atlantis_state) - AM_RANGE(0x00000000, 0x000001ff) AM_READWRITE(zeus_r, zeus_w) + AM_RANGE(0x00000000, 0x000001ff) AM_DEVREADWRITE("zeus2", zeus2_device, zeus2_r, zeus2_w) ADDRESS_MAP_END static ADDRESS_MAP_START( map3, AS_PROGRAM, 32, atlantis_state ) @@ -696,26 +683,26 @@ ADDRESS_MAP_END static INPUT_PORTS_START( mwskins ) PORT_START("DIPS") PORT_DIPNAME(0x0003, 0x0003, "Boot Mode") - PORT_DIPSETTING(0x0003, "Normal Boot") + PORT_DIPSETTING(0x0003, "Run Game") PORT_DIPSETTING(0x0002, "Boot EEPROM Based Self Test") PORT_DIPSETTING(0x0001, "Boot Disk Based Self Test") PORT_DIPSETTING(0x0000, "Run Factory Tests") - PORT_DIPNAME(0x0004, 0x0004, "Unknown0004") - PORT_DIPSETTING(0x0004, DEF_STR(Off)) - PORT_DIPSETTING(0x0000, DEF_STR(On)) - PORT_DIPNAME(0x0008, 0x0008, "Unknown0008") + PORT_DIPNAME(0x0004, 0x0004, "Boot Message") + PORT_DIPSETTING(0x0004, "Quiet") + PORT_DIPSETTING(0x0000, "Squawk During Boot") + PORT_DIPNAME(0x0008, 0x0008, "Reserved") PORT_DIPSETTING(0x0008, DEF_STR(Off)) PORT_DIPSETTING(0x0000, DEF_STR(On)) - PORT_DIPNAME(0x0010, 0x0010, "Unknown0010") + PORT_DIPNAME(0x0010, 0x0010, "Reserved") PORT_DIPSETTING(0x0010, DEF_STR(Off)) PORT_DIPSETTING(0x0000, DEF_STR(On)) - PORT_DIPNAME(0x0020, 0x0020, "Unknown0020") + PORT_DIPNAME(0x0020, 0x0020, "Reserved") PORT_DIPSETTING(0x0020, DEF_STR(Off)) PORT_DIPSETTING(0x0000, DEF_STR(On)) - PORT_DIPNAME(0x0040, 0x0040, "Unknown0040") + PORT_DIPNAME(0x0040, 0x0040, "Reserved") PORT_DIPSETTING(0x0040, DEF_STR(Off)) PORT_DIPSETTING(0x0000, DEF_STR(On)) - PORT_DIPNAME(0x0080, 0x0080, "Unknown0080") + PORT_DIPNAME(0x0080, 0x0080, "Reserved") PORT_DIPSETTING(0x0080, DEF_STR(Off)) PORT_DIPSETTING(0x0000, DEF_STR(On)) PORT_DIPNAME(0x0100, 0x0100, "Unknown0100") @@ -783,18 +770,18 @@ static INPUT_PORTS_START( mwskins ) PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("KEYPAD") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) /* keypad 3 */ - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) /* keypad 1 */ - PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) /* keypad 2 */ - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) /* keypad 6 */ - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) /* keypad 4 */ - PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) /* keypad 5 */ - PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) /* keypad 9 */ - PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) /* keypad 7 */ - PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) /* keypad 8 */ - PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad #") PORT_CODE(KEYCODE_PLUS_PAD) /* keypad # */ - PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad *") PORT_CODE(KEYCODE_MINUS_PAD) /* keypad * */ - PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) /* keypad 0 */ + PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) /* keypad 1 */ + PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) /* keypad 2 */ + PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) /* keypad 3 */ + PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) /* keypad 4 */ + PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) /* keypad 5 */ + PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) /* keypad 6 */ + PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) /* keypad 7 */ + PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) /* keypad 8 */ + PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) /* keypad 9 */ + PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad *") PORT_CODE(KEYCODE_MINUS_PAD) /* keypad - */ + PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) /* keypad 0 */ + PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad #") PORT_CODE(KEYCODE_PLUS_PAD) /* keypad + */ INPUT_PORTS_END @@ -830,21 +817,18 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state ) MCFG_IDE_PCI_IRQ_HANDLER(DEVWRITELINE(":", atlantis_state, ide_irq)) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(320, 240) - MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239) - MCFG_SCREEN_UPDATE_DRIVER(atlantis_state, screen_update_mwskins) - MCFG_SCREEN_PALETTE("palette") + MCFG_DEVICE_ADD("zeus2", ZEUS2, ZEUS2_VIDEO_CLOCK) + MCFG_ZEUS2_IRQ_CB(WRITELINE(atlantis_state, zeus_irq)) + MCFG_ZEUS2_VBLANK_CB(WRITELINE(atlantis_state, vblank_irq)) - MCFG_PALETTE_ADD_BBBBBGGGGGRRRRR("palette") + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_RAW_PARAMS(ZEUS2_VIDEO_CLOCK / 8, 529, 0, 400, 278, 0, 256) + MCFG_SCREEN_UPDATE_DEVICE("zeus2", zeus2_device, screen_update) /* sound hardware */ //MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DSIO, 0) MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DENVER, 0) - MCFG_DCS2_AUDIO_DRAM_IN_MB(8) + MCFG_DCS2_AUDIO_DRAM_IN_MB(4) MCFG_DCS2_AUDIO_POLLING_OFFSET(0) /* no place to hook :-( */ MCFG_DEVICE_ADD("ioasic", MIDWAY_IOASIC, 0) diff --git a/src/mame/drivers/midzeus.cpp b/src/mame/drivers/midzeus.cpp index 816dc219648..a8eb9a68f72 100644 --- a/src/mame/drivers/midzeus.cpp +++ b/src/mame/drivers/midzeus.cpp @@ -37,6 +37,7 @@ The Grid v1.2 10/18/2000 #include "machine/nvram.h" #include "crusnexo.lh" +#include "video/zeus2.h" #define CPU_CLOCK XTAL_60MHz @@ -114,6 +115,10 @@ INTERRUPT_GEN_MEMBER(midzeus_state::display_irq) machine().scheduler().timer_set(attotime::from_hz(30000000), timer_expired_delegate(FUNC(midzeus_state::display_irq_off),this)); } +WRITE_LINE_MEMBER(midzeus2_state::zeus_irq) +{ + m_maincpu->set_input_line(2, ASSERT_LINE); +} /************************************* @@ -575,7 +580,7 @@ static ADDRESS_MAP_START( zeus2_map, AS_PROGRAM, 32, midzeus2_state ) AM_RANGE(0x000000, 0x03ffff) AM_RAM AM_SHARE("ram_base") AM_RANGE(0x400000, 0x43ffff) AM_RAM AM_RANGE(0x808000, 0x80807f) AM_READWRITE(tms32031_control_r, tms32031_control_w) AM_SHARE("tms32031_ctl") - AM_RANGE(0x880000, 0x88007f) AM_READWRITE(zeus2_r, zeus2_w) AM_SHARE("zeusbase") + AM_RANGE(0x880000, 0x88007f) AM_DEVREADWRITE("zeus2", zeus2_device, zeus2_r, zeus2_w) AM_RANGE(0x8a0000, 0x8a003f) AM_READWRITE(linkram_r, linkram_w) AM_SHARE("linkram") AM_RANGE(0x8d0000, 0x8d000a) AM_READWRITE(bitlatches_r, bitlatches_w) AM_RANGE(0x900000, 0x91ffff) AM_READWRITE(zpram_r, zpram_w) AM_SHARE("nvram") AM_MIRROR(0x020000) @@ -1134,7 +1139,7 @@ static MACHINE_CONFIG_START( midzeus2, midzeus2_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", TMS32032, CPU_CLOCK) MCFG_CPU_PROGRAM_MAP(zeus2_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", midzeus2_state, display_irq) + MCFG_CPU_VBLANK_INT_DRIVER("screen", midzeus2_state, display_irq) MCFG_MACHINE_START_OVERRIDE(midzeus2_state,midzeus) MCFG_MACHINE_RESET_OVERRIDE(midzeus2_state,midzeus) @@ -1143,9 +1148,10 @@ static MACHINE_CONFIG_START( midzeus2, midzeus2_state ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_RAW_PARAMS(MIDZEUS_VIDEO_CLOCK/4, 666, 0, 512, 438, 0, 400) - MCFG_SCREEN_UPDATE_DRIVER(midzeus2_state, screen_update_midzeus2) + MCFG_SCREEN_UPDATE_DEVICE("zeus2", zeus2_device, screen_update) - MCFG_VIDEO_START_OVERRIDE(midzeus2_state,midzeus2) + MCFG_DEVICE_ADD("zeus2", ZEUS2, ZEUS2_VIDEO_CLOCK) + MCFG_ZEUS2_IRQ_CB(WRITELINE(midzeus2_state, zeus_irq)) /* sound hardware */ MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_2104, 0) diff --git a/src/mame/drivers/pc9801.cpp b/src/mame/drivers/pc9801.cpp index 6fa412a978c..846f87cb95e 100644 --- a/src/mame/drivers/pc9801.cpp +++ b/src/mame/drivers/pc9801.cpp @@ -3185,6 +3185,8 @@ static MACHINE_CONFIG_FRAGMENT( pc9801_ide ) MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(pc9801_state, ide1_irq_w)) MCFG_ATA_INTERFACE_ADD("ide2", pc9801_atapi_devices, "pc9801_cd", nullptr, false) MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(pc9801_state, ide2_irq_w)) + + MCFG_SOFTWARE_LIST_ADD("cd_list","pc98_cd") MACHINE_CONFIG_END static MACHINE_CONFIG_FRAGMENT( pc9801_common ) diff --git a/src/mame/drivers/poker72.cpp b/src/mame/drivers/poker72.cpp index 4867465e902..2d88b84b5b4 100644 --- a/src/mame/drivers/poker72.cpp +++ b/src/mame/drivers/poker72.cpp @@ -1,16 +1,22 @@ // license:BSD-3-Clause -// copyright-holders:David Haywood -/* - Unknown game, dump was marked 'slot 72 - poker' +// copyright-holders:David Haywood, Robbbert +/************************************************************************************************ + Poker Monarch GFX roms contain 'Extrema Systems International Ltd' as well as a logo for the company. - There are also 'Lucky Boy' graphics in various places, which might be the title. + There are also 'Lucky Boy' graphics in various places. + * Turn on all the dips of SW1 + * Restart game + * If it says ERROR OF RAM GAME STOP, press F2 + * When you get a blank blue screen Press Alt+2 + * This gives a setup screen. Press F2 to see cards and logo (and it beeps) + * Depending on settings of SW1, you can get other cards, or other test screens. -*/ +*************************************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" @@ -89,17 +95,15 @@ WRITE8_MEMBER(poker72_state::poker72_paletteram_w) WRITE8_MEMBER(poker72_state::output_w) { - UINT8 *ROM = memregion("maincpu")->base(); - printf("%02x\n",data); /* if((data & 0xc) == 0xc) - membank("bank1")->set_base(&ROM[0x10000]); + membank("bank1")->set_entry(2); else*/ if(data & 8) - membank("bank1")->set_base(&ROM[0x08000]); + membank("bank1")->set_entry(1); else - membank("bank1")->set_base(&ROM[0x00000]); + membank("bank1")->set_entry(0); } WRITE8_MEMBER(poker72_state::tile_bank_w) @@ -108,17 +112,17 @@ WRITE8_MEMBER(poker72_state::tile_bank_w) } static ADDRESS_MAP_START( poker72_map, AS_PROGRAM, 8, poker72_state ) - AM_RANGE(0x0000, 0xbfff) AM_ROMBANK("bank1") + AM_RANGE(0x0000, 0x7fff) AM_ROMBANK("bank1") AM_RANGE(0xc000, 0xdfff) AM_RAM //work ram AM_RANGE(0xe000, 0xefff) AM_RAM AM_SHARE("vram") AM_RANGE(0xf000, 0xfbff) AM_RAM_WRITE(poker72_paletteram_w) AM_SHARE("pal") AM_RANGE(0xfc00, 0xfdff) AM_RAM //??? - AM_RANGE(0xfe08, 0xfe08) AM_READ_PORT("IN0") + AM_RANGE(0xfe08, 0xfe08) AM_READ_PORT("SW1") AM_RANGE(0xfe09, 0xfe09) AM_READ_PORT("IN1") AM_RANGE(0xfe0a, 0xfe0a) AM_READ_PORT("IN2") - AM_RANGE(0xfe0c, 0xfe0c) AM_READ_PORT("IN3") - AM_RANGE(0xfe0d, 0xfe0d) AM_READ_PORT("IN4") - AM_RANGE(0xfe0e, 0xfe0e) AM_READ_PORT("IN5") + AM_RANGE(0xfe0c, 0xfe0c) AM_READ_PORT("SW4") + AM_RANGE(0xfe0d, 0xfe0d) AM_READ_PORT("SW5") + AM_RANGE(0xfe0e, 0xfe0e) AM_READ_PORT("SW6") AM_RANGE(0xfe17, 0xfe17) AM_READNOP //irq ack AM_RANGE(0xfe20, 0xfe20) AM_WRITE(output_w) //output, irq enable? @@ -142,8 +146,8 @@ ADDRESS_MAP_END static INPUT_PORTS_START( poker72 ) - PORT_START("IN0") - PORT_DIPNAME( 0x01, 0x00, "IN0" ) + PORT_START("SW1") + PORT_DIPNAME( 0x01, 0x00, "SW1" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) @@ -169,28 +173,28 @@ static INPUT_PORTS_START( poker72 ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) PORT_START("IN1") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("M. Bet") - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Black") + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_POKER_HOLD1 ) // Z + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_POKER_HOLD2 ) // X + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_POKER_HOLD3 ) // C + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_POKER_HOLD4 ) // V + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_POKER_HOLD5 ) // B + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("M. Bet") + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Black") PORT_START("IN2") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Red") - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_SERVICE( 0x0080, IP_ACTIVE_LOW ) - - PORT_START("IN3") - PORT_DIPNAME( 0x01, 0x00, "IN3" ) + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Red") + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_GAMBLE_D_UP ) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_GAMBLE_TAKE ) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_GAMBLE_DEAL ) // '2' + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_GAMBLE_BET ) // M + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_COIN2 ) + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_SERVICE1 ) // '9' + PORT_SERVICE( 0x0080, IP_ACTIVE_HIGH ) // F2 + + PORT_START("SW4") + PORT_DIPNAME( 0x01, 0x00, "SW4" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) @@ -214,8 +218,8 @@ static INPUT_PORTS_START( poker72 ) PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) - PORT_START("IN4") - PORT_DIPNAME( 0x01, 0x00, "IN4" ) + PORT_START("SW5") + PORT_DIPNAME( 0x01, 0x00, "SW5" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) @@ -239,8 +243,8 @@ static INPUT_PORTS_START( poker72 ) PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) - PORT_START("IN5") - PORT_DIPNAME( 0x01, 0x00, "IN5" ) + PORT_START("SW6") + PORT_DIPNAME( 0x01, 0x00, "SW6" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) @@ -266,8 +270,8 @@ static INPUT_PORTS_START( poker72 ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) - PORT_START("DSW0") - PORT_DIPNAME( 0x01, 0x00, "DSW0" ) + PORT_START("SW2") + PORT_DIPNAME( 0x01, 0x00, "SW2" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) @@ -292,8 +296,8 @@ static INPUT_PORTS_START( poker72 ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) - PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x00, "DSW1" ) + PORT_START("SW3") + PORT_DIPNAME( 0x01, 0x00, "SW3" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) @@ -354,9 +358,7 @@ PALETTE_INIT_MEMBER(poker72_state, poker72) void poker72_state::machine_reset() { - UINT8 *ROM = memregion("maincpu")->base(); - - membank("bank1")->set_base(&ROM[0]); + membank("bank1")->set_entry(0); } static MACHINE_CONFIG_START( poker72, poker72_state ) @@ -384,15 +386,15 @@ static MACHINE_CONFIG_START( poker72, poker72_state ) MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("ay", AY8910, 8000000/8) /* ? Mhz */ - MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSW0")) - MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSW1")) + MCFG_AY8910_PORT_A_READ_CB(IOPORT("SW2")) + MCFG_AY8910_PORT_B_READ_CB(IOPORT("SW3")) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) MACHINE_CONFIG_END ROM_START( poker72 ) - ROM_REGION( 0x20000, "maincpu", 0 ) + ROM_REGION( 0x20000, "roms", 0 ) ROM_LOAD( "27010.bin", 0x00000, 0x20000, CRC(62447341) SHA1(e442c1f834a5dd2ab6ab3bdd316dfa86f2ca6647) ) ROM_REGION( 0x1000, "89c51", 0 ) @@ -407,9 +409,14 @@ ROM_END DRIVER_INIT_MEMBER(poker72_state,poker72) { - UINT8 *rom = memregion("maincpu")->base(); + UINT8 *rom = memregion("roms")->base(); + + // configure and intialize bank 1 + membank("bank1")->configure_entries(0, 4, memregion("roms")->base(), 0x8000); + membank("bank1")->set_entry(0); - rom[0x4a9] = 0x28; + //rom[0x4a9] = 0x28; + rom[0x4aa] = 0x00; } -GAME( 1995, poker72, 0, poker72, poker72, poker72_state, poker72, ROT0, "Extrema Systems International Ltd.", "Poker Monarch (v2.50)", MACHINE_NOT_WORKING ) // actually unknown, was marked 'slot 72 poker' Manufacturers logo and 'Lucky Boy' gfx in rom.. +GAME( 1995, poker72, 0, poker72, poker72, poker72_state, poker72, ROT0, "Extrema Systems International Ltd.", "Poker Monarch (v2.50)", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp index e89fa616231..ceae4a5e568 100644 --- a/src/mame/drivers/sun4.cpp +++ b/src/mame/drivers/sun4.cpp @@ -387,6 +387,8 @@ #include "emu.h" #include "cpu/sparc/sparc.h" +#include "machine/z80scc.h" +#include "bus/rs232/rs232.h" #define ENA_NOTBOOT 0x80 #define ENA_SDVMA 0x20 @@ -394,6 +396,22 @@ #define ENA_RESET 0x04 #define ENA_DIAG 0x01 +#define SCC1_TAG "kbdmouse" +#define SCC2_TAG "uart" +#define RS232A_TAG "rs232a" +#define RS232B_TAG "rs232b" + +#define ASI_SYSTEM_SPACE 2 +#define ASI_SEGMENT_MAP 3 +#define ASI_PAGE_MAP 4 +#define ASI_USER_INSN 8 +#define ASI_SUPER_INSN 9 +#define ASI_USER_DATA 10 +#define ASI_SUPER_DATA 11 +#define ASI_FLUSH_SEGMENT 12 +#define ASI_FLUSH_PAGE 13 +#define ASI_FLUSH_CONTEXT 14 + class sun4_state : public driver_device { public: @@ -401,7 +419,10 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_rom(*this, "user1") + , m_kbdmouse(*this, SCC1_TAG) + , m_uart(*this, SCC2_TAG) , m_rom_ptr(nullptr) + , m_context(0) , m_system_enable(0) { } @@ -416,39 +437,172 @@ protected: required_device<mb86901_device> m_maincpu; required_memory_region m_rom; + required_device<z80scc_device> m_kbdmouse; + required_device<z80scc_device> m_uart; + + UINT32 read_supervisor_data(UINT32 vaddr, UINT32 mem_mask); + void write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask); + UINT32 *m_rom_ptr; UINT32 m_context; + UINT16 m_segmap[8][4096]; + UINT32 m_pagemap[8192]; UINT32 m_system_enable; }; +#define SEGMENT(vaddr) m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff] +#define PAGE(vaddr) m_pagemap[((m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff] & 0x7f) << 6) | (((vaddr) >> 12) & 0x3f)] +#define PADDR(vaddr) (((PAGE(vaddr) << 12) & 0x0ffff000) | ((vaddr) & 0xfff)) + +UINT32 sun4_state::read_supervisor_data(UINT32 vaddr, UINT32 mem_mask) +{ + UINT32 page = PAGE(vaddr); + bool v = (page & 0x80000000) ? true : false; + bool w = (page & 0x40000000) ? true : false; + bool s = (page & 0x20000000) ? true : false; + bool x = (page & 0x10000000) ? true : false; + int t = (page & 0x0c000000) >> 26; + bool a = (page & 0x02000000) ? true : false; + bool m = (page & 0x01000000) ? true : false; + char mode[4] = { 'M', 'S', '0', '1' }; + + logerror("supervisor data read: vaddr %08x, paddr %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), m_context, SEGMENT(vaddr), PAGE(vaddr) + , v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm'); + return 0; +} + +void sun4_state::write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask) +{ + UINT32 page = PAGE(vaddr); + bool v = (page & 0x80000000) ? true : false; + bool w = (page & 0x40000000) ? true : false; + bool s = (page & 0x20000000) ? true : false; + bool x = (page & 0x10000000) ? true : false; + int t = (page & 0x0c000000) >> 26; + bool a = (page & 0x02000000) ? true : false; + bool m = (page & 0x01000000) ? true : false; + char mode[4] = { 'M', 'S', '0', '1' }; + + logerror("supervisor data write: vaddr %08x, paddr %08x, data %08x, mem_mask %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), data, mem_mask, + m_context, SEGMENT(vaddr), PAGE(vaddr), v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm'); +} + READ32_MEMBER( sun4_state::sun4_mmu_r ) { UINT8 asi = m_maincpu->get_asi(); - if (asi == 2 && !space.debugger_access()) + if (!space.debugger_access()) { - switch (offset >> 26) + switch(asi) { - case 3: // context reg - return m_context; - - case 4: // system enable reg - return m_system_enable; - - case 6: // bus error register - return 0; - - case 8: // (d-)cache tags - logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc()); - return 0xffffffff; + case ASI_SYSTEM_SPACE: + switch (offset >> 26) + { + case 3: // context reg + logerror("sun4: read context register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_context << 24, mem_mask, offset << 2, m_maincpu->pc()); + return m_context << 24; + + case 4: // system enable reg + logerror("sun4: read system enable register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_system_enable << 24, mem_mask, offset << 2, m_maincpu->pc()); + return m_system_enable << 24; + + case 8: // (d-)cache tags + logerror("sun4: read dcache tags %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc()); + return 0xffffffff; + + case 9: // (d-)cache data + logerror("sun4: read dcache data %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc()); + return 0xffffffff; + + case 15: // Type 1 space passthrough + switch ((offset >> 22) & 15) + { + case 0: // keyboard/mouse + switch (offset & 1) + { + case 0: + { + UINT32 ret = 0; + if (mem_mask & 0xffff0000) + ret |= m_kbdmouse->cb_r(space, 0) << 24; + if (mem_mask & 0x0000ffff) + ret |= m_kbdmouse->db_r(space, 0) << 8; + return ret; + } + case 1: + { + UINT32 ret = 0; + if (mem_mask & 0xffff0000) + ret |= m_kbdmouse->ca_r(space, 0) << 24; + if (mem_mask & 0x0000ffff) + ret |= m_kbdmouse->da_r(space, 0) << 8; + return ret; + } + } + break; + case 1: // serial ports + switch (offset & 1) + { + case 0: + { + UINT32 ret = 0; + if (mem_mask & 0xffff0000) + ret |= m_uart->cb_r(space, 0) << 24; + if (mem_mask & 0x0000ffff) + ret |= m_uart->db_r(space, 0) << 8; + return ret; + } + case 1: + { + UINT32 ret = 0; + if (mem_mask & 0xffff0000) + ret |= m_uart->ca_r(space, 0) << 24; + if (mem_mask & 0x0000ffff) + ret |= m_uart->da_r(space, 0) << 8; + return ret; + } + } + break; + + default: + logerror("sun4: read unknown type 1 space at address %x (& %08x) asi 2, offset %x, PC = %x\n", offset << 2, mem_mask, offset << 2, m_maincpu->pc()); + } + break; + + case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur. + default: + logerror("sun4: read unknown register (& %08x) asi 2, offset %x, PC = %x\n", mem_mask, offset << 2, m_maincpu->pc()); + return 0; + } + break; + + case ASI_SEGMENT_MAP: + { + logerror("sun4: read m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 24 & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), mem_mask); + UINT32 result = SEGMENT(offset << 2); + while (!(mem_mask & 1)) + { + mem_mask >>= 1; + result <<= 1; + } + return result; + } + + case ASI_PAGE_MAP: // page map + { + logerror("sun4: read m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, PAGE(offset << 2), mem_mask); + return PAGE(offset << 2); + } + + case ASI_SUPER_INSN: // supervisor instruction space + return m_rom_ptr[offset & 0x1ffff]; // wrong, but works for now + + case ASI_SUPER_DATA: + return read_supervisor_data(offset << 2, mem_mask); - case 9: // (d-)cache data - logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc()); - return 0xffffffff; - - case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur. default: - return 0; + logerror("sun4: read (& %08x) asi %d byte offset %x, PC = %x\n", mem_mask, asi, offset << 2, m_maincpu->pc()); + break; } } @@ -456,10 +610,6 @@ READ32_MEMBER( sun4_state::sun4_mmu_r ) { return m_rom_ptr[offset & 0x1ffff]; } - else if (asi < 8 || asi > 11) - { - logerror("sun4: read asi %d byte offset %x, PC = %x\n", asi, offset << 2, m_maincpu->pc()); - } return 0; } @@ -468,34 +618,107 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w ) { UINT8 asi = m_maincpu->get_asi(); - if (asi == 2) + switch (asi) { - switch (offset >> 26) + case 2: + switch (offset >> 26) + { + case 3: // context reg + logerror("sun4: %08x (& %08x) asi 2 to context register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc()); + m_context = (UINT8)(data >> 24) & 7; + return; + + case 4: // system enable reg + logerror("sun4: write %08x (& %08x) asi 2 to system enable register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc()); + m_system_enable = (UINT8)data; + return; + + case 8: // cache tags + logerror("sun4: write %08x (& %08x) asi 2 to cache tags @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc()); + return; + + case 9: // cache data + logerror("sun4: write %08x (& %08x) asi 2 to cache data @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc()); + return; + + case 15: // Type 1 space passthrough + switch ((offset >> 22) & 15) + { + case 0: // keyboard/mouse + switch (offset & 1) + { + case 0: + if (mem_mask & 0xffff0000) + m_kbdmouse->cb_w(space, 0, data >> 24); + if (mem_mask & 0x0000ffff) + m_kbdmouse->db_w(space, 0, data >> 24); + break; + case 1: + if (mem_mask & 0xffff0000) + m_kbdmouse->ca_w(space, 0, data >> 24); + if (mem_mask & 0x0000ffff) + m_kbdmouse->da_w(space, 0, data >> 24); + break; + } + break; + case 1: // serial ports + switch (offset & 1) + { + case 0: + if (mem_mask & 0xffff0000) + m_uart->cb_w(space, 0, data >> 24); + if (mem_mask & 0x0000ffff) + m_uart->db_w(space, 0, data >> 24); + break; + case 1: + if (mem_mask & 0xffff0000) + m_uart->ca_w(space, 0, data >> 24); + if (mem_mask & 0x0000ffff) + m_uart->da_w(space, 0, data >> 24); + break; + } + break; + default: + logerror("sun4: write unknown type 1 space %08x (& %08x) asi 2, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc()); + } + break; + + case 0: // IDPROM + default: + logerror("sun4: write %08x (& %08x) asi 2 to unknown register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc()); + return; + } + break; + + case 3: // segment map + offset <<= 2; + while (!(mem_mask & 1)) + { + mem_mask >>= 1; + data >>= 1; + } + SEGMENT(offset) = data; + //m_segmap[m_context & 7][(offset >> 18) & 0xfff] &= ~(mem_mask >> 16); + //m_segmap[m_context & 7][(offset >> 18) & 0xfff] |= (data >> 16) & (mem_mask >> 16); + logerror("sun4: write m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, data, mem_mask); + break; + + case ASI_PAGE_MAP: // page map { - case 3: // context reg - m_context = (UINT8)data; - return; - - case 4: // system enable reg - m_system_enable = (UINT8)data; - return; - - case 8: // cache tags - logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc()); - return; + logerror("sun4: write m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2, + (offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, data, mem_mask); + COMBINE_DATA(&PAGE(offset << 2)); + PAGE(offset << 2) &= 0xff00ffff; + break; + } - case 9: // cache data - logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc()); - return; + case ASI_SUPER_DATA: + write_supervisor_data(offset << 2, data, mem_mask); + break; - case 0: // IDPROM - default: - return; - } - } - else if (asi < 8 || asi > 11) - { - logerror("sun4: %08x to asi %d byte offset %x, PC = %x\n", data, asi, offset << 2, m_maincpu->pc()); + default: + logerror("sun4: write %08x (& %08x) to asi %d byte offset %x, PC = %x\n", data, mem_mask, asi, offset << 2, m_maincpu->pc()); + break; } } @@ -521,6 +744,21 @@ static MACHINE_CONFIG_START( sun4, sun4_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", MB86901, 16670000) MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, sun4_mem) + + MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0) + MCFG_SCC8530_ADD(SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0) + MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd)) + MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd)) + + MCFG_RS232_PORT_ADD(RS232A_TAG, default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, rxa_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcda_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsa_w)) + + MCFG_RS232_PORT_ADD(RS232B_TAG, default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsb_w)) MACHINE_CONFIG_END /* diff --git a/src/mame/includes/midzeus.h b/src/mame/includes/midzeus.h index 7530b0b68f2..7a38879e142 100644 --- a/src/mame/includes/midzeus.h +++ b/src/mame/includes/midzeus.h @@ -29,7 +29,7 @@ public: required_shared_ptr<UINT32> m_ram_base; optional_shared_ptr<UINT32> m_linkram; required_shared_ptr<UINT32> m_tms32031_control; - required_shared_ptr<UINT32> m_zeusbase; + optional_shared_ptr<UINT32> m_zeusbase; optional_device<timekeeper_device> m_m48t35; required_device<cpu_device> m_maincpu; required_device<screen_device> m_screen; diff --git a/src/mame/includes/midzeus2.h b/src/mame/includes/midzeus2.h index ff876ae1b94..2a3801a117f 100644 --- a/src/mame/includes/midzeus2.h +++ b/src/mame/includes/midzeus2.h @@ -5,13 +5,16 @@ Driver for Midway Zeus games **************************************************************************/ +#include "video/zeus2.h" class midzeus2_state : public midzeus_state { public: midzeus2_state(const machine_config &mconfig, device_type type, const char *tag) - : midzeus_state(mconfig, type, tag) { } + : midzeus_state(mconfig, type, tag), m_zeus(*this, "zeus2") { } + required_device<zeus2_device> m_zeus; + DECLARE_WRITE_LINE_MEMBER(zeus_irq); DECLARE_VIDEO_START(midzeus2); UINT32 screen_update_midzeus2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECLARE_READ32_MEMBER( zeus2_r ); diff --git a/src/mame/layout/dlair.lay b/src/mame/layout/dlair.lay index 7b94c1f89cc..51c7096adbd 100644 --- a/src/mame/layout/dlair.lay +++ b/src/mame/layout/dlair.lay @@ -1,83 +1,51 @@ <?xml version="1.0"?> <mamelayout version="2"> - <element name="digit" defstate="10"> - <led7seg> - <color red="1.0" green="0.3" blue="0.0" /> - </led7seg> - </element> - - <view name="Simple LEDs"> - <screen index="0"> - <bounds left="0" top="0" right="4" bottom="3" /> - </screen> - - - <bezel name="digit0" element="digit"> - <bounds x="1.4" y="-1.5" width="0.2" height="0.3" /> - </bezel> - - <bezel name="digit1" element="digit"> - <bounds x="1.6" y="-1.5" width="0.2" height="0.3" /> - </bezel> - - <bezel name="digit2" element="digit"> - <bounds x="1.8" y="-1.5" width="0.2" height="0.3" /> - </bezel> - <bezel name="digit3" element="digit"> - <bounds x="2.0" y="-1.5" width="0.2" height="0.3" /> - </bezel> +<!-- define elements --> - <bezel name="digit4" element="digit"> - <bounds x="2.2" y="-1.5" width="0.2" height="0.3" /> - </bezel> - - <bezel name="digit5" element="digit"> - <bounds x="2.4" y="-1.5" width="0.2" height="0.3" /> - </bezel> - - - <bezel name="digit6" element="digit"> - <bounds x="1.9" y="-1.2" width="0.2" height="0.3" /> - </bezel> - - - <bezel name="digit8" element="digit"> - <bounds x="1.4" y="-0.9" width="0.2" height="0.3" /> - </bezel> + <element name="digit" defstate="0"> + <led7seg><color red="1.0" green="0.1" blue="0.15" /></led7seg> + </element> - <bezel name="digit9" element="digit"> - <bounds x="1.6" y="-0.9" width="0.2" height="0.3" /> - </bezel> + <element name="text_p1"><text string="PLAYER 1 SCORE"><color red="0.9" green="0.8" blue="0.05" /></text></element> + <element name="text_p2"><text string="PLAYER 2 SCORE"><color red="0.9" green="0.8" blue="0.05" /></text></element> + <element name="text_lives"><text string="LIVES" align="1"><color red="0.9" green="0.8" blue="0.05" /></text></element> + <element name="text_credits"><text string="CREDITS" align="1"><color red="0.9" green="0.8" blue="0.05" /></text></element> - <bezel name="digit10" element="digit"> - <bounds x="1.8" y="-0.9" width="0.2" height="0.3" /> - </bezel> - <bezel name="digit11" element="digit"> - <bounds x="2.0" y="-0.9" width="0.2" height="0.3" /> - </bezel> +<!-- build screen --> - <bezel name="digit12" element="digit"> - <bounds x="2.2" y="-0.9" width="0.2" height="0.3" /> - </bezel> + <view name="Internal Layout"> + <bounds x="0" y="0" width="4950" height="3000" /> + <screen index="0"> + <bounds x="0" y="0" width="4000" height="3000" /> + </screen> - <bezel name="digit13" element="digit"> - <bounds x="2.4" y="-0.9" width="0.2" height="0.3" /> - </bezel> + <bezel element="text_p1"><bounds x="4086" y="280" width="788" height="85" /></bezel> + <bezel name="digit0" element="digit"><bounds x="4086" y="380" width="118" height="165" /></bezel> + <bezel name="digit1" element="digit"><bounds x="4220" y="380" width="118" height="165" /></bezel> + <bezel name="digit2" element="digit"><bounds x="4354" y="380" width="118" height="165" /></bezel> + <bezel name="digit3" element="digit"><bounds x="4488" y="380" width="118" height="165" /></bezel> + <bezel name="digit4" element="digit"><bounds x="4622" y="380" width="118" height="165" /></bezel> + <bezel name="digit5" element="digit"><bounds x="4756" y="380" width="118" height="165" /></bezel> + <bezel element="text_lives"><bounds x="4580" y="639" width="400" height="85" /></bezel> + <bezel name="digit6" element="digit"><bounds x="4419" y="599" width="118" height="165" /></bezel> - <bezel name="digit7" element="digit"> - <bounds x="1.9" y="-0.6" width="0.2" height="0.3" /> - </bezel> + <bezel element="text_p2"><bounds x="4086" y="783" width="788" height="85" /></bezel> + <bezel name="digit8" element="digit"><bounds x="4086" y="883" width="118" height="165" /></bezel> + <bezel name="digit9" element="digit"><bounds x="4220" y="883" width="118" height="165" /></bezel> + <bezel name="digit10" element="digit"><bounds x="4354" y="883" width="118" height="165" /></bezel> + <bezel name="digit11" element="digit"><bounds x="4488" y="883" width="118" height="165" /></bezel> + <bezel name="digit12" element="digit"><bounds x="4622" y="883" width="118" height="165" /></bezel> + <bezel name="digit13" element="digit"><bounds x="4756" y="883" width="118" height="165" /></bezel> + <bezel element="text_lives"><bounds x="4580" y="1144" width="400" height="85" /></bezel> + <bezel name="digit7" element="digit"><bounds x="4419" y="1104" width="118" height="165" /></bezel> - <bezel name="digit14" element="digit"> - <bounds x="1.7" y="-0.3" width="0.2" height="0.3" /> - </bezel> + <bezel element="text_credits"><bounds x="4580" y="1413" width="400" height="85" /></bezel> + <bezel name="digit14" element="digit"><bounds x="4285" y="1383" width="118" height="165" /></bezel> + <bezel name="digit15" element="digit"><bounds x="4419" y="1383" width="118" height="165" /></bezel> - <bezel name="digit15" element="digit"> - <bounds x="1.9" y="-0.3" width="0.2" height="0.3" /> - </bezel> </view> </mamelayout> |