src/emu/cpu/asap/asap.c
| r9060 | r9061 | |
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | 3 | asap.c |
| 4 | |
| 4 | 5 | Core implementation for the portable ASAP emulator. |
| 5 | 6 | ASAP = Atari Simplified Architecture Processor |
| 6 | 7 | |
| 7 | | Written by Aaron Giles |
| 8 | 8 | Special thanks to Mike Albaugh for clarification on a couple of fine points. |
| 9 | 9 | |
| 10 | **************************************************************************** |
| 11 | |
| 12 | Copyright Aaron Giles |
| 13 | All rights reserved. |
| 14 | |
| 15 | Redistribution and use in source and binary forms, with or without |
| 16 | modification, are permitted provided that the following conditions are |
| 17 | met: |
| 18 | |
| 19 | * Redistributions of source code must retain the above copyright |
| 20 | notice, this list of conditions and the following disclaimer. |
| 21 | * Redistributions in binary form must reproduce the above copyright |
| 22 | notice, this list of conditions and the following disclaimer in |
| 23 | the documentation and/or other materials provided with the |
| 24 | distribution. |
| 25 | * Neither the name 'MAME' nor the names of its contributors may be |
| 26 | used to endorse or promote products derived from this software |
| 27 | without specific prior written permission. |
| 28 | |
| 29 | THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR |
| 30 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 31 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 32 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, |
| 33 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 34 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 35 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 36 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 37 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 38 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 39 | POSSIBILITY OF SUCH DAMAGE. |
| 40 | |
| 10 | 41 | ***************************************************************************/ |
| 11 | 42 | |
| 12 | 43 | #include "emu.h" |
| r9060 | r9061 | |
| 14 | 45 | #include "asap.h" |
| 15 | 46 | |
| 16 | 47 | |
| 17 | | /*************************************************************************** |
| 18 | | CONSTANTS |
| 19 | | ***************************************************************************/ |
| 48 | //************************************************************************** |
| 49 | // CONSTANTS |
| 50 | //************************************************************************** |
| 20 | 51 | |
| 21 | | #define PS_CFLAG 0x00000001 |
| 22 | | #define PS_VFLAG 0x00000002 |
| 23 | | #define PS_ZFLAG 0x00000004 |
| 24 | | #define PS_NFLAG 0x00000008 |
| 25 | | #define PS_IFLAG 0x00000010 |
| 26 | | #define PS_PFLAG 0x00000020 |
| 52 | const UINT32 PS_CFLAG = 0x00000001; |
| 53 | const UINT32 PS_VFLAG = 0x00000002; |
| 54 | const UINT32 PS_ZFLAG = 0x00000004; |
| 55 | const UINT32 PS_NFLAG = 0x00000008; |
| 56 | const UINT32 PS_IFLAG = 0x00000010; |
| 57 | const UINT32 PS_PFLAG = 0x00000020; |
| 27 | 58 | |
| 28 | | #define EXCEPTION_RESET 0 |
| 29 | | #define EXCEPTION_TRAP0 1 |
| 30 | | #define EXCEPTION_TRAPF 2 |
| 31 | | #define EXCEPTION_INTERRUPT 3 |
| 59 | const int EXCEPTION_RESET = 0; |
| 60 | const int EXCEPTION_TRAP0 = 1; |
| 61 | const int EXCEPTION_TRAPF = 2; |
| 62 | const int EXCEPTION_INTERRUPT = 3; |
| 32 | 63 | |
| 64 | const int REGBASE = 0xffe0; |
| 33 | 65 | |
| 34 | | #define REGBASE 0xffe0 |
| 35 | 66 | |
| 36 | 67 | |
| 37 | | #define SET_C_ADD(A,a,b) ((A)->cflag = (UINT32)(b) > (UINT32)(~(a))) |
| 38 | | #define SET_C_SUB(A,a,b) ((A)->cflag = (UINT32)(b) <= (UINT32)(a)) |
| 39 | | #define SET_V_ADD(A,r,a,b) ((A)->vflag = ~((a) ^ (b)) & ((a) ^ (r))) |
| 40 | | #define SET_V_SUB(A,r,a,b) ((A)->vflag = ((a) ^ (b)) & ((a) ^ (r))) |
| 41 | | #define SET_ZN(A,r) ((A)->znflag = (r)) |
| 42 | | #define SET_ZNCV_ADD(A,r,a,b) SET_ZN(A,r); SET_C_ADD(A,a,b); SET_V_ADD(A,r,a,b) |
| 43 | | #define SET_ZNCV_SUB(A,r,a,b) SET_ZN(A,r); SET_C_SUB(A,a,b); SET_V_SUB(A,r,a,b) |
| 68 | //************************************************************************** |
| 69 | // MACROS |
| 70 | //************************************************************************** |
| 44 | 71 | |
| 45 | | #define SET_VFLAG(A,val) ((A)->vflag = (val) << 31) |
| 46 | | #define SET_CFLAG(A,val) ((A)->cflag = (val)) |
| 72 | #define SET_C_ADD(a,b) (m_cflag = (UINT32)(b) > (UINT32)(~(a))) |
| 73 | #define SET_C_SUB(a,b) (m_cflag = (UINT32)(b) <= (UINT32)(a)) |
| 74 | #define SET_V_ADD(r,a,b) (m_vflag = ~((a) ^ (b)) & ((a) ^ (r))) |
| 75 | #define SET_V_SUB(r,a,b) (m_vflag = ((a) ^ (b)) & ((a) ^ (r))) |
| 76 | #define SET_ZN(r) (m_znflag = (r)) |
| 77 | #define SET_ZNCV_ADD(r,a,b) SET_ZN(r); SET_C_ADD(a,b); SET_V_ADD(r,a,b) |
| 78 | #define SET_ZNCV_SUB(r,a,b) SET_ZN(r); SET_C_SUB(a,b); SET_V_SUB(r,a,b) |
| 47 | 79 | |
| 48 | | #define GET_FLAGS(A) ((A)->cflag | \ |
| 49 | | (((A)->vflag >> 30) & PS_VFLAG) | \ |
| 50 | | (((A)->znflag == 0) << 2) | \ |
| 51 | | (((A)->znflag >> 28) & PS_NFLAG) | \ |
| 52 | | ((A)->iflag << 4) | \ |
| 53 | | ((A)->pflag << 5)) |
| 80 | #define SET_VFLAG(val) (m_vflag = (val) << 31) |
| 81 | #define SET_CFLAG(val) (m_cflag = (val)) |
| 54 | 82 | |
| 55 | | #define SET_FLAGS(A,v) do { \ |
| 56 | | (A)->cflag = (v) & PS_CFLAG; \ |
| 57 | | (A)->vflag = ((v) & PS_VFLAG) << 30; \ |
| 58 | | (A)->znflag = ((v) & PS_ZFLAG) ? 0 : ((v) & PS_NFLAG) ? -1 : 1; \ |
| 59 | | (A)->iflag = ((v) & PS_IFLAG) >> 4; \ |
| 60 | | (A)->pflag = ((v) & PS_PFLAG) >> 5; \ |
| 83 | #define GET_FLAGS() (m_cflag | \ |
| 84 | ((m_vflag >> 30) & PS_VFLAG) | \ |
| 85 | ((m_znflag == 0) << 2) | \ |
| 86 | ((m_znflag >> 28) & PS_NFLAG) | \ |
| 87 | (m_iflag << 4) | \ |
| 88 | (m_pflag << 5)) |
| 89 | |
| 90 | #define SET_FLAGS(v) do { \ |
| 91 | m_cflag = (v) & PS_CFLAG; \ |
| 92 | m_vflag = ((v) & PS_VFLAG) << 30; \ |
| 93 | m_znflag = ((v) & PS_ZFLAG) ? 0 : ((v) & PS_NFLAG) ? -1 : 1; \ |
| 94 | m_iflag = ((v) & PS_IFLAG) >> 4; \ |
| 95 | m_pflag = ((v) & PS_PFLAG) >> 5; \ |
| 61 | 96 | } while (0); |
| 62 | 97 | |
| 98 | #define OPCODE (m_op >> 27) |
| 99 | #define DSTREG ((m_op >> 22) & 31) |
| 100 | #define DSTVAL m_src2val[REGBASE + DSTREG] |
| 101 | #define SRC1REG ((m_op >> 16) & 31) |
| 102 | #define SRC1VAL m_src2val[REGBASE + SRC1REG] |
| 103 | #define SRC2VAL m_src2val[m_op & 0xffff] |
| 63 | 104 | |
| 64 | | /*************************************************************************** |
| 65 | | STRUCTURES & TYPEDEFS |
| 66 | | ***************************************************************************/ |
| 67 | 105 | |
| 68 | | /* ASAP Registers */ |
| 69 | | typedef struct _asap_state asap_state; |
| 70 | | struct _asap_state |
| 71 | | { |
| 72 | | /* core registers */ |
| 73 | | UINT32 pc; |
| 74 | 106 | |
| 75 | | /* expanded flags */ |
| 76 | | UINT32 pflag; |
| 77 | | UINT32 iflag; |
| 78 | | UINT32 cflag; |
| 79 | | UINT32 vflag; |
| 80 | | UINT32 znflag; |
| 107 | //************************************************************************** |
| 108 | // STATIC OPCODE TABLES |
| 109 | //************************************************************************** |
| 81 | 110 | |
| 82 | | /* internal stuff */ |
| 83 | | PAIR op; |
| 84 | | UINT32 ppc; |
| 85 | | UINT32 nextpc; |
| 86 | | UINT8 irq_state; |
| 87 | | int icount; |
| 88 | | device_irq_callback irq_callback; |
| 89 | | address_space *program; |
| 90 | | direct_read_data *direct; |
| 91 | | legacy_cpu_device *device; |
| 111 | const asap_device::ophandler asap_device::s_opcodetable[32][4] = |
| 112 | { |
| 113 | { &asap_device::trap0, &asap_device::trap0, &asap_device::trap0, &asap_device::trap0 }, |
| 114 | { &asap_device::noop, &asap_device::noop, &asap_device::noop, &asap_device::noop }, |
| 115 | { &asap_device::bsr, &asap_device::bsr_0, &asap_device::bsr, &asap_device::bsr_0 }, |
| 116 | { &asap_device::lea, &asap_device::noop, &asap_device::lea_c, &asap_device::lea_c0 }, |
| 117 | { &asap_device::leah, &asap_device::noop, &asap_device::leah_c, &asap_device::leah_c0 }, |
| 118 | { &asap_device::subr, &asap_device::noop, &asap_device::subr_c, &asap_device::subr_c0 }, |
| 119 | { &asap_device::xor_, &asap_device::noop, &asap_device::xor_c, &asap_device::xor_c0 }, |
| 120 | { &asap_device::xorn, &asap_device::noop, &asap_device::xorn_c, &asap_device::xorn_c0 }, |
| 121 | { &asap_device::add, &asap_device::noop, &asap_device::add_c, &asap_device::add_c0 }, |
| 122 | { &asap_device::sub, &asap_device::noop, &asap_device::sub_c, &asap_device::sub_c0 }, |
| 123 | { &asap_device::addc, &asap_device::noop, &asap_device::addc_c, &asap_device::addc_c0 }, |
| 124 | { &asap_device::subc, &asap_device::noop, &asap_device::subc_c, &asap_device::subc_c0 }, |
| 125 | { &asap_device::and_, &asap_device::noop, &asap_device::and_c, &asap_device::and_c0 }, |
| 126 | { &asap_device::andn, &asap_device::noop, &asap_device::andn_c, &asap_device::andn_c0 }, |
| 127 | { &asap_device::or_, &asap_device::noop, &asap_device::or_c, &asap_device::or_c0 }, |
| 128 | { &asap_device::orn, &asap_device::noop, &asap_device::orn_c, &asap_device::orn_c0 }, |
| 129 | { &asap_device::ld, &asap_device::ld_0, &asap_device::ld_c, &asap_device::ld_c0 }, |
| 130 | { &asap_device::ldh, &asap_device::ldh_0, &asap_device::ldh_c, &asap_device::ldh_c0 }, |
| 131 | { &asap_device::lduh, &asap_device::lduh_0, &asap_device::lduh_c, &asap_device::lduh_c0 }, |
| 132 | { &asap_device::sth, &asap_device::sth_0, &asap_device::sth_c, &asap_device::sth_c0 }, |
| 133 | { &asap_device::st, &asap_device::st_0, &asap_device::st_c, &asap_device::st_c0 }, |
| 134 | { &asap_device::ldb, &asap_device::ldb_0, &asap_device::ldb_c, &asap_device::ldb_c0 }, |
| 135 | { &asap_device::ldub, &asap_device::ldub_0, &asap_device::ldub_c, &asap_device::ldub_c0 }, |
| 136 | { &asap_device::stb, &asap_device::stb_0, &asap_device::stb_c, &asap_device::stb_c0 }, |
| 137 | { &asap_device::ashr, &asap_device::noop, &asap_device::ashr_c, &asap_device::ashr_c0 }, |
| 138 | { &asap_device::lshr, &asap_device::noop, &asap_device::lshr_c, &asap_device::lshr_c0 }, |
| 139 | { &asap_device::ashl, &asap_device::noop, &asap_device::ashl_c, &asap_device::ashl_c0 }, |
| 140 | { &asap_device::rotl, &asap_device::noop, &asap_device::rotl_c, &asap_device::rotl_c0 }, |
| 141 | { &asap_device::getps, &asap_device::noop, &asap_device::getps, &asap_device::noop }, |
| 142 | { &asap_device::putps, &asap_device::putps, &asap_device::putps, &asap_device::putps }, |
| 143 | { &asap_device::jsr, &asap_device::jsr_0, &asap_device::jsr_c, &asap_device::jsr_c0 }, |
| 144 | { &asap_device::trapf, &asap_device::trapf, &asap_device::trapf, &asap_device::trapf } |
| 145 | }; |
| 92 | 146 | |
| 93 | | /* src2val table, registers are at the end */ |
| 94 | | UINT32 src2val[65536]; |
| 147 | const asap_device::ophandler asap_device::s_conditiontable[16] = |
| 148 | { |
| 149 | &asap_device::bsp, &asap_device::bmz, &asap_device::bgt, &asap_device::ble, |
| 150 | &asap_device::bge, &asap_device::blt, &asap_device::bhi, &asap_device::bls, |
| 151 | &asap_device::bcc, &asap_device::bcs, &asap_device::bpl, &asap_device::bmi, |
| 152 | &asap_device::bne, &asap_device::beq, &asap_device::bvc, &asap_device::bvs |
| 95 | 153 | }; |
| 96 | 154 | |
| 97 | 155 | |
| 98 | 156 | |
| 99 | | /*************************************************************************** |
| 100 | | PRIVATE GLOBAL VARIABLES |
| 101 | | ***************************************************************************/ |
| 157 | //************************************************************************** |
| 158 | // ASAP DEVICE CONFIG |
| 159 | //************************************************************************** |
| 102 | 160 | |
| 103 | | static void (**opcode)(asap_state *); |
| 161 | //------------------------------------------------- |
| 162 | // asap_device_config - constructor |
| 163 | //------------------------------------------------- |
| 104 | 164 | |
| 165 | asap_device_config::asap_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 166 | : cpu_device_config(mconfig, static_alloc_device_config, "ASAP", tag, owner, clock), |
| 167 | m_program_config("program", ENDIANNESS_LITTLE, 32, 32) |
| 168 | { |
| 169 | } |
| 105 | 170 | |
| 106 | 171 | |
| 107 | | /*************************************************************************** |
| 108 | | OPCODE TABLE |
| 109 | | ***************************************************************************/ |
| 172 | //------------------------------------------------- |
| 173 | // static_alloc_device_config - allocate a new |
| 174 | // configuration object |
| 175 | //------------------------------------------------- |
| 110 | 176 | |
| 111 | | static void noop(asap_state *); |
| 112 | | static void trap0(asap_state *); |
| 113 | | static void bsp(asap_state *); |
| 114 | | static void bmz(asap_state *); |
| 115 | | static void bgt(asap_state *); |
| 116 | | static void ble(asap_state *); |
| 117 | | static void bge(asap_state *); |
| 118 | | static void blt(asap_state *); |
| 119 | | static void bhi(asap_state *); |
| 120 | | static void bls(asap_state *); |
| 121 | | static void bcc(asap_state *); |
| 122 | | static void bcs(asap_state *); |
| 123 | | static void bpl(asap_state *); |
| 124 | | static void bmi(asap_state *); |
| 125 | | static void bne(asap_state *); |
| 126 | | static void beq(asap_state *); |
| 127 | | static void bvc(asap_state *); |
| 128 | | static void bvs(asap_state *); |
| 129 | | static void bsr(asap_state *); |
| 130 | | static void bsr_0(asap_state *); |
| 131 | | static void lea(asap_state *); |
| 132 | | static void lea_c(asap_state *); |
| 133 | | static void lea_c0(asap_state *); |
| 134 | | static void leah(asap_state *); |
| 135 | | static void leah_c(asap_state *); |
| 136 | | static void leah_c0(asap_state *); |
| 137 | | static void subr(asap_state *); |
| 138 | | static void subr_c(asap_state *); |
| 139 | | static void subr_c0(asap_state *); |
| 140 | | static void xor_(asap_state *); |
| 141 | | static void xor_c(asap_state *); |
| 142 | | static void xor_c0(asap_state *); |
| 143 | | static void xorn(asap_state *); |
| 144 | | static void xorn_c(asap_state *); |
| 145 | | static void xorn_c0(asap_state *); |
| 146 | | static void add(asap_state *); |
| 147 | | static void add_c(asap_state *); |
| 148 | | static void add_c0(asap_state *); |
| 149 | | static void sub(asap_state *); |
| 150 | | static void sub_c(asap_state *); |
| 151 | | static void sub_c0(asap_state *); |
| 152 | | static void addc(asap_state *); |
| 153 | | static void addc_c(asap_state *); |
| 154 | | static void addc_c0(asap_state *); |
| 155 | | static void subc(asap_state *); |
| 156 | | static void subc_c(asap_state *); |
| 157 | | static void subc_c0(asap_state *); |
| 158 | | static void and_(asap_state *); |
| 159 | | static void and_c(asap_state *); |
| 160 | | static void and_c0(asap_state *); |
| 161 | | static void andn(asap_state *); |
| 162 | | static void andn_c(asap_state *); |
| 163 | | static void andn_c0(asap_state *); |
| 164 | | static void or_(asap_state *); |
| 165 | | static void or_c(asap_state *); |
| 166 | | static void or_c0(asap_state *); |
| 167 | | static void orn(asap_state *); |
| 168 | | static void orn_c(asap_state *); |
| 169 | | static void orn_c0(asap_state *); |
| 170 | | static void ld(asap_state *); |
| 171 | | static void ld_0(asap_state *); |
| 172 | | static void ld_c(asap_state *); |
| 173 | | static void ld_c0(asap_state *); |
| 174 | | static void ldh(asap_state *); |
| 175 | | static void ldh_0(asap_state *); |
| 176 | | static void ldh_c(asap_state *); |
| 177 | | static void ldh_c0(asap_state *); |
| 178 | | static void lduh(asap_state *); |
| 179 | | static void lduh_0(asap_state *); |
| 180 | | static void lduh_c(asap_state *); |
| 181 | | static void lduh_c0(asap_state *); |
| 182 | | static void sth(asap_state *); |
| 183 | | static void sth_0(asap_state *); |
| 184 | | static void sth_c(asap_state *); |
| 185 | | static void sth_c0(asap_state *); |
| 186 | | static void st(asap_state *); |
| 187 | | static void st_0(asap_state *); |
| 188 | | static void st_c(asap_state *); |
| 189 | | static void st_c0(asap_state *); |
| 190 | | static void ldb(asap_state *); |
| 191 | | static void ldb_0(asap_state *); |
| 192 | | static void ldb_c(asap_state *); |
| 193 | | static void ldb_c0(asap_state *); |
| 194 | | static void ldub(asap_state *); |
| 195 | | static void ldub_0(asap_state *); |
| 196 | | static void ldub_c(asap_state *); |
| 197 | | static void ldub_c0(asap_state *); |
| 198 | | static void stb(asap_state *); |
| 199 | | static void stb_0(asap_state *); |
| 200 | | static void stb_c(asap_state *); |
| 201 | | static void stb_c0(asap_state *); |
| 202 | | static void ashr(asap_state *); |
| 203 | | static void ashr_c(asap_state *); |
| 204 | | static void ashr_c0(asap_state *); |
| 205 | | static void lshr(asap_state *); |
| 206 | | static void lshr_c(asap_state *); |
| 207 | | static void lshr_c0(asap_state *); |
| 208 | | static void ashl(asap_state *); |
| 209 | | static void ashl_c(asap_state *); |
| 210 | | static void ashl_c0(asap_state *); |
| 211 | | static void rotl(asap_state *); |
| 212 | | static void rotl_c(asap_state *); |
| 213 | | static void rotl_c0(asap_state *); |
| 214 | | static void getps(asap_state *); |
| 215 | | static void putps(asap_state *); |
| 216 | | static void jsr(asap_state *); |
| 217 | | static void jsr_0(asap_state *); |
| 218 | | static void jsr_c(asap_state *); |
| 219 | | static void jsr_c0(asap_state *); |
| 220 | | static void trapf(asap_state *); |
| 177 | device_config *asap_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 178 | { |
| 179 | return global_alloc(asap_device_config(mconfig, tag, owner, clock)); |
| 180 | } |
| 221 | 181 | |
| 222 | | typedef void (*asap_ophandler)(asap_state *); |
| 223 | 182 | |
| 224 | | static const asap_ophandler opcodetable[32][4] = |
| 183 | //------------------------------------------------- |
| 184 | // alloc_device - allocate a new device object |
| 185 | //------------------------------------------------- |
| 186 | |
| 187 | device_t *asap_device_config::alloc_device(running_machine &machine) const |
| 225 | 188 | { |
| 226 | | { trap0, trap0, trap0, trap0 }, |
| 227 | | { NULL, NULL, NULL, NULL }, |
| 228 | | { bsr, bsr_0, bsr, bsr_0 }, |
| 229 | | { lea, noop, lea_c, lea_c0 }, |
| 230 | | { leah, noop, leah_c, leah_c0 }, |
| 231 | | { subr, noop, subr_c, subr_c0 }, |
| 232 | | { xor_, noop, xor_c, xor_c0 }, |
| 233 | | { xorn, noop, xorn_c, xorn_c0 }, |
| 234 | | { add, noop, add_c, add_c0 }, |
| 235 | | { sub, noop, sub_c, sub_c0 }, |
| 236 | | { addc, noop, addc_c, addc_c0 }, |
| 237 | | { subc, noop, subc_c, subc_c0 }, |
| 238 | | { and_, noop, and_c, and_c0 }, |
| 239 | | { andn, noop, andn_c, andn_c0 }, |
| 240 | | { or_, noop, or_c, or_c0 }, |
| 241 | | { orn, noop, orn_c, orn_c0 }, |
| 242 | | { ld, ld_0, ld_c, ld_c0 }, |
| 243 | | { ldh, ldh_0, ldh_c, ldh_c0 }, |
| 244 | | { lduh, lduh_0, lduh_c, lduh_c0 }, |
| 245 | | { sth, sth_0, sth_c, sth_c0 }, |
| 246 | | { st, st_0, st_c, st_c0 }, |
| 247 | | { ldb, ldb_0, ldb_c, ldb_c0 }, |
| 248 | | { ldub, ldub_0, ldub_c, ldub_c0 }, |
| 249 | | { stb, stb_0, stb_c, stb_c0 }, |
| 250 | | { ashr, noop, ashr_c, ashr_c0 }, |
| 251 | | { lshr, noop, lshr_c, lshr_c0 }, |
| 252 | | { ashl, noop, ashl_c, ashl_c0 }, |
| 253 | | { rotl, noop, rotl_c, rotl_c0 }, |
| 254 | | { getps, noop, getps, noop }, |
| 255 | | { putps, putps, putps, putps }, |
| 256 | | { jsr, jsr_0, jsr_c, jsr_c0 }, |
| 257 | | { trapf, trapf, trapf, trapf } |
| 258 | | }; |
| 189 | return auto_alloc(&machine, asap_device(machine, *this)); |
| 190 | } |
| 259 | 191 | |
| 260 | | static void (*const conditiontable[16])(asap_state *) = |
| 192 | //------------------------------------------------- |
| 193 | // execute_min_cycles - return minimum number of |
| 194 | // cycles it takes for one instruction to execute |
| 195 | //------------------------------------------------- |
| 196 | |
| 197 | UINT32 asap_device_config::execute_min_cycles() const |
| 261 | 198 | { |
| 262 | | bsp, bmz, bgt, ble, bge, blt, bhi, bls, |
| 263 | | bcc, bcs, bpl, bmi, bne, beq, bvc, bvs |
| 264 | | }; |
| 199 | return 1; |
| 200 | } |
| 265 | 201 | |
| 266 | 202 | |
| 203 | //------------------------------------------------- |
| 204 | // execute_max_cycles - return maximum number of |
| 205 | // cycles it takes for one instruction to execute |
| 206 | //------------------------------------------------- |
| 267 | 207 | |
| 268 | | /*************************************************************************** |
| 269 | | STATE ACCESSORS |
| 270 | | ***************************************************************************/ |
| 208 | UINT32 asap_device_config::execute_max_cycles() const |
| 209 | { |
| 210 | return 2; |
| 211 | } |
| 271 | 212 | |
| 272 | | INLINE asap_state *get_safe_token(running_device *device) |
| 213 | |
| 214 | //------------------------------------------------- |
| 215 | // execute_input_lines - return the number of |
| 216 | // input/interrupt lines |
| 217 | //------------------------------------------------- |
| 218 | |
| 219 | UINT32 asap_device_config::execute_input_lines() const |
| 273 | 220 | { |
| 274 | | assert(device != NULL); |
| 275 | | assert(device->type() == ASAP); |
| 276 | | return (asap_state *)downcast<legacy_cpu_device *>(device)->token(); |
| 221 | return 1; |
| 277 | 222 | } |
| 278 | 223 | |
| 279 | 224 | |
| 225 | //------------------------------------------------- |
| 226 | // memory_space_config - return the configuration |
| 227 | // of the specified address space, or NULL if |
| 228 | // the space doesn't exist |
| 229 | //------------------------------------------------- |
| 280 | 230 | |
| 281 | | /*************************************************************************** |
| 282 | | MEMORY ACCESSORS |
| 283 | | ***************************************************************************/ |
| 231 | const address_space_config *asap_device_config::memory_space_config(int spacenum) const |
| 232 | { |
| 233 | return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; |
| 234 | } |
| 284 | 235 | |
| 285 | | #define ROPCODE(A,pc) (A)->direct->read_decrypted_dword(pc) |
| 286 | 236 | |
| 237 | //------------------------------------------------- |
| 238 | // disasm_min_opcode_bytes - return the length |
| 239 | // of the shortest instruction, in bytes |
| 240 | //------------------------------------------------- |
| 287 | 241 | |
| 288 | | INLINE UINT8 READBYTE(asap_state *asap, offs_t address) |
| 242 | UINT32 asap_device_config::disasm_min_opcode_bytes() const |
| 289 | 243 | { |
| 290 | | /* no alignment issues with bytes */ |
| 291 | | return asap->program->read_byte(address); |
| 244 | return 4; |
| 292 | 245 | } |
| 293 | 246 | |
| 294 | | INLINE UINT16 READWORD(asap_state *asap, offs_t address) |
| 247 | |
| 248 | //------------------------------------------------- |
| 249 | // disasm_max_opcode_bytes - return the length |
| 250 | // of the longest instruction, in bytes |
| 251 | //------------------------------------------------- |
| 252 | |
| 253 | UINT32 asap_device_config::disasm_max_opcode_bytes() const |
| 295 | 254 | { |
| 296 | | /* aligned reads are easy */ |
| 297 | | if (!(address & 1)) |
| 298 | | return asap->program->read_word(address); |
| 255 | return 12; |
| 256 | } |
| 299 | 257 | |
| 300 | | /* misaligned reads are tricky */ |
| 301 | | return asap->program->read_dword(address & ~3) >> (address & 3); |
| 258 | |
| 259 | |
| 260 | //************************************************************************** |
| 261 | // DEVICE INTERFACE |
| 262 | //************************************************************************** |
| 263 | |
| 264 | //------------------------------------------------- |
| 265 | // asap_device - constructor |
| 266 | //------------------------------------------------- |
| 267 | |
| 268 | asap_device::asap_device(running_machine &_machine, const asap_device_config &config) |
| 269 | : cpu_device(_machine, config), |
| 270 | m_pc(0), |
| 271 | m_pflag(0), |
| 272 | m_iflag(0), |
| 273 | m_cflag(0), |
| 274 | m_vflag(0), |
| 275 | m_znflag(0), |
| 276 | m_flagsio(0), |
| 277 | m_op(0), |
| 278 | m_ppc(0), |
| 279 | m_nextpc(0), |
| 280 | m_irq_state(0), |
| 281 | m_icount(0), |
| 282 | m_program(NULL), |
| 283 | m_direct(NULL) |
| 284 | { |
| 285 | // initialize the src2val table to contain immediates for low values |
| 286 | for (int i = 0; i < REGBASE; i++) |
| 287 | m_src2val[i] = i; |
| 288 | |
| 289 | // build the opcode table |
| 290 | for (int op = 0; op < 32; op++) |
| 291 | for (int dst = 0; dst < 32; dst++) |
| 292 | for (int cond = 0; cond < 2; cond++) |
| 293 | if (op == 1) |
| 294 | m_opcode[(op << 6) + (dst << 1) + cond] = s_conditiontable[dst & 15]; |
| 295 | else if (cond && dst == 0) |
| 296 | m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][3]; |
| 297 | else if (cond) |
| 298 | m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][2]; |
| 299 | else if (dst == 0) |
| 300 | m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][1]; |
| 301 | else |
| 302 | m_opcode[(op << 6) + (dst << 1) + cond] = s_opcodetable[op][0]; |
| 302 | 303 | } |
| 303 | 304 | |
| 304 | | INLINE UINT32 READLONG(asap_state *asap, offs_t address) |
| 305 | |
| 306 | //------------------------------------------------- |
| 307 | // device_start - start up the device |
| 308 | //------------------------------------------------- |
| 309 | |
| 310 | void asap_device::device_start() |
| 305 | 311 | { |
| 306 | | /* aligned reads are easy */ |
| 307 | | if (!(address & 3)) |
| 308 | | return asap->program->read_dword(address); |
| 312 | // get our address spaces |
| 313 | m_program = space(AS_PROGRAM); |
| 314 | m_direct = &m_program->direct(); |
| 309 | 315 | |
| 310 | | /* misaligned reads are tricky */ |
| 311 | | return asap->program->read_dword(address & ~3) >> (address & 3); |
| 316 | // register our state for the debugger |
| 317 | astring tempstr; |
| 318 | state_add(STATE_GENPC, "GENPC", m_pc).noshow(); |
| 319 | state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow(); |
| 320 | state_add(STATE_GENSP, "GENSP", m_src2val[REGBASE + 31]).noshow(); |
| 321 | state_add(STATE_GENFLAGS, "GENFLAGS", m_flagsio).callimport().callexport().formatstr("%6s").noshow(); |
| 322 | state_add(ASAP_PC, "PC", m_pc); |
| 323 | state_add(ASAP_PS, "PS", m_flagsio).callimport().callexport(); |
| 324 | for (int regnum = 0; regnum < 32; regnum++) |
| 325 | state_add(ASAP_R0 + regnum, tempstr.format("R%d", regnum), m_src2val[REGBASE + regnum]); |
| 326 | |
| 327 | // register our state for saving |
| 328 | state_save_register_device_item(this, 0, m_pc); |
| 329 | state_save_register_device_item(this, 0, m_pflag); |
| 330 | state_save_register_device_item(this, 0, m_iflag); |
| 331 | state_save_register_device_item(this, 0, m_cflag); |
| 332 | state_save_register_device_item(this, 0, m_vflag); |
| 333 | state_save_register_device_item(this, 0, m_znflag); |
| 334 | state_save_register_device_item(this, 0, m_op); |
| 335 | state_save_register_device_item(this, 0, m_ppc); |
| 336 | state_save_register_device_item(this, 0, m_nextpc); |
| 337 | state_save_register_device_item(this, 0, m_irq_state); |
| 338 | |
| 339 | // set our instruction counter |
| 340 | m_icountptr = &m_icount; |
| 312 | 341 | } |
| 313 | 342 | |
| 314 | | INLINE void WRITEBYTE(asap_state *asap, offs_t address, UINT8 data) |
| 343 | |
| 344 | //------------------------------------------------- |
| 345 | // device_reset - reset the device |
| 346 | //------------------------------------------------- |
| 347 | |
| 348 | void asap_device::device_reset() |
| 315 | 349 | { |
| 316 | | /* no alignment issues with bytes */ |
| 317 | | asap->program->write_byte(address, data); |
| 350 | // initialize the state |
| 351 | m_src2val[REGBASE + 0] = 0; |
| 352 | m_pc = 0; |
| 353 | m_iflag = 0; |
| 354 | |
| 355 | m_ppc = 0; |
| 356 | m_nextpc = ~0; |
| 357 | m_irq_state = 0; |
| 318 | 358 | } |
| 319 | 359 | |
| 320 | | INLINE void WRITEWORD(asap_state *asap, offs_t address, UINT16 data) |
| 360 | |
| 361 | //------------------------------------------------- |
| 362 | // state_import - import state into the device, |
| 363 | // after it has been set |
| 364 | //------------------------------------------------- |
| 365 | |
| 366 | void asap_device::state_import(const device_state_entry &entry) |
| 321 | 367 | { |
| 322 | | /* aligned writes are easy */ |
| 323 | | if (!(address & 1)) |
| 368 | switch (entry.index()) |
| 324 | 369 | { |
| 325 | | asap->program->write_word(address, data); |
| 326 | | return; |
| 370 | case STATE_GENFLAGS: |
| 371 | case ASAP_PS: |
| 372 | SET_FLAGS(m_flagsio); |
| 373 | break; |
| 327 | 374 | } |
| 375 | } |
| 328 | 376 | |
| 329 | | /* misaligned writes are tricky */ |
| 330 | | if (!(address & 2)) |
| 377 | |
| 378 | //------------------------------------------------- |
| 379 | // state_export - export state from the device, |
| 380 | // to a known location where it can be read |
| 381 | //------------------------------------------------- |
| 382 | |
| 383 | void asap_device::state_export(const device_state_entry &entry) |
| 384 | { |
| 385 | switch (entry.index()) |
| 331 | 386 | { |
| 332 | | asap->program->write_byte(address + 1, data); |
| 333 | | asap->program->write_byte(address + 2, data >> 8); |
| 387 | case STATE_GENFLAGS: |
| 388 | case ASAP_PS: |
| 389 | m_flagsio = GET_FLAGS(); |
| 390 | break; |
| 334 | 391 | } |
| 335 | | else |
| 336 | | asap->program->write_byte(address + 1, data); |
| 337 | 392 | } |
| 338 | 393 | |
| 339 | | INLINE void WRITELONG(asap_state *asap, offs_t address, UINT32 data) |
| 394 | |
| 395 | //------------------------------------------------- |
| 396 | // state_string_export - export state as a string |
| 397 | // for the debugger |
| 398 | //------------------------------------------------- |
| 399 | |
| 400 | void asap_device::state_string_export(const device_state_entry &entry, astring &string) |
| 340 | 401 | { |
| 341 | | /* aligned writes are easy */ |
| 342 | | if (!(address & 3)) |
| 402 | switch (entry.index()) |
| 343 | 403 | { |
| 344 | | asap->program->write_dword(address, data); |
| 345 | | return; |
| 346 | | } |
| 347 | | |
| 348 | | /* misaligned writes are tricky */ |
| 349 | | switch (address & 3) |
| 350 | | { |
| 351 | | case 1: |
| 352 | | asap->program->write_byte(address, data); |
| 353 | | asap->program->write_word(address + 1, data >> 8); |
| 404 | case STATE_GENFLAGS: |
| 405 | string.printf("%c%c%c%c%c%c", |
| 406 | m_pflag ? 'P' : '.', |
| 407 | m_iflag ? 'I' : '.', |
| 408 | ((INT32)m_znflag < 0) ? 'N' : '.', |
| 409 | (m_znflag == 0) ? 'Z' : '.', |
| 410 | ((m_vflag >> 30) & PS_VFLAG) ? 'V' : '.', |
| 411 | m_cflag ? 'C' : '.'); |
| 354 | 412 | break; |
| 355 | | case 2: |
| 356 | | asap->program->write_word(address, data); |
| 357 | | break; |
| 358 | | case 3: |
| 359 | | asap->program->write_byte(address, data); |
| 360 | | break; |
| 361 | 413 | } |
| 362 | 414 | } |
| 363 | 415 | |
| 364 | 416 | |
| 417 | //------------------------------------------------- |
| 418 | // disasm_disassemble - call the disassembly |
| 419 | // helper function |
| 420 | //------------------------------------------------- |
| 365 | 421 | |
| 366 | | /*************************************************************************** |
| 367 | | EXCEPTION HANDLING |
| 368 | | ***************************************************************************/ |
| 369 | | |
| 370 | | INLINE void generate_exception(asap_state *asap, int exception) |
| 422 | offs_t asap_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 371 | 423 | { |
| 372 | | asap->pflag = asap->iflag; |
| 373 | | asap->iflag = 0; |
| 424 | extern offs_t asap_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); |
| 425 | return asap_disassemble(buffer, pc, oprom, opram); |
| 426 | } |
| 374 | 427 | |
| 375 | | asap->src2val[REGBASE + 30] = asap->pc; |
| 376 | | asap->src2val[REGBASE + 31] = (asap->nextpc == ~0) ? asap->pc + 4 : asap->nextpc; |
| 377 | 428 | |
| 378 | | asap->pc = 0x40 * exception; |
| 379 | | asap->nextpc = ~0; |
| 380 | 429 | |
| 381 | | asap->icount--; |
| 382 | | } |
| 430 | //************************************************************************** |
| 431 | // INLINE HELPERS |
| 432 | //************************************************************************** |
| 383 | 433 | |
| 434 | //------------------------------------------------- |
| 435 | // readop - read an opcode at the given address |
| 436 | //------------------------------------------------- |
| 384 | 437 | |
| 438 | inline UINT32 asap_device::readop(offs_t pc) |
| 439 | { |
| 440 | return m_direct->read_decrypted_dword(pc); |
| 441 | } |
| 385 | 442 | |
| 386 | | /*************************************************************************** |
| 387 | | IRQ HANDLING |
| 388 | | ***************************************************************************/ |
| 389 | 443 | |
| 390 | | INLINE void check_irqs(asap_state *asap) |
| 444 | //------------------------------------------------- |
| 445 | // readbyte - read a byte at the given address |
| 446 | //------------------------------------------------- |
| 447 | |
| 448 | inline UINT8 asap_device::readbyte(offs_t address) |
| 391 | 449 | { |
| 392 | | if (asap->irq_state && asap->iflag) |
| 393 | | { |
| 394 | | generate_exception(asap, EXCEPTION_INTERRUPT); |
| 395 | | if (asap->irq_callback != NULL) |
| 396 | | (*asap->irq_callback)(asap->device, ASAP_IRQ0); |
| 397 | | } |
| 450 | // no alignment issues with bytes |
| 451 | return m_program->read_byte(address); |
| 398 | 452 | } |
| 399 | 453 | |
| 400 | 454 | |
| 401 | | static void set_irq_line(asap_state *asap, int irqline, int state) |
| 455 | //------------------------------------------------- |
| 456 | // readword - read a word at the given address |
| 457 | //------------------------------------------------- |
| 458 | |
| 459 | inline UINT16 asap_device::readword(offs_t address) |
| 402 | 460 | { |
| 403 | | asap->irq_state = (state != CLEAR_LINE); |
| 461 | // aligned reads are easy |
| 462 | if (!(address & 1)) |
| 463 | return m_program->read_word(address); |
| 464 | |
| 465 | // misaligned reads are tricky |
| 466 | return m_program->read_dword(address & ~3) >> (address & 3); |
| 404 | 467 | } |
| 405 | 468 | |
| 406 | 469 | |
| 470 | //------------------------------------------------- |
| 471 | // readlong - read a long at the given address |
| 472 | //------------------------------------------------- |
| 407 | 473 | |
| 408 | | /*************************************************************************** |
| 409 | | INITIALIZATION AND SHUTDOWN |
| 410 | | ***************************************************************************/ |
| 474 | inline UINT32 asap_device::readlong(offs_t address) |
| 475 | { |
| 476 | // aligned reads are easy |
| 477 | if (!(address & 3)) |
| 478 | return m_program->read_dword(address); |
| 411 | 479 | |
| 412 | | static void init_tables(running_machine *machine) |
| 480 | // misaligned reads are tricky |
| 481 | return m_program->read_dword(address & ~3) >> (address & 3); |
| 482 | } |
| 483 | |
| 484 | |
| 485 | //------------------------------------------------- |
| 486 | // writebyte - write a byte at the given address |
| 487 | //------------------------------------------------- |
| 488 | |
| 489 | inline void asap_device::writebyte(offs_t address, UINT8 data) |
| 413 | 490 | { |
| 414 | | /* allocate opcode table */ |
| 415 | | if (!opcode) |
| 416 | | opcode = auto_alloc_array(machine, asap_ophandler, 32 * 32 * 2); |
| 491 | // no alignment issues with bytes |
| 492 | m_program->write_byte(address, data); |
| 493 | } |
| 417 | 494 | |
| 418 | | /* fill opcode table */ |
| 419 | | if (opcode) |
| 495 | |
| 496 | //------------------------------------------------- |
| 497 | // writeword - write a word at the given address |
| 498 | //------------------------------------------------- |
| 499 | |
| 500 | inline void asap_device::writeword(offs_t address, UINT16 data) |
| 501 | { |
| 502 | // aligned writes are easy |
| 503 | if (!(address & 1)) |
| 420 | 504 | { |
| 421 | | int op, dst, cond; |
| 505 | m_program->write_word(address, data); |
| 506 | return; |
| 507 | } |
| 422 | 508 | |
| 423 | | for (op = 0; op < 32; op++) |
| 424 | | for (dst = 0; dst < 32; dst++) |
| 425 | | for (cond = 0; cond < 2; cond++) |
| 426 | | if (op == 1) |
| 427 | | opcode[(op << 6) + (dst << 1) + cond] = conditiontable[dst & 15]; |
| 428 | | else if (cond && dst == 0) |
| 429 | | opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][3]; |
| 430 | | else if (cond) |
| 431 | | opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][2]; |
| 432 | | else if (dst == 0) |
| 433 | | opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][1]; |
| 434 | | else |
| 435 | | opcode[(op << 6) + (dst << 1) + cond] = opcodetable[op][0]; |
| 509 | // misaligned writes are tricky |
| 510 | if (!(address & 2)) |
| 511 | { |
| 512 | m_program->write_byte(address + 1, data); |
| 513 | m_program->write_byte(address + 2, data >> 8); |
| 436 | 514 | } |
| 515 | else |
| 516 | m_program->write_byte(address + 1, data); |
| 437 | 517 | } |
| 438 | 518 | |
| 439 | | static CPU_INIT( asap ) |
| 440 | | { |
| 441 | | asap_state *asap = get_safe_token(device); |
| 442 | | int i; |
| 443 | 519 | |
| 444 | | init_tables(device->machine); |
| 445 | | for (i = 0; i < REGBASE; i++) |
| 446 | | asap->src2val[i] = i; |
| 447 | | asap->irq_callback = irqcallback; |
| 448 | | asap->device = device; |
| 449 | | asap->program = device->space(AS_PROGRAM); |
| 450 | | asap->direct = &asap->program->direct(); |
| 520 | //------------------------------------------------- |
| 521 | // writelong - write a long at the given address |
| 522 | //------------------------------------------------- |
| 451 | 523 | |
| 524 | inline void asap_device::writelong(offs_t address, UINT32 data) |
| 525 | { |
| 526 | // aligned writes are easy |
| 527 | if (!(address & 3)) |
| 528 | { |
| 529 | m_program->write_dword(address, data); |
| 530 | return; |
| 531 | } |
| 452 | 532 | |
| 453 | | state_save_register_device_item(device, 0, asap->pc); |
| 454 | | state_save_register_device_item(device, 0, asap->pflag); |
| 455 | | state_save_register_device_item(device, 0, asap->iflag); |
| 456 | | state_save_register_device_item(device, 0, asap->cflag); |
| 457 | | state_save_register_device_item(device, 0, asap->vflag); |
| 458 | | state_save_register_device_item(device, 0, asap->znflag); |
| 459 | | state_save_register_device_item(device, 0, asap->op); |
| 460 | | state_save_register_device_item(device, 0, asap->ppc); |
| 461 | | state_save_register_device_item(device, 0, asap->nextpc); |
| 462 | | state_save_register_device_item(device, 0, asap->irq_state); |
| 533 | // misaligned writes are tricky |
| 534 | switch (address & 3) |
| 535 | { |
| 536 | case 1: |
| 537 | m_program->write_byte(address, data); |
| 538 | m_program->write_word(address + 1, data >> 8); |
| 539 | break; |
| 540 | case 2: |
| 541 | m_program->write_word(address, data); |
| 542 | break; |
| 543 | case 3: |
| 544 | m_program->write_byte(address, data); |
| 545 | break; |
| 546 | } |
| 463 | 547 | } |
| 464 | 548 | |
| 465 | | static CPU_RESET( asap ) |
| 549 | |
| 550 | //------------------------------------------------- |
| 551 | // generate_exception - generate an exception of |
| 552 | // the requested type |
| 553 | //------------------------------------------------- |
| 554 | |
| 555 | inline void asap_device::generate_exception(int exception) |
| 466 | 556 | { |
| 467 | | asap_state *asap = get_safe_token(device); |
| 557 | m_pflag = m_iflag; |
| 558 | m_iflag = 0; |
| 468 | 559 | |
| 469 | | /* initialize the state */ |
| 470 | | asap->src2val[REGBASE + 0] = 0; |
| 471 | | asap->pc = 0; |
| 472 | | asap->iflag = 0; |
| 560 | m_src2val[REGBASE + 30] = m_pc; |
| 561 | m_src2val[REGBASE + 31] = (m_nextpc == ~0) ? m_pc + 4 : m_nextpc; |
| 473 | 562 | |
| 474 | | asap->ppc = 0; |
| 475 | | asap->nextpc = ~0; |
| 476 | | asap->irq_state = 0; |
| 477 | | asap->irq_callback = NULL; |
| 563 | m_pc = 0x40 * exception; |
| 564 | m_nextpc = ~0; |
| 565 | |
| 566 | m_icount--; |
| 478 | 567 | } |
| 479 | 568 | |
| 480 | 569 | |
| 481 | | static CPU_EXIT( asap ) |
| 570 | //------------------------------------------------- |
| 571 | // check_irqs - check for pending IRQs |
| 572 | //------------------------------------------------- |
| 573 | |
| 574 | inline void asap_device::check_irqs() |
| 482 | 575 | { |
| 483 | | opcode = NULL; |
| 576 | if (m_irq_state && m_iflag) |
| 577 | { |
| 578 | generate_exception(EXCEPTION_INTERRUPT); |
| 579 | standard_irq_callback(ASAP_IRQ0); |
| 580 | } |
| 484 | 581 | } |
| 485 | 582 | |
| 486 | 583 | |
| 487 | 584 | |
| 488 | | /*************************************************************************** |
| 489 | | CORE EXECUTION LOOP |
| 490 | | ***************************************************************************/ |
| 585 | //************************************************************************** |
| 586 | // CORE EXECUTION |
| 587 | //************************************************************************** |
| 491 | 588 | |
| 492 | | INLINE void fetch_instruction(asap_state *asap) |
| 589 | inline void asap_device::fetch_instruction() |
| 493 | 590 | { |
| 494 | | /* debugging */ |
| 495 | | asap->ppc = asap->pc; |
| 591 | // debugging |
| 592 | m_ppc = m_pc; |
| 496 | 593 | |
| 497 | | /* instruction fetch */ |
| 498 | | asap->op.d = ROPCODE(asap, asap->pc); |
| 499 | | asap->pc += 4; |
| 594 | // instruction fetch |
| 595 | m_op = readop(m_pc); |
| 596 | m_pc += 4; |
| 500 | 597 | } |
| 501 | 598 | |
| 502 | | INLINE void fetch_instruction_debug(asap_state *asap) |
| 599 | inline void asap_device::fetch_instruction_debug() |
| 503 | 600 | { |
| 504 | | /* debugging */ |
| 505 | | asap->ppc = asap->pc; |
| 506 | | debugger_instruction_hook(asap->device, asap->pc); |
| 601 | // debugging |
| 602 | m_ppc = m_pc; |
| 603 | debugger_instruction_hook(this, m_pc); |
| 507 | 604 | |
| 508 | | /* instruction fetch */ |
| 509 | | asap->op.d = ROPCODE(asap, asap->pc); |
| 510 | | asap->pc += 4; |
| 605 | // instruction fetch |
| 606 | m_op = readop(m_pc); |
| 607 | m_pc += 4; |
| 511 | 608 | } |
| 512 | 609 | |
| 513 | | INLINE void execute_instruction(asap_state *asap) |
| 610 | inline void asap_device::execute_instruction() |
| 514 | 611 | { |
| 515 | | /* parse the instruction */ |
| 516 | | (*opcode[asap->op.d >> 21])(asap); |
| 612 | // parse the instruction |
| 613 | (this->*m_opcode[m_op >> 21])(); |
| 517 | 614 | } |
| 518 | 615 | |
| 519 | | static CPU_EXECUTE( asap ) |
| 616 | |
| 617 | void asap_device::execute_set_input(int inputnum, int state) |
| 520 | 618 | { |
| 521 | | asap_state *asap = get_safe_token(device); |
| 619 | m_irq_state = (state != CLEAR_LINE); |
| 620 | } |
| 522 | 621 | |
| 523 | | /* check for IRQs */ |
| 524 | | check_irqs(asap); |
| 525 | 622 | |
| 526 | | /* core execution loop */ |
| 527 | | if ((device->machine->debug_flags & DEBUG_FLAG_ENABLED) == 0) |
| 623 | void asap_device::execute_run() |
| 624 | { |
| 625 | // check for IRQs |
| 626 | check_irqs(); |
| 627 | |
| 628 | // core execution loop |
| 629 | if ((device_t::m_machine.debug_flags & DEBUG_FLAG_ENABLED) == 0) |
| 528 | 630 | { |
| 529 | 631 | do |
| 530 | 632 | { |
| 531 | | /* fetch and execute the next instruction */ |
| 532 | | fetch_instruction(asap); |
| 533 | | execute_instruction(asap); |
| 633 | // fetch and execute the next instruction |
| 634 | fetch_instruction(); |
| 635 | execute_instruction(); |
| 534 | 636 | |
| 535 | | /* fetch and execute the next instruction */ |
| 536 | | fetch_instruction(asap); |
| 537 | | execute_instruction(asap); |
| 637 | // fetch and execute the next instruction |
| 638 | fetch_instruction(); |
| 639 | execute_instruction(); |
| 538 | 640 | |
| 539 | | /* fetch and execute the next instruction */ |
| 540 | | fetch_instruction(asap); |
| 541 | | execute_instruction(asap); |
| 641 | // fetch and execute the next instruction |
| 642 | fetch_instruction(); |
| 643 | execute_instruction(); |
| 542 | 644 | |
| 543 | | /* fetch and execute the next instruction */ |
| 544 | | fetch_instruction(asap); |
| 545 | | execute_instruction(asap); |
| 645 | // fetch and execute the next instruction |
| 646 | fetch_instruction(); |
| 647 | execute_instruction(); |
| 546 | 648 | |
| 547 | | asap->icount -= 4; |
| 649 | m_icount -= 4; |
| 548 | 650 | |
| 549 | | } while (asap->icount > 0); |
| 651 | } while (m_icount > 0); |
| 550 | 652 | } |
| 551 | 653 | else |
| 552 | 654 | { |
| 553 | 655 | do |
| 554 | 656 | { |
| 555 | | /* fetch and execute the next instruction */ |
| 556 | | fetch_instruction_debug(asap); |
| 557 | | execute_instruction(asap); |
| 657 | // fetch and execute the next instruction |
| 658 | fetch_instruction_debug(); |
| 659 | execute_instruction(); |
| 558 | 660 | |
| 559 | | /* fetch and execute the next instruction */ |
| 560 | | fetch_instruction_debug(asap); |
| 561 | | execute_instruction(asap); |
| 661 | // fetch and execute the next instruction |
| 662 | fetch_instruction_debug(); |
| 663 | execute_instruction(); |
| 562 | 664 | |
| 563 | | /* fetch and execute the next instruction */ |
| 564 | | fetch_instruction_debug(asap); |
| 565 | | execute_instruction(asap); |
| 665 | // fetch and execute the next instruction |
| 666 | fetch_instruction_debug(); |
| 667 | execute_instruction(); |
| 566 | 668 | |
| 567 | | /* fetch and execute the next instruction */ |
| 568 | | fetch_instruction_debug(asap); |
| 569 | | execute_instruction(asap); |
| 669 | // fetch and execute the next instruction |
| 670 | fetch_instruction_debug(); |
| 671 | execute_instruction(); |
| 570 | 672 | |
| 571 | | asap->icount -= 4; |
| 673 | m_icount -= 4; |
| 572 | 674 | |
| 573 | | } while (asap->icount > 0); |
| 675 | } while (m_icount > 0); |
| 574 | 676 | } |
| 575 | 677 | } |
| 576 | 678 | |
| 577 | 679 | |
| 578 | 680 | |
| 579 | | /*************************************************************************** |
| 580 | | DISASSEMBLY HOOK |
| 581 | | ***************************************************************************/ |
| 681 | //************************************************************************** |
| 682 | // OPCODE IMPLEMENTATIONS |
| 683 | //************************************************************************** |
| 582 | 684 | |
| 583 | | extern CPU_DISASSEMBLE( asap ); |
| 584 | | |
| 585 | | |
| 586 | | |
| 587 | | /*************************************************************************** |
| 588 | | HELPER MACROS |
| 589 | | ***************************************************************************/ |
| 590 | | |
| 591 | | #define OPCODE(A) ((A)->op.d >> 27) |
| 592 | | #define DSTREG(A) (((A)->op.d >> 22) & 31) |
| 593 | | #define DSTVAL(A) (A)->src2val[REGBASE + DSTREG(A)] |
| 594 | | #define SRC1REG(A) (((A)->op.d >> 16) & 31) |
| 595 | | #define SRC1VAL(A) (A)->src2val[REGBASE + SRC1REG(A)] |
| 596 | | #define SRC2VAL(A) (A)->src2val[(A)->op.w.l] |
| 597 | | |
| 598 | | |
| 599 | | |
| 600 | | /*************************************************************************** |
| 601 | | OPCODES |
| 602 | | ***************************************************************************/ |
| 603 | | |
| 604 | | static void noop(asap_state *asap) |
| 685 | void asap_device::noop() |
| 605 | 686 | { |
| 606 | 687 | } |
| 607 | 688 | |
| 608 | 689 | /**************************** TRAP 0 ******************************/ |
| 609 | 690 | |
| 610 | | static void trap0(asap_state *asap) |
| 691 | void asap_device::trap0() |
| 611 | 692 | { |
| 612 | | generate_exception(asap, EXCEPTION_TRAP0); |
| 693 | generate_exception(EXCEPTION_TRAP0); |
| 613 | 694 | } |
| 614 | 695 | |
| 615 | 696 | /**************************** Bcc ******************************/ |
| 616 | 697 | |
| 617 | | static void bsp(asap_state *asap) |
| 698 | void asap_device::bsp() |
| 618 | 699 | { |
| 619 | | if ((INT32)asap->znflag > 0) |
| 700 | if ((INT32)m_znflag > 0) |
| 620 | 701 | { |
| 621 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 702 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 622 | 703 | |
| 623 | | fetch_instruction(asap); |
| 624 | | asap->pc = asap->nextpc; |
| 625 | | asap->nextpc = ~0; |
| 704 | fetch_instruction(); |
| 705 | m_pc = m_nextpc; |
| 706 | m_nextpc = ~0; |
| 626 | 707 | |
| 627 | | execute_instruction(asap); |
| 628 | | asap->icount--; |
| 708 | execute_instruction(); |
| 709 | m_icount--; |
| 629 | 710 | } |
| 630 | 711 | } |
| 631 | 712 | |
| 632 | | static void bmz(asap_state *asap) |
| 713 | void asap_device::bmz() |
| 633 | 714 | { |
| 634 | | if ((INT32)asap->znflag <= 0) |
| 715 | if ((INT32)m_znflag <= 0) |
| 635 | 716 | { |
| 636 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 717 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 637 | 718 | |
| 638 | | fetch_instruction(asap); |
| 639 | | asap->pc = asap->nextpc; |
| 640 | | asap->nextpc = ~0; |
| 719 | fetch_instruction(); |
| 720 | m_pc = m_nextpc; |
| 721 | m_nextpc = ~0; |
| 641 | 722 | |
| 642 | | execute_instruction(asap); |
| 643 | | asap->icount--; |
| 723 | execute_instruction(); |
| 724 | m_icount--; |
| 644 | 725 | } |
| 645 | 726 | } |
| 646 | 727 | |
| 647 | | static void bgt(asap_state *asap) |
| 728 | void asap_device::bgt() |
| 648 | 729 | { |
| 649 | | if (asap->znflag != 0 && (INT32)(asap->znflag ^ asap->vflag) >= 0) |
| 730 | if (m_znflag != 0 && (INT32)(m_znflag ^ m_vflag) >= 0) |
| 650 | 731 | { |
| 651 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 732 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 652 | 733 | |
| 653 | | fetch_instruction(asap); |
| 654 | | asap->pc = asap->nextpc; |
| 655 | | asap->nextpc = ~0; |
| 734 | fetch_instruction(); |
| 735 | m_pc = m_nextpc; |
| 736 | m_nextpc = ~0; |
| 656 | 737 | |
| 657 | | execute_instruction(asap); |
| 658 | | asap->icount--; |
| 738 | execute_instruction(); |
| 739 | m_icount--; |
| 659 | 740 | } |
| 660 | 741 | } |
| 661 | 742 | |
| 662 | | static void ble(asap_state *asap) |
| 743 | void asap_device::ble() |
| 663 | 744 | { |
| 664 | | if (asap->znflag == 0 || (INT32)(asap->znflag ^ asap->vflag) < 0) |
| 745 | if (m_znflag == 0 || (INT32)(m_znflag ^ m_vflag) < 0) |
| 665 | 746 | { |
| 666 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 747 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 667 | 748 | |
| 668 | | fetch_instruction(asap); |
| 669 | | asap->pc = asap->nextpc; |
| 670 | | asap->nextpc = ~0; |
| 749 | fetch_instruction(); |
| 750 | m_pc = m_nextpc; |
| 751 | m_nextpc = ~0; |
| 671 | 752 | |
| 672 | | execute_instruction(asap); |
| 673 | | asap->icount--; |
| 753 | execute_instruction(); |
| 754 | m_icount--; |
| 674 | 755 | } |
| 675 | 756 | } |
| 676 | 757 | |
| 677 | | static void bge(asap_state *asap) |
| 758 | void asap_device::bge() |
| 678 | 759 | { |
| 679 | | if ((INT32)(asap->znflag ^ asap->vflag) >= 0) |
| 760 | if ((INT32)(m_znflag ^ m_vflag) >= 0) |
| 680 | 761 | { |
| 681 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 762 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 682 | 763 | |
| 683 | | fetch_instruction(asap); |
| 684 | | asap->pc = asap->nextpc; |
| 685 | | asap->nextpc = ~0; |
| 764 | fetch_instruction(); |
| 765 | m_pc = m_nextpc; |
| 766 | m_nextpc = ~0; |
| 686 | 767 | |
| 687 | | execute_instruction(asap); |
| 688 | | asap->icount--; |
| 768 | execute_instruction(); |
| 769 | m_icount--; |
| 689 | 770 | } |
| 690 | 771 | } |
| 691 | 772 | |
| 692 | | static void blt(asap_state *asap) |
| 773 | void asap_device::blt() |
| 693 | 774 | { |
| 694 | | if ((INT32)(asap->znflag ^ asap->vflag) < 0) |
| 775 | if ((INT32)(m_znflag ^ m_vflag) < 0) |
| 695 | 776 | { |
| 696 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 777 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 697 | 778 | |
| 698 | | fetch_instruction(asap); |
| 699 | | asap->pc = asap->nextpc; |
| 700 | | asap->nextpc = ~0; |
| 779 | fetch_instruction(); |
| 780 | m_pc = m_nextpc; |
| 781 | m_nextpc = ~0; |
| 701 | 782 | |
| 702 | | execute_instruction(asap); |
| 703 | | asap->icount--; |
| 783 | execute_instruction(); |
| 784 | m_icount--; |
| 704 | 785 | } |
| 705 | 786 | } |
| 706 | 787 | |
| 707 | | static void bhi(asap_state *asap) |
| 788 | void asap_device::bhi() |
| 708 | 789 | { |
| 709 | | if (asap->znflag != 0 && asap->cflag) |
| 790 | if (m_znflag != 0 && m_cflag) |
| 710 | 791 | { |
| 711 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 792 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 712 | 793 | |
| 713 | | fetch_instruction(asap); |
| 714 | | asap->pc = asap->nextpc; |
| 715 | | asap->nextpc = ~0; |
| 794 | fetch_instruction(); |
| 795 | m_pc = m_nextpc; |
| 796 | m_nextpc = ~0; |
| 716 | 797 | |
| 717 | | execute_instruction(asap); |
| 718 | | asap->icount--; |
| 798 | execute_instruction(); |
| 799 | m_icount--; |
| 719 | 800 | } |
| 720 | 801 | } |
| 721 | 802 | |
| 722 | | static void bls(asap_state *asap) |
| 803 | void asap_device::bls() |
| 723 | 804 | { |
| 724 | | if (asap->znflag == 0 || !asap->cflag) |
| 805 | if (m_znflag == 0 || !m_cflag) |
| 725 | 806 | { |
| 726 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 807 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 727 | 808 | |
| 728 | | fetch_instruction(asap); |
| 729 | | asap->pc = asap->nextpc; |
| 730 | | asap->nextpc = ~0; |
| 809 | fetch_instruction(); |
| 810 | m_pc = m_nextpc; |
| 811 | m_nextpc = ~0; |
| 731 | 812 | |
| 732 | | execute_instruction(asap); |
| 733 | | asap->icount--; |
| 813 | execute_instruction(); |
| 814 | m_icount--; |
| 734 | 815 | } |
| 735 | 816 | } |
| 736 | 817 | |
| 737 | | static void bcc(asap_state *asap) |
| 818 | void asap_device::bcc() |
| 738 | 819 | { |
| 739 | | if (!asap->cflag) |
| 820 | if (!m_cflag) |
| 740 | 821 | { |
| 741 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 822 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 742 | 823 | |
| 743 | | fetch_instruction(asap); |
| 744 | | asap->pc = asap->nextpc; |
| 745 | | asap->nextpc = ~0; |
| 824 | fetch_instruction(); |
| 825 | m_pc = m_nextpc; |
| 826 | m_nextpc = ~0; |
| 746 | 827 | |
| 747 | | execute_instruction(asap); |
| 748 | | asap->icount--; |
| 828 | execute_instruction(); |
| 829 | m_icount--; |
| 749 | 830 | } |
| 750 | 831 | } |
| 751 | 832 | |
| 752 | | static void bcs(asap_state *asap) |
| 833 | void asap_device::bcs() |
| 753 | 834 | { |
| 754 | | if (asap->cflag) |
| 835 | if (m_cflag) |
| 755 | 836 | { |
| 756 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 837 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 757 | 838 | |
| 758 | | fetch_instruction(asap); |
| 759 | | asap->pc = asap->nextpc; |
| 760 | | asap->nextpc = ~0; |
| 839 | fetch_instruction(); |
| 840 | m_pc = m_nextpc; |
| 841 | m_nextpc = ~0; |
| 761 | 842 | |
| 762 | | execute_instruction(asap); |
| 763 | | asap->icount--; |
| 843 | execute_instruction(); |
| 844 | m_icount--; |
| 764 | 845 | } |
| 765 | 846 | } |
| 766 | 847 | |
| 767 | | static void bpl(asap_state *asap) |
| 848 | void asap_device::bpl() |
| 768 | 849 | { |
| 769 | | if ((INT32)asap->znflag >= 0) |
| 850 | if ((INT32)m_znflag >= 0) |
| 770 | 851 | { |
| 771 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 852 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 772 | 853 | |
| 773 | | fetch_instruction(asap); |
| 774 | | asap->pc = asap->nextpc; |
| 775 | | asap->nextpc = ~0; |
| 854 | fetch_instruction(); |
| 855 | m_pc = m_nextpc; |
| 856 | m_nextpc = ~0; |
| 776 | 857 | |
| 777 | | execute_instruction(asap); |
| 778 | | asap->icount--; |
| 858 | execute_instruction(); |
| 859 | m_icount--; |
| 779 | 860 | } |
| 780 | 861 | } |
| 781 | 862 | |
| 782 | | static void bmi(asap_state *asap) |
| 863 | void asap_device::bmi() |
| 783 | 864 | { |
| 784 | | if ((INT32)asap->znflag < 0) |
| 865 | if ((INT32)m_znflag < 0) |
| 785 | 866 | { |
| 786 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 867 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 787 | 868 | |
| 788 | | fetch_instruction(asap); |
| 789 | | asap->pc = asap->nextpc; |
| 790 | | asap->nextpc = ~0; |
| 869 | fetch_instruction(); |
| 870 | m_pc = m_nextpc; |
| 871 | m_nextpc = ~0; |
| 791 | 872 | |
| 792 | | execute_instruction(asap); |
| 793 | | asap->icount--; |
| 873 | execute_instruction(); |
| 874 | m_icount--; |
| 794 | 875 | } |
| 795 | 876 | } |
| 796 | 877 | |
| 797 | | static void bne(asap_state *asap) |
| 878 | void asap_device::bne() |
| 798 | 879 | { |
| 799 | | if (asap->znflag != 0) |
| 880 | if (m_znflag != 0) |
| 800 | 881 | { |
| 801 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 882 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 802 | 883 | |
| 803 | | fetch_instruction(asap); |
| 804 | | asap->pc = asap->nextpc; |
| 805 | | asap->nextpc = ~0; |
| 884 | fetch_instruction(); |
| 885 | m_pc = m_nextpc; |
| 886 | m_nextpc = ~0; |
| 806 | 887 | |
| 807 | | execute_instruction(asap); |
| 808 | | asap->icount--; |
| 888 | execute_instruction(); |
| 889 | m_icount--; |
| 809 | 890 | } |
| 810 | 891 | } |
| 811 | 892 | |
| 812 | | static void beq(asap_state *asap) |
| 893 | void asap_device::beq() |
| 813 | 894 | { |
| 814 | | if (asap->znflag == 0) |
| 895 | if (m_znflag == 0) |
| 815 | 896 | { |
| 816 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 897 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 817 | 898 | |
| 818 | | fetch_instruction(asap); |
| 819 | | asap->pc = asap->nextpc; |
| 820 | | asap->nextpc = ~0; |
| 899 | fetch_instruction(); |
| 900 | m_pc = m_nextpc; |
| 901 | m_nextpc = ~0; |
| 821 | 902 | |
| 822 | | execute_instruction(asap); |
| 823 | | asap->icount--; |
| 903 | execute_instruction(); |
| 904 | m_icount--; |
| 824 | 905 | } |
| 825 | 906 | } |
| 826 | 907 | |
| 827 | | static void bvc(asap_state *asap) |
| 908 | void asap_device::bvc() |
| 828 | 909 | { |
| 829 | | if ((INT32)asap->vflag >= 0) |
| 910 | if ((INT32)m_vflag >= 0) |
| 830 | 911 | { |
| 831 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 912 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 832 | 913 | |
| 833 | | fetch_instruction(asap); |
| 834 | | asap->pc = asap->nextpc; |
| 835 | | asap->nextpc = ~0; |
| 914 | fetch_instruction(); |
| 915 | m_pc = m_nextpc; |
| 916 | m_nextpc = ~0; |
| 836 | 917 | |
| 837 | | execute_instruction(asap); |
| 838 | | asap->icount--; |
| 918 | execute_instruction(); |
| 919 | m_icount--; |
| 839 | 920 | } |
| 840 | 921 | } |
| 841 | 922 | |
| 842 | | static void bvs(asap_state *asap) |
| 923 | void asap_device::bvs() |
| 843 | 924 | { |
| 844 | | if ((INT32)asap->vflag < 0) |
| 925 | if ((INT32)m_vflag < 0) |
| 845 | 926 | { |
| 846 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 927 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 847 | 928 | |
| 848 | | fetch_instruction(asap); |
| 849 | | asap->pc = asap->nextpc; |
| 850 | | asap->nextpc = ~0; |
| 929 | fetch_instruction(); |
| 930 | m_pc = m_nextpc; |
| 931 | m_nextpc = ~0; |
| 851 | 932 | |
| 852 | | execute_instruction(asap); |
| 853 | | asap->icount--; |
| 933 | execute_instruction(); |
| 934 | m_icount--; |
| 854 | 935 | } |
| 855 | 936 | } |
| 856 | 937 | |
| 857 | 938 | /**************************** BSR ******************************/ |
| 858 | 939 | |
| 859 | | static void bsr(asap_state *asap) |
| 940 | void asap_device::bsr() |
| 860 | 941 | { |
| 861 | | DSTVAL(asap) = asap->pc + 4; |
| 862 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 942 | DSTVAL = m_pc + 4; |
| 943 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 863 | 944 | |
| 864 | | fetch_instruction(asap); |
| 865 | | asap->pc = asap->nextpc; |
| 866 | | asap->nextpc = ~0; |
| 945 | fetch_instruction(); |
| 946 | m_pc = m_nextpc; |
| 947 | m_nextpc = ~0; |
| 867 | 948 | |
| 868 | | execute_instruction(asap); |
| 869 | | asap->icount--; |
| 949 | execute_instruction(); |
| 950 | m_icount--; |
| 870 | 951 | } |
| 871 | 952 | |
| 872 | | static void bsr_0(asap_state *asap) |
| 953 | void asap_device::bsr_0() |
| 873 | 954 | { |
| 874 | | asap->nextpc = asap->ppc + ((INT32)(asap->op.d << 10) >> 8); |
| 955 | m_nextpc = m_ppc + ((INT32)(m_op << 10) >> 8); |
| 875 | 956 | |
| 876 | | fetch_instruction(asap); |
| 877 | | asap->pc = asap->nextpc; |
| 878 | | asap->nextpc = ~0; |
| 957 | fetch_instruction(); |
| 958 | m_pc = m_nextpc; |
| 959 | m_nextpc = ~0; |
| 879 | 960 | |
| 880 | | execute_instruction(asap); |
| 881 | | asap->icount--; |
| 961 | execute_instruction(); |
| 962 | m_icount--; |
| 882 | 963 | } |
| 883 | 964 | |
| 884 | 965 | /**************************** LEA ******************************/ |
| 885 | 966 | |
| 886 | | static void lea(asap_state *asap) |
| 967 | void asap_device::lea() |
| 887 | 968 | { |
| 888 | | DSTVAL(asap) = SRC1VAL(asap) + (SRC2VAL(asap) << 2); |
| 969 | DSTVAL = SRC1VAL + (SRC2VAL << 2); |
| 889 | 970 | } |
| 890 | 971 | |
| 891 | | static void lea_c(asap_state *asap) |
| 972 | void asap_device::lea_c() |
| 892 | 973 | { |
| 893 | | UINT32 src1 = SRC1VAL(asap); |
| 894 | | UINT32 src2 = SRC2VAL(asap); |
| 974 | UINT32 src1 = SRC1VAL; |
| 975 | UINT32 src2 = SRC2VAL; |
| 895 | 976 | UINT32 dst = src1 + (src2 << 2); |
| 896 | 977 | |
| 897 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 978 | SET_ZNCV_ADD(dst, src1, src2); |
| 898 | 979 | if (src1 & 0xc0000000) |
| 899 | | SET_CFLAG(asap, 1); |
| 980 | SET_CFLAG(1); |
| 900 | 981 | if (((src1 ^ (src1 >> 1)) & 0x20000000) || (src1 ^ (src1 >> 2)) & 0x20000000) |
| 901 | | SET_VFLAG(asap, 1); |
| 902 | | DSTVAL(asap) = dst; |
| 982 | SET_VFLAG(1); |
| 983 | DSTVAL = dst; |
| 903 | 984 | } |
| 904 | 985 | |
| 905 | | static void lea_c0(asap_state *asap) |
| 986 | void asap_device::lea_c0() |
| 906 | 987 | { |
| 907 | | UINT32 src1 = SRC1VAL(asap); |
| 908 | | UINT32 src2 = SRC2VAL(asap); |
| 988 | UINT32 src1 = SRC1VAL; |
| 989 | UINT32 src2 = SRC2VAL; |
| 909 | 990 | UINT32 dst = src1 + (src2 << 2); |
| 910 | 991 | |
| 911 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 992 | SET_ZNCV_ADD(dst, src1, src2); |
| 912 | 993 | if (src1 & 0xc0000000) |
| 913 | | SET_CFLAG(asap, 1); |
| 994 | SET_CFLAG(1); |
| 914 | 995 | if (((src1 ^ (src1 >> 1)) & 0x20000000) || (src1 ^ (src1 >> 2)) & 0x20000000) |
| 915 | | SET_VFLAG(asap, 1); |
| 996 | SET_VFLAG(1); |
| 916 | 997 | } |
| 917 | 998 | |
| 918 | 999 | /**************************** LEAH ******************************/ |
| 919 | 1000 | |
| 920 | | static void leah(asap_state *asap) |
| 1001 | void asap_device::leah() |
| 921 | 1002 | { |
| 922 | | DSTVAL(asap) = SRC1VAL(asap) + (SRC2VAL(asap) << 1); |
| 1003 | DSTVAL = SRC1VAL + (SRC2VAL << 1); |
| 923 | 1004 | } |
| 924 | 1005 | |
| 925 | | static void leah_c(asap_state *asap) |
| 1006 | void asap_device::leah_c() |
| 926 | 1007 | { |
| 927 | | UINT32 src1 = SRC1VAL(asap); |
| 928 | | UINT32 src2 = SRC2VAL(asap); |
| 1008 | UINT32 src1 = SRC1VAL; |
| 1009 | UINT32 src2 = SRC2VAL; |
| 929 | 1010 | UINT32 dst = src1 + (src2 << 1); |
| 930 | 1011 | |
| 931 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 1012 | SET_ZNCV_ADD(dst, src1, src2); |
| 932 | 1013 | if (src1 & 0x80000000) |
| 933 | | SET_CFLAG(asap, 1); |
| 1014 | SET_CFLAG(1); |
| 934 | 1015 | if ((src1 ^ (src1 >> 1)) & 0x40000000) |
| 935 | | SET_VFLAG(asap, 1); |
| 936 | | DSTVAL(asap) = dst; |
| 1016 | SET_VFLAG(1); |
| 1017 | DSTVAL = dst; |
| 937 | 1018 | } |
| 938 | 1019 | |
| 939 | | static void leah_c0(asap_state *asap) |
| 1020 | void asap_device::leah_c0() |
| 940 | 1021 | { |
| 941 | | UINT32 src1 = SRC1VAL(asap); |
| 942 | | UINT32 src2 = SRC2VAL(asap); |
| 1022 | UINT32 src1 = SRC1VAL; |
| 1023 | UINT32 src2 = SRC2VAL; |
| 943 | 1024 | UINT32 dst = src1 + (src2 << 1); |
| 944 | 1025 | |
| 945 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 1026 | SET_ZNCV_ADD(dst, src1, src2); |
| 946 | 1027 | if (src1 & 0x80000000) |
| 947 | | SET_CFLAG(asap, 1); |
| 1028 | SET_CFLAG(1); |
| 948 | 1029 | if ((src1 ^ (src1 >> 1)) & 0x40000000) |
| 949 | | SET_VFLAG(asap, 1); |
| 1030 | SET_VFLAG(1); |
| 950 | 1031 | } |
| 951 | 1032 | |
| 952 | 1033 | /**************************** SUBR ******************************/ |
| 953 | 1034 | |
| 954 | | static void subr(asap_state *asap) |
| 1035 | void asap_device::subr() |
| 955 | 1036 | { |
| 956 | | DSTVAL(asap) = SRC2VAL(asap) - SRC1VAL(asap); |
| 1037 | DSTVAL = SRC2VAL - SRC1VAL; |
| 957 | 1038 | } |
| 958 | 1039 | |
| 959 | | static void subr_c(asap_state *asap) |
| 1040 | void asap_device::subr_c() |
| 960 | 1041 | { |
| 961 | | UINT32 src1 = SRC1VAL(asap); |
| 962 | | UINT32 src2 = SRC2VAL(asap); |
| 1042 | UINT32 src1 = SRC1VAL; |
| 1043 | UINT32 src2 = SRC2VAL; |
| 963 | 1044 | UINT32 dst = src2 - src1; |
| 964 | 1045 | |
| 965 | | SET_ZNCV_SUB(asap, dst, src2, src1); |
| 966 | | DSTVAL(asap) = dst; |
| 1046 | SET_ZNCV_SUB(dst, src2, src1); |
| 1047 | DSTVAL = dst; |
| 967 | 1048 | } |
| 968 | 1049 | |
| 969 | | static void subr_c0(asap_state *asap) |
| 1050 | void asap_device::subr_c0() |
| 970 | 1051 | { |
| 971 | | UINT32 src1 = SRC1VAL(asap); |
| 972 | | UINT32 src2 = SRC2VAL(asap); |
| 1052 | UINT32 src1 = SRC1VAL; |
| 1053 | UINT32 src2 = SRC2VAL; |
| 973 | 1054 | UINT32 dst = src2 - src1; |
| 974 | 1055 | |
| 975 | | SET_ZNCV_SUB(asap, dst, src2, src1); |
| 1056 | SET_ZNCV_SUB(dst, src2, src1); |
| 976 | 1057 | } |
| 977 | 1058 | |
| 978 | 1059 | /**************************** XOR ******************************/ |
| 979 | 1060 | |
| 980 | | static void xor_(asap_state *asap) |
| 1061 | void asap_device::xor_() |
| 981 | 1062 | { |
| 982 | | DSTVAL(asap) = SRC1VAL(asap) ^ SRC2VAL(asap); |
| 1063 | DSTVAL = SRC1VAL ^ SRC2VAL; |
| 983 | 1064 | } |
| 984 | 1065 | |
| 985 | | static void xor_c(asap_state *asap) |
| 1066 | void asap_device::xor_c() |
| 986 | 1067 | { |
| 987 | | UINT32 dst = SRC1VAL(asap) ^ SRC2VAL(asap); |
| 988 | | SET_ZN(asap, dst); |
| 989 | | DSTVAL(asap) = dst; |
| 1068 | UINT32 dst = SRC1VAL ^ SRC2VAL; |
| 1069 | SET_ZN(dst); |
| 1070 | DSTVAL = dst; |
| 990 | 1071 | } |
| 991 | 1072 | |
| 992 | | static void xor_c0(asap_state *asap) |
| 1073 | void asap_device::xor_c0() |
| 993 | 1074 | { |
| 994 | | UINT32 dst = SRC1VAL(asap) ^ SRC2VAL(asap); |
| 995 | | SET_ZN(asap, dst); |
| 1075 | UINT32 dst = SRC1VAL ^ SRC2VAL; |
| 1076 | SET_ZN(dst); |
| 996 | 1077 | } |
| 997 | 1078 | |
| 998 | 1079 | /**************************** XOR ******************************/ |
| 999 | 1080 | |
| 1000 | | static void xorn(asap_state *asap) |
| 1081 | void asap_device::xorn() |
| 1001 | 1082 | { |
| 1002 | | DSTVAL(asap) = SRC1VAL(asap) ^ ~SRC2VAL(asap); |
| 1083 | DSTVAL = SRC1VAL ^ ~SRC2VAL; |
| 1003 | 1084 | } |
| 1004 | 1085 | |
| 1005 | | static void xorn_c(asap_state *asap) |
| 1086 | void asap_device::xorn_c() |
| 1006 | 1087 | { |
| 1007 | | UINT32 dst = SRC1VAL(asap) ^ ~SRC2VAL(asap); |
| 1008 | | SET_ZN(asap, dst); |
| 1009 | | DSTVAL(asap) = dst; |
| 1088 | UINT32 dst = SRC1VAL ^ ~SRC2VAL; |
| 1089 | SET_ZN(dst); |
| 1090 | DSTVAL = dst; |
| 1010 | 1091 | } |
| 1011 | 1092 | |
| 1012 | | static void xorn_c0(asap_state *asap) |
| 1093 | void asap_device::xorn_c0() |
| 1013 | 1094 | { |
| 1014 | | UINT32 dst = SRC1VAL(asap) ^ ~SRC2VAL(asap); |
| 1015 | | SET_ZN(asap, dst); |
| 1095 | UINT32 dst = SRC1VAL ^ ~SRC2VAL; |
| 1096 | SET_ZN(dst); |
| 1016 | 1097 | } |
| 1017 | 1098 | |
| 1018 | 1099 | /**************************** ADD ******************************/ |
| 1019 | 1100 | |
| 1020 | | static void add(asap_state *asap) |
| 1101 | void asap_device::add() |
| 1021 | 1102 | { |
| 1022 | | DSTVAL(asap) = SRC1VAL(asap) + SRC2VAL(asap); |
| 1103 | DSTVAL = SRC1VAL + SRC2VAL; |
| 1023 | 1104 | } |
| 1024 | 1105 | |
| 1025 | | static void add_c(asap_state *asap) |
| 1106 | void asap_device::add_c() |
| 1026 | 1107 | { |
| 1027 | | UINT32 src1 = SRC1VAL(asap); |
| 1028 | | UINT32 src2 = SRC2VAL(asap); |
| 1108 | UINT32 src1 = SRC1VAL; |
| 1109 | UINT32 src2 = SRC2VAL; |
| 1029 | 1110 | UINT32 dst = src1 + src2; |
| 1030 | 1111 | |
| 1031 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 1032 | | DSTVAL(asap) = dst; |
| 1112 | SET_ZNCV_ADD(dst, src1, src2); |
| 1113 | DSTVAL = dst; |
| 1033 | 1114 | } |
| 1034 | 1115 | |
| 1035 | | static void add_c0(asap_state *asap) |
| 1116 | void asap_device::add_c0() |
| 1036 | 1117 | { |
| 1037 | | UINT32 src1 = SRC1VAL(asap); |
| 1038 | | UINT32 src2 = SRC2VAL(asap); |
| 1118 | UINT32 src1 = SRC1VAL; |
| 1119 | UINT32 src2 = SRC2VAL; |
| 1039 | 1120 | UINT32 dst = src1 + src2; |
| 1040 | 1121 | |
| 1041 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 1122 | SET_ZNCV_ADD(dst, src1, src2); |
| 1042 | 1123 | } |
| 1043 | 1124 | |
| 1044 | 1125 | /**************************** ADD ******************************/ |
| 1045 | 1126 | |
| 1046 | | static void sub(asap_state *asap) |
| 1127 | void asap_device::sub() |
| 1047 | 1128 | { |
| 1048 | | DSTVAL(asap) = SRC1VAL(asap) - SRC2VAL(asap); |
| 1129 | DSTVAL = SRC1VAL - SRC2VAL; |
| 1049 | 1130 | } |
| 1050 | 1131 | |
| 1051 | | static void sub_c(asap_state *asap) |
| 1132 | void asap_device::sub_c() |
| 1052 | 1133 | { |
| 1053 | | UINT32 src1 = SRC1VAL(asap); |
| 1054 | | UINT32 src2 = SRC2VAL(asap); |
| 1134 | UINT32 src1 = SRC1VAL; |
| 1135 | UINT32 src2 = SRC2VAL; |
| 1055 | 1136 | UINT32 dst = src1 - src2; |
| 1056 | 1137 | |
| 1057 | | SET_ZNCV_SUB(asap, dst, src1, src2); |
| 1058 | | DSTVAL(asap) = dst; |
| 1138 | SET_ZNCV_SUB(dst, src1, src2); |
| 1139 | DSTVAL = dst; |
| 1059 | 1140 | } |
| 1060 | 1141 | |
| 1061 | | static void sub_c0(asap_state *asap) |
| 1142 | void asap_device::sub_c0() |
| 1062 | 1143 | { |
| 1063 | | UINT32 src1 = SRC1VAL(asap); |
| 1064 | | UINT32 src2 = SRC2VAL(asap); |
| 1144 | UINT32 src1 = SRC1VAL; |
| 1145 | UINT32 src2 = SRC2VAL; |
| 1065 | 1146 | UINT32 dst = src1 - src2; |
| 1066 | 1147 | |
| 1067 | | SET_ZNCV_SUB(asap, dst, src1, src2); |
| 1148 | SET_ZNCV_SUB(dst, src1, src2); |
| 1068 | 1149 | } |
| 1069 | 1150 | |
| 1070 | 1151 | /**************************** ADDC ******************************/ |
| 1071 | 1152 | |
| 1072 | | static void addc(asap_state *asap) |
| 1153 | void asap_device::addc() |
| 1073 | 1154 | { |
| 1074 | | DSTVAL(asap) = SRC1VAL(asap) + SRC2VAL(asap) + asap->cflag; |
| 1155 | DSTVAL = SRC1VAL + SRC2VAL + m_cflag; |
| 1075 | 1156 | } |
| 1076 | 1157 | |
| 1077 | | static void addc_c(asap_state *asap) |
| 1158 | void asap_device::addc_c() |
| 1078 | 1159 | { |
| 1079 | | UINT32 src1 = SRC1VAL(asap); |
| 1080 | | UINT32 src2 = SRC2VAL(asap); |
| 1081 | | UINT32 dst = src1 + src2 + asap->cflag; |
| 1160 | UINT32 src1 = SRC1VAL; |
| 1161 | UINT32 src2 = SRC2VAL; |
| 1162 | UINT32 dst = src1 + src2 + m_cflag; |
| 1082 | 1163 | |
| 1083 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 1084 | | DSTVAL(asap) = dst; |
| 1164 | SET_ZNCV_ADD(dst, src1, src2); |
| 1165 | DSTVAL = dst; |
| 1085 | 1166 | } |
| 1086 | 1167 | |
| 1087 | | static void addc_c0(asap_state *asap) |
| 1168 | void asap_device::addc_c0() |
| 1088 | 1169 | { |
| 1089 | | UINT32 src1 = SRC1VAL(asap); |
| 1090 | | UINT32 src2 = SRC2VAL(asap); |
| 1091 | | UINT32 dst = src1 + src2 + asap->cflag; |
| 1170 | UINT32 src1 = SRC1VAL; |
| 1171 | UINT32 src2 = SRC2VAL; |
| 1172 | UINT32 dst = src1 + src2 + m_cflag; |
| 1092 | 1173 | |
| 1093 | | SET_ZNCV_ADD(asap, dst, src1, src2); |
| 1174 | SET_ZNCV_ADD(dst, src1, src2); |
| 1094 | 1175 | } |
| 1095 | 1176 | |
| 1096 | 1177 | /**************************** SUBC ******************************/ |
| 1097 | 1178 | |
| 1098 | | static void subc(asap_state *asap) |
| 1179 | void asap_device::subc() |
| 1099 | 1180 | { |
| 1100 | | DSTVAL(asap) = SRC1VAL(asap) - SRC2VAL(asap) - 1 + asap->cflag; |
| 1181 | DSTVAL = SRC1VAL - SRC2VAL - 1 + m_cflag; |
| 1101 | 1182 | } |
| 1102 | 1183 | |
| 1103 | | static void subc_c(asap_state *asap) |
| 1184 | void asap_device::subc_c() |
| 1104 | 1185 | { |
| 1105 | | UINT32 src1 = SRC1VAL(asap); |
| 1106 | | UINT32 src2 = SRC2VAL(asap); |
| 1107 | | UINT32 dst = src1 - src2 - 1 + asap->cflag; |
| 1186 | UINT32 src1 = SRC1VAL; |
| 1187 | UINT32 src2 = SRC2VAL; |
| 1188 | UINT32 dst = src1 - src2 - 1 + m_cflag; |
| 1108 | 1189 | |
| 1109 | | SET_ZNCV_SUB(asap, dst, src1, src2); |
| 1110 | | DSTVAL(asap) = dst; |
| 1190 | SET_ZNCV_SUB(dst, src1, src2); |
| 1191 | DSTVAL = dst; |
| 1111 | 1192 | } |
| 1112 | 1193 | |
| 1113 | | static void subc_c0(asap_state *asap) |
| 1194 | void asap_device::subc_c0() |
| 1114 | 1195 | { |
| 1115 | | UINT32 src1 = SRC1VAL(asap); |
| 1116 | | UINT32 src2 = SRC2VAL(asap); |
| 1117 | | UINT32 dst = src1 - src2 - 1 + asap->cflag; |
| 1196 | UINT32 src1 = SRC1VAL; |
| 1197 | UINT32 src2 = SRC2VAL; |
| 1198 | UINT32 dst = src1 - src2 - 1 + m_cflag; |
| 1118 | 1199 | |
| 1119 | | SET_ZNCV_SUB(asap, dst, src1, src2); |
| 1200 | SET_ZNCV_SUB(dst, src1, src2); |
| 1120 | 1201 | } |
| 1121 | 1202 | |
| 1122 | 1203 | /**************************** AND ******************************/ |
| 1123 | 1204 | |
| 1124 | | static void and_(asap_state *asap) |
| 1205 | void asap_device::and_() |
| 1125 | 1206 | { |
| 1126 | | DSTVAL(asap) = SRC1VAL(asap) & SRC2VAL(asap); |
| 1207 | DSTVAL = SRC1VAL & SRC2VAL; |
| 1127 | 1208 | } |
| 1128 | 1209 | |
| 1129 | | static void and_c(asap_state *asap) |
| 1210 | void asap_device::and_c() |
| 1130 | 1211 | { |
| 1131 | | UINT32 dst = SRC1VAL(asap) & SRC2VAL(asap); |
| 1132 | | SET_ZN(asap, dst); |
| 1133 | | DSTVAL(asap) = dst; |
| 1212 | UINT32 dst = SRC1VAL & SRC2VAL; |
| 1213 | SET_ZN(dst); |
| 1214 | DSTVAL = dst; |
| 1134 | 1215 | } |
| 1135 | 1216 | |
| 1136 | | static void and_c0(asap_state *asap) |
| 1217 | void asap_device::and_c0() |
| 1137 | 1218 | { |
| 1138 | | UINT32 dst = SRC1VAL(asap) & SRC2VAL(asap); |
| 1139 | | SET_ZN(asap, dst); |
| 1219 | UINT32 dst = SRC1VAL & SRC2VAL; |
| 1220 | SET_ZN(dst); |
| 1140 | 1221 | } |
| 1141 | 1222 | |
| 1142 | 1223 | /**************************** ANDN ******************************/ |
| 1143 | 1224 | |
| 1144 | | static void andn(asap_state *asap) |
| 1225 | void asap_device::andn() |
| 1145 | 1226 | { |
| 1146 | | DSTVAL(asap) = SRC1VAL(asap) & ~SRC2VAL(asap); |
| 1227 | DSTVAL = SRC1VAL & ~SRC2VAL; |
| 1147 | 1228 | } |
| 1148 | 1229 | |
| 1149 | | static void andn_c(asap_state *asap) |
| 1230 | void asap_device::andn_c() |
| 1150 | 1231 | { |
| 1151 | | UINT32 dst = SRC1VAL(asap) & ~SRC2VAL(asap); |
| 1152 | | SET_ZN(asap, dst); |
| 1153 | | DSTVAL(asap) = dst; |
| 1232 | UINT32 dst = SRC1VAL & ~SRC2VAL; |
| 1233 | SET_ZN(dst); |
| 1234 | DSTVAL = dst; |
| 1154 | 1235 | } |
| 1155 | 1236 | |
| 1156 | | static void andn_c0(asap_state *asap) |
| 1237 | void asap_device::andn_c0() |
| 1157 | 1238 | { |
| 1158 | | UINT32 dst = SRC1VAL(asap) & ~SRC2VAL(asap); |
| 1159 | | SET_ZN(asap, dst); |
| 1239 | UINT32 dst = SRC1VAL & ~SRC2VAL; |
| 1240 | SET_ZN(dst); |
| 1160 | 1241 | } |
| 1161 | 1242 | |
| 1162 | 1243 | /**************************** OR ******************************/ |
| 1163 | 1244 | |
| 1164 | | static void or_(asap_state *asap) |
| 1245 | void asap_device::or_() |
| 1165 | 1246 | { |
| 1166 | | DSTVAL(asap) = SRC1VAL(asap) | SRC2VAL(asap); |
| 1247 | DSTVAL = SRC1VAL | SRC2VAL; |
| 1167 | 1248 | } |
| 1168 | 1249 | |
| 1169 | | static void or_c(asap_state *asap) |
| 1250 | void asap_device::or_c() |
| 1170 | 1251 | { |
| 1171 | | UINT32 dst = SRC1VAL(asap) | SRC2VAL(asap); |
| 1172 | | SET_ZN(asap, dst); |
| 1173 | | DSTVAL(asap) = dst; |
| 1252 | UINT32 dst = SRC1VAL | SRC2VAL; |
| 1253 | SET_ZN(dst); |
| 1254 | DSTVAL = dst; |
| 1174 | 1255 | } |
| 1175 | 1256 | |
| 1176 | | static void or_c0(asap_state *asap) |
| 1257 | void asap_device::or_c0() |
| 1177 | 1258 | { |
| 1178 | | UINT32 dst = SRC1VAL(asap) | SRC2VAL(asap); |
| 1179 | | SET_ZN(asap, dst); |
| 1259 | UINT32 dst = SRC1VAL | SRC2VAL; |
| 1260 | SET_ZN(dst); |
| 1180 | 1261 | } |
| 1181 | 1262 | |
| 1182 | 1263 | /**************************** ORN ******************************/ |
| 1183 | 1264 | |
| 1184 | | static void orn(asap_state *asap) |
| 1265 | void asap_device::orn() |
| 1185 | 1266 | { |
| 1186 | | DSTVAL(asap) = SRC1VAL(asap) | ~SRC2VAL(asap); |
| 1267 | DSTVAL = SRC1VAL | ~SRC2VAL; |
| 1187 | 1268 | } |
| 1188 | 1269 | |
| 1189 | | static void orn_c(asap_state *asap) |
| 1270 | void asap_device::orn_c() |
| 1190 | 1271 | { |
| 1191 | | UINT32 dst = SRC1VAL(asap) | ~SRC2VAL(asap); |
| 1192 | | SET_ZN(asap, dst); |
| 1193 | | DSTVAL(asap) = dst; |
| 1272 | UINT32 dst = SRC1VAL | ~SRC2VAL; |
| 1273 | SET_ZN(dst); |
| 1274 | DSTVAL = dst; |
| 1194 | 1275 | } |
| 1195 | 1276 | |
| 1196 | | static void orn_c0(asap_state *asap) |
| 1277 | void asap_device::orn_c0() |
| 1197 | 1278 | { |
| 1198 | | UINT32 dst = SRC1VAL(asap) | ~SRC2VAL(asap); |
| 1199 | | SET_ZN(asap, dst); |
| 1279 | UINT32 dst = SRC1VAL | ~SRC2VAL; |
| 1280 | SET_ZN(dst); |
| 1200 | 1281 | } |
| 1201 | 1282 | |
| 1202 | 1283 | /**************************** LD ******************************/ |
| 1203 | 1284 | |
| 1204 | | static void ld(asap_state *asap) |
| 1285 | void asap_device::ld() |
| 1205 | 1286 | { |
| 1206 | | DSTVAL(asap) = READLONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2)); |
| 1287 | DSTVAL = readlong(SRC1VAL + (SRC2VAL << 2)); |
| 1207 | 1288 | } |
| 1208 | 1289 | |
| 1209 | | static void ld_0(asap_state *asap) |
| 1290 | void asap_device::ld_0() |
| 1210 | 1291 | { |
| 1211 | | READLONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2)); |
| 1292 | readlong(SRC1VAL + (SRC2VAL << 2)); |
| 1212 | 1293 | } |
| 1213 | 1294 | |
| 1214 | | static void ld_c(asap_state *asap) |
| 1295 | void asap_device::ld_c() |
| 1215 | 1296 | { |
| 1216 | | UINT32 dst = READLONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2)); |
| 1217 | | SET_ZN(asap, dst); |
| 1218 | | DSTVAL(asap) = dst; |
| 1297 | UINT32 dst = readlong(SRC1VAL + (SRC2VAL << 2)); |
| 1298 | SET_ZN(dst); |
| 1299 | DSTVAL = dst; |
| 1219 | 1300 | } |
| 1220 | 1301 | |
| 1221 | | static void ld_c0(asap_state *asap) |
| 1302 | void asap_device::ld_c0() |
| 1222 | 1303 | { |
| 1223 | | UINT32 dst = READLONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2)); |
| 1224 | | SET_ZN(asap, dst); |
| 1304 | UINT32 dst = readlong(SRC1VAL + (SRC2VAL << 2)); |
| 1305 | SET_ZN(dst); |
| 1225 | 1306 | } |
| 1226 | 1307 | |
| 1227 | 1308 | /**************************** LDH ******************************/ |
| 1228 | 1309 | |
| 1229 | | static void ldh(asap_state *asap) |
| 1310 | void asap_device::ldh() |
| 1230 | 1311 | { |
| 1231 | | DSTVAL(asap) = (INT16)READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1312 | DSTVAL = (INT16)readword(SRC1VAL + (SRC2VAL << 1)); |
| 1232 | 1313 | } |
| 1233 | 1314 | |
| 1234 | | static void ldh_0(asap_state *asap) |
| 1315 | void asap_device::ldh_0() |
| 1235 | 1316 | { |
| 1236 | | READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1317 | readword(SRC1VAL + (SRC2VAL << 1)); |
| 1237 | 1318 | } |
| 1238 | 1319 | |
| 1239 | | static void ldh_c(asap_state *asap) |
| 1320 | void asap_device::ldh_c() |
| 1240 | 1321 | { |
| 1241 | | UINT32 dst = (INT16)READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1242 | | SET_ZN(asap, dst); |
| 1243 | | DSTVAL(asap) = dst; |
| 1322 | UINT32 dst = (INT16)readword(SRC1VAL + (SRC2VAL << 1)); |
| 1323 | SET_ZN(dst); |
| 1324 | DSTVAL = dst; |
| 1244 | 1325 | } |
| 1245 | 1326 | |
| 1246 | | static void ldh_c0(asap_state *asap) |
| 1327 | void asap_device::ldh_c0() |
| 1247 | 1328 | { |
| 1248 | | UINT32 dst = (INT16)READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1249 | | SET_ZN(asap, dst); |
| 1329 | UINT32 dst = (INT16)readword(SRC1VAL + (SRC2VAL << 1)); |
| 1330 | SET_ZN(dst); |
| 1250 | 1331 | } |
| 1251 | 1332 | |
| 1252 | 1333 | /**************************** LDUH ******************************/ |
| 1253 | 1334 | |
| 1254 | | static void lduh(asap_state *asap) |
| 1335 | void asap_device::lduh() |
| 1255 | 1336 | { |
| 1256 | | DSTVAL(asap) = READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1337 | DSTVAL = readword(SRC1VAL + (SRC2VAL << 1)); |
| 1257 | 1338 | } |
| 1258 | 1339 | |
| 1259 | | static void lduh_0(asap_state *asap) |
| 1340 | void asap_device::lduh_0() |
| 1260 | 1341 | { |
| 1261 | | READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1342 | readword(SRC1VAL + (SRC2VAL << 1)); |
| 1262 | 1343 | } |
| 1263 | 1344 | |
| 1264 | | static void lduh_c(asap_state *asap) |
| 1345 | void asap_device::lduh_c() |
| 1265 | 1346 | { |
| 1266 | | UINT32 dst = READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1267 | | SET_ZN(asap, dst); |
| 1268 | | DSTVAL(asap) = dst; |
| 1347 | UINT32 dst = readword(SRC1VAL + (SRC2VAL << 1)); |
| 1348 | SET_ZN(dst); |
| 1349 | DSTVAL = dst; |
| 1269 | 1350 | } |
| 1270 | 1351 | |
| 1271 | | static void lduh_c0(asap_state *asap) |
| 1352 | void asap_device::lduh_c0() |
| 1272 | 1353 | { |
| 1273 | | UINT32 dst = READWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1)); |
| 1274 | | SET_ZN(asap, dst); |
| 1354 | UINT32 dst = readword(SRC1VAL + (SRC2VAL << 1)); |
| 1355 | SET_ZN(dst); |
| 1275 | 1356 | } |
| 1276 | 1357 | |
| 1277 | 1358 | /**************************** STH ******************************/ |
| 1278 | 1359 | |
| 1279 | | static void sth(asap_state *asap) |
| 1360 | void asap_device::sth() |
| 1280 | 1361 | { |
| 1281 | | WRITEWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1), DSTVAL(asap)); |
| 1362 | writeword(SRC1VAL + (SRC2VAL << 1), DSTVAL); |
| 1282 | 1363 | } |
| 1283 | 1364 | |
| 1284 | | static void sth_0(asap_state *asap) |
| 1365 | void asap_device::sth_0() |
| 1285 | 1366 | { |
| 1286 | | WRITEWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1), 0); |
| 1367 | writeword(SRC1VAL + (SRC2VAL << 1), 0); |
| 1287 | 1368 | } |
| 1288 | 1369 | |
| 1289 | | static void sth_c(asap_state *asap) |
| 1370 | void asap_device::sth_c() |
| 1290 | 1371 | { |
| 1291 | | UINT32 dst = (UINT16)DSTVAL(asap); |
| 1292 | | SET_ZN(asap, dst); |
| 1293 | | WRITEWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1), dst); |
| 1372 | UINT32 dst = (UINT16)DSTVAL; |
| 1373 | SET_ZN(dst); |
| 1374 | writeword(SRC1VAL + (SRC2VAL << 1), dst); |
| 1294 | 1375 | } |
| 1295 | 1376 | |
| 1296 | | static void sth_c0(asap_state *asap) |
| 1377 | void asap_device::sth_c0() |
| 1297 | 1378 | { |
| 1298 | | SET_ZN(asap, 0); |
| 1299 | | WRITEWORD(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 1), 0); |
| 1379 | SET_ZN(0); |
| 1380 | writeword(SRC1VAL + (SRC2VAL << 1), 0); |
| 1300 | 1381 | } |
| 1301 | 1382 | |
| 1302 | 1383 | /**************************** ST ******************************/ |
| 1303 | 1384 | |
| 1304 | | static void st(asap_state *asap) |
| 1385 | void asap_device::st() |
| 1305 | 1386 | { |
| 1306 | | WRITELONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2), DSTVAL(asap)); |
| 1387 | writelong(SRC1VAL + (SRC2VAL << 2), DSTVAL); |
| 1307 | 1388 | } |
| 1308 | 1389 | |
| 1309 | | static void st_0(asap_state *asap) |
| 1390 | void asap_device::st_0() |
| 1310 | 1391 | { |
| 1311 | | WRITELONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2), 0); |
| 1392 | writelong(SRC1VAL + (SRC2VAL << 2), 0); |
| 1312 | 1393 | } |
| 1313 | 1394 | |
| 1314 | | static void st_c(asap_state *asap) |
| 1395 | void asap_device::st_c() |
| 1315 | 1396 | { |
| 1316 | | UINT32 dst = DSTVAL(asap); |
| 1317 | | SET_ZN(asap, dst); |
| 1318 | | WRITELONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2), dst); |
| 1397 | UINT32 dst = DSTVAL; |
| 1398 | SET_ZN(dst); |
| 1399 | writelong(SRC1VAL + (SRC2VAL << 2), dst); |
| 1319 | 1400 | } |
| 1320 | 1401 | |
| 1321 | | static void st_c0(asap_state *asap) |
| 1402 | void asap_device::st_c0() |
| 1322 | 1403 | { |
| 1323 | | SET_ZN(asap, 0); |
| 1324 | | WRITELONG(asap, SRC1VAL(asap) + (SRC2VAL(asap) << 2), 0); |
| 1404 | SET_ZN(0); |
| 1405 | writelong(SRC1VAL + (SRC2VAL << 2), 0); |
| 1325 | 1406 | } |
| 1326 | 1407 | |
| 1327 | 1408 | /**************************** LDB ******************************/ |
| 1328 | 1409 | |
| 1329 | | static void ldb(asap_state *asap) |
| 1410 | void asap_device::ldb() |
| 1330 | 1411 | { |
| 1331 | | DSTVAL(asap) = (INT8)READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1412 | DSTVAL = (INT8)readbyte(SRC1VAL + SRC2VAL); |
| 1332 | 1413 | } |
| 1333 | 1414 | |
| 1334 | | static void ldb_0(asap_state *asap) |
| 1415 | void asap_device::ldb_0() |
| 1335 | 1416 | { |
| 1336 | | READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1417 | readbyte(SRC1VAL + SRC2VAL); |
| 1337 | 1418 | } |
| 1338 | 1419 | |
| 1339 | | static void ldb_c(asap_state *asap) |
| 1420 | void asap_device::ldb_c() |
| 1340 | 1421 | { |
| 1341 | | UINT32 dst = (INT8)READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1342 | | SET_ZN(asap, dst); |
| 1343 | | DSTVAL(asap) = dst; |
| 1422 | UINT32 dst = (INT8)readbyte(SRC1VAL + SRC2VAL); |
| 1423 | SET_ZN(dst); |
| 1424 | DSTVAL = dst; |
| 1344 | 1425 | } |
| 1345 | 1426 | |
| 1346 | | static void ldb_c0(asap_state *asap) |
| 1427 | void asap_device::ldb_c0() |
| 1347 | 1428 | { |
| 1348 | | UINT32 dst = (INT8)READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1349 | | SET_ZN(asap, dst); |
| 1429 | UINT32 dst = (INT8)readbyte(SRC1VAL + SRC2VAL); |
| 1430 | SET_ZN(dst); |
| 1350 | 1431 | } |
| 1351 | 1432 | |
| 1352 | 1433 | /**************************** LDUB ******************************/ |
| 1353 | 1434 | |
| 1354 | | static void ldub(asap_state *asap) |
| 1435 | void asap_device::ldub() |
| 1355 | 1436 | { |
| 1356 | | DSTVAL(asap) = READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1437 | DSTVAL = readbyte(SRC1VAL + SRC2VAL); |
| 1357 | 1438 | } |
| 1358 | 1439 | |
| 1359 | | static void ldub_0(asap_state *asap) |
| 1440 | void asap_device::ldub_0() |
| 1360 | 1441 | { |
| 1361 | | READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1442 | readbyte(SRC1VAL + SRC2VAL); |
| 1362 | 1443 | } |
| 1363 | 1444 | |
| 1364 | | static void ldub_c(asap_state *asap) |
| 1445 | void asap_device::ldub_c() |
| 1365 | 1446 | { |
| 1366 | | UINT32 dst = READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1367 | | SET_ZN(asap, dst); |
| 1368 | | DSTVAL(asap) = dst; |
| 1447 | UINT32 dst = readbyte(SRC1VAL + SRC2VAL); |
| 1448 | SET_ZN(dst); |
| 1449 | DSTVAL = dst; |
| 1369 | 1450 | } |
| 1370 | 1451 | |
| 1371 | | static void ldub_c0(asap_state *asap) |
| 1452 | void asap_device::ldub_c0() |
| 1372 | 1453 | { |
| 1373 | | UINT32 dst = READBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap)); |
| 1374 | | SET_ZN(asap, dst); |
| 1454 | UINT32 dst = readbyte(SRC1VAL + SRC2VAL); |
| 1455 | SET_ZN(dst); |
| 1375 | 1456 | } |
| 1376 | 1457 | |
| 1377 | 1458 | /**************************** STB ******************************/ |
| 1378 | 1459 | |
| 1379 | | static void stb(asap_state *asap) |
| 1460 | void asap_device::stb() |
| 1380 | 1461 | { |
| 1381 | | WRITEBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap), DSTVAL(asap)); |
| 1462 | writebyte(SRC1VAL + SRC2VAL, DSTVAL); |
| 1382 | 1463 | } |
| 1383 | 1464 | |
| 1384 | | static void stb_0(asap_state *asap) |
| 1465 | void asap_device::stb_0() |
| 1385 | 1466 | { |
| 1386 | | WRITEBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap), 0); |
| 1467 | writebyte(SRC1VAL + SRC2VAL, 0); |
| 1387 | 1468 | } |
| 1388 | 1469 | |
| 1389 | | static void stb_c(asap_state *asap) |
| 1470 | void asap_device::stb_c() |
| 1390 | 1471 | { |
| 1391 | | UINT32 dst = (UINT8)DSTVAL(asap); |
| 1392 | | SET_ZN(asap, dst); |
| 1393 | | WRITEBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap), dst); |
| 1472 | UINT32 dst = (UINT8)DSTVAL; |
| 1473 | SET_ZN(dst); |
| 1474 | writebyte(SRC1VAL + SRC2VAL, dst); |
| 1394 | 1475 | } |
| 1395 | 1476 | |
| 1396 | | static void stb_c0(asap_state *asap) |
| 1477 | void asap_device::stb_c0() |
| 1397 | 1478 | { |
| 1398 | | SET_ZN(asap, 0); |
| 1399 | | WRITEBYTE(asap, SRC1VAL(asap) + SRC2VAL(asap), 0); |
| 1479 | SET_ZN(0); |
| 1480 | writebyte(SRC1VAL + SRC2VAL, 0); |
| 1400 | 1481 | } |
| 1401 | 1482 | |
| 1402 | 1483 | /**************************** ASHR ******************************/ |
| 1403 | 1484 | |
| 1404 | | static void ashr(asap_state *asap) |
| 1485 | void asap_device::ashr() |
| 1405 | 1486 | { |
| 1406 | | UINT32 src2 = SRC2VAL(asap); |
| 1407 | | DSTVAL(asap) = (src2 < 32) ? ((INT32)SRC1VAL(asap) >> src2) : ((INT32)SRC1VAL(asap) >> 31); |
| 1487 | UINT32 src2 = SRC2VAL; |
| 1488 | DSTVAL = (src2 < 32) ? ((INT32)SRC1VAL >> src2) : ((INT32)SRC1VAL >> 31); |
| 1408 | 1489 | } |
| 1409 | 1490 | |
| 1410 | | static void ashr_c(asap_state *asap) |
| 1491 | void asap_device::ashr_c() |
| 1411 | 1492 | { |
| 1412 | | UINT32 src2 = SRC2VAL(asap); |
| 1413 | | asap->cflag = 0; |
| 1493 | UINT32 src2 = SRC2VAL; |
| 1494 | m_cflag = 0; |
| 1414 | 1495 | if (src2 < 32) |
| 1415 | 1496 | { |
| 1416 | | UINT32 src1 = SRC1VAL(asap); |
| 1497 | UINT32 src1 = SRC1VAL; |
| 1417 | 1498 | UINT32 dst = (INT32)src1 >> src2; |
| 1418 | | SET_ZN(asap, dst); |
| 1499 | SET_ZN(dst); |
| 1419 | 1500 | if (src2 != 0) |
| 1420 | 1501 | { |
| 1421 | 1502 | src1 = src1 << (32 - src2); |
| 1422 | | asap->cflag = src1 >> 31; |
| 1503 | m_cflag = src1 >> 31; |
| 1423 | 1504 | } |
| 1424 | | DSTVAL(asap) = dst; |
| 1505 | DSTVAL = dst; |
| 1425 | 1506 | } |
| 1426 | 1507 | else |
| 1427 | 1508 | { |
| 1428 | | UINT32 dst = (INT32)SRC1VAL(asap) >> 31; |
| 1429 | | SET_ZN(asap, dst); |
| 1430 | | DSTVAL(asap) = dst; |
| 1509 | UINT32 dst = (INT32)SRC1VAL >> 31; |
| 1510 | SET_ZN(dst); |
| 1511 | DSTVAL = dst; |
| 1431 | 1512 | } |
| 1432 | 1513 | } |
| 1433 | 1514 | |
| 1434 | | static void ashr_c0(asap_state *asap) |
| 1515 | void asap_device::ashr_c0() |
| 1435 | 1516 | { |
| 1436 | | UINT32 src2 = SRC2VAL(asap); |
| 1437 | | asap->cflag = 0; |
| 1517 | UINT32 src2 = SRC2VAL; |
| 1518 | m_cflag = 0; |
| 1438 | 1519 | if (src2 < 32) |
| 1439 | 1520 | { |
| 1440 | | UINT32 src1 = SRC1VAL(asap); |
| 1521 | UINT32 src1 = SRC1VAL; |
| 1441 | 1522 | UINT32 dst = (INT32)src1 >> src2; |
| 1442 | | SET_ZN(asap, dst); |
| 1523 | SET_ZN(dst); |
| 1443 | 1524 | if (src2 != 0) |
| 1444 | 1525 | { |
| 1445 | 1526 | src1 = src1 << (32 - src2); |
| 1446 | | asap->cflag = src1 >> 31; |
| 1527 | m_cflag = src1 >> 31; |
| 1447 | 1528 | } |
| 1448 | 1529 | } |
| 1449 | 1530 | else |
| 1450 | 1531 | { |
| 1451 | | UINT32 dst = (INT32)SRC1VAL(asap) >> 31; |
| 1452 | | SET_ZN(asap, dst); |
| 1532 | UINT32 dst = (INT32)SRC1VAL >> 31; |
| 1533 | SET_ZN(dst); |
| 1453 | 1534 | } |
| 1454 | 1535 | } |
| 1455 | 1536 | |
| 1456 | 1537 | /**************************** LSHR ******************************/ |
| 1457 | 1538 | |
| 1458 | | static void lshr(asap_state *asap) |
| 1539 | void asap_device::lshr() |
| 1459 | 1540 | { |
| 1460 | | UINT32 src2 = SRC2VAL(asap); |
| 1461 | | DSTVAL(asap) = (src2 < 32) ? (SRC1VAL(asap) >> src2) : (SRC1VAL(asap) >> 31); |
| 1541 | UINT32 src2 = SRC2VAL; |
| 1542 | DSTVAL = (src2 < 32) ? (SRC1VAL >> src2) : (SRC1VAL >> 31); |
| 1462 | 1543 | } |
| 1463 | 1544 | |
| 1464 | | static void lshr_c(asap_state *asap) |
| 1545 | void asap_device::lshr_c() |
| 1465 | 1546 | { |
| 1466 | | UINT32 src2 = SRC2VAL(asap); |
| 1467 | | asap->cflag = 0; |
| 1547 | UINT32 src2 = SRC2VAL; |
| 1548 | m_cflag = 0; |
| 1468 | 1549 | if (src2 < 32) |
| 1469 | 1550 | { |
| 1470 | | UINT32 src1 = SRC1VAL(asap); |
| 1551 | UINT32 src1 = SRC1VAL; |
| 1471 | 1552 | UINT32 dst = src1 >> src2; |
| 1472 | | SET_ZN(asap, dst); |
| 1553 | SET_ZN(dst); |
| 1473 | 1554 | if (src2 != 0) |
| 1474 | 1555 | { |
| 1475 | 1556 | src1 = src1 << (32 - src2); |
| 1476 | | asap->cflag = src1 >> 31; |
| 1557 | m_cflag = src1 >> 31; |
| 1477 | 1558 | } |
| 1478 | | DSTVAL(asap) = dst; |
| 1559 | DSTVAL = dst; |
| 1479 | 1560 | } |
| 1480 | 1561 | else |
| 1481 | 1562 | { |
| 1482 | | UINT32 dst = SRC1VAL(asap) >> 31; |
| 1483 | | SET_ZN(asap, dst); |
| 1484 | | DSTVAL(asap) = dst; |
| 1563 | UINT32 dst = SRC1VAL >> 31; |
| 1564 | SET_ZN(dst); |
| 1565 | DSTVAL = dst; |
| 1485 | 1566 | } |
| 1486 | 1567 | } |
| 1487 | 1568 | |
| 1488 | | static void lshr_c0(asap_state *asap) |
| 1569 | void asap_device::lshr_c0() |
| 1489 | 1570 | { |
| 1490 | | UINT32 src2 = SRC2VAL(asap); |
| 1491 | | asap->cflag = 0; |
| 1571 | UINT32 src2 = SRC2VAL; |
| 1572 | m_cflag = 0; |
| 1492 | 1573 | if (src2 < 32) |
| 1493 | 1574 | { |
| 1494 | | UINT32 src1 = SRC1VAL(asap); |
| 1575 | UINT32 src1 = SRC1VAL; |
| 1495 | 1576 | UINT32 dst = src1 >> src2; |
| 1496 | | SET_ZN(asap, dst); |
| 1577 | SET_ZN(dst); |
| 1497 | 1578 | if (src2 != 0) |
| 1498 | 1579 | { |
| 1499 | 1580 | src1 = src1 << (32 - src2); |
| 1500 | | asap->cflag = src1 >> 31; |
| 1581 | m_cflag = src1 >> 31; |
| 1501 | 1582 | } |
| 1502 | 1583 | } |
| 1503 | 1584 | else |
| 1504 | 1585 | { |
| 1505 | | SET_ZN(asap, 0); |
| 1506 | | DSTVAL(asap) = 0; |
| 1586 | SET_ZN(0); |
| 1587 | DSTVAL = 0; |
| 1507 | 1588 | } |
| 1508 | 1589 | } |
| 1509 | 1590 | |
| 1510 | 1591 | /**************************** ASHL ******************************/ |
| 1511 | 1592 | |
| 1512 | | static void ashl(asap_state *asap) |
| 1593 | void asap_device::ashl() |
| 1513 | 1594 | { |
| 1514 | | UINT32 src2 = SRC2VAL(asap); |
| 1515 | | DSTVAL(asap) = (src2 < 32) ? (SRC1VAL(asap) << src2) : 0; |
| 1595 | UINT32 src2 = SRC2VAL; |
| 1596 | DSTVAL = (src2 < 32) ? (SRC1VAL << src2) : 0; |
| 1516 | 1597 | } |
| 1517 | 1598 | |
| 1518 | | static void ashl_c(asap_state *asap) |
| 1599 | void asap_device::ashl_c() |
| 1519 | 1600 | { |
| 1520 | | UINT32 src2 = SRC2VAL(asap); |
| 1521 | | asap->cflag = asap->vflag = 0; |
| 1601 | UINT32 src2 = SRC2VAL; |
| 1602 | m_cflag = m_vflag = 0; |
| 1522 | 1603 | if (src2 < 32) |
| 1523 | 1604 | { |
| 1524 | | UINT32 src1 = SRC1VAL(asap); |
| 1605 | UINT32 src1 = SRC1VAL; |
| 1525 | 1606 | UINT32 dst = src1 << src2; |
| 1526 | | SET_ZN(asap, dst); |
| 1607 | SET_ZN(dst); |
| 1527 | 1608 | if (src2 != 0) |
| 1528 | 1609 | { |
| 1529 | 1610 | src1 = (INT32)src1 >> (32 - src2); |
| 1530 | | asap->cflag = src1 & PS_CFLAG; |
| 1531 | | asap->vflag = (src1 != ((INT32)dst >> 31)) << 31; |
| 1611 | m_cflag = src1 & PS_CFLAG; |
| 1612 | m_vflag = (src1 != ((INT32)dst >> 31)) << 31; |
| 1532 | 1613 | } |
| 1533 | | DSTVAL(asap) = dst; |
| 1614 | DSTVAL = dst; |
| 1534 | 1615 | } |
| 1535 | 1616 | else |
| 1536 | 1617 | { |
| 1537 | | SET_ZN(asap, 0); |
| 1538 | | DSTVAL(asap) = 0; |
| 1618 | SET_ZN(0); |
| 1619 | DSTVAL = 0; |
| 1539 | 1620 | } |
| 1540 | 1621 | } |
| 1541 | 1622 | |
| 1542 | | static void ashl_c0(asap_state *asap) |
| 1623 | void asap_device::ashl_c0() |
| 1543 | 1624 | { |
| 1544 | | UINT32 src2 = SRC2VAL(asap); |
| 1545 | | asap->cflag = asap->vflag = 0; |
| 1625 | UINT32 src2 = SRC2VAL; |
| 1626 | m_cflag = m_vflag = 0; |
| 1546 | 1627 | if (src2 < 32) |
| 1547 | 1628 | { |
| 1548 | | UINT32 src1 = SRC1VAL(asap); |
| 1629 | UINT32 src1 = SRC1VAL; |
| 1549 | 1630 | UINT32 dst = src1 << src2; |
| 1550 | | SET_ZN(asap, dst); |
| 1631 | SET_ZN(dst); |
| 1551 | 1632 | if (src2 != 0) |
| 1552 | 1633 | { |
| 1553 | 1634 | src1 = (INT32)src1 >> (32 - src2); |
| 1554 | | asap->cflag = src1 & PS_CFLAG; |
| 1555 | | asap->vflag = (src1 != ((INT32)dst >> 31)) << 31; |
| 1635 | m_cflag = src1 & PS_CFLAG; |
| 1636 | m_vflag = (src1 != ((INT32)dst >> 31)) << 31; |
| 1556 | 1637 | } |
| 1557 | 1638 | } |
| 1558 | 1639 | else |
| 1559 | | SET_ZN(asap, 0); |
| 1640 | SET_ZN(0); |
| 1560 | 1641 | } |
| 1561 | 1642 | |
| 1562 | 1643 | /**************************** ROTL ******************************/ |
| 1563 | 1644 | |
| 1564 | | static void rotl(asap_state *asap) |
| 1645 | void asap_device::rotl() |
| 1565 | 1646 | { |
| 1566 | | UINT32 src1 = SRC1VAL(asap); |
| 1567 | | UINT32 src2 = SRC2VAL(asap) & 31; |
| 1568 | | DSTVAL(asap) = (src1 << src2) | (src1 >> (32 - src2)); |
| 1647 | UINT32 src1 = SRC1VAL; |
| 1648 | UINT32 src2 = SRC2VAL & 31; |
| 1649 | DSTVAL = (src1 << src2) | (src1 >> (32 - src2)); |
| 1569 | 1650 | } |
| 1570 | 1651 | |
| 1571 | | static void rotl_c(asap_state *asap) |
| 1652 | void asap_device::rotl_c() |
| 1572 | 1653 | { |
| 1573 | | UINT32 src1 = SRC1VAL(asap); |
| 1574 | | UINT32 src2 = SRC2VAL(asap) & 31; |
| 1654 | UINT32 src1 = SRC1VAL; |
| 1655 | UINT32 src2 = SRC2VAL & 31; |
| 1575 | 1656 | UINT32 dst = (src1 << src2) | (src1 >> (32 - src2)); |
| 1576 | | SET_ZN(asap, dst); |
| 1577 | | DSTVAL(asap) = dst; |
| 1657 | SET_ZN(dst); |
| 1658 | DSTVAL = dst; |
| 1578 | 1659 | } |
| 1579 | 1660 | |
| 1580 | | static void rotl_c0(asap_state *asap) |
| 1661 | void asap_device::rotl_c0() |
| 1581 | 1662 | { |
| 1582 | | UINT32 src1 = SRC1VAL(asap); |
| 1583 | | UINT32 src2 = SRC2VAL(asap) & 31; |
| 1663 | UINT32 src1 = SRC1VAL; |
| 1664 | UINT32 src2 = SRC2VAL & 31; |
| 1584 | 1665 | UINT32 dst = (src1 << src2) | (src1 >> (32 - src2)); |
| 1585 | | SET_ZN(asap, dst); |
| 1666 | SET_ZN(dst); |
| 1586 | 1667 | } |
| 1587 | 1668 | |
| 1588 | 1669 | /**************************** GETPS ******************************/ |
| 1589 | 1670 | |
| 1590 | | static void getps(asap_state *asap) |
| 1671 | void asap_device::getps() |
| 1591 | 1672 | { |
| 1592 | | DSTVAL(asap) = GET_FLAGS(asap); |
| 1673 | DSTVAL = GET_FLAGS(); |
| 1593 | 1674 | } |
| 1594 | 1675 | |
| 1595 | 1676 | /**************************** PUTPS ******************************/ |
| 1596 | 1677 | |
| 1597 | | static void putps(asap_state *asap) |
| 1678 | void asap_device::putps() |
| 1598 | 1679 | { |
| 1599 | | UINT32 src2 = SRC2VAL(asap) & 0x3f; |
| 1600 | | SET_FLAGS(asap, src2); |
| 1601 | | check_irqs(asap); |
| 1680 | UINT32 src2 = SRC2VAL & 0x3f; |
| 1681 | SET_FLAGS(src2); |
| 1682 | check_irqs(); |
| 1602 | 1683 | } |
| 1603 | 1684 | |
| 1604 | 1685 | /**************************** JSR ******************************/ |
| 1605 | 1686 | |
| 1606 | | static void jsr(asap_state *asap) |
| 1687 | void asap_device::jsr() |
| 1607 | 1688 | { |
| 1608 | | DSTVAL(asap) = asap->pc + 4; |
| 1609 | | asap->nextpc = SRC1VAL(asap) + (SRC2VAL(asap) << 2); |
| 1689 | DSTVAL = m_pc + 4; |
| 1690 | m_nextpc = SRC1VAL + (SRC2VAL << 2); |
| 1610 | 1691 | |
| 1611 | | fetch_instruction(asap); |
| 1612 | | asap->pc = asap->nextpc; |
| 1613 | | asap->nextpc = ~0; |
| 1692 | fetch_instruction(); |
| 1693 | m_pc = m_nextpc; |
| 1694 | m_nextpc = ~0; |
| 1614 | 1695 | |
| 1615 | | execute_instruction(asap); |
| 1616 | | asap->icount--; |
| 1696 | execute_instruction(); |
| 1697 | m_icount--; |
| 1617 | 1698 | } |
| 1618 | 1699 | |
| 1619 | | static void jsr_0(asap_state *asap) |
| 1700 | void asap_device::jsr_0() |
| 1620 | 1701 | { |
| 1621 | | asap->nextpc = SRC1VAL(asap) + (SRC2VAL(asap) << 2); |
| 1702 | m_nextpc = SRC1VAL + (SRC2VAL << 2); |
| 1622 | 1703 | |
| 1623 | | fetch_instruction(asap); |
| 1624 | | asap->pc = asap->nextpc; |
| 1625 | | asap->nextpc = ~0; |
| 1704 | fetch_instruction(); |
| 1705 | m_pc = m_nextpc; |
| 1706 | m_nextpc = ~0; |
| 1626 | 1707 | |
| 1627 | | execute_instruction(asap); |
| 1628 | | asap->icount--; |
| 1708 | execute_instruction(); |
| 1709 | m_icount--; |
| 1629 | 1710 | } |
| 1630 | 1711 | |
| 1631 | | static void jsr_c(asap_state *asap) |
| 1712 | void asap_device::jsr_c() |
| 1632 | 1713 | { |
| 1633 | | DSTVAL(asap) = asap->pc + 4; |
| 1634 | | asap->nextpc = SRC1VAL(asap) + (SRC2VAL(asap) << 2); |
| 1635 | | asap->iflag = asap->pflag; |
| 1714 | DSTVAL = m_pc + 4; |
| 1715 | m_nextpc = SRC1VAL + (SRC2VAL << 2); |
| 1716 | m_iflag = m_pflag; |
| 1636 | 1717 | |
| 1637 | | fetch_instruction(asap); |
| 1638 | | asap->pc = asap->nextpc; |
| 1639 | | asap->nextpc = ~0; |
| 1718 | fetch_instruction(); |
| 1719 | m_pc = m_nextpc; |
| 1720 | m_nextpc = ~0; |
| 1640 | 1721 | |
| 1641 | | execute_instruction(asap); |
| 1642 | | asap->icount--; |
| 1643 | | check_irqs(asap); |
| 1722 | execute_instruction(); |
| 1723 | m_icount--; |
| 1724 | check_irqs(); |
| 1644 | 1725 | } |
| 1645 | 1726 | |
| 1646 | | static void jsr_c0(asap_state *asap) |
| 1727 | void asap_device::jsr_c0() |
| 1647 | 1728 | { |
| 1648 | | asap->nextpc = SRC1VAL(asap) + (SRC2VAL(asap) << 2); |
| 1649 | | asap->iflag = asap->pflag; |
| 1729 | m_nextpc = SRC1VAL + (SRC2VAL << 2); |
| 1730 | m_iflag = m_pflag; |
| 1650 | 1731 | |
| 1651 | | fetch_instruction(asap); |
| 1652 | | asap->pc = asap->nextpc; |
| 1653 | | asap->nextpc = ~0; |
| 1732 | fetch_instruction(); |
| 1733 | m_pc = m_nextpc; |
| 1734 | m_nextpc = ~0; |
| 1654 | 1735 | |
| 1655 | | execute_instruction(asap); |
| 1656 | | asap->icount--; |
| 1657 | | check_irqs(asap); |
| 1736 | execute_instruction(); |
| 1737 | m_icount--; |
| 1738 | check_irqs(); |
| 1658 | 1739 | } |
| 1659 | 1740 | |
| 1660 | 1741 | /**************************** TRAP F ******************************/ |
| 1661 | 1742 | |
| 1662 | | static void trapf(asap_state *asap) |
| 1743 | void asap_device::trapf() |
| 1663 | 1744 | { |
| 1664 | | generate_exception(asap, EXCEPTION_TRAPF); |
| 1745 | generate_exception(EXCEPTION_TRAPF); |
| 1665 | 1746 | } |
| 1666 | 1747 | |
| 1667 | 1748 | |
| 1668 | | /************************************************************************** |
| 1669 | | * Generic set_info |
| 1670 | | **************************************************************************/ |
| 1671 | 1749 | |
| 1672 | | static CPU_SET_INFO( asap ) |
| 1673 | | { |
| 1674 | | asap_state *asap = get_safe_token(device); |
| 1675 | | |
| 1676 | | switch (state) |
| 1677 | | { |
| 1678 | | /* --- the following bits of info are set as 64-bit signed integers --- */ |
| 1679 | | case CPUINFO_INT_INPUT_STATE + ASAP_IRQ0: set_irq_line(asap, ASAP_IRQ0, info->i); break; |
| 1680 | | |
| 1681 | | case CPUINFO_INT_PC: |
| 1682 | | case CPUINFO_INT_REGISTER + ASAP_PC: asap->pc = info->i; break; |
| 1683 | | case CPUINFO_INT_REGISTER + ASAP_PS: SET_FLAGS(asap, info->i); break; |
| 1684 | | |
| 1685 | | case CPUINFO_INT_REGISTER + ASAP_R0: asap->src2val[REGBASE + 0] = info->i; break; |
| 1686 | | case CPUINFO_INT_REGISTER + ASAP_R1: asap->src2val[REGBASE + 1] = info->i; break; |
| 1687 | | case CPUINFO_INT_REGISTER + ASAP_R2: asap->src2val[REGBASE + 2] = info->i; break; |
| 1688 | | case CPUINFO_INT_REGISTER + ASAP_R3: asap->src2val[REGBASE + 3] = info->i; break; |
| 1689 | | case CPUINFO_INT_REGISTER + ASAP_R4: asap->src2val[REGBASE + 4] = info->i; break; |
| 1690 | | case CPUINFO_INT_REGISTER + ASAP_R5: asap->src2val[REGBASE + 5] = info->i; break; |
| 1691 | | case CPUINFO_INT_REGISTER + ASAP_R6: asap->src2val[REGBASE + 6] = info->i; break; |
| 1692 | | case CPUINFO_INT_REGISTER + ASAP_R7: asap->src2val[REGBASE + 7] = info->i; break; |
| 1693 | | case CPUINFO_INT_REGISTER + ASAP_R8: asap->src2val[REGBASE + 8] = info->i; break; |
| 1694 | | case CPUINFO_INT_REGISTER + ASAP_R9: asap->src2val[REGBASE + 9] = info->i; break; |
| 1695 | | case CPUINFO_INT_REGISTER + ASAP_R10: asap->src2val[REGBASE + 10] = info->i; break; |
| 1696 | | case CPUINFO_INT_REGISTER + ASAP_R11: asap->src2val[REGBASE + 11] = info->i; break; |
| 1697 | | case CPUINFO_INT_REGISTER + ASAP_R12: asap->src2val[REGBASE + 12] = info->i; break; |
| 1698 | | case CPUINFO_INT_REGISTER + ASAP_R13: asap->src2val[REGBASE + 13] = info->i; break; |
| 1699 | | case CPUINFO_INT_REGISTER + ASAP_R14: asap->src2val[REGBASE + 14] = info->i; break; |
| 1700 | | case CPUINFO_INT_REGISTER + ASAP_R15: asap->src2val[REGBASE + 15] = info->i; break; |
| 1701 | | case CPUINFO_INT_REGISTER + ASAP_R16: asap->src2val[REGBASE + 16] = info->i; break; |
| 1702 | | case CPUINFO_INT_REGISTER + ASAP_R17: asap->src2val[REGBASE + 17] = info->i; break; |
| 1703 | | case CPUINFO_INT_REGISTER + ASAP_R18: asap->src2val[REGBASE + 18] = info->i; break; |
| 1704 | | case CPUINFO_INT_REGISTER + ASAP_R19: asap->src2val[REGBASE + 19] = info->i; break; |
| 1705 | | case CPUINFO_INT_REGISTER + ASAP_R20: asap->src2val[REGBASE + 20] = info->i; break; |
| 1706 | | case CPUINFO_INT_REGISTER + ASAP_R21: asap->src2val[REGBASE + 21] = info->i; break; |
| 1707 | | case CPUINFO_INT_REGISTER + ASAP_R22: asap->src2val[REGBASE + 22] = info->i; break; |
| 1708 | | case CPUINFO_INT_REGISTER + ASAP_R23: asap->src2val[REGBASE + 23] = info->i; break; |
| 1709 | | case CPUINFO_INT_REGISTER + ASAP_R24: asap->src2val[REGBASE + 24] = info->i; break; |
| 1710 | | case CPUINFO_INT_REGISTER + ASAP_R25: asap->src2val[REGBASE + 25] = info->i; break; |
| 1711 | | case CPUINFO_INT_REGISTER + ASAP_R26: asap->src2val[REGBASE + 26] = info->i; break; |
| 1712 | | case CPUINFO_INT_REGISTER + ASAP_R27: asap->src2val[REGBASE + 27] = info->i; break; |
| 1713 | | case CPUINFO_INT_REGISTER + ASAP_R28: asap->src2val[REGBASE + 28] = info->i; break; |
| 1714 | | case CPUINFO_INT_REGISTER + ASAP_R29: asap->src2val[REGBASE + 29] = info->i; break; |
| 1715 | | case CPUINFO_INT_REGISTER + ASAP_R30: asap->src2val[REGBASE + 30] = info->i; break; |
| 1716 | | case CPUINFO_INT_SP: |
| 1717 | | case CPUINFO_INT_REGISTER + ASAP_R31: asap->src2val[REGBASE + 31] = info->i; break; |
| 1718 | | } |
| 1719 | | } |
| 1720 | | |
| 1721 | | |
| 1722 | | |
| 1723 | | /************************************************************************** |
| 1724 | | * Generic get_info |
| 1725 | | **************************************************************************/ |
| 1726 | | |
| 1727 | | CPU_GET_INFO( asap ) |
| 1728 | | { |
| 1729 | | asap_state *asap = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; |
| 1730 | | |
| 1731 | | switch (state) |
| 1732 | | { |
| 1733 | | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 1734 | | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(asap_state); break; |
| 1735 | | case CPUINFO_INT_INPUT_LINES: info->i = 1; break; |
| 1736 | | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; |
| 1737 | | case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; |
| 1738 | | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; |
| 1739 | | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; |
| 1740 | | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break; |
| 1741 | | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 12; break; |
| 1742 | | case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; |
| 1743 | | case CPUINFO_INT_MAX_CYCLES: info->i = 2; break; |
| 1744 | | |
| 1745 | | case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; |
| 1746 | | case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; |
| 1747 | | case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; |
| 1748 | | case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 1749 | | case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 1750 | | case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 1751 | | case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break; |
| 1752 | | case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break; |
| 1753 | | case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; |
| 1754 | | |
| 1755 | | case CPUINFO_INT_INPUT_STATE + ASAP_IRQ0: info->i = asap->irq_state; break; |
| 1756 | | |
| 1757 | | case CPUINFO_INT_PREVIOUSPC: info->i = asap->ppc; break; |
| 1758 | | |
| 1759 | | case CPUINFO_INT_PC: |
| 1760 | | case CPUINFO_INT_REGISTER + ASAP_PC: info->i = asap->pc; break; |
| 1761 | | case CPUINFO_INT_REGISTER + ASAP_PS: info->i = GET_FLAGS(asap); break; |
| 1762 | | |
| 1763 | | case CPUINFO_INT_REGISTER + ASAP_R0: info->i = asap->src2val[REGBASE + 0]; break; |
| 1764 | | case CPUINFO_INT_REGISTER + ASAP_R1: info->i = asap->src2val[REGBASE + 1]; break; |
| 1765 | | case CPUINFO_INT_REGISTER + ASAP_R2: info->i = asap->src2val[REGBASE + 2]; break; |
| 1766 | | case CPUINFO_INT_REGISTER + ASAP_R3: info->i = asap->src2val[REGBASE + 3]; break; |
| 1767 | | case CPUINFO_INT_REGISTER + ASAP_R4: info->i = asap->src2val[REGBASE + 4]; break; |
| 1768 | | case CPUINFO_INT_REGISTER + ASAP_R5: info->i = asap->src2val[REGBASE + 5]; break; |
| 1769 | | case CPUINFO_INT_REGISTER + ASAP_R6: info->i = asap->src2val[REGBASE + 6]; break; |
| 1770 | | case CPUINFO_INT_REGISTER + ASAP_R7: info->i = asap->src2val[REGBASE + 7]; break; |
| 1771 | | case CPUINFO_INT_REGISTER + ASAP_R8: info->i = asap->src2val[REGBASE + 8]; break; |
| 1772 | | case CPUINFO_INT_REGISTER + ASAP_R9: info->i = asap->src2val[REGBASE + 9]; break; |
| 1773 | | case CPUINFO_INT_REGISTER + ASAP_R10: info->i = asap->src2val[REGBASE + 10]; break; |
| 1774 | | case CPUINFO_INT_REGISTER + ASAP_R11: info->i = asap->src2val[REGBASE + 11]; break; |
| 1775 | | case CPUINFO_INT_REGISTER + ASAP_R12: info->i = asap->src2val[REGBASE + 12]; break; |
| 1776 | | case CPUINFO_INT_REGISTER + ASAP_R13: info->i = asap->src2val[REGBASE + 13]; break; |
| 1777 | | case CPUINFO_INT_REGISTER + ASAP_R14: info->i = asap->src2val[REGBASE + 14]; break; |
| 1778 | | case CPUINFO_INT_REGISTER + ASAP_R15: info->i = asap->src2val[REGBASE + 15]; break; |
| 1779 | | case CPUINFO_INT_REGISTER + ASAP_R16: info->i = asap->src2val[REGBASE + 16]; break; |
| 1780 | | case CPUINFO_INT_REGISTER + ASAP_R17: info->i = asap->src2val[REGBASE + 17]; break; |
| 1781 | | case CPUINFO_INT_REGISTER + ASAP_R18: info->i = asap->src2val[REGBASE + 18]; break; |
| 1782 | | case CPUINFO_INT_REGISTER + ASAP_R19: info->i = asap->src2val[REGBASE + 19]; break; |
| 1783 | | case CPUINFO_INT_REGISTER + ASAP_R20: info->i = asap->src2val[REGBASE + 20]; break; |
| 1784 | | case CPUINFO_INT_REGISTER + ASAP_R21: info->i = asap->src2val[REGBASE + 21]; break; |
| 1785 | | case CPUINFO_INT_REGISTER + ASAP_R22: info->i = asap->src2val[REGBASE + 22]; break; |
| 1786 | | case CPUINFO_INT_REGISTER + ASAP_R23: info->i = asap->src2val[REGBASE + 23]; break; |
| 1787 | | case CPUINFO_INT_REGISTER + ASAP_R24: info->i = asap->src2val[REGBASE + 24]; break; |
| 1788 | | case CPUINFO_INT_REGISTER + ASAP_R25: info->i = asap->src2val[REGBASE + 25]; break; |
| 1789 | | case CPUINFO_INT_REGISTER + ASAP_R26: info->i = asap->src2val[REGBASE + 26]; break; |
| 1790 | | case CPUINFO_INT_REGISTER + ASAP_R27: info->i = asap->src2val[REGBASE + 27]; break; |
| 1791 | | case CPUINFO_INT_REGISTER + ASAP_R28: info->i = asap->src2val[REGBASE + 28]; break; |
| 1792 | | case CPUINFO_INT_REGISTER + ASAP_R29: info->i = asap->src2val[REGBASE + 29]; break; |
| 1793 | | case CPUINFO_INT_REGISTER + ASAP_R30: info->i = asap->src2val[REGBASE + 30]; break; |
| 1794 | | case CPUINFO_INT_REGISTER + ASAP_R31: info->i = asap->src2val[REGBASE + 31]; break; |
| 1795 | | |
| 1796 | | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 1797 | | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(asap); break; |
| 1798 | | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(asap); break; |
| 1799 | | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(asap); break; |
| 1800 | | case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(asap); break; |
| 1801 | | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(asap); break; |
| 1802 | | case CPUINFO_FCT_BURN: info->burn = NULL; break; |
| 1803 | | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(asap); break; |
| 1804 | | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &asap->icount; break; |
| 1805 | | |
| 1806 | | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 1807 | | case DEVINFO_STR_NAME: strcpy(info->s, "ASAP"); break; |
| 1808 | | case DEVINFO_STR_FAMILY: strcpy(info->s, "Atari ASAP"); break; |
| 1809 | | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; |
| 1810 | | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 1811 | | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Aaron Giles"); break; |
| 1812 | | |
| 1813 | | case CPUINFO_STR_FLAGS: strcpy(info->s, " "); break; |
| 1814 | | |
| 1815 | | case CPUINFO_STR_REGISTER + ASAP_PC: sprintf(info->s, "PC: %08X", asap->pc); break; |
| 1816 | | case CPUINFO_STR_REGISTER + ASAP_PS: sprintf(info->s, "PS: %08X", GET_FLAGS(asap)); break; |
| 1817 | | |
| 1818 | | case CPUINFO_STR_REGISTER + ASAP_R0: sprintf(info->s, "R0: %08X", asap->src2val[REGBASE + 0]); break; |
| 1819 | | case CPUINFO_STR_REGISTER + ASAP_R1: sprintf(info->s, "R1: %08X", asap->src2val[REGBASE + 1]); break; |
| 1820 | | case CPUINFO_STR_REGISTER + ASAP_R2: sprintf(info->s, "R2: %08X", asap->src2val[REGBASE + 2]); break; |
| 1821 | | case CPUINFO_STR_REGISTER + ASAP_R3: sprintf(info->s, "R3: %08X", asap->src2val[REGBASE + 3]); break; |
| 1822 | | case CPUINFO_STR_REGISTER + ASAP_R4: sprintf(info->s, "R4: %08X", asap->src2val[REGBASE + 4]); break; |
| 1823 | | case CPUINFO_STR_REGISTER + ASAP_R5: sprintf(info->s, "R5: %08X", asap->src2val[REGBASE + 5]); break; |
| 1824 | | case CPUINFO_STR_REGISTER + ASAP_R6: sprintf(info->s, "R6: %08X", asap->src2val[REGBASE + 6]); break; |
| 1825 | | case CPUINFO_STR_REGISTER + ASAP_R7: sprintf(info->s, "R7: %08X", asap->src2val[REGBASE + 7]); break; |
| 1826 | | case CPUINFO_STR_REGISTER + ASAP_R8: sprintf(info->s, "R8: %08X", asap->src2val[REGBASE + 8]); break; |
| 1827 | | case CPUINFO_STR_REGISTER + ASAP_R9: sprintf(info->s, "R9: %08X", asap->src2val[REGBASE + 9]); break; |
| 1828 | | case CPUINFO_STR_REGISTER + ASAP_R10: sprintf(info->s, "R10:%08X", asap->src2val[REGBASE + 10]); break; |
| 1829 | | case CPUINFO_STR_REGISTER + ASAP_R11: sprintf(info->s, "R11:%08X", asap->src2val[REGBASE + 11]); break; |
| 1830 | | case CPUINFO_STR_REGISTER + ASAP_R12: sprintf(info->s, "R12:%08X", asap->src2val[REGBASE + 12]); break; |
| 1831 | | case CPUINFO_STR_REGISTER + ASAP_R13: sprintf(info->s, "R13:%08X", asap->src2val[REGBASE + 13]); break; |
| 1832 | | case CPUINFO_STR_REGISTER + ASAP_R14: sprintf(info->s, "R14:%08X", asap->src2val[REGBASE + 14]); break; |
| 1833 | | case CPUINFO_STR_REGISTER + ASAP_R15: sprintf(info->s, "R15:%08X", asap->src2val[REGBASE + 15]); break; |
| 1834 | | case CPUINFO_STR_REGISTER + ASAP_R16: sprintf(info->s, "R16:%08X", asap->src2val[REGBASE + 16]); break; |
| 1835 | | case CPUINFO_STR_REGISTER + ASAP_R17: sprintf(info->s, "R17:%08X", asap->src2val[REGBASE + 17]); break; |
| 1836 | | case CPUINFO_STR_REGISTER + ASAP_R18: sprintf(info->s, "R18:%08X", asap->src2val[REGBASE + 18]); break; |
| 1837 | | case CPUINFO_STR_REGISTER + ASAP_R19: sprintf(info->s, "R19:%08X", asap->src2val[REGBASE + 19]); break; |
| 1838 | | case CPUINFO_STR_REGISTER + ASAP_R20: sprintf(info->s, "R20:%08X", asap->src2val[REGBASE + 20]); break; |
| 1839 | | case CPUINFO_STR_REGISTER + ASAP_R21: sprintf(info->s, "R21:%08X", asap->src2val[REGBASE + 21]); break; |
| 1840 | | case CPUINFO_STR_REGISTER + ASAP_R22: sprintf(info->s, "R22:%08X", asap->src2val[REGBASE + 22]); break; |
| 1841 | | case CPUINFO_STR_REGISTER + ASAP_R23: sprintf(info->s, "R23:%08X", asap->src2val[REGBASE + 23]); break; |
| 1842 | | case CPUINFO_STR_REGISTER + ASAP_R24: sprintf(info->s, "R24:%08X", asap->src2val[REGBASE + 24]); break; |
| 1843 | | case CPUINFO_STR_REGISTER + ASAP_R25: sprintf(info->s, "R25:%08X", asap->src2val[REGBASE + 25]); break; |
| 1844 | | case CPUINFO_STR_REGISTER + ASAP_R26: sprintf(info->s, "R26:%08X", asap->src2val[REGBASE + 26]); break; |
| 1845 | | case CPUINFO_STR_REGISTER + ASAP_R27: sprintf(info->s, "R27:%08X", asap->src2val[REGBASE + 27]); break; |
| 1846 | | case CPUINFO_STR_REGISTER + ASAP_R28: sprintf(info->s, "R28:%08X", asap->src2val[REGBASE + 28]); break; |
| 1847 | | case CPUINFO_STR_REGISTER + ASAP_R29: sprintf(info->s, "R29:%08X", asap->src2val[REGBASE + 29]); break; |
| 1848 | | case CPUINFO_STR_REGISTER + ASAP_R30: sprintf(info->s, "R30:%08X", asap->src2val[REGBASE + 30]); break; |
| 1849 | | case CPUINFO_STR_REGISTER + ASAP_R31: sprintf(info->s, "R31:%08X", asap->src2val[REGBASE + 31]); break; |
| 1850 | | } |
| 1851 | | } |
| 1852 | | |
| 1853 | | DEFINE_LEGACY_CPU_DEVICE(ASAP, asap); |
| 1750 | const device_type ASAP = asap_device_config::static_alloc_device_config; |