1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Magic Formel cartridge emulation
6 
7 **********************************************************************/
8 
9 /*
10 
11     TODO:
12 
13     - pia6821 port A DDR needs to reset to 0xff or this won't boot
14 
15 */
16 
17 #include "emu.h"
18 #include "magic_formel.h"
19 
20 
21 
22 //**************************************************************************
23 //  MACROS/CONSTANTS
24 //**************************************************************************
25 
26 #define MC6821_TAG      "mc6821"
27 
28 
29 
30 //**************************************************************************
31 //  DEVICE DEFINITIONS
32 //**************************************************************************
33 
34 DEFINE_DEVICE_TYPE(C64_MAGIC_FORMEL, c64_magic_formel_cartridge_device, "c64_magic_formel", "C64 Magic Formel cartridge")
35 
36 
pia_pa_w(uint8_t data)37 void c64_magic_formel_cartridge_device::pia_pa_w(uint8_t data)
38 {
39 	/*
40 
41 	    bit     description
42 
43 	    PA0     ROM A13
44 	    PA1     ROM A14
45 	    PA2     ROM A15
46 	    PA3     ROM _OE
47 	    PA4     RAM _OE
48 	    PA5
49 	    PA6
50 	    PA7
51 
52 	*/
53 
54 	m_rom_bank = data & 0x0f;
55 
56 	m_ram_oe = BIT(data, 4);
57 }
58 
pia_pb_w(uint8_t data)59 void c64_magic_formel_cartridge_device::pia_pb_w(uint8_t data)
60 {
61 	/*
62 
63 	    bit     description
64 
65 	    PB0     RAM A10
66 	    PB1     RAM A11
67 	    PB2     RAM A9
68 	    PB3     RAM A8
69 	    PB4     RAM A12
70 	    PB5     U9A clr
71 	    PB6
72 	    PB7     ROMH enable
73 
74 	*/
75 
76 	m_ram_bank = data & 0x1f;
77 
78 	if (!BIT(data, 5))
79 	{
80 		m_u9a = 0;
81 	}
82 
83 	m_pb7 = BIT(data, 7);
84 }
85 
WRITE_LINE_MEMBER(c64_magic_formel_cartridge_device::pia_cb2_w)86 WRITE_LINE_MEMBER( c64_magic_formel_cartridge_device::pia_cb2_w )
87 {
88 	if (!state)
89 	{
90 		m_u9b = 1;
91 	}
92 }
93 
94 
95 //-------------------------------------------------
96 //  device_add_mconfig - add device configuration
97 //-------------------------------------------------
98 
device_add_mconfig(machine_config & config)99 void c64_magic_formel_cartridge_device::device_add_mconfig(machine_config &config)
100 {
101 	PIA6821(config, m_pia, 0);
102 	m_pia->writepa_handler().set(FUNC(c64_magic_formel_cartridge_device::pia_pa_w));
103 	m_pia->writepb_handler().set(FUNC(c64_magic_formel_cartridge_device::pia_pb_w));
104 	m_pia->cb2_handler().set(FUNC(c64_magic_formel_cartridge_device::pia_cb2_w));
105 }
106 
107 
108 //-------------------------------------------------
109 //  INPUT_CHANGED_MEMBER( freeze )
110 //-------------------------------------------------
111 
INPUT_CHANGED_MEMBER(c64_magic_formel_cartridge_device::freeze)112 INPUT_CHANGED_MEMBER( c64_magic_formel_cartridge_device::freeze )
113 {
114 	if (newval && (!m_u9a && !m_u9b))
115 	{
116 		m_u9b = 1;
117 
118 		m_slot->nmi_w(ASSERT_LINE);
119 	}
120 	else
121 	{
122 		m_slot->nmi_w(CLEAR_LINE);
123 	}
124 }
125 
126 
127 //-------------------------------------------------
128 //  INPUT_PORTS( c64_magic_formel )
129 //-------------------------------------------------
130 
131 static INPUT_PORTS_START( c64_magic_formel )
132 	PORT_START("FREEZE")
PORT_CODE(KEYCODE_F12)133 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Freeze") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, c64_magic_formel_cartridge_device, freeze, 0)
134 INPUT_PORTS_END
135 
136 
137 //-------------------------------------------------
138 //  input_ports - device-specific input ports
139 //-------------------------------------------------
140 
141 ioport_constructor c64_magic_formel_cartridge_device::device_input_ports() const
142 {
143 	return INPUT_PORTS_NAME( c64_magic_formel );
144 }
145 
146 
147 
148 //**************************************************************************
149 //  LIVE DEVICE
150 //**************************************************************************
151 
152 //-------------------------------------------------
153 //  c64_magic_formel_cartridge_device - constructor
154 //-------------------------------------------------
155 
c64_magic_formel_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)156 c64_magic_formel_cartridge_device::c64_magic_formel_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
157 	device_t(mconfig, C64_MAGIC_FORMEL, tag, owner, clock),
158 	device_c64_expansion_card_interface(mconfig, *this),
159 	m_pia(*this, MC6821_TAG),
160 	m_ram(*this, "ram"),
161 	m_rom_bank(0),
162 	m_ram_bank(0),
163 	m_ram_oe(0),
164 	m_pb7(1),
165 	m_u9a(1),
166 	m_u9b(1)
167 {
168 }
169 
170 
171 //-------------------------------------------------
172 //  device_start - device-specific startup
173 //-------------------------------------------------
174 
device_start()175 void c64_magic_formel_cartridge_device::device_start()
176 {
177 	// allocate memory
178 	m_ram.allocate(0x2000);
179 
180 	// state saving
181 	save_item(NAME(m_rom_bank));
182 	save_item(NAME(m_ram_bank));
183 	save_item(NAME(m_ram_oe));
184 	save_item(NAME(m_pb7));
185 	save_item(NAME(m_u9a));
186 	save_item(NAME(m_u9b));
187 }
188 
189 
190 //-------------------------------------------------
191 //  device_reset - device-specific reset
192 //-------------------------------------------------
193 
device_reset()194 void c64_magic_formel_cartridge_device::device_reset()
195 {
196 	m_rom_bank = 0;
197 	m_ram_bank = 0;
198 	m_ram_oe = 0;
199 	m_pb7 = 0;
200 	m_u9a = 1;
201 	m_u9b = 1;
202 }
203 
204 
205 //-------------------------------------------------
206 //  c64_cd_r - cartridge data read
207 //-------------------------------------------------
208 
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)209 uint8_t c64_magic_formel_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
210 {
211 	if (!romh)
212 	{
213 		offs_t addr = (m_rom_bank << 13) | (offset & 0x1fff);
214 		data = m_romh[addr];
215 	}
216 	else if (!io1 && !m_ram_oe)
217 	{
218 		offs_t addr = (m_ram_bank << 8) | (offset & 0xff);
219 		data = m_ram[addr];
220 	}
221 
222 	return data;
223 }
224 
225 
226 //-------------------------------------------------
227 //  c64_cd_w - cartridge data write
228 //-------------------------------------------------
229 
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)230 void c64_magic_formel_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
231 {
232 	if (!io1 && !m_ram_oe)
233 	{
234 		offs_t addr = (m_ram_bank << 8) | (offset & 0xff);
235 		m_ram[addr] = data;
236 	}
237 	else if (!io2 && !(!m_u9b && m_ram_oe))
238 	{
239 		offs_t addr = (offset >> 6) & 0x03;
240 		uint8_t new_data = (BIT(data, 1) << 7) | (offset & 0x3f);
241 
242 		m_pia->write(addr, new_data);
243 	}
244 	else if (offset == 0x0001)
245 	{
246 		m_u9a = 1;
247 	}
248 }
249 
250 
251 //-------------------------------------------------
252 //  c64_game_r - GAME read
253 //-------------------------------------------------
254 
c64_game_r(offs_t offset,int sphi2,int ba,int rw)255 int c64_magic_formel_cartridge_device::c64_game_r(offs_t offset, int sphi2, int ba, int rw)
256 {
257 	return !(ba && rw && ((offset & 0xe000) == 0xe000) && !(!m_pb7 && !m_u9b));
258 }
259