Previous 15994 Revisions Next

r15331 Monday 28th May, 2012 at 07:27:42 UTC by Miodrag Milanović
Modernized i8008 CPU core [Lukasz Markowski]
[src/emu/cpu/i8008]i8008.c i8008.h

src/emu/cpu/i8008/i8008.c
r15330r15331
1111#include "debugger.h"
1212#include "i8008.h"
1313
14#define VERBOSE 0
14//**************************************************************************
15//  MACROS
16//**************************************************************************
1517
16#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
18#define REG_1               ((opcode >> 3) & 7)
19#define REG_2               (opcode & 7)
20#define GET_PC               (m_ADDR[m_pc_pos])
1721
18static UINT8 PARITY[256];
22//**************************************************************************
23//  GLOBAL VARIABLES
24//**************************************************************************
1925
20/***************************************************************************
21    TYPE DEFINITIONS
22***************************************************************************/
26// device type definition
27const device_type I8008 = &device_creator<i8008_device>;
2328
24typedef struct _i8008_state i8008_state;
25struct _i8008_state
26{
27   UINT8   A,B,C,D,E,H,L;
28   PAIR   PC; // It is in fact one of ADDR regs
29   PAIR   ADDR[8]; // Address registers
30   UINT8   CF; // Carry flag
31   UINT8   ZF; // Zero flag
32   UINT8   SF; // Sign flag
33   UINT8   PF; // Parity flag
34   UINT8   HALT;
35   UINT8   flags; // temporary I/O only
36   legacy_cpu_device *device;
37   address_space *program;
38   direct_read_data *direct;
39   address_space *io;
40   int               icount;
41   int             pc_pos; // PC possition in ADDR
29//**************************************************************************
30//  DEVICE INTERFACE
31//**************************************************************************
4232
43   device_irq_acknowledge_callback irq_callback;
44   UINT8         irq_state;
33//-------------------------------------------------
34//  i8008_device - constructor
35//-------------------------------------------------
36i8008_device::i8008_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
37   : cpu_device(mconfig, I8008, "i8008", tag, owner, clock),
38     m_program_config("program", ENDIANNESS_LITTLE, 8, 14),
39     m_io_config("io", ENDIANNESS_LITTLE, 8, 8),
40     m_program(0),
41     m_direct(0)
42{
43   // set our instruction counter
44   m_icountptr = &m_icount;
4545};
4646
47/***************************************************************************
48    MACROS
49***************************************************************************/
50#define REG_1               ((opcode >> 3) & 7)
51#define REG_2               (opcode & 7)
52#define GET_PC               (cpustate->ADDR[cpustate->pc_pos])
47//-------------------------------------------------
48//  device_start - start up the device
49//-------------------------------------------------
5350
54/***************************************************************************
55    INLINE FUNCTIONS
56***************************************************************************/
51void i8008_device::device_start()
52{
53   // find address spaces
54   m_program = space(AS_PROGRAM);
55   m_direct = &m_program->direct();
56   m_io = space(AS_IO);
5757
58INLINE i8008_state *get_safe_token(device_t *device)
58   // save state
59   save_item(NAME(m_PC));
60   save_item(NAME(m_A));
61   save_item(NAME(m_B));
62   save_item(NAME(m_C));
63   save_item(NAME(m_D));
64   save_item(NAME(m_E));
65   save_item(NAME(m_H));
66   save_item(NAME(m_L));
67   save_item(NAME(m_CF));
68   save_item(NAME(m_SF));
69   save_item(NAME(m_ZF));
70   save_item(NAME(m_PF));
71   save_item(NAME(m_pc_pos));
72   save_item(NAME(m_ADDR[0]));
73   save_item(NAME(m_ADDR[1]));
74   save_item(NAME(m_ADDR[2]));
75   save_item(NAME(m_ADDR[3]));
76   save_item(NAME(m_ADDR[4]));
77   save_item(NAME(m_ADDR[5]));
78   save_item(NAME(m_ADDR[6]));
79   save_item(NAME(m_ADDR[7]));
80   save_item(NAME(m_HALT));
81   save_item(NAME(m_irq_state));
82
83   // register our state for the debugger
84   state_add(I8008_PC,       "PC",       m_PC.w.l).mask(0x3fff);
85   state_add(STATE_GENPC,    "GENPC",    m_PC.w.l).mask(0x3fff).noshow();
86   state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).mask(0x0f).callimport().callexport().noshow().formatstr("%4s");
87   state_add(I8008_A,        "A",        m_A);
88   state_add(I8008_B,        "B",        m_B);
89   state_add(I8008_C,        "C",        m_C);
90   state_add(I8008_D,        "D",        m_D);
91   state_add(I8008_E,        "E",        m_E);
92   state_add(I8008_H,        "H",        m_H);
93   state_add(I8008_L,        "L",        m_L);
94
95   astring tempstr;
96   for (int addrnum = 0; addrnum < 8; addrnum++)
97      state_add(I8008_ADDR1 + addrnum, tempstr.format("ADDR%d", addrnum + 1), m_ADDR[addrnum].w.l).mask(0xfff);
98   
99   init_tables();
100}
101
102void i8008_device::init_tables (void)
59103{
60   assert(device != NULL);
61   assert(device->type() == I8008);
62   return (i8008_state *)downcast<legacy_cpu_device *>(device)->token();
104   int i;
105   UINT8 p;
106   for (i = 0; i < 256; i++)
107   {
108      p = 0;
109      if (BIT(i,0)) p++;
110      if (BIT(i,1)) p++;
111      if (BIT(i,2)) p++;
112      if (BIT(i,3)) p++;
113      if (BIT(i,4)) p++;
114      if (BIT(i,5)) p++;
115      if (BIT(i,6)) p++;
116      if (BIT(i,7)) p++;
117      m_PARITY[i] = ((p&1) ? 0 : 1);
118   }
63119}
64120
65INLINE void PUSH_STACK(i8008_state *cpustate)
121//-------------------------------------------------
122//  device_reset - reset the device
123//-------------------------------------------------
124
125void i8008_device::device_reset()
66126{
67   cpustate->pc_pos = (cpustate->pc_pos + 1) & 7;
127   m_CF = m_SF = m_ZF = m_PF = 0;
128   m_A = m_B = m_C = m_D = m_E = m_H = m_L = 0;
129   m_PC.d = 0;
130   m_pc_pos = 0;
131   m_HALT = 0;
132   m_irq_state = CLEAR_LINE;
133   memset(m_ADDR,0,sizeof(m_ADDR));
68134}
69135
70INLINE void POP_STACK(i8008_state *cpustate)
136//-------------------------------------------------
137//  memory_space_config - return the configuration
138//  of the specified address space, or NULL if
139//  the space doesn't exist
140//-------------------------------------------------
141
142const address_space_config *i8008_device::memory_space_config(address_spacenum spacenum) const
71143{
72   cpustate->ADDR[cpustate->pc_pos].d = 0;
73   cpustate->pc_pos = (cpustate->pc_pos - 1) & 7;
144   return   (spacenum == AS_PROGRAM) ? &m_program_config :
145         (spacenum == AS_IO) ? &m_io_config :
146         NULL;
74147}
75148
76INLINE UINT8 ROP(i8008_state *cpustate)
149//-------------------------------------------------
150//  state_import - import state into the device,
151//  after it has been set
152//-------------------------------------------------
153
154void i8008_device::state_import(const device_state_entry &entry)
77155{
78   UINT8 retVal = cpustate->direct->read_decrypted_byte(GET_PC.w.l);
79   GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff;
80   cpustate->PC = GET_PC;
81   return retVal;
156   switch (entry.index())
157   {
158      case STATE_GENFLAGS:
159         m_CF = (m_flags >> 3) & 1;
160         m_ZF = (m_flags >> 2) & 1;
161         m_SF = (m_flags >> 1) & 1;
162         m_PF = (m_flags >> 0) & 1;
163         break;
164   }
82165}
83166
84INLINE UINT8 GET_REG(i8008_state *cpustate,UINT8 reg)
167//-------------------------------------------------
168//  state_export - export state from the device,
169//  to a known location where it can be read
170//-------------------------------------------------
171
172void i8008_device::state_export(const device_state_entry &entry)
85173{
86   UINT8 retVal;
87   switch(reg) {
88      case 0 : retVal = cpustate->A; break;
89      case 1 : retVal = cpustate->B; break;
90      case 2 : retVal = cpustate->C; break;
91      case 3 : retVal = cpustate->D; break;
92      case 4 : retVal = cpustate->E; break;
93      case 5 : retVal = cpustate->H; break;
94      case 6 : retVal = cpustate->L; break;
95      default: retVal = cpustate->program->read_byte((cpustate->H << 8) + cpustate->L); break;
174   switch (entry.index())
175   {
176      case STATE_GENFLAGS:
177         m_flags = (m_CF ? 0x08 : 0x00) |
178                       (m_ZF ? 0x04 : 0x00) |
179                       (m_SF ? 0x02 : 0x00) |
180                       (m_PF ? 0x01 : 0x00);
181         break;
96182   }
97   return retVal;
98183}
99184
100INLINE void SET_REG(i8008_state *cpustate,UINT8 reg, UINT8 val)
185//-------------------------------------------------
186//  state_string_export - export state as a string
187//  for the debugger
188//-------------------------------------------------
189
190void i8008_device::state_string_export(const device_state_entry &entry, astring &string)
101191{
102   switch(reg) {
103      case 0 : cpustate->A = val; break;
104      case 1 : cpustate->B = val; break;
105      case 2 : cpustate->C = val; break;
106      case 3 : cpustate->D = val; break;
107      case 4 : cpustate->E = val; break;
108      case 5 : cpustate->H = val; break;
109      case 6 : cpustate->L = val; break;
110      default: cpustate->program->write_byte((cpustate->H << 8) + cpustate->L, val); break;
192   switch (entry.index())
193   {
194      case STATE_GENFLAGS:
195         string.printf("%c%c%c%c",
196            m_CF ? 'C':'.',
197            m_ZF ? 'Z':'.',
198            m_SF ? 'S':'.',
199            m_PF ? 'P':'.');
200         break;
111201   }
112202}
113203
114INLINE UINT8 ARG(i8008_state *cpustate)
204//-------------------------------------------------
205//  disasm_min_opcode_bytes - return the length
206//  of the shortest instruction, in bytes
207//-------------------------------------------------
208
209UINT32 i8008_device::disasm_min_opcode_bytes() const
115210{
116   UINT8 retVal = cpustate->direct->read_raw_byte(GET_PC.w.l);
117   GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff;
118   cpustate->PC = GET_PC;
119   return retVal;
211   return 1;
120212}
121213
122INLINE void UPDATE_FLAGS(i8008_state *cpustate,UINT8 val)
214//-------------------------------------------------
215//  disasm_max_opcode_bytes - return the length
216//  of the longest instruction, in bytes
217//-------------------------------------------------
218
219UINT32 i8008_device::disasm_max_opcode_bytes() const
123220{
124   cpustate->ZF = (val == 0) ? 1 : 0;
125   cpustate->SF = (val & 0x80) ? 1 : 0;
126   cpustate->PF = PARITY[val];
221   return 3;
127222}
128223
129INLINE UINT8 DO_CONDITION(i8008_state *cpustate, UINT8 val)
224//-------------------------------------------------
225//  disasm_disassemble - call the disassembly
226//  helper function
227//-------------------------------------------------
228
229offs_t i8008_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
130230{
131   UINT8 v = (val >> 5) & 1;
132   UINT8 cond = 0;
133   switch((val>> 3) & 0x03) {
134      case 0 :
135            if (cpustate->CF==v) cond = 1;
136            break;
137      case 1 :
138            if (cpustate->ZF==v) cond = 1;
139            break;
140      case 2 :
141            if (cpustate->SF==v) cond = 1;
142            break;
143      case 3 :
144            if (cpustate->PF==v) cond = 1;
145            break;
146   }
147   return cond;
231   extern CPU_DISASSEMBLE( i8008 );
232   return CPU_DISASSEMBLE_NAME(i8008)(NULL, buffer, pc, oprom, opram, 0);
148233}
149234
150INLINE UINT16 GET_ADDR(i8008_state *cpustate)
235//**************************************************************************
236//  EXECUTION
237//**************************************************************************
238
239//-------------------------------------------------
240//  execute_min_cycles - return minimum number of
241//  cycles it takes for one instruction to execute
242//-------------------------------------------------
243
244UINT32 i8008_device::execute_min_cycles() const
151245{
152   UINT8 lo = ARG(cpustate);
153   UINT8 hi = ARG(cpustate);
154   return ((hi & 0x3f) << 8) + lo;
246   return 8;
155247}
156248
157INLINE void illegal(i8008_state *cpustate,UINT8 opcode)
249//-------------------------------------------------
250//  execute_max_cycles - return maximum number of
251//  cycles it takes for one instruction to execute
252//-------------------------------------------------
253
254UINT32 i8008_device::execute_max_cycles() const
158255{
159#if VERBOSE
160   UINT16 pc = cpustate->PC.w.l;
161   LOG(("I8008 illegal instruction %04X $%02X\n", pc, opcode));
162#endif
256   return 16;
163257}
164258
165static void execute_one(i8008_state *cpustate, int opcode)
259//-------------------------------------------------
260//  execute_set_input - set input and IRQ lines
261//-------------------------------------------------
262
263void i8008_device::execute_set_input(int inputnum, int state)
166264{
265   m_irq_state = state;
266}
267
268//-------------------------------------------------
269//  execute_run - execute until our icount expires
270//-------------------------------------------------
271
272void i8008_device::execute_run()
273{
274   do
275   {
276      if (m_irq_state != CLEAR_LINE) {
277         take_interrupt();
278      }
279      debugger_instruction_hook(*this, m_PC.d);
280      execute_one(rop());
281   } while (m_icount > 0);
282}
283
284inline void i8008_device::illegal(UINT8 opcode)
285{
286   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
287   {
288      logerror("I8008 illegal instruction %04X $%02X\n", m_PC.w.l, opcode);
289   }
290}
291
292void i8008_device::take_interrupt()
293{
294   if (m_HALT) {
295      GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff;
296      m_PC = GET_PC;
297      m_HALT = 0;
298   }
299   // For now only support one byte operation to be executed
300   execute_one(standard_irq_callback(0));
301}
302
303inline void i8008_device::execute_one(int opcode)
304{
167305   UINT16 tmp;
168306
169307   switch (opcode >> 6)
r15330r15331
171309      case 0x03:   // starting with 11
172310               if (opcode==0xff) {
173311                  // HLT
174                  cpustate->icount -= 4;
312                  m_icount -= 4;
175313                  GET_PC.w.l = GET_PC.w.l - 1;
176                  cpustate->PC = GET_PC;
177                  cpustate->HALT = 1;
314                  m_PC = GET_PC;
315                  m_HALT = 1;
178316               } else {
179317                  // Lrr
180                  cpustate->icount -= 5;
181                  if (REG_1==7) cpustate->icount -= 2;
182                  if (REG_2==7) cpustate->icount -= 3;
183                  SET_REG(cpustate,REG_1, GET_REG(cpustate,REG_2));
318                  m_icount -= 5;
319                  if (REG_1==7) m_icount -= 2;
320                  if (REG_2==7) m_icount -= 3;
321                  set_reg(REG_1, get_reg(REG_2));
184322               }
185323               break;
186324      case 0x00:   // starting with 00
187325               switch(opcode & 7) {
188326                  case 0 :   if(((opcode >> 3) & 7)==0) {
189327                                // HLT
190                              cpustate->icount -= 4;
328                              m_icount -= 4;
191329                              GET_PC.w.l = GET_PC.w.l - 1;
192                              cpustate->PC = GET_PC;
193                              cpustate->HALT = 1;
330                              m_PC = GET_PC;
331                              m_HALT = 1;
194332                           } else {
195333                              if(((opcode >> 3) & 7)==7) {
196334                                 // ILLEGAL
197                                 cpustate->icount -= 5;
198                                 illegal(cpustate,opcode);
335                                 m_icount -= 5;
336                                 illegal(opcode);
199337                              } else {
200338                                 // INr
201                                 cpustate->icount -= 5;
202                                 tmp = GET_REG(cpustate,REG_1) + 1;
203                                 SET_REG(cpustate,REG_1, tmp & 0xff);
204                                 UPDATE_FLAGS(cpustate,tmp & 0xff);
339                                 m_icount -= 5;
340                                 tmp = get_reg(REG_1) + 1;
341                                 set_reg(REG_1, tmp & 0xff);
342                                 update_flags(tmp & 0xff);
205343                              }
206344                           }
207345                           break;
208346                  case 1 :   if(((opcode >> 3) & 7)==0) {
209347                                // HLT
210                              cpustate->icount -= 4;
348                              m_icount -= 4;
211349                              GET_PC.w.l = GET_PC.w.l - 1;
212                              cpustate->PC = GET_PC;
213                              cpustate->HALT = 1;
350                              m_PC = GET_PC;
351                              m_HALT = 1;
214352                           } else {
215353                              if(((opcode >> 3) & 7)==7) {
216354                                 // ILLEGAL
217                                 cpustate->icount -= 5;
218                                 illegal(cpustate,opcode);
355                                 m_icount -= 5;
356                                 illegal(opcode);
219357                              } else {
220358                                 // DCr
221                                 cpustate->icount -= 5;
222                                 tmp = GET_REG(cpustate,REG_1) - 1;
223                                 SET_REG(cpustate,REG_1, tmp & 0xff);
224                                 UPDATE_FLAGS(cpustate,tmp & 0xff);
359                                 m_icount -= 5;
360                                 tmp = get_reg(REG_1) - 1;
361                                 set_reg(REG_1, tmp & 0xff);
362                                 update_flags(tmp & 0xff);
225363                              }
226364                           }
227365                           break;
228366                  case 2 :   {
229367                              // All instuction from this group have same timing
230                              cpustate->icount -= 5;
368                              m_icount -= 5;
231369                              switch((opcode >> 3) & 7) {
232370                                 case 0 :
233371                                    // RLC
234                                    tmp = cpustate->A;
235                                    cpustate->A = (cpustate->A << 1) | BIT(tmp,7);
236                                    cpustate->CF = BIT(tmp,7);
372                                    tmp = m_A;
373                                    m_A = (m_A << 1) | BIT(tmp,7);
374                                    m_CF = BIT(tmp,7);
237375                                    break;
238376                                 case 1 :
239377                                    // RRC
240                                    tmp = cpustate->A;
241                                    cpustate->A = (cpustate->A >> 1) | (BIT(tmp,0) ? 0x80 : 0x00);
242                                    cpustate->CF = BIT(tmp,0);
378                                    tmp = m_A;
379                                    m_A = (m_A >> 1) | (BIT(tmp,0) ? 0x80 : 0x00);
380                                    m_CF = BIT(tmp,0);
243381                                    break;
244382                                 case 2 :
245383                                    // RAL
246                                    tmp = cpustate->A;
247                                    cpustate->A = (cpustate->A << 1) | cpustate->CF;
248                                    cpustate->CF = BIT(tmp,7);
384                                    tmp = m_A;
385                                    m_A = (m_A << 1) | m_CF;
386                                    m_CF = BIT(tmp,7);
249387                                    break;
250388                                 case 3 :
251389                                    // RAR
252                                    tmp = cpustate->A;
253                                    cpustate->A = (cpustate->A >> 1) | (cpustate->CF ? 0x80 : 0x00);
254                                    cpustate->CF = BIT(tmp,0);
390                                    tmp = m_A;
391                                    m_A = (m_A >> 1) | (m_CF ? 0x80 : 0x00);
392                                    m_CF = BIT(tmp,0);
255393                                    break;
256394                                 default :
257395                                    // ILLEGAL
258                                    illegal(cpustate,opcode);
396                                    illegal(opcode);
259397                                    break;
260398                              }
261399                           }
r15330r15331
263401                  case 3 :
264402                           // Rcc
265403                           {
266                              cpustate->icount -= 3;
267                              if (DO_CONDITION(cpustate,opcode)==1) {
268                                 cpustate->icount -= 2;
269                                 POP_STACK(cpustate);
270                                 cpustate->PC = GET_PC;
404                              m_icount -= 3;
405                              if (do_condition(opcode)==1) {
406                                 m_icount -= 2;
407                                 pop_stack();
408                                 m_PC = GET_PC;
271409                              }
272410                           }
273411                           break;
274412                  case 4 :   {
275                              cpustate->icount -= 8;
413                              m_icount -= 8;
276414                              switch((opcode >> 3) & 7) {
277415                                 case 0 :
278416                                    // ADI
279                                    tmp = GET_REG(cpustate,0) + ARG(cpustate);
280                                    SET_REG(cpustate,0,tmp & 0xff);
281                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
282                                    cpustate->CF = (tmp >> 8) & 1;
417                                    tmp = get_reg(0) + arg();
418                                    set_reg(0,tmp & 0xff);
419                                    update_flags(tmp & 0xff);
420                                    m_CF = (tmp >> 8) & 1;
283421                                    break;
284422                                 case 1 :
285423                                    // ACI
286                                    tmp = GET_REG(cpustate,0) + ARG(cpustate) + cpustate->CF;
287                                    SET_REG(cpustate,0,tmp & 0xff);
288                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
289                                    cpustate->CF = (tmp >> 8) & 1;
424                                    tmp = get_reg(0) + arg() + m_CF;
425                                    set_reg(0,tmp & 0xff);
426                                    update_flags(tmp & 0xff);
427                                    m_CF = (tmp >> 8) & 1;
290428                                    break;
291429                                 case 2 :
292430                                    // SUI
293                                    tmp = GET_REG(cpustate,0) - ARG(cpustate);
294                                    SET_REG(cpustate,0,tmp & 0xff);
295                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
296                                    cpustate->CF = (tmp >> 8) & 1;
431                                    tmp = get_reg(0) - arg();
432                                    set_reg(0,tmp & 0xff);
433                                    update_flags(tmp & 0xff);
434                                    m_CF = (tmp >> 8) & 1;
297435                                    break;
298436                                 case 3 :
299437                                    // SBI
300                                    tmp = GET_REG(cpustate,0) - ARG(cpustate) - cpustate->CF;
301                                    SET_REG(cpustate,0,tmp & 0xff);
302                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
303                                    cpustate->CF = (tmp >> 8) & 1;
438                                    tmp = get_reg(0) - arg() - m_CF;
439                                    set_reg(0,tmp & 0xff);
440                                    update_flags(tmp & 0xff);
441                                    m_CF = (tmp >> 8) & 1;
304442                                    break;
305443                                 case 4 :
306444                                    // NDI
307                                    tmp = GET_REG(cpustate,0) & ARG(cpustate);
308                                    SET_REG(cpustate,0,tmp & 0xff);
309                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
310                                    cpustate->CF = 0;
445                                    tmp = get_reg(0) & arg();
446                                    set_reg(0,tmp & 0xff);
447                                    update_flags(tmp & 0xff);
448                                    m_CF = 0;
311449                                    break;
312450                                 case 5 :
313451                                    // XRI
314                                    tmp = GET_REG(cpustate,0) ^ ARG(cpustate);
315                                    SET_REG(cpustate,0,tmp & 0xff);
316                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
317                                    cpustate->CF = 0;
452                                    tmp = get_reg(0) ^ arg();
453                                    set_reg(0,tmp & 0xff);
454                                    update_flags(tmp & 0xff);
455                                    m_CF = 0;
318456                                    break;
319457                                 case 6 :
320458                                    // ORI
321                                    tmp = GET_REG(cpustate,0) | ARG(cpustate);
322                                    SET_REG(cpustate,0,tmp & 0xff);
323                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
324                                    cpustate->CF = 0;
459                                    tmp = get_reg(0) | arg();
460                                    set_reg(0,tmp & 0xff);
461                                    update_flags(tmp & 0xff);
462                                    m_CF = 0;
325463                                    break;
326464                                 case 7 :
327465                                    // CPI
328                                    tmp = GET_REG(cpustate,0) - ARG(cpustate);
329                                    UPDATE_FLAGS(cpustate,tmp & 0xff);
330                                    cpustate->CF = (tmp >> 8) & 1;
466                                    tmp = get_reg(0) - arg();
467                                    update_flags(tmp & 0xff);
468                                    m_CF = (tmp >> 8) & 1;
331469                                    break;
332470                              }
333471                           }
334472                           break;
335473                  case 5 :   // RST
336                           cpustate->icount -= 5;
337                           PUSH_STACK(cpustate);
474                           m_icount -= 5;
475                           push_stack();
338476                           GET_PC.w.l = opcode & 0x38;
339                           cpustate->PC = GET_PC;
477                           m_PC = GET_PC;
340478                           break;
341479                  case 6 :   // LrI
342                           cpustate->icount -= 8;
343                           if (REG_1==7) cpustate->icount -= 1; // LMI
344                           SET_REG(cpustate,REG_1, ARG(cpustate));
480                           m_icount -= 8;
481                           if (REG_1==7) m_icount -= 1; // LMI
482                           set_reg(REG_1, arg());
345483                           break;
346484                  case 7 :   // RET
347                           cpustate->icount -= 5;
348                           POP_STACK(cpustate);
349                           cpustate->PC = GET_PC;
485                           m_icount -= 5;
486                           pop_stack();
487                           m_PC = GET_PC;
350488                           break;
351489               }
352490               break;
r15330r15331
355493               switch(opcode & 7) {
356494                  case 0 :
357495                     // Jcc
358                     cpustate->icount -= 9;
359                     tmp = GET_ADDR(cpustate);
360                     if (DO_CONDITION(cpustate,opcode)==1) {
361                        cpustate->icount -= 2;
496                     m_icount -= 9;
497                     tmp = get_addr();
498                     if (do_condition(opcode)==1) {
499                        m_icount -= 2;
362500                        GET_PC.w.l = tmp;
363                        cpustate->PC = GET_PC;
501                        m_PC = GET_PC;
364502                     }
365503                     break;
366504                  case 2 :
367505                     // Ccc
368                     cpustate->icount -= 9;
369                     tmp = GET_ADDR(cpustate);
370                     if (DO_CONDITION(cpustate,opcode)==1) {
371                        cpustate->icount -= 2;
372                        PUSH_STACK(cpustate);
506                     m_icount -= 9;
507                     tmp = get_addr();
508                     if (do_condition(opcode)==1) {
509                        m_icount -= 2;
510                        push_stack();
373511                        GET_PC.w.l = tmp;
374                        cpustate->PC = GET_PC;
512                        m_PC = GET_PC;
375513                     }
376514                     break;
377515                  case 4 :
378516                     // JMP
379                     cpustate->icount -= 11;
380                     GET_PC.w.l = GET_ADDR(cpustate);
381                     cpustate->PC = GET_PC;
517                     m_icount -= 11;
518                     GET_PC.w.l = get_addr();
519                     m_PC = GET_PC;
382520                     break;
383521                  case 6 :
384522                     // CAL
385                     cpustate->icount -= 11;
386                     tmp = GET_ADDR(cpustate);
387                     PUSH_STACK(cpustate);
523                     m_icount -= 11;
524                     tmp = get_addr();
525                     push_stack();
388526                     GET_PC.w.l = tmp;
389                     cpustate->PC = GET_PC;
527                     m_PC = GET_PC;
390528                     break;
391529                  default :
392530                     if (((opcode>>4)&3)==0) {
393531                        // INP
394                        cpustate->icount -= 8;
395                        cpustate->A = cpustate->io->read_byte((opcode >> 1) & 0x1f);
532                        m_icount -= 8;
533                        m_A = m_io->read_byte((opcode >> 1) & 0x1f);
396534                     } else {
397535                        // OUT
398                        cpustate->icount -= 6;
399                        cpustate->io->write_byte((opcode >> 1) & 0x1f, cpustate->A);
536                        m_icount -= 6;
537                        m_io->write_byte((opcode >> 1) & 0x1f, m_A);
400538                     }
401539                     break;
402540               }
403541               break;
404542      case 0x02:   // starting with 10
405               cpustate->icount -= 5;
406               if ((opcode & 7)==7) cpustate->icount -= 3; // operations with memory
543               m_icount -= 5;
544               if ((opcode & 7)==7) m_icount -= 3; // operations with memory
407545               switch((opcode >> 3) & 7) {
408546                  case 0 :
409547                     // ADx
410                     tmp = GET_REG(cpustate,0) + GET_REG(cpustate,opcode & 7);
411                     SET_REG(cpustate,0,tmp & 0xff);
412                     UPDATE_FLAGS(cpustate,tmp & 0xff);
413                     cpustate->CF = (tmp >> 8) & 1;
548                     tmp = get_reg(0) + get_reg(opcode & 7);
549                     set_reg(0,tmp & 0xff);
550                     update_flags(tmp & 0xff);
551                     m_CF = (tmp >> 8) & 1;
414552                     break;
415553                  case 1 :
416554                     // ACx
417                     tmp = GET_REG(cpustate,0) + GET_REG(cpustate,opcode & 7) + cpustate->CF;
418                     SET_REG(cpustate,0,tmp & 0xff);
419                     UPDATE_FLAGS(cpustate,tmp & 0xff);
420                     cpustate->CF = (tmp >> 8) & 1;
555                     tmp = get_reg(0) + get_reg(opcode & 7) + m_CF;
556                     set_reg(0,tmp & 0xff);
557                     update_flags(tmp & 0xff);
558                     m_CF = (tmp >> 8) & 1;
421559                     break;
422560                  case 2 :
423561                     // SUx
424                     tmp = GET_REG(cpustate,0) - GET_REG(cpustate,opcode & 7);
425                     SET_REG(cpustate,0,tmp & 0xff);
426                     UPDATE_FLAGS(cpustate,tmp & 0xff);
427                     cpustate->CF = (tmp >> 8) & 1;
562                     tmp = get_reg(0) - get_reg(opcode & 7);
563                     set_reg(0,tmp & 0xff);
564                     update_flags(tmp & 0xff);
565                     m_CF = (tmp >> 8) & 1;
428566                     break;
429567                  case 3 :
430568                     // SBx
431                     tmp = GET_REG(cpustate,0) - GET_REG(cpustate,opcode & 7) - cpustate->CF;
432                     SET_REG(cpustate,0,tmp & 0xff);
433                     UPDATE_FLAGS(cpustate,tmp & 0xff);
434                     cpustate->CF = (tmp >> 8) & 1;
569                     tmp = get_reg(0) - get_reg(opcode & 7) - m_CF;
570                     set_reg(0,tmp & 0xff);
571                     update_flags(tmp & 0xff);
572                     m_CF = (tmp >> 8) & 1;
435573                     break;
436574                  case 4 :
437575                     // NDx
438                     tmp = GET_REG(cpustate,0) & GET_REG(cpustate,opcode & 7);
439                     SET_REG(cpustate,0,tmp & 0xff);
440                     UPDATE_FLAGS(cpustate,tmp & 0xff);
441                     cpustate->CF = 0;
576                     tmp = get_reg(0) & get_reg(opcode & 7);
577                     set_reg(0,tmp & 0xff);
578                     update_flags(tmp & 0xff);
579                     m_CF = 0;
442580                     break;
443581                  case 5 :
444582                     // XRx
445                     tmp = GET_REG(cpustate,0) ^ GET_REG(cpustate,opcode & 7);
446                     SET_REG(cpustate,0,tmp & 0xff);
447                     UPDATE_FLAGS(cpustate,tmp & 0xff);
448                     cpustate->CF = 0;
583                     tmp = get_reg(0) ^ get_reg(opcode & 7);
584                     set_reg(0,tmp & 0xff);
585                     update_flags(tmp & 0xff);
586                     m_CF = 0;
449587                     break;
450588                  case 6 :
451589                     // ORx
452                     tmp = GET_REG(cpustate,0) | GET_REG(cpustate,opcode & 7);
453                     SET_REG(cpustate,0,tmp & 0xff);
454                     UPDATE_FLAGS(cpustate,tmp & 0xff);
455                     cpustate->CF = 0;
590                     tmp = get_reg(0) | get_reg(opcode & 7);
591                     set_reg(0,tmp & 0xff);
592                     update_flags(tmp & 0xff);
593                     m_CF = 0;
456594                     break;
457595                  case 7 :
458596                     // CPx
459                     tmp = GET_REG(cpustate,0) - GET_REG(cpustate,opcode & 7);
460                     UPDATE_FLAGS(cpustate,tmp & 0xff);
461                     cpustate->CF = (tmp >> 8) & 1;
597                     tmp = get_reg(0) - get_reg(opcode & 7);
598                     update_flags(tmp & 0xff);
599                     m_CF = (tmp >> 8) & 1;
462600                     break;
463601               }
464602               break;
465603   }
466604}
467605
468
469606/***************************************************************************
470    COMMON EXECUTION
607    INLINE FUNCTIONS
471608***************************************************************************/
472static void take_interrupt(i8008_state *cpustate)
609
610inline void i8008_device::push_stack()
473611{
474   if (cpustate->HALT) {
475      GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff;
476      cpustate->PC = GET_PC;
477      cpustate->HALT = 0;
478   }
479   // For now only support one byte operation to be executed
480   execute_one(cpustate,(*cpustate->irq_callback)(cpustate->device, 0));
612   m_pc_pos = (m_pc_pos + 1) & 7;
481613}
482614
483static CPU_EXECUTE( i8008 )
615inline void i8008_device::pop_stack()
484616{
485   i8008_state *cpustate = get_safe_token(device);
486
487   do
488   {
489      if (cpustate->irq_state != CLEAR_LINE) {
490         take_interrupt(cpustate);
491      }
492      debugger_instruction_hook(device, cpustate->PC.d);
493      execute_one(cpustate, ROP(cpustate));
494
495   } while (cpustate->icount > 0);
617   m_ADDR[m_pc_pos].d = 0;
618   m_pc_pos = (m_pc_pos - 1) & 7;
496619}
497620
498/***************************************************************************
499    CORE INITIALIZATION
500***************************************************************************/
501static void init_tables (void)
621inline UINT8 i8008_device::rop()
502622{
503   int i;
504   UINT8 p;
505   for (i = 0; i < 256; i++)
506   {
507      p = 0;
508      if (BIT(i,0)) p++;
509      if (BIT(i,1)) p++;
510      if (BIT(i,2)) p++;
511      if (BIT(i,3)) p++;
512      if (BIT(i,4)) p++;
513      if (BIT(i,5)) p++;
514      if (BIT(i,6)) p++;
515      if (BIT(i,7)) p++;
516      PARITY[i] = ((p&1) ? 0 : 1);
517   }
623   UINT8 retVal = m_direct->read_decrypted_byte(GET_PC.w.l);
624   GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff;
625   m_PC = GET_PC;
626   return retVal;
518627}
519628
520static CPU_INIT( i8008 )
629inline UINT8 i8008_device::get_reg(UINT8 reg)
521630{
522   i8008_state *cpustate = get_safe_token(device);
523
524   /* set up the state table */
525   {
526      device_state_interface *state;
527      device->interface(state);
528      state->state_add(I8008_PC,    "PC",    cpustate->PC.w.l).mask(0x3fff);
529      state->state_add(STATE_GENPC, "GENPC", cpustate->PC.w.l).mask(0x3fff).noshow();
530      state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->flags).mask(0x0f).callimport().callexport().noshow().formatstr("%4s");
531      state->state_add(I8008_A,     "A",     cpustate->A);
532      state->state_add(I8008_B,     "B",     cpustate->B);
533      state->state_add(I8008_C,     "C",     cpustate->C);
534      state->state_add(I8008_D,     "D",     cpustate->D);
535      state->state_add(I8008_E,     "E",     cpustate->E);
536      state->state_add(I8008_H,     "H",     cpustate->H);
537      state->state_add(I8008_L,     "L",     cpustate->L);
538
539      astring tempstr;
540      for (int addrnum = 0; addrnum < 8; addrnum++)
541         state->state_add(I8008_ADDR1 + addrnum, tempstr.format("ADDR%d", addrnum + 1), cpustate->ADDR[addrnum].w.l).mask(0xfff);
631   UINT8 retVal;
632   switch(reg) {
633      case 0 : retVal = m_A; break;
634      case 1 : retVal = m_B; break;
635      case 2 : retVal = m_C; break;
636      case 3 : retVal = m_D; break;
637      case 4 : retVal = m_E; break;
638      case 5 : retVal = m_H; break;
639      case 6 : retVal = m_L; break;
640      default: retVal = m_program->read_byte((m_H << 8) + m_L); break;
542641   }
543
544   cpustate->device = device;
545
546   cpustate->program = device->space(AS_PROGRAM);
547   cpustate->direct = &cpustate->program->direct();
548   cpustate->io = device->space(AS_IO);
549
550   cpustate->irq_callback = irqcallback;
551
552   init_tables();
553
554   device->save_item(NAME(cpustate->PC));
555   device->save_item(NAME(cpustate->A));
556   device->save_item(NAME(cpustate->B));
557   device->save_item(NAME(cpustate->C));
558   device->save_item(NAME(cpustate->D));
559   device->save_item(NAME(cpustate->E));
560   device->save_item(NAME(cpustate->H));
561   device->save_item(NAME(cpustate->L));
562   device->save_item(NAME(cpustate->CF));
563   device->save_item(NAME(cpustate->SF));
564   device->save_item(NAME(cpustate->ZF));
565   device->save_item(NAME(cpustate->PF));
566   device->save_item(NAME(cpustate->pc_pos));
567   device->save_item(NAME(cpustate->ADDR[0]));
568   device->save_item(NAME(cpustate->ADDR[1]));
569   device->save_item(NAME(cpustate->ADDR[2]));
570   device->save_item(NAME(cpustate->ADDR[3]));
571   device->save_item(NAME(cpustate->ADDR[4]));
572   device->save_item(NAME(cpustate->ADDR[5]));
573   device->save_item(NAME(cpustate->ADDR[6]));
574   device->save_item(NAME(cpustate->ADDR[7]));
575   device->save_item(NAME(cpustate->HALT));
576   device->save_item(NAME(cpustate->irq_state));
642   return retVal;
577643}
578644
579
580
581/***************************************************************************
582    COMMON RESET
583***************************************************************************/
584
585static CPU_RESET( i8008 )
645inline void i8008_device::set_reg(UINT8 reg, UINT8 val)
586646{
587   i8008_state *cpustate = get_safe_token(device);
588
589   cpustate->CF = cpustate->SF = cpustate->ZF = cpustate->PF = 0;
590   cpustate->A = cpustate->B = cpustate->C = cpustate->D = cpustate->E = cpustate->H = cpustate->L = 0;
591   cpustate->PC.d = 0;
592   cpustate->pc_pos = 0;
593   cpustate->HALT = 0;
594   cpustate->irq_state = CLEAR_LINE;
595   memset(cpustate->ADDR,0,sizeof(cpustate->ADDR));
596
597}
598
599/****************************************************************************
600 * Set IRQ line state
601 ****************************************************************************/
602static void set_irq_line(i8008_state *cpustate, int irqline, int state)
603{
604   cpustate->irq_state = state;
605}
606
607/***************************************************************************
608    COMMON STATE IMPORT/EXPORT
609***************************************************************************/
610
611static CPU_IMPORT_STATE( i8008 )
612{
613   i8008_state *cpustate = get_safe_token(device);
614
615   switch (entry.index())
616   {
617      case STATE_GENFLAGS:
618         cpustate->CF = (cpustate->flags >> 3) & 1;
619         cpustate->ZF = (cpustate->flags >> 2) & 1;
620         cpustate->SF = (cpustate->flags >> 1) & 1;
621         cpustate->PF = (cpustate->flags >> 0) & 1;
622         break;
647   switch(reg) {
648      case 0 : m_A = val; break;
649      case 1 : m_B = val; break;
650      case 2 : m_C = val; break;
651      case 3 : m_D = val; break;
652      case 4 : m_E = val; break;
653      case 5 : m_H = val; break;
654      case 6 : m_L = val; break;
655      default: m_program->write_byte((m_H << 8) + m_L, val); break;
623656   }
624657}
625658
626static CPU_EXPORT_STATE( i8008 )
659inline UINT8 i8008_device::arg()
627660{
628   i8008_state *cpustate = get_safe_token(device);
629
630   switch (entry.index())
631   {
632      case STATE_GENFLAGS:
633         cpustate->flags = (cpustate->CF ? 0x08 : 0x00) |
634                       (cpustate->ZF ? 0x04 : 0x00) |
635                       (cpustate->SF ? 0x02 : 0x00) |
636                       (cpustate->PF ? 0x01 : 0x00);
637         break;
638   }
661   UINT8 retVal = m_direct->read_raw_byte(GET_PC.w.l);
662   GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff;
663   m_PC = GET_PC;
664   return retVal;
639665}
640666
641static CPU_EXPORT_STRING( i8008 )
667inline void i8008_device::update_flags(UINT8 val)
642668{
643   i8008_state *cpustate = get_safe_token(device);
644
645   switch (entry.index())
646   {
647      case STATE_GENFLAGS:
648         string.printf("%c%c%c%c",
649            cpustate->CF ? 'C':'.',
650            cpustate->ZF ? 'Z':'.',
651            cpustate->SF ? 'S':'.',
652            cpustate->PF ? 'P':'.');
653         break;
654   }
669   m_ZF = (val == 0) ? 1 : 0;
670   m_SF = (val & 0x80) ? 1 : 0;
671   m_PF = m_PARITY[val];
655672}
656673
657/***************************************************************************
658    COMMON SET INFO
659***************************************************************************/
660static CPU_SET_INFO( i8008 )
674inline UINT8 i8008_device::do_condition(UINT8 val)
661675{
662   i8008_state *cpustate = get_safe_token(device);
663   switch (state)
664   {
665      /* --- the following bits of info are set as 64-bit signed integers --- */
666      case CPUINFO_INT_INPUT_STATE + 0:               set_irq_line(cpustate, 0, info->i);            break;
676   UINT8 v = (val >> 5) & 1;
677   UINT8 cond = 0;
678   switch((val>> 3) & 0x03) {
679      case 0 :
680            if (m_CF==v) cond = 1;
681            break;
682      case 1 :
683            if (m_ZF==v) cond = 1;
684            break;
685      case 2 :
686            if (m_SF==v) cond = 1;
687            break;
688      case 3 :
689            if (m_PF==v) cond = 1;
690            break;
667691   }
692   return cond;
668693}
669694
670/***************************************************************************
671    8008 GET INFO
672***************************************************************************/
673
674CPU_GET_INFO( i8008 )
695inline UINT16 i8008_device::get_addr()
675696{
676   i8008_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
677   switch (state)
678   {
679      /* --- the following bits of info are returned as 64-bit signed integers --- */
680      case CPUINFO_INT_CONTEXT_SIZE:               info->i = sizeof(i8008_state);         break;
681      case CPUINFO_INT_INPUT_LINES:               info->i = 0;                     break;
682      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:         info->i = 0;                     break;
683      case DEVINFO_INT_ENDIANNESS:               info->i = ENDIANNESS_LITTLE;         break;
684      case CPUINFO_INT_CLOCK_MULTIPLIER:            info->i = 1;                     break;
685      case CPUINFO_INT_CLOCK_DIVIDER:               info->i = 1;                     break;
686      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1;                     break;
687      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 3;                     break;
688      case CPUINFO_INT_MIN_CYCLES:               info->i = 8;                     break;
689      case CPUINFO_INT_MAX_CYCLES:               info->i = 16;                     break;
690
691      case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM:         info->i = 8;                     break;
692      case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM:      info->i = 14;                     break;
693      case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM:      info->i = 0;                     break;
694
695      case DEVINFO_INT_DATABUS_WIDTH + AS_DATA:         info->i = 0;                     break;
696      case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA:         info->i = 0;                     break;
697      case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA:         info->i = 0;                     break;
698
699      case DEVINFO_INT_DATABUS_WIDTH + AS_IO:            info->i = 8;                     break;
700      case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO:            info->i = 8;                     break;
701      case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO:            info->i = 0;                     break;
702
703      /* --- the following bits of info are returned as pointers to functions --- */
704      case CPUINFO_FCT_SET_INFO:      info->setinfo = CPU_SET_INFO_NAME(i8008);            break;
705      case CPUINFO_FCT_INIT:         info->init = CPU_INIT_NAME(i8008);                  break;
706      case CPUINFO_FCT_RESET:         info->reset = CPU_RESET_NAME(i8008);               break;
707      case CPUINFO_FCT_EXECUTE:      info->execute = CPU_EXECUTE_NAME(i8008);            break;
708      case CPUINFO_FCT_DISASSEMBLE:   info->disassemble = CPU_DISASSEMBLE_NAME(i8008);      break;
709      case CPUINFO_FCT_IMPORT_STATE:   info->import_state = CPU_IMPORT_STATE_NAME(i8008);      break;
710      case CPUINFO_FCT_EXPORT_STATE:   info->export_state = CPU_EXPORT_STATE_NAME(i8008);      break;
711      case CPUINFO_FCT_EXPORT_STRING:   info->export_string = CPU_EXPORT_STRING_NAME(i8008);   break;
712
713      /* --- the following bits of info are returned as pointers --- */
714      case CPUINFO_PTR_INSTRUCTION_COUNTER:         info->icount = &cpustate->icount;      break;
715
716      /* --- the following bits of info are returned as NULL-terminated strings --- */
717      case DEVINFO_STR_NAME:                  strcpy(info->s, "8008");            break;
718      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Intel 8008");         break;
719      case DEVINFO_STR_VERSION:               strcpy(info->s, "1.0");               break;
720      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__);            break;
721      case DEVINFO_STR_CREDITS:               strcpy(info->s, "Copyright Miodrag Milanovic"); break;
722
723      case CPUINFO_IS_OCTAL:                  info->i = true;                     break;
724   }
697   UINT8 lo = arg();
698   UINT8 hi = arg();
699   return ((hi & 0x3f) << 8) + lo;
725700}
726
727DEFINE_LEGACY_CPU_DEVICE(I8008, i8008);
src/emu/cpu/i8008/i8008.h
r15330r15331
11#ifndef __I8008_H__
22#define __I8008_H__
33
4//**************************************************************************
5//  ENUMERATIONS
6//**************************************************************************
47
5
6/***************************************************************************
7    CONSTANTS
8***************************************************************************/
9
108enum
119{
1210   I8008_PC,
1311   I8008_A,I8008_B,I8008_C,I8008_D,I8008_E,I8008_H,I8008_L,
1412   I8008_ADDR1,I8008_ADDR2,I8008_ADDR3,I8008_ADDR4,I8008_ADDR5,I8008_ADDR6,I8008_ADDR7,I8008_ADDR8,
13
1514   I8008_GENPC = STATE_GENPC,
1615   I8008_GENSP = STATE_GENSP,
1716   I8008_GENPCBASE = STATE_GENPCBASE
1817};
1918
20/***************************************************************************
21    TYPE DEFINITIONS
22***************************************************************************/
19//**************************************************************************
20//  TYPE DEFINITIONS
21//**************************************************************************
2322
24/***************************************************************************
25    FUNCTION PROTOTYPES
26***************************************************************************/
23class i8008_device;
2724
28DECLARE_LEGACY_CPU_DEVICE(I8008, i8008);
25// ======================> asap_device
26class i8008_device : public cpu_device
27{
28public:
29   // construction/destruction
30   i8008_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2931
30CPU_DISASSEMBLE( i8008 );
32protected:
33   // device-level overrides
34   virtual void device_start();
35   virtual void device_reset();
36
37   // device_execute_interface overrides
38   virtual UINT32 execute_min_cycles() const;
39   virtual UINT32 execute_max_cycles() const;
40   virtual void execute_run();
41   virtual void execute_set_input(int inputnum, int state);
42   
43   // device_memory_interface overrides
44   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
45   
46   // device_state_interface overrides
47   virtual void state_import(const device_state_entry &entry);
48   virtual void state_export(const device_state_entry &entry);
49   virtual void state_string_export(const device_state_entry &entry, astring &string);
50
51
52   // device_disasm_interface overrides
53   virtual UINT32 disasm_min_opcode_bytes() const;
54   virtual UINT32 disasm_max_opcode_bytes() const;
55   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
56   
57   virtual void execute_one(int opcode);
58
59   void push_stack();
60   void pop_stack();
61   UINT8 rop();
62   UINT8 get_reg(UINT8 reg);
63   void set_reg(UINT8 reg, UINT8 val);
64   UINT8 arg();
65   void update_flags(UINT8 val);
66   UINT8 do_condition(UINT8 val);
67   UINT16 get_addr();
68   void illegal(UINT8 opcode);
69   void take_interrupt();
70   void init_tables(void);
71   
72   int   m_pc_pos; // PC possition in ADDR
73   int   m_icount;
74   
75   // configuration
76   const address_space_config      m_program_config;
77   const address_space_config      m_io_config;
78
79   UINT8   m_A,m_B,m_C,m_D,m_E,m_H,m_L;
80   PAIR   m_PC; // It is in fact one of ADDR regs
81   PAIR   m_ADDR[8]; // Address registers
82   UINT8   m_CF; // Carry flag
83   UINT8   m_ZF; // Zero flag
84   UINT8   m_SF; // Sign flag
85   UINT8   m_PF; // Parity flag
86   UINT8   m_HALT;
87   UINT8   m_flags; // temporary I/O only
88   
89   UINT8   m_irq_state;
90   
91   UINT8 m_PARITY[256];
92   
93   address_space *m_program;
94   address_space *m_io;
95   direct_read_data *m_direct;
96};
97
98// device type definition
99extern const device_type I8008;
100
31101#endif

Previous 15994 Revisions Next


© 1998-2018 The MESS Team