laser500 etc : added bankdev, fixes MT 07180 (crash on hard reset)

This commit is contained in:
Robbbert 2018-12-24 14:55:09 +11:00
parent 52537abc08
commit 0e43a220ef
4 changed files with 131 additions and 210 deletions

View File

@ -59,9 +59,9 @@
F 0x3c000 - 0x3ffff ROM expansion
TODO:
Add ROMs and drivers for the Laser100, 110,
210 and 310 machines and the Texet 8000.
They should probably go to the vtech1.c files, though.
- Hook up cart slots
- Ram pak
- undumped DOS ROM
***************************************************************************/
@ -77,24 +77,89 @@
#include "formats/vt_cas.h"
void vtech2_state::vtech2_mem(address_map &map)
void vtech2_state::mem_map(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x3fff).bankrw("bank1");
map(0x4000, 0x7fff).bankrw("bank2");
map(0x8000, 0xbfff).bankrw("bank3");
map(0xc000, 0xffff).bankrw("bank4");
map(0x0000, 0x3fff).m(m_banka, FUNC(address_map_bank_device::amap8));
map(0x4000, 0x7fff).m(m_bankb, FUNC(address_map_bank_device::amap8));
map(0x8000, 0xbfff).m(m_bankc, FUNC(address_map_bank_device::amap8));
map(0xc000, 0xffff).m(m_bankd, FUNC(address_map_bank_device::amap8));
}
void vtech2_state::vtech2_io(address_map &map)
void vtech2_state::io_map(address_map &map)
{
map.global_mask(0xff);
map(0x10, 0x1f).rw(FUNC(vtech2_state::laser_fdc_r), FUNC(vtech2_state::laser_fdc_w));
map(0x40, 0x43).w(FUNC(vtech2_state::laser_bank_select_w));
map(0x40, 0x40).lw8("set_bankA", [this] (u8 data) { m_banka->set_bank(data & 15); });
map(0x41, 0x41).lw8("set_bankB", [this] (u8 data) { m_bankb->set_bank(data & 15); });
map(0x42, 0x42).lw8("set_bankC", [this] (u8 data) { m_bankc->set_bank(data & 15); });
map(0x43, 0x43).lw8("set_bankD", [this] (u8 data) { m_bankd->set_bank(data & 15); });
map(0x44, 0x44).w(FUNC(vtech2_state::laser_bg_mode_w));
map(0x45, 0x45).w(FUNC(vtech2_state::laser_two_color_w));
}
// Laser 350, 16k ram
void vtech2_state::m_map350(address_map &map)
{
map(0x00000, 0x03fff).rom().region("maincpu", 0);
map(0x04000, 0x07fff).rom().region("maincpu", 0x4000);
map(0x08000, 0x0bfff).rw(FUNC(vtech2_state::mmio_r), FUNC(vtech2_state::mmio_w));
map(0x0c000, 0x0ffff).ram().share(m_videoram);
map(0x10000, 0x13fff).noprw();
map(0x14000, 0x17fff).noprw();
map(0x18000, 0x1bfff).noprw();
map(0x1c000, 0x1ffff).noprw();
map(0x20000, 0x23fff).noprw(); // TODO: 64k ram expansion pak
map(0x24000, 0x27fff).noprw(); // TODO: 64k ram expansion pak
map(0x28000, 0x2bfff).noprw(); // TODO: 64k ram expansion pak
map(0x2c000, 0x2ffff).noprw(); // TODO: 64k ram expansion pak
map(0x30000, 0x33fff).noprw(); // TODO: rom in expansion port
map(0x34000, 0x37fff).noprw(); // TODO: rom in expansion port
map(0x38000, 0x3bfff).noprw(); // TODO: rom in expansion port
map(0x3c000, 0x3ffff).noprw(); // TODO: rom in expansion port
}
// Laser 500, 64k ram
void vtech2_state::m_map500(address_map &map)
{
map(0x00000, 0x03fff).rom().region("maincpu", 0);
map(0x04000, 0x07fff).rom().region("maincpu", 0x4000);
map(0x08000, 0x0bfff).rw(FUNC(vtech2_state::mmio_r), FUNC(vtech2_state::mmio_w));
map(0x0c000, 0x0ffff).noprw();
map(0x10000, 0x13fff).ram();
map(0x14000, 0x17fff).ram();
map(0x18000, 0x1bfff).ram();
map(0x1c000, 0x1ffff).ram().share(m_videoram);
map(0x20000, 0x23fff).noprw(); // TODO: 64k ram expansion pak
map(0x24000, 0x27fff).noprw(); // TODO: 64k ram expansion pak
map(0x28000, 0x2bfff).noprw(); // TODO: 64k ram expansion pak
map(0x2c000, 0x2ffff).noprw(); // TODO: 64k ram expansion pak
map(0x30000, 0x33fff).noprw(); // TODO: rom in expansion port
map(0x34000, 0x37fff).noprw(); // TODO: rom in expansion port
map(0x38000, 0x3bfff).noprw(); // TODO: rom in expansion port
map(0x3c000, 0x3ffff).noprw(); // TODO: rom in expansion port
}
// Laser 700, 128k ram
void vtech2_state::m_map700(address_map &map)
{
map(0x00000, 0x03fff).rom().region("maincpu", 0);
map(0x04000, 0x07fff).rom().region("maincpu", 0x4000);
map(0x08000, 0x0bfff).rw(FUNC(vtech2_state::mmio_r), FUNC(vtech2_state::mmio_w));
map(0x0c000, 0x0ffff).noprw();
map(0x10000, 0x13fff).ram();
map(0x14000, 0x17fff).ram();
map(0x18000, 0x1bfff).ram();
map(0x1c000, 0x1ffff).ram().share(m_videoram);
map(0x20000, 0x23fff).ram();
map(0x24000, 0x27fff).ram();
map(0x28000, 0x2bfff).ram();
map(0x2c000, 0x2ffff).ram();
map(0x30000, 0x33fff).noprw(); // TODO: rom in expansion port
map(0x34000, 0x37fff).noprw(); // TODO: rom in expansion port
map(0x38000, 0x3bfff).noprw(); // TODO: rom in expansion port
map(0x3c000, 0x3ffff).noprw(); // TODO: rom in expansion port
}
static INPUT_PORTS_START( laser500 )
PORT_START("ROW0") /* KEY ROW 0 */
@ -428,11 +493,16 @@ static const floppy_interface vtech2_floppy_interface =
MACHINE_CONFIG_START(vtech2_state::laser350)
/* basic machine hardware */
MCFG_DEVICE_ADD("maincpu", Z80, 3694700) /* 3.694700 MHz */
MCFG_DEVICE_PROGRAM_MAP(vtech2_mem)
MCFG_DEVICE_IO_MAP(vtech2_io)
MCFG_DEVICE_PROGRAM_MAP(mem_map)
MCFG_DEVICE_IO_MAP(io_map)
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", vtech2_state, vtech2_interrupt)
MCFG_QUANTUM_TIME(attotime::from_hz(60))
ADDRESS_MAP_BANK(config, "banka").set_map(&vtech2_state::m_map350).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankb").set_map(&vtech2_state::m_map350).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankc").set_map(&vtech2_state::m_map350).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankd").set_map(&vtech2_state::m_map350).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
@ -467,13 +537,29 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(vtech2_state::laser500)
laser350(config);
MCFG_MACHINE_RESET_OVERRIDE(vtech2_state, laser500 )
config.device_remove("banka");
config.device_remove("bankb");
config.device_remove("bankc");
config.device_remove("bankd");
ADDRESS_MAP_BANK(config, "banka").set_map(&vtech2_state::m_map500).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankb").set_map(&vtech2_state::m_map500).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankc").set_map(&vtech2_state::m_map500).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankd").set_map(&vtech2_state::m_map500).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
MACHINE_CONFIG_END
MACHINE_CONFIG_START(vtech2_state::laser700)
laser350(config);
MCFG_MACHINE_RESET_OVERRIDE(vtech2_state, laser700 )
config.device_remove("banka");
config.device_remove("bankb");
config.device_remove("bankc");
config.device_remove("bankd");
ADDRESS_MAP_BANK(config, "banka").set_map(&vtech2_state::m_map700).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankb").set_map(&vtech2_state::m_map700).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankc").set_map(&vtech2_state::m_map700).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
ADDRESS_MAP_BANK(config, "bankd").set_map(&vtech2_state::m_map700).set_options(ENDIANNESS_LITTLE, 8, 18, 0x4000);
/* Second 5.25" floppy drive */
MCFG_LEGACY_FLOPPY_DRIVE_ADD( FLOPPY_1, vtech2_floppy_interface )

View File

@ -9,6 +9,7 @@
#ifndef MAME_INCLUDES_VTECH2_H
#define MAME_INCLUDES_VTECH2_H
#include "machine/bankdev.h"
#include "bus/generic/carts.h"
#include "bus/generic/slot.h"
#include "imagedev/cassette.h"
@ -30,7 +31,12 @@ public:
, m_laser_file(*this, {FLOPPY_0, FLOPPY_1})
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
, m_videoram(*this, "videoram")
, m_io_keyboard(*this, {"ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7", "ROWD", "ROWC", "ROWB", "ROWA"})
, m_banka(*this, "banka")
, m_bankb(*this, "bankb")
, m_bankc(*this, "bankc")
, m_bankd(*this, "bankd")
{ }
void laser350(machine_config &config);
@ -48,31 +54,20 @@ private:
DECLARE_WRITE8_MEMBER(laser_two_color_w);
DECLARE_READ8_MEMBER(laser_fdc_r);
virtual void machine_reset() override;
virtual void video_start() override;
DECLARE_PALETTE_INIT(vtech2);
DECLARE_MACHINE_RESET(laser500);
DECLARE_MACHINE_RESET(laser700);
uint32_t screen_update_laser(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vtech2_interrupt);
DECLARE_WRITE8_MEMBER(mmio_w);
DECLARE_READ8_MEMBER(mmio_r);
int mra_bank(int bank, int offs);
void mwa_bank(int bank, int offs, int data);
DECLARE_WRITE8_MEMBER(mwa_bank1);
DECLARE_WRITE8_MEMBER(mwa_bank2);
DECLARE_WRITE8_MEMBER(mwa_bank3);
DECLARE_WRITE8_MEMBER(mwa_bank4);
DECLARE_READ8_MEMBER(mra_bank1);
DECLARE_READ8_MEMBER(mra_bank2);
DECLARE_READ8_MEMBER(mra_bank3);
DECLARE_READ8_MEMBER(mra_bank4);
void laser_machine_init(int bank_mask, int video_mask);
void laser_get_track();
void laser_put_track();
void vtech2_io(address_map &map);
void vtech2_mem(address_map &map);
void io_map(address_map &map);
void mem_map(address_map &map);
void m_map350(address_map &map);
void m_map500(address_map &map);
void m_map700(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<speaker_sound_device> m_speaker;
@ -81,16 +76,16 @@ private:
optional_device_array<legacy_floppy_image_device, 2> m_laser_file;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_shared_ptr<u8> m_videoram;
required_ioport_array<12> m_io_keyboard;
required_device<address_map_bank_device> m_banka;
required_device<address_map_bank_device> m_bankb;
required_device<address_map_bank_device> m_bankc;
required_device<address_map_bank_device> m_bankd;
uint8_t *m_videoram;
int m_laser_latch;
char m_laser_frame_message[64+1];
int m_laser_frame_time;
uint8_t *m_mem;
int m_laser_bank_mask;
int m_laser_bank[4];
int m_laser_video_bank;
u8 m_laser_latch;
uint8_t m_laser_track_x2[2];
uint8_t m_laser_fdc_status;
uint8_t m_laser_fdc_data[TRKSIZE_FM];

View File

@ -26,36 +26,6 @@
static const uint8_t laser_fdc_wrprot[2] = {0x80, 0x80};
/* wrappers for bank #1 to #4 */
WRITE8_MEMBER(vtech2_state::mwa_bank1 ) { mwa_bank(0,offset,data); }
WRITE8_MEMBER(vtech2_state::mwa_bank2 ) { mwa_bank(1,offset,data); }
WRITE8_MEMBER(vtech2_state::mwa_bank3 ) { mwa_bank(2,offset,data); }
WRITE8_MEMBER(vtech2_state::mwa_bank4 ) { mwa_bank(3,offset,data); }
/* wrappers for bank #1 to #4 */
READ8_MEMBER(vtech2_state::mra_bank1 ) { return mra_bank(0,offset); }
READ8_MEMBER(vtech2_state::mra_bank2 ) { return mra_bank(1,offset); }
READ8_MEMBER(vtech2_state::mra_bank3 ) { return mra_bank(2,offset); }
READ8_MEMBER(vtech2_state::mra_bank4 ) { return mra_bank(3,offset); }
/* read banked memory (plain ROM/RAM) */
static const char *const mra_bank_hard[4] =
{
"bank1", /* mapped in 0000-3fff */
"bank2", /* mapped in 4000-7fff */
"bank3", /* mapped in 8000-bfff */
"bank4" /* mapped in c000-ffff */
};
/* write banked memory (plain ROM/RAM) */
static const char *const mwa_bank_hard[4] =
{
"bank1", /* mapped in 0000-3fff */
"bank2", /* mapped in 4000-7fff */
"bank3", /* mapped in 8000-bfff */
"bank4" /* mapped in c000-ffff */
};
void vtech2_state::init_laser()
{
uint8_t *gfx = memregion("gfx2")->base();
@ -69,116 +39,18 @@ void vtech2_state::init_laser()
gfx[i] = i;
m_laser_latch = -1;
m_mem = memregion("maincpu")->base();
// check ROM expansion
std::string region_tag;
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
for (i = 0; i < ARRAY_LENGTH(m_laser_bank); i++)
m_laser_bank[i] = -1;
}
void vtech2_state::laser_machine_init(int bank_mask, int video_mask)
{
m_laser_bank_mask = bank_mask;
m_laser_video_bank = video_mask;
m_videoram = m_mem + m_laser_video_bank * 0x04000;
logerror("laser_machine_init(): bank mask $%04X, video %d [$%05X]\n", m_laser_bank_mask, m_laser_video_bank, m_laser_video_bank * 0x04000);
for (int i = 0; i < ARRAY_LENGTH(m_laser_bank); i++)
laser_bank_select_w(m_maincpu->space(AS_PROGRAM), i, 0);
m_language = m_io_keyboard[5]->read() & 0x30;
}
void vtech2_state::machine_reset()
{
/* banks 0 to 3 only, optional ROM extension */
laser_machine_init(0x00f, 3);
m_language = m_io_keyboard[5]->read() & 0x30;
}
MACHINE_RESET_MEMBER(vtech2_state,laser500)
{
/* banks 0 to 2, and 4-7 only, optional ROM extension */
laser_machine_init(0x0f7, 7);
}
MACHINE_RESET_MEMBER(vtech2_state,laser700)
{
/* all banks except #3 */
laser_machine_init(0xff7, 7);
}
WRITE8_MEMBER(vtech2_state::laser_bank_select_w)
{
static const char *const bank_name[16] = {
"ROM lo","ROM hi","MM I/O","Video RAM lo",
"RAM #0","RAM #1","RAM #2","RAM #3",
"RAM #4","RAM #5","RAM #6","RAM #7/Video RAM hi",
"ext ROM #0","ext ROM #1","ext ROM #2","ext ROM #3"
};
char bank[10];
offset %= 4;
data &= 15;
if( data != m_laser_bank[offset] )
{
m_laser_bank[offset] = data;
logerror("select bank #%d $%02X [$%05X] %s\n", offset+1, data, 0x4000 * (data & 15), bank_name[data]);
/* memory mapped I/O bank selected? */
if (data == 2)
{
static read8_delegate mra_bank_soft[] =
{
read8_delegate(FUNC(vtech2_state::mra_bank1), this),
read8_delegate(FUNC(vtech2_state::mra_bank2), this),
read8_delegate(FUNC(vtech2_state::mra_bank3), this),
read8_delegate(FUNC(vtech2_state::mra_bank4), this),
};
static write8_delegate mwa_bank_soft[] =
{
write8_delegate(FUNC(vtech2_state::mwa_bank1), this),
write8_delegate(FUNC(vtech2_state::mwa_bank2), this),
write8_delegate(FUNC(vtech2_state::mwa_bank3), this),
write8_delegate(FUNC(vtech2_state::mwa_bank4), this),
};
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(offset * 0x4000, offset * 0x4000 + 0x3fff, mra_bank_soft[offset], mwa_bank_soft[offset]);
}
else
{
sprintf(bank, "bank%d", offset + 1);
if (data >= 12 && m_cart_rom && (m_cart_rom->bytes() > (data % 12) * 0x4000)) // Expansion ROM banks
{
membank(bank)->set_base(m_cart_rom->base()+ (data % 12) * 0x4000);
m_maincpu->space(AS_PROGRAM).install_read_bank(offset * 0x4000, offset * 0x4000 + 0x3fff, mra_bank_hard[offset]);
m_maincpu->space(AS_PROGRAM).install_write_bank(offset * 0x4000, offset * 0x4000 + 0x3fff, mwa_bank_hard[offset]);
}
else if (data < 12 && (m_laser_bank_mask & (1 << data))) // ROM/RAM banks
{
// video RAM bank selected?
if (data == m_laser_video_bank)
logerror("select bank #%d VIDEO!\n", offset + 1);
membank(bank)->set_base(&m_mem[0x4000 * m_laser_bank[offset]]);
m_maincpu->space(AS_PROGRAM).install_read_bank(offset * 0x4000, offset * 0x4000 + 0x3fff, mra_bank_hard[offset]);
m_maincpu->space(AS_PROGRAM).install_write_bank(offset * 0x4000, offset * 0x4000 + 0x3fff, mwa_bank_hard[offset]);
}
else
{
logerror("select bank #%d MASKED!\n", offset + 1);
m_maincpu->space(AS_PROGRAM).nop_readwrite(offset * 0x4000, offset * 0x4000 + 0x3fff);
}
}
}
}
/*************************************************
* memory mapped I/O read
@ -192,19 +64,19 @@ WRITE8_MEMBER(vtech2_state::laser_bank_select_w)
* 1 column 1
* 0 column 0
************************************************/
int vtech2_state::mra_bank(int bank, int offs)
READ8_MEMBER( vtech2_state::mmio_r )
{
u8 data = 0x7f;
offs = ~offs & 0x7ff;
if (BIT(offs, 10))
offset = ~offset & 0x7ff;
if (BIT(offset, 10))
{
offs = (offs >> 8) & 3;
data &= m_io_keyboard[offs + 8]->read(); // ROW A-D
offset = (offset >> 8) & 3;
data &= m_io_keyboard[offset + 8]->read(); // ROW A-D
}
else
for (u8 i = 0; i < 8; i++)
if (BIT(offs, i))
if (BIT(offset, i))
data &= m_io_keyboard[i]->read(); // ROW 0-7
/* BIT 7 - tape input */
@ -224,40 +96,11 @@ int vtech2_state::mra_bank(int bank, int offs)
* 1 cassette out (LSB)
* 0 speaker A
************************************************/
void vtech2_state::mwa_bank(int bank, int offs, int data)
WRITE8_MEMBER( vtech2_state::mmio_w )
{
offs += 0x4000 * m_laser_bank[bank];
switch (m_laser_bank[bank])
{
case 0: /* ROM lower 16K */
case 1: /* ROM upper 16K */
logerror("bank #%d write to ROM [$%05X] $%02X\n", bank+1, offs, data);
break;
case 2: /* memory mapped output */
if (data != m_laser_latch)
{
logerror("bank #%d write to I/O [$%05X] $%02X\n", bank+1, offs, data);
/* Toggle between graphics and text modes? */
if ((data ^ m_laser_latch) & 0x01)
m_speaker->level_w(data & 1);
m_laser_latch = data;
}
m_cassette->output( BIT(data, 2) ? -1.0 : +1.0);
break;
case 12: /* ext. ROM #1 */
case 13: /* ext. ROM #2 */
case 14: /* ext. ROM #3 */
case 15: /* ext. ROM #4 */
logerror("bank #%d write to ROM [$%05X] $%02X\n", bank+1, offs, data);
break;
default: /* RAM */
if( m_laser_bank[bank] == m_laser_video_bank && m_mem[offs] != data )
{
logerror("bank #%d write to videoram [$%05X] $%02X\n", bank+1, offs, data);
}
m_mem[offs] = data;
break;
}
m_speaker->level_w(data & 1);
m_laser_latch = data;
m_cassette->output( BIT(data, 2) ? -1.0 : +1.0);
}

View File

@ -42,9 +42,6 @@
* 1 1 1 1 GR1 bank 3 0E000-0FFFF
*/
void vtech2_state::video_start()
{
}
static const int offs_2[192] = {
0x0000,0x0800,0x1000,0x1800,0x2000,0x2800,0x3000,0x3800,