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