summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/mcs96
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2012-12-18 10:42:24 +0000
committer Olivier Galibert <galibert@pobox.com>2012-12-18 10:42:24 +0000
commitfe0e8ca1683279b75148db1ede96483295563aa6 (patch)
treef2ba59aaf1f784009e98a311b5c44b6b442e4df7 /src/emu/cpu/mcs96
parentbc2f98d5c1076e64bbb8e498d206e57d861ea379 (diff)
mcs96: Add norml and the missing div variants [O. Galibert]
Diffstat (limited to 'src/emu/cpu/mcs96')
-rw-r--r--src/emu/cpu/mcs96/i8x9x.c16
-rw-r--r--src/emu/cpu/mcs96/i8x9x.h3
-rw-r--r--src/emu/cpu/mcs96/mcs96ops.lst153
3 files changed, 165 insertions, 7 deletions
diff --git a/src/emu/cpu/mcs96/i8x9x.c b/src/emu/cpu/mcs96/i8x9x.c
index cb58a072eee..ddba3f62d63 100644
--- a/src/emu/cpu/mcs96/i8x9x.c
+++ b/src/emu/cpu/mcs96/i8x9x.c
@@ -157,9 +157,11 @@ void i8x9x_device::io_w8(UINT8 adr, UINT8 data)
break;
case 0x0f:
logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC);
+ io->write_word(P1*2, data);
break;
case 0x10:
logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC);
+ io->write_word(P2*2, data);
break;
case 0x11:
logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC);
@@ -237,14 +239,16 @@ UINT8 i8x9x_device::io_r8(UINT8 adr)
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;
+ static int last = -1;
+ if(io->read_word(P0*2) != last) {
+ last = io->read_word(P0*2);
+ logerror("%s: read p0 %02x\n", tag(), io->read_word(P0*2));
+ }
+ return io->read_word(P0*2);
case 0x0f:
- logerror("%s: read io port 1 (%04x)\n", tag(), PPC);
- return 0x00;
+ return io->read_word(P1*2);
case 0x10:
- logerror("%s: read io port 2 (%04x)\n", tag(), PPC);
- return 0x00;
+ return io->read_word(P2*2);
case 0x11: {
UINT8 res = sp_stat;
sp_stat &= 0x80;
diff --git a/src/emu/cpu/mcs96/i8x9x.h b/src/emu/cpu/mcs96/i8x9x.h
index 0f2e1b4f47c..defc890dc26 100644
--- a/src/emu/cpu/mcs96/i8x9x.h
+++ b/src/emu/cpu/mcs96/i8x9x.h
@@ -46,7 +46,8 @@ class i8x9x_device : public mcs96_device {
public:
enum {
A0, A1, A2, A3, A4, A5, A6, A7,
- SERIAL
+ SERIAL,
+ P0, P1, P2
};
i8x9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
diff --git a/src/emu/cpu/mcs96/mcs96ops.lst b/src/emu/cpu/mcs96/mcs96ops.lst
index 40084dfa161..bef886451f6 100644
--- a/src/emu/cpu/mcs96/mcs96ops.lst
+++ b/src/emu/cpu/mcs96/mcs96ops.lst
@@ -305,6 +305,17 @@ macro post_indexed $cycles1 $cycles2
next(OP1 ? 7+OP1 : 8);
0f norml direct_2
+ OP2 &= 0xfc;
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2) << 16;
+ for(OP3 = 0; OP3 < 31 && INT32(TMP) >= 0; OP3++);
+ PSW &= ~(F_Z|F_N|F_C);
+ if(!TMP)
+ PSW |= F_Z;
+ reg_w8(OP1, OP3);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ next(11+OP3);
11 clrb direct_1
reg_w8(OP1, 0x00);
@@ -1008,20 +1019,138 @@ fe7f mulb indexed_2
post_indexed 6 7 // +5 when external
8c divu direct_2
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ OP1 = reg_r16(OP1);
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ UINT32 TMP2 = TMP / OP1;
+ if(TMP2 > 65535)
+ PSW |= F_V|F_VT;
+ TMP = TMP % OP1;
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ next(25);
8d divu immed_2w
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ UINT32 TMP2 = TMP / OP1;
+ if(TMP2 > 65535)
+ PSW |= F_V|F_VT;
+ TMP = TMP % OP1;
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ next(26);
8e divu indirect_2
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ UINT32 d = any_r16(OP1);
+ if(d) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ UINT32 TMP2 = TMP / d;
+ if(TMP2 > 65535)
+ PSW |= F_V|F_VT;
+ TMP = TMP % d;
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ post_indirect 2 28 29 // +4 when external
8f divu indexed_2
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ UINT32 d = any_r16(OP1);
+ if(d) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ UINT32 TMP2 = TMP / d;
+ if(TMP2 > 65535)
+ PSW |= F_V|F_VT;
+ TMP = TMP % d;
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ post_indexed 28 29 // +4 when external
fe8c div direct_2
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ OP1 = reg_r16(OP1);
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ INT32 TMP2 = INT32(TMP) / INT16(OP1);
+ if(TMP2 > 32767 || TMP2 < -32768)
+ PSW |= F_V|F_VT;
+ TMP = TMP % INT16(OP1);
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ next(30);
fe8d div immed_2w
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ if(OP1) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ INT32 TMP2 = INT32(TMP) / INT16(OP1);
+ if(TMP2 > 32767 || TMP2 < -32768)
+ PSW |= F_V|F_VT;
+ TMP = TMP % INT16(OP1);
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ next(30);
fe8e div indirect_2
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ INT32 d = INT16(any_r16(OP1));
+ if(d) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ INT32 TMP2 = INT32(TMP) / d;
+ if(TMP2 > 32767 || TMP2 < -32768)
+ PSW |= F_V|F_VT;
+ TMP = TMP % d;
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ post_indirect 2 32 33 // +4 when external
fe8f div indexed_2
+ OP2 &= 0xfc;
+ PSW &= ~F_V;
+ INT32 d = INT16(any_r16(OP1));
+ if(d) {
+ TMP = reg_r16(OP2);
+ TMP |= reg_r16(OP2+2);
+ INT32 TMP2 = INT32(TMP) / d;
+ if(TMP2 > 32767 || TMP2 < -32768)
+ PSW |= F_V|F_VT;
+ TMP = TMP % d;
+ TMP = (TMP2 & 0xffff) | ((TMP & 0xffff) << 16);
+ reg_w16(OP2, TMP);
+ reg_w16(OP2+2, TMP >> 16);
+ }
+ post_indexed 32 33 // +4 when external
90 orb direct_2
TMP = reg_r8(OP1);
@@ -1179,8 +1308,32 @@ fe9d divb immed_2b
next(21);
fe9e divb indirect_2
+ PSW &= ~F_V;
+ INT32 d = INT8(any_r8(OP1));
+ if(d) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = INT16(TMP) / d;
+ if(INT16(TMP2) > 127 || INT16(TMP2) < -128)
+ PSW |= F_V|F_VT;
+ TMP = INT16(TMP) % d;
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ post_indirect 1 24 25 // +4 when external
fe9f divb indexed_2
+ PSW &= ~F_V;
+ INT32 d = INT8(any_r8(OP1));
+ if(d) {
+ TMP = reg_r16(OP2);
+ UINT32 TMP2 = INT16(TMP) / d;
+ if(INT16(TMP2) > 127 || INT16(TMP2) < -128)
+ PSW |= F_V|F_VT;
+ TMP = INT16(TMP) % d;
+ TMP = (TMP2 & 0xff) | ((TMP & 0xff) << 8);
+ reg_w16(OP2, TMP);
+ }
+ post_indexed 1 24 25 // +4 when external
a0 ld direct_2
reg_w16(OP2, reg_r16(OP1));