diff options
Diffstat (limited to 'src/emu/cpu/asap/asap.c')
-rw-r--r-- | src/emu/cpu/asap/asap.c | 1858 |
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; + } +} |