summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mb86233/mb86233d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mb86233/mb86233d.cpp')
-rw-r--r--src/devices/cpu/mb86233/mb86233d.cpp168
1 files changed, 109 insertions, 59 deletions
diff --git a/src/devices/cpu/mb86233/mb86233d.cpp b/src/devices/cpu/mb86233/mb86233d.cpp
index 8433247dbc7..c49f01c3bba 100644
--- a/src/devices/cpu/mb86233/mb86233d.cpp
+++ b/src/devices/cpu/mb86233/mb86233d.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Ernesto Corvi
+// copyright-holders:Olivier Galibert
#include "emu.h"
#include "mb86233d.h"
@@ -15,47 +15,54 @@
2 <register file>
3 sio0 si1 pio pioa rpc - - - pad mod ear st mask tim cx dx
+ In the 86233/86234 the C, page, serial, parallel, timer registers
+ don't seem to exist. The register file is turned into i/o ports.
+ Of the second bank part '3', only "mask" is actually used.
- Address encoding:
+ Address encoding (adx uses x0/b0, ady uses x1/b1):
0 0aaa aaaa $a
0 1aaa aaaa $a(xn)
1 0aaa aaaa $a(xn+)
- 1 100b bbbb (xn+$b)
- 1 101b bbbb (bxn+$b)
- 1 110b bbbb [xn+$b]
- 1 111b bbbb [bxn+$b]
+ 1 100b bbbb (bxn+$b)
+ 1 101b bbbb (xn+$b)
+ 1 110b bbbb [bxn+$b]
+ 1 111b bbbb [xn+$b]
3322 2222 2222 1111 1111 1100 0000 0000
1098 7654 3210 9876 5432 1098 7654 3210
- 0000 00aa aaao ooyy yyyy yyyx xxxx xxxx lab
+ 0000 00aa aaa0 00yy yyyy yyyx xxxx xxxx lab adx, ady (e)
+ 0000 00aa aaa0 11yy yyyy yyyx xxxx xxxx lab adx, ady + 0x200
+ 0000 00aa aaa1 00yy yyyy yyyx xxxx xxxx lab adx + 0x200, ady
- 0000 00aa aaa0 11yy yyyy yyyx xxxx xxxx lab adx (e), ady
- 0000 00aa aaa1 00yy yyyy yyyx xxxx xxxx lab adx, ady (e)
-
- 0001 11aa aaa0 10yy yyyy yyyx xxxx xxxx mov adx, ady
- 0001 11aa aaa0 11yy yyyy yyyx xxxx xxxx mov adx (e), ady
- 0001 11aa aaa1 00yy yyyy yyyx xxxx xxxx mov adx, ady (e)
+ 0001 11aa aaa0 0?yy yyyy yyyx xxxx xxxx mov adx, ady (e) (the ? is not a + 0x200 select, cf. VR copro code)
+ 0001 11aa aaa0 10yy yyyy yyyx xxxx xxxx mov adx (e), ady
+ 0001 11aa aaa0 11yy yyyy yyyx xxxx xxxx mov adx, ady + 0x200
+ 0001 11aa aaa1 00yy yyyy yyyx xxxx xxxx mov adx + 0x200, ady
0001 11aa aaa1 01yy yyyy yyyx xxxx xxxx mov adx (o), ady
- 0001 11aa aaa1 1100 0rrr rrry yyyy yyyy mov r, ady (e)
- 0001 11aa aaa1 1100 1rrr rrry yyyy yyyy mov r, ady
- 0001 11aa aaa1 1101 1rrr rrrx xxxx xxxx mov adx (e), r
- 0001 11aa aaa1 1110 0rrr rrrx xxxx xxxx mov adx, r
+
+ 0001 11aa aaa1 1100 0rrr rrry yyyy yyyy mov r, ady
+ 0001 11aa aaa1 1100 1rrr rrry yyyy yyyy mov r, ady (e)
+ 0001 11aa aaa1 1101 0rrr rrry yyyy yyyy mov ady + 0x200, r
+ 0001 11aa aaa1 1101 1rrr rrry yyyy yyyy mov ady, r
+ 0001 11aa aaa1 1110 0rrr rrry yyyy yyyy mov ady (e), r
0001 11aa aaa1 1110 1rrr rrrx xxxx xxxx mov adx (o), r
0001 11aa aaa1 1111 0rrr rrr. ..ss ssss mov s, r
+ 0011 011. .... 101. vvvv vvvv vvvv vvvv stmh (bit0 = fp, bit 1-2 = rounding mode, rest unused)
+
0011 10rr vvvv vvvv vvvv vvvv vvvv vvvv lipl/lia/lib/lid #v
- 0011 11aa aaa. 000. rrrr rrrr rrrr rrrr clr0 <reglist>
- 0011 11aa aaa. 001. ffff ffff ffff ffff clr1 flags
- 0011 11aa aaa. 010. 0... .... nnnn nnnn rep #n
- 0011 11aa aaa. 010. 1... .... ..11 0100 rep rpc
- 0011 11aa aaa. 011. ffff ffff ffff ffff set flags
+ 0011 11.a aaaa 000. rrrr rrrr rrrr rrrr clr0 <reglist>
+ 0011 11.a aaaa 001. ffff ffff ffff ffff clr1 flags
+ 0011 11.a aaaa 010. 0... .... nnnn nnnn rep #n (0 = 0x100)
+ 0011 11.a aaaa 010. 1... .... ..11 0100 rep rpc
+ 0011 11.a aaaa 011. ffff ffff ffff ffff set flags
- 010r rrrr .... .... vvvv vvvv vvvv vvvv ldi #v, b0/.../- (bank 0/1) (h/l is special and targets exponent/mantissa size 8/24)
+ 01rr rrrr vvvv vvvv vvvv vvvv vvvv vvvv ldi #v, r (actual v size varies 3-24 depending on register)
1i11 11.c cccc 0000 aaaa aaaa aaaa aaaa brif cond #a
1i11 11.c cccc 0010 .0.. ...x xxxx xxxx brul cond (adx)
@@ -65,10 +72,17 @@
1i11 11.c cccc 0110 .1.. .... ...r rrrr bsul cond r
1i11 11.c cccc 1010 .... .... .... .... rtif cond
1i11 11.c cccc 1100 .rrr rrrx xxxx xxxx ldif cond adx, r
- 1011 11.c 0110 1110 .... .... .... .... iret
+ 1011 11.1 0110 1110 .... .... .... .... iret
Top 3 bits = instruction group, except when it isn't.
+
+ Conditions are 5 bits, but only a subset is known, see condition()
+
+ Alu can theorically be on C or D registers, but since C doesn't
+ exist, we don't know how C access is encoded. The operation
+ itself is 5-bits for the "full" alu range.
+
*/
@@ -109,24 +123,28 @@ std::string mb86233_disassembler::regs(u32 reg)
return regnames[reg & 0x3f];
}
-std::string mb86233_disassembler::memory(u32 reg, bool x1)
+std::string mb86233_disassembler::memory(u32 reg, bool x1, bool bank)
{
std::ostringstream stream;
switch(reg & 0x180) {
case 0x000:
- if((reg & 0x7f) < 10)
- util::stream_format(stream, "$%d", reg & 0x7f );
+ if(bank)
+ util::stream_format(stream, "$0x%x", 0x200 | (reg & 0x7f));
+ else if((reg & 0x7f) < 10)
+ util::stream_format(stream, "$%d", reg & 0x7f);
else
- util::stream_format(stream, "$0x%x", reg & 0x7f );
+ util::stream_format(stream, "$0x%x", reg & 0x7f);
break;
case 0x080:
- if(reg & 0x7f) {
- if((reg & 0x7f) < 10)
- util::stream_format(stream, "$%d", reg & 0x7f );
+ if(bank || (reg & 0x7f)) {
+ if(bank)
+ util::stream_format(stream, "$0x%x", 0x200 | (reg & 0x7f));
+ else if((reg & 0x7f) < 10)
+ util::stream_format(stream, "$%d", reg & 0x7f);
else
- util::stream_format(stream, "$0x%x", reg & 0x7f );
+ util::stream_format(stream, "$0x%x", reg & 0x7f);
}
stream << '(';
@@ -139,8 +157,14 @@ std::string mb86233_disassembler::memory(u32 reg, bool x1)
break;
case 0x100:
- if(reg & 0x7f)
- util::stream_format(stream, "$0x%x", reg & 0x7f );
+ if(bank || (reg & 0x7f)) {
+ if(bank)
+ util::stream_format(stream, "$0x%x", 0x200 | (reg & 0x7f));
+ else if((reg & 0x7f) < 10)
+ util::stream_format(stream, "$%d", reg & 0x7f);
+ else
+ util::stream_format(stream, "$0x%x", reg & 0x7f);
+ }
stream << '(';
@@ -152,7 +176,7 @@ std::string mb86233_disassembler::memory(u32 reg, bool x1)
break;
case 0x180:
- stream << (reg & 0x40 ? "$[" : "$(");
+ stream << (reg & 0x40 ? "[" : "(");
if(x1) {
if(!(reg & 0x20))
util::stream_format(stream, "bx1");
@@ -179,6 +203,10 @@ std::string mb86233_disassembler::memory(u32 reg, bool x1)
}
stream << (reg & 0x40 ? ']' : ')');
+
+ if(bank)
+ stream << "+0x200";
+
break;
}
@@ -204,13 +232,14 @@ std::string mb86233_disassembler::alu0_func(u32 alu)
case 0x0b: util::stream_format(stream, "fabd"); break;
case 0x0c: util::stream_format(stream, "fsmd"); break;
case 0x0d: util::stream_format(stream, "fspd"); break;
- case 0x0e: util::stream_format(stream, "cifd"); break;
- case 0x0f: util::stream_format(stream, "cfid"); break;
+ case 0x0e: util::stream_format(stream, "cxfd"); break;
+ case 0x0f: util::stream_format(stream, "cfxd"); break;
case 0x10: util::stream_format(stream, "fdvd"); break;
case 0x11: util::stream_format(stream, "fned"); break;
// 12
case 0x13: util::stream_format(stream, "d=b+a"); break;
case 0x14: util::stream_format(stream, "d=b-a"); break;
+ // 15
case 0x16: util::stream_format(stream, "lsrd"); break;
case 0x17: util::stream_format(stream, "lsld"); break;
case 0x18: util::stream_format(stream, "asrd"); break;
@@ -243,19 +272,19 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
switch(op) {
case 0:
- util::stream_format(stream, "lab %s, %s (io)", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "lab %s, %s (e)", memory(r1, false, false), memory(r2, true, false));
break;
case 3:
- util::stream_format(stream, "lab %s, %s", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "lab %s, %s", memory(r1, false, false), memory(r2, true, true));
break;
case 4:
- util::stream_format(stream, "lab %s, %s (e)", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "lab %s, %s", memory(r1, false, true), memory(r2, true, false));
break;
default:
- util::stream_format(stream, "lab {%d} %s, %s", op, memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "lab {%d} %s, %s", op, memory(r1, false, false), memory(r2, true, false));
break;
}
break;
@@ -278,53 +307,53 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
switch(op) {
case 0:
- util::stream_format(stream, "mov %s, %s", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov {0} %s, %s (e)", memory(r1, false, false), memory(r2, true, false));
break;
case 1:
- util::stream_format(stream, "mov %s, %s (io)", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov {1} %s, %s (e)", memory(r1, false, false), memory(r2, true, false));
break;
case 2:
- util::stream_format(stream, "mov %s (io), %s", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov %s (e), %s", memory(r1, false, false), memory(r2, true, false));
break;
case 3:
- util::stream_format(stream, "mov %s, %s (e)", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov %s, %s", memory(r1, false, false), memory(r2, true, true));
break;
case 4:
- util::stream_format(stream, "mov %s (e), %s", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov %s, %s", memory(r1, false, true), memory(r2, true, false));
break;
case 5:
- util::stream_format(stream, "mov %s (o), %s", memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov %s (o), %s", memory(r1, false, false), memory(r2, true, false));
break;
case 7: {
switch(r2 >> 6) {
case 0:
- util::stream_format(stream, "mov %s, %s", regs(r2 & 0x3f), memory(r1, true));
+ util::stream_format(stream, "mov %s, %s", regs(r2 & 0x3f), memory(r1, true, false));
break;
case 1:
- util::stream_format(stream, "mov %s, %s (io)", regs(r2 & 0x3f), memory(r1, true));
+ util::stream_format(stream, "mov %s, %s (e)", regs(r2 & 0x3f), memory(r1, true, false));
break;
case 2:
- util::stream_format(stream, "mov %s (e), %s", memory(r1, false), regs(r2 & 0x3f));
+ util::stream_format(stream, "mov %s, %s", memory(r1, true, true), regs(r2 & 0x3f));
break;
case 3:
- util::stream_format(stream, "mov %s, %s", memory(r1, false), regs(r2 & 0x3f));
+ util::stream_format(stream, "mov %s, %s", memory(r1, true, false), regs(r2 & 0x3f));
break;
case 4:
- util::stream_format(stream, "mov %s (io), %s", memory(r1, false), regs(r2 & 0x3f));
+ util::stream_format(stream, "mov %s (e), %s", memory(r1, true, false), regs(r2 & 0x3f));
break;
case 5:
- util::stream_format(stream, "mov %s (o), %s", memory(r1, false), regs(r2 & 0x3f));
+ util::stream_format(stream, "mov %s (o), %s", memory(r1, false, false), regs(r2 & 0x3f));
break;
case 6:
@@ -335,13 +364,33 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
break;
default:
- util::stream_format(stream, "mov {r2 %d} %s, %s", r2 >> 6, memory(r1, true), regs(r2 & 0x3f));
+ util::stream_format(stream, "mov {r2 %d} %s, %s", r2 >> 6, memory(r1, false, false), regs(r2 & 0x3f));
break;
}
break;
}
default:
- util::stream_format(stream, "mov {%d} %s, %s", op, memory(r1, false), memory(r2, true));
+ util::stream_format(stream, "mov {%d} %s, %s", op, memory(r1, false, false), memory(r2, true, false));
+ break;
+ }
+ break;
+ }
+
+ case 0x0d: { // stm/clm
+ u32 sub2 = (opcode >> 17) & 7;
+
+ switch(sub2) {
+ case 5: {
+ util::stream_format(stream, "stmh");
+ if(opcode & 0x0001)
+ util::stream_format(stream, " fp");
+ static const char *const round_mode[4] = { "rn", "rp", "rm", "rz" };
+ util::stream_format(stream, " %s", round_mode[(opcode >> 1) & 3]);
+ break;
+ }
+
+ default:
+ util::stream_format(stream, "unk %02x.%x", opcode >> 26, sub2);
break;
}
break;
@@ -354,7 +403,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
}
case 0x0f: { // rep/clr0/clr1/set
- u32 alu = (opcode >> 21) & 0x1f;
+ u32 alu = (opcode >> 20) & 0x1f;
u32 sub2 = (opcode >> 17) & 7;
if(alu)
@@ -405,6 +454,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
}
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
util::stream_format(stream, "ldi #0x%x, %s", opcode & 0xffffff, regnames[(opcode >> 24) & 0x3f]); break;
break;
@@ -424,7 +474,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
if(opcode & 0x4000)
util::stream_format(stream, "%s", regs(opcode & 0x1f));
else
- util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false));
+ util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false, false));
break;
case 2:
@@ -436,7 +486,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
if(opcode & 0x4000)
util::stream_format(stream, "%s", regs(opcode & 0x1f));
else
- util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false));
+ util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false, false));
break;
case 5:
@@ -444,7 +494,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
break;
case 6:
- util::stream_format(stream, "ldif %s %s, %s", condition(cond, invert), memory(data & 0x1ff, false), regs((data >> 9) & 0x3f));
+ util::stream_format(stream, "ldif %s %s, %s", condition(cond, invert), memory(data & 0x1ff, false, false), regs((data >> 9) & 0x3f));
break;
case 7: