diff --git a/.gitattributes b/.gitattributes index e4df589bace..a3015e04339 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/hash/a7800.xml b/hash/a7800.xml index 3fb60d20272..641934c513f 100644 --- a/hash/a7800.xml +++ b/hash/a7800.xml @@ -194,18 +194,20 @@ type of rom dumps. Effort will be made at a later date to split them and docume + - + 7800 Pro System Diagnostic Test (v1.0) 198? Atari + @@ -220,6 +222,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -234,6 +237,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -248,6 +252,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -263,6 +268,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -280,6 +286,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -294,6 +301,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -308,6 +316,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -322,6 +331,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -336,6 +346,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -370,6 +381,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -385,6 +397,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -399,6 +412,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -413,6 +427,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -427,6 +442,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -441,6 +457,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -455,6 +472,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -469,6 +487,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -483,6 +502,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -497,6 +517,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -511,6 +532,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -525,6 +547,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -539,6 +562,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -553,6 +577,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -567,6 +592,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -582,6 +608,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -597,6 +624,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -611,6 +639,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -629,6 +658,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -643,6 +673,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -657,6 +688,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -674,6 +706,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -688,6 +721,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -702,6 +736,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -716,6 +751,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -730,6 +766,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -744,6 +781,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -758,6 +796,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -772,6 +811,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -786,6 +826,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -800,6 +841,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -814,6 +856,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -828,6 +871,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -842,6 +886,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -856,6 +901,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -870,6 +916,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -884,6 +931,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -898,6 +946,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -912,6 +961,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -926,6 +976,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -940,6 +991,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -954,6 +1006,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -968,6 +1021,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -982,6 +1036,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -996,6 +1051,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1011,6 +1067,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1025,6 +1082,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1038,6 +1096,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1056,6 +1115,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1070,24 +1130,13 @@ type of rom dumps. Effort will be made at a later date to split them and docume + - - High Score Cartridge - 198? - Atari - - - - - - - - Ikari Warriors (NTSC) 1990 @@ -1096,6 +1145,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1110,6 +1160,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1124,6 +1175,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1138,6 +1190,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1152,6 +1205,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1166,6 +1220,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1179,6 +1234,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1193,6 +1249,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1207,6 +1264,7 @@ type of rom dumps. Effort will be made at a later date to split them and docume + @@ -1228,6 +1286,7 @@ the buttons not work in emulators. + @@ -1242,6 +1301,7 @@ the buttons not work in emulators. + @@ -1256,6 +1316,7 @@ the buttons not work in emulators. + @@ -1270,6 +1331,7 @@ the buttons not work in emulators. + @@ -1284,6 +1346,7 @@ the buttons not work in emulators. + @@ -1298,6 +1361,7 @@ the buttons not work in emulators. + @@ -1312,6 +1376,7 @@ the buttons not work in emulators. + @@ -1326,6 +1391,7 @@ the buttons not work in emulators. + @@ -1340,6 +1406,7 @@ the buttons not work in emulators. + @@ -1354,6 +1421,7 @@ the buttons not work in emulators. + @@ -1368,6 +1436,7 @@ the buttons not work in emulators. + @@ -1412,6 +1481,7 @@ the buttons not work in emulators. + @@ -1426,6 +1496,7 @@ the buttons not work in emulators. + @@ -1440,6 +1511,7 @@ the buttons not work in emulators. + @@ -1463,6 +1535,7 @@ almost nothing like the prototype. + @@ -1477,6 +1550,7 @@ almost nothing like the prototype. + @@ -1490,6 +1564,7 @@ almost nothing like the prototype. + @@ -1504,6 +1579,7 @@ almost nothing like the prototype. + @@ -1518,6 +1594,7 @@ almost nothing like the prototype. + @@ -1532,6 +1609,7 @@ almost nothing like the prototype. + @@ -1546,6 +1624,7 @@ almost nothing like the prototype. + @@ -1561,6 +1640,7 @@ almost nothing like the prototype. + @@ -1576,6 +1656,7 @@ almost nothing like the prototype. + @@ -1590,6 +1671,7 @@ almost nothing like the prototype. + @@ -1603,6 +1685,7 @@ almost nothing like the prototype. + @@ -1616,6 +1699,7 @@ almost nothing like the prototype. + @@ -1629,6 +1713,7 @@ almost nothing like the prototype. + @@ -1642,6 +1727,7 @@ almost nothing like the prototype. + @@ -1655,6 +1741,7 @@ almost nothing like the prototype. + @@ -1668,6 +1755,7 @@ almost nothing like the prototype. + @@ -1681,6 +1769,7 @@ almost nothing like the prototype. + @@ -1695,6 +1784,7 @@ almost nothing like the prototype. + @@ -1709,6 +1799,7 @@ almost nothing like the prototype. + @@ -1721,6 +1812,7 @@ almost nothing like the prototype. Tynesoft + @@ -1735,6 +1827,7 @@ almost nothing like the prototype. + @@ -1749,6 +1842,7 @@ almost nothing like the prototype. + @@ -1763,6 +1857,7 @@ almost nothing like the prototype. + @@ -1777,6 +1872,7 @@ almost nothing like the prototype. + @@ -1792,6 +1888,7 @@ almost nothing like the prototype. + @@ -1806,6 +1903,7 @@ almost nothing like the prototype. + @@ -1820,6 +1918,7 @@ almost nothing like the prototype. + @@ -1833,6 +1932,7 @@ almost nothing like the prototype. + @@ -1847,6 +1947,7 @@ almost nothing like the prototype. + @@ -1861,6 +1962,7 @@ almost nothing like the prototype. + @@ -1903,6 +2005,7 @@ almost nothing like the prototype. Tynesoft + @@ -1915,6 +2018,7 @@ almost nothing like the prototype. Atari Interactive + @@ -1928,6 +2032,7 @@ almost nothing like the prototype. + @@ -1941,6 +2046,7 @@ almost nothing like the prototype. + @@ -1954,6 +2060,7 @@ almost nothing like the prototype. + @@ -1967,6 +2074,7 @@ almost nothing like the prototype. + @@ -1980,6 +2088,7 @@ almost nothing like the prototype. + @@ -1994,6 +2103,7 @@ almost nothing like the prototype. + @@ -2008,6 +2118,7 @@ almost nothing like the prototype. + @@ -2022,6 +2133,7 @@ almost nothing like the prototype. + @@ -2036,6 +2148,7 @@ almost nothing like the prototype. + @@ -2050,6 +2163,7 @@ almost nothing like the prototype. + @@ -2064,6 +2178,7 @@ almost nothing like the prototype. + @@ -2078,6 +2193,7 @@ almost nothing like the prototype. + @@ -2092,6 +2208,7 @@ almost nothing like the prototype. + @@ -2106,6 +2223,7 @@ almost nothing like the prototype. + @@ -2120,6 +2238,7 @@ almost nothing like the prototype. + @@ -2133,6 +2252,7 @@ almost nothing like the prototype. + @@ -2147,6 +2267,7 @@ almost nothing like the prototype. + @@ -2161,6 +2282,7 @@ almost nothing like the prototype. + @@ -2174,6 +2296,7 @@ almost nothing like the prototype. + @@ -2188,6 +2311,7 @@ almost nothing like the prototype. + @@ -2202,6 +2326,7 @@ almost nothing like the prototype. + @@ -2216,6 +2341,7 @@ almost nothing like the prototype. + @@ -2230,6 +2356,7 @@ almost nothing like the prototype. + @@ -2244,6 +2371,7 @@ almost nothing like the prototype. + @@ -2258,12 +2386,54 @@ almost nothing like the prototype. + + + + + High Score Cartridge + 198? + Atari + + + + + + + + + + + + XBoarD Expansion + 2005 + <homebrew> + + + + + + + + + + + XM Expansion Module + 2015? + <homebrew> + + + + + + + + @@ -2272,10 +2442,11 @@ almost nothing like the prototype. Donkey Kong (homebrew, XM enhanced, HSC support) (Demo) 2012 - <homebrew> + <homebrew> + @@ -2285,10 +2456,11 @@ almost nothing like the prototype. Donkey Kong (homebrew, XM enhanced, HSC support) (Demo) (NTSC) 2012 - <homebrew> + <homebrew> + @@ -2298,10 +2470,11 @@ almost nothing like the prototype. Donkey Kong (homebrew, XM enhanced) (Demo) 2012 - <homebrew> + <homebrew> + @@ -2311,10 +2484,11 @@ almost nothing like the prototype. Donkey Kong (homebrew, XM enhanced) (Demo) (NTSC) 2012 - <homebrew> + <homebrew> + diff --git a/src/emu/bus/a7800/a78_carts.h b/src/emu/bus/a7800/a78_carts.h new file mode 100644 index 00000000000..fc463d76967 --- /dev/null +++ b/src/emu/bus/a7800/a78_carts.h @@ -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 diff --git a/src/emu/bus/a7800/a78_slot.c b/src/emu/bus/a7800/a78_slot.c new file mode 100644 index 00000000000..23429ef66a2 --- /dev/null +++ b/src/emu/bus/a7800/a78_slot.c @@ -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; + + +//------------------------------------------------- +// 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(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 \ No newline at end of file diff --git a/src/emu/bus/a7800/a78_slot.h b/src/emu/bus/a7800/a78_slot.h new file mode 100644 index 00000000000..3d54dddd993 --- /dev/null +++ b/src/emu/bus/a7800/a78_slot.h @@ -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 diff --git a/src/emu/bus/a7800/hiscore.c b/src/emu/bus/a7800/hiscore.c new file mode 100644 index 00000000000..434799cb3ee --- /dev/null +++ b/src/emu/bus/a7800/hiscore.c @@ -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(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); +} + diff --git a/src/emu/bus/a7800/hiscore.h b/src/emu/bus/a7800/hiscore.h new file mode 100644 index 00000000000..2848a144eaa --- /dev/null +++ b/src/emu/bus/a7800/hiscore.h @@ -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 m_hscslot; +}; + + + +// device type definition +extern const device_type A78_HISCORE; + + +#endif diff --git a/src/emu/bus/a7800/rom.c b/src/emu/bus/a7800/rom.c new file mode 100644 index 00000000000..2bec42385e5 --- /dev/null +++ b/src/emu/bus/a7800/rom.c @@ -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; +const device_type A78_ROM_SG = &device_creator; +const device_type A78_ROM_POKEY = &device_creator; +const device_type A78_ROM_SG_POKEY = &device_creator; +const device_type A78_ROM_SG_RAM = &device_creator; +const device_type A78_ROM_BANKRAM = &device_creator; +const device_type A78_ROM_SG_9BANKS = &device_creator; +const device_type A78_ROM_XM = &device_creator; +const device_type A78_ROM_ABSOLUTE = &device_creator; +const device_type A78_ROM_ACTIVISION = &device_creator; + + +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; +} diff --git a/src/emu/bus/a7800/rom.h b/src/emu/bus/a7800/rom.h new file mode 100644 index 00000000000..62764df81f3 --- /dev/null +++ b/src/emu/bus/a7800/rom.h @@ -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 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 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 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 diff --git a/src/emu/bus/a7800/xboard.c b/src/emu/bus/a7800/xboard.c new file mode 100644 index 00000000000..46840e18e20 --- /dev/null +++ b/src/emu/bus/a7800/xboard.c @@ -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; +const device_type A78_XM = &device_creator; + + +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]; +} + diff --git a/src/emu/bus/a7800/xboard.h b/src/emu/bus/a7800/xboard.h new file mode 100644 index 00000000000..011894b56ef --- /dev/null +++ b/src/emu/bus/a7800/xboard.h @@ -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 m_xbslot; + required_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 diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak index 9fa91b00075..04205197c69 100644 --- a/src/emu/bus/bus.mak +++ b/src/emu/bus/bus.mak @@ -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 diff --git a/src/mess/drivers/a7800.c b/src/mess/drivers/a7800.c index 745ff35c87c..2af68e471a3 100644 --- a/src/mess/drivers/a7800.c +++ b/src/mess/drivers/a7800.c @@ -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 ***************************************************************************/ diff --git a/src/mess/includes/a7800.h b/src/mess/includes/a7800.h index d37adeaf488..b8754be5f05 100644 --- a/src/mess/includes/a7800.h +++ b/src/mess/includes/a7800.h @@ -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 m_maincpu; - required_device m_pokey; required_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 m_cartslot; required_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 diff --git a/src/mess/machine/a7800.c b/src/mess/machine/a7800.c deleted file mode 100644 index 6fd3e5a22c5..00000000000 --- a/src/mess/machine/a7800.c +++ /dev/null @@ -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; -} diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 55df245aeb1..b1c259278bc 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -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 \ diff --git a/src/mess/video/a7800.c b/src/mess/video/a7800.c index c3480460d8f..4edd2091b39 100644 --- a/src/mess/video/a7800.c +++ b/src/mess/video/a7800.c @@ -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;