summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/konami/konami.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/konami/konami.c')
-rw-r--r--src/emu/cpu/konami/konami.c651
1 files changed, 651 insertions, 0 deletions
diff --git a/src/emu/cpu/konami/konami.c b/src/emu/cpu/konami/konami.c
new file mode 100644
index 00000000000..d02753ac695
--- /dev/null
+++ b/src/emu/cpu/konami/konami.c
@@ -0,0 +1,651 @@
+/*** konami: Portable Konami cpu emulator ******************************************
+
+ Copyright (C) The MAME Team 1999
+
+ Based on M6809 cpu core copyright (C) John Butler 1997
+
+ References:
+
+ 6809 Simulator V09, By L.C. Benschop, Eidnhoven The Netherlands.
+
+ m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from
+ the 6809 Simulator V09)
+
+ 6809 Microcomputer Programming & Interfacing with Experiments"
+ by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc.
+
+ System dependencies: UINT16 must be 16 bit unsigned int
+ UINT8 must be 8 bit unsigned int
+ UINT32 must be more than 16 bits
+ arrays up to 65536 bytes must be supported
+ machine must be twos complement
+
+ History:
+991022 HJB:
+ Tried to improve speed: Using bit7 of cycles1 as flag for multi
+ byte opcodes is gone, those opcodes now instead go through opcode2().
+ Inlined fetch_effective_address() into that function as well.
+ Got rid of the slow/fast flags for stack (S and U) memory accesses.
+ Minor changes to use 32 bit values as arguments to memory functions
+ and added defines for that purpose (e.g. X = 16bit XD = 32bit).
+
+990720 EHC:
+ Created this file
+
+*****************************************************************************/
+
+#include "debugger.h"
+#include "konami.h"
+
+#define VERBOSE 0
+
+#if VERBOSE
+#define LOG(x) logerror x
+#else
+#define LOG(x)
+#endif
+
+
+/* Konami Registers */
+typedef struct
+{
+ PAIR pc; /* Program counter */
+ PAIR ppc; /* Previous program counter */
+ PAIR d; /* Accumulator a and b */
+ PAIR dp; /* Direct Page register (page in MSB) */
+ PAIR u, s; /* Stack pointers */
+ PAIR x, y; /* Index registers */
+ UINT8 cc;
+ UINT8 ireg; /* first opcode */
+ UINT8 irq_state[2];
+ int extra_cycles; /* cycles used up by interrupts */
+ int (*irq_callback)(int irqline);
+ UINT8 int_state; /* SYNC and CWAI flags */
+ UINT8 nmi_state;
+ void (*setlines_callback)( int lines ); /* callback called when A16-A23 are set */
+} konami_Regs;
+
+/* flag bits in the cc register */
+#define CC_C 0x01 /* Carry */
+#define CC_V 0x02 /* Overflow */
+#define CC_Z 0x04 /* Zero */
+#define CC_N 0x08 /* Negative */
+#define CC_II 0x10 /* Inhibit IRQ */
+#define CC_H 0x20 /* Half (auxiliary) carry */
+#define CC_IF 0x40 /* Inhibit FIRQ */
+#define CC_E 0x80 /* entire state pushed */
+
+/* Konami registers */
+static konami_Regs konami;
+
+#define pPPC konami.ppc
+#define pPC konami.pc
+#define pU konami.u
+#define pS konami.s
+#define pX konami.x
+#define pY konami.y
+#define pD konami.d
+
+#define PPC konami.ppc.w.l
+#define PC konami.pc.w.l
+#define PCD konami.pc.d
+#define U konami.u.w.l
+#define UD konami.u.d
+#define S konami.s.w.l
+#define SD konami.s.d
+#define X konami.x.w.l
+#define XD konami.x.d
+#define Y konami.y.w.l
+#define YD konami.y.d
+#define D konami.d.w.l
+#define A konami.d.b.h
+#define B konami.d.b.l
+#define DP konami.dp.b.h
+#define DPD konami.dp.d
+#define CC konami.cc
+
+static PAIR ea; /* effective address */
+#define EA ea.w.l
+#define EAD ea.d
+
+#define KONAMI_CWAI 8 /* set when CWAI is waiting for an interrupt */
+#define KONAMI_SYNC 16 /* set when SYNC is waiting for an interrupt */
+#define KONAMI_LDS 32 /* set when LDS occured at least once */
+
+#define CHECK_IRQ_LINES \
+ if( konami.irq_state[KONAMI_IRQ_LINE] != CLEAR_LINE || \
+ konami.irq_state[KONAMI_FIRQ_LINE] != CLEAR_LINE ) \
+ konami.int_state &= ~KONAMI_SYNC; /* clear SYNC flag */ \
+ if( konami.irq_state[KONAMI_FIRQ_LINE]!=CLEAR_LINE && !(CC & CC_IF) ) \
+ { \
+ /* fast IRQ */ \
+ /* state already saved by CWAI? */ \
+ if( konami.int_state & KONAMI_CWAI ) \
+ { \
+ konami.int_state &= ~KONAMI_CWAI; /* clear CWAI */ \
+ konami.extra_cycles += 7; /* subtract +7 cycles */ \
+ } \
+ else \
+ { \
+ CC &= ~CC_E; /* save 'short' state */ \
+ PUSHWORD(pPC); \
+ PUSHBYTE(CC); \
+ konami.extra_cycles += 10; /* subtract +10 cycles */ \
+ } \
+ CC |= CC_IF | CC_II; /* inhibit FIRQ and IRQ */ \
+ PCD = RM16(0xfff6); \
+ change_pc(PC); /* TS 971002 */ \
+ (void)(*konami.irq_callback)(KONAMI_FIRQ_LINE); \
+ } \
+ else \
+ if( konami.irq_state[KONAMI_IRQ_LINE]!=CLEAR_LINE && !(CC & CC_II) )\
+ { \
+ /* standard IRQ */ \
+ /* state already saved by CWAI? */ \
+ if( konami.int_state & KONAMI_CWAI ) \
+ { \
+ konami.int_state &= ~KONAMI_CWAI; /* clear CWAI flag */ \
+ konami.extra_cycles += 7; /* subtract +7 cycles */ \
+ } \
+ else \
+ { \
+ CC |= CC_E; /* save entire state */ \
+ PUSHWORD(pPC); \
+ PUSHWORD(pU); \
+ PUSHWORD(pY); \
+ PUSHWORD(pX); \
+ PUSHBYTE(DP); \
+ PUSHBYTE(B); \
+ PUSHBYTE(A); \
+ PUSHBYTE(CC); \
+ konami.extra_cycles += 19; /* subtract +19 cycles */ \
+ } \
+ CC |= CC_II; /* inhibit IRQ */ \
+ PCD = RM16(0xfff8); \
+ change_pc(PC); /* TS 971002 */ \
+ (void)(*konami.irq_callback)(KONAMI_IRQ_LINE); \
+ }
+
+/* public globals */
+int konami_ICount=50000;
+int konami_Flags; /* flags for speed optimization (obsolete!!) */
+
+/* these are re-defined in konami.h TO RAM, ROM or functions in memory.c */
+#define RM(Addr) KONAMI_RDMEM(Addr)
+#define WM(Addr,Value) KONAMI_WRMEM(Addr,Value)
+#define ROP(Addr) KONAMI_RDOP(Addr)
+#define ROP_ARG(Addr) KONAMI_RDOP_ARG(Addr)
+
+#define SIGNED(a) (UINT16)(INT16)(INT8)(a)
+
+/* macros to access memory */
+#define IMMBYTE(b) { b = ROP_ARG(PCD); PC++; }
+#define IMMWORD(w) { w.d = (ROP_ARG(PCD)<<8) | ROP_ARG(PCD+1); PC += 2; }
+
+#define PUSHBYTE(b) --S; WM(SD,b)
+#define PUSHWORD(w) --S; WM(SD,w.b.l); --S; WM(SD,w.b.h)
+#define PULLBYTE(b) b=KONAMI_RDMEM(SD); S++
+#define PULLWORD(w) w=KONAMI_RDMEM(SD)<<8; S++; w|=KONAMI_RDMEM(SD); S++
+
+#define PSHUBYTE(b) --U; WM(UD,b);
+#define PSHUWORD(w) --U; WM(UD,w.b.l); --U; WM(UD,w.b.h)
+#define PULUBYTE(b) b=KONAMI_RDMEM(UD); U++
+#define PULUWORD(w) w=KONAMI_RDMEM(UD)<<8; U++; w|=KONAMI_RDMEM(UD); U++
+
+#define CLR_HNZVC CC&=~(CC_H|CC_N|CC_Z|CC_V|CC_C)
+#define CLR_NZV CC&=~(CC_N|CC_Z|CC_V)
+#define CLR_NZ CC&=~(CC_N|CC_Z)
+#define CLR_HNZC CC&=~(CC_H|CC_N|CC_Z|CC_C)
+#define CLR_NZVC CC&=~(CC_N|CC_Z|CC_V|CC_C)
+#define CLR_Z CC&=~(CC_Z)
+#define CLR_NZC CC&=~(CC_N|CC_Z|CC_C)
+#define CLR_ZC CC&=~(CC_Z|CC_C)
+
+/* macros for CC -- CC bits affected should be reset before calling */
+#define SET_Z(a) if(!a)SEZ
+#define SET_Z8(a) SET_Z((UINT8)a)
+#define SET_Z16(a) SET_Z((UINT16)a)
+#define SET_N8(a) CC|=((a&0x80)>>4)
+#define SET_N16(a) CC|=((a&0x8000)>>12)
+#define SET_H(a,b,r) CC|=(((a^b^r)&0x10)<<1)
+#define SET_C8(a) CC|=((a&0x100)>>8)
+#define SET_C16(a) CC|=((a&0x10000)>>16)
+#define SET_V8(a,b,r) CC|=(((a^b^r^(r>>1))&0x80)>>6)
+#define SET_V16(a,b,r) CC|=(((a^b^r^(r>>1))&0x8000)>>14)
+
+static UINT8 flags8i[256]= /* increment */
+{
+CC_Z,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+CC_N|CC_V,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N
+};
+static UINT8 flags8d[256]= /* decrement */
+{
+CC_Z,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,CC_V,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
+CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N
+};
+#define SET_FLAGS8I(a) {CC|=flags8i[(a)&0xff];}
+#define SET_FLAGS8D(a) {CC|=flags8d[(a)&0xff];}
+
+/* combos */
+#define SET_NZ8(a) {SET_N8(a);SET_Z(a);}
+#define SET_NZ16(a) {SET_N16(a);SET_Z(a);}
+#define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
+#define SET_FLAGS16(a,b,r) {SET_N16(r);SET_Z16(r);SET_V16(a,b,r);SET_C16(r);}
+
+/* macros for addressing modes (postbytes have their own code) */
+#define DIRECT EAD = DPD; IMMBYTE(ea.b.l)
+#define IMM8 EAD = PCD; PC++
+#define IMM16 EAD = PCD; PC+=2
+#define EXTENDED IMMWORD(ea)
+
+/* macros to set status flags */
+#define SEC CC|=CC_C
+#define CLC CC&=~CC_C
+#define SEZ CC|=CC_Z
+#define CLZ CC&=~CC_Z
+#define SEN CC|=CC_N
+#define CLN CC&=~CC_N
+#define SEV CC|=CC_V
+#define CLV CC&=~CC_V
+#define SEH CC|=CC_H
+#define CLH CC&=~CC_H
+
+/* macros for convenience */
+#define DIRBYTE(b) DIRECT; b=RM(EAD)
+#define DIRWORD(w) DIRECT; w.d=RM16(EAD)
+#define EXTBYTE(b) EXTENDED; b=RM(EAD)
+#define EXTWORD(w) EXTENDED; w.d=RM16(EAD)
+
+/* macros for branch instructions */
+#define BRANCH(f) { \
+ UINT8 t; \
+ IMMBYTE(t); \
+ if( f ) \
+ { \
+ PC += SIGNED(t); \
+ change_pc(PC); /* TS 971002 */ \
+ } \
+}
+
+#define LBRANCH(f) { \
+ PAIR t; \
+ IMMWORD(t); \
+ if( f ) \
+ { \
+ konami_ICount -= 1; \
+ PC += t.w.l; \
+ change_pc(PC); /* TS 971002 */ \
+ } \
+}
+
+#define NXORV ((CC&CC_N)^((CC&CC_V)<<2))
+
+/* macros for setting/getting registers in TFR/EXG instructions */
+#define GETREG(val,reg) \
+ switch(reg) { \
+ case 0: val = A; break; \
+ case 1: val = B; break; \
+ case 2: val = X; break; \
+ case 3: val = Y; break; \
+ case 4: val = S; break; /* ? */ \
+ case 5: val = U; break; \
+ default: val = 0xff; logerror("Unknown TFR/EXG idx at PC:%04x\n", PC ); break; \
+}
+
+#define SETREG(val,reg) \
+ switch(reg) { \
+ case 0: A = val; break; \
+ case 1: B = val; break; \
+ case 2: X = val; break; \
+ case 3: Y = val; break; \
+ case 4: S = val; break; /* ? */ \
+ case 5: U = val; break; \
+ default: logerror("Unknown TFR/EXG idx at PC:%04x\n", PC ); break; \
+}
+
+/* opcode timings */
+static UINT8 cycles1[] =
+{
+ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ /*0*/ 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 5, 5, 5, 5,
+ /*1*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ /*2*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ /*3*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 7, 6,
+ /*4*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 3, 4, 4,
+ /*5*/ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 1, 1, 1,
+ /*6*/ 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5,
+ /*7*/ 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5,
+ /*8*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+ /*9*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,
+ /*A*/ 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 3, 3, 2, 1,
+ /*B*/ 3, 2, 2,11,22,11, 2, 4, 3, 3, 3, 3, 3, 3, 3, 3,
+ /*C*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 2,
+ /*D*/ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /*E*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /*F*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+INLINE UINT32 RM16( UINT32 Addr )
+{
+ UINT32 result = RM(Addr) << 8;
+ return result | RM((Addr+1)&0xffff);
+}
+
+INLINE void WM16( UINT32 Addr, PAIR *p )
+{
+ WM( Addr, p->b.h );
+ WM( (Addr+1)&0xffff, p->b.l );
+}
+
+/****************************************************************************
+ * Get all registers in given buffer
+ ****************************************************************************/
+static void konami_get_context(void *dst)
+{
+ if( dst )
+ *(konami_Regs*)dst = konami;
+}
+
+/****************************************************************************
+ * Set all registers to given values
+ ****************************************************************************/
+static void konami_set_context(void *src)
+{
+ if( src )
+ konami = *(konami_Regs*)src;
+ change_pc(PC); /* TS 971002 */
+
+ CHECK_IRQ_LINES;
+}
+
+/****************************************************************************/
+/* Reset registers to their initial values */
+/****************************************************************************/
+static void konami_init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ konami.irq_callback = irqcallback;
+}
+
+static void konami_reset(void)
+{
+ konami.int_state = 0;
+ konami.nmi_state = CLEAR_LINE;
+ konami.irq_state[0] = CLEAR_LINE;
+ konami.irq_state[0] = CLEAR_LINE;
+
+ DPD = 0; /* Reset direct page register */
+
+ CC |= CC_II; /* IRQ disabled */
+ CC |= CC_IF; /* FIRQ disabled */
+
+ PCD = RM16(0xfffe);
+ change_pc(PC); /* TS 971002 */
+}
+
+static void konami_exit(void)
+{
+}
+
+/* Generate interrupts */
+/****************************************************************************
+ * Set IRQ line state
+ ****************************************************************************/
+static void set_irq_line(int irqline, int state)
+{
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (konami.nmi_state == state) return;
+ konami.nmi_state = state;
+ LOG(("KONAMI#%d set_nmi_line %d\n", cpu_getactivecpu(), state));
+ if( state == CLEAR_LINE ) return;
+
+ /* if the stack was not yet initialized */
+ if( !(konami.int_state & KONAMI_LDS) ) return;
+
+ konami.int_state &= ~KONAMI_SYNC;
+ /* state already saved by CWAI? */
+ if( konami.int_state & KONAMI_CWAI )
+ {
+ konami.int_state &= ~KONAMI_CWAI;
+ konami.extra_cycles += 7; /* subtract +7 cycles next time */
+ }
+ else
+ {
+ CC |= CC_E; /* save entire state */
+ PUSHWORD(pPC);
+ PUSHWORD(pU);
+ PUSHWORD(pY);
+ PUSHWORD(pX);
+ PUSHBYTE(DP);
+ PUSHBYTE(B);
+ PUSHBYTE(A);
+ PUSHBYTE(CC);
+ konami.extra_cycles += 19; /* subtract +19 cycles next time */
+ }
+ CC |= CC_IF | CC_II; /* inhibit FIRQ and IRQ */
+ PCD = RM16(0xfffc);
+ change_pc(PC); /* TS 971002 */
+ }
+ else if (irqline < 2)
+ {
+ LOG(("KONAMI#%d set_irq_line %d, %d\n", cpu_getactivecpu(), irqline, state));
+ konami.irq_state[irqline] = state;
+ if (state == CLEAR_LINE) return;
+ CHECK_IRQ_LINES;
+ }
+}
+
+#if 0
+/****************************************************************************
+ * Save CPU state
+ ****************************************************************************/
+static void state_save(void *file, const char *module)
+{
+ int cpu = cpu_getactivecpu();
+ state_save_register_item(file, cpu, module, PC);
+ state_save_register_item(file, cpu, module, U);
+ state_save_register_item(file, cpu, module, S);
+ state_save_register_item(file, cpu, module, X);
+ state_save_register_item(file, cpu, module, Y);
+ state_save_register_item(file, cpu, module, DP);
+ state_save_register_item(file, cpu, module, CC);
+ state_save_register_item(file, cpu, module, konami.int_state);
+ state_save_register_item(file, cpu, module, konami.nmi_state);
+ state_save_register_item(file, cpu, module, konami.irq_state[0]);
+ state_save_register_item(file, cpu, module, konami.irq_state[1]);
+}
+#endif
+
+/* includes the static function prototypes and the master opcode table */
+#include "konamtbl.c"
+
+/* includes the actual opcode implementations */
+#include "konamops.c"
+
+/* execute instructions on this CPU until icount expires */
+static int konami_execute(int cycles)
+{
+ konami_ICount = cycles - konami.extra_cycles;
+ konami.extra_cycles = 0;
+
+ if( konami.int_state & (KONAMI_CWAI | KONAMI_SYNC) )
+ {
+ konami_ICount = 0;
+ }
+ else
+ {
+ do
+ {
+ pPPC = pPC;
+
+ CALL_MAME_DEBUG;
+
+ konami.ireg = ROP(PCD);
+ PC++;
+
+ (*konami_main[konami.ireg])();
+
+ konami_ICount -= cycles1[konami.ireg];
+
+ } while( konami_ICount > 0 );
+
+ konami_ICount -= konami.extra_cycles;
+ konami.extra_cycles = 0;
+ }
+
+ return cycles - konami_ICount;
+}
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void konami_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + KONAMI_IRQ_LINE: set_irq_line(KONAMI_IRQ_LINE, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + KONAMI_FIRQ_LINE:set_irq_line(KONAMI_FIRQ_LINE, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + KONAMI_PC: PC = info->i; change_pc(PC); break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + KONAMI_S: S = info->i; break;
+ case CPUINFO_INT_REGISTER + KONAMI_CC: CC = info->i; CHECK_IRQ_LINES; break;
+ case CPUINFO_INT_REGISTER + KONAMI_U: U = info->i; break;
+ case CPUINFO_INT_REGISTER + KONAMI_A: A = info->i; break;
+ case CPUINFO_INT_REGISTER + KONAMI_B: B = info->i; break;
+ case CPUINFO_INT_REGISTER + KONAMI_X: X = info->i; break;
+ case CPUINFO_INT_REGISTER + KONAMI_Y: Y = info->i; break;
+ case CPUINFO_INT_REGISTER + KONAMI_DP: DP = info->i; break;
+
+ /* --- the following bits of info are set as pointers to data or functions --- */
+ case CPUINFO_PTR_KONAMI_SETLINES_CALLBACK: konami.setlines_callback = (void (*)(int))info->f; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void konami_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(konami); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 2; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 13; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + KONAMI_IRQ_LINE: info->i = konami.irq_state[KONAMI_IRQ_LINE]; break;
+ case CPUINFO_INT_INPUT_STATE + KONAMI_FIRQ_LINE:info->i = konami.irq_state[KONAMI_FIRQ_LINE]; break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = konami.nmi_state; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + KONAMI_PC: info->i = PC; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + KONAMI_S: info->i = S; break;
+ case CPUINFO_INT_REGISTER + KONAMI_CC: info->i = CC; break;
+ case CPUINFO_INT_REGISTER + KONAMI_U: info->i = U; break;
+ case CPUINFO_INT_REGISTER + KONAMI_A: info->i = A; break;
+ case CPUINFO_INT_REGISTER + KONAMI_B: info->i = B; break;
+ case CPUINFO_INT_REGISTER + KONAMI_X: info->i = X; break;
+ case CPUINFO_INT_REGISTER + KONAMI_Y: info->i = Y; break;
+ case CPUINFO_INT_REGISTER + KONAMI_DP: info->i = DP; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = konami_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = konami_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = konami_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = konami_init; break;
+ case CPUINFO_PTR_RESET: info->reset = konami_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = konami_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = konami_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = konami_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &konami_ICount; break;
+ case CPUINFO_PTR_KONAMI_SETLINES_CALLBACK: info->f = (genf *)konami.setlines_callback; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "KONAMI"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "KONAMI 5000x"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright (C) The MAME Team 1999"); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s, "%c%c%c%c%c%c%c%c",
+ konami.cc & 0x80 ? 'E':'.',
+ konami.cc & 0x40 ? 'F':'.',
+ konami.cc & 0x20 ? 'H':'.',
+ konami.cc & 0x10 ? 'I':'.',
+ konami.cc & 0x08 ? 'N':'.',
+ konami.cc & 0x04 ? 'Z':'.',
+ konami.cc & 0x02 ? 'V':'.',
+ konami.cc & 0x01 ? 'C':'.');
+ break;
+
+ case CPUINFO_STR_REGISTER + KONAMI_PC: sprintf(info->s, "PC:%04X", konami.pc.w.l); break;
+ case CPUINFO_STR_REGISTER + KONAMI_S: sprintf(info->s, "S:%04X", konami.s.w.l); break;
+ case CPUINFO_STR_REGISTER + KONAMI_CC: sprintf(info->s, "CC:%02X", konami.cc); break;
+ case CPUINFO_STR_REGISTER + KONAMI_U: sprintf(info->s, "U:%04X", konami.u.w.l); break;
+ case CPUINFO_STR_REGISTER + KONAMI_A: sprintf(info->s, "A:%02X", konami.d.b.h); break;
+ case CPUINFO_STR_REGISTER + KONAMI_B: sprintf(info->s, "B:%02X", konami.d.b.l); break;
+ case CPUINFO_STR_REGISTER + KONAMI_X: sprintf(info->s, "X:%04X", konami.x.w.l); break;
+ case CPUINFO_STR_REGISTER + KONAMI_Y: sprintf(info->s, "Y:%04X", konami.y.w.l); break;
+ case CPUINFO_STR_REGISTER + KONAMI_DP: sprintf(info->s, "DP:%02X", konami.dp.b.h); break;
+ }
+}