diff --git a/src/mess/drivers/mz3500.c b/src/mess/drivers/mz3500.c index 44c1366ee13..56fd7933ae4 100644 --- a/src/mess/drivers/mz3500.c +++ b/src/mess/drivers/mz3500.c @@ -28,6 +28,8 @@ public: UINT8 *m_work_ram; UINT8 *m_shared_ram; + UINT8 m_ma,m_mo,m_ms,m_me2,m_me1; + DECLARE_READ8_MEMBER(mz3500_master_mem_r); DECLARE_WRITE8_MEMBER(mz3500_master_mem_w); DECLARE_READ8_MEMBER(mz3500_ipl_r); @@ -36,6 +38,8 @@ public: DECLARE_WRITE8_MEMBER(mz3500_work_ram_w); DECLARE_READ8_MEMBER(mz3500_shared_ram_r); DECLARE_WRITE8_MEMBER(mz3500_shared_ram_w); + DECLARE_READ8_MEMBER(mz3500_io_r); + DECLARE_WRITE8_MEMBER(mz3500_io_w); // screen updates UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -81,26 +85,121 @@ WRITE8_MEMBER(mz3500_state::mz3500_work_ram_w) READ8_MEMBER(mz3500_state::mz3500_master_mem_r) { - if((offset & 0xe000) == 0x0000) { return mz3500_ipl_r(space,(offset & 0xfff) | 0x1000); } - if((offset & 0xe000) == 0x2000) { return mz3500_basic_r(space,offset & 0x1fff); } - if((offset & 0xe000) == 0x4000) { return mz3500_work_ram_r(space,(offset & 0x1fff) | 0x4000); } - if((offset & 0xe000) == 0x6000) { return mz3500_work_ram_r(space,(offset & 0x1fff) | 0x6000); } - if((offset & 0xe000) == 0x8000) { return mz3500_work_ram_r(space,(offset & 0x1fff) | 0x8000); } - if((offset & 0xe000) == 0xa000) { return mz3500_work_ram_r(space,(offset & 0x1fff) | 0xa000); } - if((offset & 0xe000) == 0xc000) { return mz3500_work_ram_r(space,(offset & 0x1fff) | 0xc000); } - if((offset & 0xe000) == 0xe000) { return mz3500_work_ram_r(space,(offset & 0x1fff) | 0xe000); } + if(m_ms == 0) + { + if((offset & 0xe000) == 0x0000) { return mz3500_ipl_r(space,(offset & 0xfff) | 0x1000); } + if((offset & 0xe000) == 0x2000) { return mz3500_basic_r(space,(offset & 0x1fff) | 0x2000); } + if((offset & 0xc000) == 0x4000) { return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x4000); } + if((offset & 0xc000) == 0x8000) { return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x8000); } + if((offset & 0xc000) == 0xc000) + { + if(m_ma == 0x0) { return mz3500_work_ram_r(space,(offset & 0x3fff) | 0xc000); } + if(m_ma == 0x1) { return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x0000); } + if(m_ma == 0xf) { return mz3500_shared_ram_r(space,(offset & 0x7ff)); } + } + + printf("Error: read with unmapped memory bank offset %04x MS %02x MA %02x\n",offset,m_ms,m_ma); + } + else if(m_ms == 1) + { + return ((offset & 0xf800) == 0xf800) ? mz3500_shared_ram_r(space,(offset & 0x7ff)) : mz3500_work_ram_r(space,offset); + } + else if(m_ms == 2) // ROM based BASIC + { + if((offset & 0xe000) == 0x0000) { return mz3500_basic_r(space,offset & 0x1fff); } + if((offset & 0xe000) == 0x2000) + { + switch(m_mo) + { + case 0x0: return mz3500_basic_r(space,(offset & 0x1fff) | 0x2000); + case 0x1: return mz3500_basic_r(space,(offset & 0x1fff) | 0x4000); + case 0x2: return mz3500_basic_r(space,(offset & 0x1fff) | 0x6000); + } + + printf("Error: read with unmapped memory bank offset %04x MS %02x MO %02x\n",offset,m_ms,m_mo); + } + if((offset & 0xc000) == 0x4000) { return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x4000); } + if((offset & 0xc000) == 0x8000) { return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x8000); } + if((offset & 0xc000) == 0xc000) + { + switch(m_ma) + { + case 0x0: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x0c000); + case 0x1: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x00000); + case 0x2: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x10000); + case 0x3: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x14000); + case 0x4: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x18000); + case 0x5: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x1c000); + case 0x6: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x20000); + case 0x7: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x24000); + case 0x8: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x28000); + case 0x9: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x2c000); + case 0xa: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x30000); + case 0xb: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x34000); + case 0xc: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x38000); + case 0xd: return mz3500_work_ram_r(space,(offset & 0x3fff) | 0x3c000); + case 0xf: return mz3500_shared_ram_r(space,(offset & 0x7ff)); + } + } + + printf("Error: read with unmapped memory bank offset %04x MS %02x MA %02x\n",offset,m_ms,m_ma); + } return 0xff; } WRITE8_MEMBER(mz3500_state::mz3500_master_mem_w) { - if((offset & 0xe000) == 0x4000) { mz3500_work_ram_w(space,(offset & 0x1fff) | 0x4000,data); return; } - if((offset & 0xe000) == 0x6000) { mz3500_work_ram_w(space,(offset & 0x1fff) | 0x6000,data); return; } - if((offset & 0xe000) == 0x8000) { mz3500_work_ram_w(space,(offset & 0x1fff) | 0x8000,data); return; } - if((offset & 0xe000) == 0xa000) { mz3500_work_ram_w(space,(offset & 0x1fff) | 0xa000,data); return; } - if((offset & 0xe000) == 0xc000) { mz3500_work_ram_w(space,(offset & 0x1fff) | 0xc000,data); return; } - if((offset & 0xe000) == 0xe000) { mz3500_work_ram_w(space,(offset & 0x1fff) | 0xe000,data); return; } + if(m_ms == 0) // Initialize State + { + if((offset & 0xc000) == 0x4000) { mz3500_work_ram_w(space,(offset & 0x3fff) | 0x4000,data); return; } + if((offset & 0xc000) == 0x8000) { mz3500_work_ram_w(space,(offset & 0x3fff) | 0x8000,data); return; } + if((offset & 0xc000) == 0xc000) + { + if(m_ma == 0x0) { mz3500_work_ram_w(space,(offset & 0x3fff) | 0xc000,data); return; } + if(m_ma == 0x1) { mz3500_work_ram_w(space,(offset & 0x3fff) | 0x0000,data); return; } + if(m_ma == 0xf) { mz3500_shared_ram_w(space,(offset & 0x7ff),data); return; } + } + + printf("Error: write with unmapped memory bank offset %04x data %02x MS %02x MA %02x\n",offset,data,m_ms,m_ma); + } + else if(m_ms == 1) // System Loading & CP/M + { + if((offset & 0xf800) == 0xf800) + mz3500_shared_ram_w(space,(offset & 0x7ff),data); + else + mz3500_work_ram_w(space,offset,data); + + return; + } + else if(m_ms == 2) // ROM based BASIC + { + if((offset & 0xc000) == 0x4000) { mz3500_work_ram_w(space,(offset & 0x3fff) | 0x4000,data); return; } + if((offset & 0xc000) == 0x8000) { mz3500_work_ram_w(space,(offset & 0x3fff) | 0x8000,data); return; } + if((offset & 0xc000) == 0xc000) + { + switch(m_ma) + { + case 0x0: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x0c000,data); return; + case 0x1: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x00000,data); return; + case 0x2: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x10000,data); return; + case 0x3: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x14000,data); return; + case 0x4: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x18000,data); return; + case 0x5: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x1c000,data); return; + case 0x6: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x20000,data); return; + case 0x7: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x24000,data); return; + case 0x8: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x28000,data); return; + case 0x9: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x2c000,data); return; + case 0xa: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x30000,data); return; + case 0xb: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x34000,data); return; + case 0xc: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x38000,data); return; + case 0xd: mz3500_work_ram_w(space,(offset & 0x3fff) | 0x3c000,data); return; + case 0xf: mz3500_shared_ram_w(space,(offset & 0x7ff),data); return; + } + } + + printf("Error: write with unmapped memory bank offset %04x data %02x MS %02x MA %02x\n",offset,data,m_ms,m_ma); + } } @@ -114,6 +213,55 @@ WRITE8_MEMBER(mz3500_state::mz3500_shared_ram_w) m_shared_ram[offset] = data; } +READ8_MEMBER(mz3500_state::mz3500_io_r) +{ + /* + [2] + ---x xxx- system assign switch + ---- ---x "SEC" FD assign + [3] + xxx- ---- FD assign + ---x ---- slave CPU Ready signal + ---- x--- slave CPU ack signal + ---- -xxx interrupt status + */ + + return 0; +} + +WRITE8_MEMBER(mz3500_state::mz3500_io_w) +{ + /* + [0] + ---- --x- SRQ bus request from master to slave + ---- ---x E1 + [1] + x--- ---- slave reset signal + ---- --xx memory system define + [2] + xxxx ---- ma bank (memory 0xc000-0xffff) + ---- -xxx mo bank (memory 0x2000-0x3fff) + [3] + x--- ---- me2 bank (memory 0x8000-0xbfff) + -x-- ---- me1 bank (memory 0x4000-0x7fff) + */ + + switch(offset) + { + case 1: + m_ms = data & 3; + break; + case 2: + m_ma = (data & 0xf0) >> 4; + m_mo = (data & 0x07); + break; + case 3: + m_me2 = (data & 0x80) >> 7; + m_me1 = (data & 0x40) >> 6; + break; + } +} + static ADDRESS_MAP_START( mz3500_master_map, AS_PROGRAM, 8, mz3500_state ) AM_RANGE(0x0000, 0xffff) AM_READWRITE(mz3500_master_mem_r,mz3500_master_mem_w) ADDRESS_MAP_END @@ -125,7 +273,7 @@ static ADDRESS_MAP_START( mz3500_master_io, AS_IO, 8, mz3500_state ) // AM_RANGE(0xec, 0xef) irq signal from slave to master CPU // AM_RANGE(0xf4, 0xf7) MFD upd765 // AM_RANGE(0xf8, 0xfb) MFD I/O port -// AM_RANGE(0xfc, 0xff) memory mapper + AM_RANGE(0xfc, 0xff) AM_READWRITE(mz3500_io_r,mz3500_io_w) // memory mapper ADDRESS_MAP_END static ADDRESS_MAP_START( mz3500_slave_map, AS_PROGRAM, 8, mz3500_state ) @@ -228,6 +376,13 @@ void mz3500_state::machine_start() void mz3500_state::machine_reset() { + /* init memory bank states */ + m_ms = 0; + m_ma = 0; + m_mo = 0; + m_me1 = 0; + m_me2 = 0; + m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); }