mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
(MESS) a7800.c progress: [Fabio Priuli]
- Rewritten cart emulation to use slot devices - Removed POKEY chip from the main unit since it was inside the carts (of course it gets enabled when you launch a game who contained it in its cart) - Added support for the High Score cart as a passthru cart: when you mount hiscore, a -cart2 switch will become available to mount the game you want to play - Properly implemented XBoarD and XM expansions as passthru carts as well, so that new syntax to run dkxm.a78 is "mess a7800 -cart xm -cart2 path\to\games\dkxm.a78" High Score support for XM shall work as well. - Big clean up of the driver, simplifying memory map, removing writes to ROM, etc. Out of whatsnew: In conclusion, a7800.c has been brought into the new millennium ;-)
This commit is contained in:
parent
fb3575054e
commit
a16673b284
10
.gitattributes
vendored
10
.gitattributes
vendored
@ -476,6 +476,15 @@ src/emu/bus/a2bus/laser128.c svneol=native#text/plain
|
||||
src/emu/bus/a2bus/laser128.h svneol=native#text/plain
|
||||
src/emu/bus/a2bus/timemasterho.c svneol=native#text/plain
|
||||
src/emu/bus/a2bus/timemasterho.h svneol=native#text/plain
|
||||
src/emu/bus/a7800/a78_carts.h svneol=native#text/plain
|
||||
src/emu/bus/a7800/a78_slot.c svneol=native#text/plain
|
||||
src/emu/bus/a7800/a78_slot.h svneol=native#text/plain
|
||||
src/emu/bus/a7800/hiscore.c svneol=native#text/plain
|
||||
src/emu/bus/a7800/hiscore.h svneol=native#text/plain
|
||||
src/emu/bus/a7800/rom.c svneol=native#text/plain
|
||||
src/emu/bus/a7800/rom.h svneol=native#text/plain
|
||||
src/emu/bus/a7800/xboard.c svneol=native#text/plain
|
||||
src/emu/bus/a7800/xboard.h svneol=native#text/plain
|
||||
src/emu/bus/abcbus/abc890.c svneol=native#text/plain
|
||||
src/emu/bus/abcbus/abc890.h svneol=native#text/plain
|
||||
src/emu/bus/abcbus/abcbus.c svneol=native#text/plain
|
||||
@ -8844,7 +8853,6 @@ src/mess/layout/z80netb.lay svneol=native#text/xml
|
||||
src/mess/layout/z80netf.lay svneol=native#text/xml
|
||||
src/mess/machine/6883sam.c svneol=native#text/plain
|
||||
src/mess/machine/6883sam.h svneol=native#text/plain
|
||||
src/mess/machine/a7800.c svneol=native#text/plain
|
||||
src/mess/machine/abc1600mac.c svneol=native#text/plain
|
||||
src/mess/machine/abc1600mac.h svneol=native#text/plain
|
||||
src/mess/machine/abc80kb.c svneol=native#text/plain
|
||||
|
208
hash/a7800.xml
208
hash/a7800.xml
File diff suppressed because it is too large
Load Diff
32
src/emu/bus/a7800/a78_carts.h
Normal file
32
src/emu/bus/a7800/a78_carts.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __A78_CARTS_H
|
||||
#define __A78_CARTS_H
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "rom.h"
|
||||
#include "xboard.h"
|
||||
#include "hiscore.h"
|
||||
|
||||
static SLOT_INTERFACE_START(a7800_cart)
|
||||
SLOT_INTERFACE_INTERNAL("a78_rom", A78_ROM)
|
||||
SLOT_INTERFACE_INTERNAL("a78_pokey", A78_ROM_POKEY)
|
||||
SLOT_INTERFACE_INTERNAL("a78_sg", A78_ROM_SG)
|
||||
SLOT_INTERFACE_INTERNAL("a78_sg_pokey", A78_ROM_SG_POKEY)
|
||||
SLOT_INTERFACE_INTERNAL("a78_sg_ram", A78_ROM_SG_RAM)
|
||||
// not sure which dev cart support banked ram, nor whether there shall be a 9banks or a non-sg version of this...
|
||||
SLOT_INTERFACE_INTERNAL("a78_bankram", A78_ROM_BANKRAM)
|
||||
SLOT_INTERFACE_INTERNAL("a78_sg9", A78_ROM_SG_9BANKS)
|
||||
SLOT_INTERFACE_INTERNAL("a78_xmc", A78_ROM_XM) // carts compatible with the expansions below (basically a 9Banks+POKEY)
|
||||
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_END
|
||||
|
||||
|
||||
// supported devices
|
||||
SLOT_INTERFACE_EXTERN(a78_cart);
|
||||
|
||||
#endif
|
514
src/emu/bus/a7800/a78_slot.c
Normal file
514
src/emu/bus/a7800/a78_slot.c
Normal file
@ -0,0 +1,514 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
|
||||
Atari 7800 cart emulation
|
||||
(through slot devices)
|
||||
|
||||
Emulation of the cartslot for Atari 7800
|
||||
|
||||
Quoting "ATARI 7800 BANKSWITCHING GUIDE" (by Eckhard Stolberg):
|
||||
7800 games can use the memory from $0400 to $047f, from $0500
|
||||
to $17ff and from $2800 to $ffff, but only the High-Score cart
|
||||
uses anything below $4000. It has 4KB of ROM at $3000-$3fff
|
||||
and 2KB of battery-backed RAM at $1000-$17ff.
|
||||
|
||||
Accordingly, we use the following handlers:
|
||||
- read_04xx/write_04xx for accesses in the $0400 to $047f range
|
||||
- read_10xx/write_10xx for accesses in the $1000 to $17ff range
|
||||
- read_30xx/write_30xx for accesses in the $3000 to $3fff range
|
||||
- read_40xx/write_40xx for accesses in the $4000 to $ffff range
|
||||
even if not all carts use all of them (in particular no cart type
|
||||
seems to use access to the ranges $0500 to $0fff and $2800 to $2fff)
|
||||
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "a78_slot.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type A78_CART_SLOT = &device_creator<a78_cart_slot_device>;
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_vcs_cart_interface - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_a78_cart_interface::device_a78_cart_interface (const machine_config &mconfig, device_t &device)
|
||||
: device_slot_card_interface(mconfig, device)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~device_a78_cart_interface - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_a78_cart_interface::~device_a78_cart_interface ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_alloc - alloc the space for the cart
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_a78_cart_interface::rom_alloc(UINT32 size)
|
||||
{
|
||||
if (m_rom == NULL)
|
||||
{
|
||||
// allocate rom
|
||||
m_rom.resize(size);
|
||||
|
||||
// setup other helpers
|
||||
if ((size / 0x4000) & 1) // compensate for SuperGame carts with 9 x 16K banks (to my knowledge no other cart has m_bank_mask != power of 2)
|
||||
m_bank_mask = (size / 0x4000) - 2;
|
||||
else
|
||||
m_bank_mask = (size / 0x4000) - 1;
|
||||
|
||||
// the rom is mapped to the top of the memory area
|
||||
// so we store the starting point of data to simplify
|
||||
// the access handling
|
||||
m_base_rom = 0x10000 - size;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ram_alloc - alloc the space for the on-cart RAM
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_a78_cart_interface::ram_alloc(UINT32 size)
|
||||
{
|
||||
if (m_ram == NULL)
|
||||
{
|
||||
m_ram.resize(size);
|
||||
device().save_item(NAME(m_ram));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ram_alloc - alloc the space for the on-cart RAM
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_a78_cart_interface::nvram_alloc(UINT32 size)
|
||||
{
|
||||
if (m_nvram == NULL)
|
||||
{
|
||||
m_nvram.resize(size);
|
||||
device().save_item(NAME(m_nvram));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// a78_cart_slot_device - constructor
|
||||
//-------------------------------------------------
|
||||
a78_cart_slot_device::a78_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, A78_CART_SLOT, "Atari 7800 Cartridge Slot", tag, owner, clock, "a78_cart_slot", __FILE__),
|
||||
device_image_interface(mconfig, *this),
|
||||
device_slot_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// a78_cart_slot_device - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
a78_cart_slot_device::~a78_cart_slot_device()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void a78_cart_slot_device::device_start()
|
||||
{
|
||||
m_cart = dynamic_cast<device_a78_cart_interface *>(get_card_device());
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void a78_cart_slot_device::device_config_complete()
|
||||
{
|
||||
// set brief and instance name
|
||||
update_names();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
call load
|
||||
-------------------------------------------------*/
|
||||
|
||||
//-------------------------------------------------
|
||||
// A78 PCBs
|
||||
//-------------------------------------------------
|
||||
|
||||
struct a78_slot
|
||||
{
|
||||
int pcb_id;
|
||||
const char *slot_option;
|
||||
};
|
||||
|
||||
// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
|
||||
static const a78_slot slot_list[] =
|
||||
{
|
||||
{ A78_TYPE0, "a78_rom" },
|
||||
{ A78_TYPE1, "a78_pokey" },
|
||||
{ A78_TYPE2, "a78_sg" },
|
||||
{ A78_TYPE3, "a78_sg_pokey" },
|
||||
{ A78_TYPE6, "a78_sg_ram" },
|
||||
{ A78_TYPEA, "a78_sg9" },
|
||||
{ A78_TYPEB, "a78_xmc" },
|
||||
{ A78_ABSOLUTE, "a78_abs" },
|
||||
{ A78_ACTIVISION, "a78_act" },
|
||||
{ A78_HSC, "a78_hsc" },
|
||||
{ A78_BANKRAM, "a78_bankram" },
|
||||
{ A78_XB_BOARD, "a78_xboard" },
|
||||
{ A78_XM_BOARD, "a78_xm" },
|
||||
};
|
||||
|
||||
static int a78_get_pcb_id(const char *slot)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||
{
|
||||
if (!core_stricmp(slot_list[i].slot_option, slot))
|
||||
return slot_list[i].pcb_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *a78_get_slot(int type)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||
{
|
||||
if (slot_list[i].pcb_id == type)
|
||||
return slot_list[i].slot_option;
|
||||
}
|
||||
|
||||
return "a78_rom";
|
||||
}
|
||||
|
||||
bool a78_cart_slot_device::call_load()
|
||||
{
|
||||
UINT8 *ROM;
|
||||
UINT32 len;
|
||||
|
||||
if (software_entry() != NULL)
|
||||
{
|
||||
const char *pcb_name;
|
||||
len = get_software_region_length("rom");
|
||||
|
||||
m_cart->rom_alloc(len);
|
||||
ROM = m_cart->get_rom_base();
|
||||
memcpy(ROM, get_software_region("rom"), len);
|
||||
|
||||
if ((pcb_name = get_feature("slot")) != NULL)
|
||||
m_type = a78_get_pcb_id(pcb_name);
|
||||
else
|
||||
m_type = A78_TYPE0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load and check the header
|
||||
char head[128];
|
||||
fread(head, 128);
|
||||
|
||||
if (verify_header((char *)head) == IMAGE_VERIFY_FAIL)
|
||||
return IMAGE_INIT_FAIL;
|
||||
|
||||
len = (head[49] << 24) |(head[50] << 16) |(head[51] << 8) | head[52];
|
||||
if (len + 128 > length())
|
||||
{
|
||||
logerror("Invalid length in the header. The game might be corrupted.\n");
|
||||
len = length() - 128;
|
||||
}
|
||||
|
||||
switch ((head[53] << 8) | head[54])
|
||||
{
|
||||
case 0x0000:
|
||||
m_type = A78_TYPE0;
|
||||
break;
|
||||
case 0x0001:
|
||||
m_type = A78_TYPE1;
|
||||
break;
|
||||
case 0x0002:
|
||||
m_type = A78_TYPE2;
|
||||
break;
|
||||
case 0x0003:
|
||||
m_type = A78_TYPE3;
|
||||
break;
|
||||
case 0x0006:
|
||||
m_type = A78_TYPE6;
|
||||
break;
|
||||
case 0x000a:
|
||||
m_type = A78_TYPEA;
|
||||
break;
|
||||
case 0x000b:
|
||||
m_type = A78_TYPEB;
|
||||
break;
|
||||
case 0x0020:
|
||||
m_type = A78_BANKRAM;
|
||||
break;
|
||||
case 0x0100:
|
||||
m_type = A78_ABSOLUTE;
|
||||
break;
|
||||
case 0x0200:
|
||||
m_type = A78_ACTIVISION;
|
||||
break;
|
||||
}
|
||||
logerror("Cart type: %x\n", m_type);
|
||||
|
||||
// This field is currently only used for logging
|
||||
m_stick_type = head[55];
|
||||
|
||||
m_cart->rom_alloc(len);
|
||||
ROM = m_cart->get_rom_base();
|
||||
fread(ROM, len);
|
||||
}
|
||||
|
||||
//printf("Type: %s\n", a78_get_slot(m_type));
|
||||
|
||||
if (m_type == A78_TYPE6)
|
||||
m_cart->ram_alloc(0x4000);
|
||||
if (m_type == A78_BANKRAM)
|
||||
m_cart->ram_alloc(0x8000);
|
||||
if (m_type == A78_XB_BOARD || m_type == A78_XM_BOARD)
|
||||
m_cart->ram_alloc(0x20000);
|
||||
if (m_type == A78_HSC || m_type == A78_XM_BOARD)
|
||||
{
|
||||
m_cart->nvram_alloc(0x800);
|
||||
battery_load(m_cart->get_nvram_base(), 0x800, 0xff);
|
||||
}
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
|
||||
void a78_partialhash(hash_collection &dest, const unsigned char *data,
|
||||
unsigned long length, const char *functions)
|
||||
{
|
||||
if (length <= 128)
|
||||
return;
|
||||
dest.compute(&data[128], length - 128, functions);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
call_unload
|
||||
-------------------------------------------------*/
|
||||
|
||||
void a78_cart_slot_device::call_unload()
|
||||
{
|
||||
if (m_cart && m_cart->get_nvram_size())
|
||||
battery_save(m_cart->get_nvram_base(), 0x800);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
call softlist load
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool a78_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
|
||||
{
|
||||
load_software_part_region(*this, swlist, swname, start_entry );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
identify_cart_type - code to detect cart type from
|
||||
fullpath
|
||||
-------------------------------------------------*/
|
||||
|
||||
int a78_cart_slot_device::verify_header(char *header)
|
||||
{
|
||||
const char *magic = "ATARI7800";
|
||||
|
||||
if (strncmp(magic, header + 1, 9))
|
||||
{
|
||||
logerror("Not a valid A7800 image\n");
|
||||
return IMAGE_VERIFY_FAIL;
|
||||
}
|
||||
|
||||
logerror("returning ID_OK\n");
|
||||
return IMAGE_VERIFY_PASS;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
get default card software
|
||||
-------------------------------------------------*/
|
||||
|
||||
void a78_cart_slot_device::get_default_card_software(astring &result)
|
||||
{
|
||||
if (open_image_file(mconfig().options()))
|
||||
{
|
||||
const char *slot_string = "a78_rom";
|
||||
dynamic_buffer head(128);
|
||||
int type = A78_TYPE0;
|
||||
|
||||
// Load and check the header
|
||||
core_fread(m_file, head, 128);
|
||||
switch ((head[53] << 8) | head[54])
|
||||
{
|
||||
case 0x0000:
|
||||
type = A78_TYPE0;
|
||||
break;
|
||||
case 0x0001:
|
||||
type = A78_TYPE1;
|
||||
break;
|
||||
case 0x0002:
|
||||
type = A78_TYPE2;
|
||||
break;
|
||||
case 0x0003:
|
||||
type = A78_TYPE3;
|
||||
break;
|
||||
case 0x0004:
|
||||
type = A78_TYPE6;
|
||||
break;
|
||||
case 0x000a:
|
||||
type = A78_TYPEA;
|
||||
break;
|
||||
case 0x000b:
|
||||
type = A78_TYPEB;
|
||||
break;
|
||||
case 0x0020:
|
||||
m_type = A78_BANKRAM;
|
||||
break;
|
||||
case 0x0100:
|
||||
type = A78_ABSOLUTE;
|
||||
break;
|
||||
case 0x0200:
|
||||
type = A78_ACTIVISION;
|
||||
break;
|
||||
}
|
||||
logerror("Cart type: %x\n", type);
|
||||
slot_string = a78_get_slot(type);
|
||||
|
||||
clear();
|
||||
|
||||
result.cpy(slot_string);
|
||||
}
|
||||
else
|
||||
software_get_default_slot(result, "a78_rom");
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
read
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_cart_slot_device::read_04xx)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_04xx(space, offset, mem_mask);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_cart_slot_device::read_10xx)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_10xx(space, offset, mem_mask);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_cart_slot_device::read_30xx)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_30xx(space, offset, mem_mask);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_cart_slot_device::read_40xx)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_40xx(space, offset, mem_mask);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
write
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(a78_cart_slot_device::write_04xx)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->write_04xx(space, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_cart_slot_device::write_10xx)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->write_10xx(space, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_cart_slot_device::write_30xx)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->write_30xx(space, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_cart_slot_device::write_40xx)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->write_40xx(space, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
|
||||
/* Header format
|
||||
0 Header version - 1 byte
|
||||
1..16 "ATARI7800 " - 16 bytes
|
||||
17..48 Cart title - 32 bytes
|
||||
49..52 data length - 4 bytes
|
||||
53..54 cart type - 2 bytes
|
||||
bit 0 0x01 - pokey cart
|
||||
bit 1 0x02 - supercart bank switched
|
||||
bit 2 0x04 - supercart RAM at $4000
|
||||
bit 3 0x08 - additional ROM at $4000
|
||||
bit 4 0x10 - bank 6 at $4000
|
||||
bit 5 0x20 - supercart banked RAM
|
||||
|
||||
bit 8-15 - Special
|
||||
0 = Normal cart
|
||||
1 = Absolute (F18 Hornet)
|
||||
2 = Activision
|
||||
|
||||
55 controller 1 type - 1 byte
|
||||
56 controller 2 type - 1 byte
|
||||
0 = None
|
||||
1 = Joystick
|
||||
2 = Light Gun
|
||||
57 0 = NTSC/1 = PAL
|
||||
|
||||
100..127 "ACTUAL CART DATA STARTS HERE" - 28 bytes
|
||||
|
||||
Versions:
|
||||
Version 0: Initial release
|
||||
Version 1: Added PAL/NTSC bit. Added Special cart byte.
|
||||
Changed 53 bit 2, added bit 3
|
||||
|
||||
*/
|
||||
|
||||
// TODO: log all properties from the header
|
142
src/emu/bus/a7800/a78_slot.h
Normal file
142
src/emu/bus/a7800/a78_slot.h
Normal file
@ -0,0 +1,142 @@
|
||||
#ifndef __A78_SLOT_H
|
||||
#define __A78_SLOT_H
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* PCB */
|
||||
enum
|
||||
{
|
||||
A78_TYPE0 = 0, // standard 8K/16K/32K games, no bankswitch
|
||||
A78_TYPE1, // as TYPE0 + POKEY chip on the PCB
|
||||
A78_TYPE2, // Atari SuperGame pcb (8x16K banks with bankswitch)
|
||||
A78_TYPE3, // as TYPE1 + POKEY chip on the PCB
|
||||
A78_TYPE6, // as TYPE1 + RAM IC on the PCB
|
||||
A78_TYPEA, // Alien Brigade, Crossbow (9x16K banks with diff bankswitch)
|
||||
A78_ABSOLUTE, // F18 Hornet
|
||||
A78_ACTIVISION, // Double Dragon, Rampage
|
||||
A78_HSC, // Atari HighScore cart
|
||||
A78_BANKRAM, // SuperGame + 32K RAM banked (untested)
|
||||
A78_XB_BOARD, // A7800 Expansion Board (it shall more or less apply to the Expansion Module too, but this is not officially released yet)
|
||||
A78_XM_BOARD, // A7800 XM Expansion Module (theoretical specs only, since this is not officially released yet)
|
||||
A78_TYPEB // Cart exploiting the XB board, but possibly also compatible with non-expanded A7800
|
||||
};
|
||||
|
||||
|
||||
// ======================> device_a78_cart_interface
|
||||
|
||||
class device_a78_cart_interface : public device_slot_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
device_a78_cart_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_a78_cart_interface();
|
||||
|
||||
// memory accessor
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_10xx) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_30xx) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx) { return 0xff; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx) {}
|
||||
virtual DECLARE_WRITE8_MEMBER(write_10xx) {}
|
||||
virtual DECLARE_WRITE8_MEMBER(write_30xx) {}
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx) {}
|
||||
|
||||
void rom_alloc(UINT32 size);
|
||||
void ram_alloc(UINT32 size);
|
||||
void nvram_alloc(UINT32 size);
|
||||
UINT8* get_rom_base() { return m_rom; }
|
||||
UINT8* get_ram_base() { return m_ram; }
|
||||
UINT8* get_nvram_base() { return m_nvram; }
|
||||
UINT32 get_rom_size() { return m_rom.bytes(); }
|
||||
UINT32 get_ram_size() { return m_ram.bytes(); }
|
||||
UINT32 get_nvram_size() { return m_nvram.bytes(); }
|
||||
|
||||
protected:
|
||||
// internal state
|
||||
dynamic_buffer m_rom;
|
||||
dynamic_buffer m_ram;
|
||||
dynamic_buffer m_nvram; // HiScore cart can save scores!
|
||||
// helpers
|
||||
UINT32 m_base_rom;
|
||||
int m_bank_mask;
|
||||
};
|
||||
|
||||
|
||||
void a78_partialhash(hash_collection &dest, const unsigned char *data, unsigned long length, const char *functions);
|
||||
|
||||
|
||||
// ======================> a78_cart_slot_device
|
||||
|
||||
class a78_cart_slot_device : public device_t,
|
||||
public device_image_interface,
|
||||
public device_slot_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~a78_cart_slot_device();
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_config_complete();
|
||||
|
||||
// image-level overrides
|
||||
virtual bool call_load();
|
||||
virtual void call_unload();
|
||||
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
|
||||
|
||||
int get_cart_type() { return m_type; };
|
||||
int identify_cart_type(UINT8 *ROM, UINT32 len);
|
||||
bool has_cart() { return m_cart != NULL; }
|
||||
|
||||
virtual iodevice_t image_type() const { return IO_CARTSLOT; }
|
||||
virtual bool is_readable() const { return 1; }
|
||||
virtual bool is_writeable() const { return 0; }
|
||||
virtual bool is_creatable() const { return 0; }
|
||||
virtual bool must_be_loaded() const { return 0; }
|
||||
virtual bool is_reset_on_load() const { return 1; }
|
||||
virtual const option_guide *create_option_guide() const { return NULL; }
|
||||
virtual const char *image_interface() const { return "a7800_cart"; }
|
||||
virtual const char *file_extensions() const { return "bin,a78"; }
|
||||
virtual device_image_partialhash_func get_partial_hash() const { return &a78_partialhash; }
|
||||
|
||||
// slot interface overrides
|
||||
virtual void get_default_card_software(astring &result);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_10xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_30xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_10xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_30xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
private:
|
||||
device_a78_cart_interface* m_cart;
|
||||
int m_type;
|
||||
int m_stick_type;
|
||||
|
||||
int verify_header(char *header);
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type A78_CART_SLOT;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MCFG_A78_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
|
||||
MCFG_DEVICE_ADD(_tag, A78_CART_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
|
||||
|
||||
|
||||
#endif
|
76
src/emu/bus/a7800/hiscore.c
Normal file
76
src/emu/bus/a7800/hiscore.c
Normal file
@ -0,0 +1,76 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
A7800 HighScore passthrough cart emulation
|
||||
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "hiscore.h"
|
||||
#include "a78_carts.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type A78_HISCORE = &device_creator<a78_hiscore_device>;
|
||||
|
||||
|
||||
a78_hiscore_device::a78_hiscore_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_device(mconfig, A78_HISCORE, "Atari 7800 High Score Cart", tag, owner, clock, "a78_highscore", __FILE__),
|
||||
m_hscslot(*this, "hsc_slot")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( a78_highscore )
|
||||
MCFG_A78_CARTRIDGE_ADD("hsc_slot", a7800_cart, NULL)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor a78_hiscore_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( a78_highscore );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_hiscore_device::read_10xx)
|
||||
{
|
||||
return m_nvram[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_hiscore_device::write_10xx)
|
||||
{
|
||||
m_nvram[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_hiscore_device::read_30xx)
|
||||
{
|
||||
return m_rom[offset];
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_hiscore_device::read_04xx)
|
||||
{
|
||||
return m_hscslot->read_04xx(space, offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_hiscore_device::write_04xx)
|
||||
{
|
||||
m_hscslot->write_04xx(space, offset, data);
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_hiscore_device::read_40xx)
|
||||
{
|
||||
return m_hscslot->read_40xx(space, offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_hiscore_device::write_40xx)
|
||||
{
|
||||
m_hscslot->write_40xx(space, offset, data);
|
||||
}
|
||||
|
38
src/emu/bus/a7800/hiscore.h
Normal file
38
src/emu/bus/a7800/hiscore.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef __A78_HISCORE_H
|
||||
#define __A78_HISCORE_H
|
||||
|
||||
#include "a78_slot.h"
|
||||
#include "rom.h"
|
||||
|
||||
|
||||
// ======================> a78_hiscore_device
|
||||
|
||||
class a78_hiscore_device : public a78_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_hiscore_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_10xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_10xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_30xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
required_device<a78_cart_slot_device> m_hscslot;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type A78_HISCORE;
|
||||
|
||||
|
||||
#endif
|
512
src/emu/bus/a7800/rom.c
Normal file
512
src/emu/bus/a7800/rom.c
Normal file
@ -0,0 +1,512 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
A7800 ROM cart emulation
|
||||
|
||||
For the moment we use separate devices for each combination of hardware
|
||||
- bankswitch or not
|
||||
- pokey or not
|
||||
- 9 banks or not
|
||||
etc...
|
||||
But we might merge many of these if they become too many (e.g. could there be banked 32L RAM also
|
||||
in a 9banks cart or in a cart with no bankswitch?)
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "rom.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type A78_ROM = &device_creator<a78_rom_device>;
|
||||
const device_type A78_ROM_SG = &device_creator<a78_rom_sg_device>;
|
||||
const device_type A78_ROM_POKEY = &device_creator<a78_rom_pokey_device>;
|
||||
const device_type A78_ROM_SG_POKEY = &device_creator<a78_rom_sg_pokey_device>;
|
||||
const device_type A78_ROM_SG_RAM = &device_creator<a78_rom_sg_ram_device>;
|
||||
const device_type A78_ROM_BANKRAM = &device_creator<a78_rom_bankram_device>;
|
||||
const device_type A78_ROM_SG_9BANKS = &device_creator<a78_rom_sg_9banks_device>;
|
||||
const device_type A78_ROM_XM = &device_creator<a78_rom_xm_device>;
|
||||
const device_type A78_ROM_ABSOLUTE = &device_creator<a78_rom_abs_device>;
|
||||
const device_type A78_ROM_ACTIVISION = &device_creator<a78_rom_act_device>;
|
||||
|
||||
|
||||
a78_rom_device::a78_rom_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)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_a78_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
a78_rom_device::a78_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, A78_ROM, "Atari 7800 ROM Carts w/no Bankswitch", tag, owner, clock, "a78_rom", __FILE__),
|
||||
device_a78_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
a78_rom_pokey_device::a78_rom_pokey_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_device(mconfig, A78_ROM_POKEY, "Atari 7800 ROM Carts w/no Bankswitch + POKEY", tag, owner, clock, "a78_rom_pok", __FILE__),
|
||||
m_pokey(*this, "pokey")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_sg_device::a78_rom_sg_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)
|
||||
: a78_rom_device(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
{
|
||||
}
|
||||
|
||||
a78_rom_sg_device::a78_rom_sg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_device(mconfig, A78_ROM_SG, "Atari 7800 ROM Carts w/SuperGame Bankswitch", tag, owner, clock, "a78_rom_sg", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
a78_rom_sg_pokey_device::a78_rom_sg_pokey_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_sg_device(mconfig, A78_ROM_SG_POKEY, "Atari 7800 ROM Carts w/SuperGame Bankswitch + POKEY", tag, owner, clock, "a78_rom_sgp", __FILE__),
|
||||
m_pokey(*this, "pokey")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_sg_ram_device::a78_rom_sg_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_sg_device(mconfig, A78_ROM_SG_RAM, "Atari 7800 ROM Carts w/SuperGame Bankswitch + RAM", tag, owner, clock, "a78_rom_sgr", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_bankram_device::a78_rom_bankram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_sg_device(mconfig, A78_ROM_BANKRAM, "Atari 7800 ROM Carts w/SuperGame Bankswitch + Banked RAM", tag, owner, clock, "a78_rom_bankram", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_sg_9banks_device::a78_rom_sg_9banks_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)
|
||||
: a78_rom_sg_device(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
{
|
||||
}
|
||||
|
||||
a78_rom_sg_9banks_device::a78_rom_sg_9banks_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_sg_device(mconfig, A78_ROM_SG_9BANKS, "Atari 7800 ROM Carts w/SuperGame 9Banks", tag, owner, clock, "a78_rom_sg9", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_xm_device::a78_rom_xm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_sg_9banks_device(mconfig, A78_ROM_XM, "Atari 7800 ROM Carts w/SuperGame 9Banks + POKEY (XM demo)", tag, owner, clock, "a78_rom_xm", __FILE__),
|
||||
m_pokey(*this, "pokey")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_abs_device::a78_rom_abs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_device(mconfig, A78_ROM_ABSOLUTE, "Atari 7800 ROM Carts w/Absolute Bankswitch", tag, owner, clock, "a78_rom_abs", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_rom_act_device::a78_rom_act_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_device(mconfig, A78_ROM_ACTIVISION, "Atari 7800 ROM Carts w/Activision Bankswitch", tag, owner, clock, "a78_rom_act", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void a78_rom_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void a78_rom_device::device_reset()
|
||||
{
|
||||
}
|
||||
|
||||
void a78_rom_sg_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_bank));
|
||||
}
|
||||
|
||||
void a78_rom_sg_device::device_reset()
|
||||
{
|
||||
m_bank = 0;
|
||||
}
|
||||
|
||||
void a78_rom_bankram_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_bank));
|
||||
save_item(NAME(m_ram_bank));
|
||||
}
|
||||
|
||||
void a78_rom_bankram_device::device_reset()
|
||||
{
|
||||
m_bank = 0;
|
||||
m_ram_bank = 0;
|
||||
}
|
||||
|
||||
void a78_rom_abs_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_bank));
|
||||
}
|
||||
|
||||
void a78_rom_abs_device::device_reset()
|
||||
{
|
||||
m_bank = 0;
|
||||
}
|
||||
|
||||
void a78_rom_act_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_bank));
|
||||
}
|
||||
|
||||
void a78_rom_act_device::device_reset()
|
||||
{
|
||||
m_bank = 0;
|
||||
}
|
||||
|
||||
// TO DO: do we need a PAL variant?!?
|
||||
static MACHINE_CONFIG_FRAGMENT( a78_pokey )
|
||||
MCFG_SPEAKER_STANDARD_MONO("addon")
|
||||
|
||||
MCFG_SOUND_ADD("pokey", POKEY, XTAL_14_31818MHz/8)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "addon", 1.00)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with no bankswitch (8K to 48K)
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_device::read_40xx)
|
||||
{
|
||||
if (offset + 0x4000 < m_base_rom)
|
||||
return 0xff;
|
||||
else
|
||||
return m_rom[offset + 0x4000 - m_base_rom];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with no bankswitch + POKEY chip
|
||||
The Pokey chips is accessed at 0x0450-0x045f or
|
||||
by writing at 0x4000-0x7fff in some games.
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(a78_rom_pokey_device::write_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
m_pokey->write(space, offset & 0x0f, data);
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_rom_pokey_device::read_04xx)
|
||||
{
|
||||
if (offset >= 0x50 && offset < 0x60)
|
||||
return m_pokey->read(space, offset & 0x0f);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_pokey_device::write_04xx)
|
||||
{
|
||||
if (offset >= 0x50 && offset < 0x60)
|
||||
m_pokey->write(space, offset & 0x0f, data);
|
||||
}
|
||||
|
||||
machine_config_constructor a78_rom_pokey_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( a78_pokey );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with SuperGame bankswitch:
|
||||
8 x 16K banks mappable in 0x8000-0xbfff
|
||||
bank 7 is always mapped in 0xc000-0xffff
|
||||
range 0x4000-0x7fff is not clear: some games
|
||||
expect bank 6 to be mapped there, others
|
||||
have open bus (we assume the former until
|
||||
a game requires more precise behavior or
|
||||
some test is run)
|
||||
Note that the code is written so that also
|
||||
homebrew games with larger ROMs work!
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_sg_device::read_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
return m_rom[(offset & 0x3fff) + ((m_bank_mask - 1) * 0x4000)]; // second to last bank (is this always ok?!?)
|
||||
else if (offset < 0x8000)
|
||||
return m_rom[(offset & 0x3fff) + (m_bank * 0x4000)];
|
||||
else
|
||||
return m_rom[(offset & 0x3fff) + (m_bank_mask * 0x4000)]; // last bank
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_sg_device::write_40xx)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x8000)
|
||||
m_bank = data & m_bank_mask;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with SuperGame bankswitch + POKEY chip
|
||||
As above, the Pokey chips is accessed at
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(a78_rom_sg_pokey_device::write_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
m_pokey->write(space, offset & 0x0f, data);
|
||||
else if (offset < 0x8000)
|
||||
m_bank = data & m_bank_mask;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_rom_sg_pokey_device::read_04xx)
|
||||
{
|
||||
if (offset >= 0x50 && offset < 0x60)
|
||||
return m_pokey->read(space, offset & 0x0f);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_sg_pokey_device::write_04xx)
|
||||
{
|
||||
if (offset >= 0x50 && offset < 0x60)
|
||||
m_pokey->write(space, offset & 0x0f, data);
|
||||
}
|
||||
|
||||
machine_config_constructor a78_rom_sg_pokey_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( a78_pokey );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with SuperGame bankswitch + 16K RAM
|
||||
FIXME: Some games contained only 8K of RAM, but
|
||||
for the moment we treat all as 16K of RAM even if
|
||||
from softlist we shall differentiate between them.
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_sg_ram_device::read_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
return m_ram[offset];
|
||||
else if (offset < 0x8000)
|
||||
return m_rom[(offset & 0x3fff) + (m_bank * 0x4000)];
|
||||
else
|
||||
return m_rom[(offset & 0x3fff) + (m_bank_mask * 0x4000)]; // last bank
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_sg_ram_device::write_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
m_ram[offset] = data;
|
||||
else if (offset < 0x8000)
|
||||
m_bank = data & m_bank_mask;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with SuperGame bankswitch + 32K RAM:
|
||||
RAM bank is selected by writing with bit5 enabled
|
||||
in 0x4000-0x7fff range (bit0-bit4 give the ROM bank)
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_bankram_device::read_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
return m_ram[offset + (m_ram_bank * 0x4000)];
|
||||
else if (offset < 0x8000)
|
||||
return m_rom[(offset & 0x3fff) + (m_bank * 0x4000)];
|
||||
else
|
||||
return m_rom[(offset & 0x3fff) + (m_bank_mask * 0x4000)]; // last bank
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_bankram_device::write_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
m_ram[offset] = data;
|
||||
else if (offset < 0x8000)
|
||||
{
|
||||
m_bank = data & m_bank_mask;
|
||||
m_ram_bank = BIT(data, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with SuperGame bankswitch 9banks:
|
||||
9 x 16K banks mappable in 0x8000-0xbfff
|
||||
bank 7 is always mapped in 0xc000-0xffff
|
||||
|
||||
GAMES:
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_sg_9banks_device::read_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
return m_rom[(offset & 0x3fff)];
|
||||
else if (offset < 0x8000)
|
||||
return m_rom[(offset & 0x3fff) + (m_bank * 0x4000)];
|
||||
else
|
||||
return m_rom[(offset & 0x3fff) + ((m_bank_mask + 1) * 0x4000)]; // last bank
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_sg_9banks_device::write_40xx)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x8000)
|
||||
m_bank = (data & m_bank_mask) + 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts using XM expansion module or XBoarD expansion
|
||||
The only game using this (Donkey Kong XM demo) is
|
||||
144K + POKEY, so that it's like the above with the
|
||||
addition of the POKEY.
|
||||
|
||||
GAMES: Donkey Kong XM demo
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(a78_rom_xm_device::write_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
m_pokey->write(space, offset & 0x0f, data);
|
||||
else if (offset < 0x8000)
|
||||
m_bank = (data & m_bank_mask) + 1;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a78_rom_xm_device::read_04xx)
|
||||
{
|
||||
if (offset >= 0x50 && offset < 0x60)
|
||||
return m_pokey->read(space, offset & 0x0f);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_xm_device::write_04xx)
|
||||
{
|
||||
if (offset >= 0x50 && offset < 0x60)
|
||||
m_pokey->write(space, offset & 0x0f, data);
|
||||
}
|
||||
|
||||
machine_config_constructor a78_rom_xm_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( a78_pokey );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with Absolute bankswitch:
|
||||
64K games. Lower 32K are 2 banks of 16K to be mapped
|
||||
in 0x4000-0x7fff, depending on the value written
|
||||
at 0x8000. Higher 32K are fixed in 0x8000-0xffff
|
||||
|
||||
GAMES: F-18 Hornet
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_abs_device::read_40xx)
|
||||
{
|
||||
if (offset < 0x4000)
|
||||
return m_rom[(offset & 0x3fff) + (m_bank * 0x4000)];
|
||||
else
|
||||
{
|
||||
offset -= 0x4000;
|
||||
return m_rom[offset + 0x8000];
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_abs_device::write_40xx)
|
||||
{
|
||||
if (offset == 0x4000)
|
||||
{
|
||||
if (data & 1)
|
||||
m_bank = 0;
|
||||
else if (data & 2)
|
||||
m_bank = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
||||
Carts with Activision bankswitch:
|
||||
128K games. 8 x 16K banks (0-7) to be mapped at
|
||||
0xa000-0xdfff. Bank is selected depending on the
|
||||
address written in 0xff80-0xff87.
|
||||
The rest of the memory is as follows:
|
||||
0x4000-0x5fff second 8kb of bank 6
|
||||
0x6000-0x7fff first 8kb of bank 6
|
||||
0x8000-0x9fff second 8kb of bank 7
|
||||
0xe000-0xffff first 8kb of bank 7
|
||||
|
||||
GAMES: Double Dragon, Rampage.
|
||||
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(a78_rom_act_device::read_40xx)
|
||||
{
|
||||
UINT8 data = 0xff;
|
||||
UINT16 addr = offset & 0x1fff;
|
||||
|
||||
// offset goes from 0 to 0xc000
|
||||
switch (offset & 0xe000)
|
||||
{
|
||||
case 0x0000:
|
||||
data = m_rom[addr + 0x1a000];
|
||||
break;
|
||||
case 0x2000:
|
||||
data = m_rom[addr + 0x18000];
|
||||
break;
|
||||
case 0x4000:
|
||||
data = m_rom[addr + 0x1e000];
|
||||
break;
|
||||
case 0x6000:
|
||||
data = m_rom[addr + (m_bank * 0x4000)];
|
||||
break;
|
||||
case 0x8000:
|
||||
data = m_rom[addr + (m_bank * 0x4000) + 0x2000];
|
||||
break;
|
||||
case 0xa000:
|
||||
data = m_rom[addr + 0x1c000];
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a78_rom_act_device::write_40xx)
|
||||
{
|
||||
if (offset >= 0xbf80 && offset <= 0xbf87)
|
||||
m_bank = offset & 7;
|
||||
}
|
217
src/emu/bus/a7800/rom.h
Normal file
217
src/emu/bus/a7800/rom.h
Normal file
@ -0,0 +1,217 @@
|
||||
#ifndef __A78_ROM_H
|
||||
#define __A78_ROM_H
|
||||
|
||||
#include "a78_slot.h"
|
||||
#include "sound/pokey.h"
|
||||
|
||||
|
||||
// ======================> a78_rom_device
|
||||
|
||||
class a78_rom_device : public device_t,
|
||||
public device_a78_cart_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_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);
|
||||
a78_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_pokey_device
|
||||
|
||||
class a78_rom_pokey_device : public a78_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_pokey_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
required_device<pokey_device> m_pokey;
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_sg_device
|
||||
|
||||
class a78_rom_sg_device : public a78_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_sg_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);
|
||||
a78_rom_sg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
int m_bank;
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_sg_pokey_device
|
||||
|
||||
class a78_rom_sg_pokey_device : public a78_rom_sg_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_sg_pokey_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
required_device<pokey_device> m_pokey;
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_sg_ram_device
|
||||
|
||||
class a78_rom_sg_ram_device : public a78_rom_sg_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_sg_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_bankram_device
|
||||
|
||||
class a78_rom_bankram_device : public a78_rom_sg_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_bankram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
int m_ram_bank;
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_sg_9banks_device
|
||||
|
||||
class a78_rom_sg_9banks_device : public a78_rom_sg_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_sg_9banks_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);
|
||||
a78_rom_sg_9banks_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_xm_device
|
||||
|
||||
class a78_rom_xm_device : public a78_rom_sg_9banks_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_xm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
required_device<pokey_device> m_pokey;
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_abs_device
|
||||
|
||||
class a78_rom_abs_device : public a78_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_abs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
int m_bank;
|
||||
};
|
||||
|
||||
|
||||
// ======================> a78_rom_act_device
|
||||
|
||||
class a78_rom_act_device : public a78_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_rom_act_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
int m_bank;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type A78_ROM;
|
||||
extern const device_type A78_ROM_SG;
|
||||
extern const device_type A78_ROM_POKEY;
|
||||
extern const device_type A78_ROM_SG_POKEY;
|
||||
extern const device_type A78_ROM_SG_RAM;
|
||||
extern const device_type A78_ROM_BANKRAM;
|
||||
extern const device_type A78_ROM_SG_9BANKS;
|
||||
extern const device_type A78_ROM_XM;
|
||||
extern const device_type A78_ROM_ABSOLUTE;
|
||||
extern const device_type A78_ROM_ACTIVISION;
|
||||
|
||||
|
||||
#endif
|
178
src/emu/bus/a7800/xboard.c
Normal file
178
src/emu/bus/a7800/xboard.c
Normal file
@ -0,0 +1,178 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
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
|
||||
- verify whether high score works fine with XM
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "xboard.h"
|
||||
#include "a78_carts.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type A78_XBOARD = &device_creator<a78_xboard_device>;
|
||||
const device_type A78_XM = &device_creator<a78_xm_device>;
|
||||
|
||||
|
||||
a78_xboard_device::a78_xboard_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)
|
||||
: a78_rom_device(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_xbslot(*this, "xb_slot"),
|
||||
m_pokey(*this, "xb_pokey")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_xboard_device::a78_xboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_rom_device(mconfig, A78_XBOARD, "Atari 7800 XBoarD expansion", tag, owner, clock, "a78_xboard", __FILE__),
|
||||
m_xbslot(*this, "xb_slot"),
|
||||
m_pokey(*this, "xb_pokey")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
a78_xm_device::a78_xm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: a78_xboard_device(mconfig, A78_XM, "Atari 7800 XM expansion module", tag, owner, clock, "a78_xm", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( a78_xb )
|
||||
MCFG_A78_CARTRIDGE_ADD("xb_slot", a7800_cart, NULL)
|
||||
|
||||
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_constructor a78_xboard_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( a78_xb );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
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];
|
||||
}
|
||||
|
57
src/emu/bus/a7800/xboard.h
Normal file
57
src/emu/bus/a7800/xboard.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef __A78_XBOARD_H
|
||||
#define __A78_XBOARD_H
|
||||
|
||||
#include "a78_slot.h"
|
||||
#include "rom.h"
|
||||
#include "sound/pokey.h"
|
||||
|
||||
|
||||
// ======================> a78_xboard_device
|
||||
|
||||
class a78_xboard_device : public a78_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_xboard_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);
|
||||
a78_xboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_04xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_04xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_40xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_40xx);
|
||||
|
||||
protected:
|
||||
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
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a78_xm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_10xx);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_10xx);
|
||||
virtual DECLARE_READ8_MEMBER(read_30xx);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type A78_XBOARD;
|
||||
extern const device_type A78_XM;
|
||||
|
||||
|
||||
#endif
|
@ -14,6 +14,20 @@ BUSSRC = $(EMUSRC)/bus
|
||||
BUSOBJ = $(EMUOBJ)/bus
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/bus/a7800/a78_slot.h,BUSES += A7800
|
||||
#-------------------------------------------------
|
||||
|
||||
ifneq ($(filter A7800,$(BUSES)),)
|
||||
OBJDIRS += $(BUSOBJ)/a7800
|
||||
BUSOBJS += $(BUSOBJ)/a7800/a78_slot.o
|
||||
BUSOBJS += $(BUSOBJ)/a7800/rom.o
|
||||
BUSOBJS += $(BUSOBJ)/a7800/hiscore.o
|
||||
BUSOBJS += $(BUSOBJ)/a7800/xboard.o
|
||||
endif
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/bus/abcbus/abcbus.h,BUSES += ABCBUS
|
||||
|
@ -7,8 +7,9 @@
|
||||
Dan Boris
|
||||
|
||||
2002/05/13 kubecj added more banks for bankswitching
|
||||
added PAL machine description
|
||||
changed clock to be precise
|
||||
added PAL machine description
|
||||
changed clock to be precise
|
||||
improved cart emulation (in machine/)
|
||||
|
||||
2012/10/25 Robert Tuccitto NTSC Color Generator utilized for
|
||||
color palette with hue shift/start
|
||||
@ -83,15 +84,20 @@
|
||||
|
||||
2014/03/25 Mike Saarna Fixed Riot Timer
|
||||
|
||||
2014/04/04 Mike Saarna Fix to controller button RIOT behavior
|
||||
|
||||
2014/05/06 Mike Saarna/Robert Tuccitto Brought initial Maria cycle counts
|
||||
+ inline from measurements taken with logic analyzer and tests.
|
||||
inline from measurements taken with logic analyzer and tests.
|
||||
|
||||
2014/08/25 Fabio Priuli Converted carts to be slot devices and cleaned
|
||||
up the driver (removed the pokey, cleaned up rom regions, etc.)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "sound/pokey.h"
|
||||
#include "sound/tiaintf.h"
|
||||
#include "imagedev/cartslot.h"
|
||||
#include "bus/a7800/a78_carts.h"
|
||||
#include "machine/6532riot.h"
|
||||
#include "includes/a7800.h"
|
||||
|
||||
@ -100,32 +106,122 @@
|
||||
#define CLK_PAL 1773447
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MEMORY HANDLERS
|
||||
***************************************************************************/
|
||||
|
||||
// RIOT
|
||||
READ8_MEMBER(a7800_state::riot_joystick_r)
|
||||
{
|
||||
return m_io_joysticks->read();
|
||||
}
|
||||
|
||||
READ8_MEMBER(a7800_state::riot_console_button_r)
|
||||
{
|
||||
return m_io_console_buttons->read();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a7800_state::riot_button_pullup_w)
|
||||
{
|
||||
if(m_maincpu->space(AS_PROGRAM).read_byte(0x283) & 0x04)
|
||||
m_p1_one_button = data & 0x04; // pin 6 of the controller port is held high by the riot chip when reading two-button controllers (from schematic)
|
||||
if(m_maincpu->space(AS_PROGRAM).read_byte(0x283) & 0x10)
|
||||
m_p2_one_button = data & 0x10;
|
||||
}
|
||||
|
||||
READ8_MEMBER(a7800_state::tia_r)
|
||||
{
|
||||
switch (offset & 0x0f)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
/* Even though the 7800 doesn't use the TIA graphics the collision registers should
|
||||
still return a reasonable value */
|
||||
return 0x00;
|
||||
case 0x08:
|
||||
return ((m_io_buttons->read() & 0x02) << 6);
|
||||
case 0x09:
|
||||
return ((m_io_buttons->read() & 0x08) << 4);
|
||||
case 0x0a:
|
||||
return ((m_io_buttons->read() & 0x01) << 7);
|
||||
case 0x0b:
|
||||
return ((m_io_buttons->read() & 0x04) << 5);
|
||||
case 0x0c:
|
||||
if (((m_io_buttons->read() & 0x08) ||(m_io_buttons->read() & 0x02)) && m_p1_one_button)
|
||||
return 0x00;
|
||||
else
|
||||
return 0x80;
|
||||
case 0x0d:
|
||||
if (((m_io_buttons->read() & 0x01) ||(m_io_buttons->read() & 0x04)) && m_p2_one_button)
|
||||
return 0x00;
|
||||
else
|
||||
return 0x80;
|
||||
default:
|
||||
logerror("undefined TIA read %x\n",offset);
|
||||
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
// TIA
|
||||
WRITE8_MEMBER(a7800_state::tia_w)
|
||||
{
|
||||
if (offset < 0x20)
|
||||
{ //INPTCTRL covers TIA registers 0x00-0x1F until locked
|
||||
if (data & 0x01)
|
||||
{
|
||||
if (m_ctrl_lock && offset == 0x01)
|
||||
m_maria_flag = 1;
|
||||
else if (!m_ctrl_lock)
|
||||
m_maria_flag = 1;
|
||||
}
|
||||
if (!m_ctrl_lock)
|
||||
{
|
||||
m_ctrl_lock = data & 0x01;
|
||||
m_ctrl_reg = data;
|
||||
}
|
||||
}
|
||||
m_tia->tia_sound_w(space, offset, data);
|
||||
}
|
||||
|
||||
|
||||
// ROM
|
||||
READ8_MEMBER(a7800_state::bios_or_cart_r)
|
||||
{
|
||||
if (!(m_ctrl_reg & 0x04))
|
||||
return m_bios[offset];
|
||||
else
|
||||
return m_cartslot->read_40xx(space, offset + 0x8000);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
ADDRESS MAPS
|
||||
***************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( a7800_mem, AS_PROGRAM, 8, a7800_state )
|
||||
AM_RANGE(0x0000, 0x001f) AM_MIRROR(0x300) AM_READWRITE(a7800_TIA_r, a7800_TIA_w)
|
||||
AM_RANGE(0x0020, 0x003f) AM_MIRROR(0x300) AM_READWRITE(a7800_MARIA_r, a7800_MARIA_w)
|
||||
AM_RANGE(0x0040, 0x00ff) AM_READ_BANK("bank5") AM_WRITE(a7800_RAM0_w) /* RAM (6116 block 0) */
|
||||
AM_RANGE(0x0140, 0x01ff) AM_RAMBANK("bank6") /* RAM (6116 block 1) */
|
||||
AM_RANGE(0x0000, 0x001f) AM_MIRROR(0x300) AM_READWRITE(tia_r, tia_w)
|
||||
AM_RANGE(0x0020, 0x003f) AM_MIRROR(0x300) AM_READWRITE(maria_r, maria_w)
|
||||
AM_RANGE(0x0040, 0x00ff) AM_RAMBANK("ram0") // RAM (6116 block 0)
|
||||
AM_RANGE(0x0140, 0x01ff) AM_RAMBANK("ram1") // RAM (6116 block 1)
|
||||
AM_RANGE(0x0280, 0x02ff) AM_DEVREADWRITE("riot", riot6532_device, read, write)
|
||||
AM_RANGE(0x0450, 0x045f) /* XBOARD POKEY1 */
|
||||
AM_RANGE(0x0460, 0x046f) /* XBOARD POKEY2 */
|
||||
AM_RANGE(0x0470, 0x047f) /* XBOARD CTRL */
|
||||
AM_RANGE(0x0480, 0x04ff) AM_MIRROR(0x100) AM_RAM /* RIOT RAM */
|
||||
AM_RANGE(0x1000, 0x17ff) AM_RAM /* hs SRAM */
|
||||
AM_RANGE(0x1800, 0x27ff) AM_RAM
|
||||
AM_RANGE(0x2800, 0x2fff) AM_RAMBANK("bank7") /* MAINRAM */
|
||||
AM_RANGE(0x3000, 0x37ff) AM_RAMBANK("bank7") /* MAINRAM */
|
||||
AM_RANGE(0x3800, 0x3fff) AM_RAMBANK("bank7") /* MAINRAM */
|
||||
AM_RANGE(0x3000, 0x3fff) AM_ROM /* hs ROM space */
|
||||
AM_RANGE(0x4000, 0x7fff) AM_ROMBANK("bank1") /* f18 hornet */
|
||||
AM_RANGE(0x4000, 0xffff) AM_WRITE(a7800_cart_w) /* XBOARD SRAM */
|
||||
AM_RANGE(0x8000, 0x9fff) AM_ROMBANK("bank2") /* sc */
|
||||
AM_RANGE(0xa000, 0xbfff) AM_ROMBANK("bank3") /* sc + ac */
|
||||
AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("bank4") /* ac */
|
||||
AM_RANGE(0xe000, 0xffff) AM_ROM
|
||||
AM_RANGE(0x0480, 0x04ff) AM_MIRROR(0x100) AM_RAMBANK("riot_ram")
|
||||
AM_RANGE(0x1800, 0x27ff) AM_RAMBANK("main_ram")
|
||||
|
||||
AM_RANGE(0x2040, 0x20ff) AM_RAMBANK("ram0") // mirror (6116 block 0)
|
||||
AM_RANGE(0x2140, 0x21ff) AM_RAMBANK("ram1") // mirror (6116 block 1)
|
||||
|
||||
AM_RANGE(0x2800, 0x2fff) AM_RAMBANK("mirror") // these should mirror "main_ram" (according to docs)
|
||||
AM_RANGE(0x3000, 0x37ff) AM_RAMBANK("mirror") // but system have issues in such case...
|
||||
AM_RANGE(0x3800, 0x3fff) AM_RAMBANK("mirror")
|
||||
AM_RANGE(0x4000, 0xffff) AM_DEVWRITE("cartslot", a78_cart_slot_device, write_40xx)
|
||||
AM_RANGE(0x4000, 0xbfff) AM_DEVREAD("cartslot", a78_cart_slot_device, read_40xx)
|
||||
AM_RANGE(0xc000, 0xffff) AM_READ(bios_or_cart_r) // here also the BIOS can be accessed
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
@ -134,7 +230,7 @@ ADDRESS_MAP_END
|
||||
***************************************************************************/
|
||||
|
||||
static INPUT_PORTS_START( a7800 )
|
||||
PORT_START("joysticks") /* IN0 */
|
||||
PORT_START("joysticks")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(2) PORT_8WAY
|
||||
@ -144,18 +240,18 @@ static INPUT_PORTS_START( a7800 )
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1) PORT_8WAY
|
||||
|
||||
PORT_START("buttons") /* IN1 */
|
||||
PORT_START("buttons")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(2)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(1)
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(2)
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(1)
|
||||
PORT_BIT(0xF0, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
|
||||
PORT_START("vblank") /* IN2 */
|
||||
PORT_START("vblank")
|
||||
PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_VBLANK("screen")
|
||||
|
||||
PORT_START("console_buttons") /* IN3 */
|
||||
PORT_START("console_buttons")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Reset") PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Select") PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
@ -1133,13 +1229,51 @@ PALETTE_INIT_MEMBER(a7800_state,a7800p)
|
||||
MACHINE DRIVERS
|
||||
***************************************************************************/
|
||||
|
||||
void a7800_state::machine_start()
|
||||
{
|
||||
m_bios = machine().root_device().memregion("maincpu")->base() + 0xc000;
|
||||
save_item(NAME(m_p1_one_button));
|
||||
save_item(NAME(m_p2_one_button));
|
||||
save_item(NAME(m_bios_enabled));
|
||||
save_item(NAME(m_ctrl_lock));
|
||||
save_item(NAME(m_ctrl_reg));
|
||||
save_item(NAME(m_maria_flag));
|
||||
|
||||
// install additional POKEY handlers
|
||||
switch (m_cartslot->get_cart_type())
|
||||
{
|
||||
case A78_TYPE1:
|
||||
case A78_TYPE3:
|
||||
case A78_TYPEB:
|
||||
case A78_XB_BOARD:
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0400, 0x047f, read8_delegate(FUNC(a78_cart_slot_device::read_04xx),(a78_cart_slot_device*)m_cartslot), write8_delegate(FUNC(a78_cart_slot_device::write_04xx),(a78_cart_slot_device*)m_cartslot));
|
||||
break;
|
||||
case A78_HSC:
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x17ff, read8_delegate(FUNC(a78_cart_slot_device::read_10xx),(a78_cart_slot_device*)m_cartslot), write8_delegate(FUNC(a78_cart_slot_device::write_10xx),(a78_cart_slot_device*)m_cartslot));
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x3000, 0x3fff, read8_delegate(FUNC(a78_cart_slot_device::read_30xx),(a78_cart_slot_device*)m_cartslot), write8_delegate(FUNC(a78_cart_slot_device::write_30xx),(a78_cart_slot_device*)m_cartslot));
|
||||
break;
|
||||
case A78_XM_BOARD:
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0400, 0x047f, read8_delegate(FUNC(a78_cart_slot_device::read_04xx),(a78_cart_slot_device*)m_cartslot), write8_delegate(FUNC(a78_cart_slot_device::write_04xx),(a78_cart_slot_device*)m_cartslot));
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x1000, 0x17ff, read8_delegate(FUNC(a78_cart_slot_device::read_10xx),(a78_cart_slot_device*)m_cartslot), write8_delegate(FUNC(a78_cart_slot_device::write_10xx),(a78_cart_slot_device*)m_cartslot));
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x3000, 0x3fff, read8_delegate(FUNC(a78_cart_slot_device::read_30xx),(a78_cart_slot_device*)m_cartslot), write8_delegate(FUNC(a78_cart_slot_device::write_30xx),(a78_cart_slot_device*)m_cartslot));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void a7800_state::machine_reset()
|
||||
{
|
||||
m_ctrl_lock = 0;
|
||||
m_ctrl_reg = 0;
|
||||
m_maria_flag = 0;
|
||||
m_bios_enabled = 0;
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( a7800_ntsc, a7800_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", M6502, A7800_NTSC_Y1/8) /* 1.79 MHz (switches to 1.19 MHz on TIA or RIOT access) */
|
||||
MCFG_CPU_PROGRAM_MAP(a7800_mem)
|
||||
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", a7800_state, a7800_interrupt, "screen", 0, 1)
|
||||
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS( 7159090, 454, 0, 320, 263, 27, 27 + 192 + 32 )
|
||||
@ -1149,13 +1283,10 @@ static MACHINE_CONFIG_START( a7800_ntsc, a7800_state )
|
||||
MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(a7800_palette) / 3)
|
||||
MCFG_PALETTE_INIT_OWNER(a7800_state, a7800)
|
||||
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_TIA_ADD("tia", 31400)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
MCFG_SOUND_ADD("pokey", POKEY, A7800_NTSC_Y1/8)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
/* devices */
|
||||
MCFG_DEVICE_ADD("riot", RIOT6532, A7800_NTSC_Y1/8)
|
||||
@ -1163,12 +1294,7 @@ static MACHINE_CONFIG_START( a7800_ntsc, a7800_state )
|
||||
MCFG_RIOT6532_IN_PB_CB(READ8(a7800_state, riot_console_button_r))
|
||||
MCFG_RIOT6532_OUT_PB_CB(WRITE8(a7800_state, riot_button_pullup_w))
|
||||
|
||||
MCFG_CARTSLOT_ADD("cart")
|
||||
MCFG_CARTSLOT_EXTENSION_LIST("bin,a78")
|
||||
MCFG_CARTSLOT_NOT_MANDATORY
|
||||
MCFG_CARTSLOT_LOAD(a7800_state,a7800_cart)
|
||||
MCFG_CARTSLOT_PARTIALHASH(a7800_partialhash)
|
||||
MCFG_CARTSLOT_INTERFACE("a7800_cart")
|
||||
MCFG_A78_CARTRIDGE_ADD("cartslot", a7800_cart, NULL)
|
||||
|
||||
/* software lists */
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list","a7800")
|
||||
@ -1177,7 +1303,6 @@ MACHINE_CONFIG_END
|
||||
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( a7800_pal, a7800_ntsc )
|
||||
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_CLOCK(CLK_PAL)
|
||||
@ -1189,11 +1314,6 @@ static MACHINE_CONFIG_DERIVED( a7800_pal, a7800_ntsc )
|
||||
MCFG_PALETTE_MODIFY("palette")
|
||||
MCFG_PALETTE_INIT_OWNER(a7800_state, a7800p )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SOUND_MODIFY("pokey")
|
||||
MCFG_SOUND_CLOCK(CLK_PAL)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
/* devices */
|
||||
MCFG_DEVICE_REMOVE("riot")
|
||||
MCFG_DEVICE_ADD("riot", RIOT6532, CLK_PAL)
|
||||
@ -1213,8 +1333,7 @@ MACHINE_CONFIG_END
|
||||
***************************************************************************/
|
||||
|
||||
ROM_START( a7800 )
|
||||
ROM_REGION(0x100000, "maincpu", 0)
|
||||
ROM_FILL(0x0000, 0x100000, 0xff)
|
||||
ROM_REGION(0x10000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_SYSTEM_BIOS( 0, "a7800", "Atari 7800" )
|
||||
ROMX_LOAD("7800.u7", 0xf000, 0x1000, CRC(5d13730c) SHA1(d9d134bb6b36907c615a594cc7688f7bfcef5b43), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS( 1, "a7800pr", "Atari 7800 (prototype with Asteroids)" )
|
||||
@ -1222,12 +1341,33 @@ ROM_START( a7800 )
|
||||
ROM_END
|
||||
|
||||
ROM_START( a7800p )
|
||||
ROM_REGION(0x100000, "maincpu", 0)
|
||||
ROM_FILL(0x0000, 0x100000, 0xff)
|
||||
ROM_REGION(0x10000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("7800pal.rom", 0xc000, 0x4000, CRC(d5b61170) SHA1(5a140136a16d1d83e4ff32a19409ca376a8df874))
|
||||
ROM_END
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DRIVER INIT
|
||||
***************************************************************************/
|
||||
|
||||
DRIVER_INIT_MEMBER(a7800_state,a7800_ntsc)
|
||||
{
|
||||
m_ispal = FALSE;
|
||||
m_lines = 263;
|
||||
m_p1_one_button = 1;
|
||||
m_p2_one_button = 1;
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT_MEMBER(a7800_state,a7800_pal)
|
||||
{
|
||||
m_ispal = TRUE;
|
||||
m_lines = 313;
|
||||
m_p1_one_button = 1;
|
||||
m_p2_one_button = 1;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
GAME DRIVERS
|
||||
***************************************************************************/
|
||||
|
@ -8,9 +8,9 @@
|
||||
#define A7800_H_
|
||||
|
||||
#include "machine/6532riot.h"
|
||||
#include "sound/pokey.h"
|
||||
#include "sound/tiasound.h"
|
||||
#include "sound/tiaintf.h"
|
||||
#include "bus/a7800/a78_slot.h"
|
||||
|
||||
|
||||
class a7800_state : public driver_device
|
||||
@ -19,36 +19,26 @@ public:
|
||||
a7800_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_pokey(*this, "pokey"),
|
||||
m_tia(*this, "tia"),
|
||||
m_region_maincpu(*this, "maincpu"),
|
||||
m_bank1(*this, "bank1"),
|
||||
m_bank2(*this, "bank2"),
|
||||
m_bank3(*this, "bank3"),
|
||||
m_bank4(*this, "bank4"),
|
||||
m_bank5(*this, "bank5"),
|
||||
m_bank6(*this, "bank6"),
|
||||
m_bank7(*this, "bank7"),
|
||||
m_io_joysticks(*this, "joysticks"),
|
||||
m_io_buttons(*this, "buttons"),
|
||||
m_io_vblank(*this, "vblank"),
|
||||
m_io_console_buttons(*this, "console_buttons"),
|
||||
m_bank10(NULL),
|
||||
m_bank11(NULL),
|
||||
m_cartslot(*this, "cartslot"),
|
||||
m_screen(*this, "screen") { }
|
||||
|
||||
int m_lines;
|
||||
int m_ispal;
|
||||
unsigned char *m_cart_bkup;
|
||||
unsigned char *m_bios_bkup;
|
||||
|
||||
int m_ctrl_lock;
|
||||
int m_ctrl_reg;
|
||||
int m_maria_flag;
|
||||
unsigned char *m_cartridge_rom;
|
||||
UINT16 m_cart_type;
|
||||
UINT32 m_cart_size;
|
||||
unsigned char m_stick_type;
|
||||
UINT8 *m_ROM;
|
||||
int m_p1_one_button;
|
||||
int m_p2_one_button;
|
||||
int m_bios_enabled;
|
||||
|
||||
UINT8 *m_bios;
|
||||
|
||||
int m_maria_palette[32];
|
||||
int m_line_ram[2][160];
|
||||
int m_active_buffer;
|
||||
@ -71,18 +61,16 @@ public:
|
||||
int m_maria_nmi;
|
||||
unsigned int m_maria_charbase;
|
||||
bitmap_ind16 m_bitmap;
|
||||
int m_p1_one_button;
|
||||
int m_p2_one_button;
|
||||
|
||||
DECLARE_WRITE8_MEMBER(a7800_RAM0_w);
|
||||
DECLARE_WRITE8_MEMBER(a7800_cart_w);
|
||||
DECLARE_READ8_MEMBER(a7800_TIA_r);
|
||||
DECLARE_WRITE8_MEMBER(a7800_TIA_w);
|
||||
DECLARE_READ8_MEMBER(a7800_MARIA_r);
|
||||
DECLARE_WRITE8_MEMBER(a7800_MARIA_w);
|
||||
void a7800_driver_init(int ispal, int lines);
|
||||
DECLARE_READ8_MEMBER(bios_or_cart_r);
|
||||
DECLARE_WRITE8_MEMBER(ram0_w);
|
||||
DECLARE_READ8_MEMBER(tia_r);
|
||||
DECLARE_WRITE8_MEMBER(tia_w);
|
||||
DECLARE_READ8_MEMBER(maria_r);
|
||||
DECLARE_WRITE8_MEMBER(maria_w);
|
||||
DECLARE_DRIVER_INIT(a7800_pal);
|
||||
DECLARE_DRIVER_INIT(a7800_ntsc);
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
virtual void video_start();
|
||||
DECLARE_PALETTE_INIT(a7800);
|
||||
@ -94,37 +82,19 @@ public:
|
||||
DECLARE_READ8_MEMBER(riot_console_button_r);
|
||||
DECLARE_WRITE8_MEMBER(riot_button_pullup_w);
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( a7800_cart );
|
||||
|
||||
protected:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<pokey_device> m_pokey;
|
||||
required_device<tia_device> m_tia;
|
||||
required_memory_region m_region_maincpu;
|
||||
required_memory_bank m_bank1;
|
||||
required_memory_bank m_bank2;
|
||||
required_memory_bank m_bank3;
|
||||
required_memory_bank m_bank4;
|
||||
required_memory_bank m_bank5;
|
||||
required_memory_bank m_bank6;
|
||||
required_memory_bank m_bank7;
|
||||
required_ioport m_io_joysticks;
|
||||
required_ioport m_io_buttons;
|
||||
required_ioport m_io_vblank;
|
||||
required_ioport m_io_console_buttons;
|
||||
memory_bank *m_bank10;
|
||||
memory_bank *m_bank11;
|
||||
required_device<a78_cart_slot_device> m_cartslot;
|
||||
required_device<screen_device> m_screen;
|
||||
|
||||
void maria_draw_scanline();
|
||||
int is_holey(unsigned int addr);
|
||||
int write_line_ram(int addr, UINT8 offset, int pal);
|
||||
int a7800_verify_cart(char header[128]);
|
||||
UINT16 a7800_get_pcb_id(const char *pcb);
|
||||
};
|
||||
|
||||
/*----------- defined in machine/a7800.c -----------*/
|
||||
|
||||
void a7800_partialhash(hash_collection &dest, const unsigned char *data, unsigned long length, const char *functions);
|
||||
|
||||
#endif /* A7800_H_ */
|
||||
#endif
|
||||
|
@ -1,539 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
a7800.c
|
||||
|
||||
Machine file to handle emulation of the Atari 7800.
|
||||
|
||||
5-Nov-2003 npwoods Cleanups
|
||||
|
||||
14-May-2002 kubecj Fixed Fatal Run - adding simple riot timer helped.
|
||||
maybe someone with knowledge should add full fledged
|
||||
riot emulation?
|
||||
|
||||
13-May-2002 kubecj Fixed a7800_cart_type not to be too short ;-D
|
||||
fixed for loading of bank6 cart (uh, I hope)
|
||||
fixed for loading 64k supercarts
|
||||
fixed for using PAL bios
|
||||
cart not needed when in PAL mode
|
||||
added F18 Hornet bank select type
|
||||
added Activision bank select type
|
||||
19-Feb-2010 DanB Added return values for TIA collision registers
|
||||
|
||||
04-Apr-2014 Mike Saarna Fix to controller button RIOT behavior and
|
||||
expanded cart handling (bit 05).
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/a7800.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
|
||||
|
||||
|
||||
/* local */
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
6532 RIOT
|
||||
***************************************************************************/
|
||||
|
||||
READ8_MEMBER(a7800_state::riot_joystick_r)
|
||||
{
|
||||
return m_io_joysticks->read();
|
||||
}
|
||||
|
||||
READ8_MEMBER(a7800_state::riot_console_button_r)
|
||||
{
|
||||
return m_io_console_buttons->read();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a7800_state::riot_button_pullup_w)
|
||||
{
|
||||
if(m_maincpu->space(AS_PROGRAM).read_byte(0x283) & 0x04)
|
||||
m_p1_one_button = data & 0x04; // pin 6 of the controller port is held high by the riot chip when reading two-button controllers (from schematic)
|
||||
if(m_maincpu->space(AS_PROGRAM).read_byte(0x283) & 0x10)
|
||||
m_p2_one_button = data & 0x10;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
DRIVER INIT
|
||||
***************************************************************************/
|
||||
|
||||
void a7800_state::a7800_driver_init(int ispal, int lines)
|
||||
{
|
||||
address_space& space = m_maincpu->space(AS_PROGRAM);
|
||||
m_ROM = m_region_maincpu->base();
|
||||
m_ispal = ispal;
|
||||
m_lines = lines;
|
||||
m_p1_one_button = 1;
|
||||
m_p2_one_button = 1;
|
||||
|
||||
/* standard banks */
|
||||
m_bank5->set_base(&m_ROM[0x2040]); /* RAM0 */
|
||||
m_bank6->set_base(&m_ROM[0x2140]); /* RAM1 */
|
||||
m_bank7->set_base(&m_ROM[0x2000]); /* MAINRAM */
|
||||
|
||||
/* Brutal hack put in as a consequence of new memory system; fix this */
|
||||
space.install_readwrite_bank(0x0480, 0x04FF,"bank10");
|
||||
m_bank10 = membank("bank10");
|
||||
m_bank10->set_base(m_ROM + 0x0480);
|
||||
space.install_readwrite_bank(0x1800, 0x27FF, "bank11");
|
||||
m_bank11 = membank("bank11");
|
||||
m_bank11->set_base(m_ROM + 0x1800);
|
||||
|
||||
m_bios_bkup = NULL;
|
||||
m_cart_bkup = NULL;
|
||||
|
||||
/* Allocate memory for BIOS bank switching */
|
||||
m_bios_bkup = auto_alloc_array_clear(machine(), UINT8, 0x4000);
|
||||
m_cart_bkup = auto_alloc_array(machine(), UINT8, 0x4000);
|
||||
|
||||
/* save the BIOS so we can switch it in and out */
|
||||
memcpy( m_bios_bkup, m_ROM + 0xC000, 0x4000 );
|
||||
|
||||
/* Initialize cart area to "no data" */
|
||||
memset( m_cart_bkup, 0xFF, 0x4000 );
|
||||
|
||||
/* defaults for PAL bios without cart */
|
||||
m_cart_type = 0;
|
||||
m_stick_type = 1;
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT_MEMBER(a7800_state,a7800_ntsc)
|
||||
{
|
||||
a7800_driver_init(FALSE, 263);
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT_MEMBER(a7800_state,a7800_pal)
|
||||
{
|
||||
a7800_driver_init(TRUE, 313);
|
||||
}
|
||||
|
||||
|
||||
void a7800_state::machine_reset()
|
||||
{
|
||||
UINT8 *memory;
|
||||
address_space& space = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
m_ctrl_lock = 0;
|
||||
m_ctrl_reg = 0;
|
||||
m_maria_flag = 0;
|
||||
|
||||
/* set banks to default states */
|
||||
memory = m_region_maincpu->base();
|
||||
if(m_cart_type & 0x20) //supercart bankram
|
||||
m_bank1->set_base(memory + 0xf0000 );
|
||||
else
|
||||
m_bank1->set_base(memory + 0x4000 );
|
||||
m_bank2->set_base(memory + 0x8000 );
|
||||
m_bank3->set_base(memory + 0xA000 );
|
||||
m_bank4->set_base(memory + 0xC000 );
|
||||
|
||||
/* pokey cartridge */
|
||||
if (m_cart_type & 0x01)
|
||||
{
|
||||
space.install_readwrite_handler(0x0450, 0x045F, read8_delegate(FUNC(pokey_device::read),(pokey_device*)m_pokey), write8_delegate(FUNC(pokey_device::write),(pokey_device*)m_pokey));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CARTRIDGE HANDLING
|
||||
***************************************************************************/
|
||||
|
||||
#define MBANK_TYPE_ATARI 0x0000
|
||||
#define MBANK_TYPE_ACTIVISION 0x0100
|
||||
#define MBANK_TYPE_ABSOLUTE 0x0200
|
||||
|
||||
/* Header format
|
||||
0 Header version - 1 byte
|
||||
1..16 "ATARI7800 " - 16 bytes
|
||||
17..48 Cart title - 32 bytes
|
||||
49..52 data length - 4 bytes
|
||||
53..54 cart type - 2 bytes
|
||||
bit 0 0x01 - pokey cart
|
||||
bit 1 0x02 - supercart bank switched
|
||||
bit 2 0x04 - supercart RAM at $4000
|
||||
bit 3 0x08 - additional state->m_ROM at $4000
|
||||
bit 4 0x10 - bank 6 at $4000
|
||||
bit 5 0x20 - supercart banked RAM
|
||||
|
||||
bit 8-15 - Special
|
||||
0 = Normal cart
|
||||
1 = Absolute (F18 Hornet)
|
||||
2 = Activision
|
||||
|
||||
55 controller 1 type - 1 byte
|
||||
56 controller 2 type - 1 byte
|
||||
0 = None
|
||||
1 = Joystick
|
||||
2 = Light Gun
|
||||
57 0 = NTSC/1 = PAL
|
||||
|
||||
100..127 "ACTUAL CART DATA STARTS HERE" - 28 bytes
|
||||
|
||||
Versions:
|
||||
Version 0: Initial release
|
||||
Version 1: Added PAL/NTSC bit. Added Special cart byte.
|
||||
Changed 53 bit 2, added bit 3
|
||||
|
||||
*/
|
||||
void a7800_partialhash(hash_collection &dest, const unsigned char *data,
|
||||
unsigned long length, const char *functions)
|
||||
{
|
||||
if (length <= 128)
|
||||
return;
|
||||
dest.compute(&data[128], length - 128, functions);
|
||||
}
|
||||
|
||||
|
||||
int a7800_state::a7800_verify_cart(char header[128])
|
||||
{
|
||||
const char* tag = "ATARI7800";
|
||||
|
||||
if( strncmp( tag, header + 1, 9 ) )
|
||||
{
|
||||
logerror("Not a valid A7800 image\n");
|
||||
return IMAGE_VERIFY_FAIL;
|
||||
}
|
||||
|
||||
logerror("returning ID_OK\n");
|
||||
return IMAGE_VERIFY_PASS;
|
||||
}
|
||||
|
||||
|
||||
struct a7800_pcb
|
||||
{
|
||||
const char *pcb_name;
|
||||
UINT16 type;
|
||||
};
|
||||
|
||||
// sketchy support for a7800 cart types
|
||||
// TODO: proper emulation of the banking based on xml
|
||||
// (and on the real cart layout!)
|
||||
static const a7800_pcb pcb_list[] =
|
||||
{
|
||||
{ "ABSOLUTE", MBANK_TYPE_ABSOLUTE },
|
||||
{ "ACTIVISION", MBANK_TYPE_ACTIVISION },
|
||||
{ "TYPE-0", 0x0 },
|
||||
{ "TYPE-1", 0x1 },
|
||||
{ "TYPE-2", 0x2 },
|
||||
{ "TYPE-3", 0x3 },
|
||||
{ "TYPE-6", 0x6 },
|
||||
{ "TYPE-A", 0xa },
|
||||
{ "TYPE-XM", 0xb }, /* XM cart? (dkongxm) */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
UINT16 a7800_state::a7800_get_pcb_id(const char *pcb)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(pcb_list); i++)
|
||||
{
|
||||
if (!core_stricmp(pcb_list[i].pcb_name, pcb))
|
||||
return pcb_list[i].type;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEVICE_IMAGE_LOAD_MEMBER( a7800_state, a7800_cart )
|
||||
{
|
||||
UINT32 len = 0, start = 0;
|
||||
unsigned char header[128];
|
||||
UINT8 *memory = m_region_maincpu->base();
|
||||
const char *pcb_name;
|
||||
|
||||
// detect cart type either from xml or from header
|
||||
if (image.software_entry() == NULL)
|
||||
{
|
||||
/* Load and decode the header */
|
||||
image.fread(header, 128);
|
||||
|
||||
/* Check the cart */
|
||||
if( a7800_verify_cart((char *)header) == IMAGE_VERIFY_FAIL)
|
||||
return IMAGE_INIT_FAIL;
|
||||
|
||||
len =(header[49] << 24) |(header[50] << 16) |(header[51] << 8) | header[52];
|
||||
m_cart_size = len;
|
||||
|
||||
m_cart_type =(header[53] << 8) | header[54];
|
||||
m_stick_type = header[55];
|
||||
logerror("Cart type: %x\n", m_cart_type);
|
||||
|
||||
/* For now, if game support stick and gun, set it to stick */
|
||||
if (m_stick_type == 3)
|
||||
m_stick_type = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = image.get_software_region_length("rom");
|
||||
m_cart_size = len;
|
||||
// TODO: add stick/gun support to xml!
|
||||
m_stick_type = 1;
|
||||
if ((pcb_name = image.get_feature("pcb_type")) == NULL)
|
||||
m_cart_type = 0;
|
||||
else
|
||||
m_cart_type = a7800_get_pcb_id(pcb_name);
|
||||
}
|
||||
|
||||
if (m_cart_type == 0 || m_cart_type == 1)
|
||||
{
|
||||
/* Normal Cart */
|
||||
start = 0x10000 - len;
|
||||
m_cartridge_rom = memory + start;
|
||||
if (image.software_entry() == NULL)
|
||||
image.fread(m_cartridge_rom, len);
|
||||
else
|
||||
memcpy(m_cartridge_rom, image.get_software_region("rom"), len);
|
||||
}
|
||||
else if (m_cart_type & 0x02)
|
||||
{
|
||||
/* Super Cart */
|
||||
/* Extra ROM at $4000 */
|
||||
if (m_cart_type & 0x08)
|
||||
{
|
||||
if (image.software_entry() == NULL)
|
||||
image.fread(memory + 0x4000, 0x4000);
|
||||
else
|
||||
memcpy(memory + 0x4000, image.get_software_region("rom"), 0x4000);
|
||||
len -= 0x4000;
|
||||
start = 0x4000;
|
||||
}
|
||||
|
||||
m_cartridge_rom = memory + 0x10000;
|
||||
if (image.software_entry() == NULL)
|
||||
image.fread(m_cartridge_rom, len);
|
||||
else
|
||||
memcpy(m_cartridge_rom, image.get_software_region("rom") + start, len);
|
||||
|
||||
/* bank 0 */
|
||||
memcpy(memory + 0x8000, memory + 0x10000, 0x4000);
|
||||
|
||||
/* last bank */
|
||||
memcpy(memory + 0xC000, memory + 0x10000 + len - 0x4000, 0x4000);
|
||||
|
||||
/* fixed 2002/05/13 kubecj
|
||||
there was 0x08, I added also two other cases.
|
||||
Now, it loads bank n-2 to $4000 if it's empty.
|
||||
*/
|
||||
|
||||
/* bank n-2 */
|
||||
if (!(m_cart_type & 0x0d))
|
||||
{
|
||||
memcpy(memory + 0x4000, memory + 0x10000 + len - 0x8000, 0x4000);
|
||||
}
|
||||
}
|
||||
else if (m_cart_type == MBANK_TYPE_ABSOLUTE)
|
||||
{
|
||||
/* F18 Hornet */
|
||||
|
||||
logerror("Cart type: %x Absolute\n",m_cart_type);
|
||||
|
||||
m_cartridge_rom = memory + 0x10000;
|
||||
if (image.software_entry() == NULL)
|
||||
image.fread(m_cartridge_rom, len);
|
||||
else
|
||||
memcpy(m_cartridge_rom, image.get_software_region("rom") + start, len);
|
||||
|
||||
/* bank 0 */
|
||||
memcpy(memory + 0x4000, memory + 0x10000, 0x4000);
|
||||
|
||||
/* last bank */
|
||||
memcpy(memory + 0x8000, memory + 0x18000, 0x8000);
|
||||
}
|
||||
else if (m_cart_type == MBANK_TYPE_ACTIVISION)
|
||||
{
|
||||
/* Activision */
|
||||
|
||||
logerror("Cart type: %x Activision\n",m_cart_type);
|
||||
|
||||
m_cartridge_rom = memory + 0x10000;
|
||||
if (image.software_entry() == NULL)
|
||||
image.fread(m_cartridge_rom, len);
|
||||
else
|
||||
memcpy(m_cartridge_rom, image.get_software_region("rom") + start, len);
|
||||
|
||||
/* bank 0 */
|
||||
memcpy(memory + 0xa000, memory + 0x10000, 0x4000);
|
||||
|
||||
/* bank6 hi */
|
||||
memcpy(memory + 0x4000, memory + 0x2a000, 0x2000);
|
||||
|
||||
/* bank6 lo */
|
||||
memcpy(memory + 0x6000, memory + 0x28000, 0x2000);
|
||||
|
||||
/* bank7 hi */
|
||||
memcpy(memory + 0x8000, memory + 0x2e000, 0x2000);
|
||||
|
||||
/* bank7 lo */
|
||||
memcpy(memory + 0xe000, memory + 0x2c000, 0x2000);
|
||||
|
||||
}
|
||||
|
||||
memcpy(m_cart_bkup, memory + 0xc000, 0x4000);
|
||||
memcpy(memory + 0xc000, m_bios_bkup, 0x4000);
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(a7800_state::a7800_RAM0_w)
|
||||
{
|
||||
m_ROM[0x2040 + offset] = data;
|
||||
m_ROM[0x40 + offset] = data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(a7800_state::a7800_cart_w)
|
||||
{
|
||||
UINT8 *memory = m_region_maincpu->base();
|
||||
|
||||
if(offset < 0x4000)
|
||||
{
|
||||
if(m_cart_type & 0x04)
|
||||
{
|
||||
//adjust write location if supercart bankram is in use
|
||||
if(m_cart_type & 0x20)
|
||||
{
|
||||
UINT8 *currentbank1 = (UINT8 *)m_bank1->base();
|
||||
currentbank1[offset] = data;
|
||||
}
|
||||
else
|
||||
m_ROM[0x4000 + offset] = data;
|
||||
}
|
||||
else if(m_cart_type & 0x01)
|
||||
{
|
||||
m_pokey->write(space, offset, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("Undefined write A: %x",offset + 0x4000);
|
||||
}
|
||||
}
|
||||
|
||||
if(( m_cart_type & 0x02 ) &&( offset >= 0x4000 ) )
|
||||
{
|
||||
/* check if bankram is used */
|
||||
if( m_cart_type & 0x20 )
|
||||
{
|
||||
m_bank1->set_base(memory + 0xf0000+((data & 0x20)<<9));
|
||||
}
|
||||
/* fix for 64kb supercart */
|
||||
if( m_cart_size == 0x10000 )
|
||||
{
|
||||
data &= 0x03;
|
||||
}
|
||||
else if( m_cart_size == 0x40000 )
|
||||
{
|
||||
data &= 0x0f;
|
||||
}
|
||||
else if( m_cart_size == 0x80000 )
|
||||
{
|
||||
data &= 0x1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
data &= 0x07;
|
||||
}
|
||||
m_bank2->set_base(memory + 0x10000 + (data << 14));
|
||||
m_bank3->set_base(memory + 0x12000 + (data << 14));
|
||||
/* logerror("BANK SEL: %d\n",data); */
|
||||
}
|
||||
else if(( m_cart_type == MBANK_TYPE_ABSOLUTE ) &&( offset == 0x4000 ) )
|
||||
{
|
||||
/* F18 Hornet */
|
||||
/*logerror( "F18 BANK SEL: %d\n", data );*/
|
||||
if( data & 1 )
|
||||
{
|
||||
m_bank1->set_base(memory + 0x10000 );
|
||||
}
|
||||
else if( data & 2 )
|
||||
{
|
||||
m_bank1->set_base(memory + 0x14000 );
|
||||
}
|
||||
}
|
||||
else if(( m_cart_type == MBANK_TYPE_ACTIVISION ) &&( offset >= 0xBF80 ) )
|
||||
{
|
||||
/* Activision */
|
||||
data = offset & 7;
|
||||
|
||||
/*logerror( "Activision BANK SEL: %d\n", data );*/
|
||||
|
||||
m_bank3->set_base(memory + 0x10000 + ( data << 14 ) );
|
||||
m_bank4->set_base(memory + 0x12000 + ( data << 14 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TIA
|
||||
***************************************************************************/
|
||||
|
||||
READ8_MEMBER(a7800_state::a7800_TIA_r)
|
||||
{
|
||||
switch(offset & 0x0f)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
/* Even though the 7800 doesn't use the TIA graphics the collision registers should
|
||||
still return a reasonable value */
|
||||
return 0x00;
|
||||
case 0x08:
|
||||
return((m_io_buttons->read() & 0x02) << 6);
|
||||
case 0x09:
|
||||
return((m_io_buttons->read() & 0x08) << 4);
|
||||
case 0x0A:
|
||||
return((m_io_buttons->read() & 0x01) << 7);
|
||||
case 0x0B:
|
||||
return((m_io_buttons->read() & 0x04) << 5);
|
||||
case 0x0c:
|
||||
if(((m_io_buttons->read() & 0x08) ||(m_io_buttons->read() & 0x02)) && m_p1_one_button)
|
||||
return 0x00;
|
||||
else
|
||||
return 0x80;
|
||||
case 0x0d:
|
||||
if(((m_io_buttons->read() & 0x01) ||(m_io_buttons->read() & 0x04)) && m_p2_one_button)
|
||||
return 0x00;
|
||||
else
|
||||
return 0x80;
|
||||
default:
|
||||
logerror("undefined TIA read %x\n",offset);
|
||||
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(a7800_state::a7800_TIA_w)
|
||||
{
|
||||
if (offset<0x20) { //INPTCTRL covers TIA registers 0x00-0x1F until locked
|
||||
if(data & 0x01)
|
||||
{
|
||||
if ((m_ctrl_lock)&&(offset==0x01))
|
||||
m_maria_flag=1;
|
||||
else if (!m_ctrl_lock)
|
||||
m_maria_flag=1;
|
||||
}
|
||||
if(!m_ctrl_lock)
|
||||
{
|
||||
m_ctrl_lock = data & 0x01;
|
||||
m_ctrl_reg = data;
|
||||
|
||||
if (data & 0x04)
|
||||
memcpy( m_ROM + 0xC000, m_cart_bkup, 0x4000 );
|
||||
else
|
||||
memcpy( m_ROM + 0xC000, m_bios_bkup, 0x4000 );
|
||||
}
|
||||
}
|
||||
m_tia->tia_sound_w(space, offset, data);
|
||||
m_ROM[offset] = data;
|
||||
}
|
@ -560,6 +560,7 @@ MACHINES += DIABLO_HD
|
||||
|
||||
BUSES += A1BUS
|
||||
BUSES += A2BUS
|
||||
BUSES += A7800
|
||||
BUSES += ABCBUS
|
||||
BUSES += ABCKB
|
||||
BUSES += ADAM
|
||||
@ -1023,7 +1024,6 @@ $(MESSOBJ)/at.a: \
|
||||
$(MESSOBJ)/atari.a: \
|
||||
$(MESS_MACHINE)/atarifdc.o \
|
||||
$(MESS_DRIVERS)/atari400.o \
|
||||
$(MESS_MACHINE)/a7800.o \
|
||||
$(MESS_DRIVERS)/a7800.o \
|
||||
$(MESS_VIDEO)/a7800.o \
|
||||
$(MESS_DRIVERS)/a2600.o \
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
|
||||
#include "includes/a7800.h"
|
||||
|
||||
|
||||
@ -345,7 +344,7 @@ UINT32 a7800_state::screen_update_a7800(screen_device &screen, bitmap_ind16 &bit
|
||||
|
||||
/****** MARIA ***************************************/
|
||||
|
||||
READ8_MEMBER(a7800_state::a7800_MARIA_r)
|
||||
READ8_MEMBER(a7800_state::maria_r)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
@ -358,7 +357,7 @@ READ8_MEMBER(a7800_state::a7800_MARIA_r)
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(a7800_state::a7800_MARIA_w)
|
||||
WRITE8_MEMBER(a7800_state::maria_w)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user