~ubuntu-branches/ubuntu/lucid/sdlmame/lucid

« back to all changes in this revision

Viewing changes to src/emu/cpu/mc68hc11/mc68hc11.c

  • Committer: Bazaar Package Importer
  • Author(s): Cesare Falco
  • Date: 2009-11-03 17:10:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091103171015-6hop4ory5lxnumpn
Tags: 0.135-0ubuntu1
* New upstream release - Closes (LP: #403212)
* debian/watch: unstable releases are no longer detected
* mame.ini: added the cheat subdirectories to cheatpath so zipped
  cheatfiles will be searched too
* renamed crsshair subdirectory to crosshair to reflect upstream change
* mame.ini: renamed references to crosshair subdirectory (see above)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
   Motorola MC68HC11 emulator
3
3
 
4
 
   Written by Ville Linde
 
4
   Written by Ville Linde & Angelo Salese
 
5
 
 
6
TODO:
 
7
- Interrupts handling is really bare-bones, just to make Hit Poker happy;
 
8
- Complete opcodes hook-up;
 
9
- Emulate the MC68HC12 (same as HC11 with a bunch of new opcodes);
 
10
 
5
11
 */
6
12
 
7
13
#include "debugger.h"
53
59
        int ad_channel;
54
60
 
55
61
        cpu_irq_callback irq_callback;
 
62
        UINT8 irq_state[2];
56
63
        const device_config *device;
57
64
        const address_space *program;
58
65
        const address_space *io;
59
66
        int icount;
 
67
 
60
68
        int ram_position;
61
69
        int reg_position;
62
70
        UINT8 *internal_ram;
 
71
 
 
72
        int has_extended_io; // extended I/O enable flag
63
73
        int internal_ram_size;
 
74
 
 
75
        UINT8 wait_state,stop_state;
 
76
 
 
77
        UINT8 tflg1;
64
78
};
65
79
 
66
80
INLINE hc11_state *get_safe_token(const device_config *device)
87
101
                        return memory_read_byte(cpustate->io, MC68HC11_IO_PORTA);
88
102
                case 0x01:              /* DDRA */
89
103
                        return 0;
 
104
                case 0x02:              /* PIOC */
 
105
                        return 0;
 
106
                case 0x03:              /* PORTC */
 
107
                        return memory_read_byte(cpustate->io, MC68HC11_IO_PORTC);
 
108
                case 0x04:              /* PORTB */
 
109
                        return memory_read_byte(cpustate->io, MC68HC11_IO_PORTB);
 
110
                case 0x08:              /* PORTD */
 
111
                        return memory_read_byte(cpustate->io, MC68HC11_IO_PORTD);
90
112
                case 0x09:              /* DDRD */
91
113
                        return 0;
 
114
                case 0x0a:              /* PORTE */
 
115
                        return memory_read_byte(cpustate->io, MC68HC11_IO_PORTE);
 
116
                case 0x23:
 
117
                        return cpustate->tflg1;
92
118
                case 0x28:              /* SPCR1 */
93
119
                        return 0;
94
120
                case 0x30:              /* ADCTL */
167
193
                        return 0;
168
194
        }
169
195
 
170
 
        fatalerror("HC11: regs_r %02X", reg);
 
196
        logerror("HC11: regs_r %02X\n", reg);
171
197
        return 0; // Dummy
172
198
}
173
199
 
183
209
                case 0x01:              /* DDRA */
184
210
                        //mame_printf_debug("HC11: ddra = %02X\n", value);
185
211
                        return;
 
212
                case 0x03:              /* PORTC */
 
213
                        memory_write_byte(cpustate->io, MC68HC11_IO_PORTC, value);
 
214
                        return;
 
215
                case 0x04:              /* PORTC */
 
216
                        memory_write_byte(cpustate->io, MC68HC11_IO_PORTB, value);
 
217
                        return;
186
218
                case 0x08:              /* PORTD */
187
 
                        memory_write_byte(cpustate->io, MC68HC11_IO_PORTD, value);
 
219
                        memory_write_byte(cpustate->io, MC68HC11_IO_PORTD, value); //mask & 0x3f?
188
220
                        return;
189
221
                case 0x09:              /* DDRD */
190
222
                        //mame_printf_debug("HC11: ddrd = %02X\n", value);
191
223
                        return;
 
224
                case 0x0a:              /* PORTE */
 
225
                        memory_write_byte(cpustate->io, MC68HC11_IO_PORTE, value);
 
226
                        return;
192
227
                case 0x22:              /* TMSK1 */
193
228
                        return;
 
229
                case 0x23:
 
230
                        cpustate->tflg1 = value;
 
231
                        return;
194
232
                case 0x24:              /* TMSK2 */
195
233
                        return;
196
234
                case 0x28:              /* SPCR1 */
202
240
                        return;
203
241
                case 0x39:              /* OPTION */
204
242
                        return;
 
243
                case 0x3a:              /* COPRST (watchdog) */
 
244
                        return;
205
245
 
206
246
                case 0x3d:              /* INIT */
207
247
                {
256
296
                        return;
257
297
 
258
298
        }
259
 
        fatalerror("HC11: regs_w %02X, %02X", reg, value);
 
299
 
 
300
        logerror("HC11: regs_w %02X, %02X\n", reg, value);
260
301
}
261
302
 
262
303
/*****************************************************************************/
276
317
 
277
318
INLINE UINT8 READ8(hc11_state *cpustate, UINT32 address)
278
319
{
279
 
        if(address >= cpustate->reg_position && address < cpustate->reg_position+0x100)
 
320
        if(address >= cpustate->reg_position && address < cpustate->reg_position+(cpustate->has_extended_io ? 0x100 : 0x40))
280
321
        {
281
322
                return hc11_regs_r(cpustate, address);
282
323
        }
289
330
 
290
331
INLINE void WRITE8(hc11_state *cpustate, UINT32 address, UINT8 value)
291
332
{
292
 
        if(address >= cpustate->reg_position && address < cpustate->reg_position+0x100)
 
333
        if(address >= cpustate->reg_position && address < cpustate->reg_position+(cpustate->has_extended_io ? 0x100 : 0x40))
293
334
        {
294
335
                hc11_regs_w(cpustate, address, value);
295
336
                return;
328
369
        hc11_state *cpustate = get_safe_token(device);
329
370
        int i;
330
371
 
 
372
        const hc11_config *conf = (const hc11_config *)device->static_config;
 
373
 
331
374
        /* clear the opcode tables */
332
375
        for(i=0; i < 256; i++) {
333
376
                hc11_optable[i] = HC11OP(invalid);
355
398
                }
356
399
        }
357
400
 
358
 
        cpustate->internal_ram_size = 1280;             /* FIXME: this is for MC68HC11M0 */
 
401
        if(conf)
 
402
        {
 
403
                cpustate->has_extended_io = conf->has_extended_io;
 
404
                cpustate->internal_ram_size = conf->internal_ram_size;
 
405
        }
 
406
        else
 
407
        {
 
408
                /* defaults it to the HC11M0 version for now (I might strip this down on a later date) */
 
409
                cpustate->has_extended_io = 1;
 
410
                cpustate->internal_ram_size = 1280;
 
411
        }
 
412
 
359
413
        cpustate->internal_ram = auto_alloc_array(device->machine, UINT8, cpustate->internal_ram_size);
360
414
 
361
415
        cpustate->reg_position = 0;
370
424
{
371
425
        hc11_state *cpustate = get_safe_token(device);
372
426
        cpustate->pc = READ16(cpustate, 0xfffe);
 
427
        cpustate->wait_state = 0;
 
428
        cpustate->stop_state = 0;
 
429
        cpustate->ccr = CC_X | CC_I | CC_S;
 
430
        cpustate->reg_position = 0x1000;
 
431
        cpustate->ram_position = 0;
373
432
}
374
433
 
375
434
static CPU_EXIT( hc11 )
377
436
 
378
437
}
379
438
 
 
439
/*
 
440
IRQ table vectors:
 
441
0xffd6: SCI
 
442
0xffd8: SPI
 
443
0xffda: Pulse Accumulator Input Edge
 
444
0xffdc: Pulse Accumulator Overflow
 
445
0xffde: Timer Overflow
 
446
0xffe0: Timer Output Capture 5
 
447
0xffe2: Timer Output Capture 4
 
448
0xffe4: Timer Output Capture 3
 
449
0xffe6: Timer Output Capture 2
 
450
0xffe8: Timer Output Capture 1
 
451
0xffea: Timer Input Capture 3
 
452
0xffec: Timer Input Capture 2
 
453
0xffee: Timer Input Capture 1
 
454
0xfff0: Real Time Int
 
455
0xfff2: IRQ
 
456
0xfff4: XIRQ
 
457
0xfff6: SWI (Trap IRQ)
 
458
0xfff8: Illegal Opcode (NMI)
 
459
0xfffa: CO-Processor Fail
 
460
0xfffc: Clock Monitor
 
461
0xfffe: RESET
 
462
*/
 
463
 
 
464
static void check_irq_lines(hc11_state *cpustate)
 
465
{
 
466
        if( cpustate->irq_state[MC68HC11_IRQ_LINE]!=CLEAR_LINE && (!(cpustate->ccr & CC_I)) )
 
467
        {
 
468
                UINT16 pc_vector;
 
469
 
 
470
                if(cpustate->wait_state == 0)
 
471
                {
 
472
                        PUSH16(cpustate, cpustate->pc);
 
473
                        PUSH16(cpustate, cpustate->iy);
 
474
                        PUSH16(cpustate, cpustate->ix);
 
475
                        PUSH8(cpustate, REG_A);
 
476
                        PUSH8(cpustate, REG_B);
 
477
                        PUSH8(cpustate, cpustate->ccr);
 
478
                }
 
479
                pc_vector = READ16(cpustate, 0xfff2);
 
480
                SET_PC(cpustate, pc_vector);
 
481
                cpustate->ccr |= CC_I; //irq taken, mask the flag
 
482
                if(cpustate->wait_state == 1) { cpustate->wait_state = 2; }
 
483
                if(cpustate->stop_state == 1) { cpustate->stop_state = 2; }
 
484
                (void)(*cpustate->irq_callback)(cpustate->device, MC68HC11_IRQ_LINE);
 
485
        }
 
486
}
 
487
 
 
488
static void set_irq_line(hc11_state *cpustate, int irqline, int state)
 
489
{
 
490
        cpustate->irq_state[irqline] = state;
 
491
        if (state == CLEAR_LINE) return;
 
492
        check_irq_lines(cpustate);
 
493
}
 
494
 
380
495
static CPU_EXECUTE( hc11 )
381
496
{
382
497
        hc11_state *cpustate = get_safe_token(device);
387
502
        {
388
503
                UINT8 op;
389
504
 
 
505
                check_irq_lines(cpustate);
 
506
 
390
507
                cpustate->ppc = cpustate->pc;
391
508
                debugger_instruction_hook(device, cpustate->pc);
392
509
 
405
522
 
406
523
        switch (state)
407
524
        {
 
525
                case CPUINFO_INT_INPUT_STATE + MC68HC11_IRQ_LINE:       set_irq_line(cpustate, MC68HC11_IRQ_LINE, info->i);             break;
 
526
 
408
527
                /* --- the following bits of info are set as 64-bit signed integers --- */
409
528
                case CPUINFO_INT_PC:                                                    cpustate->pc = info->i;                                         break;
410
 
                case CPUINFO_INT_REGISTER + HC11_PC:                    cpustate->pc = info->i;                                                 break;
 
529
                case CPUINFO_INT_REGISTER + HC11_PC:                    cpustate->pc = info->i;                                         break;
411
530
                case CPUINFO_INT_REGISTER + HC11_SP:                    cpustate->sp = info->i;                                         break;
412
531
                case CPUINFO_INT_REGISTER + HC11_A:                             cpustate->d.d8.a = info->i;                                     break;
413
532
                case CPUINFO_INT_REGISTER + HC11_B:                             cpustate->d.d8.b = info->i;                                     break;
423
542
        switch(state)
424
543
        {
425
544
                /* --- the following bits of info are returned as 64-bit signed integers --- */
426
 
                case CPUINFO_INT_CONTEXT_SIZE:                                  info->i = sizeof(hc11_state);                   break;
427
 
                case CPUINFO_INT_INPUT_LINES:                                   info->i = 1;                                                    break;
428
 
                case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                    info->i = 0;                                                    break;
429
 
                case CPUINFO_INT_ENDIANNESS:                                    info->i = ENDIANNESS_BIG;                                       break;
430
 
                case CPUINFO_INT_CLOCK_MULTIPLIER:                              info->i = 1;                                                    break;
431
 
                case CPUINFO_INT_CLOCK_DIVIDER:                                 info->i = 1;                                                    break;
432
 
                case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                 info->i = 1;                                                    break;
433
 
                case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                 info->i = 5;                                                    break;
434
 
                case CPUINFO_INT_MIN_CYCLES:                                    info->i = 1;                                                    break;
435
 
                case CPUINFO_INT_MAX_CYCLES:                                    info->i = 41;                                                   break;
436
 
 
437
 
                case CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 8;                                    break;
438
 
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 16;                                   break;
439
 
                case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = 0;                                    break;
440
 
                case CPUINFO_INT_DATABUS_WIDTH_DATA:    info->i = 0;                                    break;
441
 
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:    info->i = 0;                                    break;
442
 
                case CPUINFO_INT_ADDRBUS_SHIFT_DATA:    info->i = 0;                                    break;
443
 
                case CPUINFO_INT_DATABUS_WIDTH_IO:              info->i = 8;                                    break;
444
 
                case CPUINFO_INT_ADDRBUS_WIDTH_IO:              info->i = 8;                                    break;
445
 
                case CPUINFO_INT_ADDRBUS_SHIFT_IO:              info->i = 0;                                    break;
446
 
 
447
 
                case CPUINFO_INT_INPUT_STATE:                                   info->i = CLEAR_LINE;                                   break;
448
 
 
449
 
                case CPUINFO_INT_PREVIOUSPC:                                    /* not implemented */                                   break;
 
545
                case CPUINFO_INT_CONTEXT_SIZE:                                          info->i = sizeof(hc11_state);   break;
 
546
                case CPUINFO_INT_INPUT_LINES:                                           info->i = 1;                                    break;
 
547
                case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                            info->i = 0;                                    break;
 
548
                case DEVINFO_INT_ENDIANNESS:                                            info->i = ENDIANNESS_BIG;               break;
 
549
                case CPUINFO_INT_CLOCK_MULTIPLIER:                                      info->i = 1;                                    break;
 
550
                case CPUINFO_INT_CLOCK_DIVIDER:                                         info->i = 1;                                    break;
 
551
                case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                         info->i = 1;                                    break;
 
552
                case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                         info->i = 5;                                    break;
 
553
                case CPUINFO_INT_MIN_CYCLES:                                            info->i = 1;                                    break;
 
554
                case CPUINFO_INT_MAX_CYCLES:                                            info->i = 41;                                   break;
 
555
 
 
556
                case CPUINFO_INT_DATABUS_WIDTH_PROGRAM:                         info->i = 8;                                    break;
 
557
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM:                         info->i = 16;                                   break;
 
558
                case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM:                         info->i = 0;                                    break;
 
559
                case CPUINFO_INT_DATABUS_WIDTH_DATA:                            info->i = 0;                                    break;
 
560
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:                            info->i = 0;                                    break;
 
561
                case CPUINFO_INT_ADDRBUS_SHIFT_DATA:                            info->i = 0;                                    break;
 
562
                case CPUINFO_INT_DATABUS_WIDTH_IO:                                      info->i = 8;                                    break;
 
563
                case CPUINFO_INT_ADDRBUS_WIDTH_IO:                                      info->i = 8;                                    break;
 
564
                case CPUINFO_INT_ADDRBUS_SHIFT_IO:                                      info->i = 0;                                    break;
 
565
 
 
566
                case CPUINFO_INT_INPUT_STATE + MC68HC11_IRQ_LINE:       info->i = cpustate->irq_state[MC68HC11_IRQ_LINE]; break;
 
567
 
 
568
                case CPUINFO_INT_PREVIOUSPC:                                            /* not implemented */                   break;
450
569
 
451
570
                case CPUINFO_INT_PC:    /* intentional fallthrough */
452
 
                case CPUINFO_INT_REGISTER + HC11_PC:                    info->i = cpustate->pc;                                         break;
453
 
                case CPUINFO_INT_REGISTER + HC11_SP:                    info->i = cpustate->sp;                                         break;
454
 
                case CPUINFO_INT_REGISTER + HC11_A:                             info->i = cpustate->d.d8.a;                                     break;
455
 
                case CPUINFO_INT_REGISTER + HC11_B:                             info->i = cpustate->d.d8.b;                                     break;
456
 
                case CPUINFO_INT_REGISTER + HC11_IX:                    info->i = cpustate->ix;                                         break;
457
 
                case CPUINFO_INT_REGISTER + HC11_IY:                    info->i = cpustate->iy;                                         break;
 
571
                case CPUINFO_INT_REGISTER + HC11_PC:                    info->i = cpustate->pc;                         break;
 
572
                case CPUINFO_INT_REGISTER + HC11_SP:                    info->i = cpustate->sp;                         break;
 
573
                case CPUINFO_INT_REGISTER + HC11_A:                             info->i = cpustate->d.d8.a;                     break;
 
574
                case CPUINFO_INT_REGISTER + HC11_B:                             info->i = cpustate->d.d8.b;                     break;
 
575
                case CPUINFO_INT_REGISTER + HC11_IX:                    info->i = cpustate->ix;                         break;
 
576
                case CPUINFO_INT_REGISTER + HC11_IY:                    info->i = cpustate->iy;                         break;
458
577
 
459
578
                /* --- the following bits of info are returned as pointers to data or functions --- */
460
579
                case CPUINFO_FCT_SET_INFO:                                              info->setinfo = CPU_SET_INFO_NAME(mc68hc11);            break;
463
582
                case CPUINFO_FCT_EXIT:                                                  info->exit = CPU_EXIT_NAME(hc11);                                       break;
464
583
                case CPUINFO_FCT_EXECUTE:                                               info->execute = CPU_EXECUTE_NAME(hc11);                 break;
465
584
                case CPUINFO_FCT_BURN:                                                  info->burn = NULL;                                              break;
466
 
                case CPUINFO_FCT_DISASSEMBLE:                                   info->disassemble = hc11_disasm;                break;
 
585
                case CPUINFO_FCT_DISASSEMBLE:                                   info->disassemble = CPU_DISASSEMBLE_NAME(hc11);         break;
467
586
                case CPUINFO_PTR_INSTRUCTION_COUNTER:                   info->icount = &cpustate->icount;                       break;
468
587
 
469
588
                /* --- the following bits of info are returned as NULL-terminated strings --- */
470
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "MC68HC11");                    break;
471
 
                case CPUINFO_STR_CORE_FAMILY:                                   strcpy(info->s, "Motorola MC68HC11");   break;
472
 
                case CPUINFO_STR_CORE_VERSION:                                  strcpy(info->s, "1.0");                                 break;
473
 
                case CPUINFO_STR_CORE_FILE:                                             strcpy(info->s, __FILE__);                              break;
474
 
                case CPUINFO_STR_CORE_CREDITS:                                  strcpy(info->s, "Copyright Ville Linde"); break;
 
589
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "MC68HC11");                    break;
 
590
                case DEVINFO_STR_FAMILY:                                        strcpy(info->s, "Motorola MC68HC11");   break;
 
591
                case DEVINFO_STR_VERSION:                                       strcpy(info->s, "1.0");                                 break;
 
592
                case DEVINFO_STR_SOURCE_FILE:                                           strcpy(info->s, __FILE__);                              break;
 
593
                case DEVINFO_STR_CREDITS:                                       strcpy(info->s, "Copyright Ville Linde"); break;
475
594
 
476
595
                case CPUINFO_STR_FLAGS:
477
596
                        sprintf(info->s, "%c%c%c%c%c%c%c%c",