xm updates, first pass

This commit is contained in:
msaarna@gmail.com 2020-05-09 17:15:07 -04:00
parent 9038f6346d
commit 19f1ca5ad4
8 changed files with 2634 additions and 288 deletions

File diff suppressed because it is too large Load diff

View file

@ -23,8 +23,8 @@ if (BUSES["A7800"]~=null) then
MAME_DIR .. "src/devices/bus/a7800/rom.h",
MAME_DIR .. "src/devices/bus/a7800/hiscore.cpp",
MAME_DIR .. "src/devices/bus/a7800/hiscore.h",
MAME_DIR .. "src/devices/bus/a7800/xboard.cpp",
MAME_DIR .. "src/devices/bus/a7800/xboard.h",
MAME_DIR .. "src/devices/bus/a7800/xm.cpp",
MAME_DIR .. "src/devices/bus/a7800/xm.h",
MAME_DIR .. "src/devices/bus/a7800/cpuwiz.cpp",
MAME_DIR .. "src/devices/bus/a7800/cpuwiz.h",
}

View file

@ -6,7 +6,7 @@
#pragma once
#include "rom.h"
#include "xboard.h"
#include "xm.h"
#include "hiscore.h"
#include "cpuwiz.h"
@ -21,7 +21,6 @@ static SLOT_INTERFACE_START(a7800_cart)
SLOT_INTERFACE_INTERNAL("a78_abs", A78_ROM_ABSOLUTE)
SLOT_INTERFACE_INTERNAL("a78_act", A78_ROM_ACTIVISION)
SLOT_INTERFACE_INTERNAL("a78_hsc", A78_HISCORE)
SLOT_INTERFACE_INTERNAL("a78_xboard", A78_XBOARD) // the actual XBoarD expansion (as passthru)
SLOT_INTERFACE_INTERNAL("a78_xm", A78_XM) // the actual XM expansion (as passthru)
SLOT_INTERFACE_INTERNAL("a78_megacart", A78_ROM_MEGACART)
SLOT_INTERFACE_INTERNAL("a78_versa", A78_ROM_VERSABOARD)

View file

@ -300,7 +300,6 @@ static const a78_slot slot_list[] =
{ A78_ABSOLUTE, "a78_abs" },
{ A78_ACTIVISION, "a78_act" },
{ A78_HSC, "a78_hsc" },
{ A78_XB_BOARD, "a78_xboard" },
{ A78_XM_BOARD, "a78_xm" },
{ A78_MEGACART, "a78_megacart" },
{ A78_VERSABOARD, "a78_versa" },
@ -440,7 +439,7 @@ image_init_result a78_cart_slot_device::call_load()
if (head[63])
{
osd_printf_info("This cart requires XBoarD / XM expansion\n");
osd_printf_info("This cart requires XM expansion\n");
osd_printf_info("Run it through the expansion to exploit this feature.\n");
}
@ -453,7 +452,7 @@ image_init_result a78_cart_slot_device::call_load()
m_cart->ram_alloc(0x4000);
if (m_type == A78_MEGACART || (m_type >= A78_VERSABOARD && m_type <= A78_VERSA_POK450))
m_cart->ram_alloc(0x8000);
if (m_type == A78_XB_BOARD || m_type == A78_XM_BOARD)
if (m_type == A78_XM_BOARD)
m_cart->ram_alloc(0x20000);
if (m_type == A78_HSC || m_type == A78_XM_BOARD)
{

View file

@ -1,230 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
A7800 XBoarD & XM expansions emulation
The XBoarD should be socketed in the A7800 pcb in place of the Maria chip.
It adds to the system additional 128K of RAM and an onboard pokey.
The XM seems to work the same as XBoarD, but it also features HighScore savings
(using the same ROM as Atari HighScore cart)
Currently, we emulate both of these as a passthru cart, even if not 100% accurate for the XBoarD
Memory map:
POKEY1 $0450 $045F 16 bytes
POKEY2* $0460 $046F 16 bytes
XCTRL $0470 $047F 1 byte
RAM $4000 $7FFF 16384 bytes
XCTRL Bit Description
+-------------------------------+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------+
| | | | | | | |
| | | | | | | +-- Bank select bit 0 \
| | | | | | +------ Bank select bit 1 | Totally 128 KByte in 16 KByte banks
| | | | | +---------- Bank select bit 2 /
| | | | +-------------- Enable memory bit (1 = Memory enabled, 0 after power on)
| | | +------------------ Enable POKEY bit** (1 = POKEY enabled, 0 after power on)
| | |
NA NA NA = Not Available or Not Used
* = Can be mounted piggy back on the first POKEY. Description how to do this will come when i have tried it out.
** This bit controls both POKEY chip select signals.
TODO:
- verify what happens when 2 POKEYs are present
***********************************************************************************************************/
#include "emu.h"
#include "xboard.h"
#include "a78_carts.h"
#include "speaker.h"
//-------------------------------------------------
// constructor
//-------------------------------------------------
DEFINE_DEVICE_TYPE(A78_XBOARD, a78_xboard_device, "a78_xboard", "Atari 7800 XBoarD expansion")
DEFINE_DEVICE_TYPE(A78_XM, a78_xm_device, "a78_xm", "Atari 7800 XM expansion module")
a78_xboard_device::a78_xboard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a78_rom_device(mconfig, type, tag, owner, clock)
, m_xbslot(*this, "xb_slot")
, m_pokey(*this, "xb_pokey")
, m_reg(0), m_ram_bank(0)
{
}
a78_xboard_device::a78_xboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a78_xboard_device(mconfig, A78_XBOARD, tag, owner, clock)
{
}
a78_xm_device::a78_xm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a78_xboard_device(mconfig, A78_XM, tag, owner, clock)
, m_ym(*this, "xm_ym2151"), m_ym_enabled(0)
{
}
void a78_xboard_device::device_start()
{
save_item(NAME(m_reg));
save_item(NAME(m_ram_bank));
}
void a78_xboard_device::device_reset()
{
m_reg = 0;
m_ram_bank = 0;
}
void a78_xm_device::device_start()
{
save_item(NAME(m_reg));
save_item(NAME(m_ram_bank));
save_item(NAME(m_ym_enabled));
}
void a78_xm_device::device_reset()
{
m_reg = 0;
m_ram_bank = 0;
m_ym_enabled = 0;
}
MACHINE_CONFIG_MEMBER( a78_xboard_device::device_add_mconfig )
MCFG_A78_CARTRIDGE_ADD("xb_slot", a7800_cart, nullptr)
MCFG_SPEAKER_STANDARD_MONO("xb_speaker")
MCFG_SOUND_ADD("xb_pokey", POKEY, XTAL_14_31818MHz/8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "xb_speaker", 1.00)
MACHINE_CONFIG_END
MACHINE_CONFIG_MEMBER( a78_xm_device::device_add_mconfig )
MCFG_A78_CARTRIDGE_ADD("xb_slot", a7800_cart, nullptr)
MCFG_SPEAKER_STANDARD_MONO("xb_speaker")
MCFG_SOUND_ADD("xb_pokey", POKEY, XTAL_14_31818MHz/8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "xb_speaker", 1.00)
MCFG_SOUND_ADD("xm_ym2151", YM2151, XTAL_14_31818MHz/4)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "xb_speaker", 1.00)
MACHINE_CONFIG_END
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
/*-------------------------------------------------
XBoarD: passthru + 128K RAM + POKEY
-------------------------------------------------*/
READ8_MEMBER(a78_xboard_device::read_40xx)
{
if (BIT(m_reg, 3) && offset < 0x4000)
return m_ram[offset + (m_ram_bank * 0x4000)];
else
return m_xbslot->read_40xx(space, offset);
}
WRITE8_MEMBER(a78_xboard_device::write_40xx)
{
if (BIT(m_reg, 3) && offset < 0x4000)
m_ram[offset + (m_ram_bank * 0x4000)] = data;
else
m_xbslot->write_40xx(space, offset, data);
}
READ8_MEMBER(a78_xboard_device::read_04xx)
{
if (BIT(m_reg, 4) && offset >= 0x50 && offset < 0x60)
return m_pokey->read(space, offset & 0x0f);
else if (BIT(m_reg, 4) && offset >= 0x60 && offset < 0x70)
return m_xbslot->read_04xx(space, offset - 0x10); // access second POKEY
else
return 0xff;
}
WRITE8_MEMBER(a78_xboard_device::write_04xx)
{
if (BIT(m_reg, 4) && offset >= 0x50 && offset < 0x60)
m_pokey->write(space, offset & 0x0f, data);
else if (BIT(m_reg, 4) && offset >= 0x60 && offset < 0x70)
m_xbslot->write_04xx(space, offset - 0x10, data); // access second POKEY
else if (offset >= 0x70 && offset < 0x80)
{
m_reg = data;
m_ram_bank = m_reg & 7;
}
}
/*-------------------------------------------------
XM: Same as above but also featuring High Score savings
-------------------------------------------------*/
READ8_MEMBER(a78_xm_device::read_10xx)
{
return m_nvram[offset];
}
WRITE8_MEMBER(a78_xm_device::write_10xx)
{
m_nvram[offset] = data;
}
READ8_MEMBER(a78_xm_device::read_30xx)
{
return m_rom[offset];
}
READ8_MEMBER(a78_xm_device::read_04xx)
{
if (BIT(m_reg, 4) && offset >= 0x50 && offset < 0x60)
return m_pokey->read(space, offset & 0x0f);
else if (m_ym_enabled && offset >= 0x60 && offset <= 0x61)
return m_ym->read(space, offset & 1);
else if (BIT(m_reg, 4) && offset >= 0x60 && offset < 0x70)
return m_xbslot->read_04xx(space, offset - 0x10); // access second POKEY
else
return 0xff;
}
WRITE8_MEMBER(a78_xm_device::write_04xx)
{
if (BIT(m_reg, 4) && offset >= 0x50 && offset < 0x60)
m_pokey->write(space, offset & 0x0f, data);
else if (m_ym_enabled && offset >= 0x60 && offset <= 0x61)
m_ym->write(space, offset & 1, data);
else if (BIT(m_reg, 4) && offset >= 0x60 && offset < 0x70)
m_xbslot->write_04xx(space, offset - 0x10, data); // access second POKEY
else if (offset >= 0x70 && offset < 0x80)
{
//printf("regs 0x%X\n", data);
if (data == 0x84)
m_ym_enabled = 1;
m_reg = data;
m_ram_bank = m_reg & 7;
}
}

View file

@ -0,0 +1,187 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli, Mike Saarna
/***********************************************************************************************************
A7800 XM expansion module emulation
pokey $450
ym2151 $460 (R) FM status register
$460 (W) FM address register
$461 (RW) FM data register
cntrl1 $470
d0 rof lo on
d1 rof hi on
d2 0=bios,1=top slot
d3 1=hsc on
d4 1=pokey on
d5 1=bank0 on 4000-5fff
d6 1=bank1 on 6000-7fff
d7 1=ym2151 on
cntrl2 $478 - SALLY RAM bank 8K page multiplexer.
d0-d3 sally ram page 0 a0-a3
d4-d7 sally ram page 1 a0-a3
cntrl3 $47c - MARIA RAM bank 8K page multiplexer.
d0-d3 maria ram page 0 a0-a3
d4-d7 maria ram page 1 a0-a3
cntrl4 $471
d0 1=pia on
d1-d3 flash bank lo a1-a3
d4-d6 flash bank hi a1-a3
d7 1=top slot lock
cntrl5 $472
d0 1=48k ram enable
d1 1=ram we# disabled
d2 1=bios enabled (in test mode)
d3 1=POKEY enable/disable locked
d4 1=HSC enable/disable locked - cannot disable after enable
d5 1=PAL HSC enabled, 0=NTSC HSC enabled - cannot disable after enable
RAM0 $4000 $5FFF 8192 bytes
RAM1 $6000 $7FFF 8192 bytes
***********************************************************************************************************/
#include "emu.h"
#include "xm.h"
#include "a78_carts.h"
#include "speaker.h"
//-------------------------------------------------
// constructor
//-------------------------------------------------
DEFINE_DEVICE_TYPE(A78_XM, a78_xm_device, "a78_xm", "Atari 7800 XM expansion module")
a78_xm_device::a78_xm_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a78_rom_device(mconfig, type, tag, owner, clock)
, m_xmslot(*this, "xm_slot")
, m_pokey(*this, "xm_pokey")
, m_ym(*this, "xm_ym2151")
, m_cntrl1(0), m_cntrl2(0),m_cntrl3(0),m_cntrl4(0),m_cntrl5(0)
{
}
a78_xm_device::a78_xm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a78_xm_device(mconfig, A78_XM, tag, owner, clock)
{
}
void a78_xm_device::device_start()
{
save_item(NAME(m_cntrl1));
save_item(NAME(m_cntrl2));
save_item(NAME(m_cntrl3));
save_item(NAME(m_cntrl4));
save_item(NAME(m_cntrl5));
}
void a78_xm_device::device_reset()
{
m_cntrl1= 0;
m_cntrl2= 0;
m_cntrl3= 0;
m_cntrl4= 0;
m_cntrl5= 0;
}
MACHINE_CONFIG_MEMBER( a78_xm_device::device_add_mconfig )
MCFG_A78_CARTRIDGE_ADD("xm_slot", a7800_cart, nullptr)
MCFG_SPEAKER_STANDARD_MONO("xm_speaker")
MCFG_SOUND_ADD("xm_pokey", POKEY, XTAL_14_31818MHz/8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "xm_speaker", 1.00)
MCFG_SOUND_ADD("xm_ym2151", YM2151, XTAL_14_31818MHz/4)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "xm_speaker", 1.00)
MACHINE_CONFIG_END
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
READ8_MEMBER(a78_xm_device::read_40xx)
{
if (BIT(m_cntrl1, 5) && offset < 0x2000)
return m_ram[ (offset + ((m_cntrl2&15) * 0x4000)) ];
else if (BIT(m_cntrl1, 6) && offset >0x1ffff && offset < 0x4000)
return m_ram[ (offset + (((m_cntrl2>>4)&15) * 0x4000)) ];
else
return m_xmslot->read_40xx(space, offset);
// TODO: implement ROF bits in cntrl1
}
WRITE8_MEMBER(a78_xm_device::write_40xx)
{
if (BIT(m_cntrl1, 5) && offset < 0x2000)
m_ram[ (offset + ((m_cntrl2&15) * 0x4000)) ] = data;
else if (BIT(m_cntrl1, 6) && offset >0x1ffff && offset < 0x4000)
m_ram[ (offset + (((m_cntrl2>>4)&15) * 0x4000)) ] = data;
else
m_xmslot->write_40xx(space, offset, data);
// TODO: implement ROF bits in cntrl1
}
READ8_MEMBER(a78_xm_device::read_10xx)
{
if (BIT(m_cntrl1, 3))
return m_nvram[offset];
else
return 0xff;
}
WRITE8_MEMBER(a78_xm_device::write_10xx)
{
if (BIT(m_cntrl1, 3))
m_nvram[offset] = data;
}
READ8_MEMBER(a78_xm_device::read_30xx)
{
if (BIT(m_cntrl1, 3))
return m_rom[offset];
else
return 0xff;
}
READ8_MEMBER(a78_xm_device::read_04xx)
{
if (BIT(m_cntrl1, 4) && offset >= 0x50 && offset < 0x60)
return m_pokey->read(space, offset & 0x0f);
else if (BIT(m_cntrl1, 7) && offset >= 0x60 && offset <= 0x61)
return m_ym->read(space, offset & 1);
else
return 0xff;
}
WRITE8_MEMBER(a78_xm_device::write_04xx)
{
if (BIT(m_cntrl1, 4) && offset >= 0x50 && offset < 0x60)
m_pokey->write(space, offset & 0x0f, data);
else if (BIT(m_cntrl1, 7) && offset >= 0x60 && offset <= 0x61)
m_ym->write(space, offset & 1, data);
else if (offset == 0x70)
m_cntrl1 = data;
else if (offset == 0x78)
m_cntrl2 = data;
else if (offset == 0x7c)
m_cntrl3 = data;
else if (offset == 0x71)
m_cntrl4 = data;
else if (offset == 0x72)
m_cntrl5 = data;
// else do nothing
}

View file

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
#ifndef MAME_BUS_A7800_XBOARD_H
#define MAME_BUS_A7800_XBOARD_H
#ifndef MAME_BUS_A7800_XM_H
#define MAME_BUS_A7800_XM_H
#pragma once
@ -11,36 +11,9 @@
#include "sound/ym2151.h"
// ======================> a78_xboard_device
class a78_xboard_device : public a78_rom_device
{
public:
// construction/destruction
a78_xboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
virtual DECLARE_READ8_MEMBER(read_04xx) override;
virtual DECLARE_WRITE8_MEMBER(write_04xx) override;
virtual DECLARE_READ8_MEMBER(read_40xx) override;
virtual DECLARE_WRITE8_MEMBER(write_40xx) override;
protected:
a78_xboard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
required_device<a78_cart_slot_device> m_xbslot;
required_device<pokey_device> m_pokey;
int m_reg, m_ram_bank;
};
// ======================> a78_xm_device
class a78_xm_device : public a78_xboard_device
class a78_xm_device : public a78_rom_device
{
public:
// construction/destruction
@ -49,24 +22,32 @@ public:
// reading and writing
virtual DECLARE_READ8_MEMBER(read_04xx) override;
virtual DECLARE_WRITE8_MEMBER(write_04xx) override;
virtual DECLARE_READ8_MEMBER(read_40xx) override;
virtual DECLARE_WRITE8_MEMBER(write_40xx) override;
virtual DECLARE_READ8_MEMBER(read_10xx) override;
virtual DECLARE_WRITE8_MEMBER(write_10xx) override;
virtual DECLARE_READ8_MEMBER(read_30xx) override;
protected:
a78_xm_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
required_device<a78_cart_slot_device> m_xmslot;
required_device<pokey_device> m_pokey;
required_device<ym2151_device> m_ym;
int m_ym_enabled;
int m_cntrl1;
int m_cntrl2;
int m_cntrl3;
int m_cntrl4;
int m_cntrl5;
};
// device type definition
DECLARE_DEVICE_TYPE(A78_XBOARD, a78_xboard_device)
DECLARE_DEVICE_TYPE(A78_XM, a78_xm_device)
#endif // MAME_BUS_A7800_XBOARD_H
#endif // MAME_BUS_A7800_XM_H

View file

@ -1123,7 +1123,6 @@ void a7800_state::machine_start()
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x17ff, read8_delegate(FUNC(a78_cart_slot_device::read_10xx),(a78_cart_slot_device*)m_cart), write8_delegate(FUNC(a78_cart_slot_device::write_10xx),(a78_cart_slot_device*)m_cart));
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x3000, 0x3fff, read8_delegate(FUNC(a78_cart_slot_device::read_30xx),(a78_cart_slot_device*)m_cart), write8_delegate(FUNC(a78_cart_slot_device::write_30xx),(a78_cart_slot_device*)m_cart));
break;
case A78_XB_BOARD:
case A78_TYPE0_POK450:
case A78_TYPE1_POK450:
case A78_TYPE6_POK450:
@ -1417,4 +1416,4 @@ CONS( 1986, a7800u1, a7800, 0, a7800u1_ntsc, a7800, a7800_state, a78
CONS( 1986, a7800u2, a7800, 0, a7800u2_ntsc, a7800, a7800_state, a7800u2_ntsc, "Atari", "Atari 7800 (NTSC) Hot", MACHINE_SUPPORTS_SAVE )
CONS( 1986, a7800p, a7800, 0, a7800_pal, a7800, a7800_state, a7800_pal, "Atari", "Atari 7800 (PAL) Cool", MACHINE_SUPPORTS_SAVE )
CONS( 1986, a7800pu1, a7800, 0, a7800u1_pal, a7800, a7800_state, a7800u1_pal, "Atari", "Atari 7800 (PAL) Warm", MACHINE_SUPPORTS_SAVE )
CONS( 1986, a7800pu2, a7800, 0, a7800u2_pal, a7800, a7800_state, a7800u2_pal, "Atari", "Atari 7800 (PAL) Hot", MACHINE_SUPPORTS_SAVE )
CONS( 1986, a7800pu2, a7800, 0, a7800u2_pal, a7800, a7800_state, a7800u2_pal, "Atari", "Atari 7800 (PAL) Hot", MACHINE_SUPPORTS_SAVE )