1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Commodore IEEE-488 cartridge emulation
6 
7 **********************************************************************/
8 
9 #include "emu.h"
10 #include "ieee488.h"
11 
12 
13 
14 //**************************************************************************
15 //  MACROS/CONSTANTS
16 //**************************************************************************
17 
18 #define MOS6525_TAG     "u3"
19 
20 
21 
22 //**************************************************************************
23 //  DEVICE DEFINITIONS
24 //**************************************************************************
25 
26 DEFINE_DEVICE_TYPE(C64_IEEE488, c64_ieee488_device, "c64_ieee488", "C64 IEEE-488 cartridge")
27 
28 
29 //-------------------------------------------------
30 //  tpi6525_interface tpi_intf
31 //-------------------------------------------------
32 
tpi_pa_r()33 uint8_t c64_ieee488_device::tpi_pa_r()
34 {
35 	/*
36 
37 	    bit     description
38 
39 	    PA0
40 	    PA1
41 	    PA2     REN
42 	    PA3     ATN
43 	    PA4     DAV
44 	    PA5     EOI
45 	    PA6     NDAC
46 	    PA7     NRFD
47 
48 	*/
49 
50 	uint8_t data = 0;
51 
52 	data |= m_bus->ren_r() << 2;
53 	data |= m_bus->atn_r() << 3;
54 	data |= m_bus->dav_r() << 4;
55 	data |= m_bus->eoi_r() << 5;
56 	data |= m_bus->ndac_r() << 6;
57 	data |= m_bus->nrfd_r() << 7;
58 
59 	return data;
60 }
61 
tpi_pa_w(uint8_t data)62 void c64_ieee488_device::tpi_pa_w(uint8_t data)
63 {
64 	/*
65 
66 	    bit     description
67 
68 	    PA0     U4 DC
69 	    PA1     U4/U5 TE
70 	    PA2     REN
71 	    PA3     ATN
72 	    PA4     DAV
73 	    PA5     EOI
74 	    PA6     NDAC
75 	    PA7     NRFD
76 
77 	*/
78 
79 	m_bus->host_ren_w(BIT(data, 2));
80 	m_bus->host_atn_w(BIT(data, 3));
81 	m_bus->host_dav_w(BIT(data, 4));
82 	m_bus->host_eoi_w(BIT(data, 5));
83 	m_bus->host_ndac_w(BIT(data, 6));
84 	m_bus->host_nrfd_w(BIT(data, 7));
85 }
86 
tpi_pc_r(offs_t offset)87 uint8_t c64_ieee488_device::tpi_pc_r(offs_t offset)
88 {
89 	/*
90 
91 	    bit     description
92 
93 	    PC0     IFC
94 	    PC1     SRQ
95 	    PC2
96 	    PC3
97 	    PC4
98 	    PC5
99 	    PC6
100 	    PC7     slot _EXROM
101 
102 	*/
103 
104 	uint8_t data = 0;
105 
106 	data |= m_bus->ifc_r();
107 	data |= m_bus->srq_r() << 1;
108 
109 	data |= m_exp->exrom_r(offset, 1, 1, 1, 0, 0) << 7;
110 
111 	return data;
112 }
113 
tpi_pc_w(uint8_t data)114 void c64_ieee488_device::tpi_pc_w(uint8_t data)
115 {
116 	/*
117 
118 	    bit     description
119 
120 	    PC0     IFC
121 	    PC1     SRQ
122 	    PC2
123 	    PC3     C64 _EXROM
124 	    PC4     _ROML select
125 	    PC5
126 	    PC6
127 	    PC7
128 
129 	*/
130 
131 	m_bus->host_ifc_w(BIT(data, 0));
132 	m_bus->host_srq_w(BIT(data, 1));
133 
134 	m_exrom = !BIT(data, 3);
135 
136 	m_roml_sel = BIT(data, 4);
137 }
138 
139 
140 //-------------------------------------------------
141 //  device_add_mconfig - add device configuration
142 //-------------------------------------------------
143 
device_add_mconfig(machine_config & config)144 void c64_ieee488_device::device_add_mconfig(machine_config &config)
145 {
146 	TPI6525(config, m_tpi, 0);
147 	m_tpi->in_pa_cb().set(FUNC(c64_ieee488_device::tpi_pa_r));
148 	m_tpi->out_pa_cb().set(FUNC(c64_ieee488_device::tpi_pa_w));
149 	m_tpi->in_pb_cb().set(m_bus, FUNC(ieee488_device::dio_r));
150 	m_tpi->out_pb_cb().set(m_bus, FUNC(ieee488_device::host_dio_w));
151 	m_tpi->in_pc_cb().set(FUNC(c64_ieee488_device::tpi_pc_r));
152 	m_tpi->out_pc_cb().set(FUNC(c64_ieee488_device::tpi_pc_w));
153 
154 	IEEE488(config, m_bus, 0);
155 	ieee488_slot_device::add_cbm_defaults(config, nullptr);
156 
157 	C64_EXPANSION_SLOT(config, m_exp, DERIVED_CLOCK(1, 1), c64_expansion_cards, nullptr);
158 	m_exp->set_passthrough();
159 }
160 
161 
162 
163 //**************************************************************************
164 //  LIVE DEVICE
165 //**************************************************************************
166 
167 //-------------------------------------------------
168 //  c64_ieee488_device - constructor
169 //-------------------------------------------------
170 
c64_ieee488_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)171 c64_ieee488_device::c64_ieee488_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
172 	device_t(mconfig, C64_IEEE488, tag, owner, clock),
173 	device_c64_expansion_card_interface(mconfig, *this),
174 	m_tpi(*this, MOS6525_TAG),
175 	m_bus(*this, IEEE488_TAG),
176 	m_exp(*this, "exp"),
177 	m_roml_sel(1)
178 {
179 }
180 
181 
182 //-------------------------------------------------
183 //  device_start - device-specific startup
184 //-------------------------------------------------
185 
device_start()186 void c64_ieee488_device::device_start()
187 {
188 }
189 
190 
191 //-------------------------------------------------
192 //  device_reset - device-specific reset
193 //-------------------------------------------------
194 
device_reset()195 void c64_ieee488_device::device_reset()
196 {
197 	m_exrom = 0;
198 }
199 
200 
201 //-------------------------------------------------
202 //  c64_cd_r - cartridge data read
203 //-------------------------------------------------
204 
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)205 uint8_t c64_ieee488_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
206 {
207 	data = m_exp->cd_r(offset, data, sphi2, ba, roml, romh, io1, io2);
208 
209 	if (!roml && m_roml_sel)
210 	{
211 		data = m_roml[offset & 0xfff];
212 	}
213 	else if (!io2)
214 	{
215 		data = m_tpi->read(offset & 0x07);
216 	}
217 
218 	return data;
219 }
220 
221 
222 //-------------------------------------------------
223 //  c64_cd_w - cartridge data write
224 //-------------------------------------------------
225 
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)226 void c64_ieee488_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
227 {
228 	if (!io2)
229 	{
230 		m_tpi->write(offset & 0x07, data);
231 	}
232 
233 	m_exp->cd_w(offset, data, sphi2, ba, roml, romh, io1, io2);
234 }
235 
236 
237 //-------------------------------------------------
238 //  c64_game_r - GAME read
239 //-------------------------------------------------
240 
c64_game_r(offs_t offset,int sphi2,int ba,int rw)241 int c64_ieee488_device::c64_game_r(offs_t offset, int sphi2, int ba, int rw)
242 {
243 	return m_exp->game_r(offset, sphi2, ba, rw, m_slot->loram(), m_slot->hiram());
244 }
245