diff options
Diffstat (limited to 'src/devices/cpu/mb86233/mb86233d.cpp')
-rw-r--r-- | src/devices/cpu/mb86233/mb86233d.cpp | 168 |
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: |