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 ATTR_COLD void matrix_solver_direct_t::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; jname().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,6 +160,717 @@ struct IBUTTON IBUTTON_SUBKEY subkey[3]; }; +#define MCFG_FIREBEAT_GCU_CPU_TAG(_tag) \ + firebeat_gcu_device::static_set_cpu_tag(*device, _tag); + +class firebeat_gcu_device : public device_t +{ +public: + 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(device).m_cputag = tag; } + + int draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + 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(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; +} + +WRITE32_MEMBER(firebeat_gcu_device::write) +{ + 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; + } + + fbaddr0++; + fbaddr1++; +// fbaddr2++; +// fbaddr3++; + } + } + + return 0; +} + +void firebeat_gcu_device::draw_object(UINT32 *cmd) +{ + // 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: -------- xxxxxxxx xxxxxx-- -------- object y + // 0x01: -----x-- -------- -------- -------- object x flip + // 0x01: ----x--- -------- -------- -------- object y flip + // 0x01: --xx---- -------- -------- -------- object alpha enable (different blend modes?) + // 0x01: -x------ -------- -------- -------- object transparency enable (?) + + // 0x02: -------- -------- ------xx xxxxxxxx object width + // 0x02: -------- -----xxx xxxxxx-- -------- object x scale + + // 0x03: -------- -------- ------xx xxxxxxxx object height + // 0x03: -------- -----xxx xxxxxx-- -------- object y scale + + 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; + } + + UINT16 *vram16 = (UINT16*)m_vram; + + if (xscale == 0 || yscale == 0) + { + return; + } + +#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; + + int fb_pitch = 1024; + + int v = 0; + for (int j=0; j < height; j++) + { + int index; + int xinc; + UINT32 fbaddr = ((j+y) * fb_pitch) + x; + + if (yflip) + { + index = address + ((height - 1 - (v >> 6)) * 1024); + } + else + { + index = address + ((v >> 6) * 1024); + } + + if (xflip) + { + fbaddr += width; + xinc = -1; + } + else + { + xinc = 1; + } + + int u = 0; + for (int i=0; i < width; i++) + { + 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 (draw) + { + if ((pix & 0x7fff) != 0) + { + UINT16 srcpix = vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; + + UINT32 sr = (srcpix >> 10) & 0x1f; + UINT32 sg = (srcpix >> 5) & 0x1f; + UINT32 sb = (srcpix >> 0) & 0x1f; + UINT32 r = (pix >> 10) & 0x1f; + UINT32 g = (pix >> 5) & 0x1f; + UINT32 b = (pix >> 0) & 0x1f; + + sr += (r * alpha_level) >> 4; + sg += (g * alpha_level) >> 4; + sb += (b * alpha_level) >> 4; + + if (sr > 0x1f) sr = 0x1f; + if (sg > 0x1f) sg = 0x1f; + if (sb > 0x1f) sb = 0x1f; + + vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = (sr << 10) | (sg << 5) | sb | 0x8000; + } + } + } + else + { + if (draw) + { + vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = pix | 0x8000; + } + } + + fbaddr += xinc; + u += xscale; + } + + v += yscale; + } +} + +void firebeat_gcu_device::fill_rect(UINT32 *cmd) +{ + // 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 + + // 0x01: -------- -------- ------xx xxxxxxxx x + // 0x01: -------- xxxxxxxx xxxxxx-- -------- y + + // 0x02: xxxxxxxx xxxxxxxx -------- -------- fill pattern pixel 0 + // 0x02: -------- -------- xxxxxxxx xxxxxxxx fill pattern pixel 1 + + // 0x03: xxxxxxxx xxxxxxxx -------- -------- fill pattern pixel 2 + // 0x03: -------- -------- xxxxxxxx xxxxxxxx fill pattern pixel 3 + + 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 (relative_coords) + { + x += m_fb_origin_x; + y += m_fb_origin_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; + + int fb_pitch = 1024; + + for (int j=y1; j < y2; j++) + { + UINT32 fbaddr = j * fb_pitch; + for (int i=x1; i < x2; i++) + { + vram16[(fbaddr+i) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = color[i&3]; + } + } +} + +void firebeat_gcu_device::draw_character(UINT32 *cmd) +{ + // 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 + // 0x01: -------- ----xxxx xxxxxx-- -------- character y + + // 0x02: xxxxxxxx xxxxxxxx -------- -------- color 0 + // 0x02: -------- -------- xxxxxxxx xxxxxxxx color 1 + + // 0x03: xxxxxxxx xxxxxxxx -------- -------- color 2 + // 0x03: -------- -------- xxxxxxxx xxxxxxxx color 3 + + 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; + + 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 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 (int j=0; j < 8; j++) + { + UINT32 fbaddr = (y+j) * fb_pitch; + UINT16 line = vram16[address ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)]; + + address += 4; + + for (int i=0; i < 8; i++) + { + int p = (line >> ((7-i) * 2)) & 3; + vram16[(fbaddr+x+i) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = color[p] | 0x8000; + } + } +} + +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; + +#if PRINT_GCU + printf("%s Exec Display List %08X\n", basetag(), addr); +#endif + + addr /= 2; + while (!end && counter < 0x1000 && addr < (0x2000000/4)) + { + UINT32 *cmd = &m_vram[addr]; + addr += 4; + + int command = (cmd[0] >> 29) & 0x7; + + switch (command) + { + case 0: // NOP? + break; + + case 1: // Execute display list + execute_display_list(cmd[0] & 0xffffff); + break; + + case 2: // End of display list + end = true; + break; + + case 3: // Framebuffer config + fb_config(cmd); + break; + + case 4: // Fill rectangle + fill_rect(cmd); + break; + + case 5: // Draw object + draw_object(cmd); + break; + + 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; + } + counter++; + }; +} + +void firebeat_gcu_device::execute_command(UINT32* cmd) +{ + int command = (cmd[0] >> 29) & 0x7; + +#if PRINT_GCU + printf("%s Exec Command %08X, %08X, %08X, %08X\n", basetag(), cmd[0], cmd[1], cmd[2], cmd[3]); +#endif + + switch (command) + { + case 0: // NOP? + break; + + case 1: // Execute display list + execute_display_list(cmd[0] & 0xffffff); + break; + + case 2: // End of display list + break; + + case 3: // Framebuffer config + fb_config(cmd); + break; + + case 4: // Fill rectangle + fill_rect(cmd); + break; + + case 5: // Draw object + draw_object(cmd); + break; + + 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; + } +} + +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_gcu_device::device_reset() +{ + 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; + + for (int i=0; i < 4; i++) + { + m_frame[i].base = 0; + m_frame[i].width = 0; + m_frame[i].height = 0; + } +} + +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++) + { + 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 +} + + + class firebeat_state : public driver_device @@ -180,7 +887,9 @@ public: m_duart_com(*this, "duart_com"), m_kbd0(*this, "kbd0"), m_kbd1(*this, "kbd1"), - m_ata(*this, "ata") + m_ata(*this, "ata"), + m_gcu0(*this, "gcu0"), + m_gcu1(*this, "gcu1") { } required_device m_maincpu; @@ -193,11 +902,12 @@ public: optional_device m_kbd0; optional_device m_kbd1; required_device m_ata; + required_device m_gcu0; + required_device m_gcu1; 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; @@ -218,10 +928,6 @@ public: 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); @@ -252,13 +958,6 @@ public: 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); @@ -277,566 +976,10 @@ public: VIDEO_START_MEMBER(firebeat_state,firebeat) { - 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); } - -void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd) -{ - // 0x00: xxx----- -------- -------- -------- command type - // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx object data address in vram - - // 0x01: -------- -------- ------xx xxxxxxxx object x - // 0x01: -------- ----xxxx xxxxxx-- -------- object y - // 0x01: -----x-- -------- -------- -------- object x flip - // 0x01: ----x--- -------- -------- -------- object y flip - // 0x01: ---x---- -------- -------- -------- object alpha enable (?) - - // 0x02: -------- -------- ------xx xxxxxxxx object width - // 0x02: -------- -----xxx xxxxxx-- -------- object x scale - - // 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 i, j; - int u, v; - UINT16 *vr = (UINT16*)m_gcu[chip].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); - - 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; - } - - v = 0; - for (j=0; j < height; j++) - { - int xi; - int index; - UINT16 *d = &bitmap.pix16(j+y, x); - //int index = address + ((v >> 6) * 1024); - - if (yflip) - { - index = address + ((height - 1 - (v >> 6)) * 1024); - } - else - { - index = address + ((v >> 6) * 1024); - } - - if (xflip) - { - d += width; - xi = -1; - } - else - { - xi = 1; - } - - u = 0; - for (i=0; i < width; i++) - { - UINT16 pix = vr[((index + (u >> 6)) ^ 1) & 0xffffff]; - - if (alpha_enable) - { - if (pix & 0x8000) - { - 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; - */ - - UINT32 sr = (srcpix >> 10) & 0x1f; - UINT32 sg = (srcpix >> 5) & 0x1f; - UINT32 sb = (srcpix >> 0) & 0x1f; - UINT32 r = (pix >> 10) & 0x1f; - UINT32 g = (pix >> 5) & 0x1f; - UINT32 b = (pix >> 0) & 0x1f; - - sr += (r * alpha_level) >> 4; - sg += (g * alpha_level) >> 4; - sb += (b * alpha_level) >> 4; - - if (sr > 0x1f) sr = 0x1f; - if (sg > 0x1f) sg = 0x1f; - if (sb > 0x1f) sb = 0x1f; - - *d = (sr << 10) | (sg << 5) | sb; - } - } - } - else - { - if (pix & 0x8000) - { - *d = pix & 0x7fff; - } - } - - if ((cmd[0] & 0x10000000) == 0) - *d = 0x7fff; - - d += xi; - u += xscale; - } - - v += yscale; - } -} - -void firebeat_state::gcu_fill_rect(bitmap_ind16 &bitmap, const rectangle &cliprect, UINT32 *cmd) -{ - int i, j; - int x1, y1, x2, y2; - - int x = cmd[1] & 0x3ff; - int y = (cmd[1] >> 10) & 0x3ff; - int width = (cmd[0] & 0x3ff) + 1; - int height = ((cmd[0] >> 10) & 0x3ff) + 1; - - UINT16 color[4]; - - color[0] = (cmd[2] >> 16); - color[1] = (cmd[2] >> 0); - color[2] = (cmd[3] >> 16); - color[3] = (cmd[3] >> 0); - - x1 = x; - x2 = x + width; - y1 = y; - y2 = y + height; - - if ((color[0] & 0x8000) == 0 && (color[1] & 0x8000) == 0 && (color[2] & 0x8000) == 0 && (color[3] & 0x8000) == 0) - { - // optimization, nothing to fill - return; - } - - // 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; - - for (j=y1; j < y2; j++) - { - UINT16 *d = &bitmap.pix16(j); - for (i=x1; i < x2; i++) - { - if (color[i&3] & 0x8000) - { - d[i] = color[i&3] & 0x7fff; - } - } - } -} - -void firebeat_state::gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd) -{ - // 0x00: xxx----- -------- -------- -------- command type - // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx character data address in vram - - // 0x01: -------- -------- ------xx xxxxxxxx character x - // 0x01: -------- ----xxxx xxxxxx-- -------- character y - - // 0x02: xxxxxxxx xxxxxxxx -------- -------- color 0 - // 0x02: -------- -------- xxxxxxxx xxxxxxxx color 1 - - // 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; - UINT16 color[4]; - - 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 (y > cliprect.max_y || x > cliprect.max_x) { - return; - } - - - for (j=0; j < 8; j++) - { - UINT16 *d = &bitmap.pix16(y+j, x); - UINT16 line = vr[address^1]; - - address += 4; - - for (i=0; i < 8; i++) - { - int pix = (line >> ((7-i) * 2)) & 3; - d[i] = color[pix]; - } - } -} - -void firebeat_state::gcu_exec_display_list(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 address) -{ - int counter = 0; - int end = 0; - - int i = address / 4; - if (i < 0) i = 0; - while (!end && counter < 0x1000 && i < (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]; - - command = (cmd[0] >> 29) & 0x7; - - switch (command) - { - case 0x0: // ??? - { - break; - } - - case 0x1: // Branch - { - gcu_exec_display_list(bitmap, cliprect, chip, cmd[0] & 0xffffff); - break; - } - - case 0x2: // End of display list - { - end = 1; - break; - } - - case 0x3: // ??? - { - break; - } - - case 0x4: // Fill rectangle - { - gcu_fill_rect(bitmap, cliprect, cmd); - break; - } - - case 0x5: // Draw object - { - gcu_draw_object(bitmap, cliprect, chip, cmd); - break; - } - - case 0x7: // Draw 8x8 Character (2-bits per pixel) - { - gcu_draw_character(bitmap, cliprect, chip, cmd); - break; - } - - default: - //printf("Unknown command %08X %08X %08X %08X at %08X\n", cmd[0], cmd[1], cmd[2], cmd[3], i*4); - break; - } - - i += 4; - counter++; - }; -} - -UINT32 firebeat_state::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int chip) -{ - 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); - - //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); - } - } - - m_tick++; - if (m_tick >= 5) - { - m_tick = 0; - if (machine().input().code_pressed(KEYCODE_0)) - { - m_layer++; - if (m_layer > 2) - { - m_layer = 0; - } - } - - /* - 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); - } - */ - } - - return 0; -} - -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); } - -UINT32 firebeat_state::GCU_r(int chip, UINT32 offset, UINT32 mem_mask) -{ - int reg = offset * 4; - - /* VRAM Read */ - if (reg >= 0x80 && reg < 0x100) - { - return m_gcu[chip].vram[m_gcu[chip].vram_read_address + ((reg/4) - 0x20)]; - } - - switch(reg) - { - case 0x78: /* GCU Status */ - /* ppd checks bits 0x0041 of the upper halfword on interrupt */ - return 0xffff0005; - - default: - break; - } - - return 0xffffffff; -} - -void firebeat_state::GCU_w(int chip, UINT32 offset, UINT32 data, UINT32 mem_mask) -{ - int reg = offset * 4; - - if (reg != 0x70 && chip == 0) - { - //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); - } - - 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 & 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; - - 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; - - case 0x60: /* VRAM FIFO Write Address */ - m_gcu[chip].vram_write_fifo_address = (data & 0xffffff) / 2; - - // printf("gcu%d_w: %08X, %08X, %08X\n", chip, data, offset, mem_mask); - break; - - 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) -{ - 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 m_fd1797; required_device m_floppy0; required_device m_floppy1; + optional_device m_apb; required_shared_ptr m_p_videoram; required_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(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")->pointer(); + m_8086->space(AS_PROGRAM).install_readwrite_bank(0x00000, machine().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 m_8086; + +protected: + void device_start(); + void device_reset(); + +private: + required_device m_maincpu; + required_device m_pic; + bool m_8086_halt; + int m_nvi, m_vi; +}; + +extern const device_type M20_8086; + +#endif /* M20_8086_H_ */