summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/asap/asap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/asap/asap.c')
-rw-r--r--src/emu/cpu/asap/asap.c1858
1 files changed, 1858 insertions, 0 deletions
diff --git a/src/emu/cpu/asap/asap.c b/src/emu/cpu/asap/asap.c
new file mode 100644
index 00000000000..91278197f75
--- /dev/null
+++ b/src/emu/cpu/asap/asap.c
@@ -0,0 +1,1858 @@
+/***************************************************************************
+
+ asap.c
+ Core implementation for the portable ASAP emulator.
+ ASAP = Atari Simplified Architecture Processor
+
+ Written by Aaron Giles
+ Special thanks to Mike Albaugh for clarification on a couple of fine points.
+
+***************************************************************************/
+
+#include "debugger.h"
+#include "asap.h"
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define PS_CFLAG 0x00000001
+#define PS_VFLAG 0x00000002
+#define PS_ZFLAG 0x00000004
+#define PS_NFLAG 0x00000008
+#define PS_IFLAG 0x00000010
+#define PS_PFLAG 0x00000020
+
+#define EXCEPTION_RESET 0
+#define EXCEPTION_TRAP0 1
+#define EXCEPTION_TRAPF 2
+#define EXCEPTION_INTERRUPT 3
+
+
+#define REGBASE 0xffe0
+
+
+#define SET_C_ADD(a,b) (asap.cflag = (UINT32)(b) > (UINT32)(~(a)))
+#define SET_C_SUB(a,b) (asap.cflag = (UINT32)(b) <= (UINT32)(a))
+#define SET_V_ADD(r,a,b) (asap.vflag = ~((a) ^ (b)) & ((a) ^ (r)))
+#define SET_V_SUB(r,a,b) (asap.vflag = ((a) ^ (b)) & ((a) ^ (r)))
+#define SET_ZN(r) (asap.znflag = (r))
+#define SET_ZNCV_ADD(r,a,b) SET_ZN(r); SET_C_ADD(a,b); SET_V_ADD(r,a,b)
+#define SET_ZNCV_SUB(r,a,b) SET_ZN(r); SET_C_SUB(a,b); SET_V_SUB(r,a,b)
+
+#define SET_VFLAG(val) (asap.vflag = (val) << 31)
+#define SET_CFLAG(val) (asap.cflag = (val))
+
+#define GET_FLAGS(r) ((r)->cflag | \
+ (((r)->vflag >> 30) & PS_VFLAG) | \
+ (((r)->znflag == 0) << 2) | \
+ (((r)->znflag >> 28) & PS_NFLAG) | \
+ ((r)->iflag << 4) | \
+ ((r)->pflag << 5))
+
+#define SET_FLAGS(r,v) do { \
+ (r)->cflag = (v) & PS_CFLAG; \
+ (r)->vflag = ((v) & PS_VFLAG) << 30; \
+ (r)->znflag = ((v) & PS_ZFLAG) ? 0 : ((v) & PS_NFLAG) ? -1 : 1; \
+ (r)->iflag = ((v) & PS_IFLAG) >> 4; \
+ (r)->pflag = ((v) & PS_PFLAG) >> 5; \
+ } while (0);
+
+
+/***************************************************************************
+ STRUCTURES & TYPEDEFS
+***************************************************************************/
+
+/* ASAP Registers */
+typedef struct
+{
+ /* core registers */
+ UINT32 r[32];
+ UINT32 pc;
+
+ /* expanded flags */
+ UINT32 pflag;
+ UINT32 iflag;
+ UINT32 cflag;
+ UINT32 vflag;
+ UINT32 znflag;
+
+ /* internal stuff */
+ PAIR op;
+ UINT32 ppc;
+ UINT32 nextpc;
+ UINT8 irq_state;
+ int interrupt_cycles;
+ int (*irq_callback)(int irqline);
+} asap_regs;
+
+
+
+/***************************************************************************
+ PRIVATE GLOBAL VARIABLES
+***************************************************************************/
+
+static asap_regs asap;
+
+static void (**opcode)(void);
+static UINT32 *src2val;
+
+static int asap_icount;
+
+
+
+/***************************************************************************
+ OPCODE TABLE
+***************************************************************************/
+
+static void noop(void);
+static void trap0(void);
+static void bsp(void);
+static void bmz(void);
+static void bgt(void);
+static void ble(void);
+static void bge(void);
+static void blt(void);
+static void bhi(void);
+static void bls(void);
+static void bcc(void);
+static void bcs(void);
+static void bpl(void);
+static void bmi(void);
+static void bne(void);
+static void beq(void);
+static void bvc(void);
+static void bvs(void);
+static void bsr(void);
+static void bsr_0(void);
+static void lea(void);
+static void lea_c(void);
+static void lea_c0(void);
+static void leah(void);
+static void leah_c(void);
+static void leah_c0(void);
+static void subr(void);
+static void subr_c(void);
+static void subr_c0(void);
+static void xor(void);
+static void xor_c(void);
+static void xor_c0(void);
+static void xorn(void);
+static void xorn_c(void);
+static void xorn_c0(void);
+static void add(void);
+static void add_c(void);
+static void add_c0(void);
+static void sub(void);
+static void sub_c(void);
+static void sub_c0(void);
+static void addc(void);
+static void addc_c(void);
+static void addc_c0(void);
+static void subc(void);
+static void subc_c(void);
+static void subc_c0(void);
+static void and(void);
+static void and_c(void);
+static void and_c0(void);
+static void andn(void);
+static void andn_c(void);
+static void andn_c0(void);
+static void or(void);
+static void or_c(void);
+static void or_c0(void);
+static void orn(void);
+static void orn_c(void);
+static void orn_c0(void);
+static void ld(void);
+static void ld_0(void);
+static void ld_c(void);
+static void ld_c0(void);
+static void ldh(void);
+static void ldh_0(void);
+static void ldh_c(void);
+static void ldh_c0(void);
+static void lduh(void);
+static void lduh_0(void);
+static void lduh_c(void);
+static void lduh_c0(void);
+static void sth(void);
+static void sth_0(void);
+static void sth_c(void);
+static void sth_c0(void);
+static void st(void);
+static void st_0(void);
+static void st_c(void);
+static void st_c0(void);
+static void ldb(void);
+static void ldb_0(void);
+static void ldb_c(void);
+static void ldb_c0(void);
+static void ldub(void);
+static void ldub_0(void);
+static void ldub_c(void);
+static void ldub_c0(void);
+static void stb(void);
+static void stb_0(void);
+static void stb_c(void);
+static void stb_c0(void);
+static void ashr(void);
+static void ashr_c(void);
+static void ashr_c0(void);
+static void lshr(void);
+static void lshr_c(void);
+static void lshr_c0(void);
+static void ashl(void);
+static void ashl_c(void);
+static void ashl_c0(void);
+static void rotl(void);
+static void rotl_c(void);
+static void rotl_c0(void);
+static void getps(void);
+static void putps(void);
+static void jsr(void);
+static void jsr_0(void);
+static void jsr_c(void);
+static void jsr_c0(void);
+static void trapf(void);
+
+static void (*opcodetable[32][4])(void) =
+{
+ { trap0, trap0, trap0, trap0 },
+ { NULL, NULL, NULL, NULL },
+ { bsr, bsr_0, bsr, bsr_0 },
+ { lea, noop, lea_c, lea_c0 },
+ { leah, noop, leah_c, leah_c0 },
+ { subr, noop, subr_c, subr_c0 },
+ { xor, noop, xor_c, xor_c0 },
+ { xorn, noop, xorn_c, xorn_c0 },
+ { add, noop, add_c, add_c0 },
+ { sub, noop, sub_c, sub_c0 },
+ { addc, noop, addc_c, addc_c0 },
+ { subc, noop, subc_c, subc_c0 },
+ { and, noop, and_c, and_c0 },
+ { andn, noop, andn_c, andn_c0 },
+ { or, noop, or_c, or_c0 },
+ { orn, noop, orn_c, orn_c0 },
+ { ld, ld_0, ld_c, ld_c0 },
+ { ldh, ldh_0, ldh_c, ldh_c0 },
+ { lduh, lduh_0, lduh_c, lduh_c0 },
+ { sth, sth_0, sth_c, sth_c0 },
+ { st, st_0, st_c, st_c0 },
+ { ldb, ldb_0, ldb_c, ldb_c0 },
+ { ldub, ldub_0, ldub_c, ldub_c0 },
+ { stb, stb_0, stb_c, stb_c0 },
+ { ashr, noop, ashr_c, ashr_c0 },
+ { lshr, noop, lshr_c, lshr_c0 },
+ { ashl, noop, ashl_c, ashl_c0 },
+ { rotl, noop, rotl_c, rotl_c0 },
+ { getps, noop, getps, noop },
+ { putps, putps, putps, putps },
+ { jsr, jsr_0, jsr_c, jsr_c0 },
+ { trapf, trapf, trapf, trapf }
+};
+
+static void (*conditiontable[16])(void) =
+{
+ bsp, bmz, bgt, ble, bge, blt, bhi, bls,
+ bcc, bcs, bpl, bmi, bne, beq, bvc, bvs
+};
+
+
+
+/***************************************************************************
+ MEMORY ACCESSORS
+***************************************************************************/
+
+#define ROPCODE(pc) cpu_readop32(pc)
+#define UPDATEPC() change_pc(asap.pc)
+
+
+INLINE UINT8 READBYTE(offs_t address)
+{
+ /* no alignment issues with bytes */
+ return program_read_byte_32le(address);
+}
+
+INLINE UINT16 READWORD(offs_t address)
+{
+ /* aligned reads are easy */
+ if (!(address & 1))
+ return program_read_word_32le(address);
+
+ /* misaligned reads are tricky */
+ return program_read_dword_32le(address & ~3) >> (address & 3);
+}
+
+INLINE UINT32 READLONG(offs_t address)
+{
+ /* aligned reads are easy */
+ if (!(address & 3))
+ return program_read_dword_32le(address);
+
+ /* misaligned reads are tricky */
+ return program_read_dword_32le(address & ~3) >> (address & 3);
+}
+
+INLINE void WRITEBYTE(offs_t address, UINT8 data)
+{
+ /* no alignment issues with bytes */
+ program_write_byte_32le(address, data);
+}
+
+INLINE void WRITEWORD(offs_t address, UINT16 data)
+{
+ /* aligned writes are easy */
+ if (!(address & 1))
+ {
+ program_write_word_32le(address, data);
+ return;
+ }
+
+ /* misaligned writes are tricky */
+ if (!(address & 2))
+ {
+ program_write_byte_32le(address + 1, data);
+ program_write_byte_32le(address + 2, data >> 8);
+ }
+ else
+ program_write_byte_32le(address + 1, data);
+}
+
+INLINE void WRITELONG(offs_t address, UINT32 data)
+{
+ /* aligned writes are easy */
+ if (!(address & 3))
+ {
+ program_write_dword_32le(address, data);
+ return;
+ }
+
+ /* misaligned writes are tricky */
+ switch (address & 3)
+ {
+ case 1:
+ program_write_byte_32le(address, data);
+ program_write_word_32le(address + 1, data >> 8);
+ break;
+ case 2:
+ program_write_word_32le(address, data);
+ break;
+ case 3:
+ program_write_byte_32le(address, data);
+ break;
+ }
+}
+
+
+
+/***************************************************************************
+ EXCEPTION HANDLING
+***************************************************************************/
+
+INLINE void generate_exception(int exception)
+{
+ asap.pflag = asap.iflag;
+ asap.iflag = 0;
+
+ src2val[REGBASE + 30] = asap.pc;
+ src2val[REGBASE + 31] = (asap.nextpc == ~0) ? asap.pc + 4 : asap.nextpc;
+
+ asap.pc = 0x40 * exception;
+ asap.nextpc = ~0;
+ UPDATEPC();
+
+ asap.interrupt_cycles++;
+}
+
+
+
+/***************************************************************************
+ IRQ HANDLING
+***************************************************************************/
+
+INLINE void check_irqs(void)
+{
+ if (asap.irq_state && asap.iflag)
+ {
+ generate_exception(EXCEPTION_INTERRUPT);
+ if (asap.irq_callback)
+ (*asap.irq_callback)(ASAP_IRQ0);
+ }
+}
+
+
+static void set_irq_line(int irqline, int state)
+{
+ asap.irq_state = (state != CLEAR_LINE);
+ check_irqs();
+}
+
+
+
+/***************************************************************************
+ CONTEXT SWITCHING
+***************************************************************************/
+
+static void asap_get_context(void *dst)
+{
+ /* copy the context */
+ if (dst)
+ {
+ if (src2val)
+ memcpy(&asap.r[0], &src2val[REGBASE], 32 * sizeof(UINT32));
+ *(asap_regs *)dst = asap;
+ }
+}
+
+
+static void asap_set_context(void *src)
+{
+ /* copy the context */
+ if (src)
+ {
+ asap = *(asap_regs *)src;
+ if (src2val)
+ memcpy(&src2val[REGBASE], &asap.r[0], 32 * sizeof(UINT32));
+ UPDATEPC();
+
+ /* check for IRQs */
+ check_irqs();
+ }
+}
+
+
+
+/***************************************************************************
+ INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+
+static void init_tables(void)
+{
+ /* allocate opcode table */
+ if (!opcode)
+ opcode = auto_malloc(32 * 32 * 2 * sizeof(void *));
+
+ /* fill opcode table */
+ if (opcode)
+ {
+ int op, dst, cond;
+
+ for (op = 0; op < 32; op++)
+ for (dst = 0; dst < 32; dst++)
+ for (cond = 0; cond < 2; cond++)
+ if (op == 1)
+ opcode[(op << 6) + (dst << 1) + cond] = conditiontable[dst & 15];
+ else if (cond && dst == 0)
+ opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][3];
+ else if (cond)
+ opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][2];
+ else if (dst == 0)
+ opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][1];
+ else
+ opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][0];
+ }
+
+ /* allocate src2 table */
+ if (!src2val)
+ src2val = auto_malloc(65536 * sizeof(UINT32));
+
+ /* fill scr2 table */
+ if (src2val)
+ {
+ int i;
+
+ for (i = 0; i < REGBASE; i++)
+ src2val[i] = i;
+ memcpy(&src2val[REGBASE], &asap.r[0], 32 * sizeof(UINT32));
+ }
+}
+
+static void asap_init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ init_tables();
+ asap.irq_callback = irqcallback;
+}
+
+static void asap_reset(void)
+{
+ /* initialize the state */
+ src2val[REGBASE + 0] = 0;
+ asap.pc = 0;
+ asap.iflag = 0;
+
+ asap.ppc = 0;
+ asap.nextpc = ~0;
+ asap.irq_state = 0;
+ asap.interrupt_cycles = 0;
+ asap.irq_callback = NULL;
+
+ UPDATEPC();
+}
+
+
+static void asap_exit(void)
+{
+ opcode = NULL;
+ src2val = NULL;
+}
+
+
+
+/***************************************************************************
+ CORE EXECUTION LOOP
+***************************************************************************/
+
+INLINE void fetch_instruction(void)
+{
+ /* debugging */
+ asap.ppc = asap.pc;
+ CALL_MAME_DEBUG;
+
+ /* instruction fetch */
+ asap.op.d = ROPCODE(asap.pc);
+ asap.pc += 4;
+}
+
+INLINE void execute_instruction(void)
+{
+ /* parse the instruction */
+ (*opcode[asap.op.d >> 21])();
+}
+
+static int asap_execute(int cycles)
+{
+ /* count cycles and interrupt cycles */
+ asap_icount = cycles;
+ asap_icount -= asap.interrupt_cycles;
+ asap.interrupt_cycles = 0;
+ UPDATEPC();
+
+ /* core execution loop */
+ do
+ {
+ /* fetch and execute the next instruction */
+ fetch_instruction();
+ execute_instruction();
+
+ /* fetch and execute the next instruction */
+ fetch_instruction();
+ execute_instruction();
+
+ /* fetch and execute the next instruction */
+ fetch_instruction();
+ execute_instruction();
+
+ /* fetch and execute the next instruction */
+ fetch_instruction();
+ execute_instruction();
+
+ asap_icount -= 4;
+
+ } while (asap_icount > 0);
+
+ /* eat any new interrupt cycles */
+ asap_icount -= asap.interrupt_cycles;
+ asap.interrupt_cycles = 0;
+ return cycles - asap_icount;
+}
+
+
+
+/***************************************************************************
+ DISASSEMBLY HOOK
+***************************************************************************/
+
+#ifdef MAME_DEBUG
+extern offs_t asap_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
+#endif /* MAME_DEBUG */
+
+
+
+/***************************************************************************
+ HELPER MACROS
+***************************************************************************/
+
+#define OPCODE (asap.op.d >> 27)
+#define DSTREG ((asap.op.d >> 22) & 31)
+#define DSTVAL src2val[REGBASE + DSTREG]
+#define SRC1REG ((asap.op.d >> 16) & 31)
+#define SRC1VAL src2val[REGBASE + SRC1REG]
+#define SRC2VAL src2val[asap.op.w.l]
+
+
+
+/***************************************************************************
+ OPCODES
+***************************************************************************/
+
+static void noop(void)
+{
+}
+
+/**************************** TRAP 0 ******************************/
+
+static void trap0(void)
+{
+ generate_exception(EXCEPTION_TRAP0);
+}
+
+/**************************** Bcc ******************************/
+
+static void bsp(void)
+{
+ if ((INT32)asap.znflag > 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bmz(void)
+{
+ if ((INT32)asap.znflag <= 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bgt(void)
+{
+ if (asap.znflag != 0 && (INT32)(asap.znflag ^ asap.vflag) >= 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void ble(void)
+{
+ if (asap.znflag == 0 || (INT32)(asap.znflag ^ asap.vflag) < 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bge(void)
+{
+ if ((INT32)(asap.znflag ^ asap.vflag) >= 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void blt(void)
+{
+ if ((INT32)(asap.znflag ^ asap.vflag) < 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bhi(void)
+{
+ if (asap.znflag != 0 && asap.cflag)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bls(void)
+{
+ if (asap.znflag == 0 || !asap.cflag)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bcc(void)
+{
+ if (!asap.cflag)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bcs(void)
+{
+ if (asap.cflag)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bpl(void)
+{
+ if ((INT32)asap.znflag >= 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bmi(void)
+{
+ if ((INT32)asap.znflag < 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bne(void)
+{
+ if (asap.znflag != 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void beq(void)
+{
+ if (asap.znflag == 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bvc(void)
+{
+ if ((INT32)asap.vflag >= 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+static void bvs(void)
+{
+ if ((INT32)asap.vflag < 0)
+ {
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+ }
+}
+
+/**************************** BSR ******************************/
+
+static void bsr(void)
+{
+ DSTVAL = asap.pc + 4;
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+}
+
+static void bsr_0(void)
+{
+ asap.nextpc = asap.ppc + ((INT32)(asap.op.d << 10) >> 8);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ /*UPDATEPC();*/
+
+ execute_instruction();
+ asap_icount--;
+}
+
+/**************************** LEA ******************************/
+
+static void lea(void)
+{
+ DSTVAL = SRC1VAL + (SRC2VAL << 2);
+}
+
+static void lea_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + (src2 << 2);
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ if (src1 & 0xc0000000)
+ SET_CFLAG(1);
+ if (((src1 ^ (src1 >> 1)) & 0x20000000) || (src1 ^ (src1 >> 2)) & 0x20000000)
+ SET_VFLAG(1);
+ DSTVAL = dst;
+}
+
+static void lea_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + (src2 << 2);
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ if (src1 & 0xc0000000)
+ SET_CFLAG(1);
+ if (((src1 ^ (src1 >> 1)) & 0x20000000) || (src1 ^ (src1 >> 2)) & 0x20000000)
+ SET_VFLAG(1);
+}
+
+/**************************** LEAH ******************************/
+
+static void leah(void)
+{
+ DSTVAL = SRC1VAL + (SRC2VAL << 1);
+}
+
+static void leah_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + (src2 << 1);
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ if (src1 & 0x80000000)
+ SET_CFLAG(1);
+ if ((src1 ^ (src1 >> 1)) & 0x40000000)
+ SET_VFLAG(1);
+ DSTVAL = dst;
+}
+
+static void leah_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + (src2 << 1);
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ if (src1 & 0x80000000)
+ SET_CFLAG(1);
+ if ((src1 ^ (src1 >> 1)) & 0x40000000)
+ SET_VFLAG(1);
+}
+
+/**************************** SUBR ******************************/
+
+static void subr(void)
+{
+ DSTVAL = SRC2VAL - SRC1VAL;
+}
+
+static void subr_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src2 - src1;
+
+ SET_ZNCV_SUB(dst, src2, src1);
+ DSTVAL = dst;
+}
+
+static void subr_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src2 - src1;
+
+ SET_ZNCV_SUB(dst, src2, src1);
+}
+
+/**************************** XOR ******************************/
+
+static void xor(void)
+{
+ DSTVAL = SRC1VAL ^ SRC2VAL;
+}
+
+static void xor_c(void)
+{
+ UINT32 dst = SRC1VAL ^ SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void xor_c0(void)
+{
+ UINT32 dst = SRC1VAL ^ SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** XOR ******************************/
+
+static void xorn(void)
+{
+ DSTVAL = SRC1VAL ^ ~SRC2VAL;
+}
+
+static void xorn_c(void)
+{
+ UINT32 dst = SRC1VAL ^ ~SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void xorn_c0(void)
+{
+ UINT32 dst = SRC1VAL ^ ~SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** ADD ******************************/
+
+static void add(void)
+{
+ DSTVAL = SRC1VAL + SRC2VAL;
+}
+
+static void add_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+static void add_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+}
+
+/**************************** ADD ******************************/
+
+static void sub(void)
+{
+ DSTVAL = SRC1VAL - SRC2VAL;
+}
+
+static void sub_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+static void sub_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+}
+
+/**************************** ADDC ******************************/
+
+static void addc(void)
+{
+ DSTVAL = SRC1VAL + SRC2VAL + asap.cflag;
+}
+
+static void addc_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2 + asap.cflag;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+static void addc_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2 + asap.cflag;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+}
+
+/**************************** SUBC ******************************/
+
+static void subc(void)
+{
+ DSTVAL = SRC1VAL - SRC2VAL - 1 + asap.cflag;
+}
+
+static void subc_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2 - 1 + asap.cflag;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+static void subc_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2 - 1 + asap.cflag;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+}
+
+/**************************** AND ******************************/
+
+static void and(void)
+{
+ DSTVAL = SRC1VAL & SRC2VAL;
+}
+
+static void and_c(void)
+{
+ UINT32 dst = SRC1VAL & SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void and_c0(void)
+{
+ UINT32 dst = SRC1VAL & SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** ANDN ******************************/
+
+static void andn(void)
+{
+ DSTVAL = SRC1VAL & ~SRC2VAL;
+}
+
+static void andn_c(void)
+{
+ UINT32 dst = SRC1VAL & ~SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void andn_c0(void)
+{
+ UINT32 dst = SRC1VAL & ~SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** OR ******************************/
+
+static void or(void)
+{
+ DSTVAL = SRC1VAL | SRC2VAL;
+}
+
+static void or_c(void)
+{
+ UINT32 dst = SRC1VAL | SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void or_c0(void)
+{
+ UINT32 dst = SRC1VAL | SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** ORN ******************************/
+
+static void orn(void)
+{
+ DSTVAL = SRC1VAL | ~SRC2VAL;
+}
+
+static void orn_c(void)
+{
+ UINT32 dst = SRC1VAL | ~SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void orn_c0(void)
+{
+ UINT32 dst = SRC1VAL | ~SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** LD ******************************/
+
+static void ld(void)
+{
+ DSTVAL = READLONG(SRC1VAL + (SRC2VAL << 2));
+}
+
+static void ld_0(void)
+{
+ READLONG(SRC1VAL + (SRC2VAL << 2));
+}
+
+static void ld_c(void)
+{
+ UINT32 dst = READLONG(SRC1VAL + (SRC2VAL << 2));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void ld_c0(void)
+{
+ UINT32 dst = READLONG(SRC1VAL + (SRC2VAL << 2));
+ SET_ZN(dst);
+}
+
+/**************************** LDH ******************************/
+
+static void ldh(void)
+{
+ DSTVAL = (INT16)READWORD(SRC1VAL + (SRC2VAL << 1));
+}
+
+static void ldh_0(void)
+{
+ READWORD(SRC1VAL + (SRC2VAL << 1));
+}
+
+static void ldh_c(void)
+{
+ UINT32 dst = (INT16)READWORD(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void ldh_c0(void)
+{
+ UINT32 dst = (INT16)READWORD(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+}
+
+/**************************** LDUH ******************************/
+
+static void lduh(void)
+{
+ DSTVAL = READWORD(SRC1VAL + (SRC2VAL << 1));
+}
+
+static void lduh_0(void)
+{
+ READWORD(SRC1VAL + (SRC2VAL << 1));
+}
+
+static void lduh_c(void)
+{
+ UINT32 dst = READWORD(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void lduh_c0(void)
+{
+ UINT32 dst = READWORD(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+}
+
+/**************************** STH ******************************/
+
+static void sth(void)
+{
+ WRITEWORD(SRC1VAL + (SRC2VAL << 1), DSTVAL);
+}
+
+static void sth_0(void)
+{
+ WRITEWORD(SRC1VAL + (SRC2VAL << 1), 0);
+}
+
+static void sth_c(void)
+{
+ UINT32 dst = (UINT16)DSTVAL;
+ SET_ZN(dst);
+ WRITEWORD(SRC1VAL + (SRC2VAL << 1), dst);
+}
+
+static void sth_c0(void)
+{
+ SET_ZN(0);
+ WRITEWORD(SRC1VAL + (SRC2VAL << 1), 0);
+}
+
+/**************************** ST ******************************/
+
+static void st(void)
+{
+ WRITELONG(SRC1VAL + (SRC2VAL << 2), DSTVAL);
+}
+
+static void st_0(void)
+{
+ WRITELONG(SRC1VAL + (SRC2VAL << 2), 0);
+}
+
+static void st_c(void)
+{
+ UINT32 dst = DSTVAL;
+ SET_ZN(dst);
+ WRITELONG(SRC1VAL + (SRC2VAL << 2), dst);
+}
+
+static void st_c0(void)
+{
+ SET_ZN(0);
+ WRITELONG(SRC1VAL + (SRC2VAL << 2), 0);
+}
+
+/**************************** LDB ******************************/
+
+static void ldb(void)
+{
+ DSTVAL = (INT8)READBYTE(SRC1VAL + SRC2VAL);
+}
+
+static void ldb_0(void)
+{
+ READBYTE(SRC1VAL + SRC2VAL);
+}
+
+static void ldb_c(void)
+{
+ UINT32 dst = (INT8)READBYTE(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void ldb_c0(void)
+{
+ UINT32 dst = (INT8)READBYTE(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+}
+
+/**************************** LDUB ******************************/
+
+static void ldub(void)
+{
+ DSTVAL = READBYTE(SRC1VAL + SRC2VAL);
+}
+
+static void ldub_0(void)
+{
+ READBYTE(SRC1VAL + SRC2VAL);
+}
+
+static void ldub_c(void)
+{
+ UINT32 dst = READBYTE(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void ldub_c0(void)
+{
+ UINT32 dst = READBYTE(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+}
+
+/**************************** STB ******************************/
+
+static void stb(void)
+{
+ WRITEBYTE(SRC1VAL + SRC2VAL, DSTVAL);
+}
+
+static void stb_0(void)
+{
+ WRITEBYTE(SRC1VAL + SRC2VAL, 0);
+}
+
+static void stb_c(void)
+{
+ UINT32 dst = (UINT8)DSTVAL;
+ SET_ZN(dst);
+ WRITEBYTE(SRC1VAL + SRC2VAL, dst);
+}
+
+static void stb_c0(void)
+{
+ SET_ZN(0);
+ WRITEBYTE(SRC1VAL + SRC2VAL, 0);
+}
+
+/**************************** ASHR ******************************/
+
+static void ashr(void)
+{
+ UINT32 src2 = SRC2VAL;
+ DSTVAL = (src2 < 32) ? ((INT32)SRC1VAL >> src2) : ((INT32)SRC1VAL >> 31);
+}
+
+static void ashr_c(void)
+{
+ UINT32 src2 = SRC2VAL;
+ asap.cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = (INT32)src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ asap.cflag = src1 >> 31;
+ }
+ DSTVAL = dst;
+ }
+ else
+ {
+ UINT32 dst = (INT32)SRC1VAL >> 31;
+ SET_ZN(dst);
+ DSTVAL = dst;
+ }
+}
+
+static void ashr_c0(void)
+{
+ UINT32 src2 = SRC2VAL;
+ asap.cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = (INT32)src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ asap.cflag = src1 >> 31;
+ }
+ }
+ else
+ {
+ UINT32 dst = (INT32)SRC1VAL >> 31;
+ SET_ZN(dst);
+ }
+}
+
+/**************************** LSHR ******************************/
+
+static void lshr(void)
+{
+ UINT32 src2 = SRC2VAL;
+ DSTVAL = (src2 < 32) ? (SRC1VAL >> src2) : (SRC1VAL >> 31);
+}
+
+static void lshr_c(void)
+{
+ UINT32 src2 = SRC2VAL;
+ asap.cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ asap.cflag = src1 >> 31;
+ }
+ DSTVAL = dst;
+ }
+ else
+ {
+ UINT32 dst = SRC1VAL >> 31;
+ SET_ZN(dst);
+ DSTVAL = dst;
+ }
+}
+
+static void lshr_c0(void)
+{
+ UINT32 src2 = SRC2VAL;
+ asap.cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ asap.cflag = src1 >> 31;
+ }
+ }
+ else
+ {
+ SET_ZN(0);
+ DSTVAL = 0;
+ }
+}
+
+/**************************** ASHL ******************************/
+
+static void ashl(void)
+{
+ UINT32 src2 = SRC2VAL;
+ DSTVAL = (src2 < 32) ? (SRC1VAL << src2) : 0;
+}
+
+static void ashl_c(void)
+{
+ UINT32 src2 = SRC2VAL;
+ asap.cflag = asap.vflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 << src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = (INT32)src1 >> (32 - src2);
+ asap.cflag = src1 & PS_CFLAG;
+ asap.vflag = (src1 != ((INT32)dst >> 31)) << 31;
+ }
+ DSTVAL = dst;
+ }
+ else
+ {
+ SET_ZN(0);
+ DSTVAL = 0;
+ }
+}
+
+static void ashl_c0(void)
+{
+ UINT32 src2 = SRC2VAL;
+ asap.cflag = asap.vflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 << src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = (INT32)src1 >> (32 - src2);
+ asap.cflag = src1 & PS_CFLAG;
+ asap.vflag = (src1 != ((INT32)dst >> 31)) << 31;
+ }
+ }
+ else
+ SET_ZN(0);
+}
+
+/**************************** ROTL ******************************/
+
+static void rotl(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL & 31;
+ DSTVAL = (src1 << src2) | (src1 >> (32 - src2));
+}
+
+static void rotl_c(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL & 31;
+ UINT32 dst = (src1 << src2) | (src1 >> (32 - src2));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+static void rotl_c0(void)
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL & 31;
+ UINT32 dst = (src1 << src2) | (src1 >> (32 - src2));
+ SET_ZN(dst);
+}
+
+/**************************** GETPS ******************************/
+
+static void getps(void)
+{
+ DSTVAL = GET_FLAGS(&asap);
+}
+
+/**************************** PUTPS ******************************/
+
+static void putps(void)
+{
+ UINT32 src2 = SRC2VAL & 0x3f;
+ SET_FLAGS(&asap, src2);
+ check_irqs();
+}
+
+/**************************** JSR ******************************/
+
+static void jsr(void)
+{
+ DSTVAL = asap.pc + 4;
+ asap.nextpc = SRC1VAL + (SRC2VAL << 2);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ UPDATEPC();
+
+ execute_instruction();
+ asap_icount--;
+}
+
+static void jsr_0(void)
+{
+ asap.nextpc = SRC1VAL + (SRC2VAL << 2);
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ UPDATEPC();
+
+ execute_instruction();
+ asap_icount--;
+}
+
+static void jsr_c(void)
+{
+ DSTVAL = asap.pc + 4;
+ asap.nextpc = SRC1VAL + (SRC2VAL << 2);
+ asap.iflag = asap.pflag;
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ UPDATEPC();
+
+ execute_instruction();
+ asap_icount--;
+ check_irqs();
+}
+
+static void jsr_c0(void)
+{
+ asap.nextpc = SRC1VAL + (SRC2VAL << 2);
+ asap.iflag = asap.pflag;
+
+ fetch_instruction();
+ asap.pc = asap.nextpc;
+ asap.nextpc = ~0;
+ UPDATEPC();
+
+ execute_instruction();
+ asap_icount--;
+ check_irqs();
+}
+
+/**************************** TRAP F ******************************/
+
+static void trapf(void)
+{
+ generate_exception(EXCEPTION_TRAPF);
+}
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void asap_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 + ASAP_IRQ0: set_irq_line(ASAP_IRQ0, info->i); break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + ASAP_PC: asap.pc = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_PS: SET_FLAGS(&asap, info->i); break;
+
+ case CPUINFO_INT_REGISTER + ASAP_R0: src2val[REGBASE + 0] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R1: src2val[REGBASE + 1] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R2: src2val[REGBASE + 2] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R3: src2val[REGBASE + 3] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R4: src2val[REGBASE + 4] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R5: src2val[REGBASE + 5] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R6: src2val[REGBASE + 6] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R7: src2val[REGBASE + 7] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R8: src2val[REGBASE + 8] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R9: src2val[REGBASE + 9] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R10: src2val[REGBASE + 10] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R11: src2val[REGBASE + 11] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R12: src2val[REGBASE + 12] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R13: src2val[REGBASE + 13] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R14: src2val[REGBASE + 14] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R15: src2val[REGBASE + 15] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R16: src2val[REGBASE + 16] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R17: src2val[REGBASE + 17] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R18: src2val[REGBASE + 18] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R19: src2val[REGBASE + 19] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R20: src2val[REGBASE + 20] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R21: src2val[REGBASE + 21] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R22: src2val[REGBASE + 22] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R23: src2val[REGBASE + 23] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R24: src2val[REGBASE + 24] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R25: src2val[REGBASE + 25] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R26: src2val[REGBASE + 26] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R27: src2val[REGBASE + 27] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R28: src2val[REGBASE + 28] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R29: src2val[REGBASE + 29] = info->i; break;
+ case CPUINFO_INT_REGISTER + ASAP_R30: src2val[REGBASE + 30] = info->i; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + ASAP_R31: src2val[REGBASE + 31] = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void asap_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(asap); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 12; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 2; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; 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 + ASAP_IRQ0: info->i = asap.irq_state; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = asap.ppc; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + ASAP_PC: info->i = asap.pc; break;
+ case CPUINFO_INT_REGISTER + ASAP_PS: info->i = GET_FLAGS(&asap); break;
+
+ case CPUINFO_INT_REGISTER + ASAP_R0: info->i = src2val[REGBASE + 0]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R1: info->i = src2val[REGBASE + 1]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R2: info->i = src2val[REGBASE + 2]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R3: info->i = src2val[REGBASE + 3]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R4: info->i = src2val[REGBASE + 4]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R5: info->i = src2val[REGBASE + 5]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R6: info->i = src2val[REGBASE + 6]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R7: info->i = src2val[REGBASE + 7]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R8: info->i = src2val[REGBASE + 8]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R9: info->i = src2val[REGBASE + 9]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R10: info->i = src2val[REGBASE + 10]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R11: info->i = src2val[REGBASE + 11]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R12: info->i = src2val[REGBASE + 12]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R13: info->i = src2val[REGBASE + 13]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R14: info->i = src2val[REGBASE + 14]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R15: info->i = src2val[REGBASE + 15]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R16: info->i = src2val[REGBASE + 16]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R17: info->i = src2val[REGBASE + 17]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R18: info->i = src2val[REGBASE + 18]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R19: info->i = src2val[REGBASE + 19]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R20: info->i = src2val[REGBASE + 20]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R21: info->i = src2val[REGBASE + 21]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R22: info->i = src2val[REGBASE + 22]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R23: info->i = src2val[REGBASE + 23]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R24: info->i = src2val[REGBASE + 24]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R25: info->i = src2val[REGBASE + 25]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R26: info->i = src2val[REGBASE + 26]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R27: info->i = src2val[REGBASE + 27]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R28: info->i = src2val[REGBASE + 28]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R29: info->i = src2val[REGBASE + 29]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R30: info->i = src2val[REGBASE + 30]; break;
+ case CPUINFO_INT_REGISTER + ASAP_R31: info->i = src2val[REGBASE + 31]; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = asap_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = asap_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = asap_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = asap_init; break;
+ case CPUINFO_PTR_RESET: info->reset = asap_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = asap_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = asap_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = asap_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &asap_icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "ASAP"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Atari ASAP"); 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) Aaron Giles 2000-2004"); break;
+
+ case CPUINFO_STR_FLAGS: strcpy(info->s, " "); break;
+
+ case CPUINFO_STR_REGISTER + ASAP_PC: sprintf(info->s, "PC: %08X", asap.pc); break;
+ case CPUINFO_STR_REGISTER + ASAP_PS: sprintf(info->s, "PS: %08X", GET_FLAGS(&asap)); break;
+
+ case CPUINFO_STR_REGISTER + ASAP_R0: sprintf(info->s, "R0: %08X", asap.r[0]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R1: sprintf(info->s, "R1: %08X", asap.r[1]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R2: sprintf(info->s, "R2: %08X", asap.r[2]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R3: sprintf(info->s, "R3: %08X", asap.r[3]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R4: sprintf(info->s, "R4: %08X", asap.r[4]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R5: sprintf(info->s, "R5: %08X", asap.r[5]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R6: sprintf(info->s, "R6: %08X", asap.r[6]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R7: sprintf(info->s, "R7: %08X", asap.r[7]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R8: sprintf(info->s, "R8: %08X", asap.r[8]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R9: sprintf(info->s, "R9: %08X", asap.r[9]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R10: sprintf(info->s, "R10:%08X", asap.r[10]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R11: sprintf(info->s, "R11:%08X", asap.r[11]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R12: sprintf(info->s, "R12:%08X", asap.r[12]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R13: sprintf(info->s, "R13:%08X", asap.r[13]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R14: sprintf(info->s, "R14:%08X", asap.r[14]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R15: sprintf(info->s, "R15:%08X", asap.r[15]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R16: sprintf(info->s, "R16:%08X", asap.r[16]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R17: sprintf(info->s, "R17:%08X", asap.r[17]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R18: sprintf(info->s, "R18:%08X", asap.r[18]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R19: sprintf(info->s, "R19:%08X", asap.r[19]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R20: sprintf(info->s, "R20:%08X", asap.r[20]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R21: sprintf(info->s, "R21:%08X", asap.r[21]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R22: sprintf(info->s, "R22:%08X", asap.r[22]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R23: sprintf(info->s, "R23:%08X", asap.r[23]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R24: sprintf(info->s, "R24:%08X", asap.r[24]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R25: sprintf(info->s, "R25:%08X", asap.r[25]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R26: sprintf(info->s, "R26:%08X", asap.r[26]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R27: sprintf(info->s, "R27:%08X", asap.r[27]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R28: sprintf(info->s, "R28:%08X", asap.r[28]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R29: sprintf(info->s, "R29:%08X", asap.r[29]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R30: sprintf(info->s, "R30:%08X", asap.r[30]); break;
+ case CPUINFO_STR_REGISTER + ASAP_R31: sprintf(info->s, "R31:%08X", asap.r[31]); break;
+ }
+}