Previous 199869 Revisions Next

r23954 Wednesday 26th June, 2013 at 15:47:18 UTC by Andrew Gardner
DSP16 improvements. [Andrew Gardner]
- Fixed R=M disassembly
- Added flag formatting
- Shadow register is hooked up
- Opcode & flag fixes
[src/emu/cpu/dsp16]dsp16.c dsp16.h dsp16dis.c dsp16ops.c

trunk/src/emu/cpu/dsp16/dsp16dis.c
r23953r23954
535535      case 0x02: case 0x03:
536536      {
537537         // R = M
538         const UINT8 M = (op & 0x00ff);
539         const UINT8 R = (op & 0x0e00) >> 9;
538         const UINT16 M = (op & 0x01ff);
539         const UINT8  R = (op & 0x0e00) >> 9;
540540         astring rString = disasmRImmediateField(R);
541         sprintf(buffer, "%s = 0x%02x", rString.cstr(), M);
541         sprintf(buffer, "%s = 0x%04x", rString.cstr(), M);
542542         break;
543543      }
544544
trunk/src/emu/cpu/dsp16/dsp16.c
r23953r23954
1414// TODO:
1515//  * Store the cache in 15 unique memory locations as it is on-chip.
1616//  * Modify cycle counts when running from within the cache
17//
17//  * A write to PI resets the pseudoramdom sequence generator)  (page 2-4)
18//  * Handle virtual shift addressing using RB & RE (when RE is enabled)  (page 2-6)
19//  * The ALU sign-extends 32-bit operands from y or p to 36 bits and produces a 36-bit output
20//  * Interrupt lines  (page 2-15)
21//
1822
1923//**************************************************************************
2024//  DEVICE INTERFACE
r23953r23954
104108   state_add(DSP16_P,        "P",         m_p);
105109   state_add(DSP16_A0,       "A0",        m_a0).mask(U64(0xfffffffff));
106110   state_add(DSP16_A1,       "A1",        m_a1).mask(U64(0xfffffffff));
107   state_add(DSP16_AUC,      "AUC",       m_auc); //.formatstr("%6s");
108   state_add(DSP16_PSW,      "PSW",       m_psw); //.formatstr("%16s");
111   state_add(DSP16_AUC,      "AUC",       m_auc).formatstr("%8s");
112   state_add(DSP16_PSW,      "PSW",       m_psw).formatstr("%16s");
109113   state_add(DSP16_C0,       "C0",        m_c0);
110114   state_add(DSP16_C1,       "C1",        m_c1);
111115   state_add(DSP16_C2,       "C2",        m_c2);
112   state_add(DSP16_SIOC,     "SIOC",      m_sioc).formatstr("%16s");
116   state_add(DSP16_SIOC,     "SIOC",      m_sioc).formatstr("%10s");
113117   state_add(DSP16_SRTA,     "SRTA",      m_srta);
114118   state_add(DSP16_SDX,      "SDX",       m_sdx);
115   state_add(DSP16_PIOC,     "PIOC",      m_pioc);
119   state_add(DSP16_PIOC,     "PIOC",      m_pioc).formatstr("%16s");
116120   state_add(DSP16_PDX0,     "PDX0",      m_pdx0);
117121   state_add(DSP16_PDX1,     "PDX1",      m_pdx1);
118122
r23953r23954
170174{
171175   // Page 7-5
172176   m_pc = 0x0000;
173   m_sioc = 0x0000;
177   m_pi = 0x0000;
178   m_sioc = 0x0000;    // (page 5-4)
179   
174180   // SRTA is unaltered by reset
175181   m_pioc = 0x0008;
176182   m_rb = 0x0000;
177183   m_re = 0x0000;
178   // AUC is not affected by reset
184   
185    // AUC is not affected by reset
179186   m_ppc = m_pc;
180187
181188   // Hacky cache emulation.
r23953r23954
195202const address_space_config *dsp16_device::memory_space_config(address_spacenum spacenum) const
196203{
197204   return (spacenum == AS_PROGRAM) ? &m_program_config :
198         (spacenum == AS_DATA) ? &m_data_config :
199         NULL;
205         (spacenum == AS_DATA) ? &m_data_config :
206         NULL;
200207}
201208
202209
r23953r23954
213220      string.printf("(below)");
214221         break;
215222
223        case DSP16_AUC:
224        {
225            astring alignString;
226            const UINT8 align = m_auc & 0x03;
227            switch (align)
228            {
229                case 0x00: alignString.printf("xy"); break;
230                case 0x01: alignString.printf("/4"); break;
231                case 0x02: alignString.printf("x4"); break;
232                case 0x03: alignString.printf(",,"); break;
233            }
234            string.printf("%c%c%c%c%c%s",
235                          m_auc & 0x40 ? 'Y':'.',
236                          m_auc & 0x20 ? '1':'.',
237                          m_auc & 0x10 ? '0':'.',
238                          m_auc & 0x08 ? '1':'.',
239                          m_auc & 0x04 ? '0':'.',
240                          alignString.cstr());
241            break;
242        }
243
244        case DSP16_PSW:
245            string.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
246                          m_psw & 0x8000 ? 'M':'.',
247                          m_psw & 0x4000 ? 'E':'.',
248                          m_psw & 0x2000 ? 'L':'.',
249                          m_psw & 0x1000 ? 'V':'.',
250                          m_psw & 0x0800 ? ',':',',
251                          m_psw & 0x0400 ? ',':',',
252                          m_psw & 0x0200 ? 'O':'.',
253                          m_psw & 0x0100 ? '1':'.',
254                          m_psw & 0x0080 ? '1':'.',
255                          m_psw & 0x0040 ? '1':'.',
256                          m_psw & 0x0020 ? '1':'.',
257                          m_psw & 0x0010 ? 'O':'.',
258                          m_psw & 0x0008 ? '1':'.',
259                          m_psw & 0x0004 ? '1':'.',
260                          m_psw & 0x0002 ? '1':'.',
261                          m_psw & 0x0001 ? '1':'.');
262            break;
263
264        case DSP16_PIOC:
265        {
266            astring strobeString;
267            const UINT8 strobe = (m_pioc & 0x6000) >> 13;
268            switch (strobe)
269            {
270                case 0x00: strobeString.printf("1T"); break;
271                case 0x01: strobeString.printf("2T"); break;
272                case 0x02: strobeString.printf("3T"); break;
273                case 0x03: strobeString.printf("4T"); break;
274            }
275            string.printf("%c%s%c%c%c%c%c%c%c%c%c%c%c%c%c",
276                          m_pioc & 0x8000 ? 'I':'.',
277                          strobeString.cstr(),
278                          m_pioc & 0x1000 ? 'O':'I',
279                          m_pioc & 0x0800 ? 'O':'I',
280                          m_pioc & 0x0400 ? 'S':'.',
281                          m_pioc & 0x0200 ? 'I':'.',
282                          m_pioc & 0x0100 ? 'O':'.',
283                          m_pioc & 0x0080 ? 'P':'.',
284                          m_pioc & 0x0040 ? 'P':'.',
285                          m_pioc & 0x0020 ? 'I':'.',
286                          m_pioc & 0x0010 ? 'I':'.',
287                          m_pioc & 0x0008 ? 'O':'.',
288                          m_pioc & 0x0004 ? 'P':'.',
289                          m_pioc & 0x0002 ? 'P':'.',
290                          m_pioc & 0x0001 ? 'I':'.');
291            break;
292        }
293           
216294      // Placeholder for a better view later (TODO)
217295      case DSP16_SIOC:
218         string.printf("%04x", *(UINT16*)entry.dataptr());
219         break;
296        {
297            astring clkString;
298            const UINT8 clk = (m_sioc & 0x0180) >> 7;
299            switch (clk)
300            {
301                case 0x00: clkString.printf("/4"); break;
302                case 0x01: clkString.printf("12"); break;
303                case 0x02: clkString.printf("16"); break;
304                case 0x03: clkString.printf("20"); break;
305            }
306            string.printf("%c%s%c%c%c%c%c%c%c",
307                          m_sioc & 0x0200 ? 'I':'O',
308                          clkString.cstr(),
309                          m_sioc & 0x0040 ? 'L':'M',
310                          m_sioc & 0x0020 ? 'I':'O',
311                          m_sioc & 0x0010 ? 'I':'O',
312                          m_sioc & 0x0008 ? 'I':'O',
313                          m_sioc & 0x0004 ? 'I':'O',
314                          m_sioc & 0x0002 ? '2':'1',
315                          m_sioc & 0x0001 ? '2':'1');
316            break;
317        }
220318   }
221319}
222320
r23953r23954
343441      m_pc += pcAdvance;
344442      m_icount -= cycles;
345443
444        // The 16 bit PI "shadow" register gets set to PC on each instruction except
445        // when an interrupt service routine is active (TODO: Interrupt check)  (page 2-4)
446        m_pi = m_pc;
447
346448   } while (m_icount > 0);
347449}
348450
trunk/src/emu/cpu/dsp16/dsp16ops.c
r23953r23954
11#include "dsp16.h"
22
3#define DSP_LINE(__DSP_DOCLINE__) printf("0x%04x - %d (%s)\n", m_pc, __LINE__, __DSP_DOCLINE__);
34
5// TODO:
6//   * AUC has a CLR field for writing to A0 & A1 + sign extension + psw + zero lower bits
7//     implement as a clean function (page 2-7)
8//   * Implement saturation overflow (SAT on AUC) (page 2-8)
9//   * Implement p alignment (ALIGN on AUC) (page 2-9)
10//   * When a register is used as a memory pointer. its value is compared with re. If its value is
11//     equal to the contents of re and the postincrement is +1, then the value in rb is copied into
12//     the register after the memory access is complete. See Section 4.2.3.
13//   * CPU flags go to the PSW & conditionTest() works on that (Page 3-4)
14//   * Some instructions are not interruptible.
15//
16
17
18// NOTES:
19// When y is used in an assembly-language instruction, the DSPI6/DSPI6A device will read
20// or write the high half (bits 16-31) of the y register  (page 2-7)
21
422// The YL register is the lower half of the 32 bit Y register
523void* dsp16_device::addressYL()
624{
r23953r23954
826}
927
1028
29// Flag getters
30bool dsp16_device::lmi()
31{
32   return m_psw & 0x8000;
33}
34
35bool dsp16_device::leq()
36{
37    return m_psw & 0x4000;
38}
39
40bool dsp16_device::llv()
41{
42    return m_psw & 0x2000;
43}
44
45bool dsp16_device::lmv()
46{
47    return m_psw & 0x1000;
48}
49
50
1151void dsp16_device::writeRegister(void* reg, const UINT16 &value)
1252{
1353   // Make sure you're not attempting to write somewhere this function doesn't support.
r23953r23954
2262      // 8 bit registers
2363      *(UINT8*)reg = value & 0x00ff;
2464   }
65   else if (reg == &m_psw)
66   {
67      // Writes to the a0 & a1 guard bits too
68      m_a0 &= U64(0x0ffffffff);
69      m_a0 |= U64(m_psw & 0x000f) << 32;
70      m_a1 &= U64(0x0ffffffff);
71      m_a1 |= U64(m_psw & 0x01e0) << 27;
72      m_psw = value;
73   }
2574   else if (reg == &m_i)
2675   {
2776      // 12 bit register
r23953r23954
2978   }
3079   else if (reg == &m_y)
3180   {
32      // Y register [[TODO - check a flag to see if clearing yl is necessary]]
81      // Y register
82      // TODO - Automatic clearing of yl may be selected (according to the CLR field of the auc register)  (page 2-7)
3383      m_y = (value << 16) | (m_y & 0x0000ffff);
3484   }
3585   else if (reg == addressYL())
3686   {
37      // Yl register
87      // Yl register (Writes to yl do not change the data in the high half of y)
3888      m_y = value | (m_y & 0xffff0000);
3989   }
4090   else
r23953r23954
4999{
50100   switch (CON)
51101   {
52      case 0x00: return (m_psw & 0x8000);     // mi (negative result)
53      case 0x01: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // pl (positive result)
54      case 0x02: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // eq (result == 0)
55      case 0x03: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // ne (result != 0)
56      case 0x04: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // lvs (logical overflow set)
57      case 0x05: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // lvc (logical overflow clear)
58      case 0x06: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // mvs (math. overflow set)
59      case 0x07: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // mvc (math. overflow clear)
102      case 0x00: return lmi();   // mi (negative result)
103      case 0x01: return !lmi();  // pl (positive result)
104      case 0x02: return leq();   // eq (result == 0)
105      case 0x03: return !leq();  // ne (result != 0)
106      case 0x04: return llv();   // lvs (logical overflow set)
107      case 0x05: return !llv();  // lvc (logical overflow clear)
108      case 0x06: return lmv();   // mvs (math. overflow set)
109      case 0x07: return !lmv();  // mvc (math. overflow clear)
60110      case 0x08: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // heads (random bit set)
61111      case 0x09: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // tails (random bit clear)
62      case 0x0a: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c0ge (counter0 >= 0)
63      case 0x0b: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c0lt (counter0 < 0)
64      case 0x0c: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c1ge (counter1 >= 0)
65      case 0x0d: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c1lt (counter1 < 0)
66      case 0x0e: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // true (always)
67      case 0x0f: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // false (never)
68      case 0x10: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // gt (result > 0
69      case 0x11: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // le (result <= 0)
112      case 0x0a: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c0ge (counter0 >= 0)*
113      case 0x0b: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c0lt (counter0 < 0)*
114      case 0x0c: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c1ge (counter1 >= 0)*
115      case 0x0d: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false;   // c1lt (counter1 < 0)*
116      case 0x0e: return true;    // true (always)
117      case 0x0f: return false;   // false (never)
118      case 0x10: return (!lmi() && !leq());   // gt (result > 0)
119      case 0x11: return (lmi()  ||  leq());   // le (result <= 0)
70120      default: logerror("Unrecognized condition at PC=0x%04x\n", m_pc); break;
71121   }
122   
123   // Testing each of these conditions (*) increments the respective counter being tested  (page 3-5)
124   
72125   return false;
73126}
74127
r23953r23954
120173      case 0x18: return (void*)&m_sioc;
121174      case 0x19: return (void*)&m_srta;
122175      case 0x1a: return (void*)&m_sdx;
123      //case 0x1b: return (void*)&m_tdms;
176      case 0x1b: logerror("dsp16::registerFromRTable tdms requested 0x%04x.\n", m_pc); break;
124177      case 0x1c: return (void*)&m_pioc;
125178      case 0x1d: return (void*)&m_pdx0;
126179      case 0x1e: return (void*)&m_pdx1;
r23953r23954
133186
134187void dsp16_device::executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S)
135188{
136   // Where is the first operation being written?
137   //UINT64* destinationReg = NULL;
138   //switch (D)
139   //{
140   //  case 0x00: destinationReg = &m_a0;
141   //  case 0x01: destinationReg = &m_a1;
142   //  default: break;
143   //}
189   // TODO: I'm pretty sure we need to feed X into these as well - Double check
190   
191   // Note these instructions read right-to-left, so act accordingly  (page 3-6)
192   // y & p are sign extended  (page 3-9)
193   // implementation details  (page 3-9)
144194
195   // Where is are the results going?
196   UINT64* destinationReg = NULL;
197   switch (D)
198   {
199      case 0x00: destinationReg = &m_a0; break;
200      case 0x01: destinationReg = &m_a1; break;
201      default: break;
202   }
203
145204   // Which source is being used?
146   //UINT64* sourceReg = NULL;
147   //switch (S)
148   //{
149   //  case 0x00: sourceReg = &m_a0;
150   //  case 0x01: sourceReg = &m_a1;
151   //  default: break;
152   //}
205   UINT64* sourceReg = NULL;
206   switch (S)
207   {
208      case 0x00: sourceReg = &m_a0; break;
209      case 0x01: sourceReg = &m_a1; break;
210      default: break;
211   }
153212
213
214   // We must compute into an intermediate variable to compute flags on
215   UINT64 result = 0;
216   bool justATest = false;
217
154218   switch (F1)
155219   {
156      case 0x00: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
157      case 0x01: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
158      case 0x02: m_p = (INT32)((INT16)m_x * (INT16)((m_y & 0xffff0000) >> 16)); break;
159      case 0x03: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
160      case 0x04: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
161      case 0x05: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
162      case 0x06: /* nop */ break;
163      case 0x07: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
164      case 0x08: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
165      case 0x09: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
166      case 0x0a: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
167      case 0x0b: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
168      case 0x0c: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
169      case 0x0d: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
170      case 0x0e: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
171      case 0x0f: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
220      case 0x00:
221      {
222         // Ad = p   p = x*y
223         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
224         break;
225      }
226      case 0x01:
227      {
228         // Ad = aS+p   p = x*y
229         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
230         break;
231      }
232      case 0x02:
233      {
234         // p = x*y
235         // TODO: What happens to the flags in this operation?
236         const INT16 y = (m_y & 0xffff0000) >> 16;
237         m_p = (INT32)((INT16)m_x * y);
238         justATest = true;
239         break;
240      }
241      case 0x03:
242      {
243         // Ad = aS-p   p = x*y
244         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
245         break;
246      }
247      case 0x04:
248      {
249         // Ad = p
250         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
251         break;
252      }
253      case 0x05:
254      {
255         // Ad = aS+p
256         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
257         break;
258      }
259      case 0x06:
260      {
261         // nop
262         justATest = true;
263         break;
264      }
265      case 0x07:
266      {
267         // Ad = aS-p
268         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
269         break;
270      }
271      case 0x08:
272      {
273         // Ad = aS|y
274         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
275         break;
276      }
277      case 0x09:
278      {
279         // Ad = aS^y
280         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
281         break;
282      }
283      case 0x0a:
284      {
285         // aS&y
286         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
287         justATest = true;
288         break;
289      }
290      case 0x0b:
291      {
292         // aS-y
293         INT64 aS = *sourceReg;
294         if (aS & U64(0x800000000))
295            aS |= U64(0xfffffff000000000);
296         
297         INT64 y  = (m_y & 0xffff0000) >> 16;
298         if (y & 0x8000)
299            y |= U64(0xffffffffffff0000);
300         
301         result = aS-y;
302         justATest = true;
303         break;
304      }
305      case 0x0c:
306      {
307         // Ad = y
308         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
309         break;
310      }
311      case 0x0d:
312      {
313         // Ad = aS+y
314         INT64 aS = *sourceReg;
315         if (aS & U64(0x800000000))
316            aS |= U64(0xfffffff000000000);
317         
318         INT64 y  = (m_y & 0xffff0000) >> 16;
319         if (y & 0x8000)
320            y |= U64(0xffffffffffff0000);
321         
322         result = aS+y;
323         break;
324      }
325      case 0x0e:
326      {
327         // Ad = aS&y
328         printf("UNIMPLEMENTED F1 operation @ PC 0x%04x (%d)\n", m_pc, __LINE__);
329         break;
330      }
331      case 0x0f:
332      {
333         // Ad = aS-y
334         INT64 aS = *sourceReg;
335         if (aS & U64(0x800000000))
336            aS |= U64(0xfffffff000000000);
337         
338         INT64 y  = (m_y & 0xffff0000) >> 16;
339         if (y & 0x8000)
340            y |= U64(0xffffffffffff0000);
341         
342         result = aS-y;
343         break;
344      }
172345   }
346   
347   // CPU Flags  (page 3-4)
348   // LMI (logical minus)
349   if (result & U64(0x800000000))
350      m_psw |= 0x8000;
351   else
352      m_psw &= (~0x8000);
353
354   // LEQ (logical equal)
355   if (result == U64(0x000000000))
356      m_psw |= 0x4000;
357   else
358      m_psw &= (~0x4000);
359
360   // LLV (logical overflow)
361   // TODO
362   
363   // LMV (mathematical overflow)
364   if ((result | U64(0xf00000000)) != U64(0xf00000000) &&
365      (result | U64(0xf00000000)) != U64(0x000000000))
366      m_psw |= 0x1000;
367   else
368      m_psw &= (~0x1000);
369
370   // If it was a real operation, make sure the data goes where it should
371   if (!justATest)
372       *destinationReg = (UINT64)result & U64(0x0000000fffffffff);
173373}
174374
175375
176void* dsp16_device::registerFromYFieldUpper(const UINT8& Y)
376UINT16* dsp16_device::registerFromYFieldUpper(const UINT8& Y)
177377{
178378   UINT16* destinationReg = NULL;
179379   const UINT8 N = (Y & 0x0c) >> 2;
r23953r23954
191391
192392void dsp16_device::executeYFieldPost(const UINT8& Y)
193393{
194   UINT16* opReg = NULL;
195   const UINT8 N = (Y & 0x0c) >> 2;
196   switch (N)
197   {
198      case 0x00: opReg = &m_r0; break;
199      case 0x01: opReg = &m_r1; break;
200      case 0x02: opReg = &m_r2; break;
201      case 0x03: opReg = &m_r3; break;
202      default: break;
203   }
394   UINT16* opReg = registerFromYFieldUpper(Y);
204395
205396   const UINT8 lower = Y & 0x03;
206397   switch (lower)
r23953r23954
208399      case 0x00: /* nop */ break;
209400      case 0x01: (*opReg)++; break;
210401      case 0x02: (*opReg)--; break;
211      case 0x03: (*opReg) += m_j; break;
402      case 0x03: (*opReg) += m_j; break;  // TODO: J is signed
212403   }
213404}
214405
r23953r23954
221412      case 0x00: /* nop */ break;
222413      case 0x01: (*rN)++; break;
223414      case 0x02: (*rN)--; break;
224      case 0x03: (*rN) += m_j; break;
415      case 0x03: (*rN) += m_j; break;  // TODO: J is signed
225416   }
226417}
227418
r23953r23954
234425      case 0x00: (*rN)++; break;
235426      case 0x01: /* nop */   break;
236427      case 0x02: (*rN) += 2; break;
237      case 0x03: (*rN) += m_k; break;
428      case 0x03: (*rN) += m_k; break;  // TODO: K is signed
238429   }
239430}
240431
r23953r23954
244435   cycles = 1;
245436   pcAdvance = 0;
246437
438// NOTE: pages 3-5 through 3-19 are good english descriptions of what's up
439
247440   const UINT8 opcode = (op >> 11) & 0x1f;
248441   switch(opcode)
249442   {
250443      // Format 1: Multiply/ALU Read/Write Group
251444      case 0x06:
252445      {
446         DSP_LINE("3-38")
253447         // F1, Y  :  (page 3-38)
254448         const UINT8 Y = (op & 0x000f);
255449         const UINT8 S = (op & 0x0200) >> 9;
r23953r23954
263457      }
264458      case 0x04: case 0x1c:
265459      {
460         DSP_LINE("3-40")
266461         // F1 Y=a0[1] | F1 Y=a1[1]  :  (page 3-40)
267462         const UINT8 Y = (op & 0x000f);
268         const UINT8 X = (op & 0x0010) >> 4;
463         //const UINT8 X = (op & 0x0010) >> 4;
269464         const UINT8 S = (op & 0x0200) >> 9;
270465         const UINT8 D = (op & 0x0400) >> 10;
271466         const UINT8 F1 = (op & 0x01e0) >> 5;
272         UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
467         UINT16* destinationReg = registerFromYFieldUpper(Y);
468         // (page 3-18)
273469         UINT16 aRegValue = 0x0000;
274470         if (op & 0xc000)
275471         {
276            aRegValue = (X) ? (m_a0 & 0x0ffff0000) >> 16 : m_a0 & 0x00000ffff;
472            aRegValue = (m_a0 & U64(0x0ffff0000)) >> 16;
277473         }
278474         else
279475         {
280            aRegValue = (X) ? (m_a1 & 0x0ffff0000) >> 16 : m_a1 & 0x00000ffff;
476            aRegValue = (m_a1 & U64(0x0ffff0000)) >> 16;
281477         }
282478         data_write(*destinationReg, aRegValue);
283479         executeYFieldPost(Y);
r23953r23954
288484      }
289485      case 0x16:
290486      {
487         DSP_LINE("3-42")
291488         // F1, x = Y  :  (page 3-42)
292489         const UINT8 Y = (op & 0x000f);
293490         const UINT8 S = (op & 0x0200) >> 9;
294491         const UINT8 D = (op & 0x0400) >> 10;
295492         const UINT8 F1 = (op & 0x01e0) >> 5;
296493         executeF1Field(F1, D, S);
297         UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y);
494         UINT16* sourceReg = registerFromYFieldUpper(Y);
298495         writeRegister(&m_x, data_read(*sourceReg));
299496         executeYFieldPost(Y);
300497         cycles = 1;
r23953r23954
303500      }
304501      case 0x17:
305502      {
503         DSP_LINE("3-44")
306504         // F1, y[l] = Y  :  (page 3-44)
307505         const UINT8 Y = (op & 0x000f);
308506         const UINT8 X = (op & 0x0010) >> 4;
r23953r23954
310508         const UINT8 D = (op & 0x0400) >> 10;
311509         const UINT8 F1 = (op & 0x01e0) >> 5;
312510         executeF1Field(F1, D, S);
313         UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y);
511         UINT16* sourceReg = registerFromYFieldUpper(Y);
314512         UINT16 sourceValue = data_read(*sourceReg);
315513         switch (X)
316514         {
r23953r23954
325523      }
326524      case 0x1f:
327525      {
526         DSP_LINE("3-46")
328527         // F1, y = Y, x = *pt++[i]  :  (page 3-46)
329528         const UINT8 Y = (op & 0x000f);
330529         const UINT8 X = (op & 0x0010) >> 4;
r23953r23954
332531         const UINT8 D = (op & 0x0400) >> 10;
333532         const UINT8 F1 = (op & 0x01e0) >> 5;
334533         executeF1Field(F1, D, S);
335         UINT16* sourceRegR = (UINT16*)registerFromYFieldUpper(Y);
534         UINT16* sourceRegR = registerFromYFieldUpper(Y);
336535         writeRegister(&m_y, data_read(*sourceRegR));
337536         executeYFieldPost(Y);
338537         writeRegister(&m_x, data_read(m_pt));
r23953r23954
347546      }
348547      case 0x19: case 0x1b:
349548      {
549         DSP_LINE("3-48")
350550         // F1, y = a0|1, x = *pt++[i]  :  (page 3-48)
351551         const UINT8 Y = (op & 0x000f);
352552         const UINT8 X = (op & 0x0010) >> 4;
r23953r23954
369569      }
370570      case 0x14:
371571      {
372         // F1, Y = y[1]  :  (page 3-53)
572         DSP_LINE("3-53")
573         // F1, Y = y[l]  :  (page 3-53)
373574         const UINT8 Y = (op & 0x000f);
374575         const UINT8 X = (op & 0x0010) >> 4;
375576         const UINT8 S = (op & 0x0200) >> 9;
376577         const UINT8 D = (op & 0x0400) >> 10;
377578         const UINT8 F1 = (op & 0x01e0) >> 5;
378579         executeF1Field(F1, D, S);
379         UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
580         UINT16* destinationReg = registerFromYFieldUpper(Y);
380581         UINT16 yRegValue = 0x0000;
381582         switch (X)
382583         {
r23953r23954
394595      // Format 1a: Multiply/ALU Read/Write Group (TODO: Figure out major typo in docs on p3-51)
395596      case 0x07:
396597      {
598         DSP_LINE("3-50")
397599         // F1, At[1] = Y  :  (page 3-50)
600         // TODO: What does the X field do here, exactly?
398601         const UINT8 Y = (op & 0x000f);
399602         const UINT8 S = (op & 0x0200) >> 9;
400603         const UINT8 aT = (op & 0x0400) >> 10;
r23953r23954
407610            case 1: destinationReg = &m_a0; break;
408611            default: break;
409612         }
410         UINT16 sourceAddress = *((UINT16*)registerFromYFieldUpper(Y));
613         UINT16 sourceAddress = *(registerFromYFieldUpper(Y));
411614         INT64 sourceValueSigned = (INT16)data_read(sourceAddress);
412615         *destinationReg = sourceValueSigned & U64(0xffffffffff);
413616         executeYFieldPost(Y);
r23953r23954
419622      // Format 2: Multiply/ALU Read/Write Group
420623      case 0x15:
421624      {
422         // F1, Z : y[1]  :  (page 3-54)
625         DSP_LINE("3-54")
626         // F1, Z : y[l]  :  (page 3-54)
423627         const UINT8 Z = (op & 0x000f);
424628         const UINT8 X = (op & 0x0010) >> 4;
425629         const UINT8 S = (op & 0x0200) >> 9;
r23953r23954
427631         const UINT8 F1 = (op & 0x01e0) >> 5;
428632         executeF1Field(F1, D, S);
429633         UINT16 temp = 0x0000;
430         UINT16* rN = (UINT16*)registerFromYFieldUpper(Z);
634         UINT16* rN = registerFromYFieldUpper(Z);
431635         switch (X)
432636         {
433637            case 0x00:
r23953r23954
453657      }
454658      case 0x1d:
455659      {
660         DSP_LINE("?")
456661         // F1, Z : y, x=*pt++[i]
457662         //const UINT8 Z = (op & 0x000f);
458663         //const UINT8 X = (op & 0x0010) >> 4;
r23953r23954
465670      // Format 2a: Multiply/ALU Read/Write Group
466671      case 0x05:
467672      {
673         DSP_LINE("?")
468674         // F1, Z : aT[1]
469675         //const UINT8 Z = (op & 0x000f);
470676         //const UINT8 X = (op & 0x0010) >> 4;
r23953r23954
478684      case 0x12:
479685      case 0x13:
480686      {
481         // if|ifc CON F2
687         DSP_LINE("3-36")
688         // if|ifc CON F2  (page 3-36)
482689         const UINT8 CON = (op & 0x001f);
483690         //const UINT8 S = (op & 0x0200) >> 9;
484691         //const UINT8 D = (op & 0x0400) >> 10;
r23953r23954
486693         bool conditionFulfilled = conditionTest(CON);
487694         if (conditionFulfilled)
488695         {
489            printf("Fulfilled condition not yet implemented @ PC=0x%04x", m_pc);
696            printf("Fulfilled condition not yet implemented @ PC=0x%04x\n", m_pc);
490697         }
491698         cycles = 1;
492699         pcAdvance = 1;
r23953r23954
496703      // Format 4: Branch Direct Group
497704      case 0x00: case 0x01:
498705      {
499         // goto JA  :  (page 3-20)
706         DSP_LINE("3-20")
707         // goto JA  :  (page 3-20) (DONE)
500708         const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
501709         m_pc = JA;
502710         cycles = 2;
r23953r23954
506714
507715      case 0x10: case 0x11:
508716      {
717         DSP_LINE("3-23")
509718         // call JA  :  (page 3-23)
510719         const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
511720         m_pr = m_pc + 1;
r23953r23954
518727      // Format 5: Branch Indirect Group
519728      case 0x18:
520729      {
730         DSP_LINE("3-21")
521731         // goto B  :  (page 3-21)
522732         const UINT8 B = (op & 0x0700) >> 8;
523733         switch (B)
r23953r23954
536746      // Format 6: Contitional Branch Qualifier/Software Interrupt (icall)
537747      case 0x1a:
538748      {
749         DSP_LINE("3-22")
539750         // if CON [goto/call/return]  :  (page 3-22)
540751         const UINT8 CON = (op & 0x001f);
541752         bool conditionFulfilled = conditionTest(CON);
r23953r23954
551762      // Format 7: Data Move Group
552763      case 0x09: case 0x0b:
553764      {
765         DSP_LINE("3-29")
766         // R = aS  :  (page 3-29)
554767         // TODO: Fix register pdxX (pc=338)
555         // R = aS  :  (page 3-29)
556768         const UINT8 R = (op & 0x03f0) >> 4;
557769         const UINT8 S = (op & 0x1000) >> 12;
558770         void* destinationReg = registerFromRTable(R);
r23953r23954
565777      }
566778      case 0x08:
567779      {
780         DSP_LINE("3-30")
568781         // aT = R  :  (page 3-30)
569782         const UINT8 R  = (op & 0x03f0) >> 4;
570783         const UINT8 aT = (op & 0x0400) >> 10;
r23953r23954
587800      }
588801      case 0x0f:
589802      {
803         DSP_LINE("3-32")
590804         // R = Y  :  (page 3-32)
591805         const UINT8 Y = (op & 0x000f);
592806         const UINT8 R = (op & 0x03f0) >> 4;
593         UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y);
807         UINT16* sourceReg = registerFromYFieldUpper(Y);
594808         void* destinationReg = registerFromRTable(R);
595809         writeRegister(destinationReg, data_read(*sourceReg));
596810         executeYFieldPost(Y);
r23953r23954
600814      }
601815      case 0x0c:
602816      {
817         DSP_LINE("3-33")
603818         // Y = R  :  (page 3-33)
819         // TODO: Zero & Sign extend i, c0, c1, c2, and auc
604820         const UINT8 Y = (op & 0x000f);
605821         const UINT8 R = (op & 0x03f0) >> 4;
606         UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
607         UINT16* sourceReg = (UINT16*)registerFromRTable(R);
608         data_write(*destinationReg, *sourceReg);
822         UINT16* destinationReg = registerFromYFieldUpper(Y);
823         UINT16* sourceReg = (UINT16*)registerFromRTable(R);     // TODO: This won't work for certain registers!
824         data_write(*destinationReg, *sourceReg);                //       Fix in data_write() maybe?
609825         executeYFieldPost(Y);
610826         cycles = 2;
611827         pcAdvance = 1;
r23953r23954
613829      }
614830      case 0x0d:
615831      {
832         DSP_LINE("?")
616833         // Z : R
617834         //const UINT8 Z = (op & 0x000f);
618835         //const UINT8 R = (op & 0x03f0) >> 4;
r23953r23954
622839      // Format 8: Data Move (immediate operand - 2 words)
623840      case 0x0a:
624841      {
625         // R = N  :  (page 3-28)
842         DSP_LINE("3-28")
843         // R = N  :  (page 3-28) (DONE)
844         // NOTE: The docs speak of register sources & sign extension, but this is a register
845         // destination, so, typo?  If so, what does one do with the overflow bits?
626846         const UINT8 R = (op & 0x03f0) >> 4;
627847         const UINT16 iVal = opcode_read(1);
628         void* reg = registerFromRTable(R);
629         writeRegister(reg, iVal);
848         void* destinationReg = registerFromRTable(R);
849         writeRegister(destinationReg, iVal);
630850         cycles = 2;
631851         pcAdvance = 2;
632852         break;
r23953r23954
635855      // Format 9: Short Immediate Group
636856      case 0x02: case 0x03:
637857      {
858         DSP_LINE("3-27")
638859         // R = M  :  (page 3-27)
639         const INT8 M = (op & 0x00ff);
640         const UINT8 R = (op & 0x0e00) >> 9;
641         void* reg = registerFromRImmediateField(R);
642         writeRegister(reg, (INT16)M);   // Sign extend 8 bit int
860         // TODO: Figure out notes about the DSP16A vs the DSP16.  9 bit is very DSP16...
861         const UINT16 M = (op & 0x01ff);
862         const UINT8  R = (op & 0x0e00) >> 9;
863         void* destinationReg = registerFromRImmediateField(R);
864         // Sign extend if the destination is j or k
865         UINT16 mValue = M;
866         if (destinationReg == &m_j || destinationReg == &m_k)
867         {
868            if (mValue & 0x0100) mValue |= 0xfe00;
869         }
870         writeRegister(destinationReg, mValue);
643871         cycles = 1;
644872         pcAdvance = 1;
645873         break;
r23953r23954
648876      // Format 10: do - redo
649877      case 0x0e:
650878      {
879         DSP_LINE("3-25/3-26")
651880         // do|redo K  :  (pages 3-25 & 3-26)
881         // TODO: The timings are intricate to say the least...
652882         const UINT8 K = (op & 0x007f);
653883         const UINT8 NI = (op & 0x0780) >> 7;
654884         if (NI != 0)
655885         {
656886            // Do
657887            m_cacheStart = m_pc + 1;
658            m_cacheEnd = m_pc + NI + 1;
888            m_cacheEnd   = m_pc + 1 + NI;
659889            m_cacheIterations = K-1;    // -1 because we check the counter @ the end
660890            cycles = 1;
661891            pcAdvance = 1;
r23953r23954
666896            m_cacheIterations = K-1;    // -1 because we check the counter @ the end
667897            m_cacheRedoNextPC = m_pc + 1;
668898            m_pc = m_cacheStart;
899            cycles = 2;
669900            pcAdvance = 0;
670            cycles = 2;
671            pcAdvance = 1;
672901         }
673902         break;
674903      }
r23953r23954
676905      // RESERVED
677906      case 0x1e:
678907      {
908         DSP_LINE("XXX")
679909         break;
680910      }
681911
682912      // UNKNOWN
683913      default:
684914      {
915         DSP_LINE("XXX")
685916         break;
686917      }
687918   }
trunk/src/emu/cpu/dsp16/dsp16.h
r23953r23954
5454   const address_space_config m_data_config;
5555
5656   // CPU registers
57   // ROM Address Arithmetic Unit (XAAU)
57   // ROM Address Arithmetic Unit (XAAU)  (page 2-4)
5858   UINT16 m_i;     // 12 bits
5959   UINT16 m_pc;
6060   UINT16 m_pt;
6161   UINT16 m_pr;
6262   UINT16 m_pi;
63   // RAM Address Arithmetic Unit (YAAU)
64   UINT16 m_j;
65   UINT16 m_k;
63   
64   // RAM Address Arithmetic Unit (YAAU)  (page 2-6)
65   UINT16 m_j;     // Signed
66   UINT16 m_k;     // Signed
6667   UINT16 m_rb;
6768   UINT16 m_re;
6869   UINT16 m_r0;
6970   UINT16 m_r1;
7071   UINT16 m_r2;
7172   UINT16 m_r3;
72   // Data Arithmetic Unit (DAU)
73   
74    // Data Arithmetic Unit (DAU)  (page 2-6)
7375   UINT16 m_x;
7476   UINT32 m_y;
7577   UINT32 m_p;
r23953r23954
8082   UINT8 m_c0;
8183   UINT8 m_c1;
8284   UINT8 m_c2;
83   // Serial and parallel interfaces
85   
86    // Serial and parallel interfaces (TODO: More here  (page 2-13))
8487   UINT16 m_sioc;
8588   UINT16 m_srta;
8689   UINT16 m_sdx;
8790   UINT16 m_pioc;
8891   UINT16 m_pdx0;  // pdx0 & pdx1 refer to the same physical register (page 6-1)
89   UINT16 m_pdx1;  //   but we keep them seperate for logic's sake.
92   UINT16 m_pdx1;  // but we keep them seperate for logic's sake.
9093
9194   // internal stuff
9295   UINT16 m_ppc;
9396
94   // This core handles the cache as more of a loop than 15 seperate memory elements.
95   // It's a bit of a hack, but it's easier this way.
97   // This CPU core handles the cache as more of a loop than 15 seperate memory elements.
98   // It's a bit of a hack, but it's easier this way (for now).
9699   UINT16 m_cacheStart;
97100   UINT16 m_cacheEnd;
98101   UINT16 m_cacheRedoNextPC;
r23953r23954
118121   // table decoders
119122   void* registerFromRImmediateField(const UINT8& R);
120123   void* registerFromRTable(const UINT8& R);
121   void* registerFromYFieldUpper(const UINT8& Y);
124   UINT16* registerFromYFieldUpper(const UINT8& Y);
122125
123126   // execution
124127   void executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S);
r23953r23954
130133   void* addressYL();
131134   void writeRegister(void* reg, const UINT16& value);
132135   bool conditionTest(const UINT8& CON);
136   
137   // flags
138   bool lmi();
139   bool leq();
140    bool llv();
141    bool lmv();
133142};
134143
135144

Previous 199869 Revisions Next


© 1997-2024 The MAME Team