diff --git a/src/emu/cpu/mc68hc11/mc68hc11.c b/src/emu/cpu/mc68hc11/mc68hc11.c index 9e3b033bada..5d7045bf8b8 100644 --- a/src/emu/cpu/mc68hc11/mc68hc11.c +++ b/src/emu/cpu/mc68hc11/mc68hc11.c @@ -33,6 +33,8 @@ enum #define CC_V 0x02 #define CC_C 0x01 +static const int div_tab[4] = { 1, 4, 8, 16 }; + typedef struct _hc11_state hc11_state; struct _hc11_state { @@ -77,7 +79,13 @@ struct _hc11_state UINT8 wait_state,stop_state; - UINT8 tflg1; + UINT8 tflg1, tmsk1; + UINT16 toc1; + UINT16 tcnt; +// UINT8 por; + UINT8 pr; + + UINT64 frc_base; }; INLINE hc11_state *get_safe_token(device_t *device) @@ -114,6 +122,10 @@ static UINT8 hc11_regs_r(hc11_state *cpustate, UINT32 address) return 0; case 0x0a: /* PORTE */ return cpustate->io->read_byte(MC68HC11_IO_PORTE); + case 0x0e: /* TCNT */ + return cpustate->tcnt >> 8; + case 0x0f: + return cpustate->tcnt & 0xff; case 0x23: return cpustate->tflg1; case 0x28: /* SPCR1 */ @@ -225,12 +237,25 @@ static void hc11_regs_w(hc11_state *cpustate, UINT32 address, UINT8 value) case 0x0a: /* PORTE */ cpustate->io->write_byte(MC68HC11_IO_PORTE, value); return; + case 0x0e: /* TCNT */ + case 0x0f: + logerror("HC11: TCNT register write %02x %02x!\n",address,value); + return; + case 0x16: /* TOC1 */ + /* TODO: inhibit for one bus cycle */ + cpustate->toc1 = (value << 8) | (cpustate->toc1 & 0xff); + return; + case 0x17: + cpustate->toc1 = (value & 0xff) | (cpustate->toc1 & 0xff00); + return; case 0x22: /* TMSK1 */ + cpustate->tmsk1 = value; return; case 0x23: - cpustate->tflg1 = value; + cpustate->tflg1 &= ~value; return; case 0x24: /* TMSK2 */ + cpustate->pr = value & 3; return; case 0x28: /* SPCR1 */ return; @@ -251,7 +276,7 @@ static void hc11_regs_w(hc11_state *cpustate, UINT32 address, UINT8 value) if (reg_page == ram_page) { cpustate->reg_position = reg_page << 12; - cpustate->ram_position = (ram_page << 12) + 0x100; + cpustate->ram_position = (ram_page << 12) + (cpustate->has_extended_io) ? 0x100 : 0x80; } else { cpustate->reg_position = reg_page << 12; cpustate->ram_position = ram_page << 12; @@ -430,6 +455,10 @@ static CPU_RESET( hc11 ) cpustate->stop_state = 0; cpustate->ccr = CC_X | CC_I | CC_S; hc11_regs_w(cpustate,0x3d,cpustate->init_value); + cpustate->toc1 = 0xffff; + cpustate->tcnt = 0xffff; +// cpustate->por = 1; // for first timer overflow / compare stuff + cpustate->pr = 3; // timer prescale } static CPU_EXIT( hc11 ) @@ -484,6 +513,53 @@ static void check_irq_lines(hc11_state *cpustate) if(cpustate->stop_state == 1) { cpustate->stop_state = 2; } (void)(*cpustate->irq_callback)(cpustate->device, MC68HC11_IRQ_LINE); } + + /* check timers here */ + { + int divider = div_tab[cpustate->pr & 3]; + UINT64 cur_time = cpustate->device->total_cycles(); + UINT64 add = (cur_time - cpustate->frc_base) / divider; + + if (add > 0) + { + int i; + + for(i=0;itcnt++; + if(cpustate->tcnt == cpustate->toc1) + { + cpustate->tflg1 |= 0x80; + cpustate->irq_state[MC68HC11_TOC1_LINE] = ASSERT_LINE; + } + } + + cpustate->frc_base = cur_time; + } + } + + if( cpustate->irq_state[MC68HC11_TOC1_LINE]!=CLEAR_LINE && (!(cpustate->ccr & CC_I)) && cpustate->tmsk1 & 0x80) + { + UINT16 pc_vector; + + if(cpustate->wait_state == 0) + { + PUSH16(cpustate, cpustate->pc); + PUSH16(cpustate, cpustate->iy); + PUSH16(cpustate, cpustate->ix); + PUSH8(cpustate, REG_A); + PUSH8(cpustate, REG_B); + PUSH8(cpustate, cpustate->ccr); + } + pc_vector = READ16(cpustate, 0xffe8); + SET_PC(cpustate, pc_vector); + cpustate->ccr |= CC_I; //irq taken, mask the flag + if(cpustate->wait_state == 1) { cpustate->wait_state = 2; } + if(cpustate->stop_state == 1) { cpustate->stop_state = 2; } + (void)(*cpustate->irq_callback)(cpustate->device, MC68HC11_TOC1_LINE); + cpustate->irq_state[MC68HC11_TOC1_LINE] = CLEAR_LINE; // auto-ack irq + } + } static void set_irq_line(hc11_state *cpustate, int irqline, int state) @@ -520,6 +596,7 @@ static CPU_SET_INFO( mc68hc11 ) switch (state) { case CPUINFO_INT_INPUT_STATE + MC68HC11_IRQ_LINE: set_irq_line(cpustate, MC68HC11_IRQ_LINE, info->i); break; + case CPUINFO_INT_INPUT_STATE + MC68HC11_TOC1_LINE: set_irq_line(cpustate, MC68HC11_TOC1_LINE, info->i); break; /* --- the following bits of info are set as 64-bit signed integers --- */ case CPUINFO_INT_PC: cpustate->pc = info->i; break; diff --git a/src/emu/cpu/mc68hc11/mc68hc11.h b/src/emu/cpu/mc68hc11/mc68hc11.h index faf33634dfa..06bb34086d0 100644 --- a/src/emu/cpu/mc68hc11/mc68hc11.h +++ b/src/emu/cpu/mc68hc11/mc68hc11.h @@ -29,6 +29,7 @@ DECLARE_LEGACY_CPU_DEVICE(MC68HC11, mc68hc11); #define MC68HC11_IO_AD7 0x17 #define MC68HC11_IRQ_LINE 0 +#define MC68HC11_TOC1_LINE 1 typedef struct _hc11_config hc11_config; struct _hc11_config diff --git a/src/mame/drivers/30test.c b/src/mame/drivers/30test.c index 0bfe257c07a..e195c9b351a 100644 --- a/src/mame/drivers/30test.c +++ b/src/mame/drivers/30test.c @@ -38,12 +38,28 @@ static SCREEN_UPDATE( 30test ) return 0; } +static READ8_HANDLER( unk_r ) +{ + return 1; +} + +static READ8_HANDLER(namco30test_pcbid_r) +{ + static const char pcb_id[] = + {"NAMCOM1251997212"}; + + return pcb_id[offset]; +} + static ADDRESS_MAP_START( namco_30test_map, AS_PROGRAM, 8 ) - //AM_RANGE(0x0000, 0x00ff) AM_RAM // stack ram +// AM_RANGE(0x0000, 0x007f) AM_RAM // internal I/O +// AM_RANGE(0x0080, 0x037f) AM_RAM // internal RAM + AM_RANGE(0x0d80, 0x0d8f) AM_READ(namco30test_pcbid_r) AM_RANGE(0x8000, 0xffff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START( namco_30test_io, AS_IO, 8 ) + AM_RANGE(MC68HC11_IO_PORTE,MC68HC11_IO_PORTE) AM_READ(unk_r) ADDRESS_MAP_END @@ -63,8 +79,8 @@ static MACHINE_RESET( 30test ) static const hc11_config namco_30test_config = { - 1, //has extended internal I/O - 0x100, //internal RAM size, TODO + 0, //has extended internal I/O + 768, //internal RAM size 0x00 //registers are at 0-0x100 };