trunk/src/emu/cpu/mcs96/i8x9x.c
| r19633 | r19634 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | i8x9x.h |
| 4 | |
| 5 | MCS96, 8x9x branch, the original version |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Olivier Galibert |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #include "emu.h" |
| 41 | #include "i8x9x.h" |
| 42 | |
| 43 | i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 44 | mcs96_device(mconfig, type, name, tag, owner, clock, 8), |
| 45 | io_config("io", ENDIANNESS_LITTLE, 16, 16, -1) |
| 46 | { |
| 47 | } |
| 48 | |
| 49 | offs_t i8x9x_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 50 | { |
| 51 | return disasm_generic(buffer, pc, oprom, opram, options, disasm_entries); |
| 52 | } |
| 53 | |
| 54 | const address_space_config *i8x9x_device::memory_space_config(address_spacenum spacenum) const |
| 55 | { |
| 56 | return spacenum == AS_PROGRAM ? &program_config : spacenum == AS_IO ? &io_config : NULL; |
| 57 | } |
| 58 | |
| 59 | void i8x9x_device::device_start() |
| 60 | { |
| 61 | mcs96_device::device_start(); |
| 62 | io = &space(AS_IO); |
| 63 | cycles_scaling = 3; |
| 64 | } |
| 65 | |
| 66 | void i8x9x_device::device_reset() |
| 67 | { |
| 68 | mcs96_device::device_reset(); |
| 69 | memset(hso_info, 0, sizeof(hso_info)); |
| 70 | memset(&hso_cam_hold, 0, sizeof(hso_cam_hold)); |
| 71 | hso_command = 0; |
| 72 | hso_time = 0; |
| 73 | base_timer2 = 0; |
| 74 | ios0 = ios1 = ioc0 = ioc1 = 0x00; |
| 75 | ad_result = 0; |
| 76 | ad_done = 0; |
| 77 | sp_stat = 0; |
| 78 | } |
| 79 | |
| 80 | void i8x9x_device::commit_hso_cam() |
| 81 | { |
| 82 | for(int i=0; i<8; i++) |
| 83 | if(!hso_info[i].active) { |
| 84 | if(hso_command != 0x18) |
| 85 | logerror("%s: hso cam %02x %04x in slot %d (%04x)\n", tag(), hso_command, hso_time, i, PPC); |
| 86 | hso_info[i].active = true; |
| 87 | hso_info[i].command = hso_command; |
| 88 | hso_info[i].time = hso_time; |
| 89 | internal_update(get_cycle()); |
| 90 | return; |
| 91 | } |
| 92 | hso_cam_hold.active = true; |
| 93 | hso_cam_hold.command = hso_command; |
| 94 | hso_cam_hold.time = hso_time; |
| 95 | } |
| 96 | |
| 97 | void i8x9x_device::ad_start(UINT64 current_time) |
| 98 | { |
| 99 | ad_result = (io->read_word(2*((ad_command & 7) + A0)) << 6) | 8 | (ad_command & 7); |
| 100 | ad_done = current_time + 88; |
| 101 | internal_update(current_time); |
| 102 | } |
| 103 | |
| 104 | void i8x9x_device::serial_send(UINT8 data) |
| 105 | { |
| 106 | serial_send_buf = data; |
| 107 | serial_send_timer = get_cycle() + 9600; |
| 108 | } |
| 109 | |
| 110 | void i8x9x_device::serial_send_done() |
| 111 | { |
| 112 | serial_send_timer = 0; |
| 113 | io->write_word(SERIAL*2, serial_send_buf); |
| 114 | pending_irq |= IRQ_SERIAL; |
| 115 | sp_stat |= 0x20; |
| 116 | check_irq(); |
| 117 | } |
| 118 | |
| 119 | void i8x9x_device::io_w8(UINT8 adr, UINT8 data) |
| 120 | { |
| 121 | switch(adr) { |
| 122 | case 0x02: |
| 123 | ad_command = data; |
| 124 | if(ad_command & 8) |
| 125 | ad_start(get_cycle()); |
| 126 | break; |
| 127 | case 0x03: |
| 128 | logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC); |
| 129 | break; |
| 130 | case 0x04: |
| 131 | hso_time = (hso_time & 0xff00) | data; |
| 132 | break; |
| 133 | case 0x05: |
| 134 | hso_time = (hso_time & 0x00ff) | (data << 8); |
| 135 | commit_hso_cam(); |
| 136 | break; |
| 137 | case 0x06: |
| 138 | hso_command = data; |
| 139 | break; |
| 140 | case 0x07: |
| 141 | logerror("%s: sbuf %02x (%04x)\n", tag(), data, PPC); |
| 142 | serial_send(data); |
| 143 | break; |
| 144 | case 0x08: |
| 145 | PSW = (PSW & 0xff00) | data; |
| 146 | check_irq(); |
| 147 | break; |
| 148 | case 0x09: |
| 149 | pending_irq = data; |
| 150 | logerror("%s: int_pending %02x (%04x)\n", tag(), data, PPC); |
| 151 | break; |
| 152 | case 0x0a: |
| 153 | logerror("%s: watchdog %02x (%04x)\n", tag(), data, PPC); |
| 154 | break; |
| 155 | case 0x0e: |
| 156 | logerror("%s: baud rate %02x (%04x)\n", tag(), data, PPC); |
| 157 | break; |
| 158 | case 0x0f: |
| 159 | logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC); |
| 160 | break; |
| 161 | case 0x10: |
| 162 | logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC); |
| 163 | break; |
| 164 | case 0x11: |
| 165 | logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC); |
| 166 | break; |
| 167 | case 0x15: |
| 168 | logerror("%s: ioc0 %02x (%04x)\n", tag(), data, PPC); |
| 169 | ioc0 = data; |
| 170 | break; |
| 171 | case 0x16: |
| 172 | logerror("%s: ioc1 %02x (%04x)\n", tag(), data, PPC); |
| 173 | ioc1 = data; |
| 174 | break; |
| 175 | case 0x17: |
| 176 | logerror("%s: pwm control %02x (%04x)\n", tag(), data, PPC); |
| 177 | break; |
| 178 | } |
| 179 | return; |
| 180 | } |
| 181 | |
| 182 | void i8x9x_device::io_w16(UINT8 adr, UINT16 data) |
| 183 | { |
| 184 | switch(adr) { |
| 185 | case 0: |
| 186 | break; |
| 187 | case 4: |
| 188 | hso_time = data; |
| 189 | commit_hso_cam(); |
| 190 | break; |
| 191 | default: |
| 192 | io_w8(adr, data); |
| 193 | io_w8(adr+1, data>>8); |
| 194 | break; |
| 195 | } |
| 196 | return; |
| 197 | } |
| 198 | |
| 199 | UINT8 i8x9x_device::io_r8(UINT8 adr) |
| 200 | { |
| 201 | switch(adr) { |
| 202 | case 0x00: |
| 203 | return 0x00; |
| 204 | case 0x01: |
| 205 | return 0x00; |
| 206 | case 0x02: |
| 207 | return ad_result; |
| 208 | case 0x03: |
| 209 | return ad_result >> 8; |
| 210 | case 0x04: |
| 211 | logerror("%s: read hsi time l (%04x)\n", tag(), PPC); |
| 212 | return 0x00; |
| 213 | case 0x05: |
| 214 | logerror("%s: read hsi time h (%04x)\n", tag(), PPC); |
| 215 | return 0x00; |
| 216 | case 0x06: |
| 217 | logerror("%s: read hsi status (%04x)\n", tag(), PPC); |
| 218 | return 0x00; |
| 219 | case 0x07: |
| 220 | logerror("%s: read sbuf %02x (%04x)\n", tag(), sbuf, PPC); |
| 221 | return sbuf; |
| 222 | case 0x08: |
| 223 | return PSW; |
| 224 | case 0x09: |
| 225 | logerror("%s: read int pending (%04x)\n", tag(), PPC); |
| 226 | return pending_irq; |
| 227 | case 0x0a: |
| 228 | logerror("%s: read timer1 l (%04x)\n", tag(), PPC); |
| 229 | return timer_value(1, get_cycle()); |
| 230 | case 0x0b: |
| 231 | logerror("%s: read timer1 h (%04x)\n", tag(), PPC); |
| 232 | return timer_value(1, get_cycle()) >> 8; |
| 233 | case 0x0c: |
| 234 | logerror("%s: read timer2 l (%04x)\n", tag(), PPC); |
| 235 | return timer_value(2, get_cycle()); |
| 236 | case 0x0d: |
| 237 | logerror("%s: read timer2 h (%04x)\n", tag(), PPC); |
| 238 | return timer_value(2, get_cycle()) >> 8; |
| 239 | case 0x0e: |
| 240 | logerror("%s: read io port 0 (%04x)\n", tag(), PPC); |
| 241 | return 0x00; |
| 242 | case 0x0f: |
| 243 | logerror("%s: read io port 1 (%04x)\n", tag(), PPC); |
| 244 | return 0x00; |
| 245 | case 0x10: |
| 246 | logerror("%s: read io port 2 (%04x)\n", tag(), PPC); |
| 247 | return 0x00; |
| 248 | case 0x11: { |
| 249 | UINT8 res = sp_stat; |
| 250 | sp_stat &= 0x80; |
| 251 | logerror("%s: read sp stat %02x (%04x)\n", tag(), res, PPC); |
| 252 | return res; |
| 253 | } |
| 254 | case 0x15: |
| 255 | logerror("%s: read ios 0 %02x (%04x)\n", tag(), ios0, PPC); |
| 256 | return ios0; |
| 257 | case 0x16: { |
| 258 | UINT8 res = ios1; |
| 259 | ios1 = ios1 & 0xc0; |
| 260 | return res; |
| 261 | } |
| 262 | default: |
| 263 | logerror("%s: io_r8 %02x (%04x)\n", tag(), adr, PPC); |
| 264 | return 0x00; |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | UINT16 i8x9x_device::io_r16(UINT8 adr) |
| 269 | { |
| 270 | switch(adr) { |
| 271 | case 0x00: |
| 272 | return 0x0000; |
| 273 | case 0x02: |
| 274 | return ad_result; |
| 275 | case 0x04: |
| 276 | logerror("%s: read hsi time (%04x)\n", tag(), PPC); |
| 277 | return 0x0000; |
| 278 | case 0x0a: |
| 279 | return timer_value(1, get_cycle()); |
| 280 | case 0x0c: |
| 281 | logerror("%s: read timer2 (%04x)\n", tag(), PPC); |
| 282 | return timer_value(2, get_cycle()); |
| 283 | default: |
| 284 | return io_r8(adr) | (io_r8(adr+1) << 8); |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | void i8x9x_device::do_exec_partial() |
| 289 | { |
| 290 | } |
| 291 | |
| 292 | void i8x9x_device::serial_w(UINT8 val) |
| 293 | { |
| 294 | sbuf = val; |
| 295 | sp_stat |= 0x40; |
| 296 | pending_irq |= IRQ_SERIAL; |
| 297 | check_irq(); |
| 298 | } |
| 299 | |
| 300 | UINT16 i8x9x_device::timer_value(int timer, UINT64 current_time) const |
| 301 | { |
| 302 | if(timer == 2) |
| 303 | current_time -= base_timer2; |
| 304 | return current_time >> 3; |
| 305 | } |
| 306 | |
| 307 | UINT64 i8x9x_device::timer_time_until(int timer, UINT64 current_time, UINT16 timer_value) const |
| 308 | { |
| 309 | UINT64 timer_base = timer == 2 ? base_timer2 : 0; |
| 310 | UINT64 delta = (current_time - timer_base) >> 3; |
| 311 | UINT32 tdelta = UINT16(timer_value - delta); |
| 312 | if(!tdelta) |
| 313 | tdelta = 0x10000; |
| 314 | return timer_base + ((delta + tdelta) << 3); |
| 315 | } |
| 316 | |
| 317 | void i8x9x_device::trigger_cam(int id, UINT64 current_time) |
| 318 | { |
| 319 | hso_cam_entry &cam = hso_info[id]; |
| 320 | cam.active = false; |
| 321 | switch(cam.command & 0x0f) { |
| 322 | case 0x8: case 0x9: case 0xa: case 0xb: |
| 323 | ios1 |= 1 << (cam.command & 3); |
| 324 | pending_irq |= IRQ_SOFT; |
| 325 | check_irq(); |
| 326 | break; |
| 327 | |
| 328 | default: |
| 329 | logerror("%s: Action %x unimplemented\n", tag(), cam.command & 0x0f); |
| 330 | break; |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | void i8x9x_device::internal_update(UINT64 current_time) |
| 335 | { |
| 336 | UINT16 current_timer1 = timer_value(1, current_time); |
| 337 | UINT16 current_timer2 = timer_value(2, current_time); |
| 338 | |
| 339 | for(int i=0; i<8; i++) |
| 340 | if(hso_info[i].active) { |
| 341 | UINT8 cmd = hso_info[i].command; |
| 342 | UINT16 t = hso_info[i].time; |
| 343 | if(((cmd & 0x40) && t == current_timer2) || |
| 344 | (!(cmd & 0x40) && t == current_timer1)) { |
| 345 | if(cmd != 0x18) |
| 346 | logerror("%s: hso cam %02x %04x in slot %d triggered\n", |
| 347 | tag(), cmd, t, i); |
| 348 | trigger_cam(i, current_time); |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | if(current_time == ad_done) { |
| 353 | ad_done = 0; |
| 354 | ad_result &= ~8; |
| 355 | } |
| 356 | |
| 357 | if(current_time == serial_send_timer) |
| 358 | serial_send_done(); |
| 359 | |
| 360 | UINT64 event_time = 0; |
| 361 | for(int i=0; i<8; i++) { |
| 362 | if(!hso_info[i].active && hso_cam_hold.active) { |
| 363 | hso_info[i] = hso_cam_hold; |
| 364 | hso_cam_hold.active = false; |
| 365 | logerror("%s: hso cam %02x %04x in slot %d from hold\n", tag(), hso_cam_hold.command, hso_cam_hold.time, i); |
| 366 | } |
| 367 | if(hso_info[i].active) { |
| 368 | UINT64 new_time = timer_time_until(hso_info[i].command & 0x40 ? 2 : 1, current_time, hso_info[i].time); |
| 369 | if(!event_time || new_time < event_time) |
| 370 | event_time = new_time; |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | if(ad_done && ad_done < event_time) |
| 375 | event_time = ad_done; |
| 376 | |
| 377 | if(serial_send_timer && serial_send_timer < event_time) |
| 378 | event_time = serial_send_timer; |
| 379 | |
| 380 | recompute_bcount(event_time); |
| 381 | } |
| 382 | |
| 383 | c8095_device::c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 384 | i8x9x_device(mconfig, C8095, "C8095", tag, owner, clock) |
| 385 | { |
| 386 | } |
| 387 | |
| 388 | p8098_device::p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 389 | i8x9x_device(mconfig, P8098, "P8098", tag, owner, clock) |
| 390 | { |
| 391 | } |
| 392 | |
| 393 | const device_type C8095 = &device_creator<c8095_device>; |
| 394 | const device_type P8098 = &device_creator<p8098_device>; |
| 395 | |
| 396 | #include "cpu/mcs96/i8x9x.inc" |
trunk/src/emu/cpu/mcs96/i8xc196.c
| r19633 | r19634 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | i8xc196.h |
| 4 | |
| 5 | MCS96, c196 branch, the enhanced 16 bits bus version |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Olivier Galibert |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #include "emu.h" |
| 41 | #include "i8xc196.h" |
| 42 | |
| 43 | i8xc196_device::i8xc196_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 44 | mcs96_device(mconfig, type, name, tag, owner, clock, 16) |
| 45 | { |
| 46 | } |
| 47 | |
| 48 | offs_t i8xc196_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 49 | { |
| 50 | return disasm_generic(buffer, pc, oprom, opram, options, disasm_entries); |
| 51 | } |
| 52 | |
| 53 | void i8xc196_device::io_w8(UINT8 adr, UINT8 data) |
| 54 | { |
| 55 | switch(adr) { |
| 56 | case 0: |
| 57 | break; |
| 58 | case 1: |
| 59 | break; |
| 60 | default: |
| 61 | logerror("%s: io_w8 %02x, %02x (%04x)\n", tag(), adr, data, PPC); |
| 62 | } |
| 63 | return; |
| 64 | } |
| 65 | |
| 66 | void i8xc196_device::io_w16(UINT8 adr, UINT16 data) |
| 67 | { |
| 68 | switch(adr) { |
| 69 | case 0: |
| 70 | break; |
| 71 | default: |
| 72 | io_w8(adr, data); |
| 73 | io_w8(adr+1, data>>8); |
| 74 | break; |
| 75 | } |
| 76 | return; |
| 77 | } |
| 78 | |
| 79 | UINT8 i8xc196_device::io_r8(UINT8 adr) |
| 80 | { |
| 81 | switch(adr) { |
| 82 | case 0x00: |
| 83 | return 0x00; |
| 84 | case 0x01: |
| 85 | return 0x00; |
| 86 | } |
| 87 | UINT8 data = 0x00; |
| 88 | logerror("%s: io_r8 %02x, %02x (%04x)\n", tag(), adr, data, PPC); |
| 89 | return data; |
| 90 | } |
| 91 | |
| 92 | UINT16 i8xc196_device::io_r16(UINT8 adr) |
| 93 | { |
| 94 | if(adr < 2) |
| 95 | return 0x0000; |
| 96 | UINT16 data = 0x0000; |
| 97 | logerror("%s: io_r16 %02x, %04x (%04x)\n", tag(), adr, data, PPC); |
| 98 | return data; |
| 99 | } |
| 100 | |
| 101 | #include "cpu/mcs96/i8xc196.inc" |
trunk/src/emu/cpu/mcs96/i8x9x.h
| r19633 | r19634 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | i8x9x.h |
| 4 | |
| 5 | MCS96, 8x9x branch, the original version |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Olivier Galibert |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #ifndef __I8X9X_H__ |
| 41 | #define __I8X9X_H__ |
| 42 | |
| 43 | #include "mcs96.h" |
| 44 | |
| 45 | class i8x9x_device : public mcs96_device { |
| 46 | public: |
| 47 | enum { |
| 48 | A0, A1, A2, A3, A4, A5, A6, A7, |
| 49 | SERIAL |
| 50 | }; |
| 51 | |
| 52 | i8x9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 53 | |
| 54 | void serial_w(UINT8 val); |
| 55 | |
| 56 | protected: |
| 57 | virtual void device_start(); |
| 58 | virtual void device_reset(); |
| 59 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; |
| 60 | |
| 61 | static const disasm_entry disasm_entries[0x100]; |
| 62 | |
| 63 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 64 | virtual void do_exec_full(); |
| 65 | virtual void do_exec_partial(); |
| 66 | virtual void internal_update(UINT64 current_time); |
| 67 | virtual void io_w8(UINT8 adr, UINT8 data); |
| 68 | virtual void io_w16(UINT8 adr, UINT16 data); |
| 69 | virtual UINT8 io_r8(UINT8 adr); |
| 70 | virtual UINT16 io_r16(UINT8 adr); |
| 71 | |
| 72 | private: |
| 73 | enum { |
| 74 | IRQ_TIMER = 0x01, |
| 75 | IRQ_AD = 0x02, |
| 76 | IRQ_HSI = 0x04, |
| 77 | IRQ_HSO = 0x08, |
| 78 | IRQ_HSI0 = 0x10, |
| 79 | IRQ_SOFT = 0x20, |
| 80 | IRQ_SERIAL = 0x40, |
| 81 | IRQ_EXTINT = 0x80 |
| 82 | }; |
| 83 | |
| 84 | struct hso_cam_entry { |
| 85 | bool active; |
| 86 | UINT8 command; |
| 87 | UINT16 time; |
| 88 | }; |
| 89 | |
| 90 | address_space_config io_config; |
| 91 | address_space *io; |
| 92 | |
| 93 | hso_cam_entry hso_info[8]; |
| 94 | hso_cam_entry hso_cam_hold; |
| 95 | |
| 96 | UINT64 base_timer2, ad_done; |
| 97 | UINT8 hso_command, ad_command; |
| 98 | UINT16 hso_time, ad_result; |
| 99 | UINT8 ios0, ios1, ioc0, ioc1; |
| 100 | UINT8 sbuf, sp_stat; |
| 101 | UINT8 serial_send_buf; |
| 102 | UINT64 serial_send_timer; |
| 103 | |
| 104 | UINT16 timer_value(int timer, UINT64 current_time) const; |
| 105 | UINT64 timer_time_until(int timer, UINT64 current_time, UINT16 timer_value) const; |
| 106 | void commit_hso_cam(); |
| 107 | void trigger_cam(int id, UINT64 current_time); |
| 108 | void ad_start(UINT64 current_time); |
| 109 | void serial_send(UINT8 data); |
| 110 | void serial_send_done(); |
| 111 | }; |
| 112 | |
| 113 | class c8095_device : public i8x9x_device { |
| 114 | public: |
| 115 | c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 116 | }; |
| 117 | |
| 118 | class p8098_device : public i8x9x_device { |
| 119 | public: |
| 120 | p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 121 | }; |
| 122 | |
| 123 | extern const device_type C8095; |
| 124 | extern const device_type P8098; |
| 125 | |
| 126 | #endif |
trunk/src/emu/cpu/mcs96/mcs96.c
| r19633 | r19634 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | mcs96.h |
| 4 | |
| 5 | MCS96, 8098/8398/8798 branch |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Olivier Galibert |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #include "emu.h" |
| 41 | #include "debugger.h" |
| 42 | #include "mcs96.h" |
| 43 | |
| 44 | mcs96_device::mcs96_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int data_width) : |
| 45 | cpu_device(mconfig, type, name, tag, owner, clock), |
| 46 | program_config("program", ENDIANNESS_LITTLE, data_width, 16) |
| 47 | { |
| 48 | } |
| 49 | |
| 50 | void mcs96_device::device_start() |
| 51 | { |
| 52 | program = &space(AS_PROGRAM); |
| 53 | direct = &program->direct(); |
| 54 | m_icountptr = &icount; |
| 55 | |
| 56 | state_add(STATE_GENPC, "GENPC", PC).noshow(); |
| 57 | state_add(STATE_GENPCBASE, "GENPCBASE", PPC).noshow(); |
| 58 | state_add(STATE_GENSP, "GENSP", R[0]).noshow(); |
| 59 | state_add(STATE_GENFLAGS, "GENFLAGS", PSW).formatstr("%16s").noshow(); |
| 60 | state_add(MCS96_PC, "PC", PC); |
| 61 | state_add(MCS96_PSW, "PSW", PSW); |
| 62 | state_add(MCS96_R, "SP", R[0]); |
| 63 | for(int i=1; i<0x74; i++) { |
| 64 | char buf[10]; |
| 65 | sprintf(buf, "R%02x", i*2+0x18); |
| 66 | state_add(MCS96_R+i, buf, R[i]); |
| 67 | } |
| 68 | |
| 69 | memset(R, 0, sizeof(R)); |
| 70 | } |
| 71 | |
| 72 | void mcs96_device::device_reset() |
| 73 | { |
| 74 | PC = 0x2080; |
| 75 | PPC = PC; |
| 76 | PSW = 0; |
| 77 | pending_irq = 0x00; |
| 78 | irq_requested = false; |
| 79 | inst_state = STATE_FETCH; |
| 80 | } |
| 81 | |
| 82 | UINT32 mcs96_device::execute_min_cycles() const |
| 83 | { |
| 84 | return 4; |
| 85 | } |
| 86 | |
| 87 | UINT32 mcs96_device::execute_max_cycles() const |
| 88 | { |
| 89 | return 33; |
| 90 | } |
| 91 | |
| 92 | UINT32 mcs96_device::execute_input_lines() const |
| 93 | { |
| 94 | return 1; |
| 95 | } |
| 96 | |
| 97 | UINT64 mcs96_device::get_cycle() |
| 98 | { |
| 99 | return end_cycles == 0 || icount <= 0 ? machine().time().as_ticks(clock()) : end_cycles - icount; |
| 100 | } |
| 101 | |
| 102 | void mcs96_device::recompute_bcount(UINT64 event_time) |
| 103 | { |
| 104 | if(!event_time || event_time >= end_cycles) { |
| 105 | bcount = 0; |
| 106 | return; |
| 107 | } |
| 108 | bcount = end_cycles - event_time; |
| 109 | } |
| 110 | |
| 111 | void mcs96_device::check_irq() |
| 112 | { |
| 113 | irq_requested = (PSW & pending_irq) && (PSW & F_I); |
| 114 | } |
| 115 | |
| 116 | void mcs96_device::execute_run() |
| 117 | { |
| 118 | UINT64 start_cycles = machine().time().as_ticks(clock()); |
| 119 | end_cycles = start_cycles + icount; |
| 120 | |
| 121 | internal_update(start_cycles); |
| 122 | |
| 123 | if(/*inst_substate*/ 0) |
| 124 | do_exec_partial(); |
| 125 | |
| 126 | while(icount > 0) { |
| 127 | while(icount > bcount) { |
| 128 | int picount = inst_state >= 0x200 ? -1 : icount; |
| 129 | do_exec_full(); |
| 130 | if(icount == picount) { |
| 131 | fprintf(stderr, "Unhandled %x (%04x)\n", inst_state, PPC); |
| 132 | exit(0); |
| 133 | } |
| 134 | } |
| 135 | while(bcount && icount <= bcount) |
| 136 | internal_update(end_cycles - bcount); |
| 137 | } |
| 138 | end_cycles = 0; |
| 139 | } |
| 140 | |
| 141 | void mcs96_device::execute_set_input(int inputnum, int state) |
| 142 | { |
| 143 | switch(inputnum) { |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | const address_space_config *mcs96_device::memory_space_config(address_spacenum spacenum) const |
| 148 | { |
| 149 | return (spacenum == AS_PROGRAM) ? &program_config : NULL; |
| 150 | } |
| 151 | |
| 152 | void mcs96_device::state_import(const device_state_entry &entry) |
| 153 | { |
| 154 | } |
| 155 | |
| 156 | void mcs96_device::state_export(const device_state_entry &entry) |
| 157 | { |
| 158 | } |
| 159 | |
| 160 | void mcs96_device::state_string_export(const device_state_entry &entry, astring &string) |
| 161 | { |
| 162 | switch(entry.index()) { |
| 163 | case STATE_GENFLAGS: |
| 164 | case MCS96_PSW: |
| 165 | string.printf("%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c", |
| 166 | PSW & F_Z ? 'Z' : '.', |
| 167 | PSW & F_N ? 'N' : '.', |
| 168 | PSW & F_V ? 'V' : '.', |
| 169 | PSW & F_VT ? 'v' : '.', |
| 170 | PSW & F_C ? 'C' : '.', |
| 171 | PSW & F_I ? 'I' : '.', |
| 172 | PSW & F_ST ? 'S' : '.', |
| 173 | PSW & 0x80 ? '7' : '.', |
| 174 | PSW & 0x40 ? '6' : '.', |
| 175 | PSW & 0x20 ? '5' : '.', |
| 176 | PSW & 0x10 ? '4' : '.', |
| 177 | PSW & 0x08 ? '3' : '.', |
| 178 | PSW & 0x04 ? '2' : '.', |
| 179 | PSW & 0x02 ? '1' : '.', |
| 180 | PSW & 0x01 ? '0' : '.'); |
| 181 | break; |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | astring mcs96_device::regname(UINT8 reg) |
| 186 | { |
| 187 | char res[32]; |
| 188 | switch(reg) { |
| 189 | case 0x18: |
| 190 | strcpy(res, "sp"); |
| 191 | break; |
| 192 | |
| 193 | case 0x19: |
| 194 | strcpy(res, "sph"); |
| 195 | break; |
| 196 | |
| 197 | default: |
| 198 | sprintf(res, "%02x", reg); |
| 199 | break; |
| 200 | } |
| 201 | return res; |
| 202 | } |
| 203 | |
| 204 | offs_t mcs96_device::disasm_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *entries) |
| 205 | { |
| 206 | bool prefix_fe = false; |
| 207 | int off = 0; |
| 208 | if(oprom[0] == 0xfe && entries[oprom[1]].opcode_fe) { |
| 209 | prefix_fe = true; |
| 210 | pc++; |
| 211 | off++; |
| 212 | oprom++; |
| 213 | } |
| 214 | const disasm_entry &e = entries[oprom[0]]; |
| 215 | UINT32 flags = e.flags | DASMFLAG_SUPPORTED; |
| 216 | buffer += sprintf(buffer, "%s", prefix_fe ? e.opcode_fe : e.opcode); |
| 217 | |
| 218 | switch(e.mode) { |
| 219 | case DASM_none: |
| 220 | flags |= 1; |
| 221 | break; |
| 222 | |
| 223 | case DASM_nop_2: |
| 224 | sprintf(buffer, " %02x", oprom[1]); |
| 225 | flags |= 2; |
| 226 | break; |
| 227 | |
| 228 | case DASM_rel8: { |
| 229 | int delta = oprom[1]; |
| 230 | if(delta & 0x80) |
| 231 | delta -= 0x100; |
| 232 | sprintf(buffer, " %04x", (pc+2+delta) & 0xffff); |
| 233 | flags |= 2; |
| 234 | break; |
| 235 | } |
| 236 | |
| 237 | case DASM_rel11: { |
| 238 | int delta = ((oprom[0] << 8) | oprom[1]) & 0x7ff; |
| 239 | if(delta & 0x400) |
| 240 | delta -= 0x800; |
| 241 | sprintf(buffer, " %04x", (pc+2+delta) & 0xffff); |
| 242 | flags |= 2; |
| 243 | break; |
| 244 | } |
| 245 | |
| 246 | case DASM_rel16: { |
| 247 | int delta = oprom[1] | (oprom[2] << 8); |
| 248 | sprintf(buffer, " %04x", (pc+3+delta) & 0xffff); |
| 249 | flags |= 3; |
| 250 | break; |
| 251 | } |
| 252 | |
| 253 | case DASM_rrel8: { |
| 254 | int delta = oprom[2]; |
| 255 | if(delta & 0x80) |
| 256 | delta -= 0x100; |
| 257 | sprintf(buffer, " %s, %04x", regname(oprom[1]).cstr(), (pc+3+delta) & 0xffff); |
| 258 | flags |= 3; |
| 259 | break; |
| 260 | } |
| 261 | |
| 262 | case DASM_brrel8: { |
| 263 | int delta = oprom[2]; |
| 264 | if(delta & 0x80) |
| 265 | delta -= 0x100; |
| 266 | sprintf(buffer, " %d, %s, %04x", oprom[0] & 7, regname(oprom[1]).cstr(), (pc+3+delta) & 0xffff); |
| 267 | flags |= 3; |
| 268 | break; |
| 269 | } |
| 270 | |
| 271 | case DASM_direct_1: |
| 272 | sprintf(buffer, " %s", regname(oprom[1]).cstr()); |
| 273 | flags |= 2; |
| 274 | break; |
| 275 | |
| 276 | case DASM_direct_2: |
| 277 | sprintf(buffer, " %s, %s", regname(oprom[2]).cstr(), regname(oprom[1]).cstr()); |
| 278 | flags |= 3; |
| 279 | break; |
| 280 | |
| 281 | case DASM_direct_3: |
| 282 | sprintf(buffer, " %s, %s, %s", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), regname(oprom[1]).cstr()); |
| 283 | flags |= 4; |
| 284 | break; |
| 285 | |
| 286 | case DASM_immed_1b: |
| 287 | sprintf(buffer, " #%02x", oprom[1]); |
| 288 | flags |= 2; |
| 289 | break; |
| 290 | |
| 291 | case DASM_immed_2b: |
| 292 | sprintf(buffer, " %s, #%02x", regname(oprom[2]).cstr(), oprom[1]); |
| 293 | flags |= 3; |
| 294 | break; |
| 295 | |
| 296 | case DASM_immed_3b: |
| 297 | sprintf(buffer, " %s, %s, #%02x", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), oprom[1]); |
| 298 | flags |= 4; |
| 299 | break; |
| 300 | |
| 301 | case DASM_immed_1w: |
| 302 | sprintf(buffer, " #%02x%02x", oprom[2], oprom[1]); |
| 303 | flags |= 3; |
| 304 | break; |
| 305 | |
| 306 | case DASM_immed_2w: |
| 307 | sprintf(buffer, " %s, #%02x%02x", regname(oprom[3]).cstr(), oprom[2], oprom[1]); |
| 308 | flags |= 4; |
| 309 | break; |
| 310 | |
| 311 | case DASM_immed_3w: |
| 312 | sprintf(buffer, " %s, %s, #%02x%02x", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), oprom[2], oprom[1]); |
| 313 | flags |= 5; |
| 314 | break; |
| 315 | |
| 316 | case DASM_indirect_1n: |
| 317 | sprintf(buffer, " [%s]", regname(oprom[1]).cstr()); |
| 318 | flags |= 2; |
| 319 | break; |
| 320 | |
| 321 | case DASM_indirect_1: |
| 322 | if(oprom[1] & 0x01) { |
| 323 | sprintf(buffer, " [%s]+", regname(oprom[1]-1).cstr()); |
| 324 | flags |= 2; |
| 325 | } else { |
| 326 | sprintf(buffer, " [%s]", regname(oprom[1]).cstr()); |
| 327 | flags |= 2; |
| 328 | } |
| 329 | break; |
| 330 | |
| 331 | case DASM_indirect_2: |
| 332 | if(oprom[1] & 0x01) { |
| 333 | sprintf(buffer, " %s, [%s]+", regname(oprom[2]).cstr(), regname(oprom[1]-1).cstr()); |
| 334 | flags |= 3; |
| 335 | } else { |
| 336 | sprintf(buffer, " %s, [%s]", regname(oprom[2]).cstr(), regname(oprom[1]).cstr()); |
| 337 | flags |= 3; |
| 338 | } |
| 339 | break; |
| 340 | |
| 341 | case DASM_indirect_3: |
| 342 | if(oprom[1] & 0x01) { |
| 343 | sprintf(buffer, " %s, %s, [%s]+", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), regname(oprom[1]-1).cstr()); |
| 344 | flags |= 4; |
| 345 | } else { |
| 346 | sprintf(buffer, " %s, %s, [%s]", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), regname(oprom[1]).cstr()); |
| 347 | flags |= 4; |
| 348 | } |
| 349 | break; |
| 350 | |
| 351 | case DASM_indexed_1: |
| 352 | if(oprom[1] & 0x01) { |
| 353 | if(oprom[1] == 0x01) |
| 354 | sprintf(buffer, " %02x%02x", oprom[3], oprom[2]); |
| 355 | else |
| 356 | sprintf(buffer, " %02x%02x[%s]", oprom[3], oprom[2], regname(oprom[1]-1).cstr()); |
| 357 | flags |= 4; |
| 358 | } else { |
| 359 | int delta = oprom[2]; |
| 360 | if(delta & 0x80) |
| 361 | delta -= 0x100; |
| 362 | if(oprom[1] == 0x00) { |
| 363 | if(delta < 0) |
| 364 | sprintf(buffer, " %04x", delta & 0xffff); |
| 365 | else |
| 366 | sprintf(buffer, " %02x", delta); |
| 367 | } else { |
| 368 | if(delta < 0) |
| 369 | sprintf(buffer, " -%02x[%s]", -delta, regname(oprom[1]-1).cstr()); |
| 370 | else |
| 371 | sprintf(buffer, " %02x[%s]", delta, regname(oprom[1]-1).cstr()); |
| 372 | } |
| 373 | flags |= 3; |
| 374 | } |
| 375 | break; |
| 376 | |
| 377 | case DASM_indexed_2: |
| 378 | if(oprom[1] & 0x01) { |
| 379 | if(oprom[1] == 0x01) |
| 380 | sprintf(buffer, " %s, %02x%02x", regname(oprom[4]).cstr(), oprom[3], oprom[2]); |
| 381 | else |
| 382 | sprintf(buffer, " %s, %02x%02x[%s]", regname(oprom[4]).cstr(), oprom[3], oprom[2], regname(oprom[1]-1).cstr()); |
| 383 | flags |= 5; |
| 384 | } else { |
| 385 | int delta = oprom[2]; |
| 386 | if(delta & 0x80) |
| 387 | delta -= 0x100; |
| 388 | if(oprom[1] == 0x00) { |
| 389 | if(delta < 0) |
| 390 | sprintf(buffer, " %s, %04x", regname(oprom[3]).cstr(), delta & 0xffff); |
| 391 | else |
| 392 | sprintf(buffer, " %s, %02x", regname(oprom[3]).cstr(), delta); |
| 393 | } else { |
| 394 | if(delta < 0) |
| 395 | sprintf(buffer, " %s, -%02x[%s]", regname(oprom[3]).cstr(), -delta, regname(oprom[1]-1).cstr()); |
| 396 | else |
| 397 | sprintf(buffer, " %s, %02x[%s]", regname(oprom[3]).cstr(), delta, regname(oprom[1]-1).cstr()); |
| 398 | } |
| 399 | flags |= 4; |
| 400 | } |
| 401 | break; |
| 402 | |
| 403 | case DASM_indexed_3: |
| 404 | if(oprom[1] & 0x01) { |
| 405 | if(oprom[1] == 0x01) |
| 406 | sprintf(buffer, " %s, %s, %02x%02x", regname(oprom[5]).cstr(), regname(oprom[4]).cstr(), oprom[3], oprom[2]); |
| 407 | else |
| 408 | sprintf(buffer, " %s, %s, %02x%02x[%s]", regname(oprom[5]).cstr(), regname(oprom[4]).cstr(), oprom[3], oprom[2], regname(oprom[1]-1).cstr()); |
| 409 | flags |= 6; |
| 410 | } else { |
| 411 | int delta = oprom[2]; |
| 412 | if(delta & 0x80) |
| 413 | delta -= 0x100; |
| 414 | if(oprom[1] == 0x00) { |
| 415 | if(delta < 0) |
| 416 | sprintf(buffer, " %s, %s, %04x", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), delta & 0xffff); |
| 417 | else |
| 418 | sprintf(buffer, " %s, %s, %02x", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), delta); |
| 419 | } else { |
| 420 | if(delta < 0) |
| 421 | sprintf(buffer, " %s, %s, -%02x[%s]", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), -delta, regname(oprom[1]-1).cstr()); |
| 422 | else |
| 423 | sprintf(buffer, " %s, %s, %02x[%s]", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), delta, regname(oprom[1]-1).cstr()); |
| 424 | } |
| 425 | flags |= 5; |
| 426 | } |
| 427 | break; |
| 428 | |
| 429 | default: |
| 430 | fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); |
| 431 | abort(); |
| 432 | }; |
| 433 | |
| 434 | return flags+off; |
| 435 | } |
| 436 | |
| 437 | UINT32 mcs96_device::disasm_min_opcode_bytes() const |
| 438 | { |
| 439 | return 1; |
| 440 | } |
| 441 | |
| 442 | UINT32 mcs96_device::disasm_max_opcode_bytes() const |
| 443 | { |
| 444 | return 7; |
| 445 | } |
| 446 | |
| 447 | void mcs96_device::io_w8(UINT8 adr, UINT8 data) |
| 448 | { |
| 449 | switch(adr) { |
| 450 | case 0x02: |
| 451 | logerror("%s: ad_command %02x (%04x)\n", tag(), data, PPC); |
| 452 | break; |
| 453 | case 0x03: |
| 454 | logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC); |
| 455 | break; |
| 456 | case 0x04: |
| 457 | logerror("%s: hso_time.l %02x (%04x)\n", tag(), data, PPC); |
| 458 | break; |
| 459 | case 0x05: |
| 460 | logerror("%s: hso_time.h %02x (%04x)\n", tag(), data, PPC); |
| 461 | break; |
| 462 | case 0x06: |
| 463 | logerror("%s: hso_command %02x (%04x)\n", tag(), data, PPC); |
| 464 | break; |
| 465 | case 0x07: |
| 466 | logerror("%s: sbuf %02x (%04x)\n", tag(), data, PPC); |
| 467 | break; |
| 468 | case 0x08: |
| 469 | PSW = (PSW & 0xff00) | data; |
| 470 | break; |
| 471 | case 0x09: |
| 472 | logerror("%s: int_pending %02x (%04x)\n", tag(), data, PPC); |
| 473 | break; |
| 474 | case 0x0a: |
| 475 | logerror("%s: watchdog %02x (%04x)\n", tag(), data, PPC); |
| 476 | break; |
| 477 | case 0x0e: |
| 478 | logerror("%s: baud rate %02x (%04x)\n", tag(), data, PPC); |
| 479 | break; |
| 480 | case 0x0f: |
| 481 | logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC); |
| 482 | break; |
| 483 | case 0x10: |
| 484 | logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC); |
| 485 | break; |
| 486 | case 0x11: |
| 487 | logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC); |
| 488 | break; |
| 489 | case 0x15: |
| 490 | logerror("%s: ioc0 %02x (%04x)\n", tag(), data, PPC); |
| 491 | break; |
| 492 | case 0x16: |
| 493 | logerror("%s: ioc1 %02x (%04x)\n", tag(), data, PPC); |
| 494 | break; |
| 495 | case 0x17: |
| 496 | logerror("%s: pwm control %02x (%04x)\n", tag(), data, PPC); |
| 497 | break; |
| 498 | } |
| 499 | return; |
| 500 | } |
| 501 | |
| 502 | void mcs96_device::io_w16(UINT8 adr, UINT16 data) |
| 503 | { |
| 504 | switch(adr) { |
| 505 | case 0: |
| 506 | break; |
| 507 | case 4: |
| 508 | logerror("%s: hso_time %04x (%04x)\n", tag(), data, PPC); |
| 509 | break; |
| 510 | default: |
| 511 | io_w8(adr, data); |
| 512 | io_w8(adr+1, data>>8); |
| 513 | break; |
| 514 | } |
| 515 | return; |
| 516 | } |
| 517 | |
| 518 | UINT8 mcs96_device::io_r8(UINT8 adr) |
| 519 | { |
| 520 | switch(adr) { |
| 521 | case 0x00: |
| 522 | return 0x00; |
| 523 | case 0x01: |
| 524 | return 0x00; |
| 525 | case 0x08: |
| 526 | return PSW; |
| 527 | } |
| 528 | UINT8 data = 0x00; |
| 529 | logerror("%s: io_r8 %02x, %02x (%04x)\n", tag(), adr, data, PPC); |
| 530 | return data; |
| 531 | } |
| 532 | |
| 533 | UINT16 mcs96_device::io_r16(UINT8 adr) |
| 534 | { |
| 535 | if(adr < 2) |
| 536 | return 0x0000; |
| 537 | UINT16 data = 0x0000; |
| 538 | logerror("%s: io_r16 %02x, %04x (%04x)\n", tag(), adr, data, PPC); |
| 539 | return data; |
| 540 | } |
| 541 | |
| 542 | void mcs96_device::reg_w8(UINT8 adr, UINT8 data) |
| 543 | { |
| 544 | if(adr < 0x18) |
| 545 | io_w8(adr, data); |
| 546 | else { |
| 547 | UINT16 &r = R[(adr - 0x18) >> 1]; |
| 548 | if(adr & 0x01) |
| 549 | r = (r & 0x00ff) | (data << 8); |
| 550 | else |
| 551 | r = (r & 0xff00) | data; |
| 552 | } |
| 553 | } |
| 554 | |
| 555 | void mcs96_device::reg_w16(UINT8 adr, UINT16 data) |
| 556 | { |
| 557 | adr &= 0xfe; |
| 558 | if(adr < 0x18) |
| 559 | io_w16(adr, data); |
| 560 | else |
| 561 | R[(adr-0x18) >> 1] = data; |
| 562 | } |
| 563 | |
| 564 | UINT8 mcs96_device::reg_r8(UINT8 adr) |
| 565 | { |
| 566 | if(adr < 0x18) |
| 567 | return io_r8(adr); |
| 568 | |
| 569 | UINT16 data = R[(adr - 0x18) >> 1]; |
| 570 | if(adr & 0x01) |
| 571 | return data >> 8; |
| 572 | else |
| 573 | return data; |
| 574 | } |
| 575 | |
| 576 | UINT16 mcs96_device::reg_r16(UINT8 adr) |
| 577 | { |
| 578 | adr &= 0xfe; |
| 579 | if(adr < 0x18) |
| 580 | return io_r16(adr); |
| 581 | |
| 582 | return R[(adr-0x18) >> 1]; |
| 583 | } |
| 584 | |
| 585 | void mcs96_device::any_w8(UINT16 adr, UINT8 data) |
| 586 | { |
| 587 | if(adr < 0x18) |
| 588 | io_w8(adr, data); |
| 589 | else if(adr < 0x100) { |
| 590 | UINT16 &r = R[(adr - 0x18) >> 1]; |
| 591 | if(adr & 0x01) |
| 592 | r = (r & 0x00ff) | (data << 8); |
| 593 | else |
| 594 | r = (r & 0xff00) | data; |
| 595 | } else |
| 596 | program->write_byte(adr, data); |
| 597 | } |
| 598 | |
| 599 | void mcs96_device::any_w16(UINT16 adr, UINT16 data) |
| 600 | { |
| 601 | adr &= 0xfffe; |
| 602 | if(adr < 0x18) |
| 603 | io_w16(adr, data); |
| 604 | else if(adr < 0x100) |
| 605 | R[(adr-0x18) >> 1] = data; |
| 606 | else |
| 607 | program->write_word(adr, data); |
| 608 | } |
| 609 | |
| 610 | UINT8 mcs96_device::any_r8(UINT16 adr) |
| 611 | { |
| 612 | if(adr < 0x18) |
| 613 | return io_r8(adr); |
| 614 | else if(adr < 0x100) { |
| 615 | UINT16 data = R[(adr - 0x18) >> 1]; |
| 616 | if(adr & 0x01) |
| 617 | return data >> 8; |
| 618 | else |
| 619 | return data; |
| 620 | } else |
| 621 | return program->read_byte(adr); |
| 622 | } |
| 623 | |
| 624 | UINT16 mcs96_device::any_r16(UINT16 adr) |
| 625 | { |
| 626 | adr &= 0xfffe; |
| 627 | if(adr < 0x18) |
| 628 | return io_r16(adr); |
| 629 | else if(adr < 0x100) |
| 630 | return R[(adr-0x18) >> 1]; |
| 631 | else |
| 632 | return program->read_word(adr); |
| 633 | } |
| 634 | |
| 635 | UINT8 mcs96_device::do_addb(UINT8 v1, UINT8 v2) |
| 636 | { |
| 637 | UINT16 sum = v1+v2; |
| 638 | PSW &= ~(F_Z|F_N|F_C|F_V); |
| 639 | if(!UINT8(sum)) |
| 640 | PSW |= F_Z; |
| 641 | else if(INT8(sum) < 0) |
| 642 | PSW |= F_N; |
| 643 | if(~(v1^v2) & (v1^sum) & 0x80) |
| 644 | PSW |= F_V|F_VT; |
| 645 | if(sum & 0xff00) |
| 646 | PSW |= F_C; |
| 647 | return sum; |
| 648 | } |
| 649 | |
| 650 | UINT16 mcs96_device::do_add(UINT16 v1, UINT16 v2) |
| 651 | { |
| 652 | UINT32 sum = v1+v2; |
| 653 | PSW &= ~(F_Z|F_N|F_C|F_V); |
| 654 | if(!UINT16(sum)) |
| 655 | PSW |= F_Z; |
| 656 | else if(INT16(sum) < 0) |
| 657 | PSW |= F_N; |
| 658 | if(~(v1^v2) & (v1^sum) & 0x8000) |
| 659 | PSW |= F_V|F_VT; |
| 660 | if(sum & 0xffff0000) |
| 661 | PSW |= F_C; |
| 662 | return sum; |
| 663 | } |
| 664 | |
| 665 | UINT8 mcs96_device::do_subb(UINT8 v1, UINT8 v2) |
| 666 | { |
| 667 | UINT16 diff = v1 - v2; |
| 668 | PSW &= ~(F_N|F_V|F_Z|F_C); |
| 669 | if(!UINT8(diff)) |
| 670 | PSW |= F_Z; |
| 671 | else if(INT8(diff) < 0) |
| 672 | PSW |= F_N; |
| 673 | if((v1^v2) & (v1^diff) & 0x80) |
| 674 | PSW |= F_V; |
| 675 | if(!(diff & 0xff00)) |
| 676 | PSW |= F_C; |
| 677 | return diff; |
| 678 | } |
| 679 | |
| 680 | UINT16 mcs96_device::do_sub(UINT16 v1, UINT16 v2) |
| 681 | { |
| 682 | UINT32 diff = v1 - v2; |
| 683 | PSW &= ~(F_N|F_V|F_Z|F_C); |
| 684 | if(!UINT16(diff)) |
| 685 | PSW |= F_Z; |
| 686 | else if(INT16(diff) < 0) |
| 687 | PSW |= F_N; |
| 688 | if((v1^v2) & (v1^diff) & 0x8000) |
| 689 | PSW |= F_V; |
| 690 | if(!(diff & 0xffff0000)) |
| 691 | PSW |= F_C; |
| 692 | return diff; |
| 693 | } |
| 694 | |
| 695 | void mcs96_device::set_nz8(UINT8 v) |
| 696 | { |
| 697 | PSW &= ~(F_N|F_V|F_Z|F_C); |
| 698 | if(!v) |
| 699 | PSW |= F_Z; |
| 700 | else if(INT8(v) < 0) |
| 701 | PSW |= F_N; |
| 702 | } |
| 703 | |
| 704 | void mcs96_device::set_nz16(UINT16 v) |
| 705 | { |
| 706 | PSW &= ~(F_N|F_V|F_Z|F_C); |
| 707 | if(!v) |
| 708 | PSW |= F_Z; |
| 709 | else if(INT16(v) < 0) |
| 710 | PSW |= F_N; |
| 711 | } |
| 712 | |
| 713 | #include "cpu/mcs96/mcs96.inc" |
trunk/src/emu/cpu/mcs96/mcs96ops.lst
| r19633 | r19634 | |
| 1 | fetch |
| 2 | if(irq_requested) { |
| 3 | int level; |
| 4 | for(level = 7; level >= 0 && !(PSW & pending_irq & (1<<level)); level--); |
| 5 | pending_irq &= ~(1<<level); |
| 6 | OP1 = level; |
| 7 | TMP = reg_r16(0x18); |
| 8 | TMP -= 2; |
| 9 | reg_w16(0x18, TMP); |
| 10 | any_w16(TMP, PC); |
| 11 | PC = any_r16(0x2000+2*OP1); |
| 12 | standard_irq_callback(OP1); |
| 13 | check_irq(); |
| 14 | } |
| 15 | if(machine().debug_flags & DEBUG_FLAG_ENABLED) |
| 16 | debugger_instruction_hook(this, PC); |
| 17 | PPC = PC; |
| 18 | OP1 = read_pc(); |
| 19 | if(OP1 == 0xfe) { |
| 20 | OP1 = read_pc(); |
| 21 | inst_state = 0x100 | OP1; |
| 22 | } else |
| 23 | inst_state = OP1; |
| 24 | |
| 25 | fetch_noirq |
| 26 | if(machine().debug_flags & DEBUG_FLAG_ENABLED) |
| 27 | debugger_instruction_hook(this, PC); |
| 28 | PPC = PC; |
| 29 | OP1 = read_pc(); |
| 30 | if(OP1 == 0xfe) { |
| 31 | OP1 = read_pc(); |
| 32 | inst_state = 0x100 | OP1; |
| 33 | } else |
| 34 | inst_state = OP1; |
| 35 | |
| 36 | eadr rel8 |
| 37 | OP1 = INT8(read_pc()); |
| 38 | |
| 39 | eadr rel11 |
| 40 | OP1 = read_pc(); |
| 41 | OP1 = OP1 | ((inst_state & 7) << 8); |
| 42 | if(OP1 & 0x400) |
| 43 | OP1 |= 0xfc00; |
| 44 | |
| 45 | eadr rel16 |
| 46 | OP1 = read_pc(); |
| 47 | OP1 |= read_pc() << 8; |
| 48 | |
| 49 | eadr rrel8 |
| 50 | OP2 = read_pc(); |
| 51 | OP1 = INT8(read_pc()); |
| 52 | |
| 53 | eadr brrel8 |
| 54 | OP2 = read_pc(); |
| 55 | OP1 = INT8(read_pc()); |
| 56 | |
| 57 | eadr direct_1 |
| 58 | OP1 = read_pc(); |
| 59 | |
| 60 | eadr direct_2 |
| 61 | OP1 = read_pc(); |
| 62 | OP2 = read_pc(); |
| 63 | |
| 64 | eadr direct_3 |
| 65 | OP1 = read_pc(); |
| 66 | OP2 = read_pc(); |
| 67 | OP3 = read_pc(); |
| 68 | |
| 69 | eadr immed_1b |
| 70 | OP1 = read_pc(); |
| 71 | |
| 72 | eadr immed_2b |
| 73 | OP1 = read_pc(); |
| 74 | OP2 = read_pc(); |
| 75 | |
| 76 | eadr immed_3b |
| 77 | OP1 = read_pc(); |
| 78 | OP2 = read_pc(); |
| 79 | OP3 = read_pc(); |
| 80 | |
| 81 | eadr immed_1w |
| 82 | OP1 = read_pc(); |
| 83 | OP1 |= read_pc() << 8; |
| 84 | |
| 85 | eadr immed_2w |
| 86 | OP1 = read_pc(); |
| 87 | OP1 |= read_pc() << 8; |
| 88 | OP2 = read_pc(); |
| 89 | |
| 90 | eadr immed_3w |
| 91 | OP1 = read_pc(); |
| 92 | OP1 |= read_pc() << 8; |
| 93 | OP2 = read_pc(); |
| 94 | OP3 = read_pc(); |
| 95 | |
| 96 | eadr indirect_1n |
| 97 | OPI = read_pc() & 0xfe; |
| 98 | OP1 = reg_r16(OPI); |
| 99 | |
| 100 | eadr indirect_1 |
| 101 | OPI = read_pc(); |
| 102 | OP1 = reg_r16(OPI); |
| 103 | |
| 104 | eadr indirect_2 |
| 105 | OPI = read_pc(); |
| 106 | OP1 = reg_r16(OPI); |
| 107 | OP2 = read_pc(); |
| 108 | |
| 109 | eadr indirect_3 |
| 110 | OPI = read_pc(); |
| 111 | OP1 = reg_r16(OPI); |
| 112 | OP2 = read_pc(); |
| 113 | OP3 = read_pc(); |
| 114 | |
| 115 | macro post_indirect $size $cycles1 $cycles2 |
| 116 | if(OPI & 0x01) { |
| 117 | reg_w16(OPI, OP1 + $size); |
| 118 | next($cycles2); // +4 when external |
| 119 | } else { |
| 120 | next($cycles1); // +4 when external |
| 121 | } |
| 122 | |
| 123 | eadr indexed_1 |
| 124 | OPI = read_pc(); |
| 125 | OP1 = read_pc(); |
| 126 | if(OPI & 0x01) { |
| 127 | OPI &= 0xfe; |
| 128 | OP1 |= read_pc() << 8; |
| 129 | } else |
| 130 | OP1 = INT8(OP1); |
| 131 | if(OPI) { |
| 132 | OP1 += reg_r16(OPI); |
| 133 | } |
| 134 | |
| 135 | eadr indexed_2 |
| 136 | OPI = read_pc(); |
| 137 | OP1 = read_pc(); |
| 138 | if(OPI & 0x01) { |
| 139 | OPI &= 0xfe; |
| 140 | OP1 |= read_pc() << 8; |
| 141 | } else if(OP1 & 0x80) |
| 142 | OP1 |= 0xff00; |
| 143 | if(OPI) { |
| 144 | OP1 += reg_r16(OPI); |
| 145 | } |
| 146 | OP2 = read_pc(); |
| 147 | |
| 148 | eadr indexed_3 |
| 149 | OPI = read_pc(); |
| 150 | OP1 = read_pc(); |
| 151 | if(OPI & 0x01) { |
| 152 | OPI &= 0xfe; |
| 153 | OP1 |= read_pc() << 8; |
| 154 | } else if(OP1 & 0x80) |
| 155 | OP1 |= 0xff00; |
| 156 | if(OPI) { |
| 157 | OP1 += reg_r16(OPI); |
| 158 | } |
| 159 | OP2 = read_pc(); |
| 160 | OP3 = read_pc(); |
| 161 | |
| 162 | macro post_indexed $cycles1 $cycles2 |
| 163 | next(OPI & 0x01 ? $cycles2 : $cycles1); |
| 164 | |
| 165 | 00 skip immed_1b |
| 166 | next(4); |
| 167 | |
| 168 | 01 clr direct_1 |
| 169 | reg_w16(OP1, 0x0000); |
| 170 | next(4); |
| 171 | |
| 172 | 02 not direct_1 |
| 173 | TMP = ~reg_r16(OP1); |
| 174 | set_nz16(TMP); |
| 175 | reg_w16(OP1, TMP); |
| 176 | next(4); |
| 177 | |
| 178 | 03 neg direct_1 |
| 179 | TMP = reg_r16(OP1); |
| 180 | reg_w16(OP1, do_sub(0, TMP)); |
| 181 | next(4); |
| 182 | |
| 183 | 04 xch direct_2 |
| 184 | |
| 185 | 05 dec direct_1 |
| 186 | TMP = reg_r16(OP1); |
| 187 | reg_w16(OP1, do_sub(TMP, 1)); |
| 188 | next(4); |
| 189 | |
| 190 | 06 ext direct_1 |
| 191 | OP1 &= 0xfc; |
| 192 | TMP = INT16(reg_r16(OP1)); |
| 193 | set_nz16(TMP); |
| 194 | reg_w16(OP1+2, TMP >> 16); |
| 195 | next(4); |
| 196 | |
| 197 | 07 inc direct_1 |
| 198 | TMP = reg_r16(OP1); |
| 199 | reg_w16(OP1, do_add(TMP, 1)); |
| 200 | next(4); |
| 201 | |
| 202 | 08 shr immed_2b |
| 203 | OP1 &= 0x1f; |
| 204 | TMP = reg_r16(OP2); |
| 205 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 206 | if(OP1 >= 2 && (TMP & (0xffff >> (OP1 <= 16 ? 17-OP1 : 0)))) |
| 207 | PSW |= F_ST; |
| 208 | if(OP1 >= 1 && OP1 <= 16 && (TMP & (0x0001 << (OP1-1)))) |
| 209 | PSW |= F_C; |
| 210 | TMP = UINT16(TMP) >> OP1; |
| 211 | if(!TMP) |
| 212 | PSW |= F_Z; |
| 213 | else if(INT16(TMP) < 0) |
| 214 | PSW |= F_N; |
| 215 | reg_w16(OP2, TMP); |
| 216 | next(OP1 ? 7+OP1 : 8); |
| 217 | |
| 218 | 09 shl immed_2b |
| 219 | OP1 &= 0x1f; |
| 220 | TMP = reg_r16(OP2); |
| 221 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 222 | if(OP1 >= 2 && (TMP & (0xffff << (OP1 <= 16 ? 17-OP1 : 0)))) |
| 223 | PSW |= F_ST; |
| 224 | if(OP1 >= 1 && OP1 <= 16 && (TMP & (0x8000 >> (OP1-1)))) |
| 225 | PSW |= F_C; |
| 226 | TMP = UINT16(TMP << OP1); |
| 227 | if(!TMP) |
| 228 | PSW |= F_Z; |
| 229 | else if(INT16(TMP) < 0) |
| 230 | PSW |= F_N; |
| 231 | reg_w16(OP2, TMP); |
| 232 | next(OP1 ? 7+OP1 : 8); |
| 233 | |
| 234 | 0a shra immed_2b |
| 235 | OP1 &= 0x1f; |
| 236 | TMP = reg_r16(OP2); |
| 237 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 238 | if(OP1 >= 2 && (TMP & (0xffff >> (OP1 <= 16 ? 17-OP1 : 0)))) |
| 239 | PSW |= F_ST; |
| 240 | if(OP1 >= 1 && OP1 <= 16 && (TMP & (0x0001 << (OP1-1)))) |
| 241 | PSW |= F_C; |
| 242 | TMP = INT16(TMP) >> OP1; |
| 243 | if(!TMP) |
| 244 | PSW |= F_Z; |
| 245 | else if(INT16(TMP) < 0) |
| 246 | PSW |= F_N; |
| 247 | reg_w16(OP2, TMP); |
| 248 | next(OP1 ? 7+OP1 : 8); |
| 249 | |
| 250 | 0c shrl immed_2b |
| 251 | OP1 &= 0x1f; |
| 252 | OP2 &= 0xfc; |
| 253 | TMP = reg_r16(OP2); |
| 254 | TMP |= reg_r16(OP2+2) << 16; |
| 255 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 256 | if(OP1 >= 2 && (TMP & (0xffffffff >> (33-OP1)))) |
| 257 | PSW |= F_ST; |
| 258 | if(OP1 >= 1 && (TMP & (0x00000001 << (OP1-1)))) |
| 259 | PSW |= F_C; |
| 260 | TMP = TMP >> OP1; |
| 261 | if(!TMP) |
| 262 | PSW |= F_Z; |
| 263 | else if(INT32(TMP) < 0) |
| 264 | PSW |= F_N; |
| 265 | reg_w16(OP2, TMP); |
| 266 | reg_w16(OP2+2, TMP >> 16); |
| 267 | next(OP1 ? 7+OP1 : 8); |
| 268 | |
| 269 | 0d shll immed_2b |
| 270 | OP1 &= 0x1f; |
| 271 | OP2 &= 0xfc; |
| 272 | TMP = reg_r16(OP2); |
| 273 | TMP |= reg_r16(OP2+2) << 16; |
| 274 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 275 | if(OP1 >= 2 && (TMP & (0xffffffff << (33-OP1)))) |
| 276 | PSW |= F_ST; |
| 277 | if(OP1 >= 1 && (TMP & (0x80000000 >> (OP1-1)))) |
| 278 | PSW |= F_C; |
| 279 | TMP = TMP << OP1; |
| 280 | if(!TMP) |
| 281 | PSW |= F_Z; |
| 282 | else if(INT32(TMP) < 0) |
| 283 | PSW |= F_N; |
| 284 | reg_w16(OP2, TMP); |
| 285 | reg_w16(OP2+2, TMP >> 16); |
| 286 | next(OP1 ? 7+OP1 : 8); |
| 287 | |
| 288 | 0e shral immed_2b |
| 289 | OP1 &= 0x1f; |
| 290 | OP2 &= 0xfc; |
| 291 | TMP = reg_r16(OP2); |
| 292 | TMP |= reg_r16(OP2+2) << 16; |
| 293 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 294 | if(OP1 >= 2 && (TMP & (0xffffffff >> (33-OP1)))) |
| 295 | PSW |= F_ST; |
| 296 | if(OP1 >= 1 && (TMP & (0x00000001 << (OP1-1)))) |
| 297 | PSW |= F_C; |
| 298 | TMP = INT32(TMP) >> OP1; |
| 299 | if(!TMP) |
| 300 | PSW |= F_Z; |
| 301 | else if(INT32(TMP) < 0) |
| 302 | PSW |= F_N; |
| 303 | reg_w16(OP2, TMP); |
| 304 | reg_w16(OP2+2, TMP >> 16); |
| 305 | next(OP1 ? 7+OP1 : 8); |
| 306 | |
| 307 | 0f norml direct_2 |
| 308 | |
| 309 | 11 clrb direct_1 |
| 310 | reg_w8(OP1, 0x00); |
| 311 | next(4); |
| 312 | |
| 313 | 12 notb direct_1 |
| 314 | TMP = ~reg_r8(OP1); |
| 315 | set_nz8(TMP); |
| 316 | reg_w8(OP1, TMP); |
| 317 | next(4); |
| 318 | |
| 319 | 13 negb direct_1 |
| 320 | TMP = reg_r8(OP1); |
| 321 | reg_w8(OP1, do_subb(0, TMP)); |
| 322 | next(4); |
| 323 | |
| 324 | 14 xchb direct_2 |
| 325 | |
| 326 | 15 decb direct_1 |
| 327 | TMP = reg_r8(OP1); |
| 328 | reg_w8(OP1, do_subb(TMP, 1)); |
| 329 | next(4); |
| 330 | |
| 331 | 16 extb direct_1 |
| 332 | OP1 &= 0xfe; |
| 333 | TMP = INT8(reg_r8(OP1)); |
| 334 | set_nz8(TMP); |
| 335 | reg_w16(OP1, TMP); |
| 336 | next(4); |
| 337 | |
| 338 | 17 incb direct_1 |
| 339 | TMP = reg_r8(OP1); |
| 340 | reg_w8(OP1, do_addb(TMP, 1)); |
| 341 | next(4); |
| 342 | |
| 343 | 18 shrb immed_2b |
| 344 | OP1 &= 0x1f; |
| 345 | TMP = reg_r8(OP2); |
| 346 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 347 | if(OP1 >= 2 && (TMP & (0xff >> (OP1 <= 8 ? 9-OP1 : 0)))) |
| 348 | PSW |= F_ST; |
| 349 | if(OP1 >= 1 && OP1 <= 8 && (TMP & (0x01 << (OP1-1)))) |
| 350 | PSW |= F_C; |
| 351 | TMP = UINT8(TMP) >> OP1; |
| 352 | if(!TMP) |
| 353 | PSW |= F_Z; |
| 354 | else if(INT8(TMP) < 0) |
| 355 | PSW |= F_N; |
| 356 | reg_w8(OP2, TMP); |
| 357 | next(OP1 ? 7+OP1 : 8); |
| 358 | |
| 359 | 19 shlb immed_2b |
| 360 | OP1 &= 0x1f; |
| 361 | TMP = reg_r8(OP2); |
| 362 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 363 | if(OP1 >= 2 && (TMP & (0xff << (OP1 <= 8 ? 9-OP1 : 0)))) |
| 364 | PSW |= F_ST; |
| 365 | if(OP1 >= 1 && OP1 <= 8 && (TMP & (0x80 >> (OP1-1)))) |
| 366 | PSW |= F_C; |
| 367 | TMP = UINT8(TMP << OP1); |
| 368 | if(!TMP) |
| 369 | PSW |= F_Z; |
| 370 | else if(INT8(TMP) < 0) |
| 371 | PSW |= F_N; |
| 372 | reg_w8(OP2, TMP); |
| 373 | next(OP1 ? 7+OP1 : 8); |
| 374 | |
| 375 | 1a shrab immed_2b |
| 376 | OP1 &= 0x1f; |
| 377 | TMP = reg_r8(OP2); |
| 378 | PSW &= ~(F_Z|F_N|F_C|F_V|F_ST); |
| 379 | if(OP1 >= 2 && (TMP & (0xff >> (OP1 <= 8 ? 9-OP1 : 0)))) |
| 380 | PSW |= F_ST; |
| 381 | if(OP1 >= 1 && OP1 <= 8 && (TMP & (0x01 << (OP1-1)))) |
| 382 | PSW |= F_C; |
| 383 | TMP = UINT8(INT8(TMP) >> OP1); |
| 384 | if(!TMP) |
| 385 | PSW |= F_Z; |
| 386 | else if(INT8(TMP) < 0) |
| 387 | PSW |= F_N; |
| 388 | reg_w8(OP2, TMP); |
| 389 | next(OP1 ? 7+OP1 : 8); |
| 390 | |
| 391 | 20-27 sjmp rel11 |
| 392 | PC += OP1; |
| 393 | next(8); |
| 394 | |
| 395 | 28-2f scall rel11 |
| 396 | TMP = reg_r16(0x18); |
| 397 | TMP -= 2; |
| 398 | reg_w16(0x18, TMP); |
| 399 | any_w16(TMP, PC); |
| 400 | PC += OP1; |
| 401 | next(13); // real is 13/16 depending on sp's position |
| 402 | |
| 403 | 30-37 jbc brrel8 |
| 404 | TMP = reg_r8(OP2); |
| 405 | if(!((TMP >> (inst_state & 7)) & 1)) { |
| 406 | PC += OP1; |
| 407 | next(9); |
| 408 | } else { |
| 409 | next(5); |
| 410 | } |
| 411 | |
| 412 | 38-3f jbs brrel8 |
| 413 | TMP = reg_r8(OP2); |
| 414 | if((TMP >> (inst_state & 7)) & 1) { |
| 415 | PC += OP1; |
| 416 | next(9); |
| 417 | } else { |
| 418 | next(5); |
| 419 | } |
| 420 | |
| 421 | 40 and direct_3 |
| 422 | TMP = reg_r16(OP1); |
| 423 | TMP &= reg_r16(OP2); |
| 424 | set_nz16(TMP); |
| 425 | reg_w16(OP3, TMP); |
| 426 | next(5); |
| 427 | |
| 428 | 41 and immed_3w |
| 429 | TMP = OP1 & reg_r16(OP2); |
| 430 | set_nz16(TMP); |
| 431 | reg_w16(OP3, TMP); |
| 432 | next(6); |
| 433 | |
| 434 | 42 and indirect_3 |
| 435 | TMP = any_r16(OP1); |
| 436 | TMP &= reg_r16(OP2); |
| 437 | set_nz16(TMP); |
| 438 | reg_w16(OP3, TMP); |
| 439 | post_indirect 2 7 8 // +5 when external |
| 440 | |
| 441 | 43 and indexed_3 |
| 442 | TMP = any_r16(OP1); |
| 443 | TMP &= reg_r16(OP2); |
| 444 | set_nz16(TMP); |
| 445 | reg_w16(OP3, TMP); |
| 446 | post_indexed 7 8 // +5 when external |
| 447 | |
| 448 | 44 add direct_3 |
| 449 | TMP = reg_r16(OP1); |
| 450 | TMP = do_add(reg_r16(OP2), TMP); |
| 451 | reg_w16(OP3, TMP); |
| 452 | next(5); |
| 453 | |
| 454 | 45 add immed_3w |
| 455 | TMP = do_add(reg_r16(OP2), OP1); |
| 456 | reg_w16(OP3, TMP); |
| 457 | next(6); |
| 458 | |
| 459 | 46 add indirect_3 |
| 460 | TMP = any_r16(OP1); |
| 461 | TMP = do_add(reg_r16(OP2), TMP); |
| 462 | reg_w16(OP3, TMP); |
| 463 | post_indirect 2 7 8 // +5 when external |
| 464 | |
| 465 | 47 add indexed_3 |
| 466 | TMP = any_r16(OP1); |
| 467 | TMP = do_add(reg_r16(OP2), TMP); |
| 468 | reg_w16(OP3, TMP); |
| 469 | post_indexed 7 8 // +5 when external |
| 470 | |
| 471 | 48 sub direct_3 |
| 472 | TMP = reg_r16(OP1); |
| 473 | TMP = do_sub(reg_r16(OP2), TMP); |
| 474 | reg_w16(OP3, TMP); |
| 475 | next(5); |
| 476 | |
| 477 | 49 sub immed_3w |
| 478 | TMP = do_sub(reg_r16(OP2), OP1); |
| 479 | reg_w16(OP3, TMP); |
| 480 | next(6); |
| 481 | |
| 482 | 4a sub indirect_3 |
| 483 | TMP = any_r16(OP1); |
| 484 | TMP = do_sub(reg_r16(OP2), TMP); |
| 485 | reg_w16(OP3, TMP); |
| 486 | post_indexed 7 8 // +5 when external |
| 487 | |
| 488 | 4b sub indexed_3 |
| 489 | TMP = any_r16(OP1); |
| 490 | TMP = do_sub(reg_r16(OP2), TMP); |
| 491 | reg_w16(OP3, TMP); |
| 492 | post_indexed 7 8 // +5 when external |
| 493 | |
| 494 | 4c mulu direct_3 |
| 495 | TMP = reg_r16(OP1); |
| 496 | TMP *= reg_r16(OP2); |
| 497 | OP3 &= 0xfc; |
| 498 | reg_w16(OP3, TMP); |
| 499 | reg_w16(OP3+2, TMP >> 16); |
| 500 | next(26); |
| 501 | |
| 502 | 4d mulu immed_3w |
| 503 | TMP = OP1 * reg_r16(OP2); |
| 504 | OP3 &= 0xfc; |
| 505 | reg_w16(OP3, TMP); |
| 506 | reg_w16(OP3+2, TMP >> 16); |
| 507 | next(27); |
| 508 | |
| 509 | 4e mulu indirect_3 |
| 510 | TMP = any_r16(OP1); |
| 511 | TMP *= reg_r16(OP2); |
| 512 | OP3 &= 0xfc; |
| 513 | reg_w16(OP3, TMP); |
| 514 | reg_w16(OP3+2, TMP >> 16); |
| 515 | post_indirect 2 28 29 // +5 when external |
| 516 | |
| 517 | 4f mulu indexed_3 |
| 518 | TMP = any_r16(OP1); |
| 519 | TMP *= reg_r16(OP2); |
| 520 | OP3 &= 0xfc; |
| 521 | reg_w16(OP3, TMP); |
| 522 | reg_w16(OP3+2, TMP >> 16); |
| 523 | post_indexed 28 29 // +5 when external |
| 524 | |
| 525 | fe4c mul direct_3 |
| 526 | TMP = reg_r16(OP1); |
| 527 | TMP = INT16(reg_r16(OP2)) * INT16(TMP); |
| 528 | OP3 &= 0xfc; |
| 529 | reg_w16(OP3, TMP); |
| 530 | reg_w16(OP3+2, TMP >> 16); |
| 531 | next(30); |
| 532 | |
| 533 | fe4d mul immed_3w |
| 534 | TMP = INT16(OP1) * INT16(reg_r16(OP2)); |
| 535 | OP3 &= 0xfc; |
| 536 | reg_w16(OP3, TMP); |
| 537 | reg_w16(OP3+2, TMP >> 16); |
| 538 | next(31); |
| 539 | |
| 540 | fe4e mul indirect_3 |
| 541 | TMP = any_r16(OP1); |
| 542 | TMP = INT16(reg_r16(OP2)) * INT16(TMP); |
| 543 | OP3 &= 0xfc; |
| 544 | reg_w16(OP3, TMP); |
| 545 | reg_w16(OP3+2, TMP >> 16); |
| 546 | post_indirect 2 32 33 // +5 when external |
| 547 | |
| 548 | fe4f mul indexed_3 |
| 549 | TMP = any_r16(OP1); |
| 550 | TMP = INT16(reg_r16(OP2)) * INT16(TMP); |
| 551 | OP3 &= 0xfc; |
| 552 | reg_w16(OP3, TMP); |
| 553 | reg_w16(OP3+2, TMP >> 16); |
| 554 | post_indexed 32 33 // +5 when external |
| 555 | |
| 556 | 50 andb direct_3 |
| 557 | TMP = reg_r8(OP1); |
| 558 | TMP &= reg_r8(OP2); |
| 559 | set_nz8(TMP); |
| 560 | reg_w8(OP3, TMP); |
| 561 | next(5); |
| 562 | |
| 563 | 51 andb immed_3b |
| 564 | TMP = OP1 & reg_r8(OP2); |
| 565 | set_nz8(TMP); |
| 566 | reg_w8(OP3, TMP); |
| 567 | next(5); |
| 568 | |
| 569 | 52 andb indirect_3 |
| 570 | TMP = any_r8(OP1); |
| 571 | TMP &= reg_r8(OP2); |
| 572 | set_nz8(TMP); |
| 573 | reg_w8(OP3, TMP); |
| 574 | post_indirect 1 7 8 // +5 when external |
| 575 | |
| 576 | 53 andb indexed_3 |
| 577 | TMP = any_r8(OP1); |
| 578 | TMP &= reg_r8(OP2); |
| 579 | set_nz8(TMP); |
| 580 | reg_w8(OP3, TMP); |
| 581 | post_indexed 7 8 // +5 when external |
| 582 | |
| 583 | 54 addb direct_3 |
| 584 | TMP = reg_r8(OP1); |
| 585 | TMP = do_addb(reg_r8(OP2), TMP); |
| 586 | reg_w8(OP3, TMP); |
| 587 | next(5); |
| 588 | |
| 589 | 55 addb immed_3b |
| 590 | TMP = do_addb(reg_r8(OP2), OP1); |
| 591 | reg_w8(OP3, TMP); |
| 592 | next(5); |
| 593 | |
| 594 | 56 addb indirect_3 |
| 595 | TMP = any_r8(OP1); |
| 596 | TMP = do_addb(reg_r8(OP2), TMP); |
| 597 | reg_w8(OP3, TMP); |
| 598 | post_indirect 1 7 8 // +5 when external |
| 599 | |
| 600 | 57 addb indexed_3 |
| 601 | TMP = any_r8(OP1); |
| 602 | TMP = do_addb(reg_r8(OP2), TMP); |
| 603 | reg_w8(OP3, TMP); |
| 604 | post_indexed 7 8 // +5 when external |
| 605 | |
| 606 | 58 subb direct_3 |
| 607 | TMP = reg_r8(OP1); |
| 608 | TMP = do_subb(reg_r8(OP2), TMP); |
| 609 | reg_w8(OP3, TMP); |
| 610 | next(5); |
| 611 | |
| 612 | 59 subb immed_3b |
| 613 | TMP = do_subb(reg_r8(OP2), OP1); |
| 614 | reg_w8(OP3, TMP); |
| 615 | next(5); |
| 616 | |
| 617 | 5a subb indirect_3 |
| 618 | TMP = any_r8(OP1); |
| 619 | TMP = do_subb(reg_r8(OP2), TMP); |
| 620 | reg_w8(OP3, TMP); |
| 621 | post_indirect 1 7 8 // +5 when external |
| 622 | |
| 623 | 5b subb indexed_3 |
| 624 | TMP = any_r8(OP1); |
| 625 | TMP = do_subb(reg_r8(OP2), TMP); |
| 626 | reg_w8(OP3, TMP); |
| 627 | post_indexed 7 8 // +5 when external |
| 628 | |
| 629 | 5c mulub direct_3 |
| 630 | TMP = reg_r8(OP1); |
| 631 | TMP *= reg_r8(OP2); |
| 632 | reg_w16(OP3, TMP); |
| 633 | next(18); |
| 634 | |
| 635 | 5d mulub immed_3b |
| 636 | TMP = OP1 * reg_r8(OP2); |
| 637 | reg_w16(OP3, TMP); |
| 638 | next(18); |
| 639 | |
| 640 | 5e mulub indirect_3 |
| 641 | TMP = any_r8(OP1); |
| 642 | TMP *= reg_r8(OP2); |
| 643 | reg_w16(OP3, TMP); |
| 644 | post_indirect 1 20 21 // +5 when external |
| 645 | |
| 646 | 5f mulub indexed_3 |
| 647 | TMP = any_r8(OP1); |
| 648 | TMP = reg_r8(OP2); |
| 649 | reg_w16(OP3, TMP); |
| 650 | post_indexed 20 21 // +5 when external |
| 651 | |
| 652 | fe5c mulb direct_3 |
| 653 | TMP = reg_r8(OP1); |
| 654 | TMP = INT8(reg_r8(OP2)) * INT8(TMP); |
| 655 | reg_w16(OP3, TMP); |
| 656 | next(22); |
| 657 | |
| 658 | fe5d mulb immed_3b |
| 659 | TMP = INT8(OP1) * INT8(reg_r8(OP2)); |
| 660 | reg_w16(OP3, TMP); |
| 661 | next(22); |
| 662 | |
| 663 | fe5e mulb indirect_3 |
| 664 | TMP = any_r8(OP1); |
| 665 | TMP = INT8(reg_r8(OP2)) * INT8(TMP); |
| 666 | reg_w16(OP3, TMP); |
| 667 | post_indirect 1 24 25 // +5 when external |
| 668 | |
| 669 | fe5f mulb indexed_3 |
| 670 | TMP = any_r8(OP1); |
| 671 | TMP = INT8(reg_r8(OP2)) * INT8(TMP); |
| 672 | reg_w16(OP3, TMP); |
| 673 | post_indexed 24 25 // +5 when external |
| 674 | |
| 675 | 60 and direct_2 |
| 676 | TMP = reg_r16(OP1); |
| 677 | TMP &= reg_r16(OP2); |
| 678 | set_nz16(TMP); |
| 679 | reg_w16(OP2, TMP); |
| 680 | next(4); |
| 681 | |
| 682 | 61 and immed_2w |
| 683 | TMP = OP1 & reg_r16(OP2); |
| 684 | set_nz16(TMP); |
| 685 | reg_w16(OP2, TMP); |
| 686 | next(5); |
| 687 | |
| 688 | 62 and indirect_2 |
| 689 | TMP = any_r16(OP1); |
| 690 | TMP &= reg_r16(OP2); |
| 691 | set_nz16(TMP); |
| 692 | reg_w16(OP2, TMP); |
| 693 | post_indirect 2 6 7 // +5 when external |
| 694 | |
| 695 | 63 and indexed_2 |
| 696 | TMP = any_r16(OP1); |
| 697 | TMP &= reg_r16(OP2); |
| 698 | set_nz16(TMP); |
| 699 | reg_w16(OP2, TMP); |
| 700 | post_indexed 6 7 // +5 when external |
| 701 | |
| 702 | 64 add direct_2 |
| 703 | TMP = reg_r16(OP1); |
| 704 | TMP = do_add(reg_r16(OP2), TMP); |
| 705 | reg_w16(OP2, TMP); |
| 706 | next(4); |
| 707 | |
| 708 | 65 add immed_2w |
| 709 | TMP = do_add(reg_r16(OP2), OP1); |
| 710 | reg_w16(OP2, TMP); |
| 711 | next(5); |
| 712 | |
| 713 | 66 add indirect_2 |
| 714 | TMP = any_r16(OP1); |
| 715 | TMP = do_add(reg_r16(OP2), TMP); |
| 716 | reg_w16(OP2, TMP); |
| 717 | post_indirect 2 6 7 // +5 when external |
| 718 | |
| 719 | 67 add indexed_2 |
| 720 | TMP = any_r16(OP1); |
| 721 | TMP = do_add(reg_r16(OP2), TMP); |
| 722 | reg_w16(OP2, TMP); |
| 723 | post_indexed 6 7 // +5 when external |
| 724 | |
| 725 | 68 sub direct_2 |
| 726 | TMP = reg_r16(OP1); |
| 727 | TMP = do_sub(reg_r16(OP2), TMP); |
| 728 | reg_w16(OP2, TMP); |
| 729 | next(4); |
| 730 | |
| 731 | 69 sub immed_2w |
| 732 | TMP = do_sub(reg_r16(OP2), OP1); |
| 733 | reg_w16(OP2, TMP); |
| 734 | next(5); |
| 735 | |
| 736 | 6a sub indirect_2 |
| 737 | TMP = any_r16(OP1); |
| 738 | TMP = do_sub(reg_r16(OP2), TMP); |
| 739 | reg_w16(OP2, TMP); |
| 740 | post_indirect 2 6 7 // +5 when external |
| 741 | |
| 742 | 6b sub indexed_2 |
| 743 | TMP = any_r16(OP1); |
| 744 | TMP = do_sub(reg_r16(OP2), TMP); |
| 745 | reg_w16(OP2, TMP); |
| 746 | post_indexed 6 7 // +5 when external |
| 747 | |
| 748 | 6c mulu direct_2 |
| 749 | OP2 &= 0xfc; |
| 750 | TMP = reg_r16(OP1); |
| 751 | TMP *= reg_r16(OP2); |
| 752 | reg_w16(OP2, TMP); |
| 753 | reg_w16(OP2+2, TMP >> 16); |
| 754 | next(25); |
| 755 | |
| 756 | 6d mulu immed_2w |
| 757 | OP2 &= 0xfc; |
| 758 | TMP = OP1 * reg_r16(OP2); |
| 759 | reg_w16(OP2, TMP); |
| 760 | reg_w16(OP2+2, TMP >> 16); |
| 761 | next(26); |
| 762 | |
| 763 | 6e mulu indirect_2 |
| 764 | OP2 &= 0xfc; |
| 765 | TMP = any_r16(OP1); |
| 766 | TMP *= reg_r16(OP2); |
| 767 | reg_w16(OP2, TMP); |
| 768 | reg_w16(OP2+2, TMP >> 16); |
| 769 | post_indirect 2 27 28 // +5 when external |
| 770 | |
| 771 | 6f mulu indexed_2 |
| 772 | OP2 &= 0xfc; |
| 773 | TMP = any_r16(OP1); |
| 774 | TMP *= reg_r16(OP2); |
| 775 | reg_w16(OP2, TMP); |
| 776 | reg_w16(OP2+2, TMP >> 16); |
| 777 | post_indexed 27 28 // +5 when external |
| 778 | |
| 779 | fe6c mul direct_2 |
| 780 | OP2 &= 0xfc; |
| 781 | TMP = reg_r16(OP1); |
| 782 | TMP = INT16(reg_r16(OP2)) * INT16(TMP); |
| 783 | reg_w16(OP2, TMP); |
| 784 | reg_w16(OP2+2, TMP >> 16); |
| 785 | next(29); |
| 786 | |
| 787 | fe6d mul immed_2w |
| 788 | OP2 &= 0xfc; |
| 789 | TMP = INT16(OP1) * INT16(reg_r16(OP2)); |
| 790 | reg_w16(OP2, TMP); |
| 791 | reg_w16(OP2+2, TMP >> 16); |
| 792 | next(30); |
| 793 | |
| 794 | fe6e mul indirect_2 |
| 795 | OP2 &= 0xfc; |
| 796 | TMP = any_r16(OP1); |
| 797 | TMP = INT16(reg_r16(OP2)) * INT16(TMP); |
| 798 | reg_w16(OP2, TMP); |
| 799 | reg_w16(OP2+2, TMP >> 16); |
| 800 | post_indirect 2 31 32 // +5 when external |
| 801 | |
| 802 | fe6f mul indexed_2 |
| 803 | OP2 &= 0xfc; |
| 804 | TMP = any_r16(OP1); |
| 805 | TMP = INT16(reg_r16(OP2)) * INT16(TMP); |
| 806 | reg_w16(OP2, TMP); |
| 807 | reg_w16(OP2+2, TMP >> 16); |
| 808 | post_indexed 31 32 // +5 when external |
| 809 | |
| 810 | 70 andb direct_2 |
| 811 | TMP = reg_r8(OP1); |
| 812 | TMP &= reg_r8(OP2); |
| 813 | set_nz8(TMP); |
| 814 | reg_w8(OP2, TMP); |
| 815 | next(4); |
| 816 | |
| 817 | 71 andb immed_2b |
| 818 | TMP = OP1 & reg_r8(OP2); |
| 819 | set_nz8(TMP); |
| 820 | reg_w8(OP2, TMP); |
| 821 | next(4); |
| 822 | |
| 823 | 72 andb indirect_2 |
| 824 | TMP = any_r8(OP1); |
| 825 | TMP &= reg_r8(OP2); |
| 826 | set_nz8(TMP); |
| 827 | reg_w8(OP2, TMP); |
| 828 | post_indirect 1 6 7 // +5 when external |
| 829 | |
| 830 | 73 andb indexed_2 |
| 831 | TMP = any_r8(OP1); |
| 832 | TMP &= reg_r8(OP2); |
| 833 | set_nz8(TMP); |
| 834 | reg_w8(OP3, TMP); |
| 835 | post_indexed 6 7 // +5 when external |
| 836 | |
| 837 | 74 addb direct_2 |
| 838 | TMP = reg_r8(OP1); |
| 839 | TMP = do_addb(reg_r8(OP2), TMP); |
| 840 | reg_w8(OP2, TMP); |
| 841 | next(4); |
| 842 | |
| 843 | 75 addb immed_2b |
| 844 | TMP = do_addb(reg_r8(OP2), OP1); |
| 845 | reg_w8(OP2, TMP); |
| 846 | next(4); |
| 847 | |
| 848 | 76 addb indirect_2 |
| 849 | TMP = any_r8(OP1); |
| 850 | TMP = do_addb(reg_r8(OP2), TMP); |
| 851 | reg_w8(OP2, TMP); |
| 852 | post_indirect 1 6 7 // +5 when external |
| 853 | |
| 854 | 77 addb indexed_2 |
| 855 | TMP = any_r8(OP1); |
| 856 | TMP = do_addb(reg_r8(OP2), TMP); |
| 857 | reg_w8(OP2, TMP); |
| 858 | post_indexed 6 7 // +5 when external |
| 859 | |
| 860 | 78 subb direct_2 |
| 861 | TMP = reg_r8(OP1); |
| 862 | TMP = do_subb(reg_r8(OP2), TMP); |
| 863 | reg_w8(OP2, TMP); |
| 864 | next(4); |
| 865 | |
| 866 | 79 subb immed_2b |
| 867 | TMP = do_subb(reg_r8(OP2), OP1); |
| 868 | reg_w8(OP2, TMP); |
| 869 | next(4); |
| 870 | |
| 871 | 7a subb indirect_2 |
| 872 | TMP = any_r8(OP1); |
| 873 | TMP = do_subb(reg_r8(OP2), TMP); |
| 874 | reg_w8(OP2, TMP); |
| 875 | post_indirect 1 6 7 // +5 when external |
| 876 | |
| 877 | 7b subb indexed_2 |
| 878 | TMP = any_r8(OP1); |
| 879 | TMP = do_subb(reg_r8(OP2), TMP); |
| 880 | reg_w8(OP2, TMP); |
| 881 | post_indexed 6 7 // +5 when external |
| 882 | |
| 883 | 7c mulub direct_2 |
| 884 | OP2 &= 0xfe; |
| 885 | TMP = reg_r8(OP1); |
| 886 | TMP *= reg_r8(OP2); |
| 887 | reg_w16(OP2, TMP); |
| 888 | next(17); |
| 889 | |
| 890 | 7d mulub immed_2b |
| 891 | OP2 &= 0xfe; |
| 892 | TMP = OP1 * reg_r8(OP2); |
| 893 | reg_w16(OP2, TMP); |
| 894 | next(17); |
| 895 | |
| 896 | 7e mulub indirect_2 |
| 897 | OP2 &= 0xfe; |
| 898 | TMP = any_r8(OP1); |
| 899 | TMP *= reg_r8(OP2); |
| 900 | reg_w16(OP2, TMP); |
| 901 | post_indirect 1 19 20 // +5 when external |
| 902 | |
| 903 | 7f mulub indexed_2 |
| 904 | OP2 &= 0xfe; |
| 905 | TMP = any_r8(OP1); |
| 906 | TMP *= reg_r8(OP2); |
| 907 | reg_w16(OP2, TMP); |
| 908 | post_indexed 19 20 // +5 when external |
| 909 | |
| 910 | fe7c mulb direct_2 |
| 911 | OP2 &= 0xfe; |
| 912 | TMP = reg_r8(OP1); |
| 913 | TMP = INT8(reg_r16(OP2)) * INT8(TMP); |
| 914 | reg_w16(OP2, TMP); |
| 915 | next(21); |
| 916 | |
| 917 | fe7d mulb immed_2b |
| 918 | OP2 &= 0xfe; |
| 919 | TMP = INT8(OP1) * INT8(reg_r8(OP2)); |
| 920 | reg_w16(OP2, TMP); |
| 921 | next(21); |
| 922 | |
| 923 | fe7e mulb indirect_2 |
| 924 | OP2 &= 0xfe; |
| 925 | TMP = any_r8(OP1); |
| 926 | TMP = INT8(reg_r8(OP2)) * INT8(TMP); |
| 927 | reg_w16(OP2, TMP); |
| 928 | post_indirect 1 23 24 // +5 when external |
| 929 | |
| 930 | fe7f mulb indexed_2 |
| 931 | OP2 &= 0xfe; |
| 932 | TMP = any_r16(OP1); |
| 933 | TMP = INT8(reg_r16(OP2)) * INT8(TMP); |
| 934 | reg_w16(OP2, TMP); |
| 935 | post_indexed 23 24 // +5 when external |
| 936 | |
| 937 | 80 or direct_2 |
| 938 | TMP = reg_r16(OP1); |
| 939 | TMP |= reg_r16(OP2); |
| 940 | set_nz16(TMP); |
| 941 | reg_w16(OP2, TMP); |
| 942 | next(4); |
| 943 | |
| 944 | 81 or immed_2w |
| 945 | TMP = OP1 | reg_r16(OP2); |
| 946 | set_nz16(TMP); |
| 947 | reg_w16(OP2, TMP); |
| 948 | next(5); |
| 949 | |
| 950 | 82 or indirect_2 |
| 951 | TMP = any_r16(OP1); |
| 952 | TMP |= reg_r16(OP2); |
| 953 | set_nz16(TMP); |
| 954 | reg_w16(OP2, TMP); |
| 955 | post_indirect 2 6 7 // +5 when external |
| 956 | |
| 957 | 83 or indexed_2 |
| 958 | TMP = any_r16(OP1); |
| 959 | TMP |= reg_r16(OP2); |
| 960 | set_nz16(TMP); |
| 961 | reg_w16(OP2, TMP); |
| 962 | post_indexed 6 7 // +5 when external |
| 963 | |
| 964 | 84 xor direct_2 |
| 965 | TMP = reg_r16(OP1); |
| 966 | TMP ^= reg_r16(OP2); |
| 967 | set_nz16(TMP); |
| 968 | reg_w16(OP2, TMP); |
| 969 | next(4); |
| 970 | |
| 971 | 85 xor immed_2w |
| 972 | TMP = OP1 ^ reg_r16(OP2); |
| 973 | set_nz16(TMP); |
| 974 | reg_w16(OP2, TMP); |
| 975 | next(5); |
| 976 | |
| 977 | 86 xor indirect_2 |
| 978 | TMP = any_r16(OP1); |
| 979 | TMP ^= reg_r16(OP2); |
| 980 | set_nz16(TMP); |
| 981 | reg_w16(OP2, TMP); |
| 982 | post_indirect 2 6 7 // +5 when external |
| 983 | |
| 984 | 87 xor indexed_2 |
| 985 | TMP = any_r16(OP1); |
| 986 | TMP ^= reg_r16(OP2); |
| 987 | set_nz16(TMP); |
| 988 | reg_w16(OP2, TMP); |
| 989 | post_indexed 6 7 // +5 when external |
| 990 | |
| 991 | 88 cmp direct_2 |
| 992 | TMP = reg_r16(OP1); |
| 993 | do_sub(reg_r16(OP2), TMP); |
| 994 | next(4); |
| 995 | |
| 996 | 89 cmp immed_2w |
| 997 | do_sub(reg_r16(OP2), OP1); |
| 998 | next(5); |
| 999 | |
| 1000 | 8a cmp indirect_2 |
| 1001 | TMP = any_r16(OP1); |
| 1002 | do_sub(reg_r16(OP2), TMP); |
| 1003 | post_indirect 2 6 7 // +5 when external |
| 1004 | |
| 1005 | 8b cmp indexed_2 |
| 1006 | TMP = any_r16(OP1); |
| 1007 | do_sub(reg_r16(OP2), TMP); |
| 1008 | post_indexed 6 7 // +5 when external |
| 1009 | |
| 1010 | 8c divu direct_2 |
| 1011 | |
| 1012 | 8d divu immed_2w |
| 1013 | |
| 1014 | 8e divu indirect_2 |
| 1015 | |
| 1016 | 8f divu indexed_2 |
| 1017 | |
| 1018 | fe8c div direct_2 |
| 1019 | |
| 1020 | fe8d div immed_2w |
| 1021 | |
| 1022 | fe8e div indirect_2 |
| 1023 | |
| 1024 | fe8f div indexed_2 |
| 1025 | |
| 1026 | 90 orb direct_2 |
| 1027 | TMP = reg_r8(OP1); |
| 1028 | TMP |= reg_r8(OP2); |
| 1029 | set_nz8(TMP); |
| 1030 | reg_w8(OP2, TMP); |
| 1031 | next(4); |
| 1032 | |
| 1033 | 91 orb immed_2b |
| 1034 | TMP = OP1 | reg_r8(OP2); |
| 1035 | set_nz8(TMP); |
| 1036 | reg_w8(OP2, TMP); |
| 1037 | next(4); |
| 1038 | |
| 1039 | 92 orb indirect_2 |
| 1040 | TMP = any_r8(OP1); |
| 1041 | TMP |= reg_r8(OP2); |
| 1042 | set_nz8(TMP); |
| 1043 | reg_w8(OP2, TMP); |
| 1044 | post_indirect 1 6 7 // +5 when external |
| 1045 | |
| 1046 | 93 orb indexed_2 |
| 1047 | TMP = any_r8(OP1); |
| 1048 | TMP |= reg_r8(OP2); |
| 1049 | set_nz8(TMP); |
| 1050 | reg_w8(OP2, TMP); |
| 1051 | post_indexed 6 7 // +5 when external |
| 1052 | |
| 1053 | 94 xorb direct_2 |
| 1054 | TMP = reg_r8(OP1); |
| 1055 | TMP ^= reg_r8(OP2); |
| 1056 | set_nz8(TMP); |
| 1057 | reg_w8(OP2, TMP); |
| 1058 | next(4); |
| 1059 | |
| 1060 | 95 xorb immed_2b |
| 1061 | TMP = OP1 ^ reg_r8(OP2); |
| 1062 | set_nz8(TMP); |
| 1063 | reg_w8(OP2, TMP); |
| 1064 | next(4); |
| 1065 | |
| 1066 | 96 xorb indirect_2 |
| 1067 | TMP = any_r8(OP1); |
| 1068 | TMP ^= reg_r8(OP2); |
| 1069 | set_nz8(TMP); |
| 1070 | reg_w8(OP2, TMP); |
| 1071 | post_indirect 1 6 7 // +5 when external |
| 1072 | |
| 1073 | 97 xorb indexed_2 |
| 1074 | TMP = any_r8(OP1); |
| 1075 | TMP ^= reg_r8(OP2); |
| 1076 | set_nz8(TMP); |
| 1077 | reg_w8(OP2, TMP); |
| 1078 | post_indexed 6 7 // +5 when external |
| 1079 | |
| 1080 | 98 cmpb direct_2 |
| 1081 | TMP = reg_r8(OP1); |
| 1082 | do_subb(reg_r8(OP2), TMP); |
| 1083 | next(4); |
| 1084 | |
| 1085 | 99 cmpb immed_2b |
| 1086 | do_subb(reg_r8(OP2), OP1); |
| 1087 | next(4); |
| 1088 | |
| 1089 | 9a cmpb indirect_2 |
| 1090 | TMP = any_r8(OP1); |
| 1091 | do_subb(reg_r8(OP2), TMP); |
| 1092 | post_indirect 2 6 7 // +5 when external |
| 1093 | |
| 1094 | 9b cmpb indexed_2 |
| 1095 | TMP = any_r8(OP1); |
| 1096 | do_subb(reg_r8(OP2), TMP); |
| 1097 | post_indexed 6 7 // +5 when external |
| 1098 | |
| 1099 | 9c divub direct_2 |
| 1100 | PSW &= ~F_V; |
| 1101 | OP1 = reg_r8(OP1); |
| 1102 | if(OP1) { |
| 1103 | TMP = reg_r16(OP2); |
| 1104 | UINT32 TMP2 = TMP / OP1; |
| 1105 | if(TMP2 > 255) |
| 1106 | PSW |= F_V|F_VT; |
| 1107 | TMP = TMP % OP1; |
| 1108 | TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8); |
| 1109 | reg_w16(OP2, TMP); |
| 1110 | } |
| 1111 | next(17); |
| 1112 | |
| 1113 | 9d divub immed_2b |
| 1114 | PSW &= ~F_V; |
| 1115 | if(OP1) { |
| 1116 | TMP = reg_r16(OP2); |
| 1117 | UINT32 TMP2 = TMP / OP1; |
| 1118 | if(TMP2 > 255) |
| 1119 | PSW |= F_V|F_VT; |
| 1120 | TMP = TMP % OP1; |
| 1121 | TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8); |
| 1122 | reg_w16(OP2, TMP); |
| 1123 | } |
| 1124 | next(17); |
| 1125 | |
| 1126 | 9e divub indirect_2 |
| 1127 | PSW &= ~F_V; |
| 1128 | UINT32 d = any_r8(OP1); |
| 1129 | if(d) { |
| 1130 | TMP = reg_r16(OP2); |
| 1131 | UINT32 TMP2 = TMP / d; |
| 1132 | if(TMP2 > 255) |
| 1133 | PSW |= F_V|F_VT; |
| 1134 | TMP = TMP % d; |
| 1135 | TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8); |
| 1136 | reg_w16(OP2, TMP); |
| 1137 | } |
| 1138 | post_indirect 1 20 21 // +4 when external |
| 1139 | |
| 1140 | 9f divub indexed_2 |
| 1141 | PSW &= ~F_V; |
| 1142 | UINT32 d = any_r8(OP1); |
| 1143 | if(d) { |
| 1144 | TMP = reg_r16(OP2); |
| 1145 | UINT32 TMP2 = TMP / d; |
| 1146 | if(TMP2 > 255) |
| 1147 | PSW |= F_V|F_VT; |
| 1148 | TMP = TMP % d; |
| 1149 | TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8); |
| 1150 | reg_w16(OP2, TMP); |
| 1151 | } |
| 1152 | post_indexed 20 21 // +4 when external |
| 1153 | |
| 1154 | fe9c divb direct_2 |
| 1155 | PSW &= ~F_V; |
| 1156 | OP1 = reg_r8(OP1); |
| 1157 | if(OP1) { |
| 1158 | TMP = reg_r16(OP2); |
| 1159 | UINT32 TMP2 = INT16(TMP) / INT8(OP1); |
| 1160 | if(INT8(TMP2) > 127 || INT8(TMP2) < -128) |
| 1161 | PSW |= F_V|F_VT; |
| 1162 | TMP = INT16(TMP) % INT8(OP1); |
| 1163 | TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8); |
| 1164 | reg_w16(OP2, TMP); |
| 1165 | } |
| 1166 | next(21); |
| 1167 | |
| 1168 | fe9d divb immed_2b |
| 1169 | PSW &= ~F_V; |
| 1170 | OP1 = reg_r8(OP1); |
| 1171 | if(OP1) { |
| 1172 | TMP = reg_r16(OP2); |
| 1173 | UINT32 TMP2 = INT16(TMP) / INT8(OP1); |
| 1174 | if(INT8(TMP2) > 127 || INT8(TMP2) < -128) |
| 1175 | PSW |= F_V|F_VT; |
| 1176 | TMP = INT16(TMP) % INT8(OP1); |
| 1177 | TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8); |
| 1178 | reg_w16(OP2, TMP); |
| 1179 | } |
| 1180 | next(21); |
| 1181 | |
| 1182 | fe9e divb indirect_2 |
| 1183 | |
| 1184 | fe9f divb indexed_2 |
| 1185 | |
| 1186 | a0 ld direct_2 |
| 1187 | reg_w16(OP2, reg_r16(OP1)); |
| 1188 | next(4); |
| 1189 | |
| 1190 | a1 ld immed_2w |
| 1191 | reg_w16(OP2, OP1); |
| 1192 | next(5); |
| 1193 | |
| 1194 | a2 ld indirect_2 |
| 1195 | reg_w16(OP2, any_r16(OP1)); |
| 1196 | post_indirect 2 6 7 // +5 when external |
| 1197 | |
| 1198 | a3 ld indexed_2 |
| 1199 | reg_w16(OP2, any_r16(OP1)); |
| 1200 | post_indexed 6 7 // +5 when external |
| 1201 | |
| 1202 | a4 addc direct_2 |
| 1203 | |
| 1204 | a5 addc immed_2w |
| 1205 | |
| 1206 | a6 addc indirect_2 |
| 1207 | |
| 1208 | a7 addc indexed_2 |
| 1209 | |
| 1210 | a8 subc direct_2 |
| 1211 | |
| 1212 | a9 subc immed_2w |
| 1213 | |
| 1214 | aa subc indirect_2 |
| 1215 | |
| 1216 | ab subc indexed_2 |
| 1217 | |
| 1218 | ac ldbze direct_2 |
| 1219 | reg_w16(OP2, UINT8(reg_r8(OP1))); |
| 1220 | next(4); |
| 1221 | |
| 1222 | ad ldbze immed_2b |
| 1223 | reg_w16(OP2, UINT8(OP1)); |
| 1224 | next(4); |
| 1225 | |
| 1226 | ae ldbze indirect_2 |
| 1227 | reg_w16(OP2, UINT8(any_r8(OP1))); |
| 1228 | post_indirect 1 6 7 // +5 when external |
| 1229 | |
| 1230 | af ldbze indexed_2 |
| 1231 | reg_w16(OP2, UINT8(any_r8(OP1))); |
| 1232 | post_indexed 6 7 // +5 when external |
| 1233 | |
| 1234 | b0 ldb direct_2 |
| 1235 | reg_w8(OP2, reg_r8(OP1)); |
| 1236 | next(4); |
| 1237 | |
| 1238 | b1 ldb immed_2b |
| 1239 | reg_w8(OP2, OP1); |
| 1240 | next(4); |
| 1241 | |
| 1242 | b2 ldb indirect_2 |
| 1243 | reg_w8(OP2, any_r8(OP1)); |
| 1244 | post_indirect 1 6 7 // +5 when external |
| 1245 | |
| 1246 | b3 ldb indexed_2 |
| 1247 | reg_w8(OP2, any_r8(OP1)); |
| 1248 | post_indexed 6 7 // +5 when external |
| 1249 | |
| 1250 | b4 addcb direct_2 |
| 1251 | |
| 1252 | b5 addcb immed_2w |
| 1253 | |
| 1254 | b6 addcb indirect_2 |
| 1255 | |
| 1256 | b7 addcb indexed_2 |
| 1257 | |
| 1258 | b8 subcb direct_2 |
| 1259 | |
| 1260 | b9 subcb immed_2w |
| 1261 | |
| 1262 | ba subcb indirect_2 |
| 1263 | |
| 1264 | bb subcb indexed_2 |
| 1265 | |
| 1266 | bc ldbse direct_2 |
| 1267 | reg_w16(OP2, INT8(reg_r8(OP1))); |
| 1268 | next(4); |
| 1269 | |
| 1270 | bd ldbse immed_2b |
| 1271 | reg_w16(OP2, INT8(OP1)); |
| 1272 | next(4); |
| 1273 | |
| 1274 | be ldbse indirect_2 |
| 1275 | reg_w16(OP2, INT8(any_r8(OP1))); |
| 1276 | post_indirect 1 6 7 // +5 when external |
| 1277 | |
| 1278 | bf ldbse indexed_2 |
| 1279 | reg_w16(OP2, INT8(any_r8(OP1))); |
| 1280 | post_indexed 6 7 // +5 when external |
| 1281 | |
| 1282 | c0 st direct_2 |
| 1283 | reg_w16(OP1, reg_r16(OP2)); |
| 1284 | next(4); |
| 1285 | |
| 1286 | c1 bmov direct_2 196 |
| 1287 | |
| 1288 | c2 st indirect_2 |
| 1289 | any_w16(OP1, reg_r16(OP2)); |
| 1290 | post_indirect 2 7 8 // +4 when external |
| 1291 | |
| 1292 | c3 st indexed_2 |
| 1293 | any_w16(OP1, reg_r16(OP2)); |
| 1294 | post_indexed 7 8 // +4 when external |
| 1295 | |
| 1296 | c4 stb direct_2 |
| 1297 | reg_w8(OP1, reg_r8(OP2)); |
| 1298 | next(4); |
| 1299 | |
| 1300 | c5 cmpl direct_2 196 |
| 1301 | |
| 1302 | c6 stb indirect_2 |
| 1303 | any_w8(OP1, reg_r8(OP2)); |
| 1304 | post_indirect 1 7 8 // +4 when external |
| 1305 | |
| 1306 | c7 stb indexed_2 |
| 1307 | any_w8(OP1, reg_r8(OP2)); |
| 1308 | post_indexed 7 8 // +5 when external |
| 1309 | |
| 1310 | c8 push direct_1 |
| 1311 | TMP = reg_r16(0x18); |
| 1312 | TMP -= 2; |
| 1313 | reg_w16(0x18, TMP); |
| 1314 | OP1 = reg_r16(OP1); |
| 1315 | any_w16(TMP, OP1); |
| 1316 | next(8); // +4 is external sp |
| 1317 | |
| 1318 | c9 push immed_1w |
| 1319 | TMP = reg_r16(0x18); |
| 1320 | TMP -= 2; |
| 1321 | reg_w16(0x18, TMP); |
| 1322 | any_w16(TMP, OP1); |
| 1323 | next(8); // +4 is external sp |
| 1324 | |
| 1325 | ca push indirect_1 |
| 1326 | TMP = reg_r16(0x18); |
| 1327 | TMP -= 2; |
| 1328 | reg_w16(0x18, TMP); |
| 1329 | OP1 = any_r16(OP1); |
| 1330 | any_w16(TMP, OP1); |
| 1331 | post_indirect 2 11 12 // +4 when external |
| 1332 | |
| 1333 | cb push indexed_1 |
| 1334 | TMP = reg_r16(0x18); |
| 1335 | TMP -= 2; |
| 1336 | reg_w16(0x18, TMP); |
| 1337 | OP1 = any_r16(OP1); |
| 1338 | any_w16(TMP, OP1); |
| 1339 | post_indexed 11 12 // +4 when external |
| 1340 | |
| 1341 | cc pop direct_1 |
| 1342 | TMP = reg_r16(0x18); |
| 1343 | reg_w16(0x18, TMP+2); |
| 1344 | TMP = any_r16(TMP); |
| 1345 | reg_w16(OP1, TMP); |
| 1346 | next(12); // +2 when external sp |
| 1347 | |
| 1348 | cd bmovi direct_2 196 |
| 1349 | |
| 1350 | ce pop indirect_1 |
| 1351 | TMP = reg_r16(0x18); |
| 1352 | reg_w16(0x18, TMP+2); |
| 1353 | TMP = any_r16(TMP); |
| 1354 | if((OPI & 0xfe) == 0x18) |
| 1355 | OP1 += 2; |
| 1356 | any_w16(OP1, TMP); |
| 1357 | post_indirect 2 14 14 // +2 when external sp, +4 when external write |
| 1358 | |
| 1359 | ce pop indirect_1 196 |
| 1360 | TMP = reg_r16(0x18); |
| 1361 | reg_w16(0x18, TMP+2); |
| 1362 | TMP = any_r16(TMP); |
| 1363 | if((OPI & 0xfe) == 0x18) |
| 1364 | OP1 += 2; |
| 1365 | any_w16(OP1, TMP); |
| 1366 | post_indirect 2 14 14 // +2 when external sp, +4 when external write |
| 1367 | |
| 1368 | cf pop indexed_1 |
| 1369 | TMP = reg_r16(0x18); |
| 1370 | reg_w16(0x18, TMP+2); |
| 1371 | TMP = any_r16(TMP); |
| 1372 | any_w16(OP1, TMP); |
| 1373 | post_indexed 14 14 // +2 when external sp, +4 when external write |
| 1374 | |
| 1375 | cf pop indexed_1 196 |
| 1376 | TMP = reg_r16(0x18); |
| 1377 | reg_w16(0x18, TMP+2); |
| 1378 | TMP = any_r16(TMP); |
| 1379 | if((OPI & 0xfe) == 0x18) |
| 1380 | OP1 += 2; |
| 1381 | any_w16(OP1, TMP); |
| 1382 | post_indexed 14 14 // +2 when external sp, +4 when external write |
| 1383 | |
| 1384 | d0 jnst rel8 |
| 1385 | if(!(PSW & F_ST)) { |
| 1386 | PC += OP1; |
| 1387 | next(8); |
| 1388 | } else { |
| 1389 | PSW &= ~F_VT; |
| 1390 | next(4); |
| 1391 | } |
| 1392 | |
| 1393 | d1 jnh rel8 |
| 1394 | if((PSW & (F_Z|F_N)) != F_C) { |
| 1395 | PC += OP1; |
| 1396 | next(8); |
| 1397 | } else { |
| 1398 | next(4); |
| 1399 | } |
| 1400 | |
| 1401 | d2 jgt rel8 |
| 1402 | if(!(PSW & (F_Z|F_N))) { |
| 1403 | PC += OP1; |
| 1404 | next(8); |
| 1405 | } else { |
| 1406 | next(4); |
| 1407 | } |
| 1408 | |
| 1409 | d3 jnc rel8 |
| 1410 | if(!(PSW & F_C)) { |
| 1411 | PC += OP1; |
| 1412 | next(8); |
| 1413 | } else { |
| 1414 | next(4); |
| 1415 | } |
| 1416 | |
| 1417 | d4 jnvt rel8 |
| 1418 | if(!(PSW & F_VT)) { |
| 1419 | PC += OP1; |
| 1420 | next(8); |
| 1421 | } else { |
| 1422 | PSW &= ~F_VT; |
| 1423 | next(4); |
| 1424 | } |
| 1425 | |
| 1426 | d5 jnv rel8 |
| 1427 | if(!(PSW & F_V)) { |
| 1428 | PC += OP1; |
| 1429 | next(8); |
| 1430 | } else { |
| 1431 | next(4); |
| 1432 | } |
| 1433 | |
| 1434 | d6 jge rel8 |
| 1435 | if(!(PSW & F_N)) { |
| 1436 | PC += OP1; |
| 1437 | next(8); |
| 1438 | } else { |
| 1439 | next(4); |
| 1440 | } |
| 1441 | |
| 1442 | d7 jne rel8 |
| 1443 | if(!(PSW & F_Z)) { |
| 1444 | PC += OP1; |
| 1445 | next(8); |
| 1446 | } else { |
| 1447 | next(4); |
| 1448 | } |
| 1449 | |
| 1450 | d8 jst rel8 |
| 1451 | if(PSW & F_ST) { |
| 1452 | PC += OP1; |
| 1453 | next(8); |
| 1454 | } else { |
| 1455 | PSW &= ~F_VT; |
| 1456 | next(4); |
| 1457 | } |
| 1458 | |
| 1459 | d9 jh rel8 |
| 1460 | if((PSW & (F_Z|F_N)) == F_C) { |
| 1461 | PC += OP1; |
| 1462 | next(8); |
| 1463 | } else { |
| 1464 | next(4); |
| 1465 | } |
| 1466 | |
| 1467 | da jle rel8 |
| 1468 | if(PSW & (F_Z|F_N)) { |
| 1469 | PC += OP1; |
| 1470 | next(8); |
| 1471 | } else { |
| 1472 | next(4); |
| 1473 | } |
| 1474 | |
| 1475 | db jc rel8 |
| 1476 | if(PSW & F_C) { |
| 1477 | PC += OP1; |
| 1478 | next(8); |
| 1479 | } else { |
| 1480 | next(4); |
| 1481 | } |
| 1482 | |
| 1483 | dc jvt rel8 |
| 1484 | if(PSW & F_VT) { |
| 1485 | PSW &= ~F_VT; |
| 1486 | PC += OP1; |
| 1487 | next(8); |
| 1488 | } else { |
| 1489 | next(4); |
| 1490 | } |
| 1491 | |
| 1492 | dd jv rel8 |
| 1493 | if(PSW & F_V) { |
| 1494 | PC += OP1; |
| 1495 | next(8); |
| 1496 | } else { |
| 1497 | next(4); |
| 1498 | } |
| 1499 | |
| 1500 | de jlt rel8 |
| 1501 | if(PSW & F_N) { |
| 1502 | PC += OP1; |
| 1503 | next(8); |
| 1504 | } else { |
| 1505 | next(4); |
| 1506 | } |
| 1507 | |
| 1508 | df je rel8 |
| 1509 | if(PSW & F_Z) { |
| 1510 | PC += OP1; |
| 1511 | next(8); |
| 1512 | } else { |
| 1513 | next(4); |
| 1514 | } |
| 1515 | |
| 1516 | e0 djnz rrel8 |
| 1517 | TMP = reg_r8(OP2); |
| 1518 | TMP = UINT8(TMP-1); |
| 1519 | reg_w8(OP2, TMP); |
| 1520 | if(TMP) { |
| 1521 | PC += OP1; |
| 1522 | next(9); |
| 1523 | } else { |
| 1524 | next(5); |
| 1525 | } |
| 1526 | |
| 1527 | e1 djnzw rrel8 196 |
| 1528 | TMP = reg_r16(OP2); |
| 1529 | TMP = TMP-1; |
| 1530 | reg_w16(OP2, TMP); |
| 1531 | if(TMP) { |
| 1532 | PC += OP1; |
| 1533 | next(10); |
| 1534 | } else { |
| 1535 | next(6); |
| 1536 | } |
| 1537 | |
| 1538 | e3 br indirect_1n |
| 1539 | PC = OP1; |
| 1540 | next(8); |
| 1541 | |
| 1542 | e7 ljmp rel16 |
| 1543 | PC += OP1; |
| 1544 | next(8); |
| 1545 | |
| 1546 | ef lcall rel16 |
| 1547 | TMP = reg_r16(0x18); |
| 1548 | TMP -= 2; |
| 1549 | reg_w16(0x18, TMP); |
| 1550 | any_w16(TMP, PC); |
| 1551 | PC += OP1; |
| 1552 | next(13); // +3 for external sp |
| 1553 | |
| 1554 | f0 ret none |
| 1555 | TMP = reg_r16(0x18); |
| 1556 | reg_w16(0x18, TMP+2); |
| 1557 | PC = any_r16(TMP); |
| 1558 | next(12); // +4 for external sp |
| 1559 | |
| 1560 | f2 pushf none |
| 1561 | TMP = reg_r16(0x18); |
| 1562 | TMP -= 2; |
| 1563 | reg_w16(0x18, TMP); |
| 1564 | any_w16(TMP, PSW); |
| 1565 | PSW = 0x0000; |
| 1566 | check_irq(); |
| 1567 | next_noirq(8); // +4 for external sp |
| 1568 | |
| 1569 | f3 popf none |
| 1570 | TMP = reg_r16(0x18); |
| 1571 | reg_w16(0x18, TMP+2); |
| 1572 | PSW = any_r16(TMP); |
| 1573 | check_irq(); |
| 1574 | next_noirq(9); // +4 for external sp |
| 1575 | |
| 1576 | f4 pusha none 196 |
| 1577 | |
| 1578 | f5 popa none |
| 1579 | |
| 1580 | f6 idlpd none 196 |
| 1581 | |
| 1582 | f7 trap none |
| 1583 | TMP = reg_r16(0x18); |
| 1584 | TMP -= 2; |
| 1585 | reg_w16(0x18, TMP); |
| 1586 | any_w16(TMP, PC); |
| 1587 | PC = any_r16(0x2010); |
| 1588 | next_noirq(21); // +3 for external sp |
| 1589 | |
| 1590 | f8 clrc none |
| 1591 | PSW &= ~F_C; |
| 1592 | next(4); |
| 1593 | |
| 1594 | f9 setc none |
| 1595 | PSW |= F_C; |
| 1596 | next(4); |
| 1597 | |
| 1598 | fa di none |
| 1599 | PSW &= ~F_I; |
| 1600 | check_irq(); |
| 1601 | next_noirq(4); |
| 1602 | |
| 1603 | fb ei none |
| 1604 | PSW |= F_I; |
| 1605 | check_irq(); |
| 1606 | next_noirq(4); |
| 1607 | |
| 1608 | fc clrvt none |
| 1609 | PSW &= ~F_VT; |
| 1610 | next(4); |
| 1611 | |
| 1612 | fd nop none |
| 1613 | next(4); |
| 1614 | |
| 1615 | ff rst none |
| 1616 | PC = 0x2080; |
| 1617 | next(4); |
trunk/src/emu/cpu/mcs96/mcs96make.py
| r19633 | r19634 | |
| 1 | #!/usr/bin/python |
| 2 | |
| 3 | USAGE = """ |
| 4 | Usage: |
| 5 | %s mcs96ops.lst mcs96.inc |
| 6 | """ |
| 7 | import sys |
| 8 | |
| 9 | def save_full_one(f, t, name, source): |
| 10 | print >>f, "void %s_device::%s_full()" % (t, name) |
| 11 | print >>f, "{" |
| 12 | for line in source: |
| 13 | print >>f, line |
| 14 | print >>f, "}" |
| 15 | print >>f |
| 16 | |
| 17 | class Opcode: |
| 18 | def __init__(self, rng, name, amode, is_196, ea): |
| 19 | rng1 = rng.split("-") |
| 20 | self.rng_start = int(rng1[0], 16) |
| 21 | if len(rng1) == 2: |
| 22 | self.rng_end = int(rng1[1], 16) |
| 23 | else: |
| 24 | self.rng_end = self.rng_start |
| 25 | self.name = name |
| 26 | self.amode = amode |
| 27 | self.source = [] |
| 28 | self.is_196 = is_196 |
| 29 | if amode in ea: |
| 30 | for line in ea[amode].source: |
| 31 | self.source.append(line) |
| 32 | |
| 33 | def add_source_line(self, line): |
| 34 | self.source.append(line) |
| 35 | |
| 36 | class Special: |
| 37 | def __init__(self, name): |
| 38 | self.name = name |
| 39 | self.source = [] |
| 40 | |
| 41 | def add_source_line(self, line): |
| 42 | self.source.append(line) |
| 43 | |
| 44 | class Macro: |
| 45 | def __init__(self, tokens): |
| 46 | self.name = tokens[1] |
| 47 | self.params = [] |
| 48 | for i in range(2, len(tokens)): |
| 49 | self.params.append(tokens[i]) |
| 50 | self.source = [] |
| 51 | |
| 52 | def add_source_line(self, line): |
| 53 | self.source.append(line) |
| 54 | |
| 55 | def apply(self, target, tokens): |
| 56 | values = [] |
| 57 | for i in range(1, len(tokens)): |
| 58 | values.append(tokens[i]) |
| 59 | for i in range(0, len(self.source)): |
| 60 | line = self.source[i] |
| 61 | for i in range(0, len(self.params)): |
| 62 | line = line.replace(self.params[i], values[i]) |
| 63 | target.add_source_line(line) |
| 64 | |
| 65 | class OpcodeList: |
| 66 | def __init__(self, fname, is_196): |
| 67 | self.opcode_info = [] |
| 68 | self.opcode_per_id = {} |
| 69 | self.ea = {} |
| 70 | self.macros = {} |
| 71 | try: |
| 72 | f = open(fname, "r") |
| 73 | except Exception, err: |
| 74 | print "Cannot read opcodes file %s [%s]" % (fname, err) |
| 75 | sys.exit(1) |
| 76 | |
| 77 | opc = None |
| 78 | for line in f: |
| 79 | if line.startswith("#"): |
| 80 | continue |
| 81 | line = line.rstrip() |
| 82 | if not line: |
| 83 | continue |
| 84 | if line.startswith(" ") or line.startswith("\t"): |
| 85 | # append instruction to last opcode, maybe expand a macro |
| 86 | tokens = line.split() |
| 87 | if tokens[0] in self.macros: |
| 88 | self.macros[tokens[0]].apply(inf, tokens) |
| 89 | else: |
| 90 | inf.add_source_line(line) |
| 91 | else: |
| 92 | # New something |
| 93 | tokens = line.split() |
| 94 | # Addressing mode header |
| 95 | if tokens[0] == "eadr": |
| 96 | inf = Special(tokens[1]) |
| 97 | self.ea[inf.name] = inf |
| 98 | elif tokens[0] == "fetch": |
| 99 | inf = Special(tokens[0]) |
| 100 | self.fetch = inf |
| 101 | elif tokens[0] == "fetch_noirq": |
| 102 | inf = Special(tokens[0]) |
| 103 | self.fetch_noirq = inf |
| 104 | elif tokens[0] == "macro": |
| 105 | inf = Macro(tokens) |
| 106 | self.macros[inf.name] = inf |
| 107 | else: |
| 108 | inf = Opcode(tokens[0], tokens[1], tokens[2], len(tokens) >= 4 and tokens[3] == "196", self.ea) |
| 109 | self.opcode_info.append(inf) |
| 110 | if is_196 or not inf.is_196: |
| 111 | for i in range(inf.rng_start, inf.rng_end+1): |
| 112 | self.opcode_per_id[i] = inf |
| 113 | |
| 114 | def save_dasm(self, f, t): |
| 115 | print >>f, "const %s_device::disasm_entry %s_device::disasm_entries[0x100] = {" % (t, t) |
| 116 | for i in range(0, 0x100): |
| 117 | if i in self.opcode_per_id: |
| 118 | opc = self.opcode_per_id[i] |
| 119 | alt = "NULL" |
| 120 | if i + 0xfe00 in self.opcode_per_id: |
| 121 | alt = "\"" + self.opcode_per_id[i+0xfe00].name + "\"" |
| 122 | if opc.name == "scall" or opc.name == "lcall": |
| 123 | flags = "DASMFLAG_STEP_OVER" |
| 124 | elif opc.name == "rts": |
| 125 | flags = "DASMFLAG_STEP_OUT" |
| 126 | else: |
| 127 | flags = "0" |
| 128 | print >>f, "\t{ \"%s\", %s, DASM_%s, %s }," % (opc.name, alt, opc.amode, flags) |
| 129 | else: |
| 130 | print >>f, "\t{ \"???\", NULL, DASM_none, 0 }," |
| 131 | print >>f, "};" |
| 132 | print >>f |
| 133 | |
| 134 | def save_opcodes(self, f, t): |
| 135 | pf = "" |
| 136 | is_196 = False |
| 137 | if t == "i8xc196": |
| 138 | pf = "_196" |
| 139 | is_196 = True |
| 140 | for opc in self.opcode_info: |
| 141 | if opc.is_196 == is_196: |
| 142 | save_full_one(f, t, opc.name + "_" + opc.amode + pf, opc.source) |
| 143 | if not is_196: |
| 144 | save_full_one(f, t, "fetch", self.fetch.source) |
| 145 | save_full_one(f, t, "fetch_noirq", self.fetch_noirq.source) |
| 146 | |
| 147 | def save_exec(self, f, t): |
| 148 | print >>f, "void %s_device::do_exec_full()" % t |
| 149 | print >>f, "{" |
| 150 | print >>f, "\tswitch(inst_state) {" |
| 151 | for i in range(0x000, 0x200): |
| 152 | opc = None |
| 153 | if i >= 0x100 and i-0x100+0xfe00 in self.opcode_per_id: |
| 154 | opc = self.opcode_per_id[i-0x100+0xfe00] |
| 155 | if opc == None and (i & 0xff) in self.opcode_per_id: |
| 156 | opc = self.opcode_per_id[i & 0xff] |
| 157 | if opc != None: |
| 158 | nm = opc.name + "_" + opc.amode |
| 159 | if opc.is_196: |
| 160 | nm = nm + "_196" |
| 161 | print >>f, "\tcase 0x%03x: %s_full(); break;" % (i, nm) |
| 162 | print >>f, "\tcase 0x200: fetch_full(); break;" |
| 163 | print >>f, "\tcase 0x201: fetch_noirq_full(); break;" |
| 164 | print >>f, "\t}" |
| 165 | print >>f, "}" |
| 166 | |
| 167 | def main(argv): |
| 168 | if len(argv) != 4: |
| 169 | print USAGE % argv[0] |
| 170 | return 1 |
| 171 | |
| 172 | t = argv[1] |
| 173 | opcodes = OpcodeList(argv[2], t == "i8xc196") |
| 174 | |
| 175 | try: |
| 176 | f = open(argv[3], "w") |
| 177 | except Exception, err: |
| 178 | logging.error("cannot write file %s [%s]", fname, err) |
| 179 | sys.exit(1) |
| 180 | |
| 181 | if t != "mcs96": |
| 182 | opcodes.save_dasm(f, t) |
| 183 | if t != "i8x9x": |
| 184 | opcodes.save_opcodes(f, t) |
| 185 | if t != "mcs96": |
| 186 | opcodes.save_exec(f, t) |
| 187 | f.close() |
| 188 | |
| 189 | # ====================================================================== |
| 190 | if __name__ == "__main__": |
| 191 | sys.exit(main(sys.argv)) |
| 192 | |
trunk/src/emu/cpu/mcs96/mcs96.h
| r19633 | r19634 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | mcs96.h |
| 4 | |
| 5 | MCS96 |
| 6 | |
| 7 | **************************************************************************** |
| 8 | |
| 9 | Copyright Olivier Galibert |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions are |
| 14 | met: |
| 15 | |
| 16 | * Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | * Redistributions in binary form must reproduce the above copyright |
| 19 | notice, this list of conditions and the following disclaimer in |
| 20 | the documentation and/or other materials provided with the |
| 21 | distribution. |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be |
| 23 | used to endorse or promote products derived from this software |
| 24 | without specific prior written permission. |
| 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 29 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 36 | POSSIBILITY OF SUCH DAMAGE. |
| 37 | |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #ifndef __MCS96_H__ |
| 41 | #define __MCS96_H__ |
| 42 | |
| 43 | class mcs96_device : public cpu_device { |
| 44 | public: |
| 45 | mcs96_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int data_width); |
| 46 | |
| 47 | UINT64 get_cycle(); |
| 48 | |
| 49 | protected: |
| 50 | enum { |
| 51 | STATE_FETCH = 0x200, |
| 52 | STATE_FETCH_NOIRQ = 0x201, |
| 53 | }; |
| 54 | |
| 55 | enum { |
| 56 | F_ST = 0x0100, |
| 57 | F_I = 0x0200, |
| 58 | F_C = 0x0800, |
| 59 | F_VT = 0x1000, |
| 60 | F_V = 0x2000, |
| 61 | F_N = 0x4000, |
| 62 | F_Z = 0x8000, |
| 63 | }; |
| 64 | |
| 65 | struct disasm_entry { |
| 66 | const char *opcode, *opcode_fe; |
| 67 | int mode; |
| 68 | offs_t flags; |
| 69 | }; |
| 70 | |
| 71 | enum { |
| 72 | DASM_none, /* No parameters */ |
| 73 | DASM_nop_2, /* One ignored parameter byte */ |
| 74 | DASM_rel8, /* Relative, 8 bits */ |
| 75 | DASM_rel11, /* Relative, 11 bits */ |
| 76 | DASM_rel16, /* Relative, 16 bits */ |
| 77 | DASM_rrel8, /* Register + relative, 8 bits */ |
| 78 | DASM_brrel8, /* Bit test + register + relative, 8 bits */ |
| 79 | DASM_direct_1, /* Register-direct references, 1 operator */ |
| 80 | DASM_direct_2, /* Register-direct references, 2 operators */ |
| 81 | DASM_direct_3, /* Register-direct references, 3 operators */ |
| 82 | DASM_immed_1b, /* Immediate references to byte, 1 operator */ |
| 83 | DASM_immed_2b, /* Immediate references to byte, 2 operators */ |
| 84 | DASM_immed_3b, /* Immediate references to byte, 3 operators */ |
| 85 | DASM_immed_1w, /* Immediate references to word, 1 operator */ |
| 86 | DASM_immed_2w, /* Immediate references to word, 2 operators */ |
| 87 | DASM_immed_3w, /* Immediate references to word, 3 operators */ |
| 88 | DASM_indirect_1n, /* Indirect normal, 1 operator */ |
| 89 | DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */ |
| 90 | DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */ |
| 91 | DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */ |
| 92 | DASM_indexed_1, /* Indexed, short or long, 1 operator */ |
| 93 | DASM_indexed_2, /* Indexed, short or long, 2 operators */ |
| 94 | DASM_indexed_3, /* Indexed, short or long, 3 operators */ |
| 95 | }; |
| 96 | |
| 97 | // device-level overrides |
| 98 | virtual void device_start(); |
| 99 | virtual void device_reset(); |
| 100 | |
| 101 | // device_execute_interface overrides |
| 102 | virtual UINT32 execute_min_cycles() const; |
| 103 | virtual UINT32 execute_max_cycles() const; |
| 104 | virtual UINT32 execute_input_lines() const; |
| 105 | virtual void execute_run(); |
| 106 | virtual void execute_set_input(int inputnum, int state); |
| 107 | |
| 108 | // device_memory_interface overrides |
| 109 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; |
| 110 | |
| 111 | // device_state_interface overrides |
| 112 | virtual void state_import(const device_state_entry &entry); |
| 113 | virtual void state_export(const device_state_entry &entry); |
| 114 | virtual void state_string_export(const device_state_entry &entry, astring &string); |
| 115 | |
| 116 | // device_disasm_interface overrides |
| 117 | virtual UINT32 disasm_min_opcode_bytes() const; |
| 118 | virtual UINT32 disasm_max_opcode_bytes() const; |
| 119 | virtual offs_t disasm_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *entries); |
| 120 | |
| 121 | address_space_config program_config; |
| 122 | address_space *program; |
| 123 | direct_read_data *direct; |
| 124 | |
| 125 | UINT64 end_cycles; |
| 126 | int icount, bcount, inst_state, cycles_scaling; |
| 127 | UINT8 pending_irq; |
| 128 | UINT16 PC, PPC, PSW; |
| 129 | UINT16 OP1; |
| 130 | UINT8 OP2, OP3, OPI; |
| 131 | UINT32 TMP; |
| 132 | UINT16 R[0x74]; |
| 133 | bool irq_requested; |
| 134 | |
| 135 | virtual void do_exec_full() = 0; |
| 136 | virtual void do_exec_partial() = 0; |
| 137 | virtual void internal_update(UINT64 current_time) = 0; |
| 138 | virtual void io_w8(UINT8 adr, UINT8 data) = 0; |
| 139 | virtual void io_w16(UINT8 adr, UINT16 data) = 0; |
| 140 | virtual UINT8 io_r8(UINT8 adr) = 0; |
| 141 | virtual UINT16 io_r16(UINT8 adr) = 0; |
| 142 | |
| 143 | void recompute_bcount(UINT64 event_time); |
| 144 | static astring regname(UINT8 reg); |
| 145 | |
| 146 | inline void next(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH; } |
| 147 | inline void next_noirq(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH_NOIRQ; } |
| 148 | void check_irq(); |
| 149 | inline UINT8 read_pc() { return direct->read_decrypted_byte(PC++); } |
| 150 | |
| 151 | void reg_w8(UINT8 adr, UINT8 data); |
| 152 | void reg_w16(UINT8 adr, UINT16 data); |
| 153 | void any_w8(UINT16 adr, UINT8 data); |
| 154 | void any_w16(UINT16 adr, UINT16 data); |
| 155 | |
| 156 | UINT8 reg_r8(UINT8 adr); |
| 157 | UINT16 reg_r16(UINT8 adr); |
| 158 | UINT8 any_r8(UINT16 adr); |
| 159 | UINT16 any_r16(UINT16 adr); |
| 160 | |
| 161 | UINT8 do_addb(UINT8 v1, UINT8 v2); |
| 162 | UINT16 do_add(UINT16 v1, UINT16 v2); |
| 163 | UINT8 do_subb(UINT8 v1, UINT8 v2); |
| 164 | UINT16 do_sub(UINT16 v1, UINT16 v2); |
| 165 | |
| 166 | void set_nz8(UINT8 v); |
| 167 | void set_nz16(UINT16 v); |
| 168 | |
| 169 | #define O(o) void o ## _full(); void o ## _partial() |
| 170 | |
| 171 | O(add_direct_2); O(add_direct_3); O(add_immed_2w); O(add_immed_3w); O(add_indexed_2); O(add_indexed_3); O(add_indirect_2); O(add_indirect_3); |
| 172 | O(addb_direct_2); O(addb_direct_3); O(addb_immed_2b); O(addb_immed_3b); O(addb_indexed_2); O(addb_indexed_3); O(addb_indirect_2); O(addb_indirect_3); |
| 173 | O(addc_direct_2); O(addc_immed_2w); O(addc_indexed_2); O(addc_indirect_2); |
| 174 | O(addcb_direct_2); O(addcb_immed_2w); O(addcb_indexed_2); O(addcb_indirect_2); |
| 175 | O(and_direct_2); O(and_direct_3); O(and_immed_2w); O(and_immed_3w); O(and_indexed_2); O(and_indexed_3); O(and_indirect_2); O(and_indirect_3); |
| 176 | O(andb_direct_2); O(andb_direct_3); O(andb_immed_2b); O(andb_immed_3b); O(andb_indexed_2); O(andb_indexed_3); O(andb_indirect_2); O(andb_indirect_3); |
| 177 | O(br_indirect_1n); |
| 178 | O(clr_direct_1); |
| 179 | O(clrb_direct_1); |
| 180 | O(clrc_none); |
| 181 | O(clrvt_none); |
| 182 | O(cmp_direct_2); O(cmp_immed_2w); O(cmp_indexed_2); O(cmp_indirect_2); |
| 183 | O(cmpb_direct_2); O(cmpb_immed_2b); O(cmpb_indexed_2); O(cmpb_indirect_2); |
| 184 | O(dec_direct_1); |
| 185 | O(decb_direct_1); |
| 186 | O(di_none); |
| 187 | O(div_direct_2); O(div_immed_2w); O(div_indexed_2); O(div_indirect_2); |
| 188 | O(divb_direct_2); O(divb_immed_2b); O(divb_indexed_2); O(divb_indirect_2); |
| 189 | O(divu_direct_2); O(divu_immed_2w); O(divu_indexed_2); O(divu_indirect_2); |
| 190 | O(divub_direct_2); O(divub_immed_2b); O(divub_indexed_2); O(divub_indirect_2); |
| 191 | O(djnz_rrel8); |
| 192 | O(djnzw_rrel8); |
| 193 | O(ei_none); |
| 194 | O(ext_direct_1); |
| 195 | O(extb_direct_1); |
| 196 | O(idlpd_none); |
| 197 | O(inc_direct_1); |
| 198 | O(incb_direct_1); |
| 199 | O(jbc_brrel8); |
| 200 | O(jbs_brrel8); |
| 201 | O(jc_rel8); |
| 202 | O(je_rel8); |
| 203 | O(jge_rel8); |
| 204 | O(jgt_rel8); |
| 205 | O(jh_rel8); |
| 206 | O(jle_rel8); |
| 207 | O(jlt_rel8); |
| 208 | O(jnc_rel8); |
| 209 | O(jne_rel8); |
| 210 | O(jnh_rel8); |
| 211 | O(jnst_rel8); |
| 212 | O(jnv_rel8); |
| 213 | O(jnvt_rel8); |
| 214 | O(jst_rel8); |
| 215 | O(jv_rel8); |
| 216 | O(jvt_rel8); |
| 217 | O(lcall_rel16); |
| 218 | O(ld_direct_2); O(ld_immed_2w); O(ld_indexed_2); O(ld_indirect_2); |
| 219 | O(ldb_direct_2); O(ldb_immed_2b); O(ldb_indexed_2); O(ldb_indirect_2); |
| 220 | O(ldbse_direct_2); O(ldbse_immed_2b); O(ldbse_indexed_2); O(ldbse_indirect_2); |
| 221 | O(ldbze_direct_2); O(ldbze_immed_2b); O(ldbze_indexed_2); O(ldbze_indirect_2); |
| 222 | O(ljmp_rel16); |
| 223 | O(mul_direct_2); O(mul_direct_3); O(mul_immed_2w); O(mul_immed_3w); O(mul_indexed_2); O(mul_indexed_3); O(mul_indirect_2); O(mul_indirect_3); |
| 224 | O(mulb_direct_2); O(mulb_direct_3); O(mulb_immed_2b); O(mulb_immed_3b); O(mulb_indexed_2); O(mulb_indexed_3); O(mulb_indirect_2); O(mulb_indirect_3); |
| 225 | O(mulu_direct_2); O(mulu_direct_3); O(mulu_immed_2w); O(mulu_immed_3w); O(mulu_indexed_2); O(mulu_indexed_3); O(mulu_indirect_2); O(mulu_indirect_3); |
| 226 | O(mulub_direct_2); O(mulub_direct_3); O(mulub_immed_2b); O(mulub_immed_3b); O(mulub_indexed_2); O(mulub_indexed_3); O(mulub_indirect_2); O(mulub_indirect_3); |
| 227 | O(neg_direct_1); |
| 228 | O(negb_direct_1); |
| 229 | O(nop_none); |
| 230 | O(norml_direct_2); |
| 231 | O(not_direct_1); |
| 232 | O(notb_direct_1); |
| 233 | O(or_direct_2); O(or_immed_2w); O(or_indexed_2); O(or_indirect_2); |
| 234 | O(orb_direct_2); O(orb_immed_2b); O(orb_indexed_2); O(orb_indirect_2); |
| 235 | O(pop_direct_1); O(pop_indexed_1); O(pop_indirect_1); |
| 236 | O(popa_none); |
| 237 | O(popf_none); |
| 238 | O(push_direct_1); O(push_immed_1w); O(push_indexed_1); O(push_indirect_1); |
| 239 | O(pusha_none); |
| 240 | O(pushf_none); |
| 241 | O(ret_none); |
| 242 | O(rst_none); |
| 243 | O(scall_rel11); |
| 244 | O(setc_none); |
| 245 | O(shl_immed_2b); |
| 246 | O(shlb_immed_2b); |
| 247 | O(shll_immed_2b); |
| 248 | O(shr_immed_2b); |
| 249 | O(shra_immed_2b); |
| 250 | O(shrab_immed_2b); |
| 251 | O(shral_immed_2b); |
| 252 | O(shrb_immed_2b); |
| 253 | O(shrl_immed_2b); |
| 254 | O(sjmp_rel11); |
| 255 | O(skip_immed_1b); |
| 256 | O(st_direct_2); O(st_indexed_2); O(st_indirect_2); |
| 257 | O(stb_direct_2); O(stb_indexed_2); O(stb_indirect_2); |
| 258 | O(sub_direct_2); O(sub_direct_3); O(sub_immed_2w); O(sub_immed_3w); O(sub_indexed_2); O(sub_indexed_3); O(sub_indirect_2); O(sub_indirect_3); |
| 259 | O(subb_direct_2); O(subb_direct_3); O(subb_immed_2b); O(subb_immed_3b); O(subb_indexed_2); O(subb_indexed_3); O(subb_indirect_2); O(subb_indirect_3); |
| 260 | O(subc_direct_2); O(subc_immed_2w); O(subc_indexed_2); O(subc_indirect_2); |
| 261 | O(subcb_direct_2); O(subcb_immed_2w); O(subcb_indexed_2); O(subcb_indirect_2); |
| 262 | O(trap_none); |
| 263 | O(xch_direct_2); |
| 264 | O(xchb_direct_2); |
| 265 | O(xor_direct_2); O(xor_immed_2w); O(xor_indexed_2); O(xor_indirect_2); |
| 266 | O(xorb_direct_2); O(xorb_immed_2b); O(xorb_indexed_2); O(xorb_indirect_2); |
| 267 | |
| 268 | O(fetch); |
| 269 | O(fetch_noirq); |
| 270 | |
| 271 | #undef O |
| 272 | }; |
| 273 | |
| 274 | enum { |
| 275 | MCS96_PC = 1, |
| 276 | MCS96_PSW, |
| 277 | MCS96_R // 0x74 entries |
| 278 | }; |
| 279 | |
| 280 | #endif |