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