Previous 15994 Revisions Next

r8772 Saturday 14th August, 2010 at 13:19:04 UTC by Robbbert
[GAMECOM] Reapply part of r8732 lost in u1 update.
[src/emu/cpu/sm8500]sm8500.c sm8500.h sm8500d.c sm85ops.h

src/emu/cpu/sm8500/sm8500d.c
r8771r8772
4141   "iret", "jmp",  "mov",  "movm", "movw",  "mult", "neg",  "nop",  "or",
4242   "orw",  "pop",  "popw", "push", "pushw", "ret",  "rl",   "rlc",
4343   "rr",   "rrc",  "sbc",  "sbcw", "setc", "sll",   "sra",  "srl",  "stop",
44   "sub",  "subw", "swap", "xor",  "xorw", "mov PS0,", "invalid", "dm?",
44   "sub",  "subw", "swap", "xor",  "xorw", "mov PS0,", "invalid", "dm?",
4545/* unknowns */
4646"unk5A", "unk5B",
4747
src/emu/cpu/sm8500/sm8500.h
r8771r8772
3636
3737extern CPU_DISASSEMBLE( sm8500 );
3838
39UINT8 *sm8500_get_internal_ram(legacy_cpu_device *device);
40
4139#endif /* __SM8500_H__ */
src/emu/cpu/sm8500/sm85ops.h
r8771r8772
488488         case 0x0F: /* NC  */ if ( ! (cpustate->PS1 & FLAG_C) ) res = 1; break; \
489489         }
490490
491#define PUSH8(X)   cpustate->SP = cpustate->SP - 1; \
492         if ( ( cpustate->SYS & 0x40 ) == 0 ) { \
493            cpustate->SP = cpustate->SP & 0xFF; \
494         } \
491#define PUSH8(X)   cpustate->SP--; \
492         if ( ( cpustate->SYS & 0x40 ) == 0 ) cpustate->SP &= 0xFF; \
495493         sm85cpu_mem_writebyte( cpustate, cpustate->SP, X );
496494
497495#define POP8(X)      X = sm85cpu_mem_readbyte( cpustate, cpustate->SP ); \
498         cpustate->SP = cpustate->SP + 1; \
499         if ( ( cpustate->SYS & 0x40 ) == 0 ) { \
500            cpustate->SP = cpustate->SP & 0xFF; \
501         }
496         cpustate->SP++; \
497         if ( ( cpustate->SYS & 0x40 ) == 0 ) cpustate->SP &= 0xFF;
502498
503499case 0x00:   /* CLR R - 4 cycles - Flags affected: -------- */
504500   ARG_R;
r8771r8772
910906   break;
911907case 0x2E:   /* MOV PS0,#00 - 4 cycles - Flags affected: -------- */
912908   ARG_R;
913   cpustate->PS0 = r1; cpustate->register_base = cpustate->internal_ram + ( r1 & 0xF8 );
909   cpustate->PS0 = r1;
914910        mycycles += 4;
915911   break;
916912case 0x2F:   /* BTST R,i - 6 cycles - Flags affected: -Z-0---- */
src/emu/cpu/sm8500/sm8500.c
r8771r8772
2727{
2828   SM8500_CONFIG config;
2929   UINT16 PC;
30   UINT8 *register_base;
3130   UINT8 IE0;
3231   UINT8 IE1;
3332   UINT8 IR0;
3433   UINT8 IR1;
35   UINT8 P0;
36   UINT8 P1;
37   UINT8 P2;
38   UINT8 P3;
3934   UINT8 SYS;
4035   UINT8 CKC;
4136   UINT8 clock_changed;
4237   UINT16 SP;
4338   UINT8 PS0;
4439   UINT8 PS1;
45   UINT8 P0C;
46   UINT8 P1C;
47   UINT8 P2C;
48   UINT8 P3C;
4940   UINT8 IFLAGS;
5041   UINT8 CheckInterrupts;
5142   int halted;
r8771r8772
5344   device_irq_callback irq_callback;
5445   legacy_cpu_device *device;
5546   const address_space *program;
56   UINT8 internal_ram[0x500];
47   UINT16 oldpc;
5748};
5849
5950INLINE sm8500_state *get_safe_token(running_device *device)
r8771r8772
6758        0, 8, 2, 10, 4, 12, 6, 14
6859};
6960
61INLINE void sm8500_get_sp( sm8500_state *cpustate )
62{
63   UINT16 data = memory_read_byte( cpustate->program, 0x1c) << 8;
64   cpustate->SP = memory_read_byte( cpustate->program, 0x1d);
65   if (cpustate->SYS&0x40) cpustate->SP |= data;
66}
67
7068static UINT8 sm85cpu_mem_readbyte( sm8500_state *cpustate, UINT32 offset ) {
71   return ( offset < 0x10 ) ? cpustate->register_base[offset] : memory_read_byte_8be( cpustate->program, offset );
69   if (offset < 0x10) offset+= cpustate->PS0 & 0xf8;
70   return memory_read_byte( cpustate->program, offset );
7271}
7372
7473static void sm85cpu_mem_writebyte( sm8500_state *cpustate, UINT32 offset, UINT8 data ) {
75   if ( offset < 0x10 ) {
76      cpustate->register_base[offset] = data;
77   } else {
78      memory_write_byte_8be( cpustate->program, offset, data );
74   if (offset < 0x10) offset+= cpustate->PS0 & 0xf8;
75   memory_write_byte( cpustate->program, offset, data );
76   switch (offset)
77   {
78      case 0x10: cpustate->IE0 = data; break;
79      case 0x11: cpustate->IE1 = data; break;
80      case 0x12: cpustate->IR0 = data; break;
81      case 0x13: cpustate->IR1 = data; break;
82      case 0x19: cpustate->SYS = data; break;
83      case 0x1a: cpustate->CKC = data; break;
84      case 0x1c:
85      case 0x1d: sm8500_get_sp(cpustate); break;
86      case 0x1e: cpustate->PS0 = data; break;
87      case 0x1f: cpustate->PS1 = data; break;
7988   }
8089}
8190
91
8292INLINE UINT16 sm85cpu_mem_readword( sm8500_state *cpustate, UINT32 address )
8393{
8494   UINT16 value = (UINT16) sm85cpu_mem_readbyte( cpustate, address ) << 8;
r8771r8772
106116      cpustate->config.handle_dma = NULL;
107117      cpustate->config.handle_timers = NULL;
108118   }
109   cpustate->register_base = cpustate->internal_ram;
110119}
111120
112121static CPU_RESET( sm8500 )
r8771r8772
114123   sm8500_state *cpustate = get_safe_token(device);
115124
116125   cpustate->PC = 0x1020;
117   cpustate->IE0 = 0;
118   cpustate->IE1 = 0;
119   cpustate->IR0 = 0;
120   cpustate->IR1 = 0;
121   cpustate->P0 = 0xFF;
122   cpustate->P1 = 0xFF;
123   cpustate->P2 = 0xFF;
124   cpustate->P3 = 0;
125   cpustate->SYS = 0;
126   cpustate->CKC = 0; cpustate->clock_changed = 0;
127   cpustate->PS1 = 0;
128   cpustate->register_base = cpustate->internal_ram;
126   cpustate->clock_changed = 0;
129127   cpustate->halted = 0;
128   sm85cpu_mem_writeword(cpustate, 0x10, 0);                 // IE0, IE1
129   sm85cpu_mem_writeword(cpustate, 0x12, 0);                 // IR0, IR1
130   sm85cpu_mem_writeword(cpustate, 0x14, 0xffff);            // P0, P1
131   sm85cpu_mem_writeword(cpustate, 0x16, 0xff00);            // P2, P3
132   sm85cpu_mem_writebyte(cpustate, 0x19, 0);                 // SYS
133   sm85cpu_mem_writebyte(cpustate, 0x1a, 0);                 // CKC
134   sm85cpu_mem_writebyte(cpustate, 0x1f, 0);                 // PS1
135   sm85cpu_mem_writebyte(cpustate, 0x2b, 0xff);              // URTT
136   sm85cpu_mem_writebyte(cpustate, 0x2d, 0x42);              // URTS
137   sm85cpu_mem_writebyte(cpustate, 0x5f, 0x38);              // WDTC
130138}
131139
132140static CPU_EXIT( sm8500 )
133141{
134142}
135143
136#define PUSH_BYTE(X)   cpustate->SP = cpustate->SP - 1; \
137         if ( ( cpustate->SYS & 0x40 ) == 0 ) { \
138            cpustate->SP = cpustate->SP & 0xFF; \
139         } \
144#define PUSH_BYTE(X)   cpustate->SP--; \
145         if ( ( cpustate->SYS & 0x40 ) == 0 ) cpustate->SP &= 0xFF; \
140146         sm85cpu_mem_writebyte( cpustate, cpustate->SP, X );
141147
142148INLINE void sm8500_do_interrupt(sm8500_state *cpustate, UINT16 vector) {
149   /* Get regs from ram */
150   sm8500_get_sp(cpustate);
151   cpustate->SYS = memory_read_byte(cpustate->program, 0x19);   
152   cpustate->PS1 = memory_read_byte(cpustate->program, 0x1f);   
143153   /* Push PC */
144154   PUSH_BYTE( cpustate->PC & 0xFF );
145155   PUSH_BYTE( cpustate->PC >> 8 );
r8771r8772
147157   PUSH_BYTE( cpustate->PS1 );
148158   /* Clear I flag */
149159   cpustate->PS1 &= ~ 0x01;
160   /* save regs to ram */
161   memory_write_byte(cpustate->program, 0x1f, cpustate->PS1);
162   memory_write_byte(cpustate->program, 0x1d, cpustate->SP&0xFF);
163   if (cpustate->SYS&0x40) memory_write_byte(cpustate->program, 0x1c, cpustate->SP>>8);
150164   /* Change PC to address stored at "vector" */
151165   cpustate->PC = sm85cpu_mem_readword( cpustate, vector );
152166}
r8771r8772
157171      while( irqline < 11 ) {
158172         if ( cpustate->IFLAGS & ( 1 << irqline ) ) {
159173            cpustate->halted = 0;
174            cpustate->IE0 = memory_read_byte(cpustate->program, 0x10);
175            cpustate->IE1 = memory_read_byte(cpustate->program, 0x11);
176            cpustate->IR0 = memory_read_byte(cpustate->program, 0x12);
177            cpustate->IR1 = memory_read_byte(cpustate->program, 0x13);
178            cpustate->PS0 = memory_read_byte(cpustate->program, 0x1e);
179            cpustate->PS1 = memory_read_byte(cpustate->program, 0x1f);
160180            switch( irqline ) {
161            case ILL_INT:
181            case WDT_INT:
162182               sm8500_do_interrupt( cpustate, 0x101C );
163183               break;
164            case WDT_INT:
165               sm8500_do_interrupt( cpustate, 0x101E );
166               break;
184            case ILL_INT:
167185            case NMI_INT:
168186               sm8500_do_interrupt( cpustate, 0x101E );
169187               break;
r8771r8772
217235               break;
218236            }
219237            cpustate->IFLAGS &= ~ ( 1 << irqline );
238            memory_write_byte(cpustate->program, 0x12, cpustate->IR0);
239            memory_write_byte(cpustate->program, 0x13, cpustate->IR1);
220240         }
221241         irqline++;
222242      }
r8771r8772
227247{
228248   sm8500_state *cpustate = get_safe_token(device);
229249   UINT8   op;
230   UINT16 oldpc;
231250   int   mycycles;
232251
233252   do
r8771r8772
238257      UINT32   res;
239258
240259      debugger_instruction_hook(device, cpustate->PC);
241      oldpc = cpustate->PC;
260      cpustate->oldpc = cpustate->PC;
242261      mycycles = 0;
243262      sm8500_process_interrupts(cpustate);
244263      if ( !cpustate->halted ) {
245264         op = sm85cpu_mem_readbyte( cpustate, cpustate->PC++ );
265         cpustate->SYS = memory_read_byte(cpustate->program, 0x19);
266         cpustate->PS0 = memory_read_byte(cpustate->program, 0x1e);
267         cpustate->PS1 = memory_read_byte(cpustate->program, 0x1f);
268         sm8500_get_sp(cpustate);
246269         switch( op )
247270         {
248271#include "sm85ops.h"
249272         }
273         if (cpustate->SYS&0x40) memory_write_byte(cpustate->program,0x1c,cpustate->SP>>8);
274         memory_write_byte(cpustate->program,0x1d,cpustate->SP&0xFF);
275         memory_write_byte(cpustate->program,0x1e,cpustate->PS0);
276         memory_write_byte(cpustate->program,0x1f,cpustate->PS1);
250277      } else {
251278         mycycles = 4;
252279         if ( cpustate->config.handle_dma ) {
r8771r8772
278305   case STATE_GENPC:
279306   case SM8500_PC:      return cpustate->PC;
280307   case STATE_GENSP:
281   case SM8500_SP:      return ( cpustate->SYS & 0x40 ) ? cpustate->SP : cpustate->SP & 0xFF ;
282   case SM8500_PS:      return ( cpustate->PS0 << 8 ) | cpustate->PS1;
308   case SM8500_SP:      return cpustate->SP;
309   case SM8500_PS:      return sm85cpu_mem_readword( cpustate, 0x1e );
283310   case SM8500_SYS16:   return cpustate->SYS;
284311   case SM8500_RR0:   return sm85cpu_mem_readword( cpustate, 0x00 );
285312   case SM8500_RR2:   return sm85cpu_mem_readword( cpustate, 0x02 );
r8771r8772
289316   case SM8500_RR10:   return sm85cpu_mem_readword( cpustate, 0x0A );
290317   case SM8500_RR12:   return sm85cpu_mem_readword( cpustate, 0x0C );
291318   case SM8500_RR14:   return sm85cpu_mem_readword( cpustate, 0x0E );
292   case SM8500_IE0:   return cpustate->IE0;
293   case SM8500_IE1:   return cpustate->IE1;
294   case SM8500_IR0:   return cpustate->IR0;
295   case SM8500_IR1:   return cpustate->IR1;
296   case SM8500_P0:      return cpustate->P0;
297   case SM8500_P1:      return cpustate->P1;
298   case SM8500_P2:      return cpustate->P2;
299   case SM8500_P3:      return cpustate->P3;
300   case SM8500_SYS:   return cpustate->SYS;
301   case SM8500_CKC:   return cpustate->CKC;
302   case SM8500_SPH:   return (cpustate->SP >> 8);
303   case SM8500_SPL:   return cpustate->SP & 0xFF;
304   case SM8500_PS0:   return cpustate->PS0;
305   case SM8500_PS1:   return cpustate->PS1;
306   case SM8500_P0C:   return cpustate->P0C;
307   case SM8500_P1C:   return cpustate->P1C;
308   case SM8500_P2C:   return cpustate->P2C;
309   case SM8500_P3C:   return cpustate->P3C;
319   case SM8500_IE0:   return sm85cpu_mem_readbyte( cpustate, 0x10 );
320   case SM8500_IE1:   return sm85cpu_mem_readbyte( cpustate, 0x11 );
321   case SM8500_IR0:   return sm85cpu_mem_readbyte( cpustate, 0x12 );
322   case SM8500_IR1:   return sm85cpu_mem_readbyte( cpustate, 0x13 );
323   case SM8500_P0:      return sm85cpu_mem_readbyte( cpustate, 0x14 );
324   case SM8500_P1:      return sm85cpu_mem_readbyte( cpustate, 0x15 );
325   case SM8500_P2:      return sm85cpu_mem_readbyte( cpustate, 0x16 );
326   case SM8500_P3:      return sm85cpu_mem_readbyte( cpustate, 0x17 );
327   case SM8500_SYS:   return sm85cpu_mem_readbyte( cpustate, 0x19 );
328   case SM8500_CKC:   return sm85cpu_mem_readbyte( cpustate, 0x1a );
329   case SM8500_SPH:   return sm85cpu_mem_readbyte( cpustate, 0x1c );
330   case SM8500_SPL:   return sm85cpu_mem_readbyte( cpustate, 0x1d );
331   case SM8500_PS0:   return sm85cpu_mem_readbyte( cpustate, 0x1e );
332   case SM8500_PS1:   return sm85cpu_mem_readbyte( cpustate, 0x1f );
333   case SM8500_P0C:   return sm85cpu_mem_readbyte( cpustate, 0x20 );
334   case SM8500_P1C:   return sm85cpu_mem_readbyte( cpustate, 0x21 );
335   case SM8500_P2C:   return sm85cpu_mem_readbyte( cpustate, 0x22 );
336   case SM8500_P3C:   return sm85cpu_mem_readbyte( cpustate, 0x23 );
310337   }
311338   return 0;
312339}
r8771r8772
318345   case STATE_GENPC:
319346   case SM8500_PC:      cpustate->PC = val; break;
320347   case STATE_GENSP:
321   case SM8500_SP:      cpustate->SP = val; break;
322   case SM8500_PS:      sm8500_set_reg( cpustate, SM8500_PS0, ( val >> 8 ) & 0xFF ); sm8500_set_reg( cpustate, SM8500_PS1, val & 0xFF ); break;
323   case SM8500_SYS16:   cpustate->SYS = val; break;
348   case SM8500_SP:      cpustate->SP = val; memory_write_byte( cpustate->program, 0x1d, val&0xff); if (cpustate->SYS&0x40) memory_write_byte( cpustate->program, 0x1c, val>>8); break;
349   case SM8500_PS:      sm85cpu_mem_writeword( cpustate, 0x1e, val); break;
350   case SM8500_SYS16:   val&=0xff; sm85cpu_mem_writebyte( cpustate, 0x19, val); break;
324351   case SM8500_RR0:   sm85cpu_mem_writeword( cpustate, 0x00, val); break;
325352   case SM8500_RR2:   sm85cpu_mem_writeword( cpustate, 0x02, val); break;
326353   case SM8500_RR4:   sm85cpu_mem_writeword( cpustate, 0x04, val); break;
r8771r8772
329356   case SM8500_RR10:   sm85cpu_mem_writeword( cpustate, 0x0A, val); break;
330357   case SM8500_RR12:   sm85cpu_mem_writeword( cpustate, 0x0C, val); break;
331358   case SM8500_RR14:   sm85cpu_mem_writeword( cpustate, 0x0E, val); break;
332   case SM8500_IE0:   cpustate->IE0 = val; break;
333   case SM8500_IE1:   cpustate->IE1 = val; break;
334   case SM8500_IR0:   cpustate->IR0 = val; break;
335   case SM8500_IR1:   cpustate->IR1 = val; break;
336   case SM8500_P0:      cpustate->P0 = val; break;
337   case SM8500_P1:      cpustate->P1 = val; break;
338   case SM8500_P2:      cpustate->P2 = val; break;
339   case SM8500_P3:      cpustate->P3 = val; break;
340   case SM8500_SYS:   cpustate->SYS = val; break;
341   case SM8500_CKC:   cpustate->CKC = val; if ( val & 0x80 ) { cpustate->clock_changed = 1; }; break;
342   case SM8500_SPH:   cpustate->SP = ( ( val & 0xFF ) << 8 ) | ( cpustate->SP & 0xFF ); break;
343   case SM8500_SPL:   cpustate->SP = ( cpustate->SP & 0xFF00 ) | ( val & 0xFF ); break;
344   case SM8500_PS0:   cpustate->PS0 = val; cpustate->register_base = cpustate->internal_ram + ( val & 0xF8 ); break;
345   case SM8500_PS1:   cpustate->PS1 = val; break;
346   case SM8500_P0C:   cpustate->P0C = val; break;
347   case SM8500_P1C:   cpustate->P1C = val; break;
348   case SM8500_P2C:   cpustate->P2C = val; break;
349   case SM8500_P3C:   cpustate->P3C = val; break;
359   case SM8500_IE0:   sm85cpu_mem_writebyte( cpustate, 0x10, val); break;
360   case SM8500_IE1:   sm85cpu_mem_writebyte( cpustate, 0x11, val); break;
361   case SM8500_IR0:   sm85cpu_mem_writebyte( cpustate, 0x12, val); break;
362   case SM8500_IR1:   sm85cpu_mem_writebyte( cpustate, 0x13, val); break;
363   case SM8500_P0:      sm85cpu_mem_writebyte( cpustate, 0x14, val); break;
364   case SM8500_P1:      sm85cpu_mem_writebyte( cpustate, 0x15, val); break;
365   case SM8500_P2:      sm85cpu_mem_writebyte( cpustate, 0x16, val); break;
366   case SM8500_P3:      sm85cpu_mem_writebyte( cpustate, 0x17, val); break;
367   case SM8500_SYS:   sm85cpu_mem_writebyte( cpustate, 0x19, val); break;
368   case SM8500_CKC:   sm85cpu_mem_writebyte( cpustate, 0x1a, val); if ( val & 0x80 ) { cpustate->clock_changed = 1; }; break;
369   case SM8500_SPH:   sm85cpu_mem_writebyte( cpustate, 0x1c, val); break;
370   case SM8500_SPL:   sm85cpu_mem_writebyte( cpustate, 0x1d, val); break;
371   case SM8500_PS0:   sm85cpu_mem_writebyte( cpustate, 0x1e, val); break;
372   case SM8500_PS1:   sm85cpu_mem_writebyte( cpustate, 0x1f, val); break;
373   case SM8500_P0C:   sm85cpu_mem_writebyte( cpustate, 0x20, val); break;
374   case SM8500_P1C:   sm85cpu_mem_writebyte( cpustate, 0x21, val); break;
375   case SM8500_P2C:   sm85cpu_mem_writebyte( cpustate, 0x22, val); break;
376   case SM8500_P3C:   sm85cpu_mem_writebyte( cpustate, 0x23, val); break;
350377   }
351378}
352379
353380static void sm8500_set_irq_line( sm8500_state *cpustate, int irqline, int state )
354381{
382   cpustate->IR0 = memory_read_byte(cpustate->program, 0x12);
383   cpustate->IR1 = memory_read_byte(cpustate->program, 0x13);
355384   if ( state == ASSERT_LINE ) {
356385      cpustate->IFLAGS |= ( 0x01 << irqline );
357386      cpustate->CheckInterrupts = 1;
r8771r8772
381410         cpustate->CheckInterrupts = 0;
382411      }
383412   }
413   memory_write_byte(cpustate->program, 0x12, cpustate->IR0);
414   memory_write_byte(cpustate->program, 0x13, cpustate->IR1);
384415}
385416
386UINT8 *sm8500_get_internal_ram(legacy_cpu_device *device)
387{
388   sm8500_state *cpustate = get_safe_token(device);
389   return cpustate->internal_ram;
390}
391
392417static CPU_SET_INFO( sm8500 )
393418{
394419   sm8500_state *cpustate = get_safe_token(device);
r8771r8772
438463   case CPUINFO_INT_REGISTER + SM8500_P1C:
439464   case CPUINFO_INT_REGISTER + SM8500_P2C:
440465   case CPUINFO_INT_REGISTER + SM8500_P3C:
441                     sm8500_set_reg( cpustate, state - CPUINFO_INT_REGISTER, info->i ); break;
466      sm8500_set_reg( cpustate, state - CPUINFO_INT_REGISTER, info->i ); break;
442467
443468   }
444469}
r8771r8772
509534                        info->i = sm8500_get_reg( cpustate, state - CPUINFO_INT_REGISTER ); break;
510535   case CPUINFO_INT_REGISTER + STATE_GENPC:         info->i = sm8500_get_reg( cpustate, SM8500_PC ); break;
511536   case CPUINFO_INT_REGISTER + STATE_GENSP:         info->i = sm8500_get_reg( cpustate, SM8500_SP ); break;
512   case CPUINFO_INT_PREVIOUSPC:            info->i = 0x0000; break;
537   case CPUINFO_INT_PREVIOUSPC:            info->i = cpustate->oldpc; break;
513538
514539
515540   case CPUINFO_FCT_SET_INFO:            info->setinfo = CPU_SET_INFO_NAME(sm8500); break;
r8771r8772
548573   case CPUINFO_STR_REGISTER + SM8500_PC:         sprintf(info->s, "PC:%04X", cpustate->PC); break;
549574   case CPUINFO_STR_REGISTER + SM8500_SP:         sprintf(info->s, "SP:%04X", cpustate->SP); break;
550575   case CPUINFO_STR_REGISTER + SM8500_PS:         sprintf(info->s, "PS:%04X", ( cpustate->PS0 << 8 ) | cpustate->PS1 ); break;
551   case CPUINFO_STR_REGISTER + SM8500_SYS16:      sprintf(info->s, "SYS:%04X", cpustate->SYS ); break;
576   case CPUINFO_STR_REGISTER + SM8500_SYS16:      sprintf(info->s, "SYS:%02X", cpustate->SYS ); break;
552577   }
553578}
554579

Previous 15994 Revisions Next


© 1998-2018 The MESS Team