(mess) m24: add z8000 apb support [Carl]

isa_cga: m24 640x400x1 mode (nw)
upd765: return 0xff when reading from fifo while busy (nw)
z8000: mreq instruction and the apb expects sout to work just like out (nw)
This commit is contained in:
cracyc 2015-04-29 21:03:52 -05:00
parent 29fdb4d27c
commit 3c886dfe12
11 changed files with 519 additions and 11 deletions

View File

@ -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")

View File

@ -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::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<mc6845_device>(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++;
}
}

View File

@ -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__ */

View File

@ -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)

View File

@ -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()

View File

@ -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<class _Object> static devcb_base &set_mo_callback(device_t &device, _Object object) { return downcast<z8002_device &>(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;

View File

@ -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);
}
}
/******************************************

View File

@ -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)

View File

@ -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<cpu_device> m_maincpu;
required_device<pc_noppi_mb_device> m_mb;
required_device<cpu_device> m_kbc;
required_device<m24_keyboard_device> m_keyboard;
optional_device<m24_z8000_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

View File

@ -0,0 +1,227 @@
#include "m24_z8000.h"
const device_type M24_Z8000 = &device_creator<m24_z8000_device>;
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);
}

View File

@ -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<class _Object> static devcb_base &set_halt_callback(device_t &device, _Object object) { return downcast<m24_z8000_device &>(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<z8001_device> m_z8000;
protected:
void device_start();
void device_reset();
private:
required_device<cpu_device> m_maincpu;
required_device<pic8259_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_ */