1 // license:BSD-3-Clause
2 // copyright-holders:Andrew Gardner
3 // This file contains functions which handle the On-Chip peripheral Memory Map
4 // as well as the Host Interface and the SSI0/SSI1 Serial Interfaces.
5
6 #include "emu.h"
7 #include "dsp56mem.h"
8 #include "dsp56pcu.h"
9
10 namespace DSP_56156 {
11
12 /* IPR Accessor Implementations */
IPR_set(dsp56156_core * cpustate,uint16_t value)13 void IPR_set(dsp56156_core* cpustate, uint16_t value)
14 {
15 /* TODO: Is there anything else? */
16 IPR = value;
17 }
18
irqa_ipl(dsp56156_core * cpustate)19 int8_t irqa_ipl(dsp56156_core* cpustate) { return ((IPR & 0x0003) >> 0) - 1; }
irqa_trigger(dsp56156_core * cpustate)20 uint8_t irqa_trigger(dsp56156_core* cpustate){ return (IPR & 0x0004) >> 2; }
irqb_ipl(dsp56156_core * cpustate)21 int8_t irqb_ipl(dsp56156_core* cpustate) { return ((IPR & 0x0018) >> 3) - 1; }
irqb_trigger(dsp56156_core * cpustate)22 uint8_t irqb_trigger(dsp56156_core* cpustate){ return (IPR & 0x0002) >> 5; }
codec_ipl(dsp56156_core * cpustate)23 int8_t codec_ipl(dsp56156_core* cpustate) { return ((IPR & 0x00c0) >> 6) - 1; }
host_ipl(dsp56156_core * cpustate)24 int8_t host_ipl(dsp56156_core* cpustate) { return ((IPR & 0x0300) >> 8) - 1; }
ssi0_ipl(dsp56156_core * cpustate)25 int8_t ssi0_ipl(dsp56156_core* cpustate) { return ((IPR & 0x0c00) >> 10) - 1; }
ssi1_ipl(dsp56156_core * cpustate)26 int8_t ssi1_ipl(dsp56156_core* cpustate) { return ((IPR & 0x3000) >> 12) - 1; }
tm_ipl(dsp56156_core * cpustate)27 int8_t tm_ipl(dsp56156_core* cpustate) { return ((IPR & 0xc000) >> 14) - 1; }
28
mem_reset(dsp56156_core * cpustate)29 void mem_reset(dsp56156_core* cpustate)
30 {
31 // Reset the HI registers
32 dsp56156_host_interface_reset(cpustate);
33
34 // Reset the IO registers
35 dsp56156_io_reset(cpustate);
36 }
37
38
39 /***************************************************************************
40 HOST INTERFACE
41 ***************************************************************************/
42 /***************/
43 /* DSP56k SIDE */
44 /***************/
45 /************************************/
46 /* Host Control Register (HCR) Bits */
47 /************************************/
HCR_set(dsp56156_core * cpustate,uint16_t value)48 void HCR_set(dsp56156_core* cpustate, uint16_t value)
49 {
50 HF3_bit_set (cpustate, (value & 0x0010) >> 4);
51 HF2_bit_set (cpustate, (value & 0x0008) >> 3);
52 HCIE_bit_set(cpustate, (value & 0x0004) >> 2);
53 HTIE_bit_set(cpustate, (value & 0x0002) >> 1);
54 HRIE_bit_set(cpustate, (value & 0x0001) >> 0);
55 }
56 //uint16_t HF3_bit(dsp56156_core* cpustate) { return ((HCR & 0x0010) != 0); }
57 //uint16_t HF2_bit(dsp56156_core* cpustate) { return ((HCR & 0x0008) != 0); }
HCIE_bit(dsp56156_core * cpustate)58 uint16_t HCIE_bit(dsp56156_core* cpustate) { return ((HCR & 0x0004) != 0); }
HTIE_bit(dsp56156_core * cpustate)59 uint16_t HTIE_bit(dsp56156_core* cpustate) { return ((HCR & 0x0002) != 0); }
HRIE_bit(dsp56156_core * cpustate)60 uint16_t HRIE_bit(dsp56156_core* cpustate) { return ((HCR & 0x0001) != 0); }
61
HF3_bit_set(dsp56156_core * cpustate,uint16_t value)62 void HF3_bit_set(dsp56156_core* cpustate, uint16_t value)
63 {
64 value = value & 0x01;
65 HCR &= ~(0x0010);
66 HCR |= (value << 4);
67
68 HF3_bit_host_set(cpustate, value);
69 }
HF2_bit_set(dsp56156_core * cpustate,uint16_t value)70 void HF2_bit_set(dsp56156_core* cpustate, uint16_t value)
71 {
72 value = value & 0x01;
73 HCR &= ~(0x0008);
74 HCR |= (value << 3);
75
76 HF2_bit_host_set(cpustate, value);
77 }
HCIE_bit_set(dsp56156_core * cpustate,uint16_t value)78 void HCIE_bit_set(dsp56156_core* cpustate, uint16_t value)
79 {
80 value = value & 0x01;
81 HCR &= ~(0x0004);
82 HCR |= (value << 2);
83 }
HTIE_bit_set(dsp56156_core * cpustate,uint16_t value)84 void HTIE_bit_set(dsp56156_core* cpustate, uint16_t value)
85 {
86 value = value & 0x01;
87 HCR &= ~(0x0002);
88 HCR |= (value << 1);
89 }
HRIE_bit_set(dsp56156_core * cpustate,uint16_t value)90 void HRIE_bit_set(dsp56156_core* cpustate, uint16_t value)
91 {
92 value = value & 0x01;
93 HCR &= ~(0x0001);
94 HCR |= (value << 0);
95 }
96
97 /***********************************/
98 /* Host Status Register (HSR) Bits */
99 /***********************************/
100 //uint16_t DMA_bit(dsp56156_core* cpustate) { return ((HSR & 0x0080) != 0); }
101 //uint16_t HF1_bit(dsp56156_core* cpustate) { return ((HSR & 0x0010) != 0); }
102 //uint16_t HF0_bit(dsp56156_core* cpustate) { return ((HSR & 0x0008) != 0); }
103 //uint16_t HCP_bit(dsp56156_core* cpustate) { return ((HSR & 0x0004) != 0); }
HTDE_bit(dsp56156_core * cpustate)104 uint16_t HTDE_bit(dsp56156_core* cpustate) { return ((HSR & 0x0002) != 0); }
HRDF_bit(dsp56156_core * cpustate)105 uint16_t HRDF_bit(dsp56156_core* cpustate) { return ((HSR & 0x0001) != 0); }
106
DMA_bit_set(dsp56156_core * cpustate,uint16_t value)107 void DMA_bit_set(dsp56156_core* cpustate, uint16_t value)
108 {
109 value = value & 0x01;
110 HSR &= ~(0x0080);
111 HSR |= (value << 7);
112 // TODO: 5-12 When the DMA bit is set, the DMA mode is enabled by the Host Mode bits HM0 & HM1
113 }
HF1_bit_set(dsp56156_core * cpustate,uint16_t value)114 void HF1_bit_set(dsp56156_core* cpustate, uint16_t value)
115 {
116 value = value & 0x01;
117 HSR &= ~(0x0010);
118 HSR |= (value << 4);
119 }
HF0_bit_set(dsp56156_core * cpustate,uint16_t value)120 void HF0_bit_set(dsp56156_core* cpustate, uint16_t value)
121 {
122 value = value & 0x01;
123 HSR &= ~(0x0008);
124 HSR |= (value << 3);
125 }
HCP_bit_set(dsp56156_core * cpustate,uint16_t value)126 void HCP_bit_set(dsp56156_core* cpustate, uint16_t value)
127 {
128 value = value & 0x01;
129 HSR &= ~(0x0004);
130 HSR |= (value << 2);
131
132 if (value && HCIE_bit(cpustate))
133 dsp56156_add_pending_interrupt(cpustate, "Host Command");
134 }
HTDE_bit_set(dsp56156_core * cpustate,uint16_t value)135 void HTDE_bit_set(dsp56156_core* cpustate, uint16_t value)
136 {
137 value = value & 0x01;
138 HSR &= ~(0x0002);
139 HSR |= (value << 1);
140
141 // 5-10 If HTIE bit is set, whip out a Host Transmit Data interrupt
142 if (value && HTIE_bit(cpustate))
143 dsp56156_add_pending_interrupt(cpustate, "Host Transmit Data");
144
145 // 5-5 If both me and RXDF are cleared, transmit data to the host
146 if (!value && !RXDF_bit(cpustate))
147 dsp56156_host_interface_HTX_to_host(cpustate);
148 }
HRDF_bit_set(dsp56156_core * cpustate,uint16_t value)149 void HRDF_bit_set(dsp56156_core* cpustate, uint16_t value)
150 {
151 value = value & 0x01;
152 HSR &= ~(0x0001);
153 HSR |= (value << 0);
154
155 // 5-10 If HRIE is set, whip out a Host Receive Data interrupt
156 if (value && HRIE_bit(cpustate))
157 dsp56156_add_pending_interrupt(cpustate, "Host Receive Data");
158
159 // 5-5 If both me and TXDE are cleared, transmit data to the dsp56156
160 if (!value && !TXDE_bit(cpustate))
161 dsp56156_host_interface_host_to_HTX(cpustate);
162 }
163
164
165
166 /*************/
167 /* HOST SIDE */
168 /*************/
169 /*****************************************/
170 /* Interrupt Control Register (ICR) Bits */
171 /*****************************************/
ICR_set(dsp56156_core * cpustate,uint8_t value)172 void ICR_set(dsp56156_core* cpustate, uint8_t value)
173 {
174 HF1_bit_host_set(cpustate, (value & 0x10) >> 4);
175 HF0_bit_host_set(cpustate, (value & 0x08) >> 3);
176 TREQ_bit_set(cpustate, (value & 0x02) >> 1);
177 RREQ_bit_set(cpustate, (value & 0x01) >> 0);
178 }
179
180 //uint8_t INIT_bit(dsp56156_core* cpustate); #define x_initBIT ((dsp56156.HI.ICR & 0x0080) != 0)
181 //uint8_t HM1_bit(dsp56156_core* cpustate); #define x_hm1BIT ((dsp56156.HI.ICR & 0x0040) != 0)
182 //uint8_t HM0_bit(dsp56156_core* cpustate); #define x_hm0BIT ((dsp56156.HI.ICR & 0x0020) != 0)
183 //uint8_t HF1_bit_host(dsp56156_core* cpustate); #define x_hf1BIT ((dsp56156.HI.ICR & 0x0010) != 0)
184 //uint8_t HF0_bit_host(dsp56156_core* cpustate); #define x_hf0BIT ((dsp56156.HI.ICR & 0x0008) != 0)
185 //uint8_t TREQ_bit(dsp56156_core* cpustate); #define x_treqBIT ((dsp56156.HI.ICR & 0x0002) != 0)
186 //uint8_t RREQ_bit(dsp56156_core* cpustate); #define x_rreqBIT ((dsp56156.HI.ICR & 0x0001) != 0)
187
188 //void INIT_bit_set(dsp56156_core* cpustate, uint8_t value); #define CLEAR_x_initBIT() (dsp56156.HI.ICR &= (~0x0080))
189 //void HM1_bit_set(dsp56156_core* cpustate, uint8_t value); #define CLEAR_x_hm1BIT() (dsp56156.HI.ICR &= (~0x0040))
190 //void HM0_bit_set(dsp56156_core* cpustate, uint8_t value); #define CLEAR_x_hm0BIT() (dsp56156.HI.ICR &= (~0x0020))
HF1_bit_host_set(dsp56156_core * cpustate,uint8_t value)191 void HF1_bit_host_set(dsp56156_core* cpustate, uint8_t value)
192 {
193 value = value & 0x01;
194 ICR &= ~(0x10);
195 ICR |= (value << 4);
196
197 HF1_bit_set(cpustate, value); // 5-14
198 }
HF0_bit_host_set(dsp56156_core * cpustate,uint8_t value)199 void HF0_bit_host_set(dsp56156_core* cpustate, uint8_t value)
200 {
201 value = value & 0x01;
202 ICR &= ~(0x08);
203 ICR |= (value << 3);
204
205 HF0_bit_set(cpustate, value); // 5-13
206 }
TREQ_bit_set(dsp56156_core * cpustate,uint8_t value)207 void TREQ_bit_set(dsp56156_core* cpustate, uint8_t value)
208 {
209 value = value & 0x01;
210 ICR &= ~(0x02);
211 ICR |= (value << 1);
212 }
RREQ_bit_set(dsp56156_core * cpustate,uint8_t value)213 void RREQ_bit_set(dsp56156_core* cpustate, uint8_t value)
214 {
215 value = value & 0x01;
216 ICR &= ~(0x01);
217 ICR |= (value << 0);
218
219 // 5-12
220 if (value)
221 {
222 // TODO : HREQ_assert();
223 }
224 }
225
226
227
228 /**************************************/
229 /* Command Vector Register (CVR) Bits */
230 /**************************************/
HV_bits(dsp56156_core * cpustate)231 uint8_t HV_bits(dsp56156_core* cpustate) { return (CVR & 0x1f); }
232
CVR_set(dsp56156_core * cpustate,uint8_t value)233 void CVR_set(dsp56156_core* cpustate, uint8_t value)
234 {
235 /* A single, unified place to run all callbacks for each of the bits */
236 HC_bit_set(cpustate, (value & 0x80) >> 7);
237 HV_bits_set(cpustate, (value & 0x1f));
238 }
239
HC_bit_set(dsp56156_core * cpustate,uint8_t value)240 void HC_bit_set(dsp56156_core* cpustate, uint8_t value)
241 {
242 value = value & 0x01;
243 CVR &= ~(0x80);
244 CVR |= (value << 7);
245
246 HCP_bit_set(cpustate, value); // 5-9 & 5-11
247 }
HV_bits_set(dsp56156_core * cpustate,uint8_t value)248 void HV_bits_set(dsp56156_core* cpustate, uint8_t value)
249 {
250 value = value & 0x1f;
251 CVR &= ~(0x1f);
252 CVR |= (value << 0);
253 }
254
255
256 /****************************************/
257 /* Interrupt Status Register (ISR) Bits */
258 /****************************************/
TXDE_bit(dsp56156_core * cpustate)259 uint8_t TXDE_bit(dsp56156_core* cpustate) { return ((ISR & 0x0002) != 0); }
RXDF_bit(dsp56156_core * cpustate)260 uint8_t RXDF_bit(dsp56156_core* cpustate) { return ((ISR & 0x0001) != 0); }
261
HF3_bit_host_set(dsp56156_core * cpustate,uint8_t value)262 void HF3_bit_host_set(dsp56156_core* cpustate, uint8_t value)
263 {
264 value = value & 0x01;
265 ISR &= ~(0x0010);
266 ISR |= (value << 4);
267 }
HF2_bit_host_set(dsp56156_core * cpustate,uint8_t value)268 void HF2_bit_host_set(dsp56156_core* cpustate, uint8_t value)
269 {
270 value = value & 0x01;
271 ISR &= ~(0x0008);
272 ISR |= (value << 3);
273 }
274
TXDE_bit_set(dsp56156_core * cpustate,uint8_t value)275 void TXDE_bit_set(dsp56156_core* cpustate, uint8_t value)
276 {
277 value = value & 0x01;
278 ISR &= ~(0x0002);
279 ISR |= (value << 1);
280
281 // If both me and the HRDF are cleared, transmit data to the dsp56156
282 if (!value && !HRDF_bit(cpustate))
283 dsp56156_host_interface_host_to_HTX(cpustate);
284 }
285
RXDF_bit_set(dsp56156_core * cpustate,uint8_t value)286 void RXDF_bit_set(dsp56156_core* cpustate, uint8_t value)
287 {
288 value = value & 0x01;
289 ISR &= ~(0x0001);
290 ISR |= (value << 0);
291
292 // If both me and HTDE are cleared, transmit data to the host
293 if (!value && !HTDE_bit(cpustate))
294 dsp56156_host_interface_HTX_to_host(cpustate);
295 }
296
297
298 // TODO: 5-11 What is the host processor Initialize function?
299
dsp56156_host_interface_reset(dsp56156_core * cpustate)300 void dsp56156_host_interface_reset(dsp56156_core* cpustate)
301 {
302 // Hook up the CPU-side pointers properly.
303 cpustate->HI.hcr = &cpustate->peripheral_ram[A2O(0xffc4)];
304 cpustate->HI.hsr = &cpustate->peripheral_ram[A2O(0xffe4)];
305 cpustate->HI.htrx = &cpustate->peripheral_ram[A2O(0xffe5)];
306
307 // The Bootstrap hack is initialized to write to address 0x0000
308 cpustate->HI.bootstrap_offset = 0x0000;
309
310 /* HCR */
311 HCR_set(cpustate, 0x0000); // 5-10
312
313 /* HSR */
314 HRDF_bit_set(cpustate, 0); // 5-11
315 HTDE_bit_set(cpustate, 1); // 5-11
316 HCP_bit_set(cpustate, 0); // 5-11
317 HF0_bit_set(cpustate, 0); // 5-12
318 HF1_bit_set(cpustate, 0); // 5-12
319 DMA_bit_set(cpustate, 0); // 5-12
320
321 /* CVR*/
322 HV_bits_set(cpustate, 0x16); // 5-7
323 HC_bit_set(cpustate, 0); // 5-9
324
325 /* TODO: ISR (at least) */
326 }
327
dsp56156_host_interface_HTX_to_host(dsp56156_core * cpustate)328 void dsp56156_host_interface_HTX_to_host(dsp56156_core* cpustate)
329 {
330 RXH = ((HTX & 0xff00) >> 8);
331 RXL = ((HTX & 0x00ff));
332 RXDF_bit_set(cpustate, 1);
333 HTDE_bit_set(cpustate, 1);
334 }
335
dsp56156_host_interface_host_to_HTX(dsp56156_core * cpustate)336 void dsp56156_host_interface_host_to_HTX(dsp56156_core* cpustate)
337 {
338 HRX &= 0x00ff;
339 HRX |= (TXH << 8);
340 HRX &= 0xff00;
341 HRX |= TXL;
342 TXDE_bit_set(cpustate, 1);
343 HRDF_bit_set(cpustate, 1);
344 }
345
346
347 /***************************************************************************
348 I/O INTERFACE
349 ***************************************************************************/
350 /* BCR */
BCR_set(dsp56156_core * cpustate,uint16_t value)351 void BCR_set(dsp56156_core* cpustate, uint16_t value)
352 {
353 RH_bit_set(cpustate, (value & 0x8000) >> 15);
354 BS_bit_set(cpustate, (value & 0x4000) >> 14);
355 external_x_wait_states_set(cpustate, (value & 0x03e0) >> 5);
356 external_p_wait_states_set(cpustate, (value & 0x001f) >> 0);
357 }
358
359 //uint16_t RH_bit(dsp56156_core* cpustate);
360 //uint16_t BS_bit(dsp56156_core* cpustate);
361 //uint16_t external_x_wait_states(dsp56156_core* cpustate);
362 //uint16_t external_p_wait_states(dsp56156_core* cpustate);
363
RH_bit_set(dsp56156_core * cpustate,uint16_t value)364 void RH_bit_set(dsp56156_core* cpustate, uint16_t value)
365 {
366 value = value & 0x0001;
367 BCR &= ~(0x8000);
368 BCR |= (value << 15);
369
370 // TODO: 4-6 Assert BR pin?
371 }
BS_bit_set(dsp56156_core * cpustate,uint16_t value)372 void BS_bit_set(dsp56156_core* cpustate, uint16_t value)
373 {
374 value = value & 0x0001;
375 BCR &= ~(0x4000);
376 BCR |= (value << 14);
377
378 // TODO: 4-6 Respond to BR pin?
379 }
external_x_wait_states_set(dsp56156_core * cpustate,uint16_t value)380 void external_x_wait_states_set(dsp56156_core* cpustate, uint16_t value)
381 {
382 value = value & 0x001f;
383 BCR &= ~(0x03e0);
384 BCR |= (value << 5);
385 }
external_p_wait_states_set(dsp56156_core * cpustate,uint16_t value)386 void external_p_wait_states_set(dsp56156_core* cpustate, uint16_t value)
387 {
388 value = value & 0x001f;
389 BCR &= ~(0x001f);
390 BCR |= (value << 0);
391 }
392
393
394 /* Port B Control Register PBC */
PBC_set(dsp56156_core * cpustate,uint16_t value)395 void PBC_set(dsp56156_core* cpustate, uint16_t value)
396 {
397 if (value & 0xfffe)
398 cpustate->device->logerror("Dsp56k : Attempting to set reserved bits in the PBC. Ignoring.\n");
399
400 value = value & 0x0001;
401 PBC &= ~(0x0001);
402 PBC |= (value << 0);
403 }
404
405 #ifdef UNUSED_FUNCTION
host_interface_active(dsp56156_core * cpustate)406 int host_interface_active(dsp56156_core* cpustate)
407 {
408 /* The host interface is active if the 0th bit in the PBC is set */
409 return PBC & 0x0001;
410 }
411 #endif
412
413 /* Port B Data Direction Register (PBDDR) */
PBDDR_set(dsp56156_core * cpustate,uint16_t value)414 void PBDDR_set(dsp56156_core* cpustate, uint16_t value)
415 {
416 if (value & 0x8000)
417 cpustate->device->logerror("Dsp56k : Attempting to set reserved bits in the PBDDR. Ignoring.\n");
418
419 value = value & 0x7fff;
420 PBDDR &= ~(0x7fff);
421 PBDDR |= (value << 0);
422
423 /* TODO: Implement dsp56156 io restrictions, etc. */
424 }
425
426 /* Port B Data Register (PBD) */
PBD_set(dsp56156_core * cpustate,uint16_t value)427 void PBD_set(dsp56156_core* cpustate, uint16_t value)
428 {
429 if (value & 0x8000)
430 cpustate->device->logerror("Dsp56k : Attempting to set reserved bits in the PBD. Ignoring.\n");
431
432 value = value & 0x7fff;
433 PBD &= ~(0x7fff);
434 PBD |= (value << 0);
435
436 /* TODO: Implement dsp56156 io restrictions, etc. */
437 }
438
439 /* Port C Control Register (PCC) */
PCC_set(dsp56156_core * cpustate,uint16_t value)440 void PCC_set(dsp56156_core* cpustate, uint16_t value)
441 {
442 if (value & 0xf000)
443 cpustate->device->logerror("Dsp56k : Attempting to set reserved bits in the PCC. Ignoring.\n");
444
445 value = value & 0x0fff;
446 PCC &= ~(0x0fff);
447 PCC |= (value << 0);
448
449 /* TODO: Implement dsp56156 timer and control glue */
450 }
451
452 /* Port C Data Direction Register (PCDDR) */
PCDDR_set(dsp56156_core * cpustate,uint16_t value)453 void PCDDR_set(dsp56156_core* cpustate, uint16_t value)
454 {
455 if (value & 0xf000)
456 cpustate->device->logerror("Dsp56k : Attempting to set reserved bits in the PCDDR. Ignoring.\n");
457
458 value = value & 0x0fff;
459 PCDDR &= ~(0x0fff);
460 PCDDR |= (value << 0);
461
462 /* TODO: Implement dsp56156 io restrictions, etc. */
463 }
464
465 /* Port C Data Register (PCD) */
PCD_set(dsp56156_core * cpustate,uint16_t value)466 void PCD_set(dsp56156_core* cpustate, uint16_t value)
467 {
468 if (value & 0xf000)
469 cpustate->device->logerror("Dsp56k : Attempting to set reserved bits in the PCD. Ignoring.\n");
470
471 /* TODO: Temporary */
472 cpustate->device->logerror("Dsp56k : Setting general output port C data to 0x%04x\n", value);
473
474 value = value & 0x0fff;
475 PCD &= ~(0x0fff);
476 PCD |= (value << 0);
477 }
478
dsp56156_io_reset(dsp56156_core * cpustate)479 void dsp56156_io_reset(dsp56156_core* cpustate)
480 {
481 /* The BCR = 0x43ff */
482 RH_bit_set(cpustate, 0);
483 BS_bit_set(cpustate, 1);
484 external_x_wait_states_set(cpustate, 0x1f);
485 external_p_wait_states_set(cpustate, 0x1f);
486 }
487
488
489 /* Work */
peripheral_register_r(offs_t offset)490 uint16_t dsp56156_device::peripheral_register_r(offs_t offset)
491 {
492 dsp56156_core* cpustate = &m_core;
493 // (printf) cpustate->device->logerror("Peripheral read 0x%04x\n", O2A(offset));
494
495 switch (O2A(offset))
496 {
497 // Port B Control Register (PBC)
498 case 0xffc0: break;
499
500 // Port C Control Register (PCC)
501 case 0xffc1: break;
502
503 // Port B Data Direction Register (PBDDR)
504 case 0xffc2: break;
505
506 // Port C Data Direction Register (PCDDR)
507 case 0xffc3: break;
508
509 // HCR: Host Control Register
510 case 0xffc4: break;
511
512 // COCR
513 case 0xffc8: break;
514
515 // reserved for test
516 case 0xffc9: break;
517
518 // CRA-SSI0 Control Register A
519 case 0xffd0: break;
520
521 // CRB-SSI0 Control Register B
522 case 0xffd1: break;
523
524 // CRA-SSI1 Control Register A
525 case 0xffd8: break;
526
527 // CRB-SSI1 Control Register B
528 case 0xffd9: break;
529
530 // PLCR
531 case 0xffdc: break;
532
533 // reserved for future use
534 case 0xffdd: break;
535
536 // BCR: Bus Control Register
537 case 0xffde: break;
538
539 // IPR: Interrupt Priority Register
540 case 0xffdf: break;
541
542 // Port B Data Register (PBD)
543 case 0xffe2: break;
544
545 // Port C Data Register (PCD)
546 case 0xffe3: break;
547
548 // HSR: Host Status Register
549 case 0xffe4: break;
550
551 // HTX/HRX: Host TX/RX Register
552 case 0xffe5:
553 // 5-5
554 if (!DSP_56156::HRDF_bit(cpustate))
555 return 0xbeef;
556 else
557 {
558 uint16_t value = HRX; // TODO: Maybe not exactly right? Just being safe.
559 DSP_56156::HRDF_bit_set(cpustate, 0);
560 return value;
561 }
562 // COSR
563 case 0xffe8: break;
564
565 // CRX/CTX
566 case 0xffe9: break;
567
568 // Timer Control Register (TCR)
569 case 0xffec: break;
570
571 // Timer Count Register (TCTR)
572 case 0xffed: break;
573
574 // Timer Compare Register (TCPR)
575 case 0xffee: break;
576
577 // Timer Preload Register (TPR)
578 case 0xffef: break;
579
580 // SR/TSR SSI0 Status Register
581 case 0xfff0: break;
582
583 // TX/RX SSI0 Tx/RX Registers
584 case 0xfff1: break;
585
586 // RSMA0 SSI0 Register
587 case 0xfff2: break;
588
589 // RSMB0 SSI0 Register
590 case 0xfff3: break;
591
592 // TSMA0 SSI0 Register
593 case 0xfff4: break;
594
595 // TSMB0 SSI0 Register
596 case 0xfff5: break;
597
598 // SR/TSR SSI1 Status Register
599 case 0xfff8: break;
600
601 // TX/RX SSI1 TX/RX Registers
602 case 0xfff9: break;
603
604 // RSMA1 SSI1 Register
605 case 0xfffa: break;
606
607 // RSMB1 SSI1 Register
608 case 0xfffb: break;
609
610 // TSMA1 SSI1 Register
611 case 0xfffc: break;
612
613 // TSMB1 SSI1 Register
614 case 0xfffd: break;
615
616 // Reserved for on-chip emulation
617 case 0xffff: break;
618 }
619
620 // Its primary behavior is RAM
621 return cpustate->peripheral_ram[offset];
622 }
623
peripheral_register_w(offs_t offset,uint16_t data)624 void dsp56156_device::peripheral_register_w(offs_t offset, uint16_t data)
625 {
626 dsp56156_core* cpustate = &m_core;
627
628 // Its primary behavior is RAM
629 // COMBINE_DATA(&cpustate->peripheral_ram[offset]);
630
631 // (printf) cpustate->device->logerror("Peripheral write 0x%04x = %04x\n", O2A(offset), data);
632
633 // 4-8
634 switch (O2A(offset))
635 {
636 // Port B Control Register (PBC)
637 case 0xffc0:
638 DSP_56156::PBC_set(cpustate, data);
639 break;
640
641 // Port C Control Register (PCC)
642 case 0xffc1:
643 DSP_56156::PCC_set(cpustate, data);
644 break;
645
646 // Port B Data Direction Register (PBDDR)
647 case 0xffc2:
648 DSP_56156::PBDDR_set(cpustate, data);
649 break;
650
651 // Port C Data Direction Register (PCDDR)
652 case 0xffc3:
653 DSP_56156::PCDDR_set(cpustate, data);
654 break;
655
656 // HCR: Host Control Register
657 case 0xffc4:
658 DSP_56156::HCR_set(cpustate, data);
659 break;
660
661 // COCR
662 case 0xffc8: break;
663
664 // reserved for test
665 case 0xffc9:
666 cpustate->device->logerror("DSP56k : Warning write to 0xffc9 reserved for test.\n");
667 break;
668
669 // CRA-SSI0 Control Register A
670 case 0xffd0: break;
671
672 // CRB-SSI0 Control Register B
673 case 0xffd1: break;
674
675 // CRA-SSI1 Control Register A
676 case 0xffd8: break;
677
678 // CRB-SSI1 Control Register B
679 case 0xffd9: break;
680
681 // PLCR
682 case 0xffdc: break;
683
684 // reserved for future use
685 case 0xffdd:
686 cpustate->device->logerror("DSP56k : Warning write to 0xffdd reserved for future use.\n");
687 break;
688
689 // BCR: Bus Control Register
690 case 0xffde:
691 DSP_56156::BCR_set(cpustate, data);
692 break;
693
694 // IPR: Interrupt Priority Register
695 case 0xffdf:
696 DSP_56156::IPR_set(cpustate, data);
697 break;
698
699 // Port B Data Register (PBD)
700 case 0xffe2:
701 DSP_56156::PBD_set(cpustate, data);
702 break;
703
704 // Port C Data Register (PCD)
705 case 0xffe3:
706 DSP_56156::PCD_set(cpustate, data);
707 break;
708
709 // HSR: Host Status Register
710 case 0xffe4: break;
711
712 // HTX/HRX: Host TX/RX Register
713 case 0xffe5:
714 HTX = data;
715 DSP_56156::HTDE_bit_set(cpustate, 0); // 5-5
716 break;
717
718 // COSR
719 case 0xffe8: break;
720
721 // CRX/CTX
722 case 0xffe9: break;
723
724 // Timer Control Register (TCR)
725 case 0xffec: break;
726
727 // Timer Count Register (TCTR)
728 case 0xffed: break;
729
730 // Timer Compare Register (TCPR)
731 case 0xffee: break;
732
733 // Timer Preload Register (TPR)
734 case 0xffef: break;
735
736 // SR/TSR SSI0 Status Register
737 case 0xfff0: break;
738
739 // TX/RX SSI0 Tx/RX Registers
740 case 0xfff1: break;
741
742 // RSMA0 SSI0 Register
743 case 0xfff2: break;
744
745 // RSMB0 SSI0 Register
746 case 0xfff3: break;
747
748 // TSMA0 SSI0 Register
749 case 0xfff4: break;
750
751 // TSMB0 SSI0 Register
752 case 0xfff5: break;
753
754 // SR/TSR SSI1 Status Register
755 case 0xfff8: break;
756
757 // TX/RX SSI1 TX/RX Registers
758 case 0xfff9: break;
759
760 // RSMA1 SSI1 Register
761 case 0xfffa: break;
762
763 // RSMB1 SSI1 Register
764 case 0xfffb: break;
765
766 // TSMA1 SSI1 Register
767 case 0xfffc: break;
768
769 // TSMB1 SSI1 Register
770 case 0xfffd: break;
771
772 // Reserved for on-chip emulation
773 case 0xffff:
774 cpustate->device->logerror("DSP56k : Warning write to 0xffff reserved for on-chip emulation.\n");
775 break;
776 }
777 }
778
779 /* These two functions are exposed to the outside world */
780 /* They represent the host side of the dsp56156's host interface */
host_interface_write(uint8_t offset,uint8_t data)781 void dsp56156_device::host_interface_write(uint8_t offset, uint8_t data)
782 {
783 dsp56156_core* cpustate = &m_core;
784
785 /* Not exactly correct since the bootstrap hack doesn't need this to be true */
786 /*
787 if (!host_interface_active())
788 cpustate->device->logerror("Dsp56k : Host interface write called without HI being set active by the PBC.\n");
789 */
790
791 switch (offset)
792 {
793 // Interrupt Control Register (ICR)
794 case 0x00:
795 // HACK
796 if (cpustate->bootstrap_mode == BOOTSTRAP_HI)
797 {
798 // A-4 If they set HF0 while in bootstrap mode, it stops the bootstrap short.
799 if (data & 0x08)
800 {
801 cpustate->bootstrap_mode = BOOTSTRAP_OFF;
802 PC = 0x0000;
803 // TODO: Do we set HF0 then, or let it slide?
804 // TODO: Do I allow it to do an ICR_set(), or intercept it and throw everything away?
805 break;
806 }
807 }
808 DSP_56156::ICR_set(cpustate, data);
809 break;
810
811 // Command Vector Register (CVR)
812 case 0x01:
813 DSP_56156::CVR_set(cpustate, data);
814 break;
815
816 // Interrupt status register (ISR) - Read only!
817 case 0x02:
818 cpustate->device->logerror("DSP56k : Interrupt status register is read only.\n");
819 break;
820
821 // Interrupt vector register (IVR)
822 case 0x03: break;
823
824 // Not used
825 case 0x04:
826 cpustate->device->logerror("DSP56k : Address 0x4 on the host side of the host interface is not used.\n");
827 break;
828
829 // Reserved
830 case 0x05:
831 cpustate->device->logerror("DSP56k : Address 0x5 on the host side of the host interface is reserved.\n");
832 break;
833
834 // Transmit byte register - high byte (TXH)
835 case 0x06:
836 // HACK
837 if (cpustate->bootstrap_mode == BOOTSTRAP_HI)
838 {
839 cpustate->program_ram[cpustate->HI.bootstrap_offset] &= 0x00ff;
840 cpustate->program_ram[cpustate->HI.bootstrap_offset] |= (data << 8);
841 break; /* Probably the right thing to do, given this is a hack */
842 }
843
844 if (DSP_56156::TXDE_bit(cpustate)) // 5-5
845 {
846 TXH = data;
847 }
848 break;
849
850 // Transmit byte register - low byte (TXL)
851 case 0x07:
852 // HACK
853 if (cpustate->bootstrap_mode == BOOTSTRAP_HI)
854 {
855 cpustate->program_ram[cpustate->HI.bootstrap_offset] &= 0xff00;
856 cpustate->program_ram[cpustate->HI.bootstrap_offset] |= data;
857 cpustate->HI.bootstrap_offset++;
858
859 if (cpustate->HI.bootstrap_offset == 0x800)
860 {
861 cpustate->bootstrap_mode = BOOTSTRAP_OFF;
862 }
863 break; /* Probably the right thing to do, given this is a hack */
864 }
865
866 if (DSP_56156::TXDE_bit(cpustate)) // 5-5
867 {
868 TXL = data;
869 DSP_56156::TXDE_bit_set(cpustate, 0);
870 }
871 break;
872
873 default: cpustate->device->logerror("DSP56k : dsp56156_host_interface_write called with invalid address 0x%02x.\n", offset);
874 }
875 }
876
host_interface_read(uint8_t offset)877 uint8_t dsp56156_device::host_interface_read(uint8_t offset)
878 {
879 dsp56156_core* cpustate = &m_core;
880
881 /* Not exactly correct since the bootstrap hack doesn't need this to be true */
882 /*
883 if (!host_interface_active())
884 cpustate->device->logerror("Dsp56k : Host interface write called without HI being set active by the PBC.\n");
885 */
886
887 switch (offset)
888 {
889 // Interrupt Control Register (ICR)
890 case 0x00:
891 return ICR;
892
893 // Command Vector Register (CVR)
894 case 0x01:
895 return CVR;
896
897 // Interrupt status register (ISR)
898 case 0x02:
899 return ISR;
900
901 // Interrupt vector register (IVR)
902 case 0x03:
903 return IVR;
904
905 // Read zeroes
906 case 0x04:
907 return 0x00;
908
909 // Reserved
910 case 0x05:
911 cpustate->device->logerror("DSP56k : Address 0x5 on the host side of the host interface is reserved.\n");
912 break;
913
914 // Receive byte register - high byte (RXH)
915 case 0x06:
916 // 5-5
917 if (!DSP_56156::RXDF_bit(cpustate))
918 return 0xbf;
919 else
920 return RXH;
921
922 // Receive byte register - low byte (RXL)
923 case 0x07:
924 // 5-5
925 if (!DSP_56156::RXDF_bit(cpustate))
926 return 0xbf;
927 else
928 {
929 uint8_t value = RXL; // TODO: Maybe not exactly right? I'm just being safe.
930 DSP_56156::RXDF_bit_set(cpustate, 0);
931 return value;
932 }
933
934 default: cpustate->device->logerror("DSP56k : dsp56156_host_interface_read called with invalid address 0x%02x.\n", offset);
935 }
936
937 /* Shouldn't get here */
938 return 0xff;
939 }
940
941 /* MISC*/
get_peripheral_memory(uint16_t addr)942 uint16_t dsp56156_device::get_peripheral_memory(uint16_t addr)
943 {
944 dsp56156_core* cpustate = &m_core;
945 return cpustate->peripheral_ram[A2O(addr)];
946 }
947
948
949 } // namespace DSP_56156
950