From f88cefad27a1737c76e09d99c9fb43e173506081 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 13 Sep 2015 08:41:44 +0200 Subject: Move all devices into separate part of src tree (nw) --- src/emu/bus/gameboy/gb_slot.c | 860 ---------------------------- src/emu/bus/gameboy/gb_slot.h | 211 ------- src/emu/bus/gameboy/mbc.c | 1274 ----------------------------------------- src/emu/bus/gameboy/mbc.h | 393 ------------- src/emu/bus/gameboy/rom.c | 364 ------------ src/emu/bus/gameboy/rom.h | 146 ----- 6 files changed, 3248 deletions(-) delete mode 100644 src/emu/bus/gameboy/gb_slot.c delete mode 100644 src/emu/bus/gameboy/gb_slot.h delete mode 100644 src/emu/bus/gameboy/mbc.c delete mode 100644 src/emu/bus/gameboy/mbc.h delete mode 100644 src/emu/bus/gameboy/rom.c delete mode 100644 src/emu/bus/gameboy/rom.h (limited to 'src/emu/bus/gameboy') diff --git a/src/emu/bus/gameboy/gb_slot.c b/src/emu/bus/gameboy/gb_slot.c deleted file mode 100644 index 922dc91cce2..00000000000 --- a/src/emu/bus/gameboy/gb_slot.c +++ /dev/null @@ -1,860 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Fabio Priuli, Wilbert Pol -/*********************************************************************************************************** - - - Game Boy cart emulation - (through slot devices) - - - The driver exposes address ranges - 0x0000-0x7fff to read_rom/write_bank - 0xa000-0xbfff to read_ram/write_ram (typically RAM/NVRAM accesses, but megaduck uses the write for bankswitch) - - currently available slot devices: - gb_rom: standard carts + TAMA5 mapper + pirate carts with protection & bankswitch - gb_mbc: MBC1-MBC7 carts (more complex bankswitch + RAM + possibly RTC/Rumble/etc.) - - ***********************************************************************************************************/ - - -#include "emu.h" -#include "gb_slot.h" - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -const device_type GB_CART_SLOT = &device_creator; -const device_type MEGADUCK_CART_SLOT = &device_creator; - -//************************************************************************** -// GB cartridges Interface -//************************************************************************** - -//------------------------------------------------- -// device_gb_cart_interface - constructor -//------------------------------------------------- - -device_gb_cart_interface::device_gb_cart_interface(const machine_config &mconfig, device_t &device) - : device_slot_card_interface(mconfig, device), - m_rom(NULL), - m_rom_size(0), - has_rumble(false), - has_timer(false), - has_battery(false) -{ -} - - -//------------------------------------------------- -// ~device_gb_cart_interface - destructor -//------------------------------------------------- - -device_gb_cart_interface::~device_gb_cart_interface() -{ -} - -//------------------------------------------------- -// rom_alloc - alloc the space for the cart -//------------------------------------------------- - -void device_gb_cart_interface::rom_alloc(UINT32 size, const char *tag) -{ - if (m_rom == NULL) - { - m_rom = device().machine().memory().region_alloc(std::string(tag).append(GBSLOT_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base(); - m_rom_size = size; - } -} - - -//------------------------------------------------- -// ram_alloc - alloc the space for the ram -//------------------------------------------------- - -void device_gb_cart_interface::ram_alloc(UINT32 size) -{ - m_ram.resize(size); -} - - -//------------------------------------------------- -// rom_map_setup - setup map of rom banks in 16K -// blocks, so to simplify ROM access -//------------------------------------------------- - -void device_gb_cart_interface::rom_map_setup(UINT32 size) -{ - int i; - // setup the rom_bank_map array to faster ROM read - for (i = 0; i < size / 0x4000; i++) - rom_bank_map[i] = i; - - // fill up remaining blocks with mirrors - while (i % 512) - { - int j = 0, repeat_banks; - while ((i % (512 >> j)) && j < 9) - j++; - repeat_banks = i % (512 >> (j - 1)); - for (int k = 0; k < repeat_banks; k++) - rom_bank_map[i + k] = rom_bank_map[i + k - repeat_banks]; - i += repeat_banks; - } - -// check bank map! -// for (i = 0; i < 256; i++) -// { -// printf("bank %3d = %3d\t", i, rom_bank_map[i]); -// if ((i%8) == 7) -// printf("\n"); -// } -} - -//------------------------------------------------- -// ram_map_setup - setup map of ram banks in 16K -// blocks, so to simplify ROM access -//------------------------------------------------- - -void device_gb_cart_interface::ram_map_setup(UINT8 banks) -{ - int mask = banks - 1; - - for (int i = 0; i < banks; i++) - ram_bank_map[i] = i; - - // Set up rest of the (mirrored) RAM pages - for (int i = banks; i < 256; i++) - ram_bank_map[i] = i & mask; -} - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// base_gb_cart_slot_device - constructor -//------------------------------------------------- -base_gb_cart_slot_device::base_gb_cart_slot_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_image_interface(mconfig, *this), - device_slot_interface(mconfig, *this), - m_sgb_hack(0), - m_type(GB_MBC_UNKNOWN) -{ -} - -gb_cart_slot_device::gb_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - base_gb_cart_slot_device(mconfig, GB_CART_SLOT, "Game Boy Cartridge Slot", tag, owner, clock, "gb_cart_slot", __FILE__) -{ -} - -megaduck_cart_slot_device::megaduck_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - base_gb_cart_slot_device(mconfig, MEGADUCK_CART_SLOT, "Megaduck Cartridge Slot", tag, owner, clock, "megaduck_cart_slot", __FILE__) -{ -} - -//------------------------------------------------- -// base_gb_cart_slot_device - destructor -//------------------------------------------------- - -base_gb_cart_slot_device::~base_gb_cart_slot_device() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void base_gb_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 base_gb_cart_slot_device::device_config_complete() -{ - // set brief and instance name - update_names(); -} - - -//------------------------------------------------- -// GB PCB -//------------------------------------------------- - - -struct gb_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 gb_slot slot_list[] = -{ - { GB_MBC_MBC1, "rom_mbc1" }, - { GB_MBC_MBC1_COL, "rom_mbc1col" }, - { GB_MBC_MBC2, "rom_mbc2" }, - { GB_MBC_MBC3, "rom_mbc3" }, - { GB_MBC_MBC5, "rom_mbc5" }, - { GB_MBC_MBC6, "rom_mbc6" }, - { GB_MBC_MBC7, "rom_mbc7" }, - { GB_MBC_TAMA5, "rom_tama5" }, - { GB_MBC_MMM01, "rom_mmm01" }, - { GB_MBC_M161, "rom_m161_m12" }, - { GB_MBC_MBC3, "rom_huc1" }, // for now treat this as alias for MBC3 - { GB_MBC_MBC3, "rom_huc3" }, // for now treat this as alias for MBC3 - { GB_MBC_SACHEN1, "rom_sachen1" }, - { GB_MBC_SACHEN2, "rom_sachen2" }, - { GB_MBC_WISDOM, "rom_wisdom" }, - { GB_MBC_YONGYONG, "rom_yong" }, - { GB_MBC_LASAMA, "rom_lasama" }, - { GB_MBC_ATVRACIN, "rom_atvrac" }, - { GB_MBC_SINTAX, "rom_sintax" }, - { GB_MBC_CHONGWU, "rom_chong" }, - { GB_MBC_LICHENG, "rom_licheng" }, - { GB_MBC_DIGIMON, "rom_digimon" }, - { GB_MBC_ROCKMAN8, "rom_rock8" }, - { GB_MBC_SM3SP, "rom_sm3sp" }, - { GB_MBC_UNK01, "rom_unk01" }, - { GB_MBC_DKONG5, "rom_dkong5" }, - { GB_MBC_CAMERA, "rom_camera" }, - { GB_MBC_188IN1, "rom_188in1" } -}; - -static int gb_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 *gb_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 "rom"; -} - - -/*------------------------------------------------- - call load - -------------------------------------------------*/ - - -bool base_gb_cart_slot_device::call_load() -{ - if (m_cart) - { - UINT32 offset = 0; - UINT32 len = (software_entry() == NULL) ? length() : get_software_region_length("rom"); - UINT8 *ROM; - int rambanks = 0; - - // From fullpath, check for presence of a header and skip it + check filesize is valid - if (software_entry() == NULL) - { - if ((len % 0x4000) == 512) - { - logerror("Rom-header found, skipping\n"); - offset = 512; - len -= offset; - fseek(offset, SEEK_SET); - } - /* Verify that the file contains 16kb blocks */ - if ((len == 0) || ((len % 0x4000) != 0)) - { - seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid rom file size\n"); - return IMAGE_INIT_FAIL; - } - } - - m_cart->rom_alloc(len, tag()); - ROM = m_cart->get_rom_base(); - - if (software_entry() == NULL) - fread(ROM, len); - else - memcpy(ROM, get_software_region("rom"), len); - - // determine cart type - offset = 0; - if (get_mmm01_candidate(ROM, len)) - offset = len - 0x8000; - - if (software_entry() != NULL) - m_type = gb_get_pcb_id(get_feature("slot") ? get_feature("slot") : "rom"); - else - m_type = get_cart_type(ROM + offset, len - offset); - - // setup additional mask/shift for MBC1 variants: - // a few game collections use the same mapper with slightly - // different lines connection with the ROM / RAM - if (m_type == GB_MBC_MBC1 || m_type == GB_MBC_188IN1) - m_cart->set_additional_wirings(0x1f, 0); - if (m_type == GB_MBC_MBC1_COL) - m_cart->set_additional_wirings(0x0f, -1); - - // setup RAM/NVRAM/RTC/RUMBLE - if (software_entry() != NULL) - { - // from softlist we only rely on xml - if (get_software_region("ram")) - rambanks = get_software_region_length("ram") / 0x2000; - - if (get_software_region("nvram")) - { - m_cart->set_has_battery(true); - rambanks = get_software_region_length("nvram") / 0x2000; - } - - if (get_feature("rumble")) - { - if (!core_stricmp(get_feature("rumble"), "yes")) - m_cart->set_has_rumble(true); - } - - if (get_feature("rtc")) - { - if (!core_stricmp(get_feature("rtc"), "yes")) - m_cart->set_has_timer(true); - } - } - else - { - // from fullpath we rely on header - switch (ROM[0x0147 + offset]) - { - case 0x03: case 0x06: case 0x09: case 0x0d: case 0x13: case 0x17: case 0x1b: case 0x22: - m_cart->set_has_battery(true); - break; - - case 0x0f: case 0x10: - m_cart->set_has_battery(true); - m_cart->set_has_timer(true); - break; - - case 0x1c: case 0x1d: - m_cart->set_has_rumble(true); - break; - - case 0x1e: - m_cart->set_has_battery(true); - m_cart->set_has_rumble(true); - break; - } - - switch (ROM[0x0149 + offset] & 0x07) - { - case 0x00: case 0x06: case 0x07: - rambanks = 0; - break; - case 0x01: case 0x02: - rambanks = 1; - break; - case 0x03: - rambanks = 4; - break; - case 0x04: - rambanks = 16; - break; - case 0x05: - default: - rambanks = 8; - break; - } - - if (m_type == GB_MBC_MBC2 || m_type == GB_MBC_MBC7) - rambanks = 1; - } - - // setup rom bank map based on real length, not header value - m_cart->rom_map_setup(len); - - if (rambanks) - setup_ram(rambanks); - - if (m_cart->get_ram_size() && m_cart->get_has_battery()) - battery_load(m_cart->get_ram_base(), m_cart->get_ram_size(), 0xff); - - //printf("Type: %s\n", gb_get_slot(m_type)); - - internal_header_logging(ROM + offset, len); - - // Hack to support Donkey Kong Land 2 + 3 in SGB - // For some reason, these store the tile data differently. Hacks will go once it's been figured out - if (strncmp((const char*)(ROM + 0x134), "DONKEYKONGLAND 2", 16) == 0 || - strncmp((const char*)(ROM + 0x134), "DONKEYKONGLAND 3", 16) == 0) - m_sgb_hack = 1; - - return IMAGE_INIT_PASS; - } - - return IMAGE_INIT_PASS; -} - -bool megaduck_cart_slot_device::call_load() -{ - if (m_cart) - { - UINT32 len = (software_entry() == NULL) ? length() : get_software_region_length("rom"); - - m_cart->rom_alloc(len, tag()); - - if (software_entry() == NULL) - fread(m_cart->get_rom_base(), len); - else - memcpy(m_cart->get_rom_base(), get_software_region("rom"), len); - - // setup rom bank map based on real length, not header value - m_cart->rom_map_setup(len); - - return IMAGE_INIT_PASS; - } - - return IMAGE_INIT_PASS; -} - - -/*------------------------------------------------- - call_unload - -------------------------------------------------*/ - -void base_gb_cart_slot_device::call_unload() -{ - if (m_cart && m_cart->get_ram_base() && m_cart->get_ram_size() && m_cart->get_has_battery()) - battery_save(m_cart->get_ram_base(), m_cart->get_ram_size()); -} - -void base_gb_cart_slot_device::setup_ram(UINT8 banks) -{ - m_cart->ram_alloc(banks * 0x2000); - memset(m_cart->get_ram_base(), 0xff, m_cart->get_ram_size()); - m_cart->ram_map_setup(banks); -} - - - -/*------------------------------------------------- - call softlist load - -------------------------------------------------*/ - -bool base_gb_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; -} - -// This fails to catch Mani 4-in-1 carts... even when they match this, then they have MBC1/3 in the internal header instead of MMM01... -bool base_gb_cart_slot_device::get_mmm01_candidate(UINT8 *ROM, UINT32 len) -{ - if (len < 0x8147) - return false; - - static const UINT8 nintendo_logo[0x18] = { - 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, - 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D, - 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E - }; - int bytes_matched = 0; - for (int i = 0; i < 0x18; i++) - { - if (ROM[(len - 0x8000) + 0x104 + i] == nintendo_logo[i]) - bytes_matched++; - } - - if (bytes_matched == 0x18 && ROM[(len - 0x8000) + 0x147] >= 0x0b && ROM[(len - 0x8000) + 0x147] <= 0x0d) - return true; - else - return false; -} - -int base_gb_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len) -{ - int type = GB_MBC_NONE; - - if (len < 0x014c) - fatalerror("Checking header of a corrupted image!\n"); - - switch(ROM[0x0147]) - { - case 0x00: type = GB_MBC_NONE; break; - case 0x01: type = GB_MBC_MBC1; break; - case 0x02: type = GB_MBC_MBC1; break; - case 0x03: type = GB_MBC_MBC1; break; - case 0x05: type = GB_MBC_MBC2; break; - case 0x06: type = GB_MBC_MBC2; break; - case 0x08: type = GB_MBC_NONE; break; - case 0x09: type = GB_MBC_NONE; break; - case 0x0b: type = GB_MBC_MMM01; break; - case 0x0c: type = GB_MBC_MMM01; break; - case 0x0d: type = GB_MBC_MMM01; break; - case 0x0f: type = GB_MBC_MBC3; break; - case 0x10: type = GB_MBC_MBC3; break; - case 0x11: type = GB_MBC_MBC3; break; - case 0x12: type = GB_MBC_MBC3; break; - case 0x13: type = GB_MBC_MBC3; break; - case 0x15: type = GB_MBC_MBC4; break; - case 0x16: type = GB_MBC_MBC4; break; - case 0x17: type = GB_MBC_MBC4; break; - case 0x19: type = GB_MBC_MBC5; break; - case 0x1a: type = GB_MBC_MBC5; break; - case 0x1b: type = GB_MBC_MBC5; break; - case 0x1c: type = GB_MBC_MBC5; break; - case 0x1d: type = GB_MBC_MBC5; break; - case 0x1e: type = GB_MBC_MBC5; break; - case 0x20: type = GB_MBC_MBC6; break; - case 0x22: type = GB_MBC_MBC7; break; - case 0xbe: type = GB_MBC_NONE; break; /* used in Flash2Advance GB Bridge boot program */ - case 0xea: type = GB_MBC_YONGYONG; break; /* Found in Sonic 3D Blast 5 pirate */ - case 0xfc: type = GB_MBC_CAMERA; break; - case 0xfd: type = GB_MBC_TAMA5; break; - case 0xfe: type = GB_MBC_HUC3; break; - case 0xff: type = GB_MBC_HUC1; break; - } - - // Check for special mappers - if (type == GB_MBC_NONE) - { - int count = 0; - for (int i = 0x0134; i <= 0x014c; i++) - { - count += ROM[i]; - } - if (count == 0) - { - type = GB_MBC_WISDOM; - } - } - - // Check for some unlicensed games - //if (type == GB_MBC_MBC5) - { - int count = 0; - for (int i = 0x0184; i < 0x0184 + 0x30; i++) - { - count += ROM[i]; - } - - if (count == 4876) - { -// printf("Li Cheng %d\n", count); - type = GB_MBC_LICHENG; - } - if (count == 4138 || count == 4125) - { - // Zhi Huan Wang uses 4138 - // most sintax use 4125 -// printf("Sintax %d!\n", count); - type = GB_MBC_SINTAX; - } - } - - /* Check if we're dealing with the multigame variant of the MBC1 mapper */ - if (type == GB_MBC_MBC1) - { // bomberman collection korea - if (ROM[0x134] == 0x42 && ROM[0x135] == 0x4f && ROM[0x136] == 0x4d && ROM[0x137] == 0x53) - type = GB_MBC_MBC1_COL; -// if (ROM[0x13f] == 0x42 && ROM[0x140] == 0x32 && ROM[0x141] == 0x43 && ROM[0x142] == 0x4B) -// type = GB_MBC_MBC1_COL; - // genjin collection - if (ROM[0x134] == 0x47 && ROM[0x135] == 0x45 && ROM[0x136] == 0x4e && ROM[0x137] == 0x43) - type = GB_MBC_MBC1_COL; - // bomberman collection japan - if (ROM[0x134] == 0x42 && ROM[0x135] == 0x4f && ROM[0x136] == 0x4d && ROM[0x137] == 0x43) - type = GB_MBC_MBC1_COL; - // mortal kombat I & II US - if (ROM[0x140] == 0x49 && ROM[0x141] == 0x26 && ROM[0x142] == 0x49 && ROM[0x143] == 0x49) - type = GB_MBC_MBC1_COL; - // mortal kombat I & II japan - if (ROM[0x140] == 0x20 && ROM[0x141] == 0x44 && ROM[0x142] == 0x55 && ROM[0x143] == 0x4f) - type = GB_MBC_MBC1_COL; - // momotarou collection 1 japan - if (ROM[0x137] == 0x4f && ROM[0x138] == 0x43 && ROM[0x139] == 0x4f && ROM[0x13a] == 0x4c) - type = GB_MBC_MBC1_COL; - // super chinese 123 dash japan - if (ROM[0x142] == 0x32 && ROM[0x143] == 0x33 && ROM[0x144] == 0x42 && ROM[0x145] == 0x41) - type = GB_MBC_MBC1_COL; - } - - return type; -} - -/*------------------------------------------------- - get default card software - -------------------------------------------------*/ - -void base_gb_cart_slot_device::get_default_card_software(std::string &result) -{ - if (open_image_file(mconfig().options())) - { - const char *slot_string = "rom"; - UINT32 len = core_fsize(m_file), offset = 0; - dynamic_buffer rom(len); - int type; - - core_fread(m_file, &rom[0], len); - - if ((len % 0x4000) == 512) - offset = 512; - - if (get_mmm01_candidate(&rom[offset], len - offset)) - offset += (len - 0x8000); - - type = get_cart_type(&rom[offset], len - offset); - slot_string = gb_get_slot(type); - - //printf("type: %s\n", slot_string); - clear(); - - result.assign(slot_string); - return; - } - - software_get_default_slot(result, "rom"); -} - - -void megaduck_cart_slot_device::get_default_card_software(std::string &result) -{ - if (open_image_file(mconfig().options())) - { - result.assign("rom"); - return; - } - - software_get_default_slot(result, "rom"); -} - - - -/*------------------------------------------------- - read - -------------------------------------------------*/ - -READ8_MEMBER(base_gb_cart_slot_device::read_rom) -{ - if (m_cart) - return m_cart->read_rom(space, offset); - else - return 0xff; -} - -READ8_MEMBER(base_gb_cart_slot_device::read_ram) -{ - if (m_cart) - return m_cart->read_ram(space, offset); - else - return 0xff; -} - - -/*------------------------------------------------- - write - -------------------------------------------------*/ - -WRITE8_MEMBER(base_gb_cart_slot_device::write_bank) -{ - if (m_cart) - m_cart->write_bank(space, offset, data); -} - -WRITE8_MEMBER(base_gb_cart_slot_device::write_ram) -{ - if (m_cart) - m_cart->write_ram(space, offset, data); -} - - -/*------------------------------------------------- - Internal header logging - -------------------------------------------------*/ - -void base_gb_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len) -{ - static const char *const cart_types[] = - { - "ROM ONLY", "ROM+MBC1", "ROM+MBC1+RAM", - "ROM+MBC1+RAM+BATTERY", "UNKNOWN", "ROM+MBC2", - "ROM+MBC2+BATTERY", "UNKNOWN", "ROM+RAM", - "ROM+RAM+BATTERY", "UNKNOWN", "ROM+MMM01", - "ROM+MMM01+SRAM", "ROM+MMM01+SRAM+BATTERY", "UNKNOWN", - "ROM+MBC3+TIMER+BATTERY", "ROM+MBC3+TIMER+RAM+BATTERY", "ROM+MBC3", - "ROM+MBC3+RAM", "ROM+MBC3+RAM+BATTERY", "UNKNOWN", - "UNKNOWN", "UNKNOWN", "UNKNOWN", - "UNKNOWN", "ROM+MBC5", "ROM+MBC5+RAM", - "ROM+MBC5+RAM+BATTERY", "ROM+MBC5+RUMBLE", "ROM+MBC5+RUMBLE+SRAM", - "ROM+MBC5+RUMBLE+SRAM+BATTERY", "Pocket Camera", "Bandai TAMA5", - /* Need heaps of unknowns here */ - "Hudson HuC-3", "Hudson HuC-1" - }; - - // some company codes - static const struct - { - UINT16 code; - const char *name; - } - companies[] = - { - {0x3301, "Nintendo"}, - {0x7901, "Accolade"}, - {0xA400, "Konami"}, - {0x6701, "Ocean"}, - {0x5601, "LJN"}, - {0x9900, "ARC?"}, - {0x0101, "Nintendo"}, - {0x0801, "Capcom"}, - {0x0100, "Nintendo"}, - {0xBB01, "SunSoft"}, - {0xA401, "Konami"}, - {0xAF01, "Namcot?"}, - {0x4901, "Irem"}, - {0x9C01, "Imagineer"}, - {0xA600, "Kawada?"}, - {0xB101, "Nexoft"}, - {0x5101, "Acclaim"}, - {0x6001, "Titus"}, - {0xB601, "HAL"}, - {0x3300, "Nintendo"}, - {0x0B00, "Coconuts?"}, - {0x5401, "Gametek"}, - {0x7F01, "Kemco?"}, - {0xC001, "Taito"}, - {0xEB01, "Atlus"}, - {0xE800, "Asmik?"}, - {0xDA00, "Tomy?"}, - {0xB100, "ASCII?"}, - {0xEB00, "Atlus"}, - {0xC000, "Taito"}, - {0x9C00, "Imagineer"}, - {0xC201, "Kemco?"}, - {0xD101, "Sofel?"}, - {0x6101, "Virgin"}, - {0xBB00, "SunSoft"}, - {0xCE01, "FCI?"}, - {0xB400, "Enix?"}, - {0xBD01, "Imagesoft"}, - {0x0A01, "Jaleco?"}, - {0xDF00, "Altron?"}, - {0xA700, "Takara?"}, - {0xEE00, "IGS?"}, - {0x8300, "Lozc?"}, - {0x5001, "Absolute?"}, - {0xDD00, "NCS?"}, - {0xE500, "Epoch?"}, - {0xCB00, "VAP?"}, - {0x8C00, "Vic Tokai"}, - {0xC200, "Kemco?"}, - {0xBF00, "Sammy?"}, - {0x1800, "Hudson Soft"}, - {0xCA01, "Palcom/Ultra"}, - {0xCA00, "Palcom/Ultra"}, - {0xC500, "Data East?"}, - {0xA900, "Technos Japan?"}, - {0xD900, "Banpresto?"}, - {0x7201, "Broderbund?"}, - {0x7A01, "Triffix Entertainment?"}, - {0xE100, "Towachiki?"}, - {0x9300, "Tsuburava?"}, - {0xC600, "Tonkin House?"}, - {0xCE00, "Pony Canyon"}, - {0x7001, "Infogrames?"}, - {0x8B01, "Bullet-Proof Software?"}, - {0x5501, "Park Place?"}, - {0xEA00, "King Records?"}, - {0x5D01, "Tradewest?"}, - {0x6F01, "ElectroBrain?"}, - {0xAA01, "Broderbund?"}, - {0xC301, "SquareSoft"}, - {0x5201, "Activision?"}, - {0x5A01, "Bitmap Brothers/Mindscape"}, - {0x5301, "American Sammy"}, - {0x4701, "Spectrum Holobyte"}, - {0x1801, "Hudson Soft"}, - {0x0000, NULL} - }; - static const int ramsize[8] = { 0, 2, 8, 32, 128, 64, 0, 0 }; - - char soft[17]; - UINT32 tmp = 0; - int csum = 0, i = 0; - int rom_banks; - - switch (ROM[0x0148]) - { - case 0x52: - rom_banks = 72; - break; - case 0x53: - rom_banks = 80; - break; - case 0x54: - rom_banks = 96; - break; - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - rom_banks = 2 << ROM[0x0148]; - break; - default: - rom_banks = 256; - break; - } - - strncpy(soft, (char *)&ROM[0x0134], 16); - soft[16] = '\0'; - logerror("Cart Information\n"); - logerror("\tName: %s\n", soft); - logerror("\tType: %s [0x%2X]\n", (ROM[0x0147] <= 32) ? cart_types[ROM[0x0147]] : "", ROM[0x0147] ); - logerror("\tGame Boy: %s\n", (ROM[0x0143] == 0xc0) ? "No" : "Yes" ); - logerror("\tSuper GB: %s [0x%2X]\n", (ROM[0x0146] == 0x03) ? "Yes" : "No", ROM[0x0146] ); - logerror("\tColor GB: %s [0x%2X]\n", (ROM[0x0143] == 0x80 || ROM[0x0143] == 0xc0) ? "Yes" : "No", ROM[0x0143] ); - logerror("\tROM Size: %d 16kB Banks [0x%2X]\n", rom_banks, ROM[0x0148]); - logerror("\tRAM Size: %d kB [0x%2X]\n", ramsize[ROM[0x0149] & 0x07], ROM[0x0149]); - logerror("\tLicense code: 0x%2X%2X\n", ROM[0x0145], ROM[0x0144] ); - tmp = (ROM[0x014b] << 8) + ROM[0x014a]; - for (i = 0; i < ARRAY_LENGTH(companies); i++) - if (tmp == companies[i].code) - break; - logerror("\tManufacturer ID: 0x%2X", tmp); - logerror(" [%s]\n", (i < ARRAY_LENGTH(companies)) ? companies[i].name : "?"); - logerror("\tVersion Number: 0x%2X\n", ROM[0x014c]); - logerror("\tComplement Check: 0x%2X\n", ROM[0x014d]); - logerror("\tChecksum: 0x%2X\n", ((ROM[0x014e] << 8) + ROM[0x014f])); - tmp = (ROM[0x0103] << 8) + ROM[0x0102]; - logerror("\tStart Address: 0x%2X\n", tmp); - - // Additional checks - if (rom_banks == 256) - logerror("\nWarning loading cartridge: Unknown ROM size in header [0x%x].\n", ROM[0x0148]); - - if ((len / 0x4000) != rom_banks) - logerror("\nWarning loading cartridge: Filesize (0x%x) and reported ROM banks (0x%x) don't match.\n", - len, rom_banks * 0x4000); - /* Calculate and check checksum */ - tmp = (ROM[0x014e] << 8) + ROM[0x014f]; - for (int i = 0; i < len; i++) - csum += ROM[i]; - csum -= (ROM[0x014e] + ROM[0x014f]); - csum &= 0xffff; - - if (csum != tmp) - logerror("\nWarning loading cartridge: Checksum is wrong (Actual %X vs Internal %X)\n", csum, tmp); - -} diff --git a/src/emu/bus/gameboy/gb_slot.h b/src/emu/bus/gameboy/gb_slot.h deleted file mode 100644 index 711037a0da8..00000000000 --- a/src/emu/bus/gameboy/gb_slot.h +++ /dev/null @@ -1,211 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Fabio Priuli, Wilbert Pol -#ifndef __GB_SLOT_H -#define __GB_SLOT_H - -/*************************************************************************** - TYPE DEFINITIONS - ***************************************************************************/ - - -/* PCB */ -enum -{ - GB_MBC_NONE = 0, /* 32KB ROM - No memory bank controller */ - GB_MBC_MBC1, /* ~2MB ROM, 8KB RAM -or- 512KB ROM, 32KB RAM */ - GB_MBC_MBC2, /* 256KB ROM, 32KB RAM */ - GB_MBC_MBC3, /* 2MB ROM, 32KB RAM, RTC */ - GB_MBC_MBC4, /* ?? ROM, ?? RAM */ - GB_MBC_MBC5, /* 8MB ROM, 128KB RAM (32KB w/ Rumble) */ - GB_MBC_TAMA5, /* ?? ROM ?? RAM - What is this? */ - GB_MBC_HUC1, /* ?? ROM, ?? RAM - Hudson Soft Controller */ - GB_MBC_HUC3, /* ?? ROM, ?? RAM - Hudson Soft Controller */ - GB_MBC_MBC6, /* ?? ROM, 32KB SRAM */ - GB_MBC_MBC7, /* ?? ROM, ?? RAM */ - GB_MBC_M161, /* ?? ROM, ?? RAM */ - GB_MBC_MMM01, /* ?? ROM, ?? RAM */ - GB_MBC_WISDOM, /* ?? ROM, ?? RAM - Wisdom tree controller */ - GB_MBC_MBC1_COL, /* 1MB ROM, 32KB RAM - workaround for MBC1 on PCB that maps rom address lines differently */ - GB_MBC_SACHEN1, /* ?? ROM, ?? RAM - Sachen MMC-1 variant */ - GB_MBC_SACHEN2, /* ?? ROM, ?? RAM - Sachen MMC-2 variant */ - GB_MBC_YONGYONG, /* ?? ROM, ?? RAM - Appears in Sonic 3D Blast 5 pirate */ - GB_MBC_LASAMA, /* ?? ROM, ?? RAM - Appears in La Sa Ma */ - GB_MBC_ATVRACIN, - GB_MBC_CAMERA, - GB_MBC_188IN1, - GB_MBC_SINTAX, - GB_MBC_CHONGWU, - GB_MBC_LICHENG, - GB_MBC_DIGIMON, - GB_MBC_ROCKMAN8, - GB_MBC_SM3SP, - GB_MBC_DKONG5, - GB_MBC_UNK01, - GB_MBC_MEGADUCK, /* MEGADUCK style banking */ - GB_MBC_UNKNOWN /* Unknown mapper */ -}; - - -// ======================> device_gb_cart_interface - -class device_gb_cart_interface : public device_slot_card_interface -{ -public: - // construction/destruction - device_gb_cart_interface(const machine_config &mconfig, device_t &device); - virtual ~device_gb_cart_interface(); - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom) { return 0xff; } - virtual DECLARE_WRITE8_MEMBER(write_bank) {} - virtual DECLARE_READ8_MEMBER(read_ram) { return 0xff; } - virtual DECLARE_WRITE8_MEMBER(write_ram) {} - - void rom_alloc(UINT32 size, const char *tag); - void ram_alloc(UINT32 size); - UINT8* get_rom_base() { return m_rom; } - UINT8* get_ram_base() { return &m_ram[0]; } - UINT32 get_rom_size() { return m_rom_size; } - UINT32 get_ram_size() { return m_ram.size(); } - - void rom_map_setup(UINT32 size); - void ram_map_setup(UINT8 banks); - - virtual void set_additional_wirings(UINT8 mask, int shift) { } // MBC-1 will then overwrite this! - void set_has_timer(bool val) { has_timer = val; } - void set_has_rumble(bool val) { has_rumble = val; } - void set_has_battery(bool val) { has_battery = val; } - bool get_has_battery() { return has_battery; } - - void save_ram() { device().save_item(NAME(m_ram)); } - - // internal state - UINT8 *m_rom; - UINT32 m_rom_size; - dynamic_buffer m_ram; - - // bankswitch variables - // we access ROM/RAM banks through these bank maps - // default accesses are: - // 0x0000-0x3fff = rom_bank_map[m_latch_bank] (generally defaults to m_latch_bank = 0) - // 0x4000-0x7fff = rom_bank_map[m_latch_bank2] (generally defaults to m_latch_bank2 = 1) - // 0xa000-0xbfff = ram_bank_map[m_ram_bank] (generally defaults to m_ram_bank = 0) - // suitable writes to 0x0000-0x7fff can then modify m_latch_bank/m_latch_bank2 - UINT8 rom_bank_map[512]; // 16K chunks of ROM - UINT8 ram_bank_map[256]; // 16K chunks of RAM - UINT8 m_ram_bank; - UINT16 m_latch_bank, m_latch_bank2; - - bool has_rumble, has_timer, has_battery; -}; - - -// ======================> base_gb_cart_slot_device - -class base_gb_cart_slot_device : public device_t, - public device_image_interface, - public device_slot_interface -{ -public: - // construction/destruction - base_gb_cart_slot_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); - virtual ~base_gb_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_type() { return m_type; } - int get_cart_type(UINT8 *ROM, UINT32 len); - bool get_mmm01_candidate(UINT8 *ROM, UINT32 len); - // remove me when SGB is properly emulated - int get_sgb_hack() { return m_sgb_hack; } - - void setup_ram(UINT8 banks); - void internal_header_logging(UINT8 *ROM, UINT32 len); - void save_ram() { if (m_cart && m_cart->get_ram_size()) m_cart->save_ram(); } - - 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 "gameboy_cart"; } - virtual const char *file_extensions() const { return "bin,gb,gbc"; } - - // slot interface overrides - virtual void get_default_card_software(std::string &result); - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - - -protected: - // Donkey Kong Land 2 + 3 store SGB border tiles differently... this will be hopefully be removed when SGB is properly emulated! - int m_sgb_hack; - - int m_type; - device_gb_cart_interface* m_cart; -}; - -// ======================> gb_cart_slot_device - -class gb_cart_slot_device : public base_gb_cart_slot_device -{ -public: - // construction/destruction - gb_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); -}; - - -// ======================> megaduck_cart_slot_device - -class megaduck_cart_slot_device : public base_gb_cart_slot_device -{ -public: - // construction/destruction - megaduck_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // image-level overrides - virtual bool call_load(); - virtual const char *image_interface() const { return "megaduck_cart"; } - virtual const char *file_extensions() const { return "bin"; } - - // slot interface overrides - virtual void get_default_card_software(std::string &result); -}; - - - - -// device type definition -extern const device_type GB_CART_SLOT; -extern const device_type MEGADUCK_CART_SLOT; - - -/*************************************************************************** - DEVICE CONFIGURATION MACROS - ***************************************************************************/ - -#define GBSLOT_ROM_REGION_TAG ":cart:rom" - -#define MCFG_GB_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \ - MCFG_DEVICE_ADD(_tag, GB_CART_SLOT, 0) \ - MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) - -#define MCFG_MEGADUCK_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \ - MCFG_DEVICE_ADD(_tag, MEGADUCK_CART_SLOT, 0) \ - MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) - - -#endif diff --git a/src/emu/bus/gameboy/mbc.c b/src/emu/bus/gameboy/mbc.c deleted file mode 100644 index 4c0a81459b6..00000000000 --- a/src/emu/bus/gameboy/mbc.c +++ /dev/null @@ -1,1274 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Fabio Priuli, Wilbert Pol -/*********************************************************************************************************** - - Game Boy carts with MBC (Memory Bank Controller) - - - TODO: add proper RTC and Rumble support - - ***********************************************************************************************************/ - - -#include "emu.h" -#include "mbc.h" - - -//------------------------------------------------- -// gb_rom_mbc*_device - constructor -//------------------------------------------------- - -const device_type GB_ROM_MBC1 = &device_creator; -const device_type GB_ROM_MBC2 = &device_creator; -const device_type GB_ROM_MBC3 = &device_creator; -const device_type GB_ROM_MBC5 = &device_creator; -const device_type GB_ROM_MBC6 = &device_creator; -const device_type GB_ROM_MBC7 = &device_creator; -const device_type GB_ROM_M161_M12 = &device_creator; -const device_type GB_ROM_MMM01 = &device_creator; -const device_type GB_ROM_SACHEN1 = &device_creator; -const device_type GB_ROM_SACHEN2 = &device_creator; -const device_type GB_ROM_188IN1 = &device_creator; -const device_type GB_ROM_SINTAX = &device_creator; -const device_type GB_ROM_CHONGWU = &device_creator; -const device_type GB_ROM_LICHENG = &device_creator; -const device_type GB_ROM_DIGIMON = &device_creator; -const device_type GB_ROM_ROCKMAN8 = &device_creator; -const device_type GB_ROM_SM3SP = &device_creator; - - -gb_rom_mbc_device::gb_rom_mbc_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_gb_cart_interface( mconfig, *this ) -{ -} - -gb_rom_mbc1_device::gb_rom_mbc1_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) - : gb_rom_mbc_device(mconfig, type, name, tag, owner, clock, shortname, source), - m_mask(0x1f), - m_shift(0) -{ -} - -gb_rom_mbc1_device::gb_rom_mbc1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MBC1, "GB MBC1 Carts", tag, owner, clock, "gb_rom_mbc1", __FILE__), - m_mask(0x1f), - m_shift(0) -{ -} - -gb_rom_mbc2_device::gb_rom_mbc2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MBC2, "GB MBC2 Carts", tag, owner, clock, "gb_rom_mbc2", __FILE__) -{ -} - -gb_rom_mbc3_device::gb_rom_mbc3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MBC3, "GB MBC3 Carts", tag, owner, clock, "gb_rom_mbc3", __FILE__) -{ -} - -gb_rom_mbc5_device::gb_rom_mbc5_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) - : gb_rom_mbc_device(mconfig, type, name, tag, owner, clock, shortname, source) -{ -} - -gb_rom_mbc5_device::gb_rom_mbc5_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MBC5, "GB MBC5 Carts", tag, owner, clock, "gb_rom_mbc5", __FILE__) -{ -} - -gb_rom_mbc6_device::gb_rom_mbc6_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MBC6, "GB MBC6 Carts", tag, owner, clock, "gb_rom_mbc6", __FILE__) -{ -} - -gb_rom_mbc7_device::gb_rom_mbc7_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MBC7, "GB MBC7 Carts", tag, owner, clock, "gb_rom_mbc7", __FILE__) -{ -} - -gb_rom_m161_device::gb_rom_m161_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_M161_M12, "GB M161-M12 Carts", tag, owner, clock, "gb_rom_m161m12", __FILE__) -{ -} - -gb_rom_mmm01_device::gb_rom_mmm01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_MMM01, "GB MMM01 Carts", tag, owner, clock, "gb_rom_mmm01", __FILE__) -{ -} - -gb_rom_sachen_mmc1_device::gb_rom_sachen_mmc1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_SACHEN1, "GB Sachen MMC1 Carts", tag, owner, clock, "gb_rom_sachen1", __FILE__) -{ -} - -gb_rom_sachen_mmc1_device::gb_rom_sachen_mmc1_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) - : gb_rom_mbc_device(mconfig, type, name, tag, owner, clock, shortname, source) -{ -} - -gb_rom_sachen_mmc2_device::gb_rom_sachen_mmc2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_sachen_mmc1_device(mconfig, GB_ROM_SACHEN2, "GB Sachen MMC2 Carts", tag, owner, clock, "gb_rom_sachen2", __FILE__) -{ -} - -gb_rom_188in1_device::gb_rom_188in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc1_device(mconfig, GB_ROM_188IN1, "GB 188in1", tag, owner, clock, "gb_rom_188in1", __FILE__) -{ -} - -gb_rom_sintax_device::gb_rom_sintax_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_SINTAX, "GB MBC5 Sintax Carts", tag, owner, clock, "gb_rom_sintax", __FILE__) -{ -} - -gb_rom_chongwu_device::gb_rom_chongwu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc5_device(mconfig, GB_ROM_CHONGWU, "GB Chong Wu Xiao Jing Ling", tag, owner, clock, "gb_rom_chongwu", __FILE__) -{ -} - -gb_rom_licheng_device::gb_rom_licheng_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc5_device(mconfig, GB_ROM_LICHENG, "GB MBC5 Li Cheng Carts", tag, owner, clock, "gb_rom_licheng", __FILE__) -{ -} - -gb_rom_digimon_device::gb_rom_digimon_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc5_device(mconfig, GB_ROM_DIGIMON, "GB Digimon", tag, owner, clock, "gb_rom_digimon", __FILE__) -{ -} - -gb_rom_rockman8_device::gb_rom_rockman8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_ROCKMAN8, "GB MBC1 Rockman 8", tag, owner, clock, "gb_rom_rockman8", __FILE__) -{ -} - -gb_rom_sm3sp_device::gb_rom_sm3sp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_mbc_device(mconfig, GB_ROM_SM3SP, "GB MBC1 Super Mario 3 Special", tag, owner, clock, "gb_rom_sm3sp", __FILE__) -{ -} - - -//------------------------------------------------- -// shared_start -//------------------------------------------------- - -void gb_rom_mbc_device::shared_start() -{ - save_item(NAME(m_latch_bank)); - save_item(NAME(m_latch_bank2)); - save_item(NAME(m_ram_bank)); - save_item(NAME(m_ram_enable)); -} - -//------------------------------------------------- -// shared_reset -//------------------------------------------------- - -void gb_rom_mbc_device::shared_reset() -{ - m_latch_bank = 0; - m_latch_bank2 = 1; - m_ram_bank = 0; - m_ram_enable = 0; -} - -//------------------------------------------------- -// mapper specific start/reset -//------------------------------------------------- - -void gb_rom_mbc3_device::device_start() -{ - shared_start(); - save_item(NAME(m_rtc_map)); -} - -void gb_rom_mbc3_device::device_reset() -{ - shared_reset(); - memset(m_rtc_map, 0, sizeof(m_rtc_map)); -} - -void gb_rom_mbc6_device::device_start() -{ - save_item(NAME(m_bank_4000)); - save_item(NAME(m_bank_6000)); - save_item(NAME(m_latch1)); - save_item(NAME(m_latch2)); - save_item(NAME(m_latch_bank)); - save_item(NAME(m_latch_bank2)); - save_item(NAME(m_ram_bank)); - save_item(NAME(m_ram_enable)); -} - -void gb_rom_mbc6_device::device_reset() -{ - m_bank_4000 = 2; // correct default? - m_bank_6000 = 3; // correct default? - m_latch1 = 0; // correct default? - m_latch2 = 0; // correct default? - - m_latch_bank = 2; // correct default? - m_latch_bank2 = 3; // correct default? - m_ram_bank = 0; - m_ram_enable = 0; -} - -void gb_rom_m161_device::device_start() -{ - shared_start(); - save_item(NAME(m_base_bank)); -} - -void gb_rom_m161_device::device_reset() -{ - shared_reset(); - m_base_bank = 0; -} - -void gb_rom_mmm01_device::device_start() -{ - shared_start(); - save_item(NAME(m_bank_mask)); - save_item(NAME(m_bank)); - save_item(NAME(m_reg)); -} - -void gb_rom_mmm01_device::device_reset() -{ - m_latch_bank = 0x200 - 2; - m_latch_bank2 = 0x200 - 1; - m_ram_bank = 0; - m_bank_mask = 0xff; - m_bank = 0; - m_reg = 0; -} - -void gb_rom_sachen_mmc1_device::device_start() -{ - shared_start(); - save_item(NAME(m_base_bank)); - save_item(NAME(m_mask)); - save_item(NAME(m_mode)); - save_item(NAME(m_unlock_cnt)); -} - -void gb_rom_sachen_mmc1_device::device_reset() -{ - shared_reset(); - m_base_bank = 0x00; - m_mask = 0x00; - m_mode = MODE_LOCKED; - m_unlock_cnt = 0x00; -} - -void gb_rom_sachen_mmc2_device::device_start() -{ - shared_start(); - save_item(NAME(m_base_bank)); - save_item(NAME(m_mask)); - save_item(NAME(m_mode)); - save_item(NAME(m_unlock_cnt)); -} - -void gb_rom_sachen_mmc2_device::device_reset() -{ - shared_reset(); - m_base_bank = 0x00; - m_mask = 0x00; - m_mode = MODE_LOCKED_DMG; - m_unlock_cnt = 0x00; -} - -void gb_rom_sintax_device::device_start() -{ - shared_start(); - save_item(NAME(m_sintax_mode)); - save_item(NAME(m_currentxor)); - save_item(NAME(m_xor2)); - save_item(NAME(m_xor3)); - save_item(NAME(m_xor4)); - save_item(NAME(m_xor5)); -} - -void gb_rom_sintax_device::device_reset() -{ - shared_reset(); - m_sintax_mode = 0; - m_currentxor = 0; - m_xor2 = 0; - m_xor3 = 0; - m_xor4 = 0; - m_xor5 = 0; -} - -void gb_rom_chongwu_device::device_start() -{ - shared_start(); - save_item(NAME(m_protection_checked)); -} - -void gb_rom_chongwu_device::device_reset() -{ - shared_reset(); - m_protection_checked = 0; -} - - -/*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ - -READ8_MEMBER(gb_rom_mbc_device::read_rom) -{ - return m_rom[rom_bank_map[m_latch_bank] + offset]; -} - -READ8_MEMBER(gb_rom_mbc_device::read_ram) -{ - if (!m_ram.empty()) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + offset]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc_device::write_ram) -{ - if (!m_ram.empty()) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + offset] = data; -} - - -// MBC1 - -READ8_MEMBER(gb_rom_mbc1_device::read_rom) -{ - if (offset & 0x4000) /* RB1 */ - return m_rom[rom_bank_map[(m_ram_bank << (5 + m_shift)) | m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; - else - { /* RB0 */ - int bank = (m_mode == MODE_4M_256k) ? (m_ram_bank << (5 + m_shift)) : 0; - return m_rom[rom_bank_map[bank] * 0x4000 + (offset & 0x3fff)]; - } -} - -WRITE8_MEMBER(gb_rom_mbc1_device::write_bank) -{ - // the mapper only uses inputs A15..A13 - switch (offset & 0xe000) - { - case 0x0000: // RAM Enable Register - m_ram_enable = ((data & 0x0f) == 0x0a) ? 1 : 0; - break; - case 0x2000: // ROM Bank Register - data &= 0x1f; - m_latch_bank2 = data ? data : 1; - m_latch_bank2 &= m_mask; - break; - case 0x4000: // RAM Bank Register - m_ram_bank = data & 0x3; - break; - case 0x6000: // MBC1 Mode Register - m_mode = (data & 0x1) ? MODE_4M_256k : MODE_16M_64k; - break; - } -} - -READ8_MEMBER(gb_rom_mbc1_device::read_ram) -{ - if (!m_ram.empty() && m_ram_enable) - { - int bank = (m_mode == MODE_4M_256k) ? m_ram_bank : 0; - return m_ram[ram_bank_map[bank] * 0x2000 + offset]; - } - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc1_device::write_ram) -{ - if (!m_ram.empty() && m_ram_enable) - { - int bank = (m_mode == MODE_4M_256k) ? m_ram_bank : 0; - m_ram[ram_bank_map[bank] * 0x2000 + offset] = data; - } -} - - -// MBC2 - -READ8_MEMBER(gb_rom_mbc2_device::read_rom) -{ - if (offset & 0x4000) /* RB1 */ - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; - else /* RB0 */ - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_mbc2_device::write_bank) -{ - // the mapper only has data lines D3..D0 - data &= 0x0f; - - // the mapper only uses inputs A15..A14, A8 for register accesses - switch (offset & 0xc100) - { - case 0x0000: // RAM Enable Register - m_ram_enable = (data == 0x0a) ? 1 : 0; - break; - case 0x0100: // ROM Bank Register - m_latch_bank2 = (data == 0x00) ? 0x01 : data; - break; - } -} - -READ8_MEMBER(gb_rom_mbc2_device::read_ram) -{ - if (!m_ram.empty() && m_ram_enable) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x01ff)] | 0xF0; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc2_device::write_ram) -{ - if (!m_ram.empty() && m_ram_enable) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x01ff)] = data & 0x0F; -} - - -// MBC3 - -READ8_MEMBER(gb_rom_mbc3_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_mbc3_device::write_bank) -{ - if (offset < 0x2000) - m_ram_enable = ((data & 0x0f) == 0x0a) ? 1 : 0; - else if (offset < 0x4000) - { - // 7bits - data &= 0x7f; - /* Selecting bank 0 == selecting bank 1 */ - if (data == 0) - data = 1; - - m_latch_bank2 = data; - } - else if (offset < 0x6000) - { - m_ram_bank = data; - } - else - { - if (has_timer) - { - /* FIXME: RTC Latch goes here */ - m_rtc_map[0] = 50; /* Seconds */ - m_rtc_map[1] = 40; /* Minutes */ - m_rtc_map[2] = 15; /* Hours */ - m_rtc_map[3] = 25; /* Day counter lowest 8 bits */ - m_rtc_map[4] = 0x01; /* Day counter upper bit, timer off, no day overflow occurred (bit7) */ - } - } -} - -READ8_MEMBER(gb_rom_mbc3_device::read_ram) -{ - if (m_ram_bank < 4 && m_ram_enable) - { // RAM - if (!m_ram.empty()) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)]; - } - if (m_ram_bank >= 0x8 && m_ram_bank <= 0xc) - { // RAM - if (has_timer) - return m_rtc_map[m_ram_bank - 8]; - } - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc3_device::write_ram) -{ - if (m_ram_bank < 4 && m_ram_enable) - { // RAM - if (!m_ram.empty()) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data; - } - if (m_ram_bank >= 0x8 && m_ram_bank <= 0xc) - { // RAM - if (has_timer) - { - // what to do here? - } - } -} - -// MBC5 - -READ8_MEMBER(gb_rom_mbc5_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_mbc5_device::write_bank) -{ - if (offset < 0x2000) - m_ram_enable = ((data & 0x0f) == 0x0a) ? 1 : 0; - else if (offset < 0x3000) - { - // MBC5 has a 9 bit bank select - // Writing into 2000-2fff sets the lower 8 bits - m_latch_bank2 = (m_latch_bank2 & 0x100) | data; - } - else if (offset < 0x4000) - { - // MBC5 has a 9 bit bank select - // Writing into 3000-3fff sets the 9th bit - m_latch_bank2 = (m_latch_bank2 & 0xff) | ((data & 0x01) << 8); - } - else if (offset < 0x6000) - { - data &= 0x0f; - if (has_rumble) - data &= 0x7; - m_ram_bank = data; - } -} - -READ8_MEMBER(gb_rom_mbc5_device::read_ram) -{ - if (!m_ram.empty() && m_ram_enable) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc5_device::write_ram) -{ - if (!m_ram.empty() && m_ram_enable) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data; -} - -// MBC6 - -READ8_MEMBER(gb_rom_mbc6_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else if (offset < 0x6000) - return m_rom[rom_bank_map[m_bank_4000 >> 1] * 0x4000 + (m_bank_4000 & 0x01) * 0x2000 + (offset & 0x1fff)]; - else - return m_rom[rom_bank_map[m_bank_6000 >> 1] * 0x4000 + (m_bank_6000 & 0x01) * 0x2000 + (offset & 0x1fff)]; -} - -WRITE8_MEMBER(gb_rom_mbc6_device::write_bank) -{ - if (offset < 0x2000) - { - logerror( "0x%04X: write to mbc6 ram enable area: %04X <- 0x%02X\n", space.device().safe_pc(), offset, data ); - } - else if (offset < 0x3000) - { - if (!(offset & 0x0800)) - m_latch1 = data; - else if (data == 0x00) - m_bank_4000 = m_latch1; - } - else if (offset < 0x4000) - { - if (!(offset & 0x0800)) - m_latch2 = data; - else if (data == 0x00) - m_bank_6000 = m_latch2; - } -} - -READ8_MEMBER(gb_rom_mbc6_device::read_ram) -{ - if (!m_ram.empty()) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc6_device::write_ram) -{ - if (!m_ram.empty()) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data; -} - -// MBC7 - -READ8_MEMBER(gb_rom_mbc7_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_mbc7_device::write_bank) -{ - if (offset < 0x2000) - { - // FIXME: Add RAM enable support - logerror("0x%04X: Write to ram enable register 0x%04X <- 0x%02X\n", space.device().safe_pc( ), offset, data); - } - else if (offset < 0x3000) - { - logerror( "0x%04X: write to mbc7 rom select register: 0x%04X <- 0x%02X\n", space.device() .safe_pc( ), 0x2000 + offset, data ); - /* Bit 12 must be set for writing to the mbc register */ - if (offset & 0x0100) - m_latch_bank2 = data; - } - else - { - logerror( "0x%04X: write to mbc7 rom area: 0x%04X <- 0x%02X\n", space.device() .safe_pc( ), 0x3000 + offset, data ); - /* Bit 12 must be set for writing to the mbc register */ - if (offset & 0x0100) - { - switch (offset & 0x7000) - { - case 0x3000: /* 0x3000-0x3fff */ - case 0x4000: /* 0x4000-0x4fff */ - case 0x5000: /* 0x5000-0x5fff */ - case 0x6000: /* 0x6000-0x6fff */ - case 0x7000: /* 0x7000-0x7fff */ - break; - } - } - } -} - -READ8_MEMBER(gb_rom_mbc7_device::read_ram) -{ - if (!m_ram.empty()) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_mbc7_device::write_ram) -{ - if (!m_ram.empty()) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data; -} - - -// M161-M12 - -READ8_MEMBER(gb_rom_m161_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_base_bank] * 0x4000 + offset]; - else - return m_rom[rom_bank_map[m_base_bank] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_m161_device::write_bank) -{ - switch (offset & 0xe000) - { - case 0x4000: // Base Bank Register - m_base_bank = data << 1; - break; - case 0x2000: // Tetris writes 1 here when selected... - default: - break; - } -} - - -// MMM01 -// This mmm01 implementation is mostly guess work, no clue how correct it all is -/* TODO: This implementation is wrong. Tauwasser - * - * Register 0: Map Latch, AA Mask, RAM Enable - * Register 1: EA1..EA0, RA18..RA14 - * Register 2: ??, AA18..AA15, AA14..AA13 - * Register 3: AA Multiplex, RA Mask, ???, MBC1 Mode - * - */ - -READ8_MEMBER(gb_rom_mmm01_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + offset]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_mmm01_device::write_bank) -{ - if (offset < 0x2000) - { - if (data & 0x40) - { - m_latch_bank = m_reg; - m_latch_bank2 = m_latch_bank + m_bank; - } - } - else if (offset < 0x4000) - { - m_reg = data & ((m_rom_size / 0x4000) - 1); - m_bank = m_reg & m_bank_mask; - if (m_bank == 0) - m_bank = 1; - m_latch_bank2 = m_latch_bank + m_bank; - } - else if (offset < 0x6000) - logerror("0x%04X: write 0x%02X to 0x%04X\n", space.device().safe_pc(), data, offset); - else - { - logerror("0x%04X: write 0x%02X to 0x%04X\n", space.device().safe_pc(), data, offset); - /* Not sure if this is correct, Taito Variety Pack sets these values */ - /* Momotarou Collection 2 writes 01 and 21 here */ - switch (data) - { - case 0x30: m_bank_mask = 0x07; break; - case 0x38: m_bank_mask = 0x03; break; - default: m_bank_mask = 0xff; break; - } - } -} - -// Sachen MMC1 - -READ8_MEMBER(gb_rom_sachen_mmc1_device::read_rom) -{ - UINT16 off_edit = offset; - - /* Wait for 0x31 transitions of A15 (hi -> lo), i.e. ROM accesses; A15 = HI while in bootstrap */ - /* This is 0x31 transitions, because we increment counter _after_ checking it */ - if (m_unlock_cnt == 0x30) - m_mode = MODE_UNLOCKED; - else - m_unlock_cnt++; - - /* Logo Switch */ - if (m_mode == MODE_LOCKED) - off_edit |= 0x80; - - /* Header Un-Scramble */ - if ((off_edit & 0xFF00) == 0x0100) { - off_edit &= 0xFFAC; - off_edit |= ((offset >> 6) & 0x01) << 0; - off_edit |= ((offset >> 4) & 0x01) << 1; - off_edit |= ((offset >> 1) & 0x01) << 4; - off_edit |= ((offset >> 0) & 0x01) << 6; - } - //logerror("read from %04X (%04X)\n", offset, off_edit); - - if (offset & 0x4000) /* RB1 */ - return m_rom[rom_bank_map[(m_base_bank & m_mask) | (m_latch_bank2 & ~m_mask)] * 0x4000 + (offset & 0x3fff)]; - else /* RB0 */ - return m_rom[rom_bank_map[(m_base_bank & m_mask) | (m_latch_bank & ~m_mask)] * 0x4000 + (off_edit & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_sachen_mmc1_device::write_bank) -{ - /* Only A15..A6, A4, A1..A0 are connected */ - /* We only decode upper three bits */ - switch ((offset & 0xFFD3) & 0xE000) - { - case 0x0000: /* Base ROM Bank Register */ - - if ((m_latch_bank2 & 0x30) == 0x30) - m_base_bank = data; - //logerror("write to base bank %X - %X\n", data, (m_base_bank & m_mask) | (m_latch_bank2 & ~m_mask)); - break; - - case 0x2000: /* ROM Bank Register */ - - m_latch_bank2 = data ? data : 0x01; - //logerror("write to latch %X - %X\n", data, (m_base_bank & m_mask) | (m_latch_bank2 & ~m_mask)); - break; - - case 0x4000: /* ROM Bank Mask Register */ - - if ((m_latch_bank2 & 0x30) == 0x30) - m_mask = data; - //logerror("write to mask %X - %X\n", data, (m_base_bank & m_mask) | (m_latch_bank2 & ~m_mask)); - break; - - case 0x6000: - - /* nothing happens when writing to 0x6000-0x7fff, as verified by Tauwasser */ - break; - - default: - - //logerror("write to unknown/unmapped area %04X <= %02X\n", offset, data); - /* did not extensively test other unlikely ranges */ - break; - } -} - -// Sachen MMC2 - -READ8_MEMBER(gb_rom_sachen_mmc2_device::read_rom) -{ - UINT16 off_edit = offset; - - /* Wait for 0x30 transitions of A15 (lo -> hi), i.e. ROM accesses; A15 = HI while in bootstrap */ - /* This is 0x30 transitions, because we increment counter _after_ checking it, but A15 lo -> hi*/ - /* transition means first read (hi -> lo transition) must not count */ - - if (m_unlock_cnt == 0x30 && m_mode == MODE_LOCKED_DMG) { - m_mode = MODE_LOCKED_CGB; - m_unlock_cnt = 0x00; - } else if (m_unlock_cnt == 0x30 && m_mode == MODE_LOCKED_CGB) { - m_mode = MODE_UNLOCKED; - } - - if (m_unlock_cnt != 0x30) - m_unlock_cnt++; - - /* Logo Switch */ - if (m_mode == MODE_LOCKED_CGB) - off_edit |= 0x80; - - /* Header Un-Scramble */ - if ((off_edit & 0xFF00) == 0x0100) { - off_edit &= 0xFFAC; - off_edit |= ((offset >> 6) & 0x01) << 0; - off_edit |= ((offset >> 4) & 0x01) << 1; - off_edit |= ((offset >> 1) & 0x01) << 4; - off_edit |= ((offset >> 0) & 0x01) << 6; - } - //logerror("read from %04X (%04X) cnt: %02X\n", offset, off_edit, m_unlock_cnt); - - if (offset & 0x4000) /* RB1 */ - return m_rom[rom_bank_map[(m_base_bank & m_mask) | (m_latch_bank2 & ~m_mask)] * 0x4000 + (offset & 0x3fff)]; - else /* RB0 */ - return m_rom[rom_bank_map[(m_base_bank & m_mask) | (m_latch_bank & ~m_mask)] * 0x4000 + (off_edit & 0x3fff)]; -} - -READ8_MEMBER(gb_rom_sachen_mmc2_device::read_ram) -{ - if (m_mode == MODE_LOCKED_DMG) { - m_unlock_cnt = 0x00; - m_mode = MODE_LOCKED_CGB; - } - return 0xFF; - -} - -WRITE8_MEMBER(gb_rom_sachen_mmc2_device::write_ram) -{ - if (m_mode == MODE_LOCKED_DMG) { - m_unlock_cnt = 0x00; - m_mode = MODE_LOCKED_CGB; - } - -} - - -// 188 in 1 pirate (only preliminary) - -READ8_MEMBER(gb_rom_188in1_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[m_game_base + rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[m_game_base + rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_188in1_device::write_bank) -{ - if (offset == 0x7b00) - { - if (data < 0x80) - logerror("write to 0x%X data 0x%X\n", offset, data); - else - { - data -= 0x80; - m_game_base = 0x400000 + (data * 0x8000); - //logerror("offset 0x%X\n", m_game_base); - } - } - else if (offset == 0x7b01 || offset == 0x7b02) - { - // what do these writes do? - printf("write to 0x%X data 0x%X\n", offset, data); - } - else - gb_rom_mbc1_device::write_bank(space, offset, data); -} - - -// MBC5 variant used by Li Cheng / Niutoude games - -WRITE8_MEMBER(gb_rom_licheng_device::write_bank) -{ - if (offset > 0x2100 && offset < 0x3000) - return; - - gb_rom_mbc5_device::write_bank(space, offset, data); -} - -// MBC5 variant used by Chong Wu Xiao Jing Ling (this appears to be a re-release of a Li Cheng / Niutoude game, -// given that it contains the Niutoude logo, with most protection checks patched out) - -READ8_MEMBER(gb_rom_chongwu_device::read_rom) -{ - // protection check at the first read here... - if (offset == 0x41c3 && !m_protection_checked) - { - m_protection_checked = 1; - return 0x5d; - } - - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -// MBC5 variant used by Sintax games - -void gb_rom_sintax_device::set_xor_for_bank(UINT8 bank) -{ - switch (bank & 0x0f) - { - case 0x00: case 0x04: case 0x08: case 0x0c: - m_currentxor = m_xor2; - break; - case 0x01: case 0x05: case 0x09: case 0x0d: - m_currentxor = m_xor3; - break; - case 0x02: case 0x06: case 0x0a: case 0x0e: - m_currentxor = m_xor4; - break; - case 0x03: case 0x07: case 0x0b: case 0x0f: - m_currentxor = m_xor5; - break; - } -} - -READ8_MEMBER(gb_rom_sintax_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)] ^ m_currentxor; -} - -WRITE8_MEMBER(gb_rom_sintax_device::write_bank) -{ - if (offset < 0x2000) - m_ram_enable = ((data & 0x0f) == 0x0a) ? 1 : 0; - else if (offset < 0x3000) - { - set_xor_for_bank(data); - - switch (m_sintax_mode & 0x0f) - { - case 0x0d: - data = BITSWAP8(data, 1,0,7,6,5,4,3,2); - break; - case 0x09: - //data = BITSWAP8(data, 3,2,5,4,0,1,6,7); // Monkey..no - data = BITSWAP8(data, 4,5,2,3,0,1,6,7); - break; - case 0x00: // 0x10=lion 0x00 hmmmmm // 1 and 0 unconfirmed - data = BITSWAP8(data, 7,0,5,6,3,4,1,2); - break; - case 0x01: - data = BITSWAP8(data, 0,1,6,7,4,5,2,3); - break; - case 0x05: - data = BITSWAP8(data, 7,6,1,0,3,2,5,4); // Not 100% on this one - break; - case 0x07: - data = BITSWAP8(data, 2,0,3,1,5,4,7,6); // 5 and 7 unconfirmed - break; - case 0x0b: - data = BITSWAP8(data, 2,3,0,1,6,7,4,5); // 5 and 6 unconfirmed - break; - } - m_latch_bank2 = (m_latch_bank2 & 0x100) | data; - } - else if (offset < 0x4000) - { - m_latch_bank2 = (m_latch_bank2 & 0xff) | ((data & 0x01) << 8); - } - else if (offset < 0x5000) - { - data &= 0x0f; - if (has_rumble) - data &= 0x7; - m_ram_bank = data; - } - else if (offset < 0x6000) - { - if (!m_sintax_mode) - { - m_sintax_mode = data; - write_bank(space, 0x2000, 1); //force a fake bank switch - } -// printf("sintax mode %x\n", m_sintax_mode & 0xf); - } - else if (offset >= 0x7000) - { - switch ((offset & 0x00f0) >> 4) - { - case 2: - m_xor2 = data; - break; - case 3: - m_xor3 = data; - break; - case 4: - m_xor4 = data; - break; - case 5: - m_xor5 = data; - break; - } - - if (m_currentxor == 0) - set_xor_for_bank(4); - } - -} - -READ8_MEMBER(gb_rom_sintax_device::read_ram) -{ - if (!m_ram.empty() && m_ram_enable) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_sintax_device::write_ram) -{ - if (!m_ram.empty() && m_ram_enable) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data; -} - -/* - - Further MBC5 variants to emulate: - - Digimon 2 & Digimon 4 (Yong Yong) - - Digimon 2 writes at $2000 to select latch2 (data must be divided by 2, and 0 becomes 1), - then writes to $2400 a series of values that the patched version does not write... - Digimon 4 seems to share part of the $2000 behavior, but does not write to $2400... - - */ - -// MBC5 variant used by Digimon 2 (and maybe 4?) - -READ8_MEMBER(gb_rom_digimon_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_digimon_device::write_bank) -{ - if (offset < 0x2000) - m_ram_enable = ((data & 0x0f) == 0x0a) ? 1 : 0; - else if (offset == 0x2000) - { -// printf("written $02 %X at %X\n", data, offset); - if (!data) - data++; - m_latch_bank2 = data/2; - } - else if (offset < 0x3000) - { -// printf("written $03 %X at %X\n", data, offset); - } - else if (offset < 0x4000) - { -// printf("written $04 %X at %X\n", data, offset); - } - else if (offset < 0x6000) - { -// printf("written $05-$06 %X at %X\n", data, offset); - data &= 0x0f; - if (has_rumble) - data &= 0x7; - m_ram_bank = data; - } -// else -// printf("written $07 %X at %X\n", data, offset); -} - -READ8_MEMBER(gb_rom_digimon_device::read_ram) -{ - if (!m_ram.empty() && m_ram_enable) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_digimon_device::write_ram) -{ - if (!m_ram.empty() && m_ram_enable) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data; -} - - -// MBC1 variant used by Yong Yong for Rockman 8 - -READ8_MEMBER(gb_rom_rockman8_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[m_latch_bank * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[m_latch_bank2 * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_rockman8_device::write_bank) -{ - if (offset < 0x2000) - return; - else if (offset < 0x4000) - { - // 5bits only - data &= 0x1f; - if (data == 0) - data = 1; - if (data > 0xf) - data -= 8; - - m_latch_bank2 = data; - } -} - -READ8_MEMBER(gb_rom_rockman8_device::read_ram) -{ - if (!m_ram.empty()) - return m_ram[offset]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_rockman8_device::write_ram) -{ - if (!m_ram.empty()) - m_ram[offset] = data; -} - -// MBC1 variant used by Yong Yong for Super Mario 3 Special - -// Mario special seems to be 512k image (mirrored up to 1m or 2m [redump needed to establish this]) -// it consists of 13 unique 16k chunks layed out as follows -// unique chunk --> bank in bin -// 1st to 7th --> 0x00 to 0x06 -// 8th --> 0x08 -// 9th --> 0x0b -// 10th --> 0x0c -// 11th --> 0x0d -// 12th --> 0x0f -// 13th --> 0x13 - -// writing data to 0x2000-0x2fff switches bank according to the table below -// (the value values corresponding to table[0x0f] is not confirmed, choices -// 0,1,2,3,8,c,f freeze the game, while 4,5,6,7,b,d,0x13 work with glitches) -static UINT8 smb3_table1[0x20] = -{ - 0x00,0x04,0x01,0x05, 0x02,0x06,0x03,0x05, 0x08,0x0c,0x03,0x0d, 0x03,0x0b,0x0b,0x08 /* original doc here put 0x0f (i.e. 11th unique bank) */, - 0x05,0x06,0x0b,0x0d, 0x08,0x06,0x13,0x0b, 0x08,0x05,0x05,0x08, 0x0b,0x0d,0x06,0x05 -}; - -// according to old doc from Brian Provinciano, writing bit5 in 0x5000-0x5fff should -// change the bank layout, in the sense that writing to bankswitch acts like if -// the original rom has a different layout (as if unique chunks were under permutations -// (24), (365) and (8a9) with 0,1,7,b,c fixed) and the same table above is used -// however, no such a write ever happen (only bit4 is written, but changing mode with -// bit4 breaks the gfx...) - -READ8_MEMBER(gb_rom_sm3sp_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[0] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[m_latch_bank2 * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_sm3sp_device::write_bank) -{ -// printf("write 0x%x at %x\n", data, offset); - if (offset < 0x2000) - return; - else if (offset < 0x3000) - { - // Table 1 confirmed... - // 0->0, 4->2, 6->3 - // 1e -> 6 (level 1 bg gfx) - // 19 -> 5 (level 2 bg gfx) - // 1b -> 8 (level 3 bg gfx) - // 1d -> D (level 4 bg gfx) - // 1c -> B (bonus house bg gfx) - // 1 (9 maybe, or 3)? f (5 maybe)? 2->1? - // 16 -> 4-8? b? - - // 5bits only - data &= 0x1f; - - m_latch_bank2 = smb3_table1[data]; - if (m_mode) - { - switch (m_latch_bank2) - { - case 0x02: m_latch_bank2 = 4; break; - case 0x03: m_latch_bank2 = 6; break; - case 0x04: m_latch_bank2 = 2; break; - case 0x05: m_latch_bank2 = 3; break; - case 0x06: m_latch_bank2 = 5; break; - case 0x0b: m_latch_bank2 = 0xd; break; - case 0x0c: m_latch_bank2 = 0xb; break; - case 0x0d: m_latch_bank2 = 0xc; break; - - case 0x00: - case 0x01: - case 0x08: - case 0x0f: - case 0x13: - default: - break; - } - } - } - else if (offset < 0x5000) - { -// printf("write $5 %X at %X\n", data, offset); - //maybe rumble?? - } - else if (offset < 0x6000) - { -// printf("write mode %x\n", data); - m_mode = BIT(data, 5); -// write_bank(space, 0x2000, 1); - } -} - -READ8_MEMBER(gb_rom_sm3sp_device::read_ram) -{ - if (!m_ram.empty()) - return m_ram[offset]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_sm3sp_device::write_ram) -{ - if (!m_ram.empty()) - m_ram[offset] = data; -} diff --git a/src/emu/bus/gameboy/mbc.h b/src/emu/bus/gameboy/mbc.h deleted file mode 100644 index 3ad27d2cdee..00000000000 --- a/src/emu/bus/gameboy/mbc.h +++ /dev/null @@ -1,393 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Fabio Priuli, Wilbert Pol -#ifndef __GB_MBC_H -#define __GB_MBC_H - -#include "gb_slot.h" - - -// ======================> gb_rom_mbc_device - -class gb_rom_mbc_device : public device_t, - public device_gb_cart_interface -{ -public: - // construction/destruction - gb_rom_mbc_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-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - void shared_start(); - void shared_reset(); - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - - UINT8 m_ram_enable; -}; - -// ======================> gb_rom_mbc1_device - -class gb_rom_mbc1_device : public gb_rom_mbc_device -{ -public: - - enum { - MODE_16M_64k = 0, /// 16Mbit ROM, 64kBit RAM - MODE_4M_256k = 1 /// 4Mbit ROM, 256kBit RAM - }; - - // construction/destruction - gb_rom_mbc1_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); - gb_rom_mbc1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); save_item(NAME(m_mode)); }; - virtual void device_reset() { shared_reset(); m_mode = MODE_16M_64k; }; - virtual void set_additional_wirings(UINT8 mask, int shift) { m_mask = mask; m_shift = shift; } // these get set at cart loading - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - - UINT8 m_mode, m_mask; - int m_shift; -}; - -// ======================> gb_rom_mbc2_device - -class gb_rom_mbc2_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_mbc2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); -}; - -// ======================> gb_rom_mbc3_device - -class gb_rom_mbc3_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_mbc3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start(); - virtual void device_reset(); - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - UINT8 m_rtc_map[5]; -}; - -// ======================> gb_rom_mbc5_device - -class gb_rom_mbc5_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_mbc5_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); - gb_rom_mbc5_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); -}; - -// ======================> gb_rom_mbc6_device - -class gb_rom_mbc6_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_mbc6_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start(); - virtual void device_reset(); - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - UINT16 m_latch1, m_latch2; - UINT8 m_bank_4000, m_bank_6000; -}; - -// ======================> gb_rom_mbc7_device - -class gb_rom_mbc7_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_mbc7_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); -}; - -// ======================> gb_rom_m161_device - -class gb_rom_m161_device : public gb_rom_mbc_device -{ -public: - - // construction/destruction - gb_rom_m161_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start(); - virtual void device_reset(); - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram) { return 0xff; } - virtual DECLARE_WRITE8_MEMBER(write_ram) { } - - UINT8 m_base_bank; -}; - -// ======================> gb_rom_mmm01_device -class gb_rom_mmm01_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_mmm01_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_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - UINT8 m_bank_mask, m_bank, m_reg; -}; - -// ======================> gb_rom_sachen_mmc1_device - -class gb_rom_sachen_mmc1_device : public gb_rom_mbc_device -{ -public: - - enum { - MODE_LOCKED, - MODE_UNLOCKED - }; - - // construction/destruction - gb_rom_sachen_mmc1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - gb_rom_sachen_mmc1_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-level overrides - virtual void device_start(); - virtual void device_reset(); - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram) { return 0xff; } - virtual DECLARE_WRITE8_MEMBER(write_ram) { } - - UINT8 m_base_bank, m_mask, m_mode, m_unlock_cnt; -}; - -// ======================> gb_rom_sachen_mmc2_device - -class gb_rom_sachen_mmc2_device : public gb_rom_sachen_mmc1_device -{ -public: - - enum { - MODE_LOCKED_DMG, - MODE_LOCKED_CGB, - MODE_UNLOCKED - }; - - // construction/destruction - gb_rom_sachen_mmc2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start(); - virtual void device_reset(); - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - -}; - -// ======================> gb_rom_188in1_device -class gb_rom_188in1_device : public gb_rom_mbc1_device -{ -public: - // construction/destruction - gb_rom_188in1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); save_item(NAME(m_game_base)); }; - virtual void device_reset() { shared_reset(); m_game_base = 0; }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - -private: - UINT32 m_game_base; -}; - -// ======================> gb_rom_sintax_device -class gb_rom_sintax_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_sintax_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start(); - virtual void device_reset(); - void set_xor_for_bank(UINT8 bank); - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - UINT8 m_bank_mask, m_bank, m_reg; - - UINT8 m_currentxor, m_xor2, m_xor3, m_xor4, m_xor5, m_sintax_mode; -}; - -// ======================> gb_rom_chongwu_device - -class gb_rom_chongwu_device : public gb_rom_mbc5_device -{ -public: - // construction/destruction - gb_rom_chongwu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start(); - virtual void device_reset(); - - virtual DECLARE_READ8_MEMBER(read_rom); - UINT8 m_protection_checked; -}; - -// ======================> gb_rom_licheng_device - -class gb_rom_licheng_device : public gb_rom_mbc5_device -{ -public: - // construction/destruction - gb_rom_licheng_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - virtual DECLARE_WRITE8_MEMBER(write_bank); -}; - -// ======================> gb_rom_digimon_device - -class gb_rom_digimon_device : public gb_rom_mbc5_device -{ -public: - // construction/destruction - gb_rom_digimon_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); -}; - -// ======================> gb_rom_rockman8_device -class gb_rom_rockman8_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_rockman8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - UINT8 m_bank_mask, m_bank, m_reg; -}; - -// ======================> gb_rom_sm3sp_device -class gb_rom_sm3sp_device : public gb_rom_mbc_device -{ -public: - // construction/destruction - gb_rom_sm3sp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - UINT8 m_bank_mask, m_bank, m_reg, m_mode; -}; - - - -// device type definition -extern const device_type GB_ROM_MBC1; -extern const device_type GB_ROM_MBC1_COL; -extern const device_type GB_ROM_MBC2; -extern const device_type GB_ROM_MBC3; -extern const device_type GB_ROM_MBC4; -extern const device_type GB_ROM_MBC5; -extern const device_type GB_ROM_MBC6; -extern const device_type GB_ROM_MBC7; -extern const device_type GB_ROM_M161_M12; -extern const device_type GB_ROM_MMM01; -extern const device_type GB_ROM_SACHEN1; -extern const device_type GB_ROM_SACHEN2; -extern const device_type GB_ROM_188IN1; -extern const device_type GB_ROM_SINTAX; -extern const device_type GB_ROM_CHONGWU; -extern const device_type GB_ROM_LICHENG; -extern const device_type GB_ROM_DIGIMON; -extern const device_type GB_ROM_ROCKMAN8; -extern const device_type GB_ROM_SM3SP; - -#endif diff --git a/src/emu/bus/gameboy/rom.c b/src/emu/bus/gameboy/rom.c deleted file mode 100644 index 2be759adf1b..00000000000 --- a/src/emu/bus/gameboy/rom.c +++ /dev/null @@ -1,364 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Fabio Priuli, Wilbert Pol -/*********************************************************************************************************** - - Game Boy cart emulation - - - Here we emulate carts with no RAM and simple bankswitch - - - ***********************************************************************************************************/ - - -#include "emu.h" -#include "rom.h" - - -//------------------------------------------------- -// gb_rom_device - constructor -//------------------------------------------------- - -const device_type GB_STD_ROM = &device_creator; -const device_type GB_ROM_TAMA5 = &device_creator; -const device_type GB_ROM_WISDOM = &device_creator; -const device_type GB_ROM_YONG = &device_creator; -const device_type GB_ROM_ATVRAC = &device_creator; -const device_type GB_ROM_LASAMA = &device_creator; - -const device_type MEGADUCK_ROM = &device_creator; - - -gb_rom_device::gb_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_gb_cart_interface( mconfig, *this ) -{ -} - -gb_rom_device::gb_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, GB_STD_ROM, "GB Carts", tag, owner, clock, "gb_rom", __FILE__), - device_gb_cart_interface( mconfig, *this ) -{ -} - -gb_rom_tama5_device::gb_rom_tama5_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_device(mconfig, GB_ROM_TAMA5, "GB Tamagotchi", tag, owner, clock, "gb_rom_tama5", __FILE__) -{ -} - -gb_rom_wisdom_device::gb_rom_wisdom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_device(mconfig, GB_ROM_WISDOM, "GB Wisdom Tree Carts", tag, owner, clock, "gb_rom_wisdom", __FILE__) -{ -} - -gb_rom_yong_device::gb_rom_yong_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_device(mconfig, GB_ROM_YONG, "GB Yong Yong Carts", tag, owner, clock, "gb_rom_yong", __FILE__) -{ -} - -gb_rom_atvrac_device::gb_rom_atvrac_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_device(mconfig, GB_ROM_ATVRAC, "GB ATV Racin'", tag, owner, clock, "gb_rom_atvrac", __FILE__) -{ -} - -gb_rom_lasama_device::gb_rom_lasama_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gb_rom_device(mconfig, GB_ROM_LASAMA, "GB LaSaMa", tag, owner, clock, "gb_rom_lasama", __FILE__) -{ -} - - -megaduck_rom_device::megaduck_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_gb_cart_interface( mconfig, *this ) -{ -} - -megaduck_rom_device::megaduck_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MEGADUCK_ROM, "MegaDuck Carts", tag, owner, clock, "megaduck_rom", __FILE__), - device_gb_cart_interface( mconfig, *this ) -{ -} - - -//------------------------------------------------- -// shared_start -//------------------------------------------------- - -void gb_rom_device::shared_start() -{ - save_item(NAME(m_latch_bank)); - save_item(NAME(m_latch_bank2)); - save_item(NAME(m_ram_bank)); -} - -//------------------------------------------------- -// shared_reset -//------------------------------------------------- - -void gb_rom_device::shared_reset() -{ - m_ram_bank = 0; - m_latch_bank = 0; - m_latch_bank2 = 1; -} - -//------------------------------------------------- -// mapper specific start/reset -//------------------------------------------------- - -void gb_rom_tama5_device::device_start() -{ - shared_start(); - save_item(NAME(m_tama5_data)); - save_item(NAME(m_tama5_addr)); - save_item(NAME(m_tama5_cmd)); - save_item(NAME(m_regs)); - save_item(NAME(m_rtc_reg)); -} - -void gb_rom_tama5_device::device_reset() -{ - shared_reset(); - m_tama5_data = 0; - m_tama5_addr= 0; - m_tama5_cmd = 0; - memset(m_regs, 0xff, sizeof(m_regs)); - m_rtc_reg = 0xff; -} - - -// these are identical to shared ones above, but megaduck cart class is not derived from gb cart class... -void megaduck_rom_device::device_start() -{ - save_item(NAME(m_latch_bank)); - save_item(NAME(m_latch_bank2)); - save_item(NAME(m_ram_bank)); -} - -void megaduck_rom_device::device_reset() -{ - m_ram_bank = 0; - m_latch_bank = 0; - m_latch_bank2 = 1; -} - - -/*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ - -READ8_MEMBER(gb_rom_device::read_rom) -{ - m_latch_bank = offset / 0x4000; - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; -} - -READ8_MEMBER(gb_rom_device::read_ram) -{ - if (!m_ram.empty()) - return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + offset]; - else - return 0xff; -} - -WRITE8_MEMBER(gb_rom_device::write_ram) -{ - if (!m_ram.empty()) - m_ram[ram_bank_map[m_ram_bank] * 0x2000 + offset] = data; -} - - -// Tamagotchi - -READ8_MEMBER(gb_rom_tama5_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -READ8_MEMBER(gb_rom_tama5_device::read_ram) -{ - return m_rtc_reg; -} - -WRITE8_MEMBER(gb_rom_tama5_device::write_ram) -{ - switch (offset & 0x0001) - { - case 0x0000: /* Write to data register */ - switch (m_tama5_cmd) - { - case 0x00: /* Bits 0-3 for rom bank selection */ - m_latch_bank2 = (m_latch_bank2 & 0xf0) | (data & 0x0f); - break; - case 0x01: /* Bit 4(-7?) for rom bank selection */ - m_latch_bank2 = (m_latch_bank2 & 0x0f) | ((data & 0x0f) << 4); - break; - case 0x04: /* Data to write lo */ - m_tama5_data = (m_tama5_data & 0xf0) | (data & 0x0f); - break; - case 0x05: /* Data to write hi */ - m_tama5_data = (m_tama5_data & 0x0f) | ((data & 0x0f) << 4); - break; - case 0x06: /* Address selection hi */ - m_tama5_addr = (m_tama5_addr & 0x0f) | ((data & 0x0f) << 4); - break; - case 0x07: /* Address selection lo */ - /* This address always seems to written last, so we'll just - execute the command here */ - m_tama5_addr = (m_tama5_addr & 0xf0) | (data & 0x0f); - switch (m_tama5_addr & 0xe0) - { - case 0x00: /* Write memory */ - //logerror( "Write tama5 memory 0x%02X <- 0x%02X\n", m_tama5_addr & 0x1f, m_tama5_data); - m_regs[m_tama5_addr & 0x1f] = m_tama5_data; - break; - case 0x20: /* Read memory */ - //logerror( "Read tama5 memory 0x%02X\n", m_tama5_addr & 0x1f); - m_tama5_data = m_regs[m_tama5_addr & 0x1f]; - break; - case 0x40: /* Unknown, some kind of read */ - if ((m_tama5_addr & 0x1f) == 0x12) - m_tama5_data = 0xff; - case 0x80: /* Unknown, some kind of read (when 07=01)/write (when 07=00/02) */ - default: - logerror( "0x%04X: Unknown addressing mode\n", space.device() .safe_pc( ) ); - break; - } - break; - } - break; - case 0x0001: /* Write to control register */ - switch (data) - { - case 0x00: /* Bits 0-3 for rom bank selection */ - case 0x01: /* Bits 4-7 for rom bank selection */ - case 0x04: /* Data write register lo */ - case 0x05: /* Data write register hi */ - case 0x06: /* Address register hi */ - case 0x07: /* Address register lo */ - break; - case 0x0a: /* Are we ready for the next command? */ - m_rtc_reg = 0x01; - break; - case 0x0c: /* Data read register lo */ - m_rtc_reg = m_tama5_data & 0x0f; - break; - case 0x0d: /* Data read register hi */ - m_rtc_reg = (m_tama5_data & 0xf0) >> 4; - break; - default: - logerror( "0x%04X: Unknown tama5 command 0x%02X\n", space.device() .safe_pc( ), data ); - break; - } - m_tama5_cmd = data; - break; - } -} - - -// Wisdom Tree - -READ8_MEMBER(gb_rom_wisdom_device::read_rom) -{ - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + offset]; -} - -WRITE8_MEMBER(gb_rom_wisdom_device::write_bank) -{ - if (offset < 0x4000) - m_latch_bank = (offset << 1) & 0x1ff; -} - - -// Yong Yong pirate - -READ8_MEMBER(gb_rom_yong_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_yong_device::write_bank) -{ - if (offset == 0x2000) - m_latch_bank2 = data; -} - - -// ATV Racin pirate (incomplete) - -READ8_MEMBER(gb_rom_atvrac_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_atvrac_device::write_bank) -{ - if (offset == 0x3f00) - { - if (data == 0) - data = 1; - m_latch_bank2 = m_latch_bank | data; - } - if (offset == 0x3fc0) - m_latch_bank = data * 16; -} - -// La Sa Ma pirate (incomplete) - -READ8_MEMBER(gb_rom_lasama_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(gb_rom_lasama_device::write_bank) -{ - if (offset == 0x2080) - { - // Actual banking? - m_latch_bank2 = m_latch_bank | (data & 0x03); - } - if (offset == 0x6000) - { - // On boot the following two get written right after each other: - // 02 - // BE - // Disable logo switching? - if (!(data & 0x80)) - m_latch_bank = (data & 0x02) << 1; - } -} - - -// MegaDuck carts - -READ8_MEMBER(megaduck_rom_device::read_rom) -{ - if (offset < 0x4000) - return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)]; - else - return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)]; -} - -WRITE8_MEMBER(megaduck_rom_device::write_bank) -{ - if (offset == 0x0001) - m_latch_bank2 = data; -} - -WRITE8_MEMBER(megaduck_rom_device::write_ram) -{ - m_latch_bank = data * 2; - m_latch_bank2 = data * 2 + 1; -} diff --git a/src/emu/bus/gameboy/rom.h b/src/emu/bus/gameboy/rom.h deleted file mode 100644 index 3bd27a362c8..00000000000 --- a/src/emu/bus/gameboy/rom.h +++ /dev/null @@ -1,146 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Fabio Priuli, Wilbert Pol -#ifndef __GB_ROM_H -#define __GB_ROM_H - -#include "gb_slot.h" - - -// ======================> gb_rom_device - -class gb_rom_device : public device_t, - public device_gb_cart_interface -{ -public: - // construction/destruction - gb_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); - gb_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - void shared_start(); - void shared_reset(); - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); -}; - -// ======================> gb_rom_tama5_device -class gb_rom_tama5_device : public gb_rom_device -{ -public: - // construction/destruction - gb_rom_tama5_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_rom); - virtual DECLARE_READ8_MEMBER(read_ram); - virtual DECLARE_WRITE8_MEMBER(write_ram); - UINT16 m_tama5_data, m_tama5_addr, m_tama5_cmd; - UINT8 m_regs[32]; - UINT8 m_rtc_reg; -}; - -// ======================> gb_rom_wisdom_device -class gb_rom_wisdom_device : public gb_rom_device -{ -public: - // construction/destruction - gb_rom_wisdom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); -}; - -// ======================> gb_rom_yong_device -class gb_rom_yong_device : public gb_rom_device -{ -public: - // construction/destruction - gb_rom_yong_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); -}; - -// ======================> gb_rom_atvrac_device -class gb_rom_atvrac_device : public gb_rom_device -{ -public: - // construction/destruction - gb_rom_atvrac_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); -}; - -// ======================> gb_rom_lasama_device -class gb_rom_lasama_device : public gb_rom_device -{ -public: - // construction/destruction - gb_rom_lasama_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual void device_start() { shared_start(); }; - virtual void device_reset() { shared_reset(); }; - - // reading and writing - virtual DECLARE_READ8_MEMBER(read_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); -}; - - -// ======================> megaduck_rom_device -class megaduck_rom_device :public device_t, - public device_gb_cart_interface -{ -public: - // construction/destruction - megaduck_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); - megaduck_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_rom); - virtual DECLARE_WRITE8_MEMBER(write_bank); - virtual DECLARE_WRITE8_MEMBER(write_ram); -}; - -// device type definition -extern const device_type GB_STD_ROM; -extern const device_type GB_ROM_TAMA5; -extern const device_type GB_ROM_WISDOM; -extern const device_type GB_ROM_YONG; -extern const device_type GB_ROM_ATVRAC; -extern const device_type GB_ROM_LASAMA; - -extern const device_type MEGADUCK_ROM; - -#endif -- cgit v1.2.3-70-g09d2