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