Previous 199869 Revisions Next

r26795 Saturday 28th December, 2013 at 20:53:14 UTC by Wilbert Pol
scmp.c: Modernized cpu core.  [Wilbert Pol]
[src/emu/cpu/scmp]scmp.c scmp.h

trunk/src/emu/cpu/scmp/scmp.c
r26794r26795
1616
1717#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
1818
19/***************************************************************************
20    TYPE DEFINITIONS
21***************************************************************************/
2219
23struct scmp_state
20const device_type SCMP = &device_creator<scmp_device>;
21const device_type INS8060 = &device_creator<ins8060_device>;
22
23
24scmp_device::scmp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
25   : cpu_device(mconfig, SCMP, "INS 8050 SC/MP", tag, owner, clock, "ins8050", __FILE__)
26   , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
27   , m_flag_out_func(*this)
28   , m_sout_func(*this)
29   , m_sin_func(*this)
30   , m_sensea_func(*this)
31   , m_senseb_func(*this)
32   , m_halt_func(*this)
2433{
25   scmp_config         config;
26   PAIR    PC;
27   PAIR    P1;
28   PAIR    P2;
29   PAIR    P3;
30   UINT8   AC;
31   UINT8   ER;
32   UINT8   SR;
34}
3335
34   legacy_cpu_device *device;
35   address_space *program;
36   direct_read_data *direct;
37   address_space *io;
38   int                 icount;
3936
40   devcb_resolved_write8       flag_out_func;
41   devcb_resolved_write_line   sout_func;
42   devcb_resolved_read_line    sin_func;
43   devcb_resolved_read_line    sensea_func;
44   devcb_resolved_read_line    senseb_func;
45   devcb_resolved_write_line   halt_func;
46};
37scmp_device::scmp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
38   : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
39   , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
40   , m_flag_out_func(*this)
41   , m_sout_func(*this)
42   , m_sin_func(*this)
43   , m_sensea_func(*this)
44   , m_senseb_func(*this)
45   , m_halt_func(*this)
46{
47}
4748
48/***************************************************************************
49    MACROS
50***************************************************************************/
5149
52/***************************************************************************
53    INLINE FUNCTIONS
54***************************************************************************/
50ins8060_device::ins8060_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
51   : scmp_device(mconfig, INS8060, "INS 8060 SC/MP II", tag, owner, clock, "ins8060", __FILE__)
52{
53}
5554
56INLINE scmp_state *get_safe_token(device_t *device)
55
56offs_t scmp_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
5757{
58   assert(device != NULL);
59   assert(device->type() == SCMP || device->type() == INS8060);
60   return (scmp_state *)downcast<legacy_cpu_device *>(device)->token();
58   extern CPU_DISASSEMBLE( scmp );
59   return CPU_DISASSEMBLE_NAME(scmp)(this, buffer, pc, oprom, opram, options);
6160}
6261
63INLINE UINT16 ADD12(UINT16 addr, INT8 val)
62
63UINT16 scmp_device::ADD12(UINT16 addr, INT8 val)
6464{
6565   return ((addr + val) & 0x0fff) | (addr & 0xf000);
6666}
6767
68INLINE UINT8 ROP(scmp_state *cpustate)
68UINT8 scmp_device::ROP()
6969{
70   UINT16 pc = cpustate->PC.w.l;
71   cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1);
72   return cpustate->direct->read_decrypted_byte( pc);
70   UINT16 pc = m_PC.w.l;
71   m_PC.w.l = ADD12(m_PC.w.l,1);
72   return m_direct->read_decrypted_byte( pc);
7373}
7474
75INLINE UINT8 ARG(scmp_state *cpustate)
75UINT8 scmp_device::ARG()
7676{
77   UINT16 pc = cpustate->PC.w.l;
78   cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1);
79   return cpustate->direct->read_raw_byte(pc);
77   UINT16 pc = m_PC.w.l;
78   m_PC.w.l = ADD12(m_PC.w.l,1);
79   return m_direct->read_raw_byte(pc);
8080}
8181
82INLINE UINT8 RM(scmp_state *cpustate,UINT32 a)
82UINT8 scmp_device::RM(UINT32 a)
8383{
84   return cpustate->program->read_byte(a);
84   return m_program->read_byte(a);
8585}
8686
87INLINE void WM(scmp_state *cpustate,UINT32 a, UINT8 v)
87void scmp_device::WM(UINT32 a, UINT8 v)
8888{
89   cpustate->program->write_byte(a, v);
89   m_program->write_byte(a, v);
9090}
9191
92INLINE void illegal(scmp_state *cpustate,UINT8 opcode)
92void scmp_device::illegal(UINT8 opcode)
9393{
9494#if VERBOSE
95   UINT16 pc = cpustate->PC.w.l;
95   UINT16 pc = m_PC.w.l;
9696   LOG(("SC/MP illegal instruction %04X $%02X\n", pc-1, opcode));
9797#endif
9898}
9999
100INLINE PAIR *GET_PTR_REG(scmp_state *cpustate, int num)
100PAIR *scmp_device::GET_PTR_REG(int num)
101101{
102102   switch(num) {
103      case 1: return &cpustate->P1;
104      case 2: return &cpustate->P2;
105      case 3: return &cpustate->P3;
103      case 1: return &m_P1;
104      case 2: return &m_P2;
105      case 3: return &m_P3;
106106      default :
107            return &cpustate->PC;
107            return &m_PC;
108108   }
109109}
110110
111INLINE void BIN_ADD(scmp_state *cpustate, UINT8 val)
111void scmp_device::BIN_ADD(UINT8 val)
112112{
113   UINT16 tmp = cpustate->AC + val + ((cpustate->SR >> 7) & 1);
114   UINT8 ov = (((cpustate->AC & 0x80)==(val & 0x80)) && ((cpustate->AC & 0x80)!=(tmp & 0x80))) ? 0x40 : 0x00;
113   UINT16 tmp = m_AC + val + ((m_SR >> 7) & 1);
114   UINT8 ov = (((m_AC & 0x80)==(val & 0x80)) && ((m_AC & 0x80)!=(tmp & 0x80))) ? 0x40 : 0x00;
115115
116   cpustate->AC = tmp & 0xff;
117   cpustate->SR &= 0x3f; // clear CY/L and OV flag
118   cpustate->SR |= (tmp & 0x100) ? 0x80 : 0x00; // set CY/L
119   cpustate->SR |= ov;
116   m_AC = tmp & 0xff;
117   m_SR &= 0x3f; // clear CY/L and OV flag
118   m_SR |= (tmp & 0x100) ? 0x80 : 0x00; // set CY/L
119   m_SR |= ov;
120120}
121121
122INLINE void DEC_ADD(scmp_state *cpustate, UINT8 val)
122void scmp_device::DEC_ADD(UINT8 val)
123123{
124   UINT16 tmp = cpustate->AC + val + ((cpustate->SR >> 7) & 1);
124   UINT16 tmp = m_AC + val + ((m_SR >> 7) & 1);
125125   if ((tmp & 0x0f) > 9) tmp +=6;
126   cpustate->AC = tmp % 0xa0;
127   cpustate->SR &= 0x7f; // clear CY/L flag
128   cpustate->SR |= (tmp > 0x99) ? 0x80 : 0x00;
126   m_AC = tmp % 0xa0;
127   m_SR &= 0x7f; // clear CY/L flag
128   m_SR |= (tmp > 0x99) ? 0x80 : 0x00;
129129}
130130
131INLINE UINT16 GET_ADDR(scmp_state *cpustate, UINT8 code)
131UINT16 scmp_device::GET_ADDR(UINT8 code)
132132{
133133   UINT16 addr = 0;
134134   INT8 offset = 0;
135135   UINT16 retVal = 0;
136   UINT16 ptr = GET_PTR_REG(cpustate,code & 0x03)->w.l;
136   UINT16 ptr = GET_PTR_REG(code & 0x03)->w.l;
137137
138   UINT8 arg = ARG(cpustate);
138   UINT8 arg = ARG();
139139   if (arg == 0x80) {
140      offset = cpustate->ER;
140      offset = m_ER;
141141   } else {
142142      if (arg & 0x80) {
143143         offset = (INT8)arg;
r26794r26795
153153         // Auto-indexed
154154         if (offset < 0) {
155155            // pre decrement
156            GET_PTR_REG(cpustate,code & 0x03)->w.l = addr;
156            GET_PTR_REG(code & 0x03)->w.l = addr;
157157            retVal = addr;
158158         } else {
159159            // post increment
160160            retVal = ptr;
161            GET_PTR_REG(cpustate,code & 0x03)->w.l = addr;
161            GET_PTR_REG(code & 0x03)->w.l = addr;
162162         }
163163      } else {
164164         // Immediate
r26794r26795
170170   return retVal;
171171}
172172
173static void execute_one(scmp_state *cpustate, int opcode)
173void scmp_device::execute_one(int opcode)
174174{
175175   UINT8 tmp;
176176   UINT8 ptr = opcode & 3;
r26794r26795
182182         case 0xc0 : case 0xc1 : case 0xc2 : case 0xc3 :
183183         case 0xc5 : case 0xc6 : case 0xc7 :
184184                  //LD
185                  cpustate->icount -= 18;
186                  cpustate->AC = RM(cpustate,GET_ADDR(cpustate,opcode));
185                  m_icount -= 18;
186                  m_AC = RM(GET_ADDR(opcode));
187187                  break;
188188         case 0xc8 : case 0xc9 : case 0xca : case 0xcb :
189189         case 0xcd : case 0xce : case 0xcf :
190190                  // ST
191                  cpustate->icount -= 18;
192                  WM(cpustate,GET_ADDR(cpustate,opcode),cpustate->AC);
191                  m_icount -= 18;
192                  WM(GET_ADDR(opcode),m_AC);
193193                  break;
194194         case 0xd0 : case 0xd1 : case 0xd2 : case 0xd3 :
195195                  case 0xd5 : case 0xd6 : case 0xd7 :
196196                  // AND
197                  cpustate->icount -= 18;
198                  cpustate->AC &= RM(cpustate,GET_ADDR(cpustate,opcode));
197                  m_icount -= 18;
198                  m_AC &= RM(GET_ADDR(opcode));
199199                  break;
200200         case 0xd8 : case 0xd9 : case 0xda : case 0xdb :
201201                  case 0xdd : case 0xde : case 0xdf :
202202                  //OR
203                  cpustate->icount -= 18;
204                  cpustate->AC |= RM(cpustate,GET_ADDR(cpustate,opcode));
203                  m_icount -= 18;
204                  m_AC |= RM(GET_ADDR(opcode));
205205                  break;
206206         case 0xe0 : case 0xe1 : case 0xe2 : case 0xe3 :
207207                  case 0xe5 : case 0xe6 : case 0xe7 :
208208                  // XOR
209                  cpustate->icount -= 18;
210                  cpustate->AC ^= RM(cpustate,GET_ADDR(cpustate,opcode));
209                  m_icount -= 18;
210                  m_AC ^= RM(GET_ADDR(opcode));
211211                  break;
212212         case 0xe8 : case 0xe9 : case 0xea : case 0xeb :
213213                  case 0xed : case 0xee : case 0xef :
214214                  // DAD
215                  cpustate->icount -= 23;
216                  DEC_ADD(cpustate,RM(cpustate,GET_ADDR(cpustate,opcode)));
215                  m_icount -= 23;
216                  DEC_ADD(RM(GET_ADDR(opcode)));
217217                  break;
218218         case 0xf0 : case 0xf1 : case 0xf2 : case 0xf3 :
219219                  case 0xf5 : case 0xf6 : case 0xf7 :
220220                  // ADD
221                  cpustate->icount -= 19;
222                  BIN_ADD(cpustate,RM(cpustate,GET_ADDR(cpustate,opcode)));
221                  m_icount -= 19;
222                  BIN_ADD(RM(GET_ADDR(opcode)));
223223                  break;
224224         case 0xf8 : case 0xf9 : case 0xfa : case 0xfb :
225225                  case 0xfd : case 0xfe : case 0xff :
226226                  // CAD
227                  cpustate->icount -= 20;
228                  BIN_ADD(cpustate,~RM(cpustate,GET_ADDR(cpustate,opcode)));
227                  m_icount -= 20;
228                  BIN_ADD(~RM(GET_ADDR(opcode)));
229229                  break;
230230         // Memory Increment/Decrement Instructions
231231         case 0xa8 : case 0xa9 : case 0xaa : case 0xab :
232232                  // IDL
233233                  {
234                     UINT16 addr = GET_ADDR(cpustate,opcode);
235                     cpustate->icount -= 22;
236                     cpustate->AC = RM(cpustate,addr) + 1;
237                     WM(cpustate,addr,cpustate->AC);
234                     UINT16 addr = GET_ADDR(opcode);
235                     m_icount -= 22;
236                     m_AC = RM(addr) + 1;
237                     WM(addr,m_AC);
238238                  }
239239                  break;
240240         case 0xb8 : case 0xb9 : case 0xba : case 0xbb :
241241                  // DLD
242242                  {
243                     UINT16 addr = GET_ADDR(cpustate,opcode);
244                     cpustate->icount -= 22;
245                     cpustate->AC = RM(cpustate,addr) - 1;
246                     WM(cpustate,addr,cpustate->AC);
243                     UINT16 addr = GET_ADDR(opcode);
244                     m_icount -= 22;
245                     m_AC = RM(addr) - 1;
246                     WM(addr,m_AC);
247247                  }
248248                  break;
249249         // Immediate Instructions
250250         case 0xc4 : // LDI
251                  cpustate->icount -= 10;
252                  cpustate->AC = ARG(cpustate);
251                  m_icount -= 10;
252                  m_AC = ARG();
253253                  break;
254254         case 0xd4 : // ANI
255                  cpustate->icount -= 10;
256                  cpustate->AC &= ARG(cpustate);
255                  m_icount -= 10;
256                  m_AC &= ARG();
257257                  break;
258258         case 0xdc : // ORI
259                  cpustate->icount -= 10;
260                  cpustate->AC |= ARG(cpustate);
259                  m_icount -= 10;
260                  m_AC |= ARG();
261261                  break;
262262         case 0xe4 : // XRI
263                  cpustate->icount -= 10;
264                  cpustate->AC ^= ARG(cpustate);
263                  m_icount -= 10;
264                  m_AC ^= ARG();
265265                  break;
266266         case 0xec : // DAI
267                  cpustate->icount -= 15;
268                  DEC_ADD(cpustate,ARG(cpustate));
267                  m_icount -= 15;
268                  DEC_ADD(ARG());
269269                  break;
270270         case 0xf4 : // ADI
271                  cpustate->icount -= 11;
272                  BIN_ADD(cpustate,ARG(cpustate));
271                  m_icount -= 11;
272                  BIN_ADD(ARG());
273273                  break;
274274         case 0xfc : // CAI
275                  cpustate->icount -= 12;
276                  BIN_ADD(cpustate,~ARG(cpustate));
275                  m_icount -= 12;
276                  BIN_ADD(~ARG());
277277                  break;
278278         // Transfer Instructions
279279         case 0x90 : case 0x91 : case 0x92 : case 0x93 :// JMP
280                  cpustate->icount -= 11;
281                  cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)ARG(cpustate));
280                  m_icount -= 11;
281                  m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)ARG());
282282                  break;
283283         case 0x94 : case 0x95 : case 0x96 : case 0x97 :
284284                  // JP
285                  cpustate->icount -= 9;
286                  tmp = ARG(cpustate);
287                  if (!(cpustate->AC & 0x80)) {
288                     cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)tmp);
289                     cpustate->icount -= 2;
285                  m_icount -= 9;
286                  tmp = ARG();
287                  if (!(m_AC & 0x80)) {
288                     m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)tmp);
289                     m_icount -= 2;
290290                  }
291291                  break;
292292         case 0x98 : case 0x99 : case 0x9a : case 0x9b :
293293                  // JZ
294                  cpustate->icount -= 9;
295                  tmp = ARG(cpustate);
296                  if (!cpustate->AC) {
297                     cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)tmp);
298                     cpustate->icount -= 2;
294                  m_icount -= 9;
295                  tmp = ARG();
296                  if (!m_AC) {
297                     m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)tmp);
298                     m_icount -= 2;
299299                  }
300300                  break;
301301         case 0x9c : case 0x9d : case 0x9e : case 0x9f :
302302                  // JNZ
303                  cpustate->icount -= 9;
304                  tmp = ARG(cpustate);
305                  if (cpustate->AC) {
306                     cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)tmp);
307                     cpustate->icount -= 2;
303                  m_icount -= 9;
304                  tmp = ARG();
305                  if (m_AC) {
306                     m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)tmp);
307                     m_icount -= 2;
308308                  }
309309                  break;
310310         // Double-Byte Miscellaneous Instructions
311311         case 0x8f:  // DLY
312                  tmp = ARG(cpustate);
313                  cpustate->icount -= 13 + (cpustate->AC * 2) + (((UINT32)tmp) << 1) + (((UINT32)tmp) << 9);
314                  cpustate->AC = 0xff;
312                  tmp = ARG();
313                  m_icount -= 13 + (m_AC * 2) + (((UINT32)tmp) << 1) + (((UINT32)tmp) << 9);
314                  m_AC = 0xff;
315315                  break;
316316         // Others are illegal
317         default :   cpustate->icount -= 1;
318                  illegal (cpustate,opcode);
317         default :   m_icount -= 1;
318                  illegal (opcode);
319319                  break;
320320      }
321321   } else {
r26794r26795
324324      {
325325         // Extension Register Instructions
326326         case 0x40:  // LDE
327                  cpustate->icount -= 6;
328                  cpustate->AC = cpustate->ER;
327                  m_icount -= 6;
328                  m_AC = m_ER;
329329                  break;
330330         case 0x01:  // XAE
331                  cpustate->icount -= 7;
332                  tmp = cpustate->AC;
333                  cpustate->AC = cpustate->ER;
334                  cpustate->ER = tmp;
331                  m_icount -= 7;
332                  tmp = m_AC;
333                  m_AC = m_ER;
334                  m_ER = tmp;
335335                  break;
336336         case 0x50:  // ANE
337                  cpustate->icount -= 6;
338                  cpustate->AC &= cpustate->ER;
337                  m_icount -= 6;
338                  m_AC &= m_ER;
339339                  break;
340340         case 0x58:  // ORE
341                  cpustate->icount -= 6;
342                  cpustate->AC |= cpustate->ER;
341                  m_icount -= 6;
342                  m_AC |= m_ER;
343343                  break;
344344         case 0x60:  // XRE
345                  cpustate->icount -= 6;
346                  cpustate->AC ^= cpustate->ER;
345                  m_icount -= 6;
346                  m_AC ^= m_ER;
347347                  break;
348348         case 0x68:  // DAE
349                  cpustate->icount -= 11;
350                  DEC_ADD(cpustate,cpustate->ER);
349                  m_icount -= 11;
350                  DEC_ADD(m_ER);
351351                  break;
352352         case 0x70:  // ADE
353                  cpustate->icount -= 7;
354                  BIN_ADD(cpustate,cpustate->ER);
353                  m_icount -= 7;
354                  BIN_ADD(m_ER);
355355                  break;
356356         case 0x78:  // CAE
357                  cpustate->icount -= 8;
358                  BIN_ADD(cpustate,~cpustate->ER);
357                  m_icount -= 8;
358                  BIN_ADD(~m_ER);
359359                  break;
360360         // Pointer Register Move Instructions
361361         case 0x30: case 0x31: case 0x32: case 0x33: // XPAL
362                  cpustate->icount -= 8;
363                  tmp = cpustate->AC;
364                  cpustate->AC = GET_PTR_REG(cpustate,ptr)->b.l;
365                  GET_PTR_REG(cpustate,ptr)->b.l = tmp;
362                  m_icount -= 8;
363                  tmp = m_AC;
364                  m_AC = GET_PTR_REG(ptr)->b.l;
365                  GET_PTR_REG(ptr)->b.l = tmp;
366366                  break;
367367         case 0x34:  case 0x35 :case 0x36: case 0x37:
368368                  // XPAH
369                  cpustate->icount -= 8;
370                  tmp = cpustate->AC;
371                  cpustate->AC = GET_PTR_REG(cpustate,ptr)->b.h;
372                  GET_PTR_REG(cpustate,ptr)->b.h = tmp;
369                  m_icount -= 8;
370                  tmp = m_AC;
371                  m_AC = GET_PTR_REG(ptr)->b.h;
372                  GET_PTR_REG(ptr)->b.h = tmp;
373373                  break;
374374         case 0x3c:  case 0x3d :case 0x3e: case 0x3f:
375375                  // XPPC
376376                  {
377                     UINT16 tmp16 = ADD12(cpustate->PC.w.l,-1); // Since PC is incremented we need to fix it
378                     cpustate->icount -= 7;
379                     cpustate->PC.w.l = GET_PTR_REG(cpustate,ptr)->w.l;
380                     GET_PTR_REG(cpustate,ptr)->w.l = tmp16;
377                     UINT16 tmp16 = ADD12(m_PC.w.l,-1); // Since PC is incremented we need to fix it
378                     m_icount -= 7;
379                     m_PC.w.l = GET_PTR_REG(ptr)->w.l;
380                     GET_PTR_REG(ptr)->w.l = tmp16;
381381                     // After exchange CPU increment PC
382                     cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1);
382                     m_PC.w.l = ADD12(m_PC.w.l,1);
383383                  }
384384                  break;
385385         // Shift, Rotate, Serial I/O Instructions
386386         case 0x19:  // SIO
387                  cpustate->icount -= 5;
388                  cpustate->sout_func(cpustate->ER & 0x01);
389                  cpustate->ER >>= 1;
390                  cpustate->ER |= cpustate->sin_func() ? 0x80 : 0x00;
387                  m_icount -= 5;
388                  m_sout_func(m_ER & 0x01);
389                  m_ER >>= 1;
390                  m_ER |= m_sin_func() ? 0x80 : 0x00;
391391                  break;
392392         case 0x1c:  // SR
393                  cpustate->icount -= 5;
394                  cpustate->AC >>= 1;
393                  m_icount -= 5;
394                  m_AC >>= 1;
395395                  break;
396396         case 0x1d:  // SRL
397                  cpustate->icount -= 5;
398                  cpustate->AC >>= 1;
399                  cpustate->AC |= cpustate->SR & 0x80; // add C/L flag
397                  m_icount -= 5;
398                  m_AC >>= 1;
399                  m_AC |= m_SR & 0x80; // add C/L flag
400400                  break;
401401         case 0x1e:  // RR
402                  cpustate->icount -= 5;
403                  cpustate->AC =  (cpustate->AC >> 1) | ((cpustate->AC & 0x01) << 7);
402                  m_icount -= 5;
403                  m_AC =  (m_AC >> 1) | ((m_AC & 0x01) << 7);
404404                  break;
405405         case 0x1f:  // RRL
406                  cpustate->icount -= 5;
407                  tmp = (cpustate->AC & 0x01) << 7;
408                  cpustate->AC =  (cpustate->AC >> 1) | (cpustate->SR & 0x80);
409                  cpustate->SR = (cpustate->SR & 0x7f) | tmp;
406                  m_icount -= 5;
407                  tmp = (m_AC & 0x01) << 7;
408                  m_AC =  (m_AC >> 1) | (m_SR & 0x80);
409                  m_SR = (m_SR & 0x7f) | tmp;
410410                  break;
411411         // Single Byte Miscellaneous Instructions
412412         case 0x00:  // HALT
413                  cpustate->icount -= 8;
414                  cpustate->halt_func(1);
415                  cpustate->halt_func(0);
413                  m_icount -= 8;
414                  m_halt_func(1);
415                  m_halt_func(0);
416416                  break;
417417         case 0x02:  // CCL
418                  cpustate->icount -= 5;
419                  cpustate->SR &= 0x7f;
418                  m_icount -= 5;
419                  m_SR &= 0x7f;
420420                  break;
421421         case 0x03:  // SCL
422                  cpustate->icount -= 5;
423                  cpustate->SR |= 0x80;
422                  m_icount -= 5;
423                  m_SR |= 0x80;
424424                  break;
425425         case 0x04:  // DINT
426                  cpustate->icount -= 6;
427                  cpustate->SR &= 0xf7;
426                  m_icount -= 6;
427                  m_SR &= 0xf7;
428428                  break;
429429         case 0x05:  // IEN
430                  cpustate->icount -= 6;
431                  cpustate->SR |= 0x08;
430                  m_icount -= 6;
431                  m_SR |= 0x08;
432432                  break;
433433         case 0x06:  // CSA
434                  cpustate->icount -= 5;
435                  cpustate->SR &= 0xcf; // clear SA and SB flags
436                  cpustate->SR |= cpustate->sensea_func() ? 0x10 : 0x00;
437                  cpustate->SR |= cpustate->senseb_func() ? 0x20 : 0x00;
438                  cpustate->AC = cpustate->SR;
434                  m_icount -= 5;
435                  m_SR &= 0xcf; // clear SA and SB flags
436                  m_SR |= m_sensea_func() ? 0x10 : 0x00;
437                  m_SR |= m_senseb_func() ? 0x20 : 0x00;
438                  m_AC = m_SR;
439439                  break;
440440         case 0x07:  // CAS
441                  cpustate->icount -= 6;
442                  cpustate->SR = cpustate->AC;
443                  cpustate->flag_out_func(0, cpustate->SR & 0x07);
441                  m_icount -= 6;
442                  m_SR = m_AC;
443                  m_flag_out_func(m_SR & 0x07);
444444                  break;
445445         case 0x08:  // NOP
446                  cpustate->icount -= 5;
446                  m_icount -= 5;
447447                  break;
448448         // Others are illegal
449         default :   cpustate->icount -= 1;
450                  illegal (cpustate,opcode);
449         default :   m_icount -= 1;
450                  illegal (opcode);
451451                  break;
452452      }
453453   }
r26794r26795
457457/***************************************************************************
458458    COMMON EXECUTION
459459***************************************************************************/
460static void take_interrupt(scmp_state *cpustate)
460void scmp_device::take_interrupt()
461461{
462   UINT16 tmp = ADD12(cpustate->PC.w.l,-1); // We fix PC so at return it goes to current location
463   cpustate->SR &= 0xf7; // clear IE flag
462   UINT16 tmp = ADD12(m_PC.w.l,-1); // We fix PC so at return it goes to current location
463   m_SR &= 0xf7; // clear IE flag
464464
465   cpustate->icount -= 8; // assumption
465   m_icount -= 8; // assumption
466466   // do XPPC 3
467   cpustate->PC.w.l = GET_PTR_REG(cpustate,3)->w.l;
468   GET_PTR_REG(cpustate,3)->w.l = tmp;
467   m_PC.w.l = GET_PTR_REG(3)->w.l;
468   GET_PTR_REG(3)->w.l = tmp;
469469   // After exchange CPU increment PC
470   cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1);
470   m_PC.w.l = ADD12(m_PC.w.l,1);
471471}
472472
473static CPU_EXECUTE( scmp )
473void scmp_device::execute_run()
474474{
475   scmp_state *cpustate = get_safe_token(device);
476
477475   do
478476   {
479      if ((cpustate->SR & 0x08) && (cpustate->sensea_func())) {
480         take_interrupt(cpustate);
477      if ((m_SR & 0x08) && (m_sensea_func())) {
478         take_interrupt();
481479      }
482      debugger_instruction_hook(device, cpustate->PC.d);
483      execute_one(cpustate, ROP(cpustate));
480      debugger_instruction_hook(this, m_PC.d);
481      execute_one(ROP());
484482
485   } while (cpustate->icount > 0);
483   } while (m_icount > 0);
486484}
487485
488486/***************************************************************************
489487    CORE INITIALIZATION
490488***************************************************************************/
491489
492static CPU_INIT( scmp )
490void scmp_device::device_start()
493491{
494   scmp_state *cpustate = get_safe_token(device);
495
496   if (device->static_config() != NULL)
497      cpustate->config = *(scmp_config *)device->static_config();
498
499492   /* set up the state table */
500493   {
501      device_state_interface *state;
502      device->interface(state);
503      state->state_add(SCMP_PC,     "PC",    cpustate->PC.w.l);
504      state->state_add(STATE_GENPC, "GENPC", cpustate->PC.w.l).noshow();
505      state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->SR).noshow().formatstr("%8s");
506      state->state_add(SCMP_P1,     "P1",    cpustate->P1.w.l);
507      state->state_add(SCMP_P2,     "P2",    cpustate->P2.w.l);
508      state->state_add(SCMP_P3,     "P3",    cpustate->P3.w.l);
509      state->state_add(SCMP_AC,     "AC",    cpustate->AC);
510      state->state_add(SCMP_ER,     "ER",    cpustate->ER);
511      state->state_add(SCMP_SR,     "SR",    cpustate->SR);
494      state_add(SCMP_PC,     "PC",    m_PC.w.l);
495      state_add(STATE_GENPC, "GENPC", m_PC.w.l).noshow();
496      state_add(STATE_GENFLAGS, "GENFLAGS", m_SR).noshow().formatstr("%8s");
497      state_add(SCMP_P1,     "P1",    m_P1.w.l);
498      state_add(SCMP_P2,     "P2",    m_P2.w.l);
499      state_add(SCMP_P3,     "P3",    m_P3.w.l);
500      state_add(SCMP_AC,     "AC",    m_AC);
501      state_add(SCMP_ER,     "ER",    m_ER);
502      state_add(SCMP_SR,     "SR",    m_SR);
512503   }
513504
514   cpustate->device = device;
505   m_program = &space(AS_PROGRAM);
506   m_direct = &m_program->direct();
515507
516   cpustate->program = &device->space(AS_PROGRAM);
517   cpustate->direct = &cpustate->program->direct();
518
519508   /* resolve callbacks */
520   cpustate->flag_out_func.resolve(cpustate->config.flag_out_func, *device);
521   cpustate->sout_func.resolve(cpustate->config.sout_func, *device);
522   cpustate->sin_func.resolve(cpustate->config.sin_func, *device);
523   cpustate->sensea_func.resolve(cpustate->config.sensea_func, *device);
524   cpustate->senseb_func.resolve(cpustate->config.senseb_func, *device);
525   cpustate->halt_func.resolve(cpustate->config.halt_func, *device);
509   m_flag_out_func.resolve_safe();
510   m_sout_func.resolve_safe();
511   m_sin_func.resolve_safe(0);
512   m_sensea_func.resolve_safe(0);
513   m_senseb_func.resolve_safe(0);
514   m_halt_func.resolve_safe();
526515
527   device->save_item(NAME(cpustate->PC));
528   device->save_item(NAME(cpustate->P1));
529   device->save_item(NAME(cpustate->P2));
530   device->save_item(NAME(cpustate->P3));
531   device->save_item(NAME(cpustate->AC));
532   device->save_item(NAME(cpustate->ER));
533   device->save_item(NAME(cpustate->SR));
516   save_item(NAME(m_PC));
517   save_item(NAME(m_P1));
518   save_item(NAME(m_P2));
519   save_item(NAME(m_P3));
520   save_item(NAME(m_AC));
521   save_item(NAME(m_ER));
522   save_item(NAME(m_SR));
523
524   m_icountptr = &m_icount;
534525}
535526
536527
r26794r26795
539530    COMMON RESET
540531***************************************************************************/
541532
542static CPU_RESET( scmp )
533void scmp_device::device_reset()
543534{
544   scmp_state *cpustate = get_safe_token(device);
545
546   cpustate->PC.d = 0;
547   cpustate->P1.d = 0;
548   cpustate->P2.d = 0;
549   cpustate->P3.d = 0;
550   cpustate->AC = 0;
551   cpustate->ER = 0;
552   cpustate->SR = 0;
535   m_PC.d = 0;
536   m_P1.d = 0;
537   m_P2.d = 0;
538   m_P3.d = 0;
539   m_AC = 0;
540   m_ER = 0;
541   m_SR = 0;
553542}
554543
555544
r26794r26795
558547    COMMON STATE IMPORT/EXPORT
559548***************************************************************************/
560549
561static CPU_IMPORT_STATE( scmp )
550void scmp_device::state_string_export(const device_state_entry &entry, astring &string)
562551{
563}
564
565static CPU_EXPORT_STATE( scmp )
566{
567}
568
569static CPU_EXPORT_STRING( scmp )
570{
571   scmp_state *cpustate = get_safe_token(device);
572
573552   switch (entry.index())
574553   {
575554      case STATE_GENFLAGS:
576555         string.printf("%c%c%c%c%c%c%c%c",
577            (cpustate->SR & 0x80) ? 'C' : '.',
578            (cpustate->SR & 0x40) ? 'V' : '.',
579            (cpustate->SR & 0x20) ? 'B' : '.',
580            (cpustate->SR & 0x10) ? 'A' : '.',
581            (cpustate->SR & 0x08) ? 'I' : '.',
582            (cpustate->SR & 0x04) ? '2' : '.',
583            (cpustate->SR & 0x02) ? '1' : '.',
584            (cpustate->SR & 0x01) ? '0' : '.');
556            (m_SR & 0x80) ? 'C' : '.',
557            (m_SR & 0x40) ? 'V' : '.',
558            (m_SR & 0x20) ? 'B' : '.',
559            (m_SR & 0x10) ? 'A' : '.',
560            (m_SR & 0x08) ? 'I' : '.',
561            (m_SR & 0x04) ? '2' : '.',
562            (m_SR & 0x02) ? '1' : '.',
563            (m_SR & 0x01) ? '0' : '.');
585564         break;
586565   }
587566}
588567
589/***************************************************************************
590    COMMON SET INFO
591***************************************************************************/
592static CPU_SET_INFO( scmp )
593{
594}
595
596/***************************************************************************
597    SCMP GET INFO
598***************************************************************************/
599
600CPU_GET_INFO( scmp )
601{
602   scmp_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
603   switch (state)
604   {
605      /* --- the following bits of info are returned as 64-bit signed integers --- */
606      case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(scmp_state);           break;
607      case CPUINFO_INT_INPUT_LINES:                   info->i = 0;                            break;
608      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                            break;
609      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;            break;
610      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
611      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
612      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1;                            break;
613      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 2;                            break;
614      case CPUINFO_INT_MIN_CYCLES:                    info->i = 5;                            break;
615      case CPUINFO_INT_MAX_CYCLES:                    info->i = 131593;                       break; // DLY instruction max time
616
617      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:            info->i = 8;                            break;
618      case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM:        info->i = 16;                           break;
619      case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM:        info->i = 0;                            break;
620
621      case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:           info->i = 0;                            break;
622      case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:           info->i = 0;                            break;
623      case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:           info->i = 0;                            break;
624
625      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:             info->i = 0;                            break;
626      case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:             info->i = 0;                            break;
627      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:             info->i = 0;                            break;
628
629      /* --- the following bits of info are returned as pointers to functions --- */
630      case CPUINFO_FCT_SET_INFO:      info->setinfo = CPU_SET_INFO_NAME(scmp);                break;
631      case CPUINFO_FCT_INIT:          info->init = CPU_INIT_NAME(scmp);                       break;
632      case CPUINFO_FCT_RESET:         info->reset = CPU_RESET_NAME(scmp);                     break;
633      case CPUINFO_FCT_EXECUTE:       info->execute = CPU_EXECUTE_NAME(scmp);                 break;
634      case CPUINFO_FCT_DISASSEMBLE:   info->disassemble = CPU_DISASSEMBLE_NAME(scmp);         break;
635      case CPUINFO_FCT_IMPORT_STATE:  info->import_state = CPU_IMPORT_STATE_NAME(scmp);       break;
636      case CPUINFO_FCT_EXPORT_STATE:  info->export_state = CPU_EXPORT_STATE_NAME(scmp);       break;
637      case CPUINFO_FCT_EXPORT_STRING: info->export_string = CPU_EXPORT_STRING_NAME(scmp);     break;
638
639      /* --- the following bits of info are returned as pointers --- */
640      case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &cpustate->icount;       break;
641
642      /* --- the following bits of info are returned as NULL-terminated strings --- */
643      case CPUINFO_STR_NAME:                      strcpy(info->s, "INS 8050 SC/MP");              break;
644      case CPUINFO_STR_SHORTNAME:                 strcpy(info->s, "ins8050");              break;
645      case CPUINFO_STR_FAMILY:                    strcpy(info->s, "National Semiconductor SC/MP");            break;
646      case CPUINFO_STR_VERSION:                   strcpy(info->s, "1.0");                 break;
647      case CPUINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__);              break;
648      case CPUINFO_STR_CREDITS:                   strcpy(info->s, "Copyright Miodrag Milanovic"); break;
649   }
650}
651
652/**************************************************************************
653 * CPU-specific set_info
654 **************************************************************************/
655CPU_GET_INFO( ins8060 )
656{
657   switch (state)
658   {
659      /* --- the following bits of info are returned as pointers to data or functions --- */
660      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 2;    break;
661
662      /* --- the following bits of info are returned as NULL-terminated strings --- */
663      case CPUINFO_STR_NAME:                          strcpy(info->s, "INS 8060 SC/MP II");               break;
664      case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "ins8060");              break;
665
666      default:                                        CPU_GET_INFO_CALL(scmp);            break;
667   }
668}
669
670DEFINE_LEGACY_CPU_DEVICE(SCMP, scmp);
671DEFINE_LEGACY_CPU_DEVICE(INS8060, ins8060);
trunk/src/emu/cpu/scmp/scmp.h
r26794r26795
1616   SCMP_GENPCBASE = STATE_GENPCBASE
1717};
1818
19/***************************************************************************
20    TYPE DEFINITIONS
21***************************************************************************/
22struct scmp_config
19
20#define MCFG_SCMP_CONFIG(_flag_out_devcb, _sout_devcb, _sin_devcb, _sensea_devcb, _senseb_devcb, _halt_devcb) \
21   scmp_device::set_flag_out_cb(*device, DEVCB2_##_flag_out_devcb); \
22   scmp_device::set_sout_cb(*device, DEVCB2_##_sout_devcb); \
23   scmp_device::set_sin_cb(*device, DEVCB2_##_sin_devcb); \
24   scmp_device::set_sensea_cb(*device, DEVCB2_##_sensea_devcb); \
25   scmp_device::set_senseb_cb(*device, DEVCB2_##_senseb_devcb); \
26   scmp_device::set_halt_cb(*device, DEVCB2_##_halt_devcb);
27
28
29class scmp_device : public cpu_device
2330{
24   devcb_write8        flag_out_func;
25   devcb_write_line    sout_func;
26   devcb_read_line     sin_func;
27   devcb_read_line     sensea_func;
28   devcb_read_line     senseb_func;
29   devcb_write_line    halt_func;
31public:
32   // construction/destruction
33   scmp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
34   scmp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
35
36   // static configuration helpers
37   template<class _Object> static devcb2_base &set_flag_out_cb(device_t &device, _Object object) { return downcast<scmp_device &>(device).m_flag_out_func.set_callback(object); }
38   template<class _Object> static devcb2_base &set_sout_cb(device_t &device, _Object object) { return downcast<scmp_device &>(device).m_sout_func.set_callback(object); }
39   template<class _Object> static devcb2_base &set_sin_cb(device_t &device, _Object object) { return downcast<scmp_device &>(device).m_sin_func.set_callback(object); }
40   template<class _Object> static devcb2_base &set_sensea_cb(device_t &device, _Object object) { return downcast<scmp_device &>(device).m_sensea_func.set_callback(object); }
41   template<class _Object> static devcb2_base &set_senseb_cb(device_t &device, _Object object) { return downcast<scmp_device &>(device).m_senseb_func.set_callback(object); }
42   template<class _Object> static devcb2_base &set_halt_cb(device_t &device, _Object object) { return downcast<scmp_device &>(device).m_halt_func.set_callback(object); }
43
44protected:
45   // device-level overrides
46   virtual void device_start();
47   virtual void device_reset();
48
49   // device_execute_interface overrides
50   virtual UINT32 execute_min_cycles() const { return 5; }
51   virtual UINT32 execute_max_cycles() const { return 131593; }
52   virtual UINT32 execute_input_lines() const { return 0; }
53   virtual void execute_run();
54
55   // device_memory_interface overrides
56   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
57
58   // device_state_interface overrides
59   void state_string_export(const device_state_entry &entry, astring &string);
60
61   // device_disasm_interface overrides
62   virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
63   virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
64   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
65
66private:
67   address_space_config m_program_config;
68
69   PAIR    m_PC;
70   PAIR    m_P1;
71   PAIR    m_P2;
72   PAIR    m_P3;
73   UINT8   m_AC;
74   UINT8   m_ER;
75   UINT8   m_SR;
76
77   address_space *m_program;
78   direct_read_data *m_direct;
79   int                 m_icount;
80
81   devcb2_write8       m_flag_out_func;
82   devcb2_write_line   m_sout_func;
83   devcb2_read_line    m_sin_func;
84   devcb2_read_line    m_sensea_func;
85   devcb2_read_line    m_senseb_func;
86   devcb2_write_line   m_halt_func;
87
88   inline UINT16 ADD12(UINT16 addr, INT8 val);
89   inline UINT8 ROP();
90   inline UINT8 ARG();
91   inline UINT8 RM(UINT32 a);
92   inline void WM(UINT32 a, UINT8 v);
93   inline void illegal(UINT8 opcode);
94   inline PAIR *GET_PTR_REG(int num);
95   inline void BIN_ADD(UINT8 val);
96   inline void DEC_ADD(UINT8 val);
97   inline UINT16 GET_ADDR(UINT8 code);
98   void execute_one(int opcode);
99   void take_interrupt();
100
30101};
31#define SCMP_CONFIG(name) const scmp_config (name) =
32102
33/***************************************************************************
34    FUNCTION PROTOTYPES
35***************************************************************************/
36103
37DECLARE_LEGACY_CPU_DEVICE(SCMP, scmp);
104class ins8060_device : public scmp_device
105{
106public:
107   // construction/destruction
108   ins8060_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
38109
39CPU_DISASSEMBLE( scmp );
110protected:
111   virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; }
112   virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); }
113};
40114
41DECLARE_LEGACY_CPU_DEVICE(INS8060, ins8060);
42115
116extern const device_type SCMP;
117extern const device_type INS8060;
118
119
43120#endif

Previous 199869 Revisions Next


© 1997-2024 The MAME Team