mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
(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:
parent
29fdb4d27c
commit
3c886dfe12
@ -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")
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
227
src/mess/machine/m24_z8000.c
Normal file
227
src/mess/machine/m24_z8000.c
Normal 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);
|
||||
}
|
54
src/mess/machine/m24_z8000.h
Normal file
54
src/mess/machine/m24_z8000.h
Normal 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_ */
|
Loading…
Reference in New Issue
Block a user