summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/vboy/slot.cpp
blob: b80480fe953a78ee40ab9deb7d102a4e3e4b4140 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
/***************************************************************************
 Virtual Boy cartridge slot

 TODO:
 - Sound capabilities
 ***************************************************************************/

#include "emu.h"
#include "slot.h"

#include "emuopts.h"
#include "romload.h"
#include "softlist.h"

#include <cstring>

//#define VERBOSE 1
#include "logmacro.h"


//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

DEFINE_DEVICE_TYPE(VBOY_CART_SLOT, vboy_cart_slot_device, "vboy_cart_slot", "Nintendo Virtual Boy Cartridge Slot")


//**************************************************************************
//  vboy_cart_slot_device
//**************************************************************************

vboy_cart_slot_device::vboy_cart_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, VBOY_CART_SLOT, tag, owner, clock),
	device_image_interface(mconfig, *this),
	device_single_card_slot_interface<device_vboy_cart_interface>(mconfig, *this),
	m_intcro(*this),
	m_exp_space(*this, finder_base::DUMMY_TAG, -1, 32),
	m_chip_space(*this, finder_base::DUMMY_TAG, -1, 32),
	m_rom_space(*this, finder_base::DUMMY_TAG, -1, 32),
	m_exp_base(0U),
	m_chip_base(0U),
	m_rom_base(0U),
	m_cart(nullptr)
{
}


image_init_result vboy_cart_slot_device::call_load()
{
	if (!m_cart)
		return image_init_result::PASS;

	memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr);
	if (loaded_through_softlist() && !romregion)
	{
		seterror(image_error::INVALIDIMAGE, "Software list item has no 'rom' data area");
		return image_init_result::FAIL;
	}

	u32 const len(loaded_through_softlist() ? romregion->bytes() : length());
	if ((0x0000'0003 & len) || (0x0100'0000 < len))
	{
		seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size (must be a multiple of 4 bytes no larger than 16 MiB)");
		return image_init_result::FAIL;
	}

	if (!loaded_through_softlist())
	{
		LOG("Allocating %u byte cartridge ROM region\n", len);
		romregion = machine().memory().region_alloc(subtag("rom").c_str(), len, 4, ENDIANNESS_LITTLE);
		u32 const cnt(fread(romregion->base(), len));
		if (cnt != len)
		{
			seterror(image_error::UNSPECIFIED, "Error reading cartridge file");
			return image_init_result::FAIL;
		}
	}

	return m_cart->load();
}


void vboy_cart_slot_device::call_unload()
{
	if (m_cart)
		m_cart->unload();
}


void vboy_cart_slot_device::device_validity_check(validity_checker &valid) const
{
	if (m_exp_base & 0x00ff'ffff)
		osd_printf_error("EXP base address 0x%X is not on a 24-bit boundary\n", m_exp_base);

	if (m_chip_base & 0x00ff'ffff)
		osd_printf_error("CHIP base address 0x%X is not on a 24-bit boundary\n", m_chip_base);

	if (m_rom_base & 0x00ff'ffff)
		osd_printf_error("ROM base address 0x%X is not on a 24-bit boundary\n", m_rom_base);
}


void vboy_cart_slot_device::device_resolve_objects()
{
	m_intcro.resolve_safe();
}


void vboy_cart_slot_device::device_start()
{
	if (!m_exp_space && ((m_exp_space.finder_tag() != finder_base::DUMMY_TAG) || (m_exp_space.spacenum() >= 0)))
		throw emu_fatalerror("%s: Address space %d of device %s not found (EXP)\n", tag(), m_exp_space.spacenum(), m_exp_space.finder_tag());

	if (!m_chip_space && ((m_chip_space.finder_tag() != finder_base::DUMMY_TAG) || (m_chip_space.spacenum() >= 0)))
		throw emu_fatalerror("%s: Address space %d of device %s not found (CHIP)\n", tag(), m_chip_space.spacenum(), m_chip_space.finder_tag());

	if (!m_rom_space && ((m_rom_space.finder_tag() != finder_base::DUMMY_TAG) || (m_rom_space.spacenum() >= 0)))
		throw emu_fatalerror("%s: Address space %d of device %s not found (ROM)\n", tag(), m_rom_space.spacenum(), m_rom_space.finder_tag());

	m_cart = get_card_device();
}


std::string vboy_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
	std::string const image_name(mconfig().options().image_option(instance_name()).value());
	software_part const *const part(!image_name.empty() ? find_software_item(image_name, true) : nullptr);
	if (part)
	{
		//printf("[%s] Found software part for image name '%s'\n", tag(), image_name.c_str());
		for (rom_entry const &entry : part->romdata())
		{
			if (ROMENTRY_ISREGION(entry) && (entry.name() == "sram"))
			{
				//printf("[%s] Found 'sram' data area, enabling cartridge backup RAM\n", tag());
				return "flatrom_sram";
			}
		}
	}
	else
	{
		//printf("[%s] No software part found for image name '%s'\n", tag(), image_name.c_str());
	}

	//printf("[%s] Assuming plain ROM cartridge\n", tag());
	return "flatrom";
}



//**************************************************************************
//  device_vboy_cart_interface
//**************************************************************************

void device_vboy_cart_interface::unload()
{
}


device_vboy_cart_interface::device_vboy_cart_interface(machine_config const &mconfig, device_t &device) :
	device_interface(device, "vboycart"),
	m_slot(dynamic_cast<vboy_cart_slot_device *>(device.owner()))
{
}



#include "rom.h"

void vboy_carts(device_slot_interface &device)
{
	device.option_add_internal("flatrom", VBOY_FLAT_ROM);
	device.option_add_internal("flatrom_sram", VBOY_FLAT_ROM_SRAM);
}