mtx: Fully implemented both ROM and RAM based memory maps.

- Added Finnish and Danish keyboard ROMs.
- Added ROM extension board and cartridge slot.
- Support ROM 2 subpages on ROM extension board.
- Cassette motor control.
This commit is contained in:
Nigel Barnes 2017-11-24 14:13:41 +00:00
parent 9aab43a450
commit 81576092a4
3 changed files with 206 additions and 45 deletions

View File

@ -15,7 +15,6 @@
- SDX/FDX floppy
- HDX hard disk
- HRX high resolution graphics
- CBM (all RAM) mode
- "Silicon" disks
- Multi Effect Video Wall
@ -48,11 +47,6 @@
-------------------------------------------------*/
static ADDRESS_MAP_START( mtx_mem, AS_PROGRAM, 8, mtx_state )
AM_RANGE(0x0000, 0x1fff) AM_ROMBANK("bank1")
AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank2")
AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("bank3")
AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank4")
AM_RANGE(0xc000, 0xffff) AM_RAM
ADDRESS_MAP_END
/*-------------------------------------------------
@ -70,6 +64,7 @@ static ADDRESS_MAP_START( mtx_io, AS_IO, 8, mtx_state )
AM_RANGE(0x06, 0x06) AM_READWRITE(mtx_key_hi_r, mtx_sound_latch_w)
// AM_RANGE(0x07, 0x07) PIO
AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write)
AM_RANGE(0x1f, 0x1f) AM_WRITE(mtx_cst_motor_w)
AM_RANGE(0x30, 0x31) AM_WRITE(hrx_address_w)
AM_RANGE(0x32, 0x32) AM_READWRITE(hrx_data_r, hrx_data_w)
AM_RANGE(0x33, 0x33) AM_READWRITE(hrx_attr_r, hrx_attr_w)
@ -326,7 +321,7 @@ static MACHINE_CONFIG_START( mtx512 )
MCFG_SNAPSHOT_ADD("snapshot", mtx_state, mtx, "mtx", 1)
MCFG_CASSETTE_ADD("cassette")
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED)
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED)
MCFG_CASSETTE_INTERFACE("mtx_cass")
MCFG_TIMER_DRIVER_ADD_PERIODIC("cassette_timer", mtx_state, cassette_tick, attotime::from_hz(44100))
@ -334,9 +329,22 @@ static MACHINE_CONFIG_START( mtx512 )
/* internal ram */
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("64K")
MCFG_RAM_EXTRA_OPTIONS("96K,128K,160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K")
MCFG_RAM_EXTRA_OPTIONS("96K,128K,192K,320K,448K,512K")
/* rom extension board */
MCFG_GENERIC_SOCKET_ADD("extrom", generic_plain_slot, "mtx_rom")
MCFG_GENERIC_EXTENSIONS("bin,rom")
MCFG_GENERIC_LOAD(mtx_state, extrom_load)
/* cartridge slot */
MCFG_GENERIC_SOCKET_ADD("rompak", generic_plain_slot, "mtx_cart")
MCFG_GENERIC_EXTENSIONS("bin,rom")
MCFG_GENERIC_LOAD(mtx_state, rompak_load)
/* software lists */
MCFG_SOFTWARE_LIST_ADD("cass_list", "mtx_cass")
MCFG_SOFTWARE_LIST_ADD("cart_list", "mtx_cart")
MCFG_SOFTWARE_LIST_ADD("rom_list", "mtx_rom")
MACHINE_CONFIG_END
/*-------------------------------------------------
@ -348,7 +356,7 @@ static MACHINE_CONFIG_DERIVED( mtx500, mtx512 )
/* internal ram */
MCFG_RAM_MODIFY(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("32K")
MCFG_RAM_EXTRA_OPTIONS("64K,96K,128K,160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K")
MCFG_RAM_EXTRA_OPTIONS("64K,96K,128K,160K,288K,416K")
MACHINE_CONFIG_END
/*-------------------------------------------------
@ -369,7 +377,7 @@ static MACHINE_CONFIG_DERIVED( rs128, mtx512 )
/* internal ram */
MCFG_RAM_MODIFY(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("128K")
MCFG_RAM_EXTRA_OPTIONS("160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K")
MCFG_RAM_EXTRA_OPTIONS("192K,320K,448K,512K")
MACHINE_CONFIG_END
/***************************************************************************
@ -380,13 +388,19 @@ ROM_START( mtx512 )
ROM_REGION( 0x02000, "user1", 0 )
ROM_LOAD( "osrom", 0x0000, 0x2000, CRC(9ca858cc) SHA1(3804503a58f0bcdea96bb6488833782ebd03976d) )
ROM_REGION( 0x10000, "user2", 0 )
ROM_REGION( 0x10000, "user2", ROMREGION_ERASEFF )
ROM_LOAD( "basicrom", 0x0000, 0x2000, CRC(87b4e59c) SHA1(c49782a82a7f068c1195cd967882ba9edd546eaf) )
ROM_LOAD( "assemrom", 0x2000, 0x2000, CRC(9d7538c3) SHA1(d1882c4ea61a68b1715bd634ded5603e18a99c5f) )
ROM_LOAD( "newword0", 0x4000, 0x2000, CRC(5433bd01) SHA1(56897f385476864337b7b994c1b46f50eaa57128) )
ROM_LOAD( "newword1", 0x6000, 0x2000, CRC(10980c03) SHA1(8245c42fb1eda43b67fa483e50e4ee3bc5f3f29f) )
ROM_LOAD( "newword2", 0x8000, 0x2000, CRC(cbff7130) SHA1(b4ab27def6020ba8e32959a1b988fce77bcc1d7f) )
ROM_LOAD( "newword3", 0xa000, 0x2000, CRC(e6bbc33b) SHA1(26faa4a8d952c4659f610e94608b630456ab89aa) )
/* Keyboard ROMs are piggy-backed on top of the OS ROM, wired to be selected as ROM 7 */
/* Country character sets documented in the Operators Manual are:
U.S.A, France, Germany, England, Denmark, Sweden, Italy, Spain */
ROM_DEFAULT_BIOS("us")
ROM_SYSTEM_BIOS( 0, "us", "U.S.A." )
ROM_SYSTEM_BIOS( 1, "dk", "Denmark" )
ROMX_LOAD( "danish.rom", 0xe000, 0x2000, CRC(9c1b3fae) SHA1(82bc021660d88eebcf0c4d3856558ee9acc1c348), ROM_BIOS(2) )
ROM_SYSTEM_BIOS( 2, "fi", "Finland" )
ROMX_LOAD( "finnish.rom", 0xe000, 0x2000, CRC(9b96cf72) SHA1(b46d1a733e0e635ccdaf4752cc370d793c3b5c55), ROM_BIOS(3) )
ROM_REGION( 0x2000, "sdx", 0 )
ROM_LOAD( "sdx", 0x0000, 0x2000, NO_DUMP )

View File

@ -12,6 +12,8 @@
#include "imagedev/snapquik.h"
#include "imagedev/cassette.h"
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "machine/z80dart.h"
#include "machine/z80ctc.h"
#include "sound/sn76496.h"
@ -40,6 +42,8 @@ public:
, m_cassette(*this, "cassette")
, m_centronics(*this, CENTRONICS_TAG)
, m_ram(*this, RAM_TAG)
, m_extrom(*this, "extrom")
, m_rompak(*this, "rompak")
{ }
required_device<cpu_device> m_maincpu;
@ -49,6 +53,8 @@ public:
required_device<cassette_image_device> m_cassette;
required_device<centronics_device> m_centronics;
required_device<ram_device> m_ram;
required_device<generic_slot_device> m_extrom;
required_device<generic_slot_device> m_rompak;
/* keyboard state */
uint8_t m_key_sense;
@ -68,6 +74,7 @@ public:
int m_centronics_perror;
int m_centronics_select;
DECLARE_WRITE8_MEMBER(mtx_subpage_w);
DECLARE_WRITE8_MEMBER(mtx_bankswitch_w);
DECLARE_WRITE8_MEMBER(mtx_sound_latch_w);
DECLARE_WRITE8_MEMBER(mtx_sense_w);
@ -88,13 +95,16 @@ public:
DECLARE_READ8_MEMBER(mtx_strobe_r);
DECLARE_READ8_MEMBER(mtx_sound_strobe_r);
DECLARE_WRITE8_MEMBER(mtx_cst_w);
DECLARE_WRITE8_MEMBER(mtx_cst_motor_w);
DECLARE_READ8_MEMBER(mtx_prt_r);
DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
DECLARE_WRITE_LINE_MEMBER(write_centronics_fault);
DECLARE_WRITE_LINE_MEMBER(write_centronics_perror);
DECLARE_WRITE_LINE_MEMBER(write_centronics_select);
void bankswitch(uint8_t data);
DECLARE_SNAPSHOT_LOAD_MEMBER( mtx );
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(extrom_load);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rompak_load);
DECLARE_SNAPSHOT_LOAD_MEMBER(mtx);
};
#endif /* __MTX_H__ */

View File

@ -35,6 +35,31 @@ READ8_MEMBER(mtx_state::mtx_strobe_r)
return 0xff;
}
/*-------------------------------------------------
mtx_subpage_w - rom2 subpages
-------------------------------------------------*/
/*
The original ROM card supported 4 8KB ROM chips. These appeared in
ROM slot 2 in subpages 0 to 3. The subpage register starts as 0, but
is changed by attempting to write to 0x0000-0x1fff whilst in RELCPMH=0
mode (ie. attempting to write to the OS ROM). Videowalls could use a
later ROM card with 4 32KB ROMs. These also appeared in ROM slot 2
in subpages 0 to 15.
*/
WRITE8_MEMBER(mtx_state::mtx_subpage_w)
{
if (m_extrom->exists())
{
if ((data * 0x2000) < m_extrom->get_rom_size())
membank("rommap_bank1")->configure_entry(2, m_extrom->get_rom_base() + 0x2000 * data);
else
membank("rommap_bank1")->configure_entry(2, memregion("user2")->base() + 0x4000);
membank("rommap_bank1")->set_entry(2);
}
}
/*-------------------------------------------------
mtx_bankswitch_w - bankswitch
-------------------------------------------------*/
@ -73,33 +98,74 @@ void mtx_state::bankswitch(uint8_t data)
*/
address_space &program = m_maincpu->space(AS_PROGRAM);
ram_device *messram = m_ram;
// uint8_t cbm_mode = data >> 7 & 0x01;
uint8_t rom_page = data >> 4 & 0x07;
uint8_t ram_page = data >> 0 & 0x0f;
uint8_t cbm_mode = (data >> 7) & 0x01;
uint8_t rom_page = (data >> 4) & 0x07;
uint8_t ram_page = (data >> 0) & 0x0f;
/* set rom bank (switches between basic and assembler rom or cartridges) */
membank("bank2")->set_entry(rom_page);
/* set ram bank, for invalid pages a nop-handler will be installed */
if (ram_page >= messram->size()/0x8000)
if (cbm_mode)
{
program.nop_readwrite(0x4000, 0x7fff);
program.nop_readwrite(0x8000, 0xbfff);
}
else if (ram_page + 1 == messram->size()/0x8000)
{
program.nop_readwrite(0x4000, 0x7fff);
program.install_readwrite_bank(0x8000, 0xbfff, "bank4");
membank("bank4")->set_entry(ram_page);
/* ram based memory map */
program.install_readwrite_bank(0x0000, 0x3fff, "rammap_bank1");
program.install_readwrite_bank(0x4000, 0x7fff, "rammap_bank2");
program.install_readwrite_bank(0x8000, 0xbfff, "rammap_bank3");
/* set ram bank, for invalid pages a nop-handler will be installed */
switch (ram_page)
{
case 0:
if (ram_page * 0xc000 + 0x10000 <= m_ram->size())
membank("rammap_bank1")->set_entry(ram_page);
else
program.nop_readwrite(0x0000, 0x3fff);
if (ram_page * 0xc000 + 0xc000 <= m_ram->size())
membank("rammap_bank2")->set_entry(ram_page);
else
program.nop_readwrite(0x4000, 0x7fff);
if (ram_page * 0xc000 + 0x8000 <= m_ram->size())
membank("rammap_bank3")->set_entry(ram_page);
else
program.nop_readwrite(0x8000, 0xbfff);
break;
default:
if (ram_page * 0xc000 + 0x8000 <= m_ram->size())
membank("rammap_bank1")->set_entry(ram_page);
else
program.nop_readwrite(0x0000, 0x3fff);
if (ram_page * 0xc000 + 0xc000 <= m_ram->size())
membank("rammap_bank2")->set_entry(ram_page);
else
program.nop_readwrite(0x4000, 0x7fff);
if (ram_page * 0xc000 + 0x10000 <= m_ram->size())
membank("rammap_bank3")->set_entry(ram_page);
else
program.nop_readwrite(0x8000, 0xbfff);
break;
}
}
else
{
program.install_readwrite_bank(0x4000, 0x7fff, "bank3");
program.install_readwrite_bank(0x8000, 0xbfff, "bank4");
membank("bank3")->set_entry(ram_page);
membank("bank4")->set_entry(ram_page);
/* rom based memory map */
program.install_rom(0x0000, 0x1fff, memregion("user1")->base());
program.install_write_handler(0x0000, 0x1fff, write8_delegate(FUNC(mtx_state::mtx_subpage_w), this));
program.install_read_bank(0x2000, 0x3fff, "rommap_bank1");
program.unmap_write(0x2000, 0x3fff);
program.install_readwrite_bank(0x4000, 0x7fff, "rommap_bank2");
program.install_readwrite_bank(0x8000, 0xbfff, "rommap_bank3");
/* set rom bank (switches between basic and assembler rom or cartridges) */
membank("rommap_bank1")->set_entry(rom_page);
/* set ram bank, for invalid pages a nop-handler will be installed */
if (ram_page * 0x8000 + 0xc000 <= m_ram->size())
membank("rommap_bank2")->set_entry(ram_page);
else
program.nop_readwrite(0x4000, 0x7fff);
if (ram_page * 0x8000 + 0x8000 <= m_ram->size())
membank("rommap_bank3")->set_entry(ram_page);
else
program.nop_readwrite(0x8000, 0xbfff);
}
}
@ -136,6 +202,15 @@ WRITE8_MEMBER(mtx_state::mtx_cst_w)
m_cassette->output( BIT(data, 0) ? -1 : 1);
}
/*-------------------------------------------------
mtx_cst_motor_w - cassette motor
-------------------------------------------------*/
WRITE8_MEMBER(mtx_state::mtx_cst_motor_w)
{
m_cassette->change_state(data ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
}
/*-------------------------------------------------
mtx_prt_r - centronics status
-------------------------------------------------*/
@ -329,6 +404,46 @@ WRITE8_MEMBER(mtx_state::hrx_attr_w)
*/
}
/***************************************************************************
EXTENSION BOARD ROMS
***************************************************************************/
DEVICE_IMAGE_LOAD_MEMBER( mtx_state, extrom_load )
{
uint32_t size = m_extrom->common_get_size("rom");
if (size > 0x80000)
{
image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported rom size");
return image_init_result::FAIL;
}
m_extrom->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
m_extrom->common_load_rom(m_extrom->get_rom_base(), size, "rom");
return image_init_result::PASS;
}
/***************************************************************************
ROMPAK ROMS
***************************************************************************/
DEVICE_IMAGE_LOAD_MEMBER( mtx_state, rompak_load )
{
uint32_t size = m_rompak->common_get_size("rom");
if (size > 0x2000)
{
image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
return image_init_result::FAIL;
}
m_rompak->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
m_rompak->common_load_rom(m_rompak->get_rom_base(), size, "rom");
return image_init_result::PASS;
}
/***************************************************************************
SNAPSHOT
***************************************************************************/
@ -396,18 +511,40 @@ SNAPSHOT_LOAD_MEMBER( mtx_state, mtx )
MACHINE_START( mtx512 )
-------------------------------------------------*/
MACHINE_START_MEMBER(mtx_state,mtx512)
MACHINE_START_MEMBER(mtx_state, mtx512)
{
ram_device *messram = m_ram;
address_space &program = m_maincpu->space(AS_PROGRAM);
/* configure memory */
membank("bank1")->set_base(memregion("user1")->base());
membank("bank2")->configure_entries(0, 8, memregion("user2")->base(), 0x2000);
membank("bank3")->configure_entries(0, messram->size()/0x4000/2, messram->pointer(), 0x4000);
membank("bank4")->configure_entries(0, messram->size()/0x4000/2, messram->pointer() + messram->size()/2, 0x4000);
/* setup banks for rom based memory map */
program.install_read_bank(0x2000, 0x3fff, "rommap_bank1");
program.install_readwrite_bank(0x4000, 0x7fff, "rommap_bank2");
program.install_readwrite_bank(0x8000, 0xbfff, "rommap_bank3");
membank("rommap_bank1")->configure_entries(0, 8, memregion("user2")->base(), 0x2000);
if (m_extrom->exists())
membank("rommap_bank1")->configure_entry(2, m_extrom->get_rom_base());
if (m_rompak->exists())
membank("rommap_bank1")->configure_entry(7, m_rompak->get_rom_base());
membank("rommap_bank2")->configure_entries(0, 16, m_ram->pointer() + 0x8000, 0x8000);
membank("rommap_bank3")->configure_entries(0, 16, m_ram->pointer() + 0x4000, 0x8000);
/* setup banks for ram based memory map */
program.install_readwrite_bank(0x0000, 0x3fff, "rammap_bank1");
program.install_readwrite_bank(0x4000, 0x7fff, "rammap_bank2");
program.install_readwrite_bank(0x8000, 0xbfff, "rammap_bank3");
membank("rammap_bank1")->configure_entry(0, m_ram->pointer() + 0xc000);
membank("rammap_bank1")->configure_entries(1, 15, m_ram->pointer() + 0x10000, 0xc000);
membank("rammap_bank2")->configure_entry(0, m_ram->pointer() + 0x8000);
membank("rammap_bank2")->configure_entries(1, 15, m_ram->pointer() + 0x14000, 0xc000);
membank("rammap_bank3")->configure_entry(0, m_ram->pointer() + 0x4000);
membank("rammap_bank3")->configure_entries(1, 15, m_ram->pointer() + 0x18000, 0xc000);
/* install 4000h bytes common block */
program.install_ram(0xc000, 0xffff, m_ram->pointer());
}
MACHINE_RESET_MEMBER(mtx_state,mtx512)
MACHINE_RESET_MEMBER(mtx_state, mtx512)
{
/* bank switching */
bankswitch(0);