1 // license:BSD-3-Clause
2 // copyright-holders:Barry Rodewald
3 /*
4  * cpc_rom.cpp
5  * Amstrad CPC mountable ROM image device
6  *
7  */
8 
9 #include "emu.h"
10 #include "cpc_rom.h"
11 
12 DEFINE_DEVICE_TYPE(CPC_ROM, cpc_rom_device, "cpc_rom", "CPC ROM Box")
13 
14 void cpc_exp_cards(device_slot_interface &device);
15 
16 //**************************************************************************
17 //  DEVICE CONFIG INTERFACE
18 //**************************************************************************
19 
20 // device machine config
device_add_mconfig(machine_config & config)21 void cpc_rom_device::device_add_mconfig(machine_config &config)
22 {
23 	CPC_ROMSLOT(config, m_rom[0], 0);
24 	CPC_ROMSLOT(config, m_rom[1], 0);
25 	CPC_ROMSLOT(config, m_rom[2], 0);
26 	CPC_ROMSLOT(config, m_rom[3], 0);
27 	CPC_ROMSLOT(config, m_rom[4], 0);
28 	CPC_ROMSLOT(config, m_rom[5], 0);
29 	CPC_ROMSLOT(config, m_rom[6], 0);
30 	CPC_ROMSLOT(config, m_rom[7], 0);
31 
32 	// pass-through
33 	cpc_expansion_slot_device &exp(CPC_EXPANSION_SLOT(config, "exp", DERIVED_CLOCK(1, 1), cpc_exp_cards, nullptr));
34 	exp.irq_callback().set(DEVICE_SELF_OWNER, FUNC(cpc_expansion_slot_device::irq_w));
35 	exp.nmi_callback().set(DEVICE_SELF_OWNER, FUNC(cpc_expansion_slot_device::nmi_w));
36 	exp.romdis_callback().set(DEVICE_SELF_OWNER, FUNC(cpc_expansion_slot_device::romdis_w));  // ROMDIS
37 }
38 
39 
40 //**************************************************************************
41 //  LIVE DEVICE
42 //**************************************************************************
43 
cpc_rom_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)44 cpc_rom_device::cpc_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
45 	device_t(mconfig, CPC_ROM, tag, owner, clock),
46 	device_cpc_expansion_card_interface(mconfig, *this),
47 	m_rom(*this, "rom%u", 1)
48 {
49 }
50 
51 //-------------------------------------------------
52 //  device_start - device-specific startup
53 //-------------------------------------------------
54 
device_start()55 void cpc_rom_device::device_start()
56 {
57 }
58 
59 //-------------------------------------------------
60 //  device_reset - device-specific reset
61 //-------------------------------------------------
62 
device_reset()63 void cpc_rom_device::device_reset()
64 {
65 }
66 
67 
68 /*** ROM image device ***/
69 
70 // device type definition
71 DEFINE_DEVICE_TYPE(CPC_ROMSLOT, cpc_rom_image_device, "cpc_rom_image", "CPC ROM image")
72 
73 //-------------------------------------------------
74 //  cpc_rom_image_device - constructor
75 //-------------------------------------------------
76 
cpc_rom_image_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)77 cpc_rom_image_device::cpc_rom_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
78 	: device_t(mconfig, CPC_ROMSLOT, tag, owner, clock)
79 	, device_image_interface(mconfig, *this)
80 	, m_base(nullptr)
81 {
82 }
83 
84 //-------------------------------------------------
85 //  cpc_rom_image_device - destructor
86 //-------------------------------------------------
87 
~cpc_rom_image_device()88 cpc_rom_image_device::~cpc_rom_image_device()
89 {
90 }
91 
92 //-------------------------------------------------
93 //  device_start - device-specific startup
94 //-------------------------------------------------
95 
device_start()96 void cpc_rom_image_device::device_start()
97 {
98 	m_base = nullptr;
99 }
100 
101 /*-------------------------------------------------
102     DEVICE_IMAGE_LOAD( rom )
103 -------------------------------------------------*/
call_load()104 image_init_result cpc_rom_image_device::call_load()
105 {
106 	device_image_interface* image = this;
107 	uint64_t size = image->length();
108 
109 	m_base = std::make_unique<uint8_t[]>(16384);
110 	if(size <= 16384)
111 	{
112 		image->fread(m_base.get(),size);
113 	}
114 	else
115 	{
116 		image->fseek(size-16384,SEEK_SET);
117 		image->fread(m_base.get(),16384);
118 	}
119 
120 	return image_init_result::PASS;
121 }
122 
123 
124 /*-------------------------------------------------
125     DEVICE_IMAGE_UNLOAD( rom )
126 -------------------------------------------------*/
call_unload()127 void cpc_rom_image_device::call_unload()
128 {
129 	m_base = nullptr;
130 }
131