summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/asap/asap.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/asap/asap.c')
-rw-r--r--trunk/src/emu/cpu/asap/asap.c1714
1 files changed, 1714 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/asap/asap.c b/trunk/src/emu/cpu/asap/asap.c
new file mode 100644
index 00000000000..115278ec9a9
--- /dev/null
+++ b/trunk/src/emu/cpu/asap/asap.c
@@ -0,0 +1,1714 @@
+/***************************************************************************
+
+ asap.c
+
+ Core implementation for the portable ASAP emulator.
+ ASAP = Atari Simplified Architecture Processor
+
+ Special thanks to Mike Albaugh for clarification on a couple of fine points.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+#include "asap.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+const UINT32 PS_CFLAG = 0x00000001;
+const UINT32 PS_VFLAG = 0x00000002;
+const UINT32 PS_ZFLAG = 0x00000004;
+const UINT32 PS_NFLAG = 0x00000008;
+const UINT32 PS_IFLAG = 0x00000010;
+const UINT32 PS_PFLAG = 0x00000020;
+
+const int EXCEPTION_RESET = 0;
+const int EXCEPTION_TRAP0 = 1;
+const int EXCEPTION_TRAPF = 2;
+const int EXCEPTION_INTERRUPT = 3;
+
+const int REGBASE = 0xffe0;
+
+
+
+//**************************************************************************
+// MACROS
+//**************************************************************************
+
+#define SET_C_ADD(a,b) (m_cflag = (UINT32)(b) > (UINT32)(~(a)))
+#define SET_C_SUB(a,b) (m_cflag = (UINT32)(b) <= (UINT32)(a))
+#define SET_V_ADD(r,a,b) (m_vflag = ~((a) ^ (b)) & ((a) ^ (r)))
+#define SET_V_SUB(r,a,b) (m_vflag = ((a) ^ (b)) & ((a) ^ (r)))
+#define SET_ZN(r) (m_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) (m_vflag = (val) << 31)
+#define SET_CFLAG(val) (m_cflag = (val))
+
+#define GET_FLAGS() (m_cflag | \
+ ((m_vflag >> 30) & PS_VFLAG) | \
+ ((m_znflag == 0) << 2) | \
+ ((m_znflag >> 28) & PS_NFLAG) | \
+ (m_iflag << 4) | \
+ (m_pflag << 5))
+
+#define SET_FLAGS(v) do { \
+ m_cflag = (v) & PS_CFLAG; \
+ m_vflag = ((v) & PS_VFLAG) << 30; \
+ m_znflag = ((v) & PS_ZFLAG) ? 0 : ((v) & PS_NFLAG) ? -1 : 1; \
+ m_iflag = ((v) & PS_IFLAG) >> 4; \
+ m_pflag = ((v) & PS_PFLAG) >> 5; \
+ } while (0);
+
+#define OPCODE (m_op >> 27)
+#define DSTREG ((m_op >> 22) & 31)
+#define DSTVAL m_src2val[REGBASE + DSTREG]
+#define SRC1REG ((m_op >> 16) & 31)
+#define SRC1VAL m_src2val[REGBASE + SRC1REG]
+#define SRC2VAL m_src2val[m_op & 0xffff]
+
+
+
+//**************************************************************************
+// STATIC OPCODE TABLES
+//**************************************************************************
+
+const asap_device::ophandler asap_device::s_opcodetable[32][4] =
+{
+ { &asap_device::trap0, &asap_device::trap0, &asap_device::trap0, &asap_device::trap0 },
+ { &asap_device::noop, &asap_device::noop, &asap_device::noop, &asap_device::noop },
+ { &asap_device::bsr, &asap_device::bsr_0, &asap_device::bsr, &asap_device::bsr_0 },
+ { &asap_device::lea, &asap_device::noop, &asap_device::lea_c, &asap_device::lea_c0 },
+ { &asap_device::leah, &asap_device::noop, &asap_device::leah_c, &asap_device::leah_c0 },
+ { &asap_device::subr, &asap_device::noop, &asap_device::subr_c, &asap_device::subr_c0 },
+ { &asap_device::xor_, &asap_device::noop, &asap_device::xor_c, &asap_device::xor_c0 },
+ { &asap_device::xorn, &asap_device::noop, &asap_device::xorn_c, &asap_device::xorn_c0 },
+ { &asap_device::add, &asap_device::noop, &asap_device::add_c, &asap_device::add_c0 },
+ { &asap_device::sub, &asap_device::noop, &asap_device::sub_c, &asap_device::sub_c0 },
+ { &asap_device::addc, &asap_device::noop, &asap_device::addc_c, &asap_device::addc_c0 },
+ { &asap_device::subc, &asap_device::noop, &asap_device::subc_c, &asap_device::subc_c0 },
+ { &asap_device::and_, &asap_device::noop, &asap_device::and_c, &asap_device::and_c0 },
+ { &asap_device::andn, &asap_device::noop, &asap_device::andn_c, &asap_device::andn_c0 },
+ { &asap_device::or_, &asap_device::noop, &asap_device::or_c, &asap_device::or_c0 },
+ { &asap_device::orn, &asap_device::noop, &asap_device::orn_c, &asap_device::orn_c0 },
+ { &asap_device::ld, &asap_device::ld_0, &asap_device::ld_c, &asap_device::ld_c0 },
+ { &asap_device::ldh, &asap_device::ldh_0, &asap_device::ldh_c, &asap_device::ldh_c0 },
+ { &asap_device::lduh, &asap_device::lduh_0, &asap_device::lduh_c, &asap_device::lduh_c0 },
+ { &asap_device::sth, &asap_device::sth_0, &asap_device::sth_c, &asap_device::sth_c0 },
+ { &asap_device::st, &asap_device::st_0, &asap_device::st_c, &asap_device::st_c0 },
+ { &asap_device::ldb, &asap_device::ldb_0, &asap_device::ldb_c, &asap_device::ldb_c0 },
+ { &asap_device::ldub, &asap_device::ldub_0, &asap_device::ldub_c, &asap_device::ldub_c0 },
+ { &asap_device::stb, &asap_device::stb_0, &asap_device::stb_c, &asap_device::stb_c0 },
+ { &asap_device::ashr, &asap_device::noop, &asap_device::ashr_c, &asap_device::ashr_c0 },
+ { &asap_device::lshr, &asap_device::noop, &asap_device::lshr_c, &asap_device::lshr_c0 },
+ { &asap_device::ashl, &asap_device::noop, &asap_device::ashl_c, &asap_device::ashl_c0 },
+ { &asap_device::rotl, &asap_device::noop, &asap_device::rotl_c, &asap_device::rotl_c0 },
+ { &asap_device::getps, &asap_device::noop, &asap_device::getps, &asap_device::noop },
+ { &asap_device::putps, &asap_device::putps, &asap_device::putps, &asap_device::putps },
+ { &asap_device::jsr, &asap_device::jsr_0, &asap_device::jsr_c, &asap_device::jsr_c0 },
+ { &asap_device::trapf, &asap_device::trapf, &asap_device::trapf, &asap_device::trapf }
+};
+
+const asap_device::ophandler asap_device::s_conditiontable[16] =
+{
+ &asap_device::bsp, &asap_device::bmz, &asap_device::bgt, &asap_device::ble,
+ &asap_device::bge, &asap_device::blt, &asap_device::bhi, &asap_device::bls,
+ &asap_device::bcc, &asap_device::bcs, &asap_device::bpl, &asap_device::bmi,
+ &asap_device::bne, &asap_device::beq, &asap_device::bvc, &asap_device::bvs
+};
+
+
+
+//**************************************************************************
+// DEVICE INTERFACE
+//**************************************************************************
+
+// device type definition
+const device_type ASAP = &device_creator<asap_device>;
+
+//-------------------------------------------------
+// asap_device - constructor
+//-------------------------------------------------
+
+asap_device::asap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : cpu_device(mconfig, ASAP, "ASAP", tag, owner, clock),
+ m_program_config("program", ENDIANNESS_LITTLE, 32, 32),
+ m_pc(0),
+ m_pflag(0),
+ m_iflag(0),
+ m_cflag(0),
+ m_vflag(0),
+ m_znflag(0),
+ m_flagsio(0),
+ m_op(0),
+ m_ppc(0),
+ m_nextpc(0),
+ m_irq_state(0),
+ m_icount(0),
+ m_program(NULL),
+ m_direct(NULL)
+{
+ // initialize the src2val table to contain immediates for low values
+ for (int i = 0; i < REGBASE; i++)
+ m_src2val[i] = i;
+
+ // build the opcode table
+ for (int op = 0; op < 32; op++)
+ for (int dst = 0; dst < 32; dst++)
+ for (int cond = 0; cond < 2; cond++)
+ if (op == 1)
+ m_opcode[(op << 6) + (dst << 1) + cond] = s_conditiontable[dst & 15];
+ else if (cond && dst == 0)
+ m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][3];
+ else if (cond)
+ m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][2];
+ else if (dst == 0)
+ m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][1];
+ else
+ m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][0];
+}
+
+
+//-------------------------------------------------
+// device_start - start up the device
+//-------------------------------------------------
+
+void asap_device::device_start()
+{
+ // get our address spaces
+ m_program = space(AS_PROGRAM);
+ m_direct = &m_program->direct();
+
+ // register our state for the debugger
+ astring tempstr;
+ state_add(STATE_GENPC, "GENPC", m_pc).noshow();
+ state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow();
+ state_add(STATE_GENSP, "GENSP", m_src2val[REGBASE + 31]).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_flagsio).callimport().callexport().formatstr("%6s").noshow();
+ state_add(ASAP_PC, "PC", m_pc);
+ state_add(ASAP_PS, "PS", m_flagsio).callimport().callexport();
+ for (int regnum = 0; regnum < 32; regnum++)
+ state_add(ASAP_R0 + regnum, tempstr.format("R%d", regnum), m_src2val[REGBASE + regnum]);
+
+ // register our state for saving
+ save_item(NAME(m_pc));
+ save_item(NAME(m_pflag));
+ save_item(NAME(m_iflag));
+ save_item(NAME(m_cflag));
+ save_item(NAME(m_vflag));
+ save_item(NAME(m_znflag));
+ save_item(NAME(m_op));
+ save_item(NAME(m_ppc));
+ save_item(NAME(m_nextpc));
+ save_item(NAME(m_irq_state));
+
+ // set our instruction counter
+ m_icountptr = &m_icount;
+}
+
+
+//-------------------------------------------------
+// device_reset - reset the device
+//-------------------------------------------------
+
+void asap_device::device_reset()
+{
+ // initialize the state
+ m_src2val[REGBASE + 0] = 0;
+ m_pc = 0;
+ m_iflag = 0;
+
+ m_ppc = 0;
+ m_nextpc = ~0;
+ m_irq_state = 0;
+}
+
+
+//-------------------------------------------------
+// memory_space_config - return the configuration
+// of the specified address space, or NULL if
+// the space doesn't exist
+//-------------------------------------------------
+
+const address_space_config *asap_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_PROGRAM) ? &m_program_config : NULL;
+}
+
+
+//-------------------------------------------------
+// state_import - import state into the device,
+// after it has been set
+//-------------------------------------------------
+
+void asap_device::state_import(const device_state_entry &entry)
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ case ASAP_PS:
+ SET_FLAGS(m_flagsio);
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// state_export - export state from the device,
+// to a known location where it can be read
+//-------------------------------------------------
+
+void asap_device::state_export(const device_state_entry &entry)
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ case ASAP_PS:
+ m_flagsio = GET_FLAGS();
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// state_string_export - export state as a string
+// for the debugger
+//-------------------------------------------------
+
+void asap_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ string.printf("%c%c%c%c%c%c",
+ m_pflag ? 'P' : '.',
+ m_iflag ? 'I' : '.',
+ ((INT32)m_znflag < 0) ? 'N' : '.',
+ (m_znflag == 0) ? 'Z' : '.',
+ ((m_vflag >> 30) & PS_VFLAG) ? 'V' : '.',
+ m_cflag ? 'C' : '.');
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// disasm_min_opcode_bytes - return the length
+// of the shortest instruction, in bytes
+//-------------------------------------------------
+
+UINT32 asap_device::disasm_min_opcode_bytes() const
+{
+ return 4;
+}
+
+
+//-------------------------------------------------
+// disasm_max_opcode_bytes - return the length
+// of the longest instruction, in bytes
+//-------------------------------------------------
+
+UINT32 asap_device::disasm_max_opcode_bytes() const
+{
+ return 12;
+}
+
+
+//-------------------------------------------------
+// disasm_disassemble - call the disassembly
+// helper function
+//-------------------------------------------------
+
+offs_t asap_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( asap );
+ return CPU_DISASSEMBLE_NAME(asap)(NULL, buffer, pc, oprom, opram, 0);
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// readop - read an opcode at the given address
+//-------------------------------------------------
+
+inline UINT32 asap_device::readop(offs_t pc)
+{
+ return m_direct->read_decrypted_dword(pc);
+}
+
+
+//-------------------------------------------------
+// readbyte - read a byte at the given address
+//-------------------------------------------------
+
+inline UINT8 asap_device::readbyte(offs_t address)
+{
+ // no alignment issues with bytes
+ return m_program->read_byte(address);
+}
+
+
+//-------------------------------------------------
+// readword - read a word at the given address
+//-------------------------------------------------
+
+inline UINT16 asap_device::readword(offs_t address)
+{
+ // aligned reads are easy
+ if (!(address & 1))
+ return m_program->read_word(address);
+
+ // misaligned reads are tricky
+ return m_program->read_dword(address & ~3) >> (address & 3);
+}
+
+
+//-------------------------------------------------
+// readlong - read a long at the given address
+//-------------------------------------------------
+
+inline UINT32 asap_device::readlong(offs_t address)
+{
+ // aligned reads are easy
+ if (!(address & 3))
+ return m_program->read_dword(address);
+
+ // misaligned reads are tricky
+ return m_program->read_dword(address & ~3) >> (address & 3);
+}
+
+
+//-------------------------------------------------
+// writebyte - write a byte at the given address
+//-------------------------------------------------
+
+inline void asap_device::writebyte(offs_t address, UINT8 data)
+{
+ // no alignment issues with bytes
+ m_program->write_byte(address, data);
+}
+
+
+//-------------------------------------------------
+// writeword - write a word at the given address
+//-------------------------------------------------
+
+inline void asap_device::writeword(offs_t address, UINT16 data)
+{
+ // aligned writes are easy
+ if (!(address & 1))
+ {
+ m_program->write_word(address, data);
+ return;
+ }
+
+ // misaligned writes are tricky
+ if (!(address & 2))
+ {
+ m_program->write_byte(address + 1, data);
+ m_program->write_byte(address + 2, data >> 8);
+ }
+ else
+ m_program->write_byte(address + 1, data);
+}
+
+
+//-------------------------------------------------
+// writelong - write a long at the given address
+//-------------------------------------------------
+
+inline void asap_device::writelong(offs_t address, UINT32 data)
+{
+ // aligned writes are easy
+ if (!(address & 3))
+ {
+ m_program->write_dword(address, data);
+ return;
+ }
+
+ // misaligned writes are tricky
+ switch (address & 3)
+ {
+ case 1:
+ m_program->write_byte(address, data);
+ m_program->write_word(address + 1, data >> 8);
+ break;
+ case 2:
+ m_program->write_word(address, data);
+ break;
+ case 3:
+ m_program->write_byte(address, data);
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// generate_exception - generate an exception of
+// the requested type
+//-------------------------------------------------
+
+inline void asap_device::generate_exception(int exception)
+{
+ m_pflag = m_iflag;
+ m_iflag = 0;
+
+ m_src2val[REGBASE + 30] = m_pc;
+ m_src2val[REGBASE + 31] = (m_nextpc == ~0) ? m_pc + 4 : m_nextpc;
+
+ m_pc = 0x40 * exception;
+ m_nextpc = ~0;
+
+ m_icount--;
+}
+
+
+//-------------------------------------------------
+// check_irqs - check for pending IRQs
+//-------------------------------------------------
+
+inline void asap_device::check_irqs()
+{
+ if (m_irq_state && m_iflag)
+ {
+ generate_exception(EXCEPTION_INTERRUPT);
+ standard_irq_callback(ASAP_IRQ0);
+ }
+}
+
+
+
+//**************************************************************************
+// CORE EXECUTION
+//**************************************************************************
+
+inline void asap_device::fetch_instruction()
+{
+ // debugging
+ m_ppc = m_pc;
+
+ // instruction fetch
+ m_op = readop(m_pc);
+ m_pc += 4;
+}
+
+inline void asap_device::fetch_instruction_debug()
+{
+ // debugging
+ m_ppc = m_pc;
+ debugger_instruction_hook(this, m_pc);
+
+ // instruction fetch
+ m_op = readop(m_pc);
+ m_pc += 4;
+}
+
+inline void asap_device::execute_instruction()
+{
+ // parse the instruction
+ (this->*m_opcode[m_op >> 21])();
+}
+
+
+//-------------------------------------------------
+// execute_min_cycles - return minimum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+UINT32 asap_device::execute_min_cycles() const
+{
+ return 1;
+}
+
+
+//-------------------------------------------------
+// execute_max_cycles - return maximum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+UINT32 asap_device::execute_max_cycles() const
+{
+ return 2;
+}
+
+
+//-------------------------------------------------
+// execute_input_lines - return the number of
+// input/interrupt lines
+//-------------------------------------------------
+
+UINT32 asap_device::execute_input_lines() const
+{
+ return 1;
+}
+
+
+void asap_device::execute_set_input(int inputnum, int state)
+{
+ m_irq_state = (state != CLEAR_LINE);
+}
+
+
+void asap_device::execute_run()
+{
+ // check for IRQs
+ check_irqs();
+
+ // core execution loop
+ if ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) == 0)
+ {
+ 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();
+
+ m_icount -= 4;
+
+ } while (m_icount > 0);
+ }
+ else
+ {
+ do
+ {
+ // fetch and execute the next instruction
+ fetch_instruction_debug();
+ execute_instruction();
+
+ // fetch and execute the next instruction
+ fetch_instruction_debug();
+ execute_instruction();
+
+ // fetch and execute the next instruction
+ fetch_instruction_debug();
+ execute_instruction();
+
+ // fetch and execute the next instruction
+ fetch_instruction_debug();
+ execute_instruction();
+
+ m_icount -= 4;
+
+ } while (m_icount > 0);
+ }
+}
+
+
+
+//**************************************************************************
+// OPCODE IMPLEMENTATIONS
+//**************************************************************************
+
+void asap_device::noop()
+{
+}
+
+/**************************** TRAP 0 ******************************/
+
+void asap_device::trap0()
+{
+ generate_exception(EXCEPTION_TRAP0);
+}
+
+/**************************** Bcc ******************************/
+
+void asap_device::bsp()
+{
+ if ((INT32)m_znflag > 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bmz()
+{
+ if ((INT32)m_znflag <= 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bgt()
+{
+ if (m_znflag != 0 && (INT32)(m_znflag ^ m_vflag) >= 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::ble()
+{
+ if (m_znflag == 0 || (INT32)(m_znflag ^ m_vflag) < 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bge()
+{
+ if ((INT32)(m_znflag ^ m_vflag) >= 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::blt()
+{
+ if ((INT32)(m_znflag ^ m_vflag) < 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bhi()
+{
+ if (m_znflag != 0 && m_cflag)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bls()
+{
+ if (m_znflag == 0 || !m_cflag)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bcc()
+{
+ if (!m_cflag)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bcs()
+{
+ if (m_cflag)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bpl()
+{
+ if ((INT32)m_znflag >= 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bmi()
+{
+ if ((INT32)m_znflag < 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bne()
+{
+ if (m_znflag != 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::beq()
+{
+ if (m_znflag == 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bvc()
+{
+ if ((INT32)m_vflag >= 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+void asap_device::bvs()
+{
+ if ((INT32)m_vflag < 0)
+ {
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ }
+}
+
+/**************************** BSR ******************************/
+
+void asap_device::bsr()
+{
+ DSTVAL = m_pc + 4;
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+}
+
+void asap_device::bsr_0()
+{
+ m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+}
+
+/**************************** LEA ******************************/
+
+void asap_device::lea()
+{
+ DSTVAL = SRC1VAL + (SRC2VAL << 2);
+}
+
+void asap_device::lea_c()
+{
+ 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;
+}
+
+void asap_device::lea_c0()
+{
+ 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 ******************************/
+
+void asap_device::leah()
+{
+ DSTVAL = SRC1VAL + (SRC2VAL << 1);
+}
+
+void asap_device::leah_c()
+{
+ 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;
+}
+
+void asap_device::leah_c0()
+{
+ 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 ******************************/
+
+void asap_device::subr()
+{
+ DSTVAL = SRC2VAL - SRC1VAL;
+}
+
+void asap_device::subr_c()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src2 - src1;
+
+ SET_ZNCV_SUB(dst, src2, src1);
+ DSTVAL = dst;
+}
+
+void asap_device::subr_c0()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src2 - src1;
+
+ SET_ZNCV_SUB(dst, src2, src1);
+}
+
+/**************************** XOR ******************************/
+
+void asap_device::xor_()
+{
+ DSTVAL = SRC1VAL ^ SRC2VAL;
+}
+
+void asap_device::xor_c()
+{
+ UINT32 dst = SRC1VAL ^ SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::xor_c0()
+{
+ UINT32 dst = SRC1VAL ^ SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** XOR ******************************/
+
+void asap_device::xorn()
+{
+ DSTVAL = SRC1VAL ^ ~SRC2VAL;
+}
+
+void asap_device::xorn_c()
+{
+ UINT32 dst = SRC1VAL ^ ~SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::xorn_c0()
+{
+ UINT32 dst = SRC1VAL ^ ~SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** ADD ******************************/
+
+void asap_device::add()
+{
+ DSTVAL = SRC1VAL + SRC2VAL;
+}
+
+void asap_device::add_c()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+void asap_device::add_c0()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+}
+
+/**************************** ADD ******************************/
+
+void asap_device::sub()
+{
+ DSTVAL = SRC1VAL - SRC2VAL;
+}
+
+void asap_device::sub_c()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+void asap_device::sub_c0()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+}
+
+/**************************** ADDC ******************************/
+
+void asap_device::addc()
+{
+ DSTVAL = SRC1VAL + SRC2VAL + m_cflag;
+}
+
+void asap_device::addc_c()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2 + m_cflag;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+void asap_device::addc_c0()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 + src2 + m_cflag;
+
+ SET_ZNCV_ADD(dst, src1, src2);
+}
+
+/**************************** SUBC ******************************/
+
+void asap_device::subc()
+{
+ DSTVAL = SRC1VAL - SRC2VAL - 1 + m_cflag;
+}
+
+void asap_device::subc_c()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2 - 1 + m_cflag;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+ DSTVAL = dst;
+}
+
+void asap_device::subc_c0()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL;
+ UINT32 dst = src1 - src2 - 1 + m_cflag;
+
+ SET_ZNCV_SUB(dst, src1, src2);
+}
+
+/**************************** AND ******************************/
+
+void asap_device::and_()
+{
+ DSTVAL = SRC1VAL & SRC2VAL;
+}
+
+void asap_device::and_c()
+{
+ UINT32 dst = SRC1VAL & SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::and_c0()
+{
+ UINT32 dst = SRC1VAL & SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** ANDN ******************************/
+
+void asap_device::andn()
+{
+ DSTVAL = SRC1VAL & ~SRC2VAL;
+}
+
+void asap_device::andn_c()
+{
+ UINT32 dst = SRC1VAL & ~SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::andn_c0()
+{
+ UINT32 dst = SRC1VAL & ~SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** OR ******************************/
+
+void asap_device::or_()
+{
+ DSTVAL = SRC1VAL | SRC2VAL;
+}
+
+void asap_device::or_c()
+{
+ UINT32 dst = SRC1VAL | SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::or_c0()
+{
+ UINT32 dst = SRC1VAL | SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** ORN ******************************/
+
+void asap_device::orn()
+{
+ DSTVAL = SRC1VAL | ~SRC2VAL;
+}
+
+void asap_device::orn_c()
+{
+ UINT32 dst = SRC1VAL | ~SRC2VAL;
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::orn_c0()
+{
+ UINT32 dst = SRC1VAL | ~SRC2VAL;
+ SET_ZN(dst);
+}
+
+/**************************** LD ******************************/
+
+void asap_device::ld()
+{
+ DSTVAL = readlong(SRC1VAL + (SRC2VAL << 2));
+}
+
+void asap_device::ld_0()
+{
+ readlong(SRC1VAL + (SRC2VAL << 2));
+}
+
+void asap_device::ld_c()
+{
+ UINT32 dst = readlong(SRC1VAL + (SRC2VAL << 2));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::ld_c0()
+{
+ UINT32 dst = readlong(SRC1VAL + (SRC2VAL << 2));
+ SET_ZN(dst);
+}
+
+/**************************** LDH ******************************/
+
+void asap_device::ldh()
+{
+ DSTVAL = (INT16)readword(SRC1VAL + (SRC2VAL << 1));
+}
+
+void asap_device::ldh_0()
+{
+ readword(SRC1VAL + (SRC2VAL << 1));
+}
+
+void asap_device::ldh_c()
+{
+ UINT32 dst = (INT16)readword(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::ldh_c0()
+{
+ UINT32 dst = (INT16)readword(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+}
+
+/**************************** LDUH ******************************/
+
+void asap_device::lduh()
+{
+ DSTVAL = readword(SRC1VAL + (SRC2VAL << 1));
+}
+
+void asap_device::lduh_0()
+{
+ readword(SRC1VAL + (SRC2VAL << 1));
+}
+
+void asap_device::lduh_c()
+{
+ UINT32 dst = readword(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::lduh_c0()
+{
+ UINT32 dst = readword(SRC1VAL + (SRC2VAL << 1));
+ SET_ZN(dst);
+}
+
+/**************************** STH ******************************/
+
+void asap_device::sth()
+{
+ writeword(SRC1VAL + (SRC2VAL << 1), DSTVAL);
+}
+
+void asap_device::sth_0()
+{
+ writeword(SRC1VAL + (SRC2VAL << 1), 0);
+}
+
+void asap_device::sth_c()
+{
+ UINT32 dst = (UINT16)DSTVAL;
+ SET_ZN(dst);
+ writeword(SRC1VAL + (SRC2VAL << 1), dst);
+}
+
+void asap_device::sth_c0()
+{
+ SET_ZN(0);
+ writeword(SRC1VAL + (SRC2VAL << 1), 0);
+}
+
+/**************************** ST ******************************/
+
+void asap_device::st()
+{
+ writelong(SRC1VAL + (SRC2VAL << 2), DSTVAL);
+}
+
+void asap_device::st_0()
+{
+ writelong(SRC1VAL + (SRC2VAL << 2), 0);
+}
+
+void asap_device::st_c()
+{
+ UINT32 dst = DSTVAL;
+ SET_ZN(dst);
+ writelong(SRC1VAL + (SRC2VAL << 2), dst);
+}
+
+void asap_device::st_c0()
+{
+ SET_ZN(0);
+ writelong(SRC1VAL + (SRC2VAL << 2), 0);
+}
+
+/**************************** LDB ******************************/
+
+void asap_device::ldb()
+{
+ DSTVAL = (INT8)readbyte(SRC1VAL + SRC2VAL);
+}
+
+void asap_device::ldb_0()
+{
+ readbyte(SRC1VAL + SRC2VAL);
+}
+
+void asap_device::ldb_c()
+{
+ UINT32 dst = (INT8)readbyte(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::ldb_c0()
+{
+ UINT32 dst = (INT8)readbyte(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+}
+
+/**************************** LDUB ******************************/
+
+void asap_device::ldub()
+{
+ DSTVAL = readbyte(SRC1VAL + SRC2VAL);
+}
+
+void asap_device::ldub_0()
+{
+ readbyte(SRC1VAL + SRC2VAL);
+}
+
+void asap_device::ldub_c()
+{
+ UINT32 dst = readbyte(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::ldub_c0()
+{
+ UINT32 dst = readbyte(SRC1VAL + SRC2VAL);
+ SET_ZN(dst);
+}
+
+/**************************** STB ******************************/
+
+void asap_device::stb()
+{
+ writebyte(SRC1VAL + SRC2VAL, DSTVAL);
+}
+
+void asap_device::stb_0()
+{
+ writebyte(SRC1VAL + SRC2VAL, 0);
+}
+
+void asap_device::stb_c()
+{
+ UINT32 dst = (UINT8)DSTVAL;
+ SET_ZN(dst);
+ writebyte(SRC1VAL + SRC2VAL, dst);
+}
+
+void asap_device::stb_c0()
+{
+ SET_ZN(0);
+ writebyte(SRC1VAL + SRC2VAL, 0);
+}
+
+/**************************** ASHR ******************************/
+
+void asap_device::ashr()
+{
+ UINT32 src2 = SRC2VAL;
+ DSTVAL = (src2 < 32) ? ((INT32)SRC1VAL >> src2) : ((INT32)SRC1VAL >> 31);
+}
+
+void asap_device::ashr_c()
+{
+ UINT32 src2 = SRC2VAL;
+ m_cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = (INT32)src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ m_cflag = src1 >> 31;
+ }
+ DSTVAL = dst;
+ }
+ else
+ {
+ UINT32 dst = (INT32)SRC1VAL >> 31;
+ SET_ZN(dst);
+ DSTVAL = dst;
+ }
+}
+
+void asap_device::ashr_c0()
+{
+ UINT32 src2 = SRC2VAL;
+ m_cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = (INT32)src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ m_cflag = src1 >> 31;
+ }
+ }
+ else
+ {
+ UINT32 dst = (INT32)SRC1VAL >> 31;
+ SET_ZN(dst);
+ }
+}
+
+/**************************** LSHR ******************************/
+
+void asap_device::lshr()
+{
+ UINT32 src2 = SRC2VAL;
+ DSTVAL = (src2 < 32) ? (SRC1VAL >> src2) : (SRC1VAL >> 31);
+}
+
+void asap_device::lshr_c()
+{
+ UINT32 src2 = SRC2VAL;
+ m_cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ m_cflag = src1 >> 31;
+ }
+ DSTVAL = dst;
+ }
+ else
+ {
+ UINT32 dst = SRC1VAL >> 31;
+ SET_ZN(dst);
+ DSTVAL = dst;
+ }
+}
+
+void asap_device::lshr_c0()
+{
+ UINT32 src2 = SRC2VAL;
+ m_cflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 >> src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = src1 << (32 - src2);
+ m_cflag = src1 >> 31;
+ }
+ }
+ else
+ {
+ SET_ZN(0);
+ DSTVAL = 0;
+ }
+}
+
+/**************************** ASHL ******************************/
+
+void asap_device::ashl()
+{
+ UINT32 src2 = SRC2VAL;
+ DSTVAL = (src2 < 32) ? (SRC1VAL << src2) : 0;
+}
+
+void asap_device::ashl_c()
+{
+ UINT32 src2 = SRC2VAL;
+ m_cflag = m_vflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 << src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = (INT32)src1 >> (32 - src2);
+ m_cflag = src1 & PS_CFLAG;
+ m_vflag = (src1 != ((INT32)dst >> 31)) << 31;
+ }
+ DSTVAL = dst;
+ }
+ else
+ {
+ SET_ZN(0);
+ DSTVAL = 0;
+ }
+}
+
+void asap_device::ashl_c0()
+{
+ UINT32 src2 = SRC2VAL;
+ m_cflag = m_vflag = 0;
+ if (src2 < 32)
+ {
+ UINT32 src1 = SRC1VAL;
+ UINT32 dst = src1 << src2;
+ SET_ZN(dst);
+ if (src2 != 0)
+ {
+ src1 = (INT32)src1 >> (32 - src2);
+ m_cflag = src1 & PS_CFLAG;
+ m_vflag = (src1 != ((INT32)dst >> 31)) << 31;
+ }
+ }
+ else
+ SET_ZN(0);
+}
+
+/**************************** ROTL ******************************/
+
+void asap_device::rotl()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL & 31;
+ DSTVAL = (src1 << src2) | (src1 >> (32 - src2));
+}
+
+void asap_device::rotl_c()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL & 31;
+ UINT32 dst = (src1 << src2) | (src1 >> (32 - src2));
+ SET_ZN(dst);
+ DSTVAL = dst;
+}
+
+void asap_device::rotl_c0()
+{
+ UINT32 src1 = SRC1VAL;
+ UINT32 src2 = SRC2VAL & 31;
+ UINT32 dst = (src1 << src2) | (src1 >> (32 - src2));
+ SET_ZN(dst);
+}
+
+/**************************** GETPS ******************************/
+
+void asap_device::getps()
+{
+ DSTVAL = GET_FLAGS();
+}
+
+/**************************** PUTPS ******************************/
+
+void asap_device::putps()
+{
+ UINT32 src2 = SRC2VAL & 0x3f;
+ SET_FLAGS(src2);
+ check_irqs();
+}
+
+/**************************** JSR ******************************/
+
+void asap_device::jsr()
+{
+ DSTVAL = m_pc + 4;
+ m_nextpc = SRC1VAL + (SRC2VAL << 2);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+}
+
+void asap_device::jsr_0()
+{
+ m_nextpc = SRC1VAL + (SRC2VAL << 2);
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+}
+
+void asap_device::jsr_c()
+{
+ DSTVAL = m_pc + 4;
+ m_nextpc = SRC1VAL + (SRC2VAL << 2);
+ m_iflag = m_pflag;
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ check_irqs();
+}
+
+void asap_device::jsr_c0()
+{
+ m_nextpc = SRC1VAL + (SRC2VAL << 2);
+ m_iflag = m_pflag;
+
+ fetch_instruction();
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
+
+ execute_instruction();
+ m_icount--;
+ check_irqs();
+}
+
+/**************************** TRAP F ******************************/
+
+void asap_device::trapf()
+{
+ generate_exception(EXCEPTION_TRAPF);
+}