diff --git a/src/mame/drivers/aristmk5.c b/src/mame/drivers/aristmk5.c index 072529948f1..bc8893b1f5c 100644 --- a/src/mame/drivers/aristmk5.c +++ b/src/mame/drivers/aristmk5.c @@ -11,6 +11,11 @@ - bp 0x3400230: EPROM checksum branch test - bp 0x3400258: DRAM Check branch test - bp 0x3400280: CPU Check branch test + bp 0x340027c: checks IRQ status A and FIQ status bit 7 (force IRQ flag) + - R0 == 0: CPU Check OK + - R0 == 1: IRQ status A force IRQ flag check failed + - R0 == 2: FIQ status force IRQ flag check failed + - R0 == 3: Timer 1 latch low val == 0xf5 - bp 0x34002a8: SRAM Check branch test - bp 0x34002d0: 2KHz Timer branch test - bp 0x34002f8: DRAM emulator branch tests diff --git a/src/mame/includes/archimds.h b/src/mame/includes/archimds.h index 1e68bd355da..faf7353600d 100644 --- a/src/mame/includes/archimds.h +++ b/src/mame/includes/archimds.h @@ -13,11 +13,11 @@ #define ARCHIMEDES_IRQA_PRINTER_BUSY (0x01) #define ARCHIMEDES_IRQA_SERIAL_RING (0x02) #define ARCHIMEDES_IRQA_PRINTER_ACK (0x04) -#define ARCHIMEDES_IRQA_VBL (0x08) +#define ARCHIMEDES_IRQA_VBL (0x08) #define ARCHIMEDES_IRQA_RESET (0x10) #define ARCHIMEDES_IRQA_TIMER0 (0x20) #define ARCHIMEDES_IRQA_TIMER1 (0x40) -#define ARCHIMEDES_IRQA_ALWAYS (0x80) +#define ARCHIMEDES_IRQA_FORCE (0x80) #define ARCHIMEDES_IRQB_PODULE_FIQ (0x01) #define ARCHIMEDES_IRQB_SOUND_EMPTY (0x02) diff --git a/src/mame/machine/archimds.c b/src/mame/machine/archimds.c index 32c9246f654..0ce6efdf7e7 100644 --- a/src/mame/machine/archimds.c +++ b/src/mame/machine/archimds.c @@ -49,11 +49,18 @@ static UINT32 vidc_sndstart, vidc_sndend, vidc_sndcur; static emu_timer *timer[4], *snd_timer; emu_timer *vbl_timer; +#define IRQ_STATUS_A 4 +#define IRQ_MASK_A 6 +#define IRQ_STATUS_B 8 +#define IRQ_MASK_B 10 +#define FIQ_STATUS 12 +#define FIQ_MASK 14 + void archimedes_request_irq_a(running_machine *machine, int mask) { - ioc_regs[4] |= mask; + ioc_regs[IRQ_STATUS_A] |= mask; - if (ioc_regs[6] & mask) + if (ioc_regs[IRQ_MASK_A] & mask) { cputag_set_input_line(machine, "maincpu", ARM_IRQ_LINE, ASSERT_LINE); } @@ -61,9 +68,9 @@ void archimedes_request_irq_a(running_machine *machine, int mask) void archimedes_request_irq_b(running_machine *machine, int mask) { - ioc_regs[8] |= mask; + ioc_regs[IRQ_STATUS_B] |= mask; - if (ioc_regs[10] & mask) + if (ioc_regs[IRQ_MASK_B] & mask) { generic_pulse_irq_line(machine->device("maincpu"), ARM_IRQ_LINE); } @@ -71,9 +78,9 @@ void archimedes_request_irq_b(running_machine *machine, int mask) void archimedes_request_fiq(running_machine *machine, int mask) { - ioc_regs[12] |= mask; + ioc_regs[FIQ_STATUS] |= mask; - if (ioc_regs[14] & mask) + if (ioc_regs[FIQ_MASK] & mask) { generic_pulse_irq_line(machine->device("maincpu"), ARM_FIRQ_LINE); } @@ -81,17 +88,17 @@ void archimedes_request_fiq(running_machine *machine, int mask) void archimedes_clear_irq_a(running_machine *machine, int mask) { - ioc_regs[4] &= ~mask; + ioc_regs[IRQ_STATUS_A] &= ~mask; } void archimedes_clear_irq_b(running_machine *machine, int mask) { - ioc_regs[8] &= ~mask; + ioc_regs[IRQ_STATUS_B] &= ~mask; } void archimedes_clear_fiq(running_machine *machine, int mask) { - ioc_regs[12] &= ~mask; + ioc_regs[FIQ_STATUS] &= ~mask; } static TIMER_CALLBACK( vidc_vblank ) @@ -119,7 +126,7 @@ static void a310_set_timer(int tmr) if(ioc_timercnt[tmr] != 0) // FIXME: dmdtouch does a divide by zero? { freq = 2000000.0 / (double)ioc_timercnt[tmr]; - // logerror("IOC: starting timer %d, %d ticks, freq %f Hz\n", tmr, ioc_timercnt[tmr], freq); +// logerror("IOC: starting timer %d, %d ticks, freq %f Hz\n", tmr, ioc_timercnt[tmr], freq); timer_adjust_oneshot(timer[tmr], ATTOTIME_IN_HZ(freq), tmr); } } @@ -155,8 +162,13 @@ void archimedes_reset(running_machine *machine) memc_pages[i] = -1; // indicate unmapped } - ioc_regs[4] = 0x10; //set up POR (Power On Reset) at start-up - ioc_regs[8] = 0x02; //set up IL[1] On + ioc_regs[IRQ_STATUS_A] = 0x10 | 0x80; //set up POR (Power On Reset) and Force IRQ at start-up + ioc_regs[IRQ_STATUS_B] = 0x02; //set up IL[1] On + ioc_regs[FIQ_STATUS] = 0x80; //set up Force FIQ + + /* Aristocrat MK-5 tests this inside the CPU check routine *without* firing a latch command in the POST, could be open bus, fixed value or undefined behaviour, + almost surely something checked as an anti-cheat measure */ + ioc_timerout[1] = 0xf5; } void archimedes_init(running_machine *machine) @@ -326,12 +338,20 @@ READ32_HANDLER(archimedes_ioc_r) #endif if (offset*4 >= 0x200000 && offset*4 < 0x300000) { + logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], ioc_regs[offset&0x1f], cpu_get_pc( space->cpu ),offset & 0x1f); + switch (offset & 0x1f) { case 1: // keyboard read archimedes_request_irq_b(space->machine, ARCHIMEDES_IRQB_KBD_XMIT_EMPTY); break; + case IRQ_STATUS_A: + return (ioc_regs[IRQ_STATUS_A] & 0x7f) | 0x80; // Force IRQ is always '1' + + case FIQ_STATUS: + return (ioc_regs[FIQ_STATUS] & 0x7f) | 0x80; // Force FIQ is always '1' + case 16: // timer 0 read return ioc_timerout[0]&0xff; case 17: @@ -350,7 +370,6 @@ READ32_HANDLER(archimedes_ioc_r) return (ioc_timerout[3]>>8)&0xff; } - logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], ioc_regs[offset&0x1f], cpu_get_pc( space->cpu ),offset & 0x1f); return ioc_regs[offset&0x1f]; } #ifdef MESS @@ -377,7 +396,7 @@ WRITE32_HANDLER(archimedes_ioc_w) if (offset*4 >= 0x200000 && offset*4 < 0x300000) { -// logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], cpu_get_pc( space->cpu )); + logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], cpu_get_pc( space->cpu )); switch (offset&0x1f) { @@ -385,11 +404,27 @@ WRITE32_HANDLER(archimedes_ioc_w) //logerror("IOC I2C: CLK %d DAT %d\n", (data>>1)&1, data&1); break; + case IRQ_MASK_A: + ioc_regs[IRQ_MASK_A] = data & 0xff; + + if(data & 0x80) //force an IRQ + archimedes_request_irq_a(space->machine,ARCHIMEDES_IRQA_FORCE); + + break; + + case FIQ_MASK: + ioc_regs[FIQ_MASK] = data & 0xff; + + if(data & 0x80) //force a FIRQ + archimedes_request_fiq(space->machine,ARCHIMEDES_FIQ_FORCE); + + break; + case 5: // IRQ clear A - ioc_regs[4] &= ~(data&0xff); + ioc_regs[IRQ_STATUS_A] &= ~(data&0xff); // if that did it, clear the IRQ - if (ioc_regs[4] == 0) + if (ioc_regs[IRQ_STATUS_A] == 0) { cputag_set_input_line(space->machine, "maincpu", ARM_IRQ_LINE, CLEAR_LINE); }