diff options
author | 2015-07-02 22:56:05 +0200 | |
---|---|---|
committer | 2015-07-02 22:56:05 +0200 | |
commit | 13d62dd0eb853f36f61112c31fc57ac9d6f93372 (patch) | |
tree | 1952f52db588907d5627bf65045ee666af80976a | |
parent | 40e74477ebec95cc6c73108cd7b69997e897f148 (diff) | |
parent | b755895f0fc372e219849eeeac399922ea0549e9 (diff) |
Merge branch 'master' of https://github.com/mamedev/mame
-rw-r--r-- | scripts/target/mame/mess.lua | 2 | ||||
-rw-r--r-- | src/emu/cpu/sm510/sm510.c | 76 | ||||
-rw-r--r-- | src/emu/cpu/sm510/sm510.h | 55 | ||||
-rw-r--r-- | src/emu/cpu/sm510/sm510op.inc | 263 | ||||
-rw-r--r-- | src/emu/cpu/z8000/z8000ops.inc | 3 | ||||
-rw-r--r-- | src/emu/netlist/nl_parser.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/plib/pconfig.h | 10 | ||||
-rw-r--r-- | src/emu/netlist/plib/pparser.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/solver/nld_ms_direct.h | 2 | ||||
-rw-r--r-- | src/emu/netlist/solver/nld_solver.c | 10 | ||||
-rw-r--r-- | src/emu/netlist/tools/nl_convert.c | 2 | ||||
-rw-r--r-- | src/mame/drivers/cps2.c | 8 | ||||
-rw-r--r-- | src/mame/drivers/firebeat.c | 1121 | ||||
-rw-r--r-- | src/mame/drivers/suprloco.c | 5 | ||||
-rw-r--r-- | src/mess/drivers/m20.c | 50 | ||||
-rw-r--r-- | src/mess/machine/m20_8086.c | 119 | ||||
-rw-r--r-- | src/mess/machine/m20_8086.h | 40 |
17 files changed, 1240 insertions, 530 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 9b37d308995..223700a25b5 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -941,7 +941,6 @@ files { MAME_DIR .. "src/mame/video/n64.c", MAME_DIR .. "src/mame/video/rdpblend.c", MAME_DIR .. "src/mame/video/rdptpipe.c", - MAME_DIR .. "src/mame/video/rdpspn16.c", MAME_DIR .. "src/mame/machine/megadriv.c", MAME_DIR .. "src/mame/drivers/naomi.c", MAME_DIR .. "src/mame/machine/awboard.c", @@ -1898,6 +1897,7 @@ createMESSProjects(_target, _subtarget, "olivetti") files { MAME_DIR .. "src/mess/drivers/m20.c", MAME_DIR .. "src/mess/machine/m20_kbd.c", + MAME_DIR .. "src/mess/machine/m20_8086.c", MAME_DIR .. "src/mess/drivers/m24.c", MAME_DIR .. "src/mess/machine/m24_kbd.c", MAME_DIR .. "src/mess/machine/m24_z8000.c" diff --git a/src/emu/cpu/sm510/sm510.c b/src/emu/cpu/sm510/sm510.c index 7878288205b..3d723e0def4 100644 --- a/src/emu/cpu/sm510/sm510.c +++ b/src/emu/cpu/sm510/sm510.c @@ -138,9 +138,6 @@ void sm510_base_device::device_reset() - - - //------------------------------------------------- // execute //------------------------------------------------- @@ -180,6 +177,77 @@ void sm510_base_device::execute_run() get_opcode_param(); // handle opcode - + switch (m_op & 0xf0) + { + case 0x20: op_lax(); break; + case 0x30: op_adx(); break; + case 0x40: op_lb(); break; + + case 0x80: case 0x90: case 0xa0: case 0xb0: + op_t(); break; + case 0xc0: case 0xd0: case 0xe0: case 0xf0: + op_tm(); break; + + default: + switch (m_op & 0xfc) + { + case 0x04: op_rm(); break; + case 0x0c: op_sm(); break; + case 0x10: op_exc(); break; + case 0x14: op_exci(); break; + case 0x18: op_lda(); break; + case 0x1c: op_excd(); break; + case 0x54: op_tmi(); break; + case 0x70: case 0x74: case 0x78: op_tl(); + case 0x7c: op_tml(); break; + + default: + switch (m_op) + { + case 0x00: op_skip(); break; + case 0x01: op_atbp(); break; + case 0x02: op_sbm(); break; + case 0x03: op_atpl(); break; + case 0x08: op_add(); break; + case 0x09: op_add11(); break; + case 0x0a: op_coma(); break; + case 0x0b: op_exbla(); break; + + case 0x51: op_tb(); break; + case 0x52: op_tc(); break; + case 0x53: op_tam(); break; + case 0x58: op_tis(); break; + case 0x59: op_atl(); break; + case 0x5a: op_ta0(); break; + case 0x5b: op_tabl(); break; + case 0x5d: op_cend(); break; + case 0x5e: op_tal(); break; + case 0x5f: op_lbl(); break; + + case 0x60: op_atfc(); break; + case 0x61: op_atr(); break; + case 0x62: op_wr(); break; + case 0x63: op_ws(); break; + case 0x64: op_incb(); break; + case 0x65: op_idiv(); break; + case 0x66: op_rc(); break; + case 0x67: op_sc(); break; + case 0x68: op_tf1(); break; + case 0x69: op_tf4(); break; + case 0x6a: op_kta(); break; + case 0x6b: op_rot(); break; + case 0x6c: op_decb(); break; + case 0x6d: op_bdc(); break; + case 0x6e: op_rtn0(); break; + case 0x6f: op_rtn1(); break; + + default: op_illegal(); break; + } + break; // 0xff + + } + break; // 0xfc + + } // big switch } } diff --git a/src/emu/cpu/sm510/sm510.h b/src/emu/cpu/sm510/sm510.h index 2b8c84cc534..fe9ce5ec898 100644 --- a/src/emu/cpu/sm510/sm510.h +++ b/src/emu/cpu/sm510/sm510.h @@ -93,6 +93,61 @@ protected: void push_stack(); // opcode handlers + void op_lb(); + void op_lbl(); + void op_sbm(); + void op_exbla(); + void op_incb(); + void op_decb(); + + void op_atpl(); + void op_rtn0(); + void op_rtn1(); + void op_tl(); + void op_tml(); + void op_tm(); + void op_t(); + + void op_exc(); + void op_bdc(); + void op_exci(); + void op_excd(); + void op_lda(); + void op_lax(); + void op_wr(); + void op_ws(); + + void op_kta(); + void op_atbp(); + void op_atl(); + void op_atfc(); + void op_atr(); + + void op_add(); + void op_add11(); + void op_adx(); + void op_coma(); + void op_rot(); + void op_rc(); + void op_sc(); + + void op_tb(); + void op_tc(); + void op_tam(); + void op_tmi(); + void op_ta0(); + void op_tabl(); + void op_tis(); + void op_tal(); + void op_tf1(); + void op_tf4(); + + void op_rm(); + void op_sm(); + void op_skip(); + void op_cend(); + void op_idiv(); + void op_illegal(); }; diff --git a/src/emu/cpu/sm510/sm510op.inc b/src/emu/cpu/sm510/sm510op.inc index f8e6aa40645..921ef27cad8 100644 --- a/src/emu/cpu/sm510/sm510op.inc +++ b/src/emu/cpu/sm510/sm510op.inc @@ -35,6 +35,269 @@ void sm510_base_device::push_stack() // instruction set +// RAM address instructions + +void sm510_base_device::op_lb() +{ + // x +} + +void sm510_base_device::op_lbl() +{ + // x +} + +void sm510_base_device::op_sbm() +{ + // x +} + +void sm510_base_device::op_exbla() +{ + // x +} + +void sm510_base_device::op_incb() +{ + // x +} + +void sm510_base_device::op_decb() +{ + // x +} + + +// ROM address instructions + +void sm510_base_device::op_atpl() +{ + // x +} + +void sm510_base_device::op_rtn0() +{ + // x +} + +void sm510_base_device::op_rtn1() +{ + // x +} + +void sm510_base_device::op_tl() +{ + // x +} + +void sm510_base_device::op_tml() +{ + // x +} + +void sm510_base_device::op_tm() +{ + // x +} + +void sm510_base_device::op_t() +{ + // x +} + + +// Data transfer instructions + +void sm510_base_device::op_exc() +{ + // x +} + +void sm510_base_device::op_bdc() +{ + // x +} + +void sm510_base_device::op_exci() +{ + // x +} + +void sm510_base_device::op_excd() +{ + // x +} + +void sm510_base_device::op_lda() +{ + // x +} + +void sm510_base_device::op_lax() +{ + // x +} + +void sm510_base_device::op_wr() +{ + // x +} + +void sm510_base_device::op_ws() +{ + // x +} + + +// I/O instructions + +void sm510_base_device::op_kta() +{ + // x +} + +void sm510_base_device::op_atbp() +{ + // x +} + +void sm510_base_device::op_atl() +{ + // x +} + +void sm510_base_device::op_atfc() +{ + // x +} + +void sm510_base_device::op_atr() +{ + // x +} + + +// Arithmetic instructions + +void sm510_base_device::op_add() +{ + // x +} + +void sm510_base_device::op_add11() +{ + // x +} + +void sm510_base_device::op_adx() +{ + // x +} + +void sm510_base_device::op_coma() +{ + // x +} + +void sm510_base_device::op_rot() +{ + // x +} + +void sm510_base_device::op_rc() +{ + // x +} + +void sm510_base_device::op_sc() +{ + // x +} + + +// Test instructions + +void sm510_base_device::op_tb() +{ + // x +} + +void sm510_base_device::op_tc() +{ + // x +} + +void sm510_base_device::op_tam() +{ + // x +} + +void sm510_base_device::op_tmi() +{ + // x +} + +void sm510_base_device::op_ta0() +{ + // x +} + +void sm510_base_device::op_tabl() +{ + // x +} + +void sm510_base_device::op_tis() +{ + // x +} + +void sm510_base_device::op_tal() +{ + // x +} + +void sm510_base_device::op_tf1() +{ + // x +} + +void sm510_base_device::op_tf4() +{ + // x +} + + +// Bit manipulation instructions + +void sm510_base_device::op_rm() +{ + // x +} + +void sm510_base_device::op_sm() +{ + // x +} + + +// Special instructions + +void sm510_base_device::op_skip() +{ + // no operation +} + +void sm510_base_device::op_cend() +{ + // clock stop +} + +void sm510_base_device::op_idiv() +{ + // reset DIV +} + void sm510_base_device::op_illegal() { logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_prev_pc); diff --git a/src/emu/cpu/z8000/z8000ops.inc b/src/emu/cpu/z8000/z8000ops.inc index 511a0034887..c9d0b365783 100644 --- a/src/emu/cpu/z8000/z8000ops.inc +++ b/src/emu/cpu/z8000/z8000ops.inc @@ -4515,13 +4515,14 @@ void z8002_device::Z76_ssN0_dddd_addr() GET_DST(OP0,NIB3); GET_SRC(OP0,NIB2); GET_ADDR_RAW(OP1); + UINT16 temp = RW(src); // store src in case dst == src if (segmented_mode()) { RL(dst) = addr; } else { RW(dst) = addr; } - add_to_addr_reg(dst, RW(src)); + add_to_addr_reg(dst, temp); } /****************************************** diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c index dc219323a41..cbd9be4ec5a 100644 --- a/src/emu/netlist/nl_parser.c +++ b/src/emu/netlist/nl_parser.c @@ -376,7 +376,7 @@ void parser_t::device(const pstring &dev_type) tok = get_token(); } if (cnt != termlist.size()) - m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), termlist.size(), cnt); + m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), SIZET_PRINTF(termlist.size()), SIZET_PRINTF(cnt)); require_token(tok, m_tok_param_right); } } diff --git a/src/emu/netlist/plib/pconfig.h b/src/emu/netlist/plib/pconfig.h index 4ff0a07602d..2bf1a2f26c5 100644 --- a/src/emu/netlist/plib/pconfig.h +++ b/src/emu/netlist/plib/pconfig.h @@ -48,6 +48,11 @@ #undef ATTR_COLD #define ATTR_COLD +static inline std::size_t SIZET_PRINTF(const std::size_t &v) +{ + return (unsigned) v; +} + /* use MAME */ #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL) #define PHAS_PMF_INTERNAL 1 @@ -148,6 +153,11 @@ typedef int64_t INT64; #endif #endif +static inline std::size_t SIZET_PRINTF(const std::size_t &v) +{ + return (unsigned) v; +} + #endif /* diff --git a/src/emu/netlist/plib/pparser.c b/src/emu/netlist/plib/pparser.c index a6e633f22bb..954b9048810 100644 --- a/src/emu/netlist/plib/pparser.c +++ b/src/emu/netlist/plib/pparser.c @@ -463,7 +463,7 @@ pstring ppreprocessor::process(const pstring &contents) } } else - error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", i, line.cstr())); + error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", SIZET_PRINTF(i), line.cstr())); } else { diff --git a/src/emu/netlist/solver/nld_ms_direct.h b/src/emu/netlist/solver/nld_ms_direct.h index 6f63d51db15..f715b9d074d 100644 --- a/src/emu/netlist/solver/nld_ms_direct.h +++ b/src/emu/netlist/solver/nld_ms_direct.h @@ -147,7 +147,7 @@ template <unsigned m_N, unsigned _storage_N> ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::list_t &nets) { if (m_dim < nets.size()) - netlist().error("Dimension %d less than %" SIZETFMT, m_dim, nets.size()); + netlist().error("Dimension %d less than %" SIZETFMT, m_dim, SIZET_PRINTF(nets.size())); for (unsigned k = 0; k < N(); k++) { diff --git a/src/emu/netlist/solver/nld_solver.c b/src/emu/netlist/solver/nld_solver.c index d1f080bd176..46391bef3e6 100644 --- a/src/emu/netlist/solver/nld_solver.c +++ b/src/emu/netlist/solver/nld_solver.c @@ -162,7 +162,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets) if (net_proxy_output == NULL) { net_proxy_output = palloc(analog_output_t); - net_proxy_output->init_object(*this, this->name() + "." + pstring::sprintf("m%" SIZETFMT, m_inps.size())); + net_proxy_output->init_object(*this, this->name() + "." + pstring::sprintf("m%" SIZETFMT, SIZET_PRINTF(m_inps.size()))); m_inps.add(net_proxy_output); net_proxy_output->m_proxied_net = &p->net().as_analog(); } @@ -511,7 +511,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() } // setup the solvers - netlist().log("Found %d net groups in %" SIZETFMT " nets\n", cur_group + 1, netlist().m_nets.size()); + netlist().log("Found %d net groups in %" SIZETFMT " nets\n", cur_group + 1, SIZET_PRINTF(netlist().m_nets.size())); for (int i = 0; i <= cur_group; i++) { matrix_solver_t *ms; @@ -576,19 +576,19 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() break; } - register_sub(pstring::sprintf("Solver_%" SIZETFMT,m_mat_solvers.size()), *ms); + register_sub(pstring::sprintf("Solver_%" SIZETFMT,SIZET_PRINTF(m_mat_solvers.size())), *ms); ms->vsetup(groups[i]); m_mat_solvers.add(ms); netlist().log("Solver %s", ms->name().cstr()); - netlist().log(" # %d ==> %" SIZETFMT " nets", i, groups[i].size()); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr()); + netlist().log(" # %d ==> %" SIZETFMT " nets", i, SIZET_PRINTF(groups[i].size())); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr()); netlist().log(" has %s elements", ms->is_dynamic() ? "dynamic" : "no dynamic"); netlist().log(" has %s elements", ms->is_timestep() ? "timestep" : "no timestep"); for (std::size_t j=0; j<groups[i].size(); j++) { - netlist().log("Net %" SIZETFMT ": %s", j, groups[i][j]->name().cstr()); + netlist().log("Net %" SIZETFMT ": %s", SIZET_PRINTF(j), groups[i][j]->name().cstr()); net_t *n = groups[i][j]; for (std::size_t k = 0; k < n->m_core_terms.size(); k++) { diff --git a/src/emu/netlist/tools/nl_convert.c b/src/emu/netlist/tools/nl_convert.c index 39fad2d7241..23e5c537b12 100644 --- a/src/emu/netlist/tools/nl_convert.c +++ b/src/emu/netlist/tools/nl_convert.c @@ -337,7 +337,7 @@ void nl_convert_spice_t::process_line(const pstring &line) add_device(tname, xname); for (std::size_t i=1; i < tt.size() - 1; i++) { - pstring term = pstring::sprintf("%s.%" SIZETFMT, xname.cstr(), i); + pstring term = pstring::sprintf("%s.%" SIZETFMT, xname.cstr(), SIZET_PRINTF(i)); add_term(tt[i], term); } break; diff --git a/src/mame/drivers/cps2.c b/src/mame/drivers/cps2.c index 8e483dbb429..b66415be907 100644 --- a/src/mame/drivers/cps2.c +++ b/src/mame/drivers/cps2.c @@ -8755,8 +8755,8 @@ ROM_END ROM_START( xmvsfur1 ) ROM_REGION( CODE_SIZE, "maincpu", 0 ) /* 68000 code */ - ROM_LOAD16_WORD_SWAP( "xvsu.03h", 0x000000, 0x80000, CRC(5481155a) SHA1(799a2488684cbead33206498d13261b79624a46e) ) - ROM_LOAD16_WORD_SWAP( "xvsu.04h", 0x080000, 0x80000, CRC(1e236388) SHA1(329c08103840fadbc4176785c4b24013a7a2b1bc) ) + ROM_LOAD16_WORD_SWAP( "xvsu.03h", 0x000000, 0x80000, CRC(5481155a) SHA1(799a2488684cbead33206498d13261b79624a46e) ) /* also found as rev I */ + ROM_LOAD16_WORD_SWAP( "xvsu.04h", 0x080000, 0x80000, CRC(1e236388) SHA1(329c08103840fadbc4176785c4b24013a7a2b1bc) ) /* also found as rev I */ ROM_LOAD16_WORD_SWAP( "xvs.05a", 0x100000, 0x80000, CRC(7db6025d) SHA1(2d74f48f83f45359bfaca28ab686625766af12ee) ) ROM_LOAD16_WORD_SWAP( "xvs.06a", 0x180000, 0x80000, CRC(e8e2c75c) SHA1(929408cb5d98e95cec75ea58e4701b0cbdbcd016) ) ROM_LOAD16_WORD_SWAP( "xvs.07", 0x200000, 0x80000, CRC(08f0abed) SHA1(ef16c376232dba63b0b9bc3aa0640f9001ccb68a) ) @@ -8788,8 +8788,8 @@ ROM_END ROM_START( xmvsfur2 ) ROM_REGION( CODE_SIZE, "maincpu", 0 ) /* 68000 code */ - ROM_LOAD16_WORD_SWAP( "xvsu.03", 0x000000, 0x80000, CRC(bd8b152f) SHA1(6b029b7314ce2516c67e5a71508f86aa01d30ab8) ) - ROM_LOAD16_WORD_SWAP( "xvsu.04", 0x080000, 0x80000, CRC(7c7d1da3) SHA1(96dd1f83c8f8053177b91ad31c4c051b28dd0208) ) + ROM_LOAD16_WORD_SWAP( "xvsu.03d", 0x000000, 0x80000, CRC(bd8b152f) SHA1(6b029b7314ce2516c67e5a71508f86aa01d30ab8) ) + ROM_LOAD16_WORD_SWAP( "xvsu.04d", 0x080000, 0x80000, CRC(7c7d1da3) SHA1(96dd1f83c8f8053177b91ad31c4c051b28dd0208) ) ROM_LOAD16_WORD_SWAP( "xvs.05a", 0x100000, 0x80000, CRC(7db6025d) SHA1(2d74f48f83f45359bfaca28ab686625766af12ee) ) ROM_LOAD16_WORD_SWAP( "xvs.06a", 0x180000, 0x80000, CRC(e8e2c75c) SHA1(929408cb5d98e95cec75ea58e4701b0cbdbcd016) ) ROM_LOAD16_WORD_SWAP( "xvs.07", 0x200000, 0x80000, CRC(08f0abed) SHA1(ef16c376232dba63b0b9bc3aa0640f9001ccb68a) ) diff --git a/src/mame/drivers/firebeat.c b/src/mame/drivers/firebeat.c index 346691f8098..e58068c25f1 100644 --- a/src/mame/drivers/firebeat.c +++ b/src/mame/drivers/firebeat.c @@ -82,9 +82,9 @@ ------------------------------------------------------------------ GQ972 GQ972 2000 Beatmania III GQ972(?) ? 2001 Beatmania III Append 6th Mix - GQ972(?) ? 2002 Beatmania III Append 7th Mix + GQ972(?) GCB07 2002 Beatmania III Append 7th Mix GQ972(?) ? 2000 Beatmania III Append Core Remix - GQ972(?) ? 2003 Beatmania III The Final + GQ972(?) GCC01 2003 Beatmania III The Final GQ974 GQ974 2000 Keyboardmania GQ974 GCA01 2000 Keyboardmania 2nd Mix GQ974 GCA12 2001 Keyboardmania 3rd Mix @@ -92,13 +92,13 @@ GQ977 GQ977 2000 Para Para Dancing GQ977 GC977 2000 Para Para Paradise 1.1 GQ977 GQA11 2000 Para Para Paradise 1st Mix+ - GQA02(?) ? 2000 Pop'n Music 4 - ??? ? 2000 Pop'n Music 5 - ??? ? 2001 Pop'n Music 6 + GQA02(?) GQ986 2000 Pop'n Music 4 + ??? G?A04 2000 Pop'n Music 5 + ??? GQA16 2001 Pop'n Music 6 GQA02 GCB00 2001 Pop'n Music 7 - ??? ? 2002 Pop'n Music 8 + ??? GQB30 2002 Pop'n Music 8 ??? ? 2000 Pop'n Music Animelo - ??? ? 2001 Pop'n Music Animelo 2 + ??? GEA02 2001 Pop'n Music Animelo 2 ??? ? 2001 Pop'n Music Mickey Tunes TODO: @@ -144,13 +144,9 @@ #include "firebeat.lh" -struct GCU_REGS -{ - UINT32 *vram; - UINT32 vram_read_address; - UINT32 vram_write_fifo_address; - UINT32 visible_area; -}; +#define DUMP_VRAM 0 +#define PRINT_GCU 0 + struct IBUTTON_SUBKEY { @@ -164,136 +160,324 @@ struct IBUTTON IBUTTON_SUBKEY subkey[3]; }; +#define MCFG_FIREBEAT_GCU_CPU_TAG(_tag) \ + firebeat_gcu_device::static_set_cpu_tag(*device, _tag); - -class firebeat_state : public driver_device +class firebeat_gcu_device : public device_t { public: - firebeat_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_work_ram(*this, "work_ram"), - m_flash_main(*this, "flash_main"), - m_flash_snd1(*this, "flash_snd1"), - m_flash_snd2(*this, "flash_snd2"), - m_duart_midi(*this, "duart_midi"), - m_duart_com(*this, "duart_com"), - m_kbd0(*this, "kbd0"), - m_kbd1(*this, "kbd1"), - m_ata(*this, "ata") - { } + firebeat_gcu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + static void static_set_cpu_tag(device_t &device, const char *tag) { downcast<firebeat_gcu_device &>(device).m_cputag = tag; } - required_device<ppc4xx_device> m_maincpu; - required_shared_ptr<UINT32> m_work_ram; - required_device<fujitsu_29f016a_device> m_flash_main; - required_device<fujitsu_29f016a_device> m_flash_snd1; - required_device<fujitsu_29f016a_device> m_flash_snd2; - optional_device<pc16552_device> m_duart_midi; - required_device<pc16552_device> m_duart_com; - optional_device<midi_keyboard_device> m_kbd0; - optional_device<midi_keyboard_device> m_kbd1; - required_device<ata_interface_device> m_ata; + int draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - UINT8 m_extend_board_irq_enable; - UINT8 m_extend_board_irq_active; -// emu_timer *m_keyboard_timer; - GCU_REGS m_gcu[2]; - int m_tick; - int m_layer; - int m_cab_data_ptr; - const int * m_cur_cab_data; -// int m_keyboard_state[2]; - UINT8 m_spu_shared_ram[0x400]; - IBUTTON m_ibutton; - int m_ibutton_state; - int m_ibutton_read_subkey_ptr; - UINT8 m_ibutton_subkey_data[0x40]; - DECLARE_READ8_MEMBER(soundram_r); - DECLARE_DRIVER_INIT(ppd); - DECLARE_DRIVER_INIT(kbm); - DECLARE_DRIVER_INIT(ppp); - DECLARE_MACHINE_START(firebeat); - DECLARE_MACHINE_RESET(firebeat); - DECLARE_VIDEO_START(firebeat); - UINT32 screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - UINT32 screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(firebeat_interrupt); - DECLARE_READ32_MEMBER(gcu0_r); - DECLARE_WRITE32_MEMBER(gcu0_w); - DECLARE_READ32_MEMBER(gcu1_r); - DECLARE_WRITE32_MEMBER(gcu1_w); - DECLARE_READ32_MEMBER(input_r); - DECLARE_READ32_MEMBER(sensor_r ); - DECLARE_READ32_MEMBER(flashram_r); - DECLARE_WRITE32_MEMBER(flashram_w); - DECLARE_READ32_MEMBER(soundflash_r); - DECLARE_WRITE32_MEMBER(soundflash_w); - DECLARE_WRITE_LINE_MEMBER(ata_interrupt); - DECLARE_READ32_MEMBER(ata_command_r); - DECLARE_WRITE32_MEMBER(ata_command_w); - DECLARE_READ32_MEMBER(ata_control_r); - DECLARE_WRITE32_MEMBER(ata_control_w); -// DECLARE_READ32_MEMBER(comm_uart_r); -// DECLARE_WRITE32_MEMBER(comm_uart_w); - DECLARE_READ32_MEMBER(cabinet_r); - DECLARE_READ32_MEMBER(keyboard_wheel_r); - DECLARE_READ8_MEMBER(midi_uart_r); - DECLARE_WRITE8_MEMBER(midi_uart_w); - DECLARE_READ32_MEMBER(extend_board_irq_r); - DECLARE_WRITE32_MEMBER(extend_board_irq_w); - DECLARE_WRITE32_MEMBER(lamp_output_w); - DECLARE_WRITE32_MEMBER(lamp_output_kbm_w); - DECLARE_WRITE32_MEMBER(lamp_output_ppp_w); - DECLARE_WRITE32_MEMBER(lamp_output2_w); - DECLARE_WRITE32_MEMBER(lamp_output2_ppp_w); - DECLARE_WRITE32_MEMBER(lamp_output3_w); - DECLARE_WRITE32_MEMBER(lamp_output3_ppp_w); - DECLARE_READ32_MEMBER(ppc_spu_share_r); - DECLARE_WRITE32_MEMBER(ppc_spu_share_w); - DECLARE_READ16_MEMBER(spu_unk_r); -// TIMER_CALLBACK_MEMBER(keyboard_timer_callback); - void gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd); - void gcu_fill_rect(bitmap_ind16 &bitmap, const rectangle &cliprect, UINT32 *cmd); - void gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd); - void gcu_exec_display_list(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 address); - UINT32 update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int chip); - UINT32 GCU_r(int chip, UINT32 offset, UINT32 mem_mask); - void GCU_w(int chip, UINT32 offset, UINT32 data, UINT32 mem_mask); - void set_ibutton(UINT8 *data); - int ibutton_w(UINT8 data); - DECLARE_WRITE8_MEMBER(security_w); - void init_lights(write32_delegate out1, write32_delegate out2, write32_delegate out3); - void init_firebeat(); - void init_keyboard(); - DECLARE_WRITE_LINE_MEMBER(sound_irq_callback); - DECLARE_WRITE_LINE_MEMBER(midi_uart_ch0_irq_callback); - DECLARE_WRITE_LINE_MEMBER(midi_uart_ch1_irq_callback); + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); + + struct framebuffer + { + UINT32 base; + int width; + int height; + }; + +protected: + virtual void device_start(); + virtual void device_stop(); + virtual void device_reset(); + +private: + void execute_command(UINT32 *cmd); + void execute_display_list(UINT32 addr); + void draw_object(UINT32 *cmd); + void fill_rect(UINT32 *cmd); + void draw_character(UINT32 *cmd); + void fb_config(UINT32 *cmd); + + UINT32 *m_vram; + UINT32 m_vram_read_addr; + UINT32 m_vram_fifo0_addr; + UINT32 m_vram_fifo1_addr; + UINT32 m_vram_fifo0_mode; + UINT32 m_vram_fifo1_mode; + UINT32 m_command_fifo0[4]; + UINT32 m_command_fifo0_ptr; + UINT32 m_command_fifo1[4]; + UINT32 m_command_fifo1_ptr; + + const char* m_cputag; + device_t* m_cpu; + + framebuffer m_frame[4]; + UINT32 m_fb_origin_x; + UINT32 m_fb_origin_y; }; +const device_type FIREBEAT_GCU = &device_creator<firebeat_gcu_device>; + +firebeat_gcu_device::firebeat_gcu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, FIREBEAT_GCU, "FireBeat GCU", tag, owner, clock, "firebeat_gcu", __FILE__) +{ +} + +READ32_MEMBER(firebeat_gcu_device::read) +{ + int reg = offset * 4; + // VRAM Read + if (reg >= 0x80 && reg < 0x100) + { + return m_vram[m_vram_read_addr + offset - 0x20]; + } + switch (reg) + { + case 0x78: // GCU Status + /* ppd checks bits 0x0041 of the upper halfword on interrupt */ + return 0xffff0005; + default: + break; + } + return 0xffffffff; +} -VIDEO_START_MEMBER(firebeat_state,firebeat) +WRITE32_MEMBER(firebeat_gcu_device::write) { - m_gcu[0].vram = auto_alloc_array(machine(), UINT32, 0x2000000/4); - m_gcu[1].vram = auto_alloc_array(machine(), UINT32, 0x2000000/4); - memset(m_gcu[0].vram, 0, 0x2000000); - memset(m_gcu[1].vram, 0, 0x2000000); + int reg = offset * 4; + + switch (reg) + { + case 0x10: + /* IRQ clear/enable; ppd writes bit off then on in response to interrupt */ + /* it enables bits 0x41, but 0x01 seems to be the one it cares about */ + if (ACCESSING_BITS_16_31 && (data & 0x00010000) == 0) + m_cpu->execute().set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); + if (ACCESSING_BITS_0_15) +#if PRINT_GCU + printf("%s_w: %02X, %08X, %08X\n", basetag(), reg, data, mem_mask); +#endif + break; + + case 0x14: // ? + break; + + case 0x18: // ? + break; + + case 0x20: // Framebuffer 0 Origin(?) + break; + + case 0x24: // Framebuffer 1 Origin(?) + break; + + case 0x28: // Framebuffer 2 Origin(?) + break; + + case 0x2c: // Framebuffer 3 Origin(?) + break; + + case 0x30: // Framebuffer 0 Dimensions + if (ACCESSING_BITS_16_31) + m_frame[0].height = (data >> 16) & 0xffff; + if (ACCESSING_BITS_0_15) + m_frame[0].width = data & 0xffff; + break; + + case 0x34: // Framebuffer 1 Dimensions + if (ACCESSING_BITS_16_31) + m_frame[1].height = (data >> 16) & 0xffff; + if (ACCESSING_BITS_0_15) + m_frame[1].width = data & 0xffff; + break; + + case 0x38: // Framebuffer 2 Dimensions + if (ACCESSING_BITS_16_31) + m_frame[2].height = (data >> 16) & 0xffff; + if (ACCESSING_BITS_0_15) + m_frame[2].width = data & 0xffff; + break; + + case 0x3c: // Framebuffer 3 Dimensions + if (ACCESSING_BITS_16_31) + m_frame[3].height = (data >> 16) & 0xffff; + if (ACCESSING_BITS_0_15) + m_frame[3].width = data & 0xffff; + break; + + case 0x40: // Framebuffer 0 Base + m_frame[0].base = data; +#if PRINT_GCU + printf("%s FB0 Base: %08X\n", basetag(), data); +#endif + break; + + case 0x44: // Framebuffer 1 Base + m_frame[1].base = data; +#if PRINT_GCU + printf("%s FB1 Base: %08X\n", basetag(), data); +#endif + break; + + case 0x48: // Framebuffer 2 Base + m_frame[2].base = data; +#if PRINT_GCU + printf("%s FB2 Base: %08X\n", basetag(), data); +#endif + break; + + case 0x4c: // Framebuffer 3 Base + m_frame[3].base = data; +#if PRINT_GCU + printf("%s FB3 Base: %08X\n", basetag(), data); +#endif + break; + + case 0x5c: // VRAM Read Address + m_vram_read_addr = (data & 0xffffff) / 2; + break; + + case 0x60: // VRAM Port 0 Write Address + m_vram_fifo0_addr = (data & 0xffffff) / 2; + break; + + case 0x68: // VRAM Port 0/1 Mode + if (ACCESSING_BITS_16_31) + m_vram_fifo0_mode = data >> 16; + if (ACCESSING_BITS_0_15) + m_vram_fifo1_mode = data & 0xffff; + break; + + case 0x70: // VRAM Port 0 Write FIFO + if (m_vram_fifo0_mode & 0x100) + { + // write to command fifo + m_command_fifo0[m_command_fifo0_ptr] = data; + m_command_fifo0_ptr++; + + // execute when filled + if (m_command_fifo0_ptr >= 4) + { + //printf("GCU FIFO0 exec: %08X %08X %08X %08X\n", m_command_fifo0[0], m_command_fifo0[1], m_command_fifo0[2], m_command_fifo0[3]); + execute_command(m_command_fifo0); + m_command_fifo0_ptr = 0; + } + } + else + { + // write to VRAM fifo + m_vram[m_vram_fifo0_addr] = data; + m_vram_fifo0_addr++; + } + break; + + case 0x64: // VRAM Port 1 Write Address + m_vram_fifo1_addr = (data & 0xffffff) / 2; + printf("GCU FIFO1 addr = %08X\n", data); + break; + + case 0x74: // VRAM Port 1 Write FIFO + printf("GCU FIFO1 write = %08X\n", data); + + if (m_vram_fifo1_mode & 0x100) + { + // write to command fifo + m_command_fifo1[m_command_fifo1_ptr] = data; + m_command_fifo1_ptr++; + + // execute when filled + if (m_command_fifo1_ptr >= 4) + { + printf("GCU FIFO1 exec: %08X %08X %08X %08X\n", m_command_fifo1[0], m_command_fifo1[1], m_command_fifo1[2], m_command_fifo1[3]); + m_command_fifo1_ptr = 0; + } + } + else + { + // write to VRAM fifo + m_vram[m_vram_fifo1_addr] = data; + m_vram_fifo1_addr++; + } + break; + + default: + //printf("%s_w: %02X, %08X, %08X\n", basetag(), reg, data, mem_mask); + break; + } } +int firebeat_gcu_device::draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + UINT16 *vram16 = (UINT16*)m_vram; + + int x = 0; + int y = 0; + int width = m_frame[0].width; + int height = m_frame[0].height; + + if (width != 0 && height != 0) + { + rectangle visarea = screen.visible_area(); + if ((visarea.max_x+1) != width || (visarea.max_y+1) != height) + { + visarea.max_x = width-1; + visarea.max_y = height-1; + screen.configure(width, height, visarea, screen.frame_period().attoseconds); + } + } + + int fb_pitch = 1024; + + for (int j=0; j < height; j++) + { + UINT16 *d = &bitmap.pix16(j, x); + int li = ((j+y) * fb_pitch) + x; + UINT32 fbaddr0 = m_frame[0].base + li; + UINT32 fbaddr1 = m_frame[1].base + li; +// UINT32 fbaddr2 = m_frame[2].base + li; +// UINT32 fbaddr3 = m_frame[3].base + li; + + for (int i=0; i < width; i++) + { + UINT16 pix0 = vram16[fbaddr0 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; + UINT16 pix1 = vram16[fbaddr1 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; +// UINT16 pix2 = vram16[fbaddr2 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; +// UINT16 pix3 = vram16[fbaddr3 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; + + if (pix0 & 0x8000) + { + d[i] = pix0 & 0x7fff; + } + else + { + d[i] = pix1 & 0x7fff; + } -void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd) + fbaddr0++; + fbaddr1++; +// fbaddr2++; +// fbaddr3++; + } + } + + return 0; +} + +void firebeat_gcu_device::draw_object(UINT32 *cmd) { - // 0x00: xxx----- -------- -------- -------- command type + // 0x00: xxx----- -------- -------- -------- command (5) + // 0x00: ---x---- -------- -------- -------- 0: absolute coordinates + // 1: relative coordinates from framebuffer origin + // 0x00: ----xx-- -------- -------- -------- ? // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx object data address in vram // 0x01: -------- -------- ------xx xxxxxxxx object x - // 0x01: -------- ----xxxx xxxxxx-- -------- object y + // 0x01: -------- xxxxxxxx xxxxxx-- -------- object y // 0x01: -----x-- -------- -------- -------- object x flip // 0x01: ----x--- -------- -------- -------- object y flip - // 0x01: ---x---- -------- -------- -------- object alpha enable (?) + // 0x01: --xx---- -------- -------- -------- object alpha enable (different blend modes?) + // 0x01: -x------ -------- -------- -------- object transparency enable (?) // 0x02: -------- -------- ------xx xxxxxxxx object width // 0x02: -------- -----xxx xxxxxx-- -------- object x scale @@ -301,53 +485,49 @@ void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &clip // 0x03: -------- -------- ------xx xxxxxxxx object height // 0x03: -------- -----xxx xxxxxx-- -------- object y scale - int x = cmd[1] & 0x3ff; - int y = (cmd[1] >> 10) & 0x3ff; - int width = (cmd[2] & 0x3ff) + 1; - int height = (cmd[3] & 0x3ff) + 1; - int xscale = (cmd[2] >> 10) & 0x1ff; - int yscale = (cmd[3] >> 10) & 0x1ff; - int xflip = (cmd[1] & 0x04000000) ? 1 : 0; - int yflip = (cmd[1] & 0x08000000) ? 1 : 0; - int alpha_enable = (cmd[1] & 0x10000000) ? 1 : 0; - UINT32 address = cmd[0] & 0xffffff; - int alpha_level = (cmd[2] >> 27) & 0x1f; + int x = cmd[1] & 0x3ff; + int y = (cmd[1] >> 10) & 0x3fff; + int width = (cmd[2] & 0x3ff) + 1; + int height = (cmd[3] & 0x3ff) + 1; + int xscale = (cmd[2] >> 10) & 0x1ff; + int yscale = (cmd[3] >> 10) & 0x1ff; + bool xflip = (cmd[1] & 0x04000000) ? true : false; + bool yflip = (cmd[1] & 0x08000000) ? true : false; + bool alpha_enable = (cmd[1] & 0x30000000) ? true : false; + bool trans_enable = (cmd[1] & 0x40000000) ? true : false; + UINT32 address = cmd[0] & 0xffffff; + int alpha_level = (cmd[2] >> 27) & 0x1f; + bool relative_coords = (cmd[0] & 0x10000000) ? true : false; + + if (relative_coords) + { + x += m_fb_origin_x; + y += m_fb_origin_y; + } - int i, j; - int u, v; - UINT16 *vr = (UINT16*)m_gcu[chip].vram; + UINT16 *vram16 = (UINT16*)m_vram; if (xscale == 0 || yscale == 0) { - xscale = 0x40; - yscale = 0x40; return; } - //if ((cmd[2] >> 24) != 0x84 && (cmd[2] >> 24) != 0x04 && (cmd[2] >> 24) != 0x00) - // printf("Unknown value = %d, %d\n", (cmd[2] >> 27) & 0x1f, (cmd[2] >> 22) & 0x1f); +#if PRINT_GCU + printf("%s Draw Object %08X, x %d, y %d, w %d, h %d [%08X %08X %08X %08X]\n", basetag(), address, x, y, width, height, cmd[0], cmd[1], cmd[2], cmd[3]); +#endif - width = (((width * 65536) / xscale) * 64) / 65536; - height = (((height * 65536) / yscale) * 64) / 65536; + width = (((width * 65536) / xscale) * 64) / 65536; + height = (((height * 65536) / yscale) * 64) / 65536; - if (y > cliprect.max_y || x > cliprect.max_x) { - return; - } - if ((y+height) > cliprect.max_y) { - height = cliprect.max_y - y; - } - if ((x+width) > cliprect.max_x) { - width = cliprect.max_x - x; - } + int fb_pitch = 1024; - v = 0; - for (j=0; j < height; j++) + int v = 0; + for (int j=0; j < height; j++) { - int xi; int index; - UINT16 *d = &bitmap.pix16(j+y, x); - //int index = address + ((v >> 6) * 1024); - + int xinc; + UINT32 fbaddr = ((j+y) * fb_pitch) + x; + if (yflip) { index = address + ((height - 1 - (v >> 6)) * 1024); @@ -359,45 +539,26 @@ void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &clip if (xflip) { - d += width; - xi = -1; + fbaddr += width; + xinc = -1; } else { - xi = 1; + xinc = 1; } - u = 0; - for (i=0; i < width; i++) + int u = 0; + for (int i=0; i < width; i++) { - UINT16 pix = vr[((index + (u >> 6)) ^ 1) & 0xffffff]; - + UINT16 pix = vram16[((index + (u >> 6)) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)) & 0xffffff]; + bool draw = !trans_enable || (trans_enable && (pix & 0x8000)); if (alpha_enable) { - if (pix & 0x8000) + if (draw) { if ((pix & 0x7fff) != 0) { - //*d = pix & 0x7fff; - UINT16 srcpix = *d; - /* - UINT32 r = pix & 0x7c00; - UINT32 g = pix & 0x03e0; - UINT32 b = pix & 0x001f; - - UINT32 sr = srcpix & 0x7c00; - UINT32 sg = srcpix & 0x03e0; - UINT32 sb = srcpix & 0x001f; - - sr += r; - sg += g; - sb += b; - if (sr > 0x7c00) sr = 0x7c00; - if (sg > 0x03e0) sg = 0x03e0; - if (sb > 0x001f) sb = 0x001f; - - *d = sr | sg | sb; - */ + UINT16 srcpix = vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; UINT32 sr = (srcpix >> 10) & 0x1f; UINT32 sg = (srcpix >> 5) & 0x1f; @@ -414,22 +575,19 @@ void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &clip if (sg > 0x1f) sg = 0x1f; if (sb > 0x1f) sb = 0x1f; - *d = (sr << 10) | (sg << 5) | sb; + vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = (sr << 10) | (sg << 5) | sb | 0x8000; } } } else { - if (pix & 0x8000) + if (draw) { - *d = pix & 0x7fff; + vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = pix | 0x8000; } } - if ((cmd[0] & 0x10000000) == 0) - *d = 0x7fff; - - d += xi; + fbaddr += xinc; u += xscale; } @@ -437,56 +595,70 @@ void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &clip } } -void firebeat_state::gcu_fill_rect(bitmap_ind16 &bitmap, const rectangle &cliprect, UINT32 *cmd) +void firebeat_gcu_device::fill_rect(UINT32 *cmd) { - int i, j; - int x1, y1, x2, y2; + // 0x00: xxx----- -------- -------- -------- command (4) + // 0x00: ---x---- -------- -------- -------- 0: absolute coordinates + // 1: relative coordinates from framebuffer origin + // 0x00: ----xx-- -------- -------- -------- ? + // 0x00: -------- -------- ------xx xxxxxxxx width + // 0x00: -------- ----xxxx xxxxxx-- -------- height - int x = cmd[1] & 0x3ff; - int y = (cmd[1] >> 10) & 0x3ff; - int width = (cmd[0] & 0x3ff) + 1; - int height = ((cmd[0] >> 10) & 0x3ff) + 1; + // 0x01: -------- -------- ------xx xxxxxxxx x + // 0x01: -------- xxxxxxxx xxxxxx-- -------- y - UINT16 color[4]; + // 0x02: xxxxxxxx xxxxxxxx -------- -------- fill pattern pixel 0 + // 0x02: -------- -------- xxxxxxxx xxxxxxxx fill pattern pixel 1 - color[0] = (cmd[2] >> 16); - color[1] = (cmd[2] >> 0); - color[2] = (cmd[3] >> 16); - color[3] = (cmd[3] >> 0); + // 0x03: xxxxxxxx xxxxxxxx -------- -------- fill pattern pixel 2 + // 0x03: -------- -------- xxxxxxxx xxxxxxxx fill pattern pixel 3 - x1 = x; - x2 = x + width; - y1 = y; - y2 = y + height; + int x = cmd[1] & 0x3ff; + int y = (cmd[1] >> 10) & 0x3fff; + int width = (cmd[0] & 0x3ff) + 1; + int height = ((cmd[0] >> 10) & 0x3ff) + 1; + bool relative_coords = (cmd[0] & 0x10000000) ? true : false; - if ((color[0] & 0x8000) == 0 && (color[1] & 0x8000) == 0 && (color[2] & 0x8000) == 0 && (color[3] & 0x8000) == 0) + if (relative_coords) { - // optimization, nothing to fill - return; + x += m_fb_origin_x; + y += m_fb_origin_y; } - // clip - if (x1 < cliprect.min_x) x1 = cliprect.min_x; - if (y1 < cliprect.min_y) y1 = cliprect.min_y; - if (x2 > cliprect.max_x) x2 = cliprect.max_x; - if (y2 > cliprect.max_y) y2 = cliprect.max_y; + UINT16 color[4]; + color[0] = (cmd[2] >> 16); + color[1] = (cmd[2] & 0xffff); + color[2] = (cmd[3] >> 16); + color[3] = (cmd[3] & 0xffff); + +#if PRINT_GCU + printf("%s Fill Rect x %d, y %d, w %d, h %d, %08X %08X [%08X %08X %08X %08X]\n", basetag(), x, y, width, height, cmd[2], cmd[3], cmd[0], cmd[1], cmd[2], cmd[3]); +#endif + + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + + UINT16 *vram16 = (UINT16*)m_vram; - for (j=y1; j < y2; j++) + int fb_pitch = 1024; + + for (int j=y1; j < y2; j++) { - UINT16 *d = &bitmap.pix16(j); - for (i=x1; i < x2; i++) + UINT32 fbaddr = j * fb_pitch; + for (int i=x1; i < x2; i++) { - if (color[i&3] & 0x8000) - { - d[i] = color[i&3] & 0x7fff; - } + vram16[(fbaddr+i) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = color[i&3]; } } } -void firebeat_state::gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd) +void firebeat_gcu_device::draw_character(UINT32 *cmd) { - // 0x00: xxx----- -------- -------- -------- command type + // 0x00: xxx----- -------- -------- -------- command (7) + // 0x00: ---x---- -------- -------- -------- 0: absolute coordinates + // 1: relative coordinates from framebuffer base (unverified, should be same as other operations) // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx character data address in vram // 0x01: -------- -------- ------xx xxxxxxxx character x @@ -498,345 +670,316 @@ void firebeat_state::gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &c // 0x03: xxxxxxxx xxxxxxxx -------- -------- color 2 // 0x03: -------- -------- xxxxxxxx xxxxxxxx color 3 - int i, j; - int x = cmd[1] & 0x3ff; - int y = (cmd[1] >> 10) & 0x3ff; - UINT32 address = cmd[0] & 0xffffff; + int x = cmd[1] & 0x3ff; + int y = (cmd[1] >> 10) & 0x3ff; + UINT32 address = cmd[0] & 0xffffff; UINT16 color[4]; + bool relative_coords = (cmd[0] & 0x10000000) ? true : false; - UINT16 *vr = (UINT16*)m_gcu[chip].vram; - - color[0] = (cmd[2] >> 16) & 0xffff; - color[1] = (cmd[2] >> 0) & 0xffff; - color[2] = (cmd[3] >> 16) & 0xffff; - color[3] = (cmd[3] >> 0) & 0xffff; + if (relative_coords) + { + x += m_fb_origin_x; + y += m_fb_origin_y; + } + color[0] = cmd[2] >> 16; + color[1] = cmd[2] & 0xffff; + color[2] = cmd[3] >> 16; + color[3] = cmd[3] & 0xffff; - if (y > cliprect.max_y || x > cliprect.max_x) { - return; - } +#if PRINT_GCU + printf("%s Draw Char %08X, x %d, y %d\n", basetag(), address, x, y); +#endif + UINT16 *vram16 = (UINT16*)m_vram; + int fb_pitch = 1024; - for (j=0; j < 8; j++) + for (int j=0; j < 8; j++) { - UINT16 *d = &bitmap.pix16(y+j, x); - UINT16 line = vr[address^1]; + UINT32 fbaddr = (y+j) * fb_pitch; + UINT16 line = vram16[address ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; address += 4; - for (i=0; i < 8; i++) + for (int i=0; i < 8; i++) { - int pix = (line >> ((7-i) * 2)) & 3; - d[i] = color[pix]; + int p = (line >> ((7-i) * 2)) & 3; + vram16[(fbaddr+x+i) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = color[p] | 0x8000; } } } -void firebeat_state::gcu_exec_display_list(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 address) +void firebeat_gcu_device::fb_config(UINT32 *cmd) +{ + // 0x00: xxx----- -------- -------- -------- command (3) + + // 0x01: -------- -------- -------- -------- unused? + + // 0x02: -------- -------- ------xx xxxxxxxx Framebuffer Origin X + + // 0x03: -------- -------- --xxxxxx xxxxxxxx Framebuffer Origin Y + +#if PRINT_GCU + printf("%s FB Config %08X %08X %08X %08X\n", basetag(), cmd[0], cmd[1], cmd[2], cmd[3]); +#endif + + m_fb_origin_x = cmd[2] & 0x3ff; + m_fb_origin_y = cmd[3] & 0x3fff; +} + +void firebeat_gcu_device::execute_display_list(UINT32 addr) { + bool end = false; + int counter = 0; - int end = 0; - int i = address / 4; - if (i < 0) i = 0; - while (!end && counter < 0x1000 && i < (0x2000000/4)) +#if PRINT_GCU + printf("%s Exec Display List %08X\n", basetag(), addr); +#endif + + addr /= 2; + while (!end && counter < 0x1000 && addr < (0x2000000/4)) { - int command; - UINT32 cmd[4]; - cmd[0] = m_gcu[chip].vram[i+0]; - cmd[1] = m_gcu[chip].vram[i+1]; - cmd[2] = m_gcu[chip].vram[i+2]; - cmd[3] = m_gcu[chip].vram[i+3]; + UINT32 *cmd = &m_vram[addr]; + addr += 4; - command = (cmd[0] >> 29) & 0x7; + int command = (cmd[0] >> 29) & 0x7; switch (command) { - case 0x0: // ??? - { + case 0: // NOP? break; - } - case 0x1: // Branch - { - gcu_exec_display_list(bitmap, cliprect, chip, cmd[0] & 0xffffff); + case 1: // Execute display list + execute_display_list(cmd[0] & 0xffffff); break; - } - case 0x2: // End of display list - { - end = 1; + case 2: // End of display list + end = true; break; - } - case 0x3: // ??? - { + case 3: // Framebuffer config + fb_config(cmd); break; - } - case 0x4: // Fill rectangle - { - gcu_fill_rect(bitmap, cliprect, cmd); + case 4: // Fill rectangle + fill_rect(cmd); break; - } - case 0x5: // Draw object - { - gcu_draw_object(bitmap, cliprect, chip, cmd); + case 5: // Draw object + draw_object(cmd); break; - } - case 0x7: // Draw 8x8 Character (2-bits per pixel) - { - gcu_draw_character(bitmap, cliprect, chip, cmd); + case 7: // Draw 8x8 character (2 bits per pixel) + draw_character(cmd); break; - } default: - //printf("Unknown command %08X %08X %08X %08X at %08X\n", cmd[0], cmd[1], cmd[2], cmd[3], i*4); + printf("GCU Unknown command %08X %08X %08X %08X\n", cmd[0], cmd[1], cmd[2], cmd[3]); break; } - - i += 4; counter++; }; } -UINT32 firebeat_state::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int chip) +void firebeat_gcu_device::execute_command(UINT32* cmd) { - bitmap.fill(0, cliprect); - - if ((core_strnicmp(machine().system().name, "popn", 4) == 0) || (core_strnicmp(machine().system().name, "bm3", 3) == 0)) - { - gcu_exec_display_list( bitmap, cliprect, chip, 0x1f80000); - } - else - { - if (m_layer >= 2) - { - gcu_exec_display_list(bitmap, cliprect, chip, 0x8000); - gcu_exec_display_list(bitmap, cliprect, chip, 0x0000); - gcu_exec_display_list(bitmap, cliprect, chip, 0x10000); - } - else if (m_layer == 0) - { - gcu_exec_display_list(bitmap, cliprect, chip, 0x200000); + int command = (cmd[0] >> 29) & 0x7; - //gcu_exec_display_list(bitmap, cliprect, chip, 0x186040); - } - else if (m_layer == 1) - { - gcu_exec_display_list(bitmap, cliprect, chip, 0x1d0800); - - gcu_exec_display_list(bitmap, cliprect, chip, 0x1a9440); - } - } +#if PRINT_GCU + printf("%s Exec Command %08X, %08X, %08X, %08X\n", basetag(), cmd[0], cmd[1], cmd[2], cmd[3]); +#endif - m_tick++; - if (m_tick >= 5) + switch (command) { - m_tick = 0; - if (machine().input().code_pressed(KEYCODE_0)) - { - m_layer++; - if (m_layer > 2) - { - m_layer = 0; - } - } + case 0: // NOP? + break; - /* - if (machine().input().code_pressed_once(KEYCODE_9)) - { - FILE *file = fopen("vram0.bin", "wb"); - int i; - - for (i=0; i < 0x2000000/4; i++) - { - fputc((m_gcu[0].vram[i] >> 24) & 0xff, file); - fputc((m_gcu[0].vram[i] >> 16) & 0xff, file); - fputc((m_gcu[0].vram[i] >> 8) & 0xff, file); - fputc((m_gcu[0].vram[i] >> 0) & 0xff, file); - } - - fclose(file); - file = fopen("vram1.bin", "wb"); - - for (i=0; i < 0x2000000/4; i++) - { - fputc((m_gcu[1].vram[i] >> 24) & 0xff, file); - fputc((m_gcu[1].vram[i] >> 16) & 0xff, file); - fputc((m_gcu[1].vram[i] >> 8) & 0xff, file); - fputc((m_gcu[1].vram[i] >> 0) & 0xff, file); - } - - fclose(file); - } - */ - } + case 1: // Execute display list + execute_display_list(cmd[0] & 0xffffff); + break; - return 0; -} + case 2: // End of display list + break; -UINT32 firebeat_state::screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 0); } -UINT32 firebeat_state::screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 1); } + case 3: // Framebuffer config + fb_config(cmd); + break; -UINT32 firebeat_state::GCU_r(int chip, UINT32 offset, UINT32 mem_mask) -{ - int reg = offset * 4; + case 4: // Fill rectangle + fill_rect(cmd); + break; - /* VRAM Read */ - if (reg >= 0x80 && reg < 0x100) - { - return m_gcu[chip].vram[m_gcu[chip].vram_read_address + ((reg/4) - 0x20)]; - } + case 5: // Draw object + draw_object(cmd); + break; - switch(reg) - { - case 0x78: /* GCU Status */ - /* ppd checks bits 0x0041 of the upper halfword on interrupt */ - return 0xffff0005; + case 7: // Draw 8x8 character (2 bits per pixel) + draw_character(cmd); + break; default: + printf("GCU Unknown command %08X %08X %08X %08X\n", cmd[0], cmd[1], cmd[2], cmd[3]); break; } +} - return 0xffffffff; +void firebeat_gcu_device::device_start() +{ + m_cpu = machine().device(m_cputag); + + m_vram = auto_alloc_array(machine(), UINT32, 0x2000000/4); + memset(m_vram, 0, 0x2000000); } -void firebeat_state::GCU_w(int chip, UINT32 offset, UINT32 data, UINT32 mem_mask) +void firebeat_gcu_device::device_reset() { - int reg = offset * 4; + m_vram_read_addr = 0; + m_command_fifo0_ptr = 0; + m_command_fifo1_ptr = 0; + m_vram_fifo0_addr = 0; + m_vram_fifo1_addr = 0; - if (reg != 0x70 && chip == 0) + for (int i=0; i < 4; i++) { - //printf("%s:gcu%d_w: %08X, %08X, %08X at %08X\n", machine().describe_context(), chip, data, offset, mem_mask); - //logerror("%s:gcu%d_w: %08X, %08X, %08X at %08X\n", cmachine->describe_context(), hip, data, offset, mem_mask); + m_frame[i].base = 0; + m_frame[i].width = 0; + m_frame[i].height = 0; } +} - switch(reg) +void firebeat_gcu_device::device_stop() +{ +#if DUMP_VRAM + char filename[200]; + sprintf(filename, "%s_vram.bin", basetag()); + printf("dumping %s\n", filename); + FILE *file = fopen(filename, "wb"); + int i; + + for (i=0; i < 0x2000000/4; i++) { - case 0x10: /* ??? */ - /* IRQ clear/enable; ppd writes bit off then on in response to interrupt */ - /* it enables bits 0x41, but 0x01 seems to be the one it cares about */ - if (ACCESSING_BITS_16_31 && (data & 0x0001) == 0) - m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); - break; - - case 0x30: - //case 0x34: - //case 0x38: - //case 0x3c: - { - COMBINE_DATA( &m_gcu[chip].visible_area ); - if (ACCESSING_BITS_0_15) - { - screen_device_iterator iter(machine().root_device()); - screen_device *screen = iter.byindex(chip); - - if (screen != NULL) - { - rectangle visarea = screen->visible_area(); - int width, height; - - width = (m_gcu[chip].visible_area & 0xffff); - height = (m_gcu[chip].visible_area >> 16) & 0xffff; - - visarea.max_x = width-1; - visarea.max_y = height-1; + fputc((m_vram[i] >> 24) & 0xff, file); + fputc((m_vram[i] >> 16) & 0xff, file); + fputc((m_vram[i] >> 8) & 0xff, file); + fputc((m_vram[i] >> 0) & 0xff, file); + } + + fclose(file); +#endif +} - screen->configure(visarea.max_x + 1, visarea.max_y + 1, visarea, screen->frame_period().attoseconds); - } - } - break; - } - case 0x40: /* framebuffer config */ - // HACK: switch display lists at the right times for the ParaParaParadise games until we - // do the video emulation properly - if (core_strnicmp(machine().system().name, "pp", 2) == 0) - { - switch (data) - { - case 0x00080000: // post - m_layer = 0; - break; - - case 0x00008400: // startup tests - if (m_layer != 2) - { - m_layer = 1; - } - break; - - case 0x00068400: // game & svc menu - m_layer = 2; - break; - } - } - else if (core_strnicmp(machine().system().name, "kbm", 3) == 0) - { - switch (data) - { - case 0x00080000: // post - m_layer = 0; - break; - case 0x0000c400: // game & svn menu - m_layer = 2; - break; - } - } - break; - //case 0x44: /* ??? */ - // break; - case 0x5c: /* VRAM Read Address */ - m_gcu[chip].vram_read_address = (data & 0xffffff) / 2; - break; +class firebeat_state : public driver_device +{ +public: + firebeat_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_work_ram(*this, "work_ram"), + m_flash_main(*this, "flash_main"), + m_flash_snd1(*this, "flash_snd1"), + m_flash_snd2(*this, "flash_snd2"), + m_duart_midi(*this, "duart_midi"), + m_duart_com(*this, "duart_com"), + m_kbd0(*this, "kbd0"), + m_kbd1(*this, "kbd1"), + m_ata(*this, "ata"), + m_gcu0(*this, "gcu0"), + m_gcu1(*this, "gcu1") + { } - case 0x60: /* VRAM FIFO Write Address */ - m_gcu[chip].vram_write_fifo_address = (data & 0xffffff) / 2; + required_device<ppc4xx_device> m_maincpu; + required_shared_ptr<UINT32> m_work_ram; + required_device<fujitsu_29f016a_device> m_flash_main; + required_device<fujitsu_29f016a_device> m_flash_snd1; + required_device<fujitsu_29f016a_device> m_flash_snd2; + optional_device<pc16552_device> m_duart_midi; + required_device<pc16552_device> m_duart_com; + optional_device<midi_keyboard_device> m_kbd0; + optional_device<midi_keyboard_device> m_kbd1; + required_device<ata_interface_device> m_ata; + required_device<firebeat_gcu_device> m_gcu0; + required_device<firebeat_gcu_device> m_gcu1; - // printf("gcu%d_w: %08X, %08X, %08X\n", chip, data, offset, mem_mask); - break; + UINT8 m_extend_board_irq_enable; + UINT8 m_extend_board_irq_active; +// emu_timer *m_keyboard_timer; + int m_tick; + int m_layer; + int m_cab_data_ptr; + const int * m_cur_cab_data; +// int m_keyboard_state[2]; + UINT8 m_spu_shared_ram[0x400]; + IBUTTON m_ibutton; + int m_ibutton_state; + int m_ibutton_read_subkey_ptr; + UINT8 m_ibutton_subkey_data[0x40]; + DECLARE_READ8_MEMBER(soundram_r); + DECLARE_DRIVER_INIT(ppd); + DECLARE_DRIVER_INIT(kbm); + DECLARE_DRIVER_INIT(ppp); + DECLARE_MACHINE_START(firebeat); + DECLARE_MACHINE_RESET(firebeat); + DECLARE_VIDEO_START(firebeat); + UINT32 screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + UINT32 screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(firebeat_interrupt); + DECLARE_READ32_MEMBER(input_r); + DECLARE_READ32_MEMBER(sensor_r ); + DECLARE_READ32_MEMBER(flashram_r); + DECLARE_WRITE32_MEMBER(flashram_w); + DECLARE_READ32_MEMBER(soundflash_r); + DECLARE_WRITE32_MEMBER(soundflash_w); + DECLARE_WRITE_LINE_MEMBER(ata_interrupt); + DECLARE_READ32_MEMBER(ata_command_r); + DECLARE_WRITE32_MEMBER(ata_command_w); + DECLARE_READ32_MEMBER(ata_control_r); + DECLARE_WRITE32_MEMBER(ata_control_w); +// DECLARE_READ32_MEMBER(comm_uart_r); +// DECLARE_WRITE32_MEMBER(comm_uart_w); + DECLARE_READ32_MEMBER(cabinet_r); + DECLARE_READ32_MEMBER(keyboard_wheel_r); + DECLARE_READ8_MEMBER(midi_uart_r); + DECLARE_WRITE8_MEMBER(midi_uart_w); + DECLARE_READ32_MEMBER(extend_board_irq_r); + DECLARE_WRITE32_MEMBER(extend_board_irq_w); + DECLARE_WRITE32_MEMBER(lamp_output_w); + DECLARE_WRITE32_MEMBER(lamp_output_kbm_w); + DECLARE_WRITE32_MEMBER(lamp_output_ppp_w); + DECLARE_WRITE32_MEMBER(lamp_output2_w); + DECLARE_WRITE32_MEMBER(lamp_output2_ppp_w); + DECLARE_WRITE32_MEMBER(lamp_output3_w); + DECLARE_WRITE32_MEMBER(lamp_output3_ppp_w); + DECLARE_READ32_MEMBER(ppc_spu_share_r); + DECLARE_WRITE32_MEMBER(ppc_spu_share_w); + DECLARE_READ16_MEMBER(spu_unk_r); +// TIMER_CALLBACK_MEMBER(keyboard_timer_callback); + void set_ibutton(UINT8 *data); + int ibutton_w(UINT8 data); + DECLARE_WRITE8_MEMBER(security_w); + void init_lights(write32_delegate out1, write32_delegate out2, write32_delegate out3); + void init_firebeat(); + void init_keyboard(); + DECLARE_WRITE_LINE_MEMBER(sound_irq_callback); + DECLARE_WRITE_LINE_MEMBER(midi_uart_ch0_irq_callback); + DECLARE_WRITE_LINE_MEMBER(midi_uart_ch1_irq_callback); +}; - case 0x68: /* Unknown */ - { - break; - } - case 0x70: /* VRAM FIFO Write */ - m_gcu[chip].vram[m_gcu[chip].vram_write_fifo_address] = data; - m_gcu[chip].vram_write_fifo_address++; - break; - default: - // printf("gcu%d_w: %08X, %08X, %08X\n", chip, data, offset, mem_mask); - break; - } -} -READ32_MEMBER(firebeat_state::gcu0_r) -{ - return GCU_r(0, offset, mem_mask); -} -WRITE32_MEMBER(firebeat_state::gcu0_w) -{ - GCU_w(0, offset, data, mem_mask); -} -READ32_MEMBER(firebeat_state::gcu1_r) +VIDEO_START_MEMBER(firebeat_state,firebeat) { - return GCU_r(1, offset, mem_mask); } -WRITE32_MEMBER(firebeat_state::gcu1_w) -{ - GCU_w(1, offset, data, mem_mask); -} +UINT32 firebeat_state::screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu0->draw(screen, bitmap, cliprect); } +UINT32 firebeat_state::screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu1->draw(screen, bitmap, cliprect); } /*****************************************************************************/ @@ -1508,8 +1651,8 @@ static ADDRESS_MAP_START( firebeat_map, AS_PROGRAM, 32, firebeat_state ) AM_RANGE(0x7dc00000, 0x7dc0000f) AM_DEVREADWRITE8("duart_com", pc16552_device, read, write, 0xffffffff) AM_RANGE(0x7e000000, 0x7e00003f) AM_DEVREADWRITE8("rtc", rtc65271_device, rtc_r, rtc_w, 0xffffffff) AM_RANGE(0x7e000100, 0x7e00013f) AM_DEVREADWRITE8("rtc", rtc65271_device, xram_r, xram_w, 0xffffffff) - AM_RANGE(0x7e800000, 0x7e8000ff) AM_READWRITE(gcu0_r, gcu0_w) - AM_RANGE(0x7e800100, 0x7e8001ff) AM_READWRITE(gcu1_r, gcu1_w) + AM_RANGE(0x7e800000, 0x7e8000ff) AM_DEVREADWRITE("gcu0", firebeat_gcu_device, read, write) + AM_RANGE(0x7e800100, 0x7e8001ff) AM_DEVREADWRITE("gcu1", firebeat_gcu_device, read, write) AM_RANGE(0x7fe00000, 0x7fe0000f) AM_READWRITE(ata_command_r, ata_command_w) AM_RANGE(0x7fe80000, 0x7fe8000f) AM_READWRITE(ata_control_r, ata_control_w) AM_RANGE(0x7ff80000, 0x7fffffff) AM_ROM AM_REGION("user1", 0) /* System BIOS */ @@ -1724,6 +1867,12 @@ static MACHINE_CONFIG_START( firebeat, firebeat_state ) /* video hardware */ MCFG_PALETTE_ADD_RRRRRGGGGGBBBBB("palette") + MCFG_DEVICE_ADD("gcu0", FIREBEAT_GCU, 0) + MCFG_FIREBEAT_GCU_CPU_TAG("maincpu") + + MCFG_DEVICE_ADD("gcu1", FIREBEAT_GCU, 0) + MCFG_FIREBEAT_GCU_CPU_TAG("maincpu") + MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) @@ -1778,6 +1927,12 @@ static MACHINE_CONFIG_START( firebeat2, firebeat_state ) /* video hardware */ MCFG_PALETTE_ADD_RRRRRGGGGGBBBBB("palette") + MCFG_DEVICE_ADD("gcu0", FIREBEAT_GCU, 0) + MCFG_FIREBEAT_GCU_CPU_TAG("maincpu") + + MCFG_DEVICE_ADD("gcu1", FIREBEAT_GCU, 0) + MCFG_FIREBEAT_GCU_CPU_TAG("maincpu") + MCFG_SCREEN_ADD("lscreen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) diff --git a/src/mame/drivers/suprloco.c b/src/mame/drivers/suprloco.c index 2779544ffa9..7ac0c12c437 100644 --- a/src/mame/drivers/suprloco.c +++ b/src/mame/drivers/suprloco.c @@ -52,7 +52,8 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, suprloco_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( decrypted_opcodes_map, AS_DECRYPTED_OPCODES, 8, suprloco_state ) - AM_RANGE(0x0000, 0xbfff) AM_ROM AM_SHARE("decrypted_opcodes") + AM_RANGE(0x0000, 0x7fff) AM_ROM AM_SHARE("decrypted_opcodes") + AM_RANGE(0x8000, 0xbfff) AM_ROM AM_REGION("maincpu", 0x8000) ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, suprloco_state ) @@ -319,7 +320,7 @@ DRIVER_INIT_MEMBER(suprloco_state,suprloco) }; /* decrypt program ROMs */ - sega_decode(memregion("maincpu")->base(), m_decrypted_opcodes, 0xc000, convtable); + sega_decode(memregion("maincpu")->base(), m_decrypted_opcodes, 0x8000, convtable); } diff --git a/src/mess/drivers/m20.c b/src/mess/drivers/m20.c index 652a1b77bbd..5dd4d00503e 100644 --- a/src/mess/drivers/m20.c +++ b/src/mess/drivers/m20.c @@ -47,8 +47,10 @@ E I1 Vectored interrupt error #include "machine/pit8253.h" #include "machine/pic8259.h" #include "formats/m20_dsk.h" +#include "formats/pc_dsk.h" #include "machine/m20_kbd.h" #include "bus/rs232/rs232.h" +#include "machine/m20_8086.h" class m20_state : public driver_device { @@ -64,6 +66,7 @@ public: m_fd1797(*this, "fd1797"), m_floppy0(*this, "fd1797:0:5dd"), m_floppy1(*this, "fd1797:1:5dd"), + m_apb(*this, "apb"), m_p_videoram(*this, "p_videoram"), m_palette(*this, "palette") { @@ -78,6 +81,7 @@ public: required_device<fd1797_t> m_fd1797; required_device<floppy_image_device> m_floppy0; required_device<floppy_image_device> m_floppy1; + optional_device<m20_8086_device> m_apb; required_shared_ptr<UINT16> m_p_videoram; required_device<palette_device> m_palette; @@ -92,6 +96,8 @@ public: DECLARE_WRITE_LINE_MEMBER(tty_clock_tick_w); DECLARE_WRITE_LINE_MEMBER(kbd_clock_tick_w); DECLARE_WRITE_LINE_MEMBER(timer_tick_w); + DECLARE_WRITE_LINE_MEMBER(halt_apb_w); + DECLARE_WRITE_LINE_MEMBER(int_w); private: offs_t m_memsize; @@ -226,7 +232,9 @@ WRITE_LINE_MEMBER( m20_state::timer_tick_w ) * 8253 is programmed in square wave mode, not rate * generator mode. */ - m_maincpu->set_input_line(0, state ? HOLD_LINE /*ASSERT_LINE*/ : CLEAR_LINE); + if(m_apb) + m_apb->nvi_w(state); + m_maincpu->set_input_line(INPUT_LINE_IRQ0, state ? HOLD_LINE /*ASSERT_LINE*/ : CLEAR_LINE); } @@ -714,24 +722,9 @@ static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state) AM_RANGE(0x140, 0x143) AM_READWRITE(m20_i8259_r, m20_i8259_w) + AM_RANGE(0x3ffa, 0x3ffd) AM_DEVWRITE("apb", m20_8086_device, handshake_w) ADDRESS_MAP_END -#if 0 -static ADDRESS_MAP_START(m20_apb_mem, AS_PROGRAM, 16, m20_state) - ADDRESS_MAP_UNMAP_HIGH - AM_RANGE( 0x00000, 0x007ff ) AM_RAM - AM_RANGE( 0xf0000, 0xf7fff ) AM_RAM //mirrored? - AM_RANGE( 0xfc000, 0xfffff ) AM_ROM AM_REGION("apb_bios",0) -ADDRESS_MAP_END - -static ADDRESS_MAP_START(m20_apb_io, AS_IO, 16, m20_state) - ADDRESS_MAP_UNMAP_HIGH - ADDRESS_MAP_GLOBAL_MASK(0xff) // may not be needed - //0x4060 crtc address - //0x4062 crtc data -ADDRESS_MAP_END -#endif - IRQ_CALLBACK_MEMBER(m20_state::m20_irq_callback) { if (! irqline) @@ -740,6 +733,13 @@ IRQ_CALLBACK_MEMBER(m20_state::m20_irq_callback) return m_i8259->acknowledge(); } +WRITE_LINE_MEMBER(m20_state::int_w) +{ + if(m_apb && !m_apb->halted()) + m_apb->vi_w(state); + m_maincpu->set_input_line(INPUT_LINE_IRQ1, state ? ASSERT_LINE : CLEAR_LINE); +} + void m20_state::machine_start() { install_memory(); @@ -762,6 +762,8 @@ void m20_state::machine_reset() memcpy(RAM, ROM, 8); // we need only the reset vector m_maincpu->reset(); // reset the CPU to ensure it picks up the new vector + if(m_apb) + m_apb->m_8086->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); } @@ -770,7 +772,8 @@ static SLOT_INTERFACE_START( m20_floppies ) SLOT_INTERFACE_END FLOPPY_FORMATS_MEMBER( m20_state::floppy_formats ) - FLOPPY_M20_FORMAT + FLOPPY_M20_FORMAT, + FLOPPY_PC_FORMAT FLOPPY_FORMATS_END static SLOT_INTERFACE_START(keyboard) @@ -790,13 +793,6 @@ static MACHINE_CONFIG_START( m20, m20_state ) MCFG_RAM_DEFAULT_VALUE(0) MCFG_RAM_EXTRA_OPTIONS("128K,192K,224K,256K,384K,512K") -#if 0 - MCFG_CPU_ADD("apb", I8086, MAIN_CLOCK) - MCFG_CPU_PROGRAM_MAP(m20_apb_mem) - MCFG_CPU_IO_MAP(m20_apb_io) - MCFG_DEVICE_DISABLE() -#endif - /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) @@ -832,11 +828,13 @@ static MACHINE_CONFIG_START( m20, m20_state ) MCFG_PIT8253_CLK2(1230782) MCFG_PIT8253_OUT2_HANDLER(WRITELINE(m20_state, timer_tick_w)) - MCFG_PIC8259_ADD("i8259", INPUTLINE("maincpu", 1), VCC, NULL) + MCFG_PIC8259_ADD("i8259", WRITELINE(m20_state, int_w), VCC, NULL) MCFG_RS232_PORT_ADD("kbd", keyboard, "m20") MCFG_RS232_RXD_HANDLER(DEVWRITELINE("i8251_1", i8251_device, write_rxd)) + MCFG_DEVICE_ADD("apb", M20_8086, 0) + MCFG_SOFTWARE_LIST_ADD("flop_list","m20") MACHINE_CONFIG_END diff --git a/src/mess/machine/m20_8086.c b/src/mess/machine/m20_8086.c new file mode 100644 index 00000000000..5c817b17edf --- /dev/null +++ b/src/mess/machine/m20_8086.c @@ -0,0 +1,119 @@ +// license:BSD-3-Clause +// copyright-holders:Carl +#include "m20_8086.h" +#include "machine/ram.h" + +const device_type M20_8086 = &device_creator<m20_8086_device>; + +m20_8086_device::m20_8086_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, M20_8086, "Olivetti M20 8086 Adapter", tag, owner, clock, "m20_8086", __FILE__), + m_8086(*this, "8086"), + m_maincpu(*this, ":maincpu"), + m_pic(*this, ":i8259"), + m_8086_halt(true) +{ +} + +void m20_8086_device::device_start() +{ + UINT8* ram = machine().device<ram_device>("ram")->pointer(); + m_8086->space(AS_PROGRAM).install_readwrite_bank(0x00000, machine().device<ram_device>("ram")->size() - 0x4001, "mainram"); + membank("highram")->set_base(ram); + membank("mainram")->set_base(&ram[0x4000]); + membank("vram")->set_base(memshare(":p_videoram")->ptr()); + membank("vram2")->set_base(memshare(":p_videoram")->ptr()); +} + +void m20_8086_device::device_reset() +{ + m_8086_halt = true; + m_nvi = m_vi = 0; + m_8086->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); +} + +ROM_START( m20_8086 ) + ROM_REGION(0x4000, "8086", 0) + ROM_LOAD("apb-1086-2.0.bin", 0x0000, 0x4000, CRC(8c05be93) SHA1(2bb424afd874cc6562e9642780eaac2391308053)) +ROM_END + + +const rom_entry *m20_8086_device::device_rom_region() const +{ + return ROM_NAME( m20_8086 ); +} + +static ADDRESS_MAP_START(i86_prog, AS_PROGRAM, 16, m20_8086_device) + AM_RANGE(0xe0000, 0xe3fff) AM_RAMBANK("vram2") + AM_RANGE(0xf0000, 0xf3fff) AM_RAMBANK("highram") + AM_RANGE(0xf4000, 0xf7fff) AM_RAMBANK("vram") + AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION("8086",0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START(i86_io, AS_IO, 16, m20_8086_device) + AM_RANGE(0x4000, 0x4fff) AM_READWRITE(z8000_io_r, z8000_io_w) + AM_RANGE(0x7ffa, 0x7ffd) AM_WRITE(handshake_w) +ADDRESS_MAP_END + +static MACHINE_CONFIG_FRAGMENT( m20_8086 ) + MCFG_CPU_ADD("8086", I8086, XTAL_24MHz/3) + MCFG_CPU_PROGRAM_MAP(i86_prog) + MCFG_CPU_IO_MAP(i86_io) + MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(m20_8086_device, int_cb) +MACHINE_CONFIG_END + +machine_config_constructor m20_8086_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( m20_8086 ); +} + +READ16_MEMBER(m20_8086_device::z8000_io_r) +{ + return m_maincpu->space(AS_IO).read_word(offset << 1, mem_mask); +} + +WRITE16_MEMBER(m20_8086_device::z8000_io_w) +{ + m_maincpu->space(AS_IO).write_word(offset << 1, data, mem_mask); +} + +IRQ_CALLBACK_MEMBER(m20_8086_device::int_cb) +{ + if(m_nvi) + { + m_nvi = false; + m_8086->set_input_line(INPUT_LINE_IRQ0, m_vi ? ASSERT_LINE : CLEAR_LINE); + return 0xff; + } + else + return m_pic->acknowledge() << 1; +} + +WRITE_LINE_MEMBER(m20_8086_device::nvi_w) +{ + m_nvi = state; + m_8086->set_input_line(INPUT_LINE_IRQ0, (state || m_vi) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(m20_8086_device::vi_w) +{ + m_vi = state; + m_8086->set_input_line(INPUT_LINE_IRQ0, (state || m_nvi) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE16_MEMBER(m20_8086_device::handshake_w) +{ + if(!offset) + { + m_8086->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); + m_8086_halt = true; + } + else + { + m_8086->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + m_8086->set_input_line(INPUT_LINE_RESET, PULSE_LINE); + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_8086_halt = false; + } +} diff --git a/src/mess/machine/m20_8086.h b/src/mess/machine/m20_8086.h new file mode 100644 index 00000000000..148ba808c0a --- /dev/null +++ b/src/mess/machine/m20_8086.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:Carl +#ifndef M20_8086_H_ +#define M20_8086_H_ + +#include "emu.h" +#include "cpu/i86/i86.h" +#include "machine/pic8259.h" + +class m20_8086_device : public device_t +{ +public: + m20_8086_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + + DECLARE_READ16_MEMBER(z8000_io_r); + DECLARE_WRITE16_MEMBER(z8000_io_w); + DECLARE_WRITE_LINE_MEMBER(vi_w); + DECLARE_WRITE_LINE_MEMBER(nvi_w); + DECLARE_WRITE16_MEMBER(handshake_w); + IRQ_CALLBACK_MEMBER(int_cb); + bool halted() { return m_8086_halt; } + required_device<cpu_device> m_8086; + +protected: + void device_start(); + void device_reset(); + +private: + required_device<cpu_device> m_maincpu; + required_device<pic8259_device> m_pic; + bool m_8086_halt; + int m_nvi, m_vi; +}; + +extern const device_type M20_8086; + +#endif /* M20_8086_H_ */ |