1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Timeworks PARTNER 128 cartridge emulation
6 
7 **********************************************************************/
8 
9 /*
10 
11     PCB Layout
12     ----------
13 
14     |---------------|
15     |LS74  SW     * |
16     |LS09      LS273|
17     |LS139   RAM    |
18     |LS133          |
19     |     LS240     |
20     |LS33    ROM    |
21     |LS09           |
22      |||||||||||||||
23 
24     ROM     - Toshiba TMM24128AP 16Kx8 EPROM (blank label)
25     RAM     - Sony CXK5864PN-15L 8Kx8 SRAM
26     SW      - push button switch
27     *       - solder point for joystick port dongle
28 
29 */
30 
31 #include "emu.h"
32 #include "c128_partner.h"
33 
34 
35 
36 //**************************************************************************
37 //  DEVICE DEFINITIONS
38 //**************************************************************************
39 
40 DEFINE_DEVICE_TYPE(C128_PARTNER, c128_partner_cartridge_device, "c128_partner", "PARTNER 128 cartridge")
41 
42 
43 //-------------------------------------------------
44 //  INPUT_PORTS( c128_partner )
45 //-------------------------------------------------
46 
WRITE_LINE_MEMBER(c128_partner_cartridge_device::nmi_w)47 WRITE_LINE_MEMBER( c128_partner_cartridge_device::nmi_w )
48 {
49 	if (state)
50 	{
51 		m_ls74_q1 = 1;
52 	}
53 }
54 
55 static INPUT_PORTS_START( c128_partner )
56 	PORT_START("NMI")
PORT_CODE(KEYCODE_END)57 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Menu") PORT_CODE(KEYCODE_END) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, c128_partner_cartridge_device, nmi_w)
58 INPUT_PORTS_END
59 
60 
61 //-------------------------------------------------
62 //  input_ports - device-specific input ports
63 //-------------------------------------------------
64 
65 ioport_constructor c128_partner_cartridge_device::device_input_ports() const
66 {
67 	return INPUT_PORTS_NAME( c128_partner );
68 }
69 
70 
71 
72 //**************************************************************************
73 //  LIVE DEVICE
74 //**************************************************************************
75 
76 //-------------------------------------------------
77 //  c128_partner_cartridge_device - constructor
78 //-------------------------------------------------
79 
c128_partner_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)80 c128_partner_cartridge_device::c128_partner_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
81 	device_t(mconfig, C128_PARTNER, tag, owner, clock),
82 	device_c64_expansion_card_interface(mconfig, *this),
83 	m_ram(*this, "ram"), t_joyb2(nullptr),
84 	m_ram_a12_a7(0),
85 	m_ls74_cd(0),
86 	m_ls74_q1(0),
87 	m_ls74_q2(0),
88 	m_joyb2(0)
89 {
90 }
91 
92 
93 //-------------------------------------------------
94 //  device_start - device-specific startup
95 //-------------------------------------------------
96 
device_start()97 void c128_partner_cartridge_device::device_start()
98 {
99 	// allocate memory
100 	m_ram.allocate(0x2000);
101 
102 	// simulate the 16.7ms pulse from CIA1 PB2 that would arrive thru the joystick port dongle
103 	t_joyb2 = timer_alloc();
104 	t_joyb2->adjust(attotime::from_msec(16), 0, attotime::from_msec(16));
105 
106 	// state saving
107 	save_item(NAME(m_ram_a12_a7));
108 	save_item(NAME(m_ls74_cd));
109 	save_item(NAME(m_ls74_q1));
110 	save_item(NAME(m_ls74_q2));
111 	save_item(NAME(m_joyb2));
112 }
113 
114 
115 //-------------------------------------------------
116 //  device_reset - device-specific reset
117 //-------------------------------------------------
118 
device_reset()119 void c128_partner_cartridge_device::device_reset()
120 {
121 	m_ram_a12_a7 = 0;
122 
123 	m_ls74_cd = 0;
124 	m_ls74_q1 = 0;
125 	m_ls74_q2 = 0;
126 
127 	nmi_w(CLEAR_LINE);
128 }
129 
130 
131 //-------------------------------------------------
132 //  device_timer -
133 //-------------------------------------------------
134 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)135 void c128_partner_cartridge_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
136 {
137 	if (m_ls74_cd)
138 	{
139 		m_ls74_q2 = m_ls74_q1;
140 
141 		nmi_w(m_ls74_q2 ? ASSERT_LINE : CLEAR_LINE);
142 	}
143 }
144 
145 
146 //-------------------------------------------------
147 //  c64_cd_r - cartridge data read
148 //-------------------------------------------------
149 
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)150 uint8_t c128_partner_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
151 {
152 	if (!roml)
153 	{
154 		data = m_roml[offset & 0x3fff];
155 	}
156 
157 	if (!io1)
158 	{
159 		if (BIT(offset, 7))
160 		{
161 			data = m_roml[offset & 0x3fff];
162 
163 			if (m_ls74_cd)
164 			{
165 				m_ls74_q1 = 0;
166 			}
167 		}
168 		else
169 		{
170 			data = m_ram[(m_ram_a12_a7 << 7) | (offset & 0x7f)];
171 		}
172 	}
173 
174 	if (m_ls74_q2 && ((offset & 0xfffa) == 0xfffa))
175 	{
176 		// override the 8502 NMI/IRQ vectors with 0xdede
177 		data = 0xde;
178 	}
179 
180 	return data;
181 }
182 
183 
184 //-------------------------------------------------
185 //  c64_cd_w - cartridge data write
186 //-------------------------------------------------
187 
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)188 void c128_partner_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
189 {
190 	if (!io1)
191 	{
192 		if (BIT(offset, 7))
193 		{
194 			/*
195 
196 			    bit     description
197 
198 			    0       RAM A7
199 			    1       RAM A8
200 			    2       RAM A9
201 			    3       RAM A10
202 			    4       RAM A11
203 			    5       RAM A12
204 			    6       LS74 1Cd,2Cd
205 			    7       N/C
206 
207 			*/
208 
209 			m_ram_a12_a7 = data & 0x3f;
210 
211 			m_ls74_cd = BIT(data, 6);
212 
213 			if (!m_ls74_cd)
214 			{
215 				m_ls74_q1 = 0;
216 				m_ls74_q2 = 0;
217 
218 				nmi_w(CLEAR_LINE);
219 			}
220 		}
221 		else
222 		{
223 			m_ram[(m_ram_a12_a7 << 7) | (offset & 0x7f)] = data;
224 		}
225 	}
226 
227 	if (sphi2 && ((offset & 0xfff0) == 0xd600))
228 	{
229 		m_ram[(m_ram_a12_a7 << 7) | (offset & 0x7f)] = data;
230 	}
231 }
232 
233 
234 //-------------------------------------------------
235 //  vcs_joy_w - joystick write
236 //-------------------------------------------------
237 
vcs_joy_w(uint8_t data)238 void c128_partner_cartridge_device::vcs_joy_w(uint8_t data)
239 {
240 	int joyb2 = BIT(data, 2);
241 
242 	if (!m_joyb2 && joyb2 && m_ls74_cd)
243 	{
244 		m_ls74_q2 = m_ls74_q1;
245 
246 		nmi_w(m_ls74_q2 ? ASSERT_LINE : CLEAR_LINE);
247 	}
248 
249 	m_joyb2 = joyb2;
250 }
251