summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/mcs96
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2012-12-17 23:19:50 +0000
committer Olivier Galibert <galibert@pobox.com>2012-12-17 23:19:50 +0000
commit73e4eb26ebb39f5636d233109e25298cfbe82dad (patch)
tree8a5c516da9e8a17dac66438bd5aae66d0bbf1fe1 /src/emu/cpu/mcs96
parentb6fe84c9275c4b1bfc69459803e7171b96aaf67e (diff)
(mess) mcs96: First (incomplete) stab at a core [O. Galibert]
Diffstat (limited to 'src/emu/cpu/mcs96')
-rw-r--r--src/emu/cpu/mcs96/i8x9x.c396
-rw-r--r--src/emu/cpu/mcs96/i8x9x.h126
-rw-r--r--src/emu/cpu/mcs96/i8xc196.c101
-rw-r--r--src/emu/cpu/mcs96/i8xc196.h75
-rw-r--r--src/emu/cpu/mcs96/mcs96.c713
-rw-r--r--src/emu/cpu/mcs96/mcs96.h280
-rw-r--r--src/emu/cpu/mcs96/mcs96make.py192
-rw-r--r--src/emu/cpu/mcs96/mcs96ops.lst1617
8 files changed, 3500 insertions, 0 deletions
diff --git a/src/emu/cpu/mcs96/i8x9x.c b/src/emu/cpu/mcs96/i8x9x.c
index e69de29bb2d..cb58a072eee 100644
--- a/src/emu/cpu/mcs96/i8x9x.c
+++ b/src/emu/cpu/mcs96/i8x9x.c
@@ -0,0 +1,396 @@
+/***************************************************************************
+
+ i8x9x.h
+
+ MCS96, 8x9x branch, the original version
+
+****************************************************************************
+
+ Copyright Olivier Galibert
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i8x9x.h"
+
+i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
+ mcs96_device(mconfig, type, name, tag, owner, clock, 8),
+ io_config("io", ENDIANNESS_LITTLE, 16, 16, -1)
+{
+}
+
+offs_t i8x9x_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ return disasm_generic(buffer, pc, oprom, opram, options, disasm_entries);
+}
+
+const address_space_config *i8x9x_device::memory_space_config(address_spacenum spacenum) const
+{
+ return spacenum == AS_PROGRAM ? &program_config : spacenum == AS_IO ? &io_config : NULL;
+}
+
+void i8x9x_device::device_start()
+{
+ mcs96_device::device_start();
+ io = &space(AS_IO);
+ cycles_scaling = 3;
+}
+
+void i8x9x_device::device_reset()
+{
+ mcs96_device::device_reset();
+ memset(hso_info, 0, sizeof(hso_info));
+ memset(&hso_cam_hold, 0, sizeof(hso_cam_hold));
+ hso_command = 0;
+ hso_time = 0;
+ base_timer2 = 0;
+ ios0 = ios1 = ioc0 = ioc1 = 0x00;
+ ad_result = 0;
+ ad_done = 0;
+ sp_stat = 0;
+}
+
+void i8x9x_device::commit_hso_cam()
+{
+ for(int i=0; i<8; i++)
+ if(!hso_info[i].active) {
+ if(hso_command != 0x18)
+ logerror("%s: hso cam %02x %04x in slot %d (%04x)\n", tag(), hso_command, hso_time, i, PPC);
+ hso_info[i].active = true;
+ hso_info[i].command = hso_command;
+ hso_info[i].time = hso_time;
+ internal_update(get_cycle());
+ return;
+ }
+ hso_cam_hold.active = true;
+ hso_cam_hold.command = hso_command;
+ hso_cam_hold.time = hso_time;
+}
+
+void i8x9x_device::ad_start(UINT64 current_time)
+{
+ ad_result = (io->read_word(2*((ad_command & 7) + A0)) << 6) | 8 | (ad_command & 7);
+ ad_done = current_time + 88;
+ internal_update(current_time);
+}
+
+void i8x9x_device::serial_send(UINT8 data)
+{
+ serial_send_buf = data;
+ serial_send_timer = get_cycle() + 9600;
+}
+
+void i8x9x_device::serial_send_done()
+{
+ serial_send_timer = 0;
+ io->write_word(SERIAL*2, serial_send_buf);
+ pending_irq |= IRQ_SERIAL;
+ sp_stat |= 0x20;
+ check_irq();
+}
+
+void i8x9x_device::io_w8(UINT8 adr, UINT8 data)
+{
+ switch(adr) {
+ case 0x02:
+ ad_command = data;
+ if(ad_command & 8)
+ ad_start(get_cycle());
+ break;
+ case 0x03:
+ logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x04:
+ hso_time = (hso_time & 0xff00) | data;
+ break;
+ case 0x05:
+ hso_time = (hso_time & 0x00ff) | (data << 8);
+ commit_hso_cam();
+ break;
+ case 0x06:
+ hso_command = data;
+ break;
+ case 0x07:
+ logerror("%s: sbuf %02x (%04x)\n", tag(), data, PPC);
+ serial_send(data);
+ break;
+ case 0x08:
+ PSW = (PSW & 0xff00) | data;
+ check_irq();
+ break;
+ case 0x09:
+ pending_irq = data;
+ logerror("%s: int_pending %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x0a:
+ logerror("%s: watchdog %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x0e:
+ logerror("%s: baud rate %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x0f:
+ logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x10:
+ logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x11:
+ logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x15:
+ logerror("%s: ioc0 %02x (%04x)\n", tag(), data, PPC);
+ ioc0 = data;
+ break;
+ case 0x16:
+ logerror("%s: ioc1 %02x (%04x)\n", tag(), data, PPC);
+ ioc1 = data;
+ break;
+ case 0x17:
+ logerror("%s: pwm control %02x (%04x)\n", tag(), data, PPC);
+ break;
+ }
+ return;
+}
+
+void i8x9x_device::io_w16(UINT8 adr, UINT16 data)
+{
+ switch(adr) {
+ case 0:
+ break;
+ case 4:
+ hso_time = data;
+ commit_hso_cam();
+ break;
+ default:
+ io_w8(adr, data);
+ io_w8(adr+1, data>>8);
+ break;
+ }
+ return;
+}
+
+UINT8 i8x9x_device::io_r8(UINT8 adr)
+{
+ switch(adr) {
+ case 0x00:
+ return 0x00;
+ case 0x01:
+ return 0x00;
+ case 0x02:
+ return ad_result;
+ case 0x03:
+ return ad_result >> 8;
+ case 0x04:
+ logerror("%s: read hsi time l (%04x)\n", tag(), PPC);
+ return 0x00;
+ case 0x05:
+ logerror("%s: read hsi time h (%04x)\n", tag(), PPC);
+ return 0x00;
+ case 0x06:
+ logerror("%s: read hsi status (%04x)\n", tag(), PPC);
+ return 0x00;
+ case 0x07:
+ logerror("%s: read sbuf %02x (%04x)\n", tag(), sbuf, PPC);
+ return sbuf;
+ case 0x08:
+ return PSW;
+ case 0x09:
+ logerror("%s: read int pending (%04x)\n", tag(), PPC);
+ return pending_irq;
+ case 0x0a:
+ logerror("%s: read timer1 l (%04x)\n", tag(), PPC);
+ return timer_value(1, get_cycle());
+ case 0x0b:
+ logerror("%s: read timer1 h (%04x)\n", tag(), PPC);
+ return timer_value(1, get_cycle()) >> 8;
+ case 0x0c:
+ logerror("%s: read timer2 l (%04x)\n", tag(), PPC);
+ return timer_value(2, get_cycle());
+ case 0x0d:
+ logerror("%s: read timer2 h (%04x)\n", tag(), PPC);
+ return timer_value(2, get_cycle()) >> 8;
+ case 0x0e:
+ logerror("%s: read io port 0 (%04x)\n", tag(), PPC);
+ return 0x00;
+ case 0x0f:
+ logerror("%s: read io port 1 (%04x)\n", tag(), PPC);
+ return 0x00;
+ case 0x10:
+ logerror("%s: read io port 2 (%04x)\n", tag(), PPC);
+ return 0x00;
+ case 0x11: {
+ UINT8 res = sp_stat;
+ sp_stat &= 0x80;
+ logerror("%s: read sp stat %02x (%04x)\n", tag(), res, PPC);
+ return res;
+ }
+ case 0x15:
+ logerror("%s: read ios 0 %02x (%04x)\n", tag(), ios0, PPC);
+ return ios0;
+ case 0x16: {
+ UINT8 res = ios1;
+ ios1 = ios1 & 0xc0;
+ return res;
+ }
+ default:
+ logerror("%s: io_r8 %02x (%04x)\n", tag(), adr, PPC);
+ return 0x00;
+ }
+}
+
+UINT16 i8x9x_device::io_r16(UINT8 adr)
+{
+ switch(adr) {
+ case 0x00:
+ return 0x0000;
+ case 0x02:
+ return ad_result;
+ case 0x04:
+ logerror("%s: read hsi time (%04x)\n", tag(), PPC);
+ return 0x0000;
+ case 0x0a:
+ return timer_value(1, get_cycle());
+ case 0x0c:
+ logerror("%s: read timer2 (%04x)\n", tag(), PPC);
+ return timer_value(2, get_cycle());
+ default:
+ return io_r8(adr) | (io_r8(adr+1) << 8);
+ }
+}
+
+void i8x9x_device::do_exec_partial()
+{
+}
+
+void i8x9x_device::serial_w(UINT8 val)
+{
+ sbuf = val;
+ sp_stat |= 0x40;
+ pending_irq |= IRQ_SERIAL;
+ check_irq();
+}
+
+UINT16 i8x9x_device::timer_value(int timer, UINT64 current_time) const
+{
+ if(timer == 2)
+ current_time -= base_timer2;
+ return current_time >> 3;
+}
+
+UINT64 i8x9x_device::timer_time_until(int timer, UINT64 current_time, UINT16 timer_value) const
+{
+ UINT64 timer_base = timer == 2 ? base_timer2 : 0;
+ UINT64 delta = (current_time - timer_base) >> 3;
+ UINT32 tdelta = UINT16(timer_value - delta);
+ if(!tdelta)
+ tdelta = 0x10000;
+ return timer_base + ((delta + tdelta) << 3);
+}
+
+void i8x9x_device::trigger_cam(int id, UINT64 current_time)
+{
+ hso_cam_entry &cam = hso_info[id];
+ cam.active = false;
+ switch(cam.command & 0x0f) {
+ case 0x8: case 0x9: case 0xa: case 0xb:
+ ios1 |= 1 << (cam.command & 3);
+ pending_irq |= IRQ_SOFT;
+ check_irq();
+ break;
+
+ default:
+ logerror("%s: Action %x unimplemented\n", tag(), cam.command & 0x0f);
+ break;
+ }
+}
+
+void i8x9x_device::internal_update(UINT64 current_time)
+{
+ UINT16 current_timer1 = timer_value(1, current_time);
+ UINT16 current_timer2 = timer_value(2, current_time);
+
+ for(int i=0; i<8; i++)
+ if(hso_info[i].active) {
+ UINT8 cmd = hso_info[i].command;
+ UINT16 t = hso_info[i].time;
+ if(((cmd & 0x40) && t == current_timer2) ||
+ (!(cmd & 0x40) && t == current_timer1)) {
+ if(cmd != 0x18)
+ logerror("%s: hso cam %02x %04x in slot %d triggered\n",
+ tag(), cmd, t, i);
+ trigger_cam(i, current_time);
+ }
+ }
+
+ if(current_time == ad_done) {
+ ad_done = 0;
+ ad_result &= ~8;
+ }
+
+ if(current_time == serial_send_timer)
+ serial_send_done();
+
+ UINT64 event_time = 0;
+ for(int i=0; i<8; i++) {
+ if(!hso_info[i].active && hso_cam_hold.active) {
+ hso_info[i] = hso_cam_hold;
+ hso_cam_hold.active = false;
+ logerror("%s: hso cam %02x %04x in slot %d from hold\n", tag(), hso_cam_hold.command, hso_cam_hold.time, i);
+ }
+ if(hso_info[i].active) {
+ UINT64 new_time = timer_time_until(hso_info[i].command & 0x40 ? 2 : 1, current_time, hso_info[i].time);
+ if(!event_time || new_time < event_time)
+ event_time = new_time;
+ }
+ }
+
+ if(ad_done && ad_done < event_time)
+ event_time = ad_done;
+
+ if(serial_send_timer && serial_send_timer < event_time)
+ event_time = serial_send_timer;
+
+ recompute_bcount(event_time);
+}
+
+c8095_device::c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ i8x9x_device(mconfig, C8095, "C8095", tag, owner, clock)
+{
+}
+
+p8098_device::p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ i8x9x_device(mconfig, P8098, "P8098", tag, owner, clock)
+{
+}
+
+const device_type C8095 = &device_creator<c8095_device>;
+const device_type P8098 = &device_creator<p8098_device>;
+
+#include "cpu/mcs96/i8x9x.inc"
diff --git a/src/emu/cpu/mcs96/i8x9x.h b/src/emu/cpu/mcs96/i8x9x.h
index e69de29bb2d..0f2e1b4f47c 100644
--- a/src/emu/cpu/mcs96/i8x9x.h
+++ b/src/emu/cpu/mcs96/i8x9x.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+
+ i8x9x.h
+
+ MCS96, 8x9x branch, the original version
+
+****************************************************************************
+
+ Copyright Olivier Galibert
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#ifndef __I8X9X_H__
+#define __I8X9X_H__
+
+#include "mcs96.h"
+
+class i8x9x_device : public mcs96_device {
+public:
+ enum {
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ SERIAL
+ };
+
+ i8x9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
+
+ void serial_w(UINT8 val);
+
+protected:
+ virtual void device_start();
+ virtual void device_reset();
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
+
+ static const disasm_entry disasm_entries[0x100];
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+ virtual void do_exec_full();
+ virtual void do_exec_partial();
+ virtual void internal_update(UINT64 current_time);
+ virtual void io_w8(UINT8 adr, UINT8 data);
+ virtual void io_w16(UINT8 adr, UINT16 data);
+ virtual UINT8 io_r8(UINT8 adr);
+ virtual UINT16 io_r16(UINT8 adr);
+
+private:
+ enum {
+ IRQ_TIMER = 0x01,
+ IRQ_AD = 0x02,
+ IRQ_HSI = 0x04,
+ IRQ_HSO = 0x08,
+ IRQ_HSI0 = 0x10,
+ IRQ_SOFT = 0x20,
+ IRQ_SERIAL = 0x40,
+ IRQ_EXTINT = 0x80
+ };
+
+ struct hso_cam_entry {
+ bool active;
+ UINT8 command;
+ UINT16 time;
+ };
+
+ address_space_config io_config;
+ address_space *io;
+
+ hso_cam_entry hso_info[8];
+ hso_cam_entry hso_cam_hold;
+
+ UINT64 base_timer2, ad_done;
+ UINT8 hso_command, ad_command;
+ UINT16 hso_time, ad_result;
+ UINT8 ios0, ios1, ioc0, ioc1;
+ UINT8 sbuf, sp_stat;
+ UINT8 serial_send_buf;
+ UINT64 serial_send_timer;
+
+ UINT16 timer_value(int timer, UINT64 current_time) const;
+ UINT64 timer_time_until(int timer, UINT64 current_time, UINT16 timer_value) const;
+ void commit_hso_cam();
+ void trigger_cam(int id, UINT64 current_time);
+ void ad_start(UINT64 current_time);
+ void serial_send(UINT8 data);
+ void serial_send_done();
+};
+
+class c8095_device : public i8x9x_device {
+public:
+ c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class p8098_device : public i8x9x_device {
+public:
+ p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+extern const device_type C8095;
+extern const device_type P8098;
+
+#endif
diff --git a/src/emu/cpu/mcs96/i8xc196.c b/src/emu/cpu/mcs96/i8xc196.c
index e69de29bb2d..4eb8489a382 100644
--- a/src/emu/cpu/mcs96/i8xc196.c
+++ b/src/emu/cpu/mcs96/i8xc196.c
@@ -0,0 +1,101 @@
+/***************************************************************************
+
+ i8xc196.h
+
+ MCS96, c196 branch, the enhanced 16 bits bus version
+
+****************************************************************************
+
+ Copyright Olivier Galibert
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i8xc196.h"
+
+i8xc196_device::i8xc196_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
+ mcs96_device(mconfig, type, name, tag, owner, clock, 16)
+{
+}
+
+offs_t i8xc196_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ return disasm_generic(buffer, pc, oprom, opram, options, disasm_entries);
+}
+
+void i8xc196_device::io_w8(UINT8 adr, UINT8 data)
+{
+ switch(adr) {
+ case 0:
+ break;
+ case 1:
+ break;
+ default:
+ logerror("%s: io_w8 %02x, %02x (%04x)\n", tag(), adr, data, PPC);
+ }
+ return;
+}
+
+void i8xc196_device::io_w16(UINT8 adr, UINT16 data)
+{
+ switch(adr) {
+ case 0:
+ break;
+ default:
+ io_w8(adr, data);
+ io_w8(adr+1, data>>8);
+ break;
+ }
+ return;
+}
+
+UINT8 i8xc196_device::io_r8(UINT8 adr)
+{
+ switch(adr) {
+ case 0x00:
+ return 0x00;
+ case 0x01:
+ return 0x00;
+ }
+ UINT8 data = 0x00;
+ logerror("%s: io_r8 %02x, %02x (%04x)\n", tag(), adr, data, PPC);
+ return data;
+}
+
+UINT16 i8xc196_device::io_r16(UINT8 adr)
+{
+ if(adr < 2)
+ return 0x0000;
+ UINT16 data = 0x0000;
+ logerror("%s: io_r16 %02x, %04x (%04x)\n", tag(), adr, data, PPC);
+ return data;
+}
+
+#include "cpu/mcs96/i8xc196.inc"
diff --git a/src/emu/cpu/mcs96/i8xc196.h b/src/emu/cpu/mcs96/i8xc196.h
index e69de29bb2d..de509ba0b7e 100644
--- a/src/emu/cpu/mcs96/i8xc196.h
+++ b/src/emu/cpu/mcs96/i8xc196.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+
+ i8xc196.h
+
+ MCS96, c196 branch, the enhanced 16 bits bus version
+
+****************************************************************************
+
+ Copyright Olivier Galibert
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#ifndef __I8XC196_H__
+#define __I8XC196_H__
+
+#include "mcs96.h"
+
+class i8xc196_device : public mcs96_device {
+public:
+ i8xc196_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
+
+ static const disasm_entry disasm_entries[0x100];
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+ virtual void do_exec_full();
+ virtual void do_exec_partial();
+
+ virtual void next(int cycles);
+ virtual void io_w8(UINT8 adr, UINT8 data);
+ virtual void io_w16(UINT8 adr, UINT16 data);
+ virtual UINT8 io_r8(UINT8 adr);
+ virtual UINT16 io_r16(UINT8 adr);
+
+#define O(o) void o ## _196_full(); void o ## _196_partial()
+
+ O(bmov_direct_2);
+ O(cmpl_direct_2);
+ O(bmovi_direct_2);
+ O(pop_indirect_1);
+ O(pop_indexed_1);
+ O(djnzw_rrel8);
+ O(pusha_none);
+ O(idlpd_none);
+
+#undef O
+};
+
+#endif
diff --git a/src/emu/cpu/mcs96/mcs96.c b/src/emu/cpu/mcs96/mcs96.c
index e69de29bb2d..849163fb2e3 100644
--- a/src/emu/cpu/mcs96/mcs96.c
+++ b/src/emu/cpu/mcs96/mcs96.c
@@ -0,0 +1,713 @@
+/***************************************************************************
+
+ mcs96.h
+
+ MCS96, 8098/8398/8798 branch
+
+****************************************************************************
+
+ Copyright Olivier Galibert
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+#include "mcs96.h"
+
+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) :
+ cpu_device(mconfig, type, name, tag, owner, clock),
+ program_config("program", ENDIANNESS_LITTLE, data_width, 16)
+{
+}
+
+void mcs96_device::device_start()
+{
+ program = &space(AS_PROGRAM);
+ direct = &program->direct();
+ m_icountptr = &icount;
+
+ state_add(STATE_GENPC, "GENPC", PC).noshow();
+ state_add(STATE_GENPCBASE, "GENPCBASE", PPC).noshow();
+ state_add(STATE_GENSP, "GENSP", R[0]).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", PSW).formatstr("%16s").noshow();
+ state_add(MCS96_PC, "PC", PC);
+ state_add(MCS96_PSW, "PSW", PSW);
+ state_add(MCS96_R, "SP", R[0]);
+ for(int i=1; i<0x74; i++) {
+ char buf[10];
+ sprintf(buf, "R%02x", i*2+0x18);
+ state_add(MCS96_R+i, buf, R[i]);
+ }
+
+ memset(R, 0, sizeof(R));
+}
+
+void mcs96_device::device_reset()
+{
+ PC = 0x2080;
+ PPC = PC;
+ PSW = 0;
+ pending_irq = 0x00;
+ irq_requested = false;
+ inst_state = STATE_FETCH;
+}
+
+UINT32 mcs96_device::execute_min_cycles() const
+{
+ return 4;
+}
+
+UINT32 mcs96_device::execute_max_cycles() const
+{
+ return 33;
+}
+
+UINT32 mcs96_device::execute_input_lines() const
+{
+ return 1;
+}
+
+UINT64 mcs96_device::get_cycle()
+{
+ return end_cycles == 0 || icount <= 0 ? machine().time().as_ticks(clock()) : end_cycles - icount;
+}
+
+void mcs96_device::recompute_bcount(UINT64 event_time)
+{
+ if(!event_time || event_time >= end_cycles) {
+ bcount = 0;
+ return;
+ }
+ bcount = end_cycles - event_time;
+}
+
+void mcs96_device::check_irq()
+{
+ irq_requested = (PSW & pending_irq) && (PSW & F_I);
+}
+
+void mcs96_device::execute_run()
+{
+ UINT64 start_cycles = machine().time().as_ticks(clock());
+ end_cycles = start_cycles + icount;
+
+ internal_update(start_cycles);
+
+ if(/*inst_substate*/ 0)
+ do_exec_partial();
+
+ while(icount > 0) {
+ while(icount > bcount) {
+ int picount = inst_state >= 0x200 ? -1 : icount;
+ do_exec_full();
+ if(icount == picount) {
+ fprintf(stderr, "Unhandled %x (%04x)\n", inst_state, PPC);
+ exit(0);
+ }
+ }
+ while(bcount && icount <= bcount)
+ internal_update(end_cycles - bcount);
+ }
+ end_cycles = 0;
+}
+
+void mcs96_device::execute_set_input(int inputnum, int state)
+{
+ switch(inputnum) {
+ }
+}
+
+const address_space_config *mcs96_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_PROGRAM) ? &program_config : NULL;
+}
+
+void mcs96_device::state_import(const device_state_entry &entry)
+{
+}
+
+void mcs96_device::state_export(const device_state_entry &entry)
+{
+}
+
+void mcs96_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch(entry.index()) {
+ case STATE_GENFLAGS:
+ case MCS96_PSW:
+ string.printf("%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c",
+ PSW & F_Z ? 'Z' : '.',
+ PSW & F_N ? 'N' : '.',
+ PSW & F_V ? 'V' : '.',
+ PSW & F_VT ? 'v' : '.',
+ PSW & F_C ? 'C' : '.',
+ PSW & F_I ? 'I' : '.',
+ PSW & F_ST ? 'S' : '.',
+ PSW & 0x80 ? '7' : '.',
+ PSW & 0x40 ? '6' : '.',
+ PSW & 0x20 ? '5' : '.',
+ PSW & 0x10 ? '4' : '.',
+ PSW & 0x08 ? '3' : '.',
+ PSW & 0x04 ? '2' : '.',
+ PSW & 0x02 ? '1' : '.',
+ PSW & 0x01 ? '0' : '.');
+ break;
+ }
+}
+
+astring mcs96_device::regname(UINT8 reg)
+{
+ char res[32];
+ switch(reg) {
+ case 0x18:
+ strcpy(res, "sp");
+ break;
+
+ case 0x19:
+ strcpy(res, "sph");
+ break;
+
+ default:
+ sprintf(res, "%02x", reg);
+ break;
+ }
+ return res;
+}
+
+offs_t mcs96_device::disasm_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *entries)
+{
+ bool prefix_fe = false;
+ int off = 0;
+ if(oprom[0] == 0xfe && entries[oprom[1]].opcode_fe) {
+ prefix_fe = true;
+ pc++;
+ off++;
+ oprom++;
+ }
+ const disasm_entry &e = entries[oprom[0]];
+ UINT32 flags = e.flags | DASMFLAG_SUPPORTED;
+ buffer += sprintf(buffer, "%s", prefix_fe ? e.opcode_fe : e.opcode);
+
+ switch(e.mode) {
+ case DASM_none:
+ flags |= 1;
+ break;
+
+ case DASM_nop_2:
+ sprintf(buffer, " %02x", oprom[1]);
+ flags |= 2;
+ break;
+
+ case DASM_rel8: {
+ int delta = oprom[1];
+ if(delta & 0x80)
+ delta -= 0x100;
+ sprintf(buffer, " %04x", (pc+2+delta) & 0xffff);
+ flags |= 2;
+ break;
+ }
+
+ case DASM_rel11: {
+ int delta = ((oprom[0] << 8) | oprom[1]) & 0x7ff;
+ if(delta & 0x400)
+ delta -= 0x800;
+ sprintf(buffer, " %04x", (pc+2+delta) & 0xffff);
+ flags |= 2;
+ break;
+ }
+
+ case DASM_rel16: {
+ int delta = oprom[1] | (oprom[2] << 8);
+ sprintf(buffer, " %04x", (pc+3+delta) & 0xffff);
+ flags |= 3;
+ break;
+ }
+
+ case DASM_rrel8: {
+ int delta = oprom[2];
+ if(delta & 0x80)
+ delta -= 0x100;
+ sprintf(buffer, " %s, %04x", regname(oprom[1]).cstr(), (pc+3+delta) & 0xffff);
+ flags |= 3;
+ break;
+ }
+
+ case DASM_brrel8: {
+ int delta = oprom[2];
+ if(delta & 0x80)
+ delta -= 0x100;
+ sprintf(buffer, " %d, %s, %04x", oprom[0] & 7, regname(oprom[1]).cstr(), (pc+3+delta) & 0xffff);
+ flags |= 3;
+ break;
+ }
+
+ case DASM_direct_1:
+ sprintf(buffer, " %s", regname(oprom[1]).cstr());
+ flags |= 2;
+ break;
+
+ case DASM_direct_2:
+ sprintf(buffer, " %s, %s", regname(oprom[2]).cstr(), regname(oprom[1]).cstr());
+ flags |= 3;
+ break;
+
+ case DASM_direct_3:
+ sprintf(buffer, " %s, %s, %s", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), regname(oprom[1]).cstr());
+ flags |= 4;
+ break;
+
+ case DASM_immed_1b:
+ sprintf(buffer, " #%02x", oprom[1]);
+ flags |= 2;
+ break;
+
+ case DASM_immed_2b:
+ sprintf(buffer, " %s, #%02x", regname(oprom[2]).cstr(), oprom[1]);
+ flags |= 3;
+ break;
+
+ case DASM_immed_3b:
+ sprintf(buffer, " %s, %s, #%02x", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), oprom[1]);
+ flags |= 4;
+ break;
+
+ case DASM_immed_1w:
+ sprintf(buffer, " #%02x%02x", oprom[2], oprom[1]);
+ flags |= 3;
+ break;
+
+ case DASM_immed_2w:
+ sprintf(buffer, " %s, #%02x%02x", regname(oprom[3]).cstr(), oprom[2], oprom[1]);
+ flags |= 4;
+ break;
+
+ case DASM_immed_3w:
+ sprintf(buffer, " %s, %s, #%02x%02x", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), oprom[2], oprom[1]);
+ flags |= 5;
+ break;
+
+ case DASM_indirect_1n:
+ sprintf(buffer, " [%s]", regname(oprom[1]).cstr());
+ flags |= 2;
+ break;
+
+ case DASM_indirect_1:
+ if(oprom[1] & 0x01) {
+ sprintf(buffer, " [%s]+", regname(oprom[1]-1).cstr());
+ flags |= 2;
+ } else {
+ sprintf(buffer, " [%s]", regname(oprom[1]).cstr());
+ flags |= 2;
+ }
+ break;
+
+ case DASM_indirect_2:
+ if(oprom[1] & 0x01) {
+ sprintf(buffer, " %s, [%s]+", regname(oprom[2]).cstr(), regname(oprom[1]-1).cstr());
+ flags |= 3;
+ } else {
+ sprintf(buffer, " %s, [%s]", regname(oprom[2]).cstr(), regname(oprom[1]).cstr());
+ flags |= 3;
+ }
+ break;
+
+ case DASM_indirect_3:
+ if(oprom[1] & 0x01) {
+ sprintf(buffer, " %s, %s, [%s]+", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), regname(oprom[1]-1).cstr());
+ flags |= 4;
+ } else {
+ sprintf(buffer, " %s, %s, [%s]", regname(oprom[3]).cstr(), regname(oprom[2]).cstr(), regname(oprom[1]).cstr());
+ flags |= 4;
+ }
+ break;
+
+ case DASM_indexed_1:
+ if(oprom[1] & 0x01) {
+ if(oprom[1] == 0x01)
+ sprintf(buffer, " %02x%02x", oprom[3], oprom[2]);
+ else
+ sprintf(buffer, " %02x%02x[%s]", oprom[3], oprom[2], regname(oprom[1]-1).cstr());
+ flags |= 4;
+ } else {
+ int delta = oprom[2];
+ if(delta & 0x80)
+ delta -= 0x100;
+ if(oprom[1] == 0x00) {
+ if(delta < 0)
+ sprintf(buffer, " %04x", delta & 0xffff);
+ else
+ sprintf(buffer, " %02x", delta);
+ } else {
+ if(delta < 0)
+ sprintf(buffer, " -%02x[%s]", -delta, regname(oprom[1]-1).cstr());
+ else
+ sprintf(buffer, " %02x[%s]", delta, regname(oprom[1]-1).cstr());
+ }
+ flags |= 3;
+ }
+ break;
+
+ case DASM_indexed_2:
+ if(oprom[1] & 0x01) {
+ if(oprom[1] == 0x01)
+ sprintf(buffer, " %s, %02x%02x", regname(oprom[4]).cstr(), oprom[3], oprom[2]);
+ else
+ sprintf(buffer, " %s, %02x%02x[%s]", regname(oprom[4]).cstr(), oprom[3], oprom[2], regname(oprom[1]-1).cstr());
+ flags |= 5;
+ } else {
+ int delta = oprom[2];
+ if(delta & 0x80)
+ delta -= 0x100;
+ if(oprom[1] == 0x00) {
+ if(delta < 0)
+ sprintf(buffer, " %s, %04x", regname(oprom[3]).cstr(), delta & 0xffff);
+ else
+ sprintf(buffer, " %s, %02x", regname(oprom[3]).cstr(), delta);
+ } else {
+ if(delta < 0)
+ sprintf(buffer, " %s, -%02x[%s]", regname(oprom[3]).cstr(), -delta, regname(oprom[1]-1).cstr());
+ else
+ sprintf(buffer, " %s, %02x[%s]", regname(oprom[3]).cstr(), delta, regname(oprom[1]-1).cstr());
+ }
+ flags |= 4;
+ }
+ break;
+
+ case DASM_indexed_3:
+ if(oprom[1] & 0x01) {
+ if(oprom[1] == 0x01)
+ sprintf(buffer, " %s, %s, %02x%02x", regname(oprom[5]).cstr(), regname(oprom[4]).cstr(), oprom[3], oprom[2]);
+ else
+ sprintf(buffer, " %s, %s, %02x%02x[%s]", regname(oprom[5]).cstr(), regname(oprom[4]).cstr(), oprom[3], oprom[2], regname(oprom[1]-1).cstr());
+ flags |= 6;
+ } else {
+ int delta = oprom[2];
+ if(delta & 0x80)
+ delta -= 0x100;
+ if(oprom[1] == 0x00) {
+ if(delta < 0)
+ sprintf(buffer, " %s, %s, %04x", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), delta & 0xffff);
+ else
+ sprintf(buffer, " %s, %s, %02x", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), delta);
+ } else {
+ if(delta < 0)
+ sprintf(buffer, " %s, %s, -%02x[%s]", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), -delta, regname(oprom[1]-1).cstr());
+ else
+ sprintf(buffer, " %s, %s, %02x[%s]", regname(oprom[4]).cstr(), regname(oprom[3]).cstr(), delta, regname(oprom[1]-1).cstr());
+ }
+ flags |= 5;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unhandled dasm mode %d\n", e.mode);
+ abort();
+ };
+
+ return flags+off;
+}
+
+UINT32 mcs96_device::disasm_min_opcode_bytes() const
+{
+ return 1;
+}
+
+UINT32 mcs96_device::disasm_max_opcode_bytes() const
+{
+ return 7;
+}
+
+void mcs96_device::io_w8(UINT8 adr, UINT8 data)
+{
+ switch(adr) {
+ case 0x02:
+ logerror("%s: ad_command %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x03:
+ logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x04:
+ logerror("%s: hso_time.l %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x05:
+ logerror("%s: hso_time.h %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x06:
+ logerror("%s: hso_command %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x07:
+ logerror("%s: sbuf %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x08:
+ PSW = (PSW & 0xff00) | data;
+ break;
+ case 0x09:
+ logerror("%s: int_pending %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x0a:
+ logerror("%s: watchdog %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x0e:
+ logerror("%s: baud rate %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x0f:
+ logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x10:
+ logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x11:
+ logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x15:
+ logerror("%s: ioc0 %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x16:
+ logerror("%s: ioc1 %02x (%04x)\n", tag(), data, PPC);
+ break;
+ case 0x17:
+ logerror("%s: pwm control %02x (%04x)\n", tag(), data, PPC);
+ break;
+ }
+ return;
+}
+
+void mcs96_device::io_w16(UINT8 adr, UINT16 data)
+{
+ switch(adr) {
+ case 0:
+ break;
+ case 4:
+ logerror("%s: hso_time %04x (%04x)\n", tag(), data, PPC);
+ break;
+ default:
+ io_w8(adr, data);
+ io_w8(adr+1, data>>8);
+ break;
+ }
+ return;
+}
+
+UINT8 mcs96_device::io_r8(UINT8 adr)
+{
+ switch(adr) {
+ case 0x00:
+ return 0x00;
+ case 0x01:
+ return 0x00;
+ case 0x08:
+ return PSW;
+ }
+ UINT8 data = 0x00;
+ logerror("%s: io_r8 %02x, %02x (%04x)\n", tag(), adr, data, PPC);
+ return data;
+}
+
+UINT16 mcs96_device::io_r16(UINT8 adr)
+{
+ if(adr < 2)
+ return 0x0000;
+ UINT16 data = 0x0000;
+ logerror("%s: io_r16 %02x, %04x (%04x)\n", tag(), adr, data, PPC);
+ return data;
+}
+
+void mcs96_device::reg_w8(UINT8 adr, UINT8 data)
+{
+ if(adr < 0x18)
+ io_w8(adr, data);
+ else {
+ UINT16 &r = R[(adr - 0x18) >> 1];
+ if(adr & 0x01)
+ r = (r & 0x00ff) | (data << 8);
+ else
+ r = (r & 0xff00) | data;
+ }
+}
+
+void mcs96_device::reg_w16(UINT8 adr, UINT16 data)
+{
+ adr &= 0xfe;
+ if(adr < 0x18)
+ io_w16(adr, data);
+ else
+ R[(adr-0x18) >> 1] = data;
+}
+
+UINT8 mcs96_device::reg_r8(UINT8 adr)
+{
+ if(adr < 0x18)
+ return io_r8(adr);
+
+ UINT16 data = R[(adr - 0x18) >> 1];
+ if(adr & 0x01)
+ return data >> 8;
+ else
+ return data;
+}
+
+UINT16 mcs96_device::reg_r16(UINT8 adr)
+{
+ adr &= 0xfe;
+ if(adr < 0x18)
+ return io_r16(adr);
+
+ return R[(adr-0x18) >> 1];
+}
+
+void mcs96_device::any_w8(UINT16 adr, UINT8 data)
+{
+ if(adr < 0x18)
+ io_w8(adr, data);
+ else if(adr < 0x100) {
+ UINT16 &r = R[(adr - 0x18) >> 1];
+ if(adr & 0x01)
+ r = (r & 0x00ff) | (data << 8);
+ else
+ r = (r & 0xff00) | data;
+ } else
+ program->write_byte(adr, data);
+}
+
+void mcs96_device::any_w16(UINT16 adr, UINT16 data)
+{
+ adr &= 0xfffe;
+ if(adr < 0x18)
+ io_w16(adr, data);
+ else if(adr < 0x100)
+ R[(adr-0x18) >> 1] = data;
+ else
+ program->write_word(adr, data);
+}
+
+UINT8 mcs96_device::any_r8(UINT16 adr)
+{
+ if(adr < 0x18)
+ return io_r8(adr);
+ else if(adr < 0x100) {
+ UINT16 data = R[(adr - 0x18) >> 1];
+ if(adr & 0x01)
+ return data >> 8;
+ else
+ return data;
+ } else
+ return program->read_byte(adr);
+}
+
+UINT16 mcs96_device::any_r16(UINT16 adr)
+{
+ adr &= 0xfffe;
+ if(adr < 0x18)
+ return io_r16(adr);
+ else if(adr < 0x100)
+ return R[(adr-0x18) >> 1];
+ else
+ return program->read_word(adr);
+}
+
+UINT8 mcs96_device::do_addb(UINT8 v1, UINT8 v2)
+{
+ UINT16 sum = v1+v2;
+ PSW &= ~(F_Z|F_N|F_C|F_V);
+ if(!UINT8(sum))
+ PSW |= F_Z;
+ else if(INT8(sum) < 0)
+ PSW |= F_N;
+ if(~(v1^v2) & (v1^sum) & 0x80)
+ PSW |= F_V|F_VT;
+ if(sum & 0xff00)
+ PSW |= F_C;
+ return sum;
+}
+
+UINT16 mcs96_device::do_add(UINT16 v1, UINT16 v2)
+{
+ UINT32 sum = v1+v2;
+ PSW &= ~(F_Z|F_N|F_C|F_V);
+ if(!UINT16(sum))
+ PSW |= F_Z;
+ else if(INT16(sum) < 0)
+ PSW |= F_N;
+ if(~(v1^v2) & (v1^sum) & 0x8000)
+ PSW |= F_V|F_VT;
+ if(sum & 0xffff0000)
+ PSW |= F_C;
+ return sum;
+}
+
+UINT8 mcs96_device::do_subb(UINT8 v1, UINT8 v2)
+{
+ UINT16 diff = v1 - v2;
+ PSW &= ~(F_N|F_V|F_Z|F_C);
+ if(!UINT8(diff))
+ PSW |= F_Z;
+ else if(INT8(diff) < 0)
+ PSW |= F_N;
+ if((v1^v2) & (v1^diff) & 0x80)
+ PSW |= F_V;
+ if(!(diff & 0xff00))
+ PSW |= F_C;
+ return diff;
+}
+
+UINT16 mcs96_device::do_sub(UINT16 v1, UINT16 v2)
+{
+ UINT32 diff = v1 - v2;
+ PSW &= ~(F_N|F_V|F_Z|F_C);
+ if(!UINT16(diff))
+ PSW |= F_Z;
+ else if(INT16(diff) < 0)
+ PSW |= F_N;
+ if((v1^v2) & (v1^diff) & 0x8000)
+ PSW |= F_V;
+ if(!(diff & 0xffff0000))
+ PSW |= F_C;
+ return diff;
+}
+
+void mcs96_device::set_nz8(UINT8 v)
+{
+ PSW &= ~(F_N|F_V|F_Z|F_C);
+ if(!v)
+ PSW |= F_Z;
+ else if(INT8(v) < 0)
+ PSW |= F_N;
+}
+
+void mcs96_device::set_nz16(UINT16 v)
+{
+ PSW &= ~(F_N|F_V|F_Z|F_C);
+ if(!v)
+ PSW |= F_Z;
+ else if(INT16(v) < 0)
+ PSW |= F_N;
+}
+
+#include "cpu/mcs96/mcs96.inc"
diff --git a/src/emu/cpu/mcs96/mcs96.h b/src/emu/cpu/mcs96/mcs96.h
index e69de29bb2d..a1a1b0aa175 100644
--- a/src/emu/cpu/mcs96/mcs96.h
+++ b/src/emu/cpu/mcs96/mcs96.h
@@ -0,0 +1,280 @@
+/***************************************************************************
+
+ mcs96.h
+
+ MCS96
+
+****************************************************************************
+
+ Copyright Olivier Galibert
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#ifndef __MCS96_H__
+#define __MCS96_H__
+
+class mcs96_device : public cpu_device {
+public:
+ mcs96_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int data_width);
+
+ UINT64 get_cycle();
+
+protected:
+ enum {
+ STATE_FETCH = 0x200,
+ STATE_FETCH_NOIRQ = 0x201,
+ };
+
+ enum {
+ F_ST = 0x0100,
+ F_I = 0x0200,
+ F_C = 0x0800,
+ F_VT = 0x1000,
+ F_V = 0x2000,
+ F_N = 0x4000,
+ F_Z = 0x8000,
+ };
+
+ struct disasm_entry {
+ const char *opcode, *opcode_fe;
+ int mode;
+ offs_t flags;
+ };
+
+ enum {
+ DASM_none, /* No parameters */
+ DASM_nop_2, /* One ignored parameter byte */
+ DASM_rel8, /* Relative, 8 bits */
+ DASM_rel11, /* Relative, 11 bits */
+ DASM_rel16, /* Relative, 16 bits */
+ DASM_rrel8, /* Register + relative, 8 bits */
+ DASM_brrel8, /* Bit test + register + relative, 8 bits */
+ DASM_direct_1, /* Register-direct references, 1 operator */
+ DASM_direct_2, /* Register-direct references, 2 operators */
+ DASM_direct_3, /* Register-direct references, 3 operators */
+ DASM_immed_1b, /* Immediate references to byte, 1 operator */
+ DASM_immed_2b, /* Immediate references to byte, 2 operators */
+ DASM_immed_3b, /* Immediate references to byte, 3 operators */
+ DASM_immed_1w, /* Immediate references to word, 1 operator */
+ DASM_immed_2w, /* Immediate references to word, 2 operators */
+ DASM_immed_3w, /* Immediate references to word, 3 operators */
+ DASM_indirect_1n, /* Indirect normal, 1 operator */
+ DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */
+ DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */
+ DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */
+ DASM_indexed_1, /* Indexed, short or long, 1 operator */
+ DASM_indexed_2, /* Indexed, short or long, 2 operators */
+ DASM_indexed_3, /* Indexed, short or long, 3 operators */
+ };
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const;
+ virtual UINT32 execute_max_cycles() const;
+ virtual UINT32 execute_input_lines() const;
+ virtual void execute_run();
+ virtual void execute_set_input(int inputnum, int state);
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
+
+ // device_state_interface overrides
+ virtual void state_import(const device_state_entry &entry);
+ virtual void state_export(const device_state_entry &entry);
+ virtual void state_string_export(const device_state_entry &entry, astring &string);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const;
+ virtual UINT32 disasm_max_opcode_bytes() const;
+ virtual offs_t disasm_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *entries);
+
+ address_space_config program_config;
+ address_space *program;
+ direct_read_data *direct;
+
+ UINT64 end_cycles;
+ int icount, bcount, inst_state, cycles_scaling;
+ UINT8 pending_irq;
+ UINT16 PC, PPC, PSW;
+ UINT16 OP1;
+ UINT8 OP2, OP3, OPI;
+ UINT32 TMP;
+ UINT16 R[0x74];
+ bool irq_requested;
+
+ virtual void do_exec_full() = 0;
+ virtual void do_exec_partial() = 0;
+ virtual void internal_update(UINT64 current_time) = 0;
+ virtual void io_w8(UINT8 adr, UINT8 data) = 0;
+ virtual void io_w16(UINT8 adr, UINT16 data) = 0;
+ virtual UINT8 io_r8(UINT8 adr) = 0;
+ virtual UINT16 io_r16(UINT8 adr) = 0;
+
+ void recompute_bcount(UINT64 event_time);
+ static astring regname(UINT8 reg);
+
+ inline void next(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH; }
+ inline void next_noirq(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH_NOIRQ; }
+ void check_irq();
+ inline UINT8 read_pc() { return direct->read_decrypted_byte(PC++); }
+
+ void reg_w8(UINT8 adr, UINT8 data);
+ void reg_w16(UINT8 adr, UINT16 data);
+ void any_w8(UINT16 adr, UINT8 data);
+ void any_w16(UINT16 adr, UINT16 data);
+
+ UINT8 reg_r8(UINT8 adr);
+ UINT16 reg_r16(UINT8 adr);
+ UINT8 any_r8(UINT16 adr);
+ UINT16 any_r16(UINT16 adr);
+
+ UINT8 do_addb(UINT8 v1, UINT8 v2);
+ UINT16 do_add(UINT16 v1, UINT16 v2);
+ UINT8 do_subb(UINT8 v1, UINT8 v2);
+ UINT16 do_sub(UINT16 v1, UINT16 v2);
+
+ void set_nz8(UINT8 v);
+ void set_nz16(UINT16 v);
+
+#define O(o) void o ## _full(); void o ## _partial()
+
+ 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);
+ 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);
+ O(addc_direct_2); O(addc_immed_2w); O(addc_indexed_2); O(addc_indirect_2);
+ O(addcb_direct_2); O(addcb_immed_2w); O(addcb_indexed_2); O(addcb_indirect_2);
+ 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);
+ 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);
+ O(br_indirect_1n);
+ O(clr_direct_1);
+ O(clrb_direct_1);
+ O(clrc_none);
+ O(clrvt_none);
+ O(cmp_direct_2); O(cmp_immed_2w); O(cmp_indexed_2); O(cmp_indirect_2);
+ O(cmpb_direct_2); O(cmpb_immed_2b); O(cmpb_indexed_2); O(cmpb_indirect_2);
+ O(dec_direct_1);
+ O(decb_direct_1);
+ O(di_none);
+ O(div_direct_2); O(div_immed_2w); O(div_indexed_2); O(div_indirect_2);
+ O(divb_direct_2); O(divb_immed_2b); O(divb_indexed_2); O(divb_indirect_2);
+ O(divu_direct_2); O(divu_immed_2w); O(divu_indexed_2); O(divu_indirect_2);
+ O(divub_direct_2); O(divub_immed_2b); O(divub_indexed_2); O(divub_indirect_2);
+ O(djnz_rrel8);
+ O(djnzw_rrel8);
+ O(ei_none);
+ O(ext_direct_1);
+ O(extb_direct_1);
+ O(idlpd_none);
+ O(inc_direct_1);
+ O(incb_direct_1);
+ O(jbc_brrel8);
+ O(jbs_brrel8);
+ O(jc_rel8);
+ O(je_rel8);
+ O(jge_rel8);
+ O(jgt_rel8);
+ O(jh_rel8);
+ O(jle_rel8);
+ O(jlt_rel8);
+ O(jnc_rel8);
+ O(jne_rel8);
+ O(jnh_rel8);
+ O(jnst_rel8);
+ O(jnv_rel8);
+ O(jnvt_rel8);
+ O(jst_rel8);
+ O(jv_rel8);
+ O(jvt_rel8);
+ O(lcall_rel16);
+ O(ld_direct_2); O(ld_immed_2w); O(ld_indexed_2); O(ld_indirect_2);
+ O(ldb_direct_2); O(ldb_immed_2b); O(ldb_indexed_2); O(ldb_indirect_2);
+ O(ldbse_direct_2); O(ldbse_immed_2b); O(ldbse_indexed_2); O(ldbse_indirect_2);
+ O(ldbze_direct_2); O(ldbze_immed_2b); O(ldbze_indexed_2); O(ldbze_indirect_2);
+ O(ljmp_rel16);
+ 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);
+ 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);
+ 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);
+ 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);
+ O(neg_direct_1);
+ O(negb_direct_1);
+ O(nop_none);
+ O(norml_direct_2);
+ O(not_direct_1);
+ O(notb_direct_1);
+ O(or_direct_2); O(or_immed_2w); O(or_indexed_2); O(or_indirect_2);
+ O(orb_direct_2); O(orb_immed_2b); O(orb_indexed_2); O(orb_indirect_2);
+ O(pop_direct_1); O(pop_indexed_1); O(pop_indirect_1);
+ O(popa_none);
+ O(popf_none);
+ O(push_direct_1); O(push_immed_1w); O(push_indexed_1); O(push_indirect_1);
+ O(pusha_none);
+ O(pushf_none);
+ O(ret_none);
+ O(rst_none);
+ O(scall_rel11);
+ O(setc_none);
+ O(shl_immed_2b);
+ O(shlb_immed_2b);
+ O(shll_immed_2b);
+ O(shr_immed_2b);
+ O(shra_immed_2b);
+ O(shrab_immed_2b);
+ O(shral_immed_2b);
+ O(shrb_immed_2b);
+ O(shrl_immed_2b);
+ O(sjmp_rel11);
+ O(skip_immed_1b);
+ O(st_direct_2); O(st_indexed_2); O(st_indirect_2);
+ O(stb_direct_2); O(stb_indexed_2); O(stb_indirect_2);
+ 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);
+ 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);
+ O(subc_direct_2); O(subc_immed_2w); O(subc_indexed_2); O(subc_indirect_2);
+ O(subcb_direct_2); O(subcb_immed_2w); O(subcb_indexed_2); O(subcb_indirect_2);
+ O(trap_none);
+ O(xch_direct_2);
+ O(xchb_direct_2);
+ O(xor_direct_2); O(xor_immed_2w); O(xor_indexed_2); O(xor_indirect_2);
+ O(xorb_direct_2); O(xorb_immed_2b); O(xorb_indexed_2); O(xorb_indirect_2);
+
+ O(fetch);
+ O(fetch_noirq);
+
+#undef O
+};
+
+enum {
+ MCS96_PC = 1,
+ MCS96_PSW,
+ MCS96_R // 0x74 entries
+};
+
+#endif
diff --git a/src/emu/cpu/mcs96/mcs96make.py b/src/emu/cpu/mcs96/mcs96make.py
index e69de29bb2d..4c6158a4914 100644
--- a/src/emu/cpu/mcs96/mcs96make.py
+++ b/src/emu/cpu/mcs96/mcs96make.py
@@ -0,0 +1,192 @@
+#!/usr/bin/python
+
+USAGE = """
+Usage:
+%s mcs96ops.lst mcs96.inc
+"""
+import sys
+
+def save_full_one(f, t, name, source):
+ print >>f, "void %s_device::%s_full()" % (t, name)
+ print >>f, "{"
+ for line in source:
+ print >>f, line
+ print >>f, "}"
+ print >>f
+
+class Opcode:
+ def __init__(self, rng, name, amode, is_196, ea):
+ rng1 = rng.split("-")
+ self.rng_start = int(rng1[0], 16)
+ if len(rng1) == 2:
+ self.rng_end = int(rng1[1], 16)
+ else:
+ self.rng_end = self.rng_start
+ self.name = name
+ self.amode = amode
+ self.source = []
+ self.is_196 = is_196
+ if amode in ea:
+ for line in ea[amode].source:
+ self.source.append(line)
+
+ def add_source_line(self, line):
+ self.source.append(line)
+
+class Special:
+ def __init__(self, name):
+ self.name = name
+ self.source = []
+
+ def add_source_line(self, line):
+ self.source.append(line)
+
+class Macro:
+ def __init__(self, tokens):
+ self.name = tokens[1]
+ self.params = []
+ for i in range(2, len(tokens)):
+ self.params.append(tokens[i])
+ self.source = []
+
+ def add_source_line(self, line):
+ self.source.append(line)
+
+ def apply(self, target, tokens):
+ values = []
+ for i in range(1, len(tokens)):
+ values.append(tokens[i])
+ for i in range(0, len(self.source)):
+ line = self.source[i]
+ for i in range(0, len(self.params)):
+ line = line.replace(self.params[i], values[i])
+ target.add_source_line(line)
+
+class OpcodeList:
+ def __init__(self, fname, is_196):
+ self.opcode_info = []
+ self.opcode_per_id = {}
+ self.ea = {}
+ self.macros = {}
+ try:
+ f = open(fname, "r")
+ except Exception, err:
+ print "Cannot read opcodes file %s [%s]" % (fname, err)
+ sys.exit(1)
+
+ opc = None
+ for line in f:
+ if line.startswith("#"):
+ continue
+ line = line.rstrip()
+ if not line:
+ continue
+ if line.startswith(" ") or line.startswith("\t"):
+ # append instruction to last opcode, maybe expand a macro
+ tokens = line.split()
+ if tokens[0] in self.macros:
+ self.macros[tokens[0]].apply(inf, tokens)
+ else:
+ inf.add_source_line(line)
+ else:
+ # New something
+ tokens = line.split()
+ # Addressing mode header
+ if tokens[0] == "eadr":
+ inf = Special(tokens[1])
+ self.ea[inf.name] = inf
+ elif tokens[0] == "fetch":
+ inf = Special(tokens[0])
+ self.fetch = inf
+ elif tokens[0] == "fetch_noirq":
+ inf = Special(tokens[0])
+ self.fetch_noirq = inf
+ elif tokens[0] == "macro":
+ inf = Macro(tokens)
+ self.macros[inf.name] = inf
+ else:
+ inf = Opcode(tokens[0], tokens[1], tokens[2], len(tokens) >= 4 and tokens[3] == "196", self.ea)
+ self.opcode_info.append(inf)
+ if is_196 or not inf.is_196:
+ for i in range(inf.rng_start, inf.rng_end+1):
+ self.opcode_per_id[i] = inf
+
+ def save_dasm(self, f, t):
+ print >>f, "const %s_device::disasm_entry %s_device::disasm_entries[0x100] = {" % (t, t)
+ for i in range(0, 0x100):
+ if i in self.opcode_per_id:
+ opc = self.opcode_per_id[i]
+ alt = "NULL"
+ if i + 0xfe00 in self.opcode_per_id:
+ alt = "\"" + self.opcode_per_id[i+0xfe00].name + "\""
+ if opc.name == "scall" or opc.name == "lcall":
+ flags = "DASMFLAG_STEP_OVER"
+ elif opc.name == "rts":
+ flags = "DASMFLAG_STEP_OUT"
+ else:
+ flags = "0"
+ print >>f, "\t{ \"%s\", %s, DASM_%s, %s }," % (opc.name, alt, opc.amode, flags)
+ else:
+ print >>f, "\t{ \"???\", NULL, DASM_none, 0 },"
+ print >>f, "};"
+ print >>f
+
+ def save_opcodes(self, f, t):
+ pf = ""
+ is_196 = False
+ if t == "i8xc196":
+ pf = "_196"
+ is_196 = True
+ for opc in self.opcode_info:
+ if opc.is_196 == is_196:
+ save_full_one(f, t, opc.name + "_" + opc.amode + pf, opc.source)
+ if not is_196:
+ save_full_one(f, t, "fetch", self.fetch.source)
+ save_full_one(f, t, "fetch_noirq", self.fetch_noirq.source)
+
+ def save_exec(self, f, t):
+ print >>f, "void %s_device::do_exec_full()" % t
+ print >>f, "{"
+ print >>f, "\tswitch(inst_state) {"
+ for i in range(0x000, 0x200):
+ opc = None
+ if i >= 0x100 and i-0x100+0xfe00 in self.opcode_per_id:
+ opc = self.opcode_per_id[i-0x100+0xfe00]
+ if opc == None and (i & 0xff) in self.opcode_per_id:
+ opc = self.opcode_per_id[i & 0xff]
+ if opc != None:
+ nm = opc.name + "_" + opc.amode
+ if opc.is_196:
+ nm = nm + "_196"
+ print >>f, "\tcase 0x%03x: %s_full(); break;" % (i, nm)
+ print >>f, "\tcase 0x200: fetch_full(); break;"
+ print >>f, "\tcase 0x201: fetch_noirq_full(); break;"
+ print >>f, "\t}"
+ print >>f, "}"
+
+def main(argv):
+ if len(argv) != 4:
+ print USAGE % argv[0]
+ return 1
+
+ t = argv[1]
+ opcodes = OpcodeList(argv[2], t == "i8xc196")
+
+ try:
+ f = open(argv[3], "w")
+ except Exception, err:
+ logging.error("cannot write file %s [%s]", fname, err)
+ sys.exit(1)
+
+ if t != "mcs96":
+ opcodes.save_dasm(f, t)
+ if t != "i8x9x":
+ opcodes.save_opcodes(f, t)
+ if t != "mcs96":
+ opcodes.save_exec(f, t)
+ f.close()
+
+# ======================================================================
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
+
diff --git a/src/emu/cpu/mcs96/mcs96ops.lst b/src/emu/cpu/mcs96/mcs96ops.lst
index e69de29bb2d..0f41d2c777d 100644
--- a/src/emu/cpu/mcs96/mcs96ops.lst
+++ b/src/emu/cpu/mcs96/mcs96ops.lst
@@ -0,0 +1,1617 @@
+fetch
+ if(irq_requested) {
+ int level;
+ for(level = 7; level >= 0 && !(PSW & pending_irq & (1<<level)); level--);
+ pending_irq &= ~(1<<level);
+ OP1 = level;
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ any_w16(TMP, PC);
+ PC = any_r16(0x2000+2*OP1);
+ standard_irq_callback(OP1);
+ check_irq();
+ }
+ if(machine().debug_flags & DEBUG_FLAG_ENABLED)
+ debugger_instruction_hook(this, PC);
+ PPC = PC;
+ OP1 = read_pc();
+ if(OP1 == 0xfe) {
+ OP1 = read_pc();
+ inst_state = 0x100 | OP1;
+ } else
+ inst_state = OP1;
+
+fetch_noirq
+ if(machine().debug_flags & DEBUG_FLAG_ENABLED)
+ debugger_instruction_hook(this, PC);
+ PPC = PC;
+ OP1 = read_pc();
+ if(OP1 == 0xfe) {
+ OP1 = read_pc();
+ inst_state = 0x100 | OP1;
+ } else
+ inst_state = OP1;
+
+eadr rel8
+ OP1 = INT8(read_pc());
+
+eadr rel11
+ OP1 = read_pc();
+ OP1 = OP1 | ((inst_state & 7) << 8);
+ if(OP1 & 0x400)
+ OP1 |= 0xfc00;
+
+eadr rel16
+ OP1 = read_pc();
+ OP1 |= read_pc() << 8;
+
+eadr rrel8
+ OP2 = read_pc();
+ OP1 = INT8(read_pc());
+
+eadr brrel8
+ OP2 = read_pc();
+ OP1 = INT8(read_pc());
+
+eadr direct_1
+ OP1 = read_pc();
+
+eadr direct_2
+ OP1 = read_pc();
+ OP2 = read_pc();
+
+eadr direct_3
+ OP1 = read_pc();
+ OP2 = read_pc();
+ OP3 = read_pc();
+
+eadr immed_1b
+ OP1 = read_pc();
+
+eadr immed_2b
+ OP1 = read_pc();
+ OP2 = read_pc();
+
+eadr immed_3b
+ OP1 = read_pc();
+ OP2 = read_pc();
+ OP3 = read_pc();
+
+eadr immed_1w
+ OP1 = read_pc();
+ OP1 |= read_pc() << 8;
+
+eadr immed_2w
+ OP1 = read_pc();
+ OP1 |= read_pc() << 8;
+ OP2 = read_pc();
+
+eadr immed_3w
+ OP1 = read_pc();
+ OP1 |= read_pc() << 8;
+ OP2 = read_pc();
+ OP3 = read_pc();
+
+eadr indirect_1n
+ OPI = read_pc() & 0xfe;
+ OP1 = reg_r16(OPI);
+
+eadr indirect_1
+ OPI = read_pc();
+ OP1 = reg_r16(OPI);
+
+eadr indirect_2
+ OPI = read_pc();
+ OP1 = reg_r16(OPI);
+ OP2 = read_pc();
+
+eadr indirect_3
+ OPI = read_pc();
+ OP1 = reg_r16(OPI);
+ OP2 = read_pc();
+ OP3 = read_pc();
+
+macro post_indirect $size $cycles1 $cycles2
+ if(OPI & 0x01) {
+ reg_w16(OPI, OP1 + $size);
+ next($cycles2); // +4 when external
+ } else {
+ next($cycles1); // +4 when external
+ }
+
+eadr indexed_1
+ OPI = read_pc();
+ OP1 = read_pc();
+ if(OPI & 0x01) {
+ OPI &= 0xfe;
+ OP1 |= read_pc() << 8;
+ } else
+ OP1 = INT8(OP1);
+ if(OPI) {
+ OP1 += reg_r16(OPI);
+ }
+
+eadr indexed_2
+ OPI = read_pc();
+ OP1 = read_pc();
+ if(OPI & 0x01) {
+ OPI &= 0xfe;
+ OP1 |= read_pc() << 8;
+ } else if(OP1 & 0x80)
+ OP1 |= 0xff00;
+ if(OPI) {
+ OP1 += reg_r16(OPI);
+ }
+ OP2 = read_pc();
+
+eadr indexed_3
+ OPI = read_pc();
+ OP1 = read_pc();
+ if(OPI & 0x01) {
+ OPI &= 0xfe;
+ OP1 |= read_pc() << 8;
+ } else if(OP1 & 0x80)
+ OP1 |= 0xff00;
+ if(OPI) {
+ OP1 += reg_r16(OPI);
+ }
+ OP2 = read_pc();
+ OP3 = read_pc();
+
+macro post_indexed $cycles1 $cycles2
+ next(OPI & 0x01 ? $cycles2 : $cycles1);
+
+00 skip immed_1b
+ next(4);
+
+01 clr direct_1
+ reg_w16(OP1, 0x0000);
+ next(4);
+
+02 not direct_1
+ TMP = ~reg_r16(OP1);
+ set_nz16(TMP);
+ reg_w16(OP1, TMP);
+ next(4);
+
+03 neg direct_1
+ TMP = reg_r16(OP1);
+ reg_w16(OP1, do_sub(0, TMP));
+ next(4);
+
+04 xch direct_2
+
+05 dec direct_1
+ TMP = reg_r16(OP1);
+ reg_w16(OP1, do_sub(TMP, 1));
+ next(4);
+
+06 ext direct_1
+ OP1 &= 0xfc;
+ TMP = INT16(reg_r16(OP1));
+ set_nz16(TMP);
+ reg_w16(OP1+2, TMP >> 16);
+ next(4);
+
+07 inc direct_1
+ TMP = reg_r16(OP1);
+ reg_w16(OP1, do_add(TMP, 1));
+ next(4);
+
+08 shr immed_2b
+ OP1 &= 0x1f;
+ TMP = reg_r16(OP2);
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xffff >> (OP1 <= 16 ? 17-OP1 : 0))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && OP1 <= 16 && (TMP & (0x0001 << (OP1-1))))
+ PSW |= F_C;
+ TMP = UINT16(TMP) >> OP1;
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT16(TMP) < 0)
+ PSW |= F_N;
+ reg_w16(OP2, TMP);
+ next(OP1 ? 7+OP1 : 8);
+
+09 shl immed_2b
+ OP1 &= 0x1f;
+ TMP = reg_r16(OP2);
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xffff << (OP1 <= 16 ? 17-OP1 : 0))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && OP1 <= 16 && (TMP & (0x8000 >> (OP1-1))))
+ PSW |= F_C;
+ TMP = UINT16(TMP << OP1);
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT16(TMP) < 0)
+ PSW |= F_N;
+ reg_w16(OP2, TMP);
+ next(OP1 ? 7+OP1 : 8);
+
+0a shra immed_2b
+ OP1 &= 0x1f;
+ TMP = reg_r16(OP2);
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xffff >> (OP1 <= 16 ? 17-OP1 : 0))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && OP1 <= 16 && (TMP & (0x0001 << (OP1-1))))
+ PSW |= F_C;
+ TMP = INT16(TMP) >> OP1;
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT16(TMP) < 0)
+ PSW |= F_N;
+ reg_w16(OP2, TMP);
+ next(OP1 ? 7+OP1 : 8);
+
+0c shrl immed_2b
+ OP1 &= 0x1f;
+ OP2 &= 0xfc;
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2) << 16;
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xffffffff >> (33-OP1))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && (TMP & (0x00000001 << (OP1-1))))
+ PSW |= F_C;
+ TMP = TMP >> OP1;
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT32(TMP) < 0)
+ PSW |= F_N;
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(OP1 ? 7+OP1 : 8);
+
+0d shll immed_2b
+ OP1 &= 0x1f;
+ OP2 &= 0xfc;
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2) << 16;
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xffffffff << (33-OP1))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && (TMP & (0x80000000 >> (OP1-1))))
+ PSW |= F_C;
+ TMP = TMP << OP1;
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT32(TMP) < 0)
+ PSW |= F_N;
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(OP1 ? 7+OP1 : 8);
+
+0e shral immed_2b
+ OP1 &= 0x1f;
+ OP2 &= 0xfc;
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2) << 16;
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xffffffff >> (33-OP1))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && (TMP & (0x00000001 << (OP1-1))))
+ PSW |= F_C;
+ TMP = INT32(TMP) >> OP1;
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT32(TMP) < 0)
+ PSW |= F_N;
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(OP1 ? 7+OP1 : 8);
+
+0f norml direct_2
+
+11 clrb direct_1
+ reg_w8(OP1, 0x00);
+ next(4);
+
+12 notb direct_1
+ TMP = ~reg_r8(OP1);
+ set_nz8(TMP);
+ reg_w8(OP1, TMP);
+ next(4);
+
+13 negb direct_1
+ TMP = reg_r8(OP1);
+ reg_w8(OP1, do_subb(0, TMP));
+ next(4);
+
+14 xchb direct_2
+
+15 decb direct_1
+ TMP = reg_r8(OP1);
+ reg_w8(OP1, do_subb(TMP, 1));
+ next(4);
+
+16 extb direct_1
+ OP1 &= 0xfe;
+ TMP = INT8(reg_r8(OP1));
+ set_nz8(TMP);
+ reg_w16(OP1, TMP);
+ next(4);
+
+17 incb direct_1
+ TMP = reg_r8(OP1);
+ reg_w8(OP1, do_addb(TMP, 1));
+ next(4);
+
+18 shrb immed_2b
+ OP1 &= 0x1f;
+ TMP = reg_r8(OP2);
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xff >> (OP1 <= 8 ? 9-OP1 : 0))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && OP1 <= 8 && (TMP & (0x01 << (OP1-1))))
+ PSW |= F_C;
+ TMP = UINT8(TMP) >> OP1;
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT8(TMP) < 0)
+ PSW |= F_N;
+ reg_w8(OP2, TMP);
+ next(OP1 ? 7+OP1 : 8);
+
+19 shlb immed_2b
+ OP1 &= 0x1f;
+ TMP = reg_r8(OP2);
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xff << (OP1 <= 8 ? 9-OP1 : 0))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && OP1 <= 8 && (TMP & (0x80 >> (OP1-1))))
+ PSW |= F_C;
+ TMP = UINT8(TMP << OP1);
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT8(TMP) < 0)
+ PSW |= F_N;
+ reg_w8(OP2, TMP);
+ next(OP1 ? 7+OP1 : 8);
+
+1a shrab immed_2b
+ OP1 &= 0x1f;
+ TMP = reg_r8(OP2);
+ PSW &= ~(F_Z|F_N|F_C|F_V|F_ST);
+ if(OP1 >= 2 && (TMP & (0xff >> (OP1 <= 8 ? 9-OP1 : 0))))
+ PSW |= F_ST;
+ if(OP1 >= 1 && OP1 <= 8 && (TMP & (0x01 << (OP1-1))))
+ PSW |= F_C;
+ TMP = UINT8(INT8(TMP) >> OP1);
+ if(!TMP)
+ PSW |= F_Z;
+ else if(INT8(TMP) < 0)
+ PSW |= F_N;
+ reg_w8(OP2, TMP);
+ next(OP1 ? 7+OP1 : 8);
+
+20-27 sjmp rel11
+ PC += OP1;
+ next(8);
+
+28-2f scall rel11
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ any_w16(TMP, PC);
+ PC += OP1;
+ next(13); // real is 13/16 depending on sp's position
+
+30-37 jbc brrel8
+ TMP = reg_r8(OP2);
+ if(!((TMP >> (inst_state & 7)) & 1)) {
+ PC += OP1;
+ next(9);
+ } else {
+ next(5);
+ }
+
+38-3f jbs brrel8
+ TMP = reg_r8(OP2);
+ if((TMP >> (inst_state & 7)) & 1) {
+ PC += OP1;
+ next(9);
+ } else {
+ next(5);
+ }
+
+40 and direct_3
+ TMP = reg_r16(OP1);
+ TMP &= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP3, TMP);
+ next(5);
+
+41 and immed_3w
+ TMP = OP1 & reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP3, TMP);
+ next(6);
+
+42 and indirect_3
+ TMP = any_r16(OP1);
+ TMP &= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP3, TMP);
+ post_indirect 2 7 8 // +5 when external
+
+43 and indexed_3
+ TMP = any_r16(OP1);
+ TMP &= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+44 add direct_3
+ TMP = reg_r16(OP1);
+ TMP = do_add(reg_r16(OP2), TMP);
+ reg_w16(OP3, TMP);
+ next(5);
+
+45 add immed_3w
+ TMP = do_add(reg_r16(OP2), OP1);
+ reg_w16(OP3, TMP);
+ next(6);
+
+46 add indirect_3
+ TMP = any_r16(OP1);
+ TMP = do_add(reg_r16(OP2), TMP);
+ reg_w16(OP3, TMP);
+ post_indirect 2 7 8 // +5 when external
+
+47 add indexed_3
+ TMP = any_r16(OP1);
+ TMP = do_add(reg_r16(OP2), TMP);
+ reg_w16(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+48 sub direct_3
+ TMP = reg_r16(OP1);
+ TMP = do_sub(reg_r16(OP2), TMP);
+ reg_w16(OP3, TMP);
+ next(5);
+
+49 sub immed_3w
+ TMP = do_sub(reg_r16(OP2), OP1);
+ reg_w16(OP3, TMP);
+ next(6);
+
+4a sub indirect_3
+ TMP = any_r16(OP1);
+ TMP = do_sub(reg_r16(OP2), TMP);
+ reg_w16(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+4b sub indexed_3
+ TMP = any_r16(OP1);
+ TMP = do_sub(reg_r16(OP2), TMP);
+ reg_w16(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+4c mulu direct_3
+ TMP = reg_r16(OP1);
+ TMP *= reg_r16(OP2);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ next(26);
+
+4d mulu immed_3w
+ TMP = OP1 * reg_r16(OP2);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ next(27);
+
+4e mulu indirect_3
+ TMP = any_r16(OP1);
+ TMP *= reg_r16(OP2);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ post_indirect 2 28 29 // +5 when external
+
+4f mulu indexed_3
+ TMP = any_r16(OP1);
+ TMP *= reg_r16(OP2);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ post_indexed 28 29 // +5 when external
+
+fe4c mul direct_3
+ TMP = reg_r16(OP1);
+ TMP = INT16(reg_r16(OP2)) * INT16(TMP);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ next(30);
+
+fe4d mul immed_3w
+ TMP = INT16(OP1) * INT16(reg_r16(OP2));
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ next(31);
+
+fe4e mul indirect_3
+ TMP = any_r16(OP1);
+ TMP = INT16(reg_r16(OP2)) * INT16(TMP);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ post_indirect 2 32 33 // +5 when external
+
+fe4f mul indexed_3
+ TMP = any_r16(OP1);
+ TMP = INT16(reg_r16(OP2)) * INT16(TMP);
+ OP3 &= 0xfc;
+ reg_w16(OP3, TMP);
+ reg_w16(OP3+2, TMP >> 16);
+ post_indexed 32 33 // +5 when external
+
+50 andb direct_3
+ TMP = reg_r8(OP1);
+ TMP &= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP3, TMP);
+ next(5);
+
+51 andb immed_3b
+ TMP = OP1 & reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP3, TMP);
+ next(5);
+
+52 andb indirect_3
+ TMP = any_r8(OP1);
+ TMP &= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP3, TMP);
+ post_indirect 1 7 8 // +5 when external
+
+53 andb indexed_3
+ TMP = any_r8(OP1);
+ TMP &= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+54 addb direct_3
+ TMP = reg_r8(OP1);
+ TMP = do_addb(reg_r8(OP2), TMP);
+ reg_w8(OP3, TMP);
+ next(5);
+
+55 addb immed_3b
+ TMP = do_addb(reg_r8(OP2), OP1);
+ reg_w8(OP3, TMP);
+ next(5);
+
+56 addb indirect_3
+ TMP = any_r8(OP1);
+ TMP = do_addb(reg_r8(OP2), TMP);
+ reg_w8(OP3, TMP);
+ post_indirect 1 7 8 // +5 when external
+
+57 addb indexed_3
+ TMP = any_r8(OP1);
+ TMP = do_addb(reg_r8(OP2), TMP);
+ reg_w8(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+58 subb direct_3
+ TMP = reg_r8(OP1);
+ TMP = do_subb(reg_r8(OP2), TMP);
+ reg_w8(OP3, TMP);
+ next(5);
+
+59 subb immed_3b
+ TMP = do_subb(reg_r8(OP2), OP1);
+ reg_w8(OP3, TMP);
+ next(5);
+
+5a subb indirect_3
+ TMP = any_r8(OP1);
+ TMP = do_subb(reg_r8(OP2), TMP);
+ reg_w8(OP3, TMP);
+ post_indirect 1 7 8 // +5 when external
+
+5b subb indexed_3
+ TMP = any_r8(OP1);
+ TMP = do_subb(reg_r8(OP2), TMP);
+ reg_w8(OP3, TMP);
+ post_indexed 7 8 // +5 when external
+
+5c mulub direct_3
+ TMP = reg_r8(OP1);
+ TMP *= reg_r8(OP2);
+ reg_w16(OP3, TMP);
+ next(18);
+
+5d mulub immed_3b
+ TMP = OP1 * reg_r8(OP2);
+ reg_w16(OP3, TMP);
+ next(18);
+
+5e mulub indirect_3
+ TMP = any_r8(OP1);
+ TMP *= reg_r8(OP2);
+ reg_w16(OP3, TMP);
+ post_indirect 1 20 21 // +5 when external
+
+5f mulub indexed_3
+ TMP = any_r8(OP1);
+ TMP = reg_r8(OP2);
+ reg_w16(OP3, TMP);
+ post_indexed 20 21 // +5 when external
+
+fe5c mulb direct_3
+ TMP = reg_r8(OP1);
+ TMP = INT8(reg_r8(OP2)) * INT8(TMP);
+ reg_w16(OP3, TMP);
+ next(22);
+
+fe5d mulb immed_3b
+ TMP = INT8(OP1) * INT8(reg_r8(OP2));
+ reg_w16(OP3, TMP);
+ next(22);
+
+fe5e mulb indirect_3
+ TMP = any_r8(OP1);
+ TMP = INT8(reg_r8(OP2)) * INT8(TMP);
+ reg_w16(OP3, TMP);
+ post_indirect 1 24 25 // +5 when external
+
+fe5f mulb indexed_3
+ TMP = any_r8(OP1);
+ TMP = INT8(reg_r8(OP2)) * INT8(TMP);
+ reg_w16(OP3, TMP);
+ post_indexed 24 25 // +5 when external
+
+60 and direct_2
+ TMP = reg_r16(OP1);
+ TMP &= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ next(4);
+
+61 and immed_2w
+ TMP = OP1 & reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ next(5);
+
+62 and indirect_2
+ TMP = any_r16(OP1);
+ TMP &= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ post_indirect 2 6 7 // +5 when external
+
+63 and indexed_2
+ TMP = any_r16(OP1);
+ TMP &= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+64 add direct_2
+ TMP = reg_r16(OP1);
+ TMP = do_add(reg_r16(OP2), TMP);
+ reg_w16(OP2, TMP);
+ next(4);
+
+65 add immed_2w
+ TMP = do_add(reg_r16(OP2), OP1);
+ reg_w16(OP2, TMP);
+ next(5);
+
+66 add indirect_2
+ TMP = any_r16(OP1);
+ TMP = do_add(reg_r16(OP2), TMP);
+ reg_w16(OP2, TMP);
+ post_indirect 2 6 7 // +5 when external
+
+67 add indexed_2
+ TMP = any_r16(OP1);
+ TMP = do_add(reg_r16(OP2), TMP);
+ reg_w16(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+68 sub direct_2
+ TMP = reg_r16(OP1);
+ TMP = do_sub(reg_r16(OP2), TMP);
+ reg_w16(OP2, TMP);
+ next(4);
+
+69 sub immed_2w
+ TMP = do_sub(reg_r16(OP2), OP1);
+ reg_w16(OP2, TMP);
+ next(5);
+
+6a sub indirect_2
+ TMP = any_r16(OP1);
+ TMP = do_sub(reg_r16(OP2), TMP);
+ reg_w16(OP2, TMP);
+ post_indirect 2 6 7 // +5 when external
+
+6b sub indexed_2
+ TMP = any_r16(OP1);
+ TMP = do_sub(reg_r16(OP2), TMP);
+ reg_w16(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+6c mulu direct_2
+ OP2 &= 0xfc;
+ TMP = reg_r16(OP1);
+ TMP *= reg_r16(OP2);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(25);
+
+6d mulu immed_2w
+ OP2 &= 0xfc;
+ TMP = OP1 * reg_r16(OP2);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(26);
+
+6e mulu indirect_2
+ OP2 &= 0xfc;
+ TMP = any_r16(OP1);
+ TMP *= reg_r16(OP2);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ post_indirect 2 27 28 // +5 when external
+
+6f mulu indexed_2
+ OP2 &= 0xfc;
+ TMP = any_r16(OP1);
+ TMP *= reg_r16(OP2);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ post_indexed 27 28 // +5 when external
+
+fe6c mul direct_2
+ OP2 &= 0xfc;
+ TMP = reg_r16(OP1);
+ TMP = INT16(reg_r16(OP2)) * INT16(TMP);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(29);
+
+fe6d mul immed_2w
+ OP2 &= 0xfc;
+ TMP = INT16(OP1) * INT16(reg_r16(OP2));
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(30);
+
+fe6e mul indirect_2
+ OP2 &= 0xfc;
+ TMP = any_r16(OP1);
+ TMP = INT16(reg_r16(OP2)) * INT16(TMP);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ post_indirect 2 31 32 // +5 when external
+
+fe6f mul indexed_2
+ OP2 &= 0xfc;
+ TMP = any_r16(OP1);
+ TMP = INT16(reg_r16(OP2)) * INT16(TMP);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ post_indexed 31 32 // +5 when external
+
+70 andb direct_2
+ TMP = reg_r8(OP1);
+ TMP &= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+71 andb immed_2b
+ TMP = OP1 & reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+72 andb indirect_2
+ TMP = any_r8(OP1);
+ TMP &= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ post_indirect 1 6 7 // +5 when external
+
+73 andb indexed_2
+ TMP = any_r8(OP1);
+ TMP &= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP3, TMP);
+ post_indexed 6 7 // +5 when external
+
+74 addb direct_2
+ TMP = reg_r8(OP1);
+ TMP = do_addb(reg_r8(OP2), TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+75 addb immed_2b
+ TMP = do_addb(reg_r8(OP2), OP1);
+ reg_w8(OP2, TMP);
+ next(4);
+
+76 addb indirect_2
+ TMP = any_r8(OP1);
+ TMP = do_addb(reg_r8(OP2), TMP);
+ reg_w8(OP2, TMP);
+ post_indirect 1 6 7 // +5 when external
+
+77 addb indexed_2
+ TMP = any_r8(OP1);
+ TMP = do_addb(reg_r8(OP2), TMP);
+ reg_w8(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+78 subb direct_2
+ TMP = reg_r8(OP1);
+ TMP = do_subb(reg_r8(OP2), TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+79 subb immed_2b
+ TMP = do_subb(reg_r8(OP2), OP1);
+ reg_w8(OP2, TMP);
+ next(4);
+
+7a subb indirect_2
+ TMP = any_r8(OP1);
+ TMP = do_subb(reg_r8(OP2), TMP);
+ reg_w8(OP2, TMP);
+ post_indirect 1 6 7 // +5 when external
+
+7b subb indexed_2
+ TMP = any_r8(OP1);
+ TMP = do_subb(reg_r8(OP2), TMP);
+ reg_w8(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+7c mulub direct_2
+ OP2 &= 0xfe;
+ TMP = reg_r8(OP1);
+ TMP *= reg_r8(OP2);
+ reg_w16(OP2, TMP);
+ next(17);
+
+7d mulub immed_2b
+ OP2 &= 0xfe;
+ TMP = OP1 * reg_r8(OP2);
+ reg_w16(OP2, TMP);
+ next(17);
+
+7e mulub indirect_2
+ OP2 &= 0xfe;
+ TMP = any_r8(OP1);
+ TMP *= reg_r8(OP2);
+ reg_w16(OP2, TMP);
+ post_indirect 1 19 20 // +5 when external
+
+7f mulub indexed_2
+ OP2 &= 0xfe;
+ TMP = any_r8(OP1);
+ TMP *= reg_r8(OP2);
+ reg_w16(OP2, TMP);
+ post_indexed 19 20 // +5 when external
+
+fe7c mulb direct_2
+ OP2 &= 0xfe;
+ TMP = reg_r8(OP1);
+ TMP = INT8(reg_r16(OP2)) * INT8(TMP);
+ reg_w16(OP2, TMP);
+ next(21);
+
+fe7d mulb immed_2b
+ OP2 &= 0xfe;
+ TMP = INT8(OP1) * INT8(reg_r8(OP2));
+ reg_w16(OP2, TMP);
+ next(21);
+
+fe7e mulb indirect_2
+ OP2 &= 0xfe;
+ TMP = any_r8(OP1);
+ TMP = INT8(reg_r8(OP2)) * INT8(TMP);
+ reg_w16(OP2, TMP);
+ post_indirect 1 23 24 // +5 when external
+
+fe7f mulb indexed_2
+ OP2 &= 0xfe;
+ TMP = any_r16(OP1);
+ TMP = INT8(reg_r16(OP2)) * INT8(TMP);
+ reg_w16(OP2, TMP);
+ post_indexed 23 24 // +5 when external
+
+80 or direct_2
+ TMP = reg_r16(OP1);
+ TMP |= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ next(4);
+
+81 or immed_2w
+ TMP = OP1 | reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ next(5);
+
+82 or indirect_2
+ TMP = any_r16(OP1);
+ TMP |= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ post_indirect 2 6 7 // +5 when external
+
+83 or indexed_2
+ TMP = any_r16(OP1);
+ TMP |= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+84 xor direct_2
+ TMP = reg_r16(OP1);
+ TMP ^= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ next(4);
+
+85 xor immed_2w
+ TMP = OP1 ^ reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ next(5);
+
+86 xor indirect_2
+ TMP = any_r16(OP1);
+ TMP ^= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ post_indirect 2 6 7 // +5 when external
+
+87 xor indexed_2
+ TMP = any_r16(OP1);
+ TMP ^= reg_r16(OP2);
+ set_nz16(TMP);
+ reg_w16(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+88 cmp direct_2
+ TMP = reg_r16(OP1);
+ do_sub(reg_r16(OP2), TMP);
+ next(4);
+
+89 cmp immed_2w
+ do_sub(reg_r16(OP2), OP1);
+ next(5);
+
+8a cmp indirect_2
+ TMP = any_r16(OP1);
+ do_sub(reg_r16(OP2), TMP);
+ post_indirect 2 6 7 // +5 when external
+
+8b cmp indexed_2
+ TMP = any_r16(OP1);
+ do_sub(reg_r16(OP2), TMP);
+ post_indexed 6 7 // +5 when external
+
+8c divu direct_2
+
+8d divu immed_2w
+
+8e divu indirect_2
+
+8f divu indexed_2
+
+fe8c div direct_2
+
+fe8d div immed_2w
+
+fe8e div indirect_2
+
+fe8f div indexed_2
+
+90 orb direct_2
+ TMP = reg_r8(OP1);
+ TMP |= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+91 orb immed_2b
+ TMP = OP1 | reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+92 orb indirect_2
+ TMP = any_r8(OP1);
+ TMP |= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ post_indirect 1 6 7 // +5 when external
+
+93 orb indexed_2
+ TMP = any_r8(OP1);
+ TMP |= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+94 xorb direct_2
+ TMP = reg_r8(OP1);
+ TMP ^= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+95 xorb immed_2b
+ TMP = OP1 ^ reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ next(4);
+
+96 xorb indirect_2
+ TMP = any_r8(OP1);
+ TMP ^= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ post_indirect 1 6 7 // +5 when external
+
+97 xorb indexed_2
+ TMP = any_r8(OP1);
+ TMP ^= reg_r8(OP2);
+ set_nz8(TMP);
+ reg_w8(OP2, TMP);
+ post_indexed 6 7 // +5 when external
+
+98 cmpb direct_2
+ TMP = reg_r8(OP1);
+ do_subb(reg_r8(OP2), TMP);
+ next(4);
+
+99 cmpb immed_2b
+ do_subb(reg_r8(OP2), OP1);
+ next(4);
+
+9a cmpb indirect_2
+ TMP = any_r8(OP1);
+ do_subb(reg_r8(OP2), TMP);
+ post_indirect 2 6 7 // +5 when external
+
+9b cmpb indexed_2
+ TMP = any_r8(OP1);
+ do_subb(reg_r8(OP2), TMP);
+ post_indexed 6 7 // +5 when external
+
+9c divub direct_2
+ PSW &= ~F_V;
+ OP1 = reg_r8(OP1);
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = TMP / OP1;
+ if(TMP2 > 255)
+ PSW |= F_V|F_VT;
+ TMP = TMP % OP1;
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ next(17);
+
+9d divub immed_2b
+ PSW &= ~F_V;
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = TMP / OP1;
+ if(TMP2 > 255)
+ PSW |= F_V|F_VT;
+ TMP = TMP % OP1;
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ next(17);
+
+9e divub indirect_2
+ PSW &= ~F_V;
+ UINT32 d = any_r8(OP1);
+ if(d) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = TMP / d;
+ if(TMP2 > 255)
+ PSW |= F_V|F_VT;
+ TMP = TMP % d;
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ post_indirect 1 20 21 // +4 when external
+
+9f divub indexed_2
+ PSW &= ~F_V;
+ UINT32 d = any_r8(OP1);
+ if(d) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = TMP / d;
+ if(TMP2 > 255)
+ PSW |= F_V|F_VT;
+ TMP = TMP % d;
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ post_indexed 20 21 // +4 when external
+
+fe9c divb direct_2
+ PSW &= ~F_V;
+ OP1 = reg_r8(OP1);
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = INT16(TMP) / INT8(OP1);
+ if(INT8(TMP2) > 127 || INT8(TMP2) < -128)
+ PSW |= F_V|F_VT;
+ TMP = INT16(TMP) % INT8(OP1);
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ next(21);
+
+fe9d divb immed_2b
+ PSW &= ~F_V;
+ OP1 = reg_r8(OP1);
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = INT16(TMP) / INT8(OP1);
+ if(INT8(TMP2) > 127 || INT8(TMP2) < -128)
+ PSW |= F_V|F_VT;
+ TMP = INT16(TMP) % INT8(OP1);
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ next(21);
+
+fe9e divb indirect_2
+
+fe9f divb indexed_2
+
+a0 ld direct_2
+ reg_w16(OP2, reg_r16(OP1));
+ next(4);
+
+a1 ld immed_2w
+ reg_w16(OP2, OP1);
+ next(5);
+
+a2 ld indirect_2
+ reg_w16(OP2, any_r16(OP1));
+ post_indirect 2 6 7 // +5 when external
+
+a3 ld indexed_2
+ reg_w16(OP2, any_r16(OP1));
+ post_indexed 6 7 // +5 when external
+
+a4 addc direct_2
+
+a5 addc immed_2w
+
+a6 addc indirect_2
+
+a7 addc indexed_2
+
+a8 subc direct_2
+
+a9 subc immed_2w
+
+aa subc indirect_2
+
+ab subc indexed_2
+
+ac ldbze direct_2
+ reg_w16(OP2, UINT8(reg_r8(OP1)));
+ next(4);
+
+ad ldbze immed_2b
+ reg_w16(OP2, UINT8(OP1));
+ next(4);
+
+ae ldbze indirect_2
+ reg_w16(OP2, UINT8(any_r8(OP1)));
+ post_indirect 1 6 7 // +5 when external
+
+af ldbze indexed_2
+ reg_w16(OP2, UINT8(any_r8(OP1)));
+ post_indexed 6 7 // +5 when external
+
+b0 ldb direct_2
+ reg_w8(OP2, reg_r8(OP1));
+ next(4);
+
+b1 ldb immed_2b
+ reg_w8(OP2, OP1);
+ next(4);
+
+b2 ldb indirect_2
+ reg_w8(OP2, any_r8(OP1));
+ post_indirect 1 6 7 // +5 when external
+
+b3 ldb indexed_2
+ reg_w8(OP2, any_r8(OP1));
+ post_indexed 6 7 // +5 when external
+
+b4 addcb direct_2
+
+b5 addcb immed_2w
+
+b6 addcb indirect_2
+
+b7 addcb indexed_2
+
+b8 subcb direct_2
+
+b9 subcb immed_2w
+
+ba subcb indirect_2
+
+bb subcb indexed_2
+
+bc ldbse direct_2
+ reg_w16(OP2, INT8(reg_r8(OP1)));
+ next(4);
+
+bd ldbse immed_2b
+ reg_w16(OP2, INT8(OP1));
+ next(4);
+
+be ldbse indirect_2
+ reg_w16(OP2, INT8(any_r8(OP1)));
+ post_indirect 1 6 7 // +5 when external
+
+bf ldbse indexed_2
+ reg_w16(OP2, INT8(any_r8(OP1)));
+ post_indexed 6 7 // +5 when external
+
+c0 st direct_2
+ reg_w16(OP1, reg_r16(OP2));
+ next(4);
+
+c1 bmov direct_2 196
+
+c2 st indirect_2
+ any_w16(OP1, reg_r16(OP2));
+ post_indirect 2 7 8 // +4 when external
+
+c3 st indexed_2
+ any_w16(OP1, reg_r16(OP2));
+ post_indexed 7 8 // +4 when external
+
+c4 stb direct_2
+ reg_w8(OP1, reg_r8(OP2));
+ next(4);
+
+c5 cmpl direct_2 196
+
+c6 stb indirect_2
+ any_w8(OP1, reg_r8(OP2));
+ post_indirect 1 7 8 // +4 when external
+
+c7 stb indexed_2
+ any_w8(OP1, reg_r8(OP2));
+ post_indexed 7 8 // +5 when external
+
+c8 push direct_1
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ OP1 = reg_r16(OP1);
+ any_w16(TMP, OP1);
+ next(8); // +4 is external sp
+
+c9 push immed_1w
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ any_w16(TMP, OP1);
+ next(8); // +4 is external sp
+
+ca push indirect_1
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ OP1 = any_r16(OP1);
+ any_w16(TMP, OP1);
+ post_indirect 2 11 12 // +4 when external
+
+cb push indexed_1
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ OP1 = any_r16(OP1);
+ any_w16(TMP, OP1);
+ post_indexed 11 12 // +4 when external
+
+cc pop direct_1
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ TMP = any_r16(TMP);
+ reg_w16(OP1, TMP);
+ next(12); // +2 when external sp
+
+cd bmovi direct_2 196
+
+ce pop indirect_1
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ TMP = any_r16(TMP);
+ if((OPI & 0xfe) == 0x18)
+ OP1 += 2;
+ any_w16(OP1, TMP);
+ post_indirect 2 14 14 // +2 when external sp, +4 when external write
+
+ce pop indirect_1 196
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ TMP = any_r16(TMP);
+ if((OPI & 0xfe) == 0x18)
+ OP1 += 2;
+ any_w16(OP1, TMP);
+ post_indirect 2 14 14 // +2 when external sp, +4 when external write
+
+cf pop indexed_1
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ TMP = any_r16(TMP);
+ any_w16(OP1, TMP);
+ post_indexed 14 14 // +2 when external sp, +4 when external write
+
+cf pop indexed_1 196
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ TMP = any_r16(TMP);
+ if((OPI & 0xfe) == 0x18)
+ OP1 += 2;
+ any_w16(OP1, TMP);
+ post_indexed 14 14 // +2 when external sp, +4 when external write
+
+d0 jnst rel8
+ if(!(PSW & F_ST)) {
+ PC += OP1;
+ next(8);
+ } else {
+ PSW &= ~F_VT;
+ next(4);
+ }
+
+d1 jnh rel8
+ if((PSW & (F_Z|F_N)) != F_C) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+d2 jgt rel8
+ if(!(PSW & (F_Z|F_N))) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+d3 jnc rel8
+ if(!(PSW & F_C)) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+d4 jnvt rel8
+ if(!(PSW & F_VT)) {
+ PC += OP1;
+ next(8);
+ } else {
+ PSW &= ~F_VT;
+ next(4);
+ }
+
+d5 jnv rel8
+ if(!(PSW & F_V)) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+d6 jge rel8
+ if(!(PSW & F_N)) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+d7 jne rel8
+ if(!(PSW & F_Z)) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+d8 jst rel8
+ if(PSW & F_ST) {
+ PC += OP1;
+ next(8);
+ } else {
+ PSW &= ~F_VT;
+ next(4);
+ }
+
+d9 jh rel8
+ if((PSW & (F_Z|F_N)) == F_C) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+da jle rel8
+ if(PSW & (F_Z|F_N)) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+db jc rel8
+ if(PSW & F_C) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+dc jvt rel8
+ if(PSW & F_VT) {
+ PSW &= ~F_VT;
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+dd jv rel8
+ if(PSW & F_V) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+de jlt rel8
+ if(PSW & F_N) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+df je rel8
+ if(PSW & F_Z) {
+ PC += OP1;
+ next(8);
+ } else {
+ next(4);
+ }
+
+e0 djnz rrel8
+ TMP = reg_r8(OP2);
+ TMP = UINT8(TMP-1);
+ reg_w8(OP2, TMP);
+ if(TMP) {
+ PC += OP1;
+ next(9);
+ } else {
+ next(5);
+ }
+
+e1 djnzw rrel8 196
+ TMP = reg_r16(OP2);
+ TMP = TMP-1;
+ reg_w16(OP2, TMP);
+ if(TMP) {
+ PC += OP1;
+ next(10);
+ } else {
+ next(6);
+ }
+
+e3 br indirect_1n
+ PC = OP1;
+ next(8);
+
+e7 ljmp rel16
+ PC += OP1;
+ next(8);
+
+ef lcall rel16
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ any_w16(TMP, PC);
+ PC += OP1;
+ next(13); // +3 for external sp
+
+f0 ret none
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ PC = any_r16(TMP);
+ next(12); // +4 for external sp
+
+f2 pushf none
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ any_w16(TMP, PSW);
+ PSW = 0x0000;
+ check_irq();
+ next_noirq(8); // +4 for external sp
+
+f3 popf none
+ TMP = reg_r16(0x18);
+ reg_w16(0x18, TMP+2);
+ PSW = any_r16(TMP);
+ check_irq();
+ next_noirq(9); // +4 for external sp
+
+f4 pusha none 196
+
+f5 popa none
+
+f6 idlpd none 196
+
+f7 trap none
+ TMP = reg_r16(0x18);
+ TMP -= 2;
+ reg_w16(0x18, TMP);
+ any_w16(TMP, PC);
+ PC = any_r16(0x2010);
+ next_noirq(21); // +3 for external sp
+
+f8 clrc none
+ PSW &= ~F_C;
+ next(4);
+
+f9 setc none
+ PSW |= F_C;
+ next(4);
+
+fa di none
+ PSW &= ~F_I;
+ check_irq();
+ next_noirq(4);
+
+fb ei none
+ PSW |= F_I;
+ check_irq();
+ next_noirq(4);
+
+fc clrvt none
+ PSW &= ~F_VT;
+ next(4);
+
+fd nop none
+ next(4);
+
+ff rst none
+ PC = 0x2080;
+ next(4);