diff --git a/scripts/target/mess/mess.lua b/scripts/target/mess/mess.lua index 176e84aa75a..a15af28b02b 100644 --- a/scripts/target/mess/mess.lua +++ b/scripts/target/mess/mess.lua @@ -1875,6 +1875,7 @@ files { MAME_DIR .. "src/mess/drivers/m20.c", MAME_DIR .. "src/mess/drivers/m24.c", MAME_DIR .. "src/mess/machine/m24_kbd.c", + MAME_DIR .. "src/mess/machine/m24_z8000.c" } createMESSProjects(_target, _subtarget, "omnibyte") diff --git a/src/emu/bus/isa/cga.c b/src/emu/bus/isa/cga.c index c296158e9da..c18a4c38940 100644 --- a/src/emu/bus/isa/cga.c +++ b/src/emu/bus/isa/cga.c @@ -844,7 +844,7 @@ MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_2bpp_update_row ) if ( y == 0 ) CGA_LOG(1,"cga_gfx_2bpp_update_row",("\n")); for ( i = 0; i < x_count; i++ ) { - UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( y & 1 ) << 13 ); + UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( ra & 1 ) << 13 ); UINT8 data = videoram[ offset ]; *p = palette[m_palette_lut_2bpp[ ( data >> 6 ) & 0x03 ]]; p++; @@ -1888,3 +1888,122 @@ const rom_entry *isa8_cga_mc1502_device::device_rom_region() const { return ROM_NAME( mc1502 ); } + +const device_type ISA8_CGA_M24 = &device_creator; + +isa8_cga_m24_device::isa8_cga_m24_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + isa8_cga_device( mconfig, ISA8_CGA_M24, "Olivetti M24 CGA", tag, owner, clock, "cga_m24", __FILE__) +{ + m_vram_size = 0x8000; +} + +void isa8_cga_m24_device::device_reset() +{ + isa8_cga_device::device_reset(); + m_mode2 = 0; + m_start_offset = 0; +} + +WRITE8_MEMBER( isa8_cga_m24_device::io_write ) +{ + mc6845_device *mc6845 = subdevice(CGA_MC6845_NAME); + switch(offset) + { + case 0: case 2: case 4: case 6: + m_index = data; + mc6845->address_w( space, offset, data ); + break; + case 1: case 3: case 5: case 7: + switch(m_index & 0x1f) // TODO: this is handled by a pal and prom + { + case 0: + data &= 0x7f; + break; + case 9: + if((data < 0x80) && (data != 3)) + data = (data << 1) + 1; + break; + case 10: + data = ((data << 1) & 0x1f) | (data & 0x60); + break; + case 11: + data <<= 1; + break; + } + mc6845->register_w( space, offset, data ); + break; + case 0x0e: + m_mode2 = data; + if((data & 8) && !(data & 1)) + m_start_offset = 0x4000; + else + m_start_offset = 0; + break; + default: + isa8_cga_device::io_write(space, offset, data); + break; + } +} + +READ8_MEMBER( isa8_cga_m24_device::io_read ) +{ + UINT8 data = 0xff; + + switch(offset) + { + case 0x0a: + data = 0xc0 | m_vsync | ( ( data & 0x40 ) >> 4 ) | m_hsync; // 0xc0 == no expansion + break; + case 0x0e: + data = m_mode2; + break; + default: + data = isa8_cga_device::io_read(space, offset); + break; + } + return data; +} + +MC6845_UPDATE_ROW( isa8_cga_m24_device::crtc_update_row ) +{ + if(m_mode2 & 1) + m24_gfx_1bpp_m24_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + else + isa8_cga_device::crtc_update_row(bitmap, cliprect, ma, ra >> 1, y, x_count, cursor_x, de, hbp, vbp); +} + +MC6845_UPDATE_ROW( isa8_cga_m24_device::m24_gfx_1bpp_m24_update_row ) +{ + UINT8 *videoram = &m_vram[m_start_offset]; + UINT32 *p = &bitmap.pix32(y); + const rgb_t *palette = m_palette->palette()->entry_list_raw(); + UINT8 fg = m_color_select & 0x0F; + int i; + + if ( y == 0 ) CGA_LOG(1,"m24_gfx_1bpp_m24_update_row",("\n")); + for ( i = 0; i < x_count; i++ ) + { + UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( ra & 3 ) << 13 ); + UINT8 data = videoram[ offset ]; + + *p = palette[( data & 0x80 ) ? fg : 0]; p++; + *p = palette[( data & 0x40 ) ? fg : 0]; p++; + *p = palette[( data & 0x20 ) ? fg : 0]; p++; + *p = palette[( data & 0x10 ) ? fg : 0]; p++; + *p = palette[( data & 0x08 ) ? fg : 0]; p++; + *p = palette[( data & 0x04 ) ? fg : 0]; p++; + *p = palette[( data & 0x02 ) ? fg : 0]; p++; + *p = palette[( data & 0x01 ) ? fg : 0]; p++; + + data = videoram[ offset + 1 ]; + + *p = palette[( data & 0x80 ) ? fg : 0]; p++; + *p = palette[( data & 0x40 ) ? fg : 0]; p++; + *p = palette[( data & 0x20 ) ? fg : 0]; p++; + *p = palette[( data & 0x10 ) ? fg : 0]; p++; + *p = palette[( data & 0x08 ) ? fg : 0]; p++; + *p = palette[( data & 0x04 ) ? fg : 0]; p++; + *p = palette[( data & 0x02 ) ? fg : 0]; p++; + *p = palette[( data & 0x01 ) ? fg : 0]; p++; + } +} diff --git a/src/emu/bus/isa/cga.h b/src/emu/bus/isa/cga.h index cf889c4c22f..9f5c9227676 100644 --- a/src/emu/bus/isa/cga.h +++ b/src/emu/bus/isa/cga.h @@ -260,4 +260,25 @@ public: extern const device_type ISA8_CGA_MC1502; +class isa8_cga_m24_device : + public isa8_cga_device +{ +public: + // construction/destruction + isa8_cga_m24_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + // optional information overrides + //virtual const rom_entry *device_rom_region() const; + virtual DECLARE_READ8_MEMBER( io_read ); + virtual DECLARE_WRITE8_MEMBER( io_write ); + virtual MC6845_UPDATE_ROW( crtc_update_row ); + MC6845_UPDATE_ROW( m24_gfx_1bpp_m24_update_row ); +protected: + virtual void device_reset(); +private: + UINT8 m_mode2, m_index; +}; + +// device type definition +extern const device_type ISA8_CGA_M24; + #endif /* __ISA_CGA_H__ */ diff --git a/src/emu/bus/isa/isa_cards.c b/src/emu/bus/isa/isa_cards.c index ad287f9b0b9..4f1d133644b 100644 --- a/src/emu/bus/isa/isa_cards.c +++ b/src/emu/bus/isa/isa_cards.c @@ -15,6 +15,7 @@ SLOT_INTERFACE_START( pc_isa8_cards ) SLOT_INTERFACE("cga_ec1841", ISA8_EC1841_0002) SLOT_INTERFACE("cga_poisk2", ISA8_CGA_POISK2) SLOT_INTERFACE("cga_mc1502", ISA8_CGA_MC1502) + SLOT_INTERFACE("cga_m24", ISA8_CGA_M24) SLOT_INTERFACE("aga", ISA8_AGA) SLOT_INTERFACE("aga_pc200", ISA8_AGA_PC200) SLOT_INTERFACE("ega", ISA8_EGA) diff --git a/src/emu/cpu/z8000/z8000.c b/src/emu/cpu/z8000/z8000.c index 924313481ec..ae15b0dad81 100644 --- a/src/emu/cpu/z8000/z8000.c +++ b/src/emu/cpu/z8000/z8000.c @@ -72,6 +72,7 @@ z8002_device::z8002_device(const machine_config &mconfig, const char *tag, devic : cpu_device(mconfig, Z8002, "Z8002", tag, owner, clock, "z8002", __FILE__) , m_program_config("program", ENDIANNESS_BIG, 16, 16, 0) , m_io_config("io", ENDIANNESS_BIG, 8, 16, 0) + , m_mo_out(*this) , m_vector_mult(1) { } @@ -81,6 +82,7 @@ z8002_device::z8002_device(const machine_config &mconfig, device_type type, cons : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) , m_program_config("program", ENDIANNESS_BIG, 16, 20, 0) , m_io_config("io", ENDIANNESS_BIG, 16, 16, 0) + , m_mo_out(*this) , m_vector_mult(2) { } @@ -316,8 +318,8 @@ UINT8 z8002_device::RDPORT_B(int mode, UINT16 addr) } else { - /* how to handle MMU reads? */ - return 0x00; + /* how to handle MMU reads? for now just do it */ + return m_io->read_byte(addr); } } @@ -356,7 +358,8 @@ void z8002_device::WRPORT_B(int mode, UINT16 addr, UINT8 value) } else { - /* how to handle MMU writes? */ + /* how to handle MMU writes? for now just do it */ + m_io->write_byte(addr,value); } } @@ -701,6 +704,8 @@ void z8001_device::device_start() register_debug_state(); m_icountptr = &m_icount; + m_mo_out.resolve_safe(); + m_mi = CLEAR_LINE; } void z8002_device::device_start() @@ -726,6 +731,8 @@ void z8002_device::device_start() register_debug_state(); m_icountptr = &m_icount; + m_mo_out.resolve_safe(); + m_mi = CLEAR_LINE; } void z8001_device::device_reset() diff --git a/src/emu/cpu/z8000/z8000.h b/src/emu/cpu/z8000/z8000.h index 20a15ee6738..5eacb5c8e85 100644 --- a/src/emu/cpu/z8000/z8000.h +++ b/src/emu/cpu/z8000/z8000.h @@ -26,6 +26,8 @@ enum #define Z8000_SYSCALL 0x0200 /* system call (lsb is vector) */ #define Z8000_HALT 0x0100 /* halted flag */ +#define MCFG_Z8000_MO(_devcb) \ + devcb = &z8002_device::set_mo_callback(*device, DEVCB_##_devcb); class z8002_device : public cpu_device { @@ -35,6 +37,9 @@ public: z8002_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); ~z8002_device(); + template static devcb_base &set_mo_callback(device_t &device, _Object object) { return downcast(device).m_mo_out.set_callback(object); } + DECLARE_WRITE_LINE_MEMBER(mi_w) { m_mi = state; } // XXX: this has to apply in the middle of an insn for now + protected: // device-level overrides virtual void device_start(); @@ -69,6 +74,7 @@ protected: address_space_config m_program_config; address_space_config m_io_config; + devcb_write_line m_mo_out; UINT32 m_op[4]; /* opcodes/data of current instruction */ UINT32 m_ppc; /* previous program counter */ @@ -91,6 +97,7 @@ protected: } m_regs; /* registers */ int m_nmi_state; /* NMI line state */ int m_irq_state[2]; /* IRQ line states (NVI, VI) */ + int m_mi; address_space *m_program; address_space *m_data; direct_read_data *m_direct; diff --git a/src/emu/cpu/z8000/z8000ops.inc b/src/emu/cpu/z8000/z8000ops.inc index 69cbddd97aa..cfb83557fae 100644 --- a/src/emu/cpu/z8000/z8000ops.inc +++ b/src/emu/cpu/z8000/z8000ops.inc @@ -4674,6 +4674,24 @@ void z8002_device::Z7B_dddd_1101() { CHECK_PRIVILEGED_INSTR(); /* test mu-I line, invert cascade to mu-0 */ + if (m_mi) + { + CLR_Z; + CLR_S; + m_mo_out(CLEAR_LINE); + return; + } + SET_Z; + m_mo_out(ASSERT_LINE); + if (m_mi) + { + SET_S; + } + else + { + CLR_S; + m_mo_out(CLEAR_LINE); + } } /****************************************** diff --git a/src/emu/machine/upd765.c b/src/emu/machine/upd765.c index 84aa7e1ae85..2e19c8a2cb1 100644 --- a/src/emu/machine/upd765.c +++ b/src/emu/machine/upd765.c @@ -379,7 +379,7 @@ void upd765_family_device::set_rate(int rate) READ8_MEMBER(upd765_family_device::fifo_r) { - UINT8 r = 0; + UINT8 r = 0xff; switch(main_phase) { case PHASE_EXEC: if(internal_drq) diff --git a/src/mess/drivers/m24.c b/src/mess/drivers/m24.c index b29edcf54ae..d1423898e53 100644 --- a/src/mess/drivers/m24.c +++ b/src/mess/drivers/m24.c @@ -5,6 +5,7 @@ #include "bus/isa/isa.h" #include "bus/isa/isa_cards.h" #include "machine/m24_kbd.h" +#include "machine/m24_z8000.h" #include "machine/mm58274c.h" #include "includes/genpc.h" @@ -16,12 +17,14 @@ public: m_maincpu(*this, "maincpu"), m_mb(*this, "mb"), m_kbc(*this, "kbc"), - m_keyboard(*this, "keyboard") + m_keyboard(*this, "keyboard"), + m_z8000_apb(*this, "z8000_apb") { } required_device m_maincpu; required_device m_mb; required_device m_kbc; required_device m_keyboard; + optional_device m_z8000_apb; DECLARE_READ8_MEMBER(keyboard_r); DECLARE_WRITE8_MEMBER(keyboard_w); @@ -30,11 +33,14 @@ public: DECLARE_READ8_MEMBER(kbcdata_r); DECLARE_WRITE8_MEMBER(kbcdata_w); DECLARE_WRITE_LINE_MEMBER(kbcin_w); + DECLARE_WRITE_LINE_MEMBER(dma_hrq_w); + DECLARE_WRITE_LINE_MEMBER(int_w); + DECLARE_WRITE_LINE_MEMBER(halt_i86_w); void machine_reset(); UINT8 m_sysctl, m_pa, m_kbcin, m_kbcout; - bool m_kbcibf, m_kbdata; + bool m_kbcibf, m_kbdata, m_i86_halt, m_i86_halt_perm; }; void m24_state::machine_reset() @@ -43,6 +49,10 @@ void m24_state::machine_reset() m_pa = 0x40; m_kbcibf = false; m_kbdata = true; + m_i86_halt = false; + m_i86_halt_perm = false; + if(m_z8000_apb) + m_z8000_apb->m_z8000->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); } READ8_MEMBER(m24_state::keyboard_r) @@ -81,6 +91,10 @@ WRITE8_MEMBER(m24_state::keyboard_w) else m_pa &= ~4; break; + case 5: + m_maincpu->set_input_line(INPUT_LINE_HALT, (data & 0x40) ? ASSERT_LINE : CLEAR_LINE); + m_i86_halt = true; + m_i86_halt_perm = true; } } @@ -115,6 +129,33 @@ WRITE_LINE_MEMBER(m24_state::kbcin_w) m_kbdata = state; } +WRITE_LINE_MEMBER(m24_state::dma_hrq_w) +{ + if(!m_i86_halt) + m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); + if(m_z8000_apb && !m_z8000_apb->halted()) + m_z8000_apb->m_z8000->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); + + /* Assert HLDA */ + m_mb->m_dma8237->hack_w(state); +} + +WRITE_LINE_MEMBER(m24_state::int_w) +{ + if(!m_i86_halt) + m_maincpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); + if(m_z8000_apb && !m_z8000_apb->halted()) + m_z8000_apb->m_z8000->set_input_line(INPUT_LINE_IRQ1, state ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(m24_state::halt_i86_w) +{ + if(m_i86_halt_perm) + return; + m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); + m_i86_halt = state ? true : false; +} + static ADDRESS_MAP_START( m24_map, AS_PROGRAM, 16, m24_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000, 0x9ffff) AM_RAMBANK("bank10") @@ -127,6 +168,7 @@ static ADDRESS_MAP_START(m24_io, AS_IO, 16, m24_state ) AM_RANGE(0x0060, 0x0065) AM_READWRITE8(keyboard_r, keyboard_w, 0xffff) AM_RANGE(0x0066, 0x0067) AM_READ_PORT("DSW0") AM_RANGE(0x0070, 0x007f) AM_DEVREADWRITE8("mm58174an", mm58274c_device, read, write, 0xffff) + AM_RANGE(0x80c0, 0x80c1) AM_DEVREADWRITE8("z8000_apb", m24_z8000_device, handshake_r, handshake_w, 0xff00) ADDRESS_MAP_END static ADDRESS_MAP_START(kbc_map, AS_PROGRAM, 8, m24_state) @@ -191,10 +233,14 @@ static MACHINE_CONFIG_START( olivetti, m24_state ) MCFG_PCNOPPI_MOTHERBOARD_ADD("mb", "maincpu") - MCFG_ISA8_SLOT_ADD("mb:isa", "isa1", pc_isa8_cards, "cga", false) - MCFG_ISA8_SLOT_ADD("mb:isa", "isa2", pc_isa8_cards, "fdc_xt", false) - MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "lpt", false) - MCFG_ISA8_SLOT_ADD("mb:isa", "isa4", pc_isa8_cards, "com", false) + MCFG_ISA8_SLOT_ADD("mb:isa", "mb1", pc_isa8_cards, "cga_m24", true) + MCFG_ISA8_SLOT_ADD("mb:isa", "mb2", pc_isa8_cards, "fdc_xt", true) + MCFG_ISA8_SLOT_ADD("mb:isa", "mb3", pc_isa8_cards, "lpt", true) + MCFG_ISA8_SLOT_ADD("mb:isa", "mb4", pc_isa8_cards, "com", true) + + MCFG_ISA8_SLOT_ADD("mb:isa", "isa1", pc_isa8_cards, NULL, false) + MCFG_ISA8_SLOT_ADD("mb:isa", "isa2", pc_isa8_cards, NULL, false) + MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, NULL, false) /* internal ram */ MCFG_RAM_ADD(RAM_TAG) @@ -211,6 +257,13 @@ static MACHINE_CONFIG_START( olivetti, m24_state ) MCFG_MM58274C_MODE24(1) // ? MCFG_MM58274C_DAY1(1) // ? + MCFG_DEVICE_ADD("z8000_apb", M24_Z8000, 0) + MCFG_M24_Z8000_HALT(WRITELINE(m24_state, halt_i86_w)) + MCFG_DEVICE_MODIFY("mb:dma8237") + MCFG_I8237_OUT_HREQ_CB(DEVWRITELINE(":", m24_state, dma_hrq_w)) + MCFG_DEVICE_MODIFY("mb:pic8259") + devcb = &pic8259_device::static_set_out_int_callback(*device, DEVCB_DEVWRITELINE(":", m24_state, int_w)); + /* software lists */ MCFG_SOFTWARE_LIST_ADD("disk_list","ibm5150") MACHINE_CONFIG_END diff --git a/src/mess/machine/m24_z8000.c b/src/mess/machine/m24_z8000.c new file mode 100644 index 00000000000..540d47ddfb1 --- /dev/null +++ b/src/mess/machine/m24_z8000.c @@ -0,0 +1,227 @@ +#include "m24_z8000.h" + +const device_type M24_Z8000 = &device_creator; + +m24_z8000_device::m24_z8000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, M24_Z8000, "Olivetti M24 Z8000 Adapter", tag, owner, clock, "m24_z8000", __FILE__), + m_z8000(*this, "z8000"), + m_maincpu(*this, ":maincpu"), + m_pic(*this, ":mb:pic8259"), + m_halt_out(*this), + m_z8000_halt(true) +{ +} + +void m24_z8000_device::device_start() +{ + m_halt_out.resolve_safe(); +} + +void m24_z8000_device::device_reset() +{ + m_z8000_halt = true; + m_z8000_mem = false; + m_timer_irq = false; + m_irq = 0; + m_z8000->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); +} + +ROM_START( m24_z8000 ) + ROM_REGION(0x4000, "z8000", 0) + ROM_LOAD("m24apb.bin", 0x0000, 0x4000, CRC(3b3d2895) SHA1(ff048cf61b090b147be7e29a929a0be7b3ac8409)) +ROM_END + + +const rom_entry *m24_z8000_device::device_rom_region() const +{ + return ROM_NAME( m24_z8000 ); +} + +static ADDRESS_MAP_START(z8000_prog, AS_PROGRAM, 16, m24_z8000_device) + AM_RANGE(0x40000, 0x43fff) AM_ROM AM_REGION("z8000", 0) + AM_RANGE(0x50000, 0x53fff) AM_ROM AM_REGION("z8000", 0) + AM_RANGE(0x70000, 0x73fff) AM_ROM AM_REGION("z8000", 0) + AM_RANGE(0x00000, 0xfffff) AM_READWRITE(pmem_r, pmem_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START(z8000_data, AS_DATA, 16, m24_z8000_device) + AM_RANGE(0x40000, 0x43fff) AM_ROM AM_REGION("z8000", 0) + AM_RANGE(0x70000, 0x73fff) AM_ROM AM_REGION("z8000", 0) + AM_RANGE(0x00000, 0xfffff) AM_READWRITE(dmem_r, dmem_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START(z8000_io, AS_IO, 16, m24_z8000_device) + AM_RANGE(0x0080, 0x0081) AM_WRITE8(irqctl_w, 0x00ff) + AM_RANGE(0x00a0, 0x00a1) AM_WRITE8(serctl_w, 0x00ff) + AM_RANGE(0x00c0, 0x00c1) AM_DEVREADWRITE8("i8251", i8251_device, data_r, data_w, 0x00ff) + AM_RANGE(0x00c2, 0x00c3) AM_DEVREADWRITE8("i8251", i8251_device, status_r, control_w, 0x00ff) + AM_RANGE(0x0120, 0x0127) AM_DEVREADWRITE8("pit8253", pit8253_device, read, write, 0x00ff) + AM_RANGE(0x80c0, 0x80c1) AM_READWRITE8(handshake_r, handshake_w, 0x00ff) + AM_RANGE(0x8000, 0x83ff) AM_READWRITE(i86_io_r, i86_io_w) +ADDRESS_MAP_END + +static MACHINE_CONFIG_FRAGMENT( m24_z8000 ) + MCFG_CPU_ADD("z8000", Z8001, XTAL_8MHz/2) + MCFG_CPU_PROGRAM_MAP(z8000_prog) + MCFG_CPU_DATA_MAP(z8000_data) + MCFG_CPU_IO_MAP(z8000_io) + MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(m24_z8000_device, int_cb) + MCFG_Z8000_MO(WRITELINE(m24_z8000_device, mo_w)) + + MCFG_DEVICE_ADD("pit8253", PIT8253, 0) + MCFG_PIT8253_CLK0(19660000/15) + MCFG_PIT8253_OUT0_HANDLER(NULL) //8251 + MCFG_PIT8253_CLK1(19660000/15) + MCFG_PIT8253_OUT1_HANDLER(NULL) + MCFG_PIT8253_CLK2(19660000/15) + MCFG_PIT8253_OUT2_HANDLER(WRITELINE(m24_z8000_device, timer_irq_w)) + + MCFG_DEVICE_ADD("i8251", I8251, 0) +MACHINE_CONFIG_END + +machine_config_constructor m24_z8000_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( m24_z8000 ); +} + +const UINT8 m24_z8000_device::pmem_table[16][4] = + {{0, 1, 2, 3}, {1, 2, 3, 255}, {4, 5, 6, 7}, {46, 40, 41, 42}, + {255, 255, 255, 255}, {255, 255, 255, 47}, {1, 2, 3, 255}, {255, 255, 255, 255}, + {1, 2, 8, 9}, {5, 6, 10, 11}, {1, 2, 8, 9}, {12, 13, 14, 15}, + {16, 17, 18, 19}, {20, 21, 22, 23}, {24, 25, 26, 27}, {28, 29, 30, 31}}; + +READ16_MEMBER(m24_z8000_device::pmem_r) +{ + UINT16 ret; + UINT8 hostseg; + offset <<= 1; + if(!m_z8000_mem) + return memregion(subtag("z8000").c_str())->u16(offset >> 1); + + hostseg = pmem_table[(offset >> 16) & 0xf][(offset >> 14) & 3]; + if(hostseg == 255) + return 0; + offset = (offset & 0x3fff) | (hostseg << 14); + if((hostseg >= 40) && (hostseg <= 47)) + offset = (offset & 0xf0000) | BITSWAP16(offset,15,7,6,14,13,12,11,10,9,8,5,4,3,2,1,0); // move A6/A7 so CGA framebuffer appears linear + ret = m_maincpu->space(AS_PROGRAM).read_word(offset, (mem_mask << 8) | (mem_mask >> 8)); + return (ret << 8) | (ret >> 8); +} + +WRITE16_MEMBER(m24_z8000_device::pmem_w) +{ + UINT8 hostseg; + data = (data << 8) | (data >> 8); + offset <<= 1; + hostseg = pmem_table[(offset >> 16) & 0xf][(offset >> 14) & 3]; + if(hostseg == 255) + return; + offset = (offset & 0x3fff) | (hostseg << 14); + if((hostseg >= 40) && (hostseg <= 47)) + offset = (offset & 0xf0000) | BITSWAP16(offset,15,7,6,14,13,12,11,10,9,8,5,4,3,2,1,0); + m_maincpu->space(AS_PROGRAM).write_word(offset, data, (mem_mask << 8) | (mem_mask >> 8)); +} + +const UINT8 m24_z8000_device::dmem_table[16][4] = + {{0, 1, 2, 3}, {4, 5, 6, 7}, {4, 5, 6, 7}, {46, 40, 41, 42}, + {255, 255, 255, 255}, {1, 2, 3, 47}, {1, 2, 3, 255}, {255, 255, 255, 255}, + {5, 6, 10, 11}, {5, 6, 10, 11}, {1, 2, 8, 9}, {12, 13, 14, 15}, + {16, 17, 18, 19}, {20, 21, 22, 23}, {24, 25, 26, 27}, {28, 29, 30, 31}}; + +READ16_MEMBER(m24_z8000_device::dmem_r) +{ + UINT16 ret; + UINT8 hostseg; + offset <<= 1; + hostseg = dmem_table[(offset >> 16) & 0xf][(offset >> 14) & 3]; + if(hostseg == 255) + return 0; + offset = (offset & 0x3fff) | (hostseg << 14); + if((hostseg >= 40) && (hostseg <= 47)) + offset = (offset & 0xf0000) | BITSWAP16(offset,15,7,6,14,13,12,11,10,9,8,5,4,3,2,1,0); + ret = m_maincpu->space(AS_PROGRAM).read_word(offset, (mem_mask << 8) | (mem_mask >> 8)); + return (ret << 8) | (ret >> 8); +} + +WRITE16_MEMBER(m24_z8000_device::dmem_w) +{ + UINT8 hostseg; + data = (data << 8) | (data >> 8); + offset <<= 1; + hostseg = dmem_table[(offset >> 16) & 0xf][(offset >> 14) & 3]; + if(hostseg == 255) + return; + offset = (offset & 0x3fff) | (hostseg << 14); + if((hostseg >= 40) && (hostseg <= 47)) + offset = (offset & 0xf0000) | BITSWAP16(offset,15,7,6,14,13,12,11,10,9,8,5,4,3,2,1,0); + m_maincpu->space(AS_PROGRAM).write_word(offset, data, (mem_mask << 8) | (mem_mask >> 8)); +} + +READ16_MEMBER(m24_z8000_device::i86_io_r) +{ + UINT16 ret = m_maincpu->space(AS_IO).read_word(offset << 1, (mem_mask << 8) | (mem_mask >> 8)); + return (ret << 8) | (ret >> 8); +} + +WRITE16_MEMBER(m24_z8000_device::i86_io_w) +{ + data = (data << 8) | (data >> 8); + m_maincpu->space(AS_IO).write_word(offset << 1, data, (mem_mask << 8) | (mem_mask >> 8)); +} + +WRITE8_MEMBER(m24_z8000_device::irqctl_w) +{ + m_irq = data; +} + +WRITE8_MEMBER(m24_z8000_device::serctl_w) +{ + m_z8000_mem = (data & 0x20) ? true : false; +} + +IRQ_CALLBACK_MEMBER(m24_z8000_device::int_cb) +{ + if (!irqline) + { + m_z8000->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); + return 0xff; // NVI, value ignored + } + else + return m_pic->acknowledge(); +} + +READ8_MEMBER(m24_z8000_device::handshake_r) +{ + return 0; +} + +WRITE8_MEMBER(m24_z8000_device::handshake_w) +{ + m_handshake = data; + if(data & 1) + { + m_z8000->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + m_z8000->set_input_line(INPUT_LINE_RESET, PULSE_LINE); + m_z8000->mi_w(CLEAR_LINE); + m_z8000_halt = false; + } + else + { + m_z8000->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_z8000_halt = true; + m_z8000_mem = false; + m_halt_out(CLEAR_LINE); + } +} + +WRITE_LINE_MEMBER(m24_z8000_device::mo_w) +{ + m_z8000->mi_w(state ? ASSERT_LINE : CLEAR_LINE); + m_halt_out(state); +} + +WRITE_LINE_MEMBER(m24_z8000_device::timer_irq_w) +{ + m_timer_irq = state ? true : false; + m_z8000->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); +} diff --git a/src/mess/machine/m24_z8000.h b/src/mess/machine/m24_z8000.h new file mode 100644 index 00000000000..1d27f882dd6 --- /dev/null +++ b/src/mess/machine/m24_z8000.h @@ -0,0 +1,54 @@ +#ifndef M24_Z8000_H_ +#define M24_Z8000_H_ + +#include "emu.h" +#include "cpu/z8000/z8000.h" +#include "machine/i8251.h" +#include "machine/pit8253.h" +#include "machine/pic8259.h" + +#define MCFG_M24_Z8000_HALT(_devcb) \ + devcb = &m24_z8000_device::set_halt_callback(*device, DEVCB_##_devcb); + +class m24_z8000_device : public device_t +{ +public: + m24_z8000_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; + template static devcb_base &set_halt_callback(device_t &device, _Object object) { return downcast(device).m_halt_out.set_callback(object); } + + DECLARE_READ16_MEMBER(pmem_r); + DECLARE_WRITE16_MEMBER(pmem_w); + DECLARE_READ16_MEMBER(dmem_r); + DECLARE_WRITE16_MEMBER(dmem_w); + DECLARE_READ16_MEMBER(i86_io_r); + DECLARE_WRITE16_MEMBER(i86_io_w); + DECLARE_WRITE8_MEMBER(irqctl_w); + DECLARE_WRITE8_MEMBER(serctl_w); + DECLARE_READ8_MEMBER(handshake_r); + DECLARE_WRITE8_MEMBER(handshake_w); + DECLARE_WRITE_LINE_MEMBER(mo_w); + DECLARE_WRITE_LINE_MEMBER(timer_irq_w); + IRQ_CALLBACK_MEMBER(int_cb); + bool halted() { return m_z8000_halt; } + + required_device m_z8000; +protected: + void device_start(); + void device_reset(); + +private: + required_device m_maincpu; + required_device m_pic; + devcb_write_line m_halt_out; + static const UINT8 pmem_table[16][4]; + static const UINT8 dmem_table[16][4]; + UINT8 m_handshake, m_irq; + bool m_z8000_halt, m_z8000_mem, m_timer_irq; +}; + +extern const device_type M24_Z8000; + +#endif /* M24_Z8000_H_ */