summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mb86233
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mb86233')
-rw-r--r--src/devices/cpu/mb86233/mb86233.cpp2356
-rw-r--r--src/devices/cpu/mb86233/mb86233.h206
-rw-r--r--src/devices/cpu/mb86233/mb86233d.cpp168
-rw-r--r--src/devices/cpu/mb86233/mb86233d.h2
4 files changed, 1155 insertions, 1577 deletions
diff --git a/src/devices/cpu/mb86233/mb86233.cpp b/src/devices/cpu/mb86233/mb86233.cpp
index 68cf6a8fe6f..7244e0d5d04 100644
--- a/src/devices/cpu/mb86233/mb86233.cpp
+++ b/src/devices/cpu/mb86233/mb86233.cpp
@@ -1,1666 +1,1200 @@
// license:BSD-3-Clause
-// copyright-holders:Ernesto Corvi
-/***************************************************************************
-
- mb86233.c
- Core implementation for the portable Fujitsu MB86233 series DSP emulator.
-
- Written by ElSemi
- MAME version by Ernesto Corvi
-
- TODO:
- - Properly emulate the TGP Tables from the ROM (See GETEXTERNAL)
- - Many unknown opcodes and addressing modes
- - Interrupts?
-
-***************************************************************************/
+// copyright-holders:Olivier Galibert
#include "emu.h"
#include "debugger.h"
#include "mb86233.h"
#include "mb86233d.h"
+/*
+ Driver based on the initial reverse-engineering of Elsemi, extended,
+ generalized and made to look more like a cpu since then thanks in
+ part to a "manual" that barely deserves the name.
+
+ The 86232 has 512 32-bits dwords of triple-port memory (1 write, 2
+ read). The 86233/86234 have instead two normal (1 read, 1 write,
+ non-simultaneous) independant ram banks, one of 256 dwords and one
+ of 512.
+
+ The ram banks are mapped at 0x000-0x0ff and 0x200-0x3ff (proven by
+ geometrizer code that clears the ram at startup). Move and load
+ instructions kind of target a specific ram, but do it by adding
+ 0x200 to the address on one side of the other, which can then end up
+ anywhere. In particular model1 coprocessor has the output fifo at
+ 0x400, which is sometimes hit by having x1 at 0x200 and using the
+ automatic 0x200 adder. Theorically external accesses to 100-1ff and
+ 400+ seem to be routed externally, since they're used for the fifo
+ in model 1.
+
+ The cpu can theorically work in either floating point (32-bits ieee
+ flots) or fixed point (32/36/48 bits registers) modes. All sega
+ programs start by activating floating point and staying there, so
+ fixed point is not implemented.
+
+ An interrupt is used to update the rf0 (status? leds?) registers in
+ the coprocessor programs. It's on bit 1 of the mask (irq3?) and
+ vector 0x004. It's probably periodic, maybe on vblank. Note that
+ the copro programs never initialize the stack pointer. Interrupts
+ are not implemented at this point.
+
+ The 86233 and 86234 dies are slightly different in the die shots,
+ but there's no known programming-level difference at this point.
+ It's unclear whether some register-file linked functionality is
+ internal or external though (fifos, banking in model2/86234), so
+ there may lie the actual differences.
+*/
+
+
+DEFINE_DEVICE_TYPE(MB86233, mb86233_device, "mb86233", "Fujitsu MB86233 (TGP)")
+DEFINE_DEVICE_TYPE(MB86234, mb86234_device, "mb86234", "Fujitsu MB86234 (TGP)")
+
+
+mb86233_device::mb86233_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : cpu_device(mconfig, type, tag, owner, clock)
+ , m_program_config("program", ENDIANNESS_LITTLE, 32, 16, -2)
+ , m_data_config("data", ENDIANNESS_LITTLE, 32, 16, -2)
+ , m_io_config("io", ENDIANNESS_LITTLE, 32, 16, -2)
+ , m_rf_config("rf", ENDIANNESS_LITTLE, 32, 4, -2)
+{
+}
-DEFINE_DEVICE_TYPE(MB86233, mb86233_cpu_device, "mb86233", "Fujitsu MB86233 \"TGP\"")
-
+mb86233_device::mb86233_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mb86233_device(mconfig, MB86233, tag, owner, clock)
+{
+}
-mb86233_cpu_device::mb86233_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cpu_device(mconfig, MB86233, tag, owner, clock)
- , m_program_config("program", ENDIANNESS_LITTLE, 32, 32, -2)
- , m_data_config("data", ENDIANNESS_LITTLE, 32, 32, 0)
- , m_pc(0), m_reps(0), m_pcsp(0), m_eb(0), m_shift(0), m_repcnt(0), m_sr(0)
- , m_fpucontrol(0), m_program(nullptr), m_direct(nullptr), m_icount(0), m_fifo_wait(0)
- , m_fifo_read_cb(*this)
- , m_fifo_read_ok_cb(*this)
- , m_fifo_write_cb(*this)
- , m_tablergn(nullptr), m_ARAM(nullptr), m_BRAM(nullptr)
- , m_Tables(nullptr)
+mb86234_device::mb86234_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mb86233_device(mconfig, MB86234, tag, owner, clock)
{
}
-device_memory_interface::space_config_vector mb86233_cpu_device::memory_space_config() const
+device_memory_interface::space_config_vector mb86233_device::memory_space_config() const
{
return space_config_vector {
- std::make_pair(AS_PROGRAM, &m_program_config),
- std::make_pair(AS_DATA, &m_data_config)
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_DATA, &m_data_config),
+ std::make_pair(AS_IO, &m_io_config),
+ std::make_pair(AS_RF, &m_rf_config)
};
}
-std::unique_ptr<util::disasm_interface> mb86233_cpu_device::create_disassembler()
+std::unique_ptr<util::disasm_interface> mb86233_device::create_disassembler()
{
return std::make_unique<mb86233_disassembler>();
}
-/***************************************************************************
- MACROS
-***************************************************************************/
-
-#define ZERO_FLAG (1 << 0)
-#define SIGN_FLAG (1 << 1)
-#define EXTERNAL_FLAG (1 << 2) //This seems to be a flag coming from some external circuit??
-
-#define GETPC() m_pc
-#define GETA() m_a
-#define GETB() m_b
-#define GETD() m_d
-#define GETP() m_p
-#define GETSR() m_sr
-#define GETGPR(a) m_gpr[a]
-#define GETSHIFT() m_shift
-#define GETPCS() m_pcs
-#define GETPCSP() m_pcsp
-#define GETEB() m_eb
-#define GETREPS() m_reps
-#define GETEXTPORT() m_extport
-#define GETFIFOWAIT() m_fifo_wait
-#define GETARAM() m_ARAM
-#define GETBRAM() m_BRAM
-#define GETREPCNT() m_repcnt
-
-#define ROPCODE(a) m_direct->read_dword(a)
-#define RDMEM(a) m_program->read_dword(a)
-#define WRMEM(a,v) m_program->write_dword((a), v)
-
-/***************************************************************************
- Initialization and Shutdown
-***************************************************************************/
-
-void mb86233_cpu_device::device_start()
-{
- m_pc = 0;
- m_a.u = 0;
- m_b.u = 0;
- m_d.u = 0;
- m_p.u = 0;
- m_reps = 0;
- m_pcs[0] = m_pcs[1] = m_pcs[2] = m_pcs[3] = 0;
- m_pcsp = 0;
- m_eb = 0;
- m_shift = 0;
- m_repcnt = 0;
- m_sr = 0;
- memset(m_gpr, 0, sizeof(m_gpr));
- memset(m_extport, 0, sizeof(m_extport));
- m_fifo_wait = 0;
-
- m_fifo_read_cb.resolve_safe(0);
- m_fifo_read_ok_cb.resolve_safe(0);
- m_fifo_write_cb.resolve_safe();
+void mb86233_device::device_start()
+{
m_program = &space(AS_PROGRAM);
- m_direct = m_program->direct<-2>();
-
- if ( m_tablergn )
- {
- m_Tables = (uint32_t*) machine().root_device().memregion(m_tablergn)->base();
- }
-
- memset( m_RAM, 0, 2 * 0x200 * sizeof(uint32_t) );
- m_ARAM = &m_RAM[0];
- m_BRAM = &m_RAM[0x200];
-
+ m_direct = m_program->direct<-2>();
+
+ m_data = &space(AS_DATA);
+ m_io = &space(AS_IO);
+ m_rf = &space(AS_RF);
+
+ state_add(STATE_GENPC, "GENPC", m_pc);
+ state_add(STATE_GENPCBASE, "PC", m_ppc).noshow();
+ state_add(STATE_GENSP, "SP", m_sp);
+ state_add(STATE_GENFLAGS, "ST", m_st);
+
+ state_add(REG_A, "A", m_a);
+ state_add(REG_B, "B", m_b);
+ state_add(REG_D, "D", m_d);
+ state_add(REG_P, "P", m_p);
+ state_add(REG_R, "R", m_r);
+ state_add(REG_R, "RPC", m_rpc);
+ state_add(REG_C0, "C0", m_c0);
+ state_add(REG_C1, "C1", m_c1);
+ state_add(REG_B0, "B0", m_b0);
+ state_add(REG_B1, "B1", m_b1);
+ state_add(REG_X0, "X0", m_x0);
+ state_add(REG_X1, "X1", m_x1);
+ state_add(REG_I0, "I0", m_i0);
+ state_add(REG_I1, "I1", m_i1);
+ state_add(REG_SFT, "SFT", m_sft);
+ state_add(REG_VSM, "VSM", m_vsm);
+ state_add(REG_PCS0, "PCS0", m_pcs[0]);
+ state_add(REG_PCS1, "PCS1", m_pcs[1]);
+ state_add(REG_PCS2, "PCS2", m_pcs[2]);
+ state_add(REG_PCS3, "PCS3", m_pcs[3]);
+ state_add(REG_MASK, "MASK", m_mask);
+ state_add(REG_M, "M", m_m);
+
+ save_item(NAME(m_ppc));
save_item(NAME(m_pc));
- save_item(NAME(m_a.u));
- save_item(NAME(m_b.u));
- save_item(NAME(m_d.u));
- save_item(NAME(m_p.u));
- save_item(NAME(m_reps));
+ save_item(NAME(m_st));
+ save_item(NAME(m_sp));
+ save_item(NAME(m_a));
+ save_item(NAME(m_b));
+ save_item(NAME(m_d));
+ save_item(NAME(m_p));
+ save_item(NAME(m_r));
+ save_item(NAME(m_rpc));
+ save_item(NAME(m_c0));
+ save_item(NAME(m_c1));
+ save_item(NAME(m_b0));
+ save_item(NAME(m_b1));
+ save_item(NAME(m_x0));
+ save_item(NAME(m_x1));
+ save_item(NAME(m_i0));
+ save_item(NAME(m_i1));
+ save_item(NAME(m_sft));
+ save_item(NAME(m_vsm));
+ save_item(NAME(m_vsmr));
save_item(NAME(m_pcs));
- save_item(NAME(m_pcsp));
- save_item(NAME(m_eb));
- save_item(NAME(m_shift));
- save_item(NAME(m_repcnt));
- save_item(NAME(m_sr));
- save_item(NAME(m_gpr));
- save_item(NAME(m_extport));
- save_item(NAME(m_RAM));
-
- state_add( MB86233_PC, "PC", m_pc).formatstr("%04X");
- state_add( MB86233_A, "PA", m_a.u).formatstr("%08X");
- state_add( MB86233_B, "PB", m_b.u).formatstr("%08X");
- state_add( MB86233_P, "PP", m_p.u).formatstr("%08X");
- state_add( MB86233_D, "PD", m_d.u).formatstr("%08X");
- state_add( MB86233_REP, "REPS", m_reps).formatstr("%08X");
- state_add( MB86233_SP, "PCSP", m_pcsp).mask(0xf).formatstr("%01X");
- state_add( MB86233_EB, "EB", m_eb).formatstr("%08X");
- state_add( MB86233_SHIFT, "SHIFT", m_shift).formatstr("%08X");
- state_add( MB86233_R0, "R0", m_gpr[0]).formatstr("%08X");
- state_add( MB86233_R1, "R1", m_gpr[1]).formatstr("%08X");
- state_add( MB86233_R2, "R2", m_gpr[2]).formatstr("%08X");
- state_add( MB86233_R3, "R3", m_gpr[3]).formatstr("%08X");
- state_add( MB86233_R4, "R4", m_gpr[4]).formatstr("%08X");
- state_add( MB86233_R5, "R5", m_gpr[5]).formatstr("%08X");
- state_add( MB86233_R6, "R6", m_gpr[6]).formatstr("%08X");
- state_add( MB86233_R7, "R7", m_gpr[7]).formatstr("%08X");
- state_add( MB86233_R8, "R8", m_gpr[8]).formatstr("%08X");
- state_add( MB86233_R9, "R9", m_gpr[9]).formatstr("%08X");
- state_add( MB86233_R10, "R10", m_gpr[10]).formatstr("%08X");
- state_add( MB86233_R11, "R11", m_gpr[11]).formatstr("%08X");
- state_add( MB86233_R12, "R12", m_gpr[12]).formatstr("%08X");
- state_add( MB86233_R13, "R13", m_gpr[13]).formatstr("%08X");
- state_add( MB86233_R14, "R14", m_gpr[14]).formatstr("%08X");
- state_add( MB86233_R15, "R15", m_gpr[15]).formatstr("%08X");
-
- state_add( STATE_GENPC, "GENPC", m_pc).noshow();
- state_add( STATE_GENPCBASE, "CURPC", m_pc).noshow();
- state_add( STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%2s").noshow();
+ save_item(NAME(m_mask));
+ save_item(NAME(m_m));
+ save_item(NAME(m_gpio0));
+ save_item(NAME(m_gpio1));
+ save_item(NAME(m_gpio2));
+ save_item(NAME(m_gpio3));
+
+ save_item(NAME(m_alu_stmask));
+ save_item(NAME(m_alu_stset));
+ save_item(NAME(m_alu_r1));
+ save_item(NAME(m_alu_r2));
+
+ m_gpio0 = m_gpio1 = m_gpio2 = m_gpio3 = false;
set_icountptr(m_icount);
}
-void mb86233_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
+void mb86233_device::state_string_export(const device_state_entry &entry, std::string &str) const
{
- switch (entry.index())
- {
- case STATE_GENFLAGS:
- str = string_format("%c%c", (m_sr & SIGN_FLAG) ? 'N' : 'n', (m_sr & ZERO_FLAG) ? 'Z' : 'z');
- break;
- }
}
-
-void mb86233_cpu_device::device_reset()
+WRITE_LINE_MEMBER(mb86233_device::gpio0_w)
{
- /* zero registers and flags */
- m_pc = 0;
- m_sr = 0;
- m_pcsp = 0;
- m_eb = 0;
- m_shift = 0;
- m_fifo_wait = 0;
+ m_gpio0 = state;
}
+WRITE_LINE_MEMBER(mb86233_device::gpio1_w)
+{
+ m_gpio1 = state;
+}
+WRITE_LINE_MEMBER(mb86233_device::gpio2_w)
+{
+ m_gpio2 = state;
+}
-/***************************************************************************
- Status Register
-***************************************************************************/
-
-#define ZERO_FLAG (1 << 0)
-#define SIGN_FLAG (1 << 1)
-#define EXTERNAL_FLAG (1 << 2) //This seems to be a flag coming from some external circuit??
-
-void mb86233_cpu_device::FLAGSF( float v )
+WRITE_LINE_MEMBER(mb86233_device::gpio3_w)
{
- GETSR() &= ~(ZERO_FLAG|SIGN_FLAG);
+ m_gpio3 = state;
+}
- if ( v == 0 )
- GETSR() |= ZERO_FLAG;
+void mb86233_device::device_reset()
+{
+ m_pc = 0;
+ m_ppc = 0;
+ m_st = F_ZRC|F_ZRD|F_ZX0|F_ZX1|F_ZX2|F_ZC0|F_ZC1;
+ m_sp = 0;
+
+ m_a = 0;
+ m_b = 0;
+ m_d = 0;
+ m_p = 0;
+ m_r = 1;
+ m_rpc = 1;
+ m_c0 = 1;
+ m_c1 = 1;
+ m_b0 = 0;
+ m_b1 = 0;
+ m_x0 = 0;
+ m_x1 = 0;
+ m_i0 = 0;
+ m_i1 = 0;
+ m_sft = 0;
+ m_vsm = 0;
+ m_vsmr = 7;
+ m_mask = 0;
+ m_m = 1;
+
+ m_alu_stmask = 0;
+ m_alu_stset = 0;
+ m_alu_r1 = 0;
+ m_alu_r2 = 0;
+
+ std::fill(std::begin(m_pcs), std::end(m_pcs), 0);
+
+ m_stall = false;
+}
- if ( v < 0 )
- GETSR() |= SIGN_FLAG;
+s32 mb86233_device::s24_32(u32 val)
+{
+ if(val & 0x00800000)
+ return val | 0xff000000;
+ else
+ return val & 0x00ffffff;
}
-void mb86233_cpu_device::FLAGSI( uint32_t v )
+u32 mb86233_device::set_exp(u32 val, u32 exp)
{
- GETSR() &= ~(ZERO_FLAG|SIGN_FLAG);
+ return (val & 0x807fffff) | ((exp & 0xff) << 23);
+}
- if ( v == 0 )
- GETSR() |= ZERO_FLAG;
+u32 mb86233_device::set_mant(u32 val, u32 mant)
+{
+ return (val & 0x07f800000) | ((mant & 0x00800000) << 8) | (mant & 0x007fffff);
+}
- if ( v & 0x80000000 )
- GETSR() |= SIGN_FLAG;
+u32 mb86233_device::get_exp(u32 val)
+{
+ return (val >> 23) & 0xff;
}
+u32 mb86233_device::get_mant(u32 val)
+{
+ return val & 0x80000000 ? val | 0x7f800000 : val & 0x807fffff;
+}
+void mb86233_device::pcs_push()
+{
+ for(unsigned int i=3; i; i--)
+ m_pcs[i] = m_pcs[i-1];
+ m_pcs[0] = m_pc;
+}
-/***************************************************************************
- Condition Codes
-***************************************************************************/
+void mb86233_device::pcs_pop()
+{
+ m_pc = m_pcs[0];
+ for(unsigned int i=0; i != 3; i++)
+ m_pcs[i] = m_pcs[i+1];
+}
-int mb86233_cpu_device::COND( uint32_t cond )
+void mb86233_device::testdz()
{
- switch( cond )
- {
- case 0x00: /* eq */
- if ( (GETSR() & ZERO_FLAG) ) return 1;
- break;
+ if(m_d)
+ m_st &= ~F_ZRD;
+ else
+ m_st |= F_ZRD;
+ if(m_d & 0x80000000)
+ m_st |= F_SGD;
+ else
+ m_st &= ~F_SGD;
+}
- case 0x01: /* ge */
- if ( (GETSR() & ZERO_FLAG) || ((GETSR() & SIGN_FLAG)==0) ) return 1;
+void mb86233_device::alu_pre(u32 alu)
+{
+ switch(alu) {
+ case 0x00: break; // no alu
+
+ case 0x01: {
+ // andd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d & m_a;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x02: /* le */
- if ( (GETSR() & ZERO_FLAG) || (GETSR() & SIGN_FLAG) ) return 1;
+ case 0x02: {
+ // orad
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d | m_a;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x06: /* never */
+ case 0x03: {
+ // eord
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d ^ m_a;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0a:
- if(GETSR() & EXTERNAL_FLAG) return 1;
+ case 0x05: {
+ // fcpd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ u32 r = f2u(u2f(m_d) - u2f(m_a));
+ m_alu_stset = r ? r & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x10: /* --r12 != 0 */
- GETGPR(12)--;
- if ( GETGPR(12) != 0 ) return 1;
+ case 0x06: {
+ // fmad
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_d) + u2f(m_a));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x11: /* --r13 != 0 */
- GETGPR(13)--;
- if ( GETGPR(13) != 0 ) return 1;
+ case 0x07: {
+ // fsbd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_d) - u2f(m_a));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x16: /* always */
- return 1;
-
- default:
- logerror( "TGP: Unknown condition code (cc=%d) at PC:%x\n", cond, GETPC());
+ case 0x08: {
+ // fml
+ m_alu_stmask = 0;
+ m_alu_r1 = f2u(u2f(m_a) * u2f(m_b));
+ m_alu_stset = 0;
break;
}
- return 0;
-}
-
-
-
-/***************************************************************************
- ALU
-***************************************************************************/
-
-void mb86233_cpu_device::ALU( uint32_t alu)
-{
- float ftmp;
-
- switch(alu)
- {
- case 0x00: /* NOP */
+ case 0x09: {
+ // fmsd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_d) + u2f(m_p));
+ m_alu_r2 = f2u(u2f(m_a) * u2f(m_b));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x01: /* D = D & A */
- GETD().u &= GETA().u;
- FLAGSI( GETD().u);
+ case 0x0a: {
+ // fmrd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_d) - u2f(m_p));
+ m_alu_r2 = f2u(u2f(m_a) * u2f(m_b));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x02: /* D = D | A */
- GETD().u |= GETA().u;
- FLAGSI( GETD().u);
+ case 0x0b: {
+ // fabd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d & 0x7fffffff;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x03: /* D = D ^ A */
- GETD().u ^= GETA().u;
- FLAGSI( GETD().u);
+ case 0x0c: {
+ // fsmd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_d) + u2f(m_p));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x04: /* D = D ~ A */
- GETD().u = ~GETA().u;
- FLAGSI( GETD().u);
+ case 0x0d: {
+ // fspd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_p;
+ m_alu_r2 = f2u(u2f(m_a) * u2f(m_b));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x05: /* CMP D,A */
- ftmp = GETD().f - GETA().f;
- FLAGSF( ftmp);
- m_icount--;
+ case 0x0e: {
+ // cxfd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(s32(m_d));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x06: /* D = D + A */
- GETD().f += GETA().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x0f: {
+ // cfxd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ switch((m_m >> 1) & 3) {
+ case 0: m_alu_r1 = s32(roundf(u2f(m_d))); break;
+ case 1: m_alu_r1 = s32(ceilf(u2f(m_d))); break;
+ case 2: m_alu_r1 = s32(floorf(u2f(m_d))); break;
+ case 3: m_alu_r1 = s32(u2f(m_d)); break;
+ }
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x07: /* D = D - A */
- GETD().f -= GETA().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x10: {
+ // fdvd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_d) / u2f(m_a));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x08: /* P = A * B */
- GETP().f = GETA().f * GETB().f;
- m_icount--;
+ case 0x11: {
+ // fned
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d ? m_d ^ 0x80000000 : 0;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x09: /* D = D + P; P = A * B */
- GETD().f += GETP().f;
- GETP().f = GETA().f * GETB().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x13: {
+ // d = b + a
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_b) + u2f(m_a));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0A: /* D = D - P; P = A * B */
- GETD().f -= GETP().f;
- GETP().f = GETA().f * GETB().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x14: {
+ // d = b - a
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = f2u(u2f(m_b) - u2f(m_a));
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0B: /* D = fabs(D) */
- GETD().f = fabs( GETD().f );
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x16: {
+ // lsrd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d >> m_sft;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0C: /* D = D + P */
- GETD().f += GETP().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x17: {
+ // lsld
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d << m_sft;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0D: /* D = P; P = A * B */
- GETD().f = GETP().f;
- GETP().f = GETA().f * GETB().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x18: {
+ // asrd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = s32(m_d) >> m_sft;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0E: /* D = float(D) */
- GETD().f = (float)GETD().i;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x19: {
+ // asld
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = s32(m_d) << m_sft;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x0F: /* D = int(D) */
- switch((m_fpucontrol>>1)&3)
- {
- //case 0: GETD().i = floorf(GETD().f+0.5f); break;
- //case 1: GETD().i = ceilf(GETD().f); break;
- case 2: GETD().i = floorf(GETD().f); break; // Manx TT
- case 3: GETD().i = (int32_t)GETD().f; break;
- default: popmessage("TGP uses D = int(D) with FPU control = %02x, contact MAMEdev",m_fpucontrol>>1); break;
- }
-
- FLAGSI( GETD().i);
+ case 0x1a: {
+ // addd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d + m_a;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x10: /* D = D / A */
- if ( GETA().u != 0 )
- GETD().f = GETD().f / GETA().f;
- FLAGSF( GETD().f);
- m_icount--;
+ case 0x1b: {
+ // subd
+ m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
+ m_alu_r1 = m_d - m_a;
+ m_alu_stset = m_alu_r1 ? m_alu_r1 & 0x80000000 ? F_SGD : 0 : F_ZRD;
break;
+ }
- case 0x11: /* D = -D */
- GETD().f = -GETD().f;
- FLAGSF( GETD().f);
- m_icount--;
+ default:
+ logerror("unhandled alu pre %02x\n", alu);
break;
+ }
+}
- case 0x13: /* D = A + B */
- GETD().f = GETA().f + GETB().f;
- FLAGSF( GETD().f);
- m_icount--;
- break;
+void mb86233_device::alu_update_st()
+{
+ m_st = (m_st & ~m_alu_stmask) | m_alu_stset;
+}
- case 0x14: /* D = B - A */
- GETD().f = GETB().f - GETA().f;
- FLAGSF( GETD().f);
- m_icount--;
- break;
+void mb86233_device::alu_post(u32 alu)
+{
+ switch(alu) {
+ case 0x00: break; // no alu
- case 0x16: /* LSR D, SHIFT */
- GETD().u >>= GETSHIFT();
- FLAGSI( GETD().u);
+ case 0x05:
+ // flags only
+ alu_update_st();
break;
- case 0x17: /* LSL D, SHIFT */
- GETD().u <<= GETSHIFT();
- FLAGSI( GETD().u);
+ case 0x01: case 0x02: case 0x03: case 0x06:
+ case 0x07: case 0x0b: case 0x0c: case 0x0e:
+ case 0x0f: case 0x10: case 0x11: case 0x13:
+ case 0x14: case 0x16: case 0x17: case 0x18:
+ case 0x19: case 0x1a: case 0x1b:
+ // d update
+ m_d = m_alu_r1;
+ alu_update_st();
break;
- case 0x18: /* ASR D, SHIFT */
-// GETD().u = (GETD().u & 0x80000000) | (GETD().u >> GETSHIFT());
- GETD().i >>= GETSHIFT();
- FLAGSI( GETD().u);
+ case 0x08:
+ // p update
+ m_p = m_alu_r1;
break;
- case 0x1A: /* D = D + A */
- GETD().i += GETA().i;
- FLAGSI( GETD().u);
+ case 0x09: case 0x0a: case 0xd:
+ // d, p update
+ m_d = m_alu_r1;
+ m_p = m_alu_r2;
+ alu_update_st();
break;
- case 0x1B: /* D = D - A */
- GETD().i -= GETA().i;
- FLAGSI( GETD().u);
+ default:
+ logerror("unhandled alu post %02x\n", alu);
break;
-
- default:
- fatalerror( "TGP: Unknown ALU op %x at PC:%04x\n", alu, GETPC() );
}
}
-
-
-/***************************************************************************
- Memory Access
-***************************************************************************/
-
-uint32_t mb86233_cpu_device::ScaleExp(unsigned int v,int scale)
-{
- int exp=(v>>23)&0xff;
- exp+=scale;
- v&=~0x7f800000;
- return v|(exp<<23);
-}
-
-
-uint32_t mb86233_cpu_device::GETEXTERNAL( uint32_t EB, uint32_t offset )
+u16 mb86233_device::ea_pre_0(u32 r)
{
- uint32_t addr;
-
- if ( EB == 0 && offset >= 0x20 && offset <= 0x2f ) /* TGP Tables in ROM - FIXME - */
- {
- if(offset>=0x20 && offset<=0x23) //SIN from value at RAM(0x20) in 0x4000/PI steps
- {
- uint32_t r;
- uint32_t value=GETEXTPORT()[0x20];
- uint32_t off;
- value+=(offset-0x20)<<14;
- off=value&0x3fff;
- if((value&0x7fff)==0)
- r=0;
- else if((value&0x7fff)==0x4000)
- r=0x3f800000;
- else
- {
- if(value&0x4000)
- off=0x4000-off;
- r=m_Tables[off];
- }
- if(value&0x8000)
- r|=1<<31;
- return r;
+ switch(r & 0x180) {
+ case 0x000: return r & 0x7f;
+ case 0x080: case 0x100: return (r & 0x7f) + m_b0 + m_x0;
+ case 0x180: {
+ switch(r & 0x60) {
+ case 0x00: return m_b0 + m_x0;
+ case 0x20: return m_x0;
+ case 0x40: return m_b0 + (m_x0 & m_vsmr);
+ case 0x60: return m_x0 & m_vsmr;
}
-
- if(offset==0x27)
- {
- unsigned int value=GETEXTPORT()[0x27];
- int exp=(value>>23)&0xff;
- unsigned int res;
- unsigned int sign=0;
- MB86233_REG a,b;
- int index;
-
- a.u=GETEXTPORT()[0x24];
- b.u=GETEXTPORT()[0x25];
-
-
- if(!exp)
- {
- if((a.u&0x7fffffff)<=(b.u&0x7fffffff))
- {
- if(b.u&0x80000000)
- res=0xc000;
- else
- res=0x4000;
- }
- else
- {
- if(a.u&0x80000000)
- res=0x8000;
- else
- res=0x0000;
- }
- return res;
- }
-
- if((a.u^b.u)&0x80000000)
- sign=16; //the negative values are in the high word
-
- if((exp&0x70)!=0x70)
- index=0;
- else if(exp<0x70 || exp>0x7e)
- index=0x3fff;
- else
- {
- int expdif=exp-0x71;
- int base;
- int mask;
- int shift;
-
-
- if(expdif<0)
- expdif=0;
- base=1<<expdif;
- mask=base-1;
- shift=23-expdif;
-
- index=base+((value>>shift)&mask);
-
- }
-
- res=(m_Tables[index+0x10000/4]>>sign)&0xffff;
-
- if((a.u&0x7fffffff)<=(b.u&0x7fffffff))
- res=0x4000-res;
-
-
- if((a.u&0x80000000) && (b.u&0x80000000)) //3rd quadrant
- {
- res=0x8000|res;
- }
- else if((a.u&0x80000000) && !(b.u&0x80000000)) //2nd quadrant
- {
- res=res&0x7fff;
- }
- else if(!(a.u&0x80000000) && (b.u&0x80000000)) //2nd quadrant
- {
- res=0x8000|res;
- }
-
- return res;
-
- }
-
- if(offset==0x28)
- {
- uint32_t offset=(GETEXTPORT()[0x28]>>10)&0x1fff;
- uint32_t value=m_Tables[offset*2+0x20000/4];
- uint32_t srcexp=(GETEXTPORT()[0x28]>>23)&0xff;
-
- value&=0x7FFFFFFF;
-
- return ScaleExp(value,0x7f-srcexp);
- }
- if(offset==0x29)
- {
- uint32_t offset=(GETEXTPORT()[0x28]>>10)&0x1fff;
- uint32_t value=m_Tables[offset*2+(0x20000/4)+1];
- uint32_t srcexp=(GETEXTPORT()[0x28]>>23)&0xff;
-
- value&=0x7FFFFFFF;
- if(GETEXTPORT()[0x28]&(1<<31))
- value|=1<<31;
-
- return ScaleExp(value,0x7f-srcexp);
- }
- if(offset==0x2a)
- {
- uint32_t offset=((GETEXTPORT()[0x2a]>>11)&0x1fff)^0x1000;
- uint32_t value=m_Tables[offset*2+0x30000/4];
- uint32_t srcexp=(GETEXTPORT()[0x2a]>>24)&0x7f;
-
- value&=0x7FFFFFFF;
-
- return ScaleExp(value,0x3f-srcexp);
- }
- if(offset==0x2b)
- {
- uint32_t offset=((GETEXTPORT()[0x2a]>>11)&0x1fff)^0x1000;
- uint32_t value=m_Tables[offset*2+(0x30000/4)+1];
- uint32_t srcexp=(GETEXTPORT()[0x2a]>>24)&0x7f;
-
- value&=0x7FFFFFFF;
- if(GETEXTPORT()[0x2a]&(1<<31))
- value|=1<<31;
-
- return ScaleExp(value,0x3f-srcexp);
- }
-
- return GETEXTPORT()[offset];
}
-
- addr = ( EB & 0xFFFF0000 ) | ( offset & 0xFFFF );
-
- return RDMEM(addr);
+ }
+ return 0;
}
-void mb86233_cpu_device::SETEXTERNAL( uint32_t EB, uint32_t offset, uint32_t value )
+void mb86233_device::ea_post_0(u32 r)
{
- uint32_t addr;
-
- if ( EB == 0 && offset >= 0x20 && offset <= 0x2f ) /* TGP Tables in ROM - FIXME - */
- {
- GETEXTPORT()[offset] = value;
-
- if(offset==0x25 || offset==0x24)
- {
- if((GETEXTPORT()[0x24]&0x7fffffff)<=(GETEXTPORT()[0x25]&0x7fffffff))
- {
- GETSR()|=EXTERNAL_FLAG;
- }
- else
- {
- GETSR()&=~EXTERNAL_FLAG;
- }
- }
+ if(!(r & 0x100))
return;
+ if(!(r & 0x080))
+ m_x0 += m_i0;
+ else {
+ if(r & 0x10)
+ m_x0 += (r & 0xf) - 0x10;
+ else
+ m_x0 += r & 0xf;
}
-
- addr = ( EB & 0xFFFF0000 ) | ( offset & 0xFFFF );
-
- WRMEM( addr, value );
}
-
-
-/***************************************************************************
- Register Access
-***************************************************************************/
-
-uint32_t mb86233_cpu_device::GETREGS( uint32_t reg, int source )
+u16 mb86233_device::ea_pre_1(u32 r)
{
- uint32_t mode = ( reg >> 6 ) & 0x07;
-
- reg &= 0x3f;
-
- if ( mode == 0 || mode == 1 || mode == 3 )
- {
- if ( reg < 0x10 )
- {
- return GETGPR(reg);
- }
-
- switch( reg )
- {
- case 0x10: /* A */
- return GETA().u;
-
- case 0x11: /* A.e */
- return (GETA().u >> 23) & 0xff;
-
- case 0x12: /* A.m */
- return (GETA().u & 0x7fffff) | ((GETA().u&0x80000000) >> 8);
-
- case 0x13: /* B */
- return GETB().u;
-
- case 0x14: /* B.e */
- return (GETB().u >> 23) & 0xff;
-
- case 0x15: /* B.m */
- return (GETB().u & 0x7fffff) | ((GETB().u&0x80000000) >> 8);
-
- case 0x19: /* D */
- return GETD().u;
-
- case 0x1A: /* D.e */
- return (GETD().u >> 23) & 0xff;
-
- case 0x1B: /* D.m */
- return (GETD().u & 0x7fffff) | ((GETD().u&0x80000000) >> 8);
-
- case 0x1C: /* P */
- return GETP().u;
-
- case 0x1D: /* P.e */
- return (GETP().u >> 23) & 0xff;
-
- case 0x1E: /* P.m */
- return (GETP().u & 0x7fffff) | ((GETP().u&0x80000000) >> 8);
-
- case 0x1F: /* Shift */
- return GETSHIFT();
-
- case 0x20: /* Parallel Port */
- logerror( "TGP: Parallel port read at PC:%04x\n", GETPC() );
- return 0;
-
- case 0x21: /* FIn */
- {
- if ( m_fifo_read_ok_cb() == ASSERT_LINE )
- {
- return m_fifo_read_cb();
- }
-
- GETFIFOWAIT() = 1;
- return 0;
- }
-
- case 0x22: /* FOut */
- return 0;
-
- case 0x23: /* EB */
- return GETEB();
-
- case 0x34:
- return GETREPCNT();
-
- default:
- fatalerror( "TGP: Unknown GETREG (%d) at PC=%04x\n", reg, GETPC() );
+ switch(r & 0x180) {
+ case 0x000: return r & 0x7f;
+ case 0x080: case 0x100: return (r & 0x7f) + m_b1 + m_x1;
+ case 0x180: {
+ switch(r & 0x60) {
+ case 0x00: return m_b1 + m_x1;
+ case 0x20: return m_x1;
+ case 0x40: return m_b1 + (m_x1 & m_vsmr);
+ case 0x60: return m_x1 & m_vsmr;
}
}
- else if ( mode == 2 ) /* Indexed */
- {
- uint32_t addr = reg & 0x1f;
-
- if ( source )
- {
- if( !( reg & 0x20 ) )
- addr += GETGPR(0);
-
- addr += GETGPR(2);
- }
- else
- {
- if( !( reg & 0x20 ) )
- addr += GETGPR(1);
-
- addr += GETGPR(3);
- }
-
- return addr;
}
- else if( mode == 6 ) /* Indexed with postop */
- {
- uint32_t addr = 0;
-
- if ( source )
- {
- if( !( reg & 0x20 ) )
- addr += GETGPR(0);
-
- addr += GETGPR(2);
- }
- else
- {
- if( !( reg & 0x20 ) )
- addr += GETGPR(1);
-
- addr += GETGPR(3);
- }
+ return 0;
+}
- if ( reg & 0x10 )
- {
- if ( source )
- GETGPR(2) -= 0x20 - ( reg & 0x1f );
- else
- GETGPR(3) -= 0x20 - ( reg & 0x1f );
- }
+void mb86233_device::ea_post_1(u32 r)
+{
+ if(!(r & 0x100))
+ return;
+ if(!(r & 0x080))
+ m_x1 += m_i1;
+ else {
+ if(r & 0x10)
+ m_x1 += (r & 0xf) - 0x10;
else
- {
- if ( source )
- GETGPR(2) += ( reg & 0x1f );
- else
- GETGPR(3) += ( reg & 0x1f );
- }
-
- return addr;
- }
- else
- {
- fatalerror( "TGP: Unknown GETREG mode %d at PC:%04x\n", mode, GETPC() );
+ m_x1 += r & 0xf;
}
-
- // never executed
- //return 0;
}
-void mb86233_cpu_device::SETREGS( uint32_t reg, uint32_t val )
+u32 mb86233_device::read_reg(u32 r)
{
- int mode = ( reg >> 6) & 0x07;
-
- reg &= 0x3f;
-
- if( mode == 0 || mode == 1 || mode == 3 )
- {
- if(reg==12 || reg==13) // counter regs seem to be 8 bit only
- val&=0xff;
-
- if ( reg < 0x10 )
- {
- GETGPR(reg) = val;
- return;
- }
-
- switch( reg )
- {
- case 0x10: /* A */
- GETA().u = val;
- break;
-
- case 0x11: /* A.e */
- GETA().u &= ~((0x0000007f) << 23);
- GETA().u |= (( val & 0xff ) << 23 );
- break;
-
- case 0x12: /* A.m */
- GETA().u &= ~( 0x807fffff );
- GETA().u |= ( val & 0x7fffff );
- GETA().u |= ( val & 0x800000 ) << 8;
- break;
-
- case 0x13: /* B */
- GETB().u = val;
- break;
-
- case 0x14: /* B.e */
- GETB().u &= ~((0x0000007f) << 23);
- GETB().u |= (( val & 0xff ) << 23 );
- break;
-
- case 0x15: /* B.m */
- GETB().u &= ~( 0x807fffff );
- GETB().u |= ( val & 0x7fffff );
- GETB().u |= ( val & 0x800000 ) << 8;
- break;
-
- case 0x19: /* D */
- GETD().u = val;
- break;
-
- case 0x1A: /* D.e */
- GETD().u &= ~((0x0000007f) << 23);
- GETD().u |= (( val & 0xff ) << 23 );
- break;
-
- case 0x1B: /* B.m */
- GETD().u &= ~( 0x807fffff );
- GETD().u |= ( val & 0x7fffff );
- GETD().u |= ( val & 0x800000 ) << 8;
- break;
-
- case 0x1C: /* P */
- GETP().u = val;
- break;
-
- case 0x1D: /* P.e */
- GETP().u &= ~((0x000000ff) << 23);
- GETP().u |= (( val & 0xff ) << 23 );
- break;
-
- case 0x1E: /* P.m */
- GETP().u &= ~( 0x807fffff );
- GETP().u |= ( val & 0x7fffff );
- GETP().u |= ( val & 0x800000 ) << 8;
- break;
-
- case 0x1F:
- GETSHIFT() = val;
- break;
-
- case 0x20: /* Parallel Port */
- logerror( "TGP: Parallel port write: %08x at PC:%04x\n", val, GETPC() );
- break;
-
- case 0x22: /* FOut */
- m_fifo_write_cb( val );
- break;
-
- case 0x23:
- GETEB() = val;
- break;
-
- case 0x34:
- GETREPCNT() = val;
- break;
-
- default:
- fatalerror( "TGP: Unknown register write (r:%d, mode:%d) at PC:%04x\n", reg, mode, GETPC());
- }
- }
- else
- {
- fatalerror( "TGP: Unknown register write (r:%d, mode:%d) at PC:%04x\n", reg, mode, GETPC());
+ r &= 0x3f;
+ if(r >= 0x20 && r < 0x30)
+ return m_rf->read_dword(r & 0x1f);
+ switch(r) {
+ case 0x00: return m_b0;
+ case 0x01: return m_b1;
+ case 0x02: return m_x0;
+ case 0x03: return m_x1;
+
+ case 0x0c: return m_c0;
+ case 0x0d: return m_c1;
+
+ case 0x10: return m_a;
+ case 0x11: return get_exp(m_a);
+ case 0x12: return get_mant(m_a);
+ case 0x13: return m_b;
+ case 0x14: return get_exp(m_b);
+ case 0x15: return get_mant(m_b);
+ case 0x19: return m_d;
+ /* c */
+ case 0x1a: return get_exp(m_d);
+ case 0x1b: return get_mant(m_d);
+ case 0x1c: return m_p;
+ case 0x1d: return get_exp(m_p);
+ case 0x1e: return get_mant(m_p);
+ case 0x1f: return m_sft;
+
+ case 0x34: return m_rpc;
+
+ default:
+ logerror("unimplemented read_reg(%02x)\n", r);
+ return 0;
}
}
-
-/***************************************************************************
- Addressing Modes
-***************************************************************************/
-
-uint32_t mb86233_cpu_device::INDIRECT( uint32_t reg, int source )
+void mb86233_device::write_reg(u32 r, u32 v)
{
- uint32_t mode = ( reg >> 6 ) & 0x07;
-
- if ( mode == 0 || mode == 1 || mode == 3 )
- {
- return reg;
+ r &= 0x3f;
+ if(r >= 0x20 && r < 0x30) {
+ m_rf->write_dword(r & 0x1f, v);
+ return;
}
- else if ( mode == 2 )
- {
- uint32_t addr = reg & 0x3f;
-
- if ( source )
- {
- if( !(reg & 0x20) )
- addr += GETGPR(0);
+ switch(r) {
+ case 0x00: m_b0 = v; break;
+ case 0x01: m_b1 = v; break;
+ case 0x02: m_x0 = v; break;
+ case 0x03: m_x1 = v; break;
- addr += GETGPR(2);
- }
- else
- {
- if( !(reg & 0x20) )
- addr += GETGPR(1);
+ case 0x05: m_i0 = v; break;
+ case 0x06: m_i1 = v; break;
- addr += GETGPR(3);
- }
+ case 0x08: m_sp = v; break;
- return addr;
- }
- else if ( mode == 6 || mode == 7 )
- {
- uint32_t addr = 0;
+ case 0x0a: m_vsm = v & 7; m_vsmr = (8 << m_vsm) - 1; break;
- if ( source )
- {
- if ( !( reg & 0x20 ) )
- addr += GETGPR(0);
-
- addr += GETGPR(2);
- }
+ case 0x0c:
+ m_c0 = v;
+ if(m_c0 == 1)
+ m_st |= F_ZC0;
else
- {
- if ( !( reg & 0x20 ) )
- addr += GETGPR(1);
-
- addr += GETGPR(3);
- }
+ m_st &= ~F_ZC0;
+ break;
- if ( reg & 0x10 )
- {
- if ( source )
- GETGPR(2) -= 0x20 - ( reg & 0x1f );
- else
- GETGPR(3) -= 0x20 - ( reg & 0x1f );
- }
+ case 0x0d:
+ m_c1 = v;
+ if(m_c1 == 1)
+ m_st |= F_ZC1;
else
- {
- if ( source )
- GETGPR(2) += ( reg & 0x1f );
- else
- GETGPR(3) += ( reg & 0x1f );
- }
- if( mode == 7)
- {
- if ( source )
- GETGPR(2)&=0x3f;
- else
- GETGPR(3)&=0x3f;
- }
+ m_st &= ~F_ZC1;
+ break;
- return addr;
- }
- else
- {
- fatalerror( "TGP: Unknown INDIRECT mode %d at PC:%04x\n", mode, GETPC() );
+ case 0x0f: break;
+
+ case 0x10: m_a = v; break;
+ case 0x11: m_a = set_exp(m_a, v); break;
+ case 0x12: m_a = set_mant(m_a, v); break;
+ case 0x13: m_b = v; break;
+ case 0x14: m_b = set_exp(m_b, v); break;
+ case 0x15: m_b = set_mant(m_b, v); break;
+ /* c */
+ case 0x19: m_d = v; testdz(); break;
+ case 0x1a: m_d = set_exp(m_d, v); testdz(); break;
+ case 0x1b: m_d = set_mant(m_d, v); testdz(); break;
+ case 0x1c: m_p = v; break;
+ case 0x1d: m_p = set_exp(m_p, v); break;
+ case 0x1e: m_p = set_mant(m_p, v); break;
+ case 0x1f: m_sft = v; break;
+
+ case 0x34: m_rpc = v; break;
+ case 0x3c: m_mask = v; break;
+
+ default:
+ logerror("unimplemented write_reg(%02x, %08x)\n", r, v);
+ break;
}
-
- // never executed
- //return 0;
}
-/***************************************************************************
- Core Execution Loop
-***************************************************************************/
+void mb86233_device::write_mem_internal_1(u32 r, u32 v, bool bank)
+{
+ u16 ea = ea_pre_1(r);
+ if(bank)
+ ea += 0x200;
+ m_data->write_dword(ea, v);
+ ea_post_1(r);
+}
-void mb86233_cpu_device::execute_run()
+void mb86233_device::write_mem_io_1(u32 r, u32 v)
{
- while( m_icount > 0 )
- {
- uint32_t val;
- uint32_t opcode;
+ u16 ea = ea_pre_1(r);
+ m_io->write_dword(ea, v);
+ ea_post_1(r);
+}
- debugger_instruction_hook(GETPC());
+void mb86233_device::execute_run()
+{
+ while(m_icount > 0) {
+ m_ppc = m_pc;
+ debugger_instruction_hook(m_ppc);
+ u32 opcode = m_direct->read_dword(m_pc++);
+
+ switch((opcode >> 26) & 0x3f) {
+ case 0x00: {
+ // lab
+ u32 r1 = opcode & 0x1ff;
+ u32 r2 = (opcode >> 9) & 0x1ff;
+ u32 alu = (opcode >> 21) & 0x1f;
+ u32 op = (opcode >> 18) & 0x7;
+
+ alu_pre(alu);
+
+ switch(op) {
+ case 0: {
+ // lab mem, mem (e)
+
+ u32 ea1 = ea_pre_0(r1);
+ u32 v1 = m_data->read_dword(ea1);
+ if(m_stall) goto do_stall;
+
+ u32 ea2 = ea_pre_1(r2);
+ u32 v2 = m_io->read_dword(ea2);
+ if(m_stall) goto do_stall;
+
+ ea_post_0(r1);
+ ea_post_1(r2);
+
+ m_a = v1;
+ m_b = v2;
+ break;
+ }
- opcode = ROPCODE(GETPC());
+ case 3: {
+ // lab mem, mem + 0x200
- GETFIFOWAIT() = 0;
+ u32 ea1 = ea_pre_0(r1);
+ u32 v1 = m_data->read_dword(ea1);
+ if(m_stall) goto do_stall;
- switch( (opcode >> 26) & 0x3f )
- {
- case 0x00: /* dual move */
- {
- uint32_t r1 = opcode & 0x1ff;
- uint32_t r2 = ( opcode >> 9 ) & 0x7f;
- uint32_t alu = ( opcode >> 21 ) & 0x1f;
- uint32_t op = ( opcode >> 16 ) & 0x1f;
+ u32 ea2 = ea_pre_1(r2) + 0x200;
+ u32 v2 = m_data->read_dword(ea2);
+ if(m_stall) goto do_stall;
- ALU( alu );
+ ea_post_0(r1);
+ ea_post_1(r2);
- switch( op )
- {
- case 0x01:
- GETA().u = GETARAM()[INDIRECT(r1,1)];
- GETB().u = GETEXTERNAL( GETEB(),INDIRECT(r2|(2<<6), 0));
- break;
+ m_a = v1;
+ m_b = v2;
+ break;
+ }
- case 0x04: // ?
- GETA().u = GETARAM()[r1];
- GETB().u = GETEXTERNAL( GETEB(),r2);
- break;
+ case 4: {
+ // lab mem + 0x200, mem
- case 0x0C:
- GETA().u = GETARAM()[INDIRECT(r1,1)];
- GETB().u = GETBRAM()[r2];
- break;
+ u32 ea1 = ea_pre_0(r1) + 0x200;
+ u32 v1 = m_data->read_dword(ea1);
+ if(m_stall) goto do_stall;
- case 0x0D: // VF2 shadows
- GETA().u = GETARAM()[INDIRECT(r1,1)];
- GETB().u = GETBRAM()[INDIRECT(r2|2<<6,0)];
- break;
+ u32 ea2 = ea_pre_1(r2);
+ u32 v2 = m_data->read_dword(ea2);
+ if(m_stall) goto do_stall;
- case 0x0F:
- GETA().u = GETARAM()[r1];
- GETB().u = GETBRAM()[INDIRECT(r2|6<<6,0)];
- break;
+ ea_post_0(r1);
+ ea_post_1(r2);
- case 0x10:
- GETA().u = GETBRAM()[INDIRECT(r1,1)];
- GETB().u = GETARAM()[r2];
- break;
+ m_a = v1;
+ m_b = v2;
+ break;
+ }
- case 0x11:
- GETA().u = GETBRAM()[INDIRECT(r1,1)];
- GETB().u = GETARAM()[INDIRECT(r2|(2<<6),0)];
- break;
+ default:
+ logerror("unhandler lab subop %x\n", op);
+ break;
- default:
- logerror( "TGP: Unknown TGP double move (op=%d) at PC:%x\n", op, GETPC());
- break;
- }
}
- break;
-
- case 0x7: /* LD/MOV */
- {
- uint32_t r1 = opcode & 0x1ff;
- uint32_t r2 = ( opcode >> 9 ) & 0x7f;
- uint32_t alu = ( opcode >> 21 ) & 0x1f;
- uint32_t op = ( opcode >> 16 ) & 0x1f;
-
- switch( op )
- {
- case 0x04: /* MOV RAM->External */
- {
- SETEXTERNAL( GETEB(), r2, GETARAM()[r1]);
- ALU(alu);
- }
- break;
- case 0x0c: /* MOV RAM->BRAM */
- {
- GETBRAM()[r2] = GETARAM()[r1];
- ALU(alu);
- }
- break;
+ alu_post(alu);
+ break;
+ }
- case 0x0d: /* Move RAM->BRAM indirect? */
- {
- val = GETARAM()[r1];
- ALU(alu);
- GETBRAM()[INDIRECT(r2|(2<<6),0)] = val;
- }
- break;
- case 0x1d: /* MOV RAM->Reg */
- {
- if ( r1 & 0x180 )
- {
- val = GETARAM()[GETREGS(r1,0)];
- }
- else
- {
- val = GETARAM()[r1];
- }
-
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
-
- ALU(alu);
- SETREGS(r2,val);
- }
- break;
+ case 0x07: {
+ // ld / mov
+ u32 r1 = opcode & 0x1ff;
+ u32 r2 = (opcode >> 9) & 0x1ff;
+ u32 alu = (opcode >> 21) & 0x1f;
+ u32 op = (opcode >> 18) & 0x7;
- case 0x1c: /* MOV Reg->RAMInd */
- {
- val = GETREGS(r2,1);
+ alu_pre(alu);
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
+ switch(op) {
+ case 0: {
+ // mov mem, mem (e)
+ u32 ea = ea_pre_0(r1);
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_mem_io_1(r2, v);
+ break;
+ }
- ALU(alu);
+ case 1: {
+ // mov mem + 0x200, mem (e)
+ u32 ea = ea_pre_0(r1) + 0x200*0;
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_mem_io_1(r2, v);
+ break;
+ }
- if ( ( r2 >> 6 ) & 0x01)
- {
- SETEXTERNAL( GETEB(),INDIRECT(r1,0),val);
- }
- else
- {
- GETARAM()[INDIRECT(r1,0)] = val;
- }
- }
- break;
+ case 2: {
+ // mov mem (e), mem
+ u32 ea = ea_pre_0(r1);
+ u32 v = m_io->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_mem_internal_1(r2, v, false);
+ break;
+ }
- case 0x1f: /* MOV Reg->Reg */
- {
- if ( r1 == 0x10 && r2 == 0xf )
- {
- /* NOP */
- ALU( alu);
- }
- else
- {
- val = GETREGS(r1,1);
-
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
-
- ALU(alu);
- SETREGS(r2, val);
- }
- }
- break;
+ case 3: {
+ // mov mem, mem + 0x200
+ u32 ea = ea_pre_0(r1);
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_mem_internal_1(r2, v, true);
+ break;
+ }
- case 0x0f: /* MOV RAMInd->BRAMInd */
- {
- val = GETARAM()[INDIRECT(r1,1)];
- ALU(alu);
- GETBRAM()[INDIRECT(r2|(6<<6),0)] = val;
- }
- break;
+ case 4: {
+ // mov mem + 0x200, mem
+ u32 ea = ea_pre_0(r1) + 0x200;
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_mem_internal_1(r2, v, false);
+ break;
+ }
- case 0x13: /* MOV BRAMInd->RAMInd */
- {
- val = GETBRAM()[INDIRECT(r1,1)];
- ALU(alu);
- GETARAM()[INDIRECT(r2|(6<<6),0)] = val;
- }
- break;
+ case 5: {
+ // mov mem (o), mem
+ u32 ea = ea_pre_0(r1);
+ u32 v = m_program->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_mem_internal_1(r2, v, false);
+ break;
+ }
- case 0x10: /* MOV RAMInd->RAM */
- {
- val = GETBRAM()[INDIRECT(r1,1)];
- ALU(alu);
- GETARAM()[r2] = val;
- }
+ case 7: {
+ switch(r2 >> 6) {
+ case 0: {
+ // mov reg, mem
+ u32 v = read_reg(r2);
+ if(m_stall) goto do_stall;
+ write_mem_internal_1(r1, v, false);
break;
+ }
- case 0x1e: /* External->Reg */
- {
- uint32_t offset;
-
- if ( (( r2 >> 6 ) & 7) == 1 )
- {
- offset = INDIRECT(r1,1);
- val = GETEXTERNAL(0,offset);
- }
- else
- {
- offset = INDIRECT(r1,0);
- val = GETEXTERNAL(GETEB(),offset);
- }
-
- ALU(alu);
- SETREGS(r2,val);
- }
+ case 1: {
+ // mov reg, mem (e)
+ u32 v = read_reg(r2);
+ if(m_stall) goto do_stall;
+ write_mem_io_1(r1, v);
break;
+ }
- case 0x03: /* RAM->External Ind */
- {
- val = GETARAM()[r1];
- ALU(alu);
- SETEXTERNAL(GETEB(),INDIRECT(r2|(6<<6),0),val);
- }
+ case 2: {
+ // mov mem + 0x200, reg
+ u32 ea = ea_pre_1(r1) + 0x200;
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_1(r1);
+ write_reg(r2, v);
break;
+ }
- case 0x07: /* RAMInd->External */
- {
- val = GETARAM()[INDIRECT(r1,1)];
- ALU(alu);
- SETEXTERNAL( GETEB(),INDIRECT(r2|(6<<6),0),val);
- }
+ case 3: {
+ // mov mem, reg
+ u32 ea = ea_pre_1(r1);
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_1(r1);
+ write_reg(r2, v);
break;
+ }
- case 0x08: /* External->RAM */
- {
- val = GETEXTERNAL( GETEB(),INDIRECT(r1,1));
- ALU(alu);
- GETARAM()[r2] = val;
- }
+ case 4: {
+ // mov mem (e), reg
+ u32 ea = ea_pre_1(r1);
+ u32 v = m_io->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_1(r1);
+ write_reg(r2, v);
break;
+ }
- case 0x0b: /* External->RAMInd */
- {
- val = GETEXTERNAL( GETEB(),INDIRECT(r1,1));
- ALU( alu);
- GETARAM()[INDIRECT(r2|(6<<6),0)] = val;
- }
+ case 5: {
+ // mov mem (o), reg
+ u32 ea = ea_pre_0(r1);
+ u32 v = m_program->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(r1);
+ write_reg(r2, v);
break;
+ }
- case 0x17: /* External r2-> RAMInd r3 */
- {
- uint32_t offset;
-
- offset = INDIRECT(r1,1);
-
- val = GETEXTERNAL( GETEB(), offset);
- ALU(alu);
- GETARAM()[INDIRECT(r2|(6<<6),0)] = val;
- }
+ case 6: {
+ // mov reg, reg
+ u32 v = read_reg(r1);
+ if(m_stall) goto do_stall;
+ write_reg(r2, v);
break;
- case 0x14:
- {
- uint32_t offset;
-
- offset = INDIRECT(r1,1);
+ }
- val = GETEXTERNAL( 0, offset);
- ALU(alu);
- GETARAM()[r2] = val;
- }
+ default:
+ logerror("unhandler ld/mov subop 7/%x\n", r2 >> 6);
break;
-
- default:
- fatalerror( "TGP: Unknown TGP move (op=%02x) at PC:%x\n", op, GETPC());
}
+ break;
}
- break;
-
- case 0x0d: /* CONTROL? */
- {
- uint32_t sub = (opcode>>16) & 0xff;
-
- switch(sub)
- {
- case 0x0a: // FPU Round Control opcode
- m_fpucontrol = opcode & 0xff;
- logerror( "TGP: FPU Round CONTROL sets %02x at PC:%x\n", m_fpucontrol, GETPC());
- break;
- default:
- logerror( "TGP: Unknown CONTROL sub-type %02x at PC:%x\n", sub, GETPC());
- break;
- }
+ default:
+ logerror("unhandler ld/mov subop %x\n", op);
break;
}
- case 0x0e: /* LDIMM24 */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
-
- /* sign extend 24->32 */
- if ( imm & 0x800000 )
- imm |= 0xFF000000;
+ alu_post(alu);
+ break;
+ }
- switch( sub )
- {
- case 0x00: /* P */
- GETP().u = imm;
- break;
+ case 0x0d: {
+ // stm/clm
+ u32 sub2 = (opcode >> 17) & 7;
- case 0x01: /* A */
- GETA().u = imm;
- break;
+ // Theorically has restricted alu too
- case 0x02: /* B */
- GETB().u = imm;
- break;
+ switch(sub2) {
+ case 5:
+ // stmh
+ // bit 0 = floating point
+ // bit 1-2 = rounding mode
+ m_m = opcode;
+ break;
- case 0x03: /* D */
- GETD().u = imm;
- break;
- }
+ default:
+ logerror("unimplemented opcode 0d/%x\n", sub2);
+ break;
}
break;
+ }
- case 0x0f: /* REP/CLEAR/FLAGS */
- {
- uint32_t alu = ( opcode >> 20 ) & 0x1f;
- uint32_t sub2 = ( opcode >> 16 ) & 0x0f;
-
- ALU(alu);
-
- if( sub2 == 0x00 ) /* CLEAR reg */
- {
- uint32_t reg = opcode & 0x1f;
-
- switch( reg )
- {
- case 0x10:
- GETD().u = 0;
- break;
-
- case 0x08:
- GETB().u = 0;
- break;
-
- case 0x04:
- GETA().u = 0;
- break;
- }
- }
- else if ( sub2 == 0x04 ) /* REP xxx */
- {
- uint32_t sub3 = ( opcode >> 12 ) & 0x0f;
-
- if ( sub3 == 0 )
- {
- GETREPS() = opcode & 0xfff;
-
- if ( GETREPS() == 0 )
- GETREPS() = 0x100;
-
- GETPC()++;
- }
- else if ( sub3 == 8 )
- {
- GETREPS() = GETREGS( opcode & 0xfff, 0 );
- GETPC()++;
- }
- }
- else if ( sub2 == 0x02 ) /* CLRFLAGS */
- {
- GETSR() &= ~(opcode&0xfff);
- }
- else if ( sub2 == 0x06 ) /* SETFLAGS */
- {
- GETSR() |= (opcode&0xfff);
- }
+ case 0x0e: {
+ // lipl / lia / lib / lid
+ switch((opcode >> 24) & 0x3) {
+ case 0:
+ m_p = (m_p & 0xffffff000000) | (opcode & 0xffffff);
+ break;
+ case 1:
+ m_a = s24_32(opcode);
+ break;
+ case 2:
+ m_b = s24_32(opcode);
+ break;
+ case 3:
+ m_d = s24_32(opcode);
+ testdz();
+ break;
}
break;
+ }
- case 0x10: /* LDIMM rx */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffff;
+ case 0x0f: {
+ // rep/clr0/clr1/set
+ u32 alu = (opcode >> 20) & 0x1f;
+ u32 sub2 = (opcode >> 17) & 7;
+
+ alu_pre(alu);
+
+ switch(sub2) {
+ case 0:
+ // clr0
+ if(opcode & 0x0004) m_a = 0;
+ if(opcode & 0x0008) m_b = 0;
+ if(opcode & 0x0010) m_d = 0;
+ break;
- GETGPR(sub) = imm;
- }
- break;
+ case 1:
+ // clr1 - flags mapping unknown
+ break;
- case 0x13: /* LDIMM r1x */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
-
- if ( sub == 0 ) /* R12 */
- GETGPR(12) = imm;
- else if ( sub == 1 ) /* R13 */
- GETGPR(13) = imm;
- else
- logerror( "TGP: Unknown LDIMM r12 (sub=%d) at PC:%04x\n", sub, GETPC() );
+ case 2: {
+ // rep
+ u8 r = opcode & 0x8000 ? read_reg(opcode) : opcode;
+ if(m_stall) goto do_stall;
+ m_r = r;
+ goto rep_start;
}
- break;
- case 0x14: /* LDIMM m,e */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
+ case 3:
+ // set - flags mapping unknown
+ // 0800 = enable interrupt flag
+ break;
- if ( sub == 0 ) /* A */
- {
- GETA().u = imm;
- }
- else if ( sub == 1 ) /* A.e */
- {
- GETA().u &= ~0x7f800000;
- GETA().u |= (imm & 0xff) << 23;
- }
- else if ( sub == 2 ) /* A.m */
- {
- GETA().u &= 0x7f800000;
- GETA().u |= (imm & 0x7fffff ) | ((imm & 0x800000) << 8);
- }
- else
- {
- fatalerror( "TGP: Unknown LDIMM m,e (sub=%d) at PC:%04x\n", sub, GETPC() );
- }
+ default:
+ logerror("unimplemented opcode 0f/%x\n", sub2);
+ break;
}
+
+ alu_post(alu);
break;
+ }
- case 0x15: /* LDIMM m,e */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
-
- if ( sub == 0 ) /* B.e again? */
- {
- //GETB().u = ((imm & 0x7f) << 23) | ((imm & 0xff) << 8) | ( imm & 0xff );
- GETB().u &= ~0x7f800000;
- GETB().u |= (imm & 0xff) << 23;
- }
- else if ( sub == 1 ) /* B.e */
- {
- GETB().u &= ~0x7f800000;
- GETB().u |= (imm & 0xff) << 23;
- }
- else if ( sub == 2 ) /* B.m */
- {
- GETB().u &= 0x7f800000;
- GETB().u |= (imm & 0x7fffff ) | ((imm & 0x800000) << 8);
- }
- else
- {
- fatalerror( "TGP: Unknown LDIMM m,e (sub=%d) at PC:%04x\n", sub, GETPC() );
- }
- }
+ 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: {
+ // ldi
+ write_reg(opcode >> 24, s24_32(opcode));
break;
+ }
- case 0x16: /* LDIMM m,e */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
+ case 0x2f: case 0x3f: {
+ // Conditional branch of every kind
+ u32 cond = ( opcode >> 20 ) & 0x1f;
+ u32 subtype = ( opcode >> 17 ) & 7;
+ u32 data = opcode & 0xffff;
+ bool invert = opcode & 0x40000000;
- if ( sub == 1 ) /* clear + D.m */
- {
- GETD().u = (imm & 0x7fffff ) | ((imm & 0x800000) << 8);
- }
- else if ( sub == 2 ) /* D.e */
- {
- GETD().u &= ~0x7f800000;
- GETD().u |= (imm & 0xff) << 23;
- }
- else if ( sub == 3 ) /* D.m */
- {
- GETD().u &= 0x7f800000;
- GETD().u |= (imm & 0x7fffff ) | ((imm & 0x800000) << 8);
- }
- else
- {
- fatalerror( "TGP: Unknown LDIMM m,e (sub=%d) at PC:%04x\n", sub, GETPC() );
- }
- }
- break;
+ bool cond_passed = false;
- case 0x17: /* LDIMM special reg */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
+ switch(cond) {
+ case 0x00: // zrd - d zero
+ cond_passed = m_st & F_ZRD;
+ break;
- if ( sub == 0x03 )
- {
- GETSHIFT() = imm;
- }
- else
- {
- logerror( "TGP: Unknown LDIMM special reg (sub=%d) at PC:%04x\n", sub, GETPC() );
- }
- }
- break;
+ case 0x01: // ged - d >= 0
+ cond_passed = !(m_st & F_SGD);
+ break;
- case 0x18: /* LDIMM external reg */
- {
- uint32_t sub = (opcode>>24) & 0x03;
- uint32_t imm = opcode & 0xffffff;
+ case 0x02: // led - d <= 0
+ cond_passed = m_st & (F_ZRD | F_SGD);
+ break;
- if ( sub == 0x03 )
- {
- GETEB() = imm;
- }
- else
- {
- fatalerror( "TGP: Unknown LDIMM external reg (sub=%d) at PC:%04x\n", sub, GETPC() );
- }
- }
- break;
+ case 0x0a: // gpio0
+ cond_passed = m_gpio0;
+ break;
- case 0x1d: //LDIMM to Rep regs
- {
- uint32_t sub = (opcode>>24)&0x3;
- uint32_t imm = opcode&0xffffff;
- if(sub == 0x00)
- {
- GETREPCNT() = imm;
- }
- else
- {
- fatalerror( "TGP: Unknown LDIMM REPCnt (sub=%d) at PC:%04x\n", sub, GETPC() );
- }
- }
- break;
+ case 0x0b: // gpio1
+ cond_passed = m_gpio1;
+ break;
- case 0x2f: /* Conditional Branches */
- {
- uint32_t cond = ( opcode >> 20 ) & 0x1f;
- uint32_t subtype = ( opcode >> 16 ) & 0x0f;
- uint32_t data = opcode & 0xffff;
-
- if( COND( cond) )
- {
- switch( subtype )
- {
- case 0x00: /* BRIF <addr> */
- GETPC() = data - 1;
- break;
-
- case 0x02: /* BRIF indirect */
- data = GETREGS(data&0x7f,0) - 1;
-
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
-
- GETPC() = data;
- break;
-
- case 0x04: /* BSIF <addr> */
- GETPCS()[GETPCSP()] = GETPC();
- GETPCSP()++;
- GETPC() = data - 1;
- break;
-
- case 0x06: /* BSIF indirect */
- GETPCS()[GETPCSP()] = GETPC();
- GETPCSP()++;
- if ( data & 0x4000 )
- data = GETREGS(data&0x7f,0) - 1;
- else
- data = ((GETARAM()[data&0x3ff])&0xffff)-1;
-
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
-
- GETPC() = data;
- break;
-
- case 0x0a: /* RTIF */
- --GETPCSP();
- GETPC() = GETPCS()[GETPCSP()];
- break;
-
- case 0x0c: /* LDIF */
- SETREGS(((data>>9)&0x7f), GETARAM()[data&0x1FF] );
- break;
-
- case 0x0e: /* RIIF */
- fatalerror( "TGP: RIIF unimplemented at PC:%04x\n", GETPC() );
-
- default:
- fatalerror( "TGP: Unknown Branch opcode (subtype=%d) at PC:%04x\n", subtype, GETPC() );
- }
- }
- }
- break;
+ case 0x0c: // gpio2
+ cond_passed = m_gpio2;
+ break;
- case 0x3f: /* Inverse Conditional Branches */
- {
- uint32_t cond = ( opcode >> 20 ) & 0x1f;
- uint32_t subtype = ( opcode >> 16 ) & 0x0f;
- uint32_t data = opcode & 0xffff;
+ case 0x10: // zc0 - c0 == 1
+ cond_passed = !(m_st & F_ZC0);
+ break;
- if( !COND( cond) )
- {
- switch( subtype )
- {
- case 0x00: /* BRUL <addr> */
- GETPC() = data - 1;
- break;
+ case 0x11: // zc1 - c1 == 1
+ cond_passed = !(m_st & F_ZC1);
+ break;
- case 0x02: /* BRUL indirect */
- data = GETREGS(data&0x7f,0) - 1;
+ case 0x12: // gpio3
+ cond_passed = m_gpio3;
+ break;
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
+ case 0x16: // alw - always
+ cond_passed = true;
+ break;
- GETPC() = data;
- break;
+ default:
+ logerror("unimplemented condition %x\n", cond);
+ break;
+ }
+ if(invert)
+ cond_passed = !cond_passed;
- case 0x04: /* BSUL <addr> */
- GETPCS()[GETPCSP()] = GETPC();
- GETPCSP()++;
- GETPC() = data - 1;
- break;
+ if(cond_passed) {
+ switch(subtype) {
+ case 0: // brif #adr
+ m_pc = data;
+ break;
- case 0x06: /* BSUL indirect */
- data = GETARAM()[data] - 1;
+ case 1: // brul
+ if(opcode & 0x4000) {
+ // brul reg
+ u32 v = read_reg(opcode);
+ if(m_stall) goto do_stall;
+ m_pc = v;
+ } else {
+ // brul adr
+ u32 ea = ea_pre_0(opcode);
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(opcode);
+ m_pc = v;
+ }
+ break;
- /* if we're waiting for data, don't complete the instruction */
- if ( GETFIFOWAIT() )
- break;
+ case 2: // bsif #adr
+ pcs_push();
+ m_pc = data;
+ break;
- GETPC() = data;
- break;
+ case 3: // bsul
+ if(opcode & 0x4000) {
+ // bsul reg
+ u32 v = read_reg(opcode);
+ if(m_stall) goto do_stall;
+ pcs_push();
+ m_pc = v;
+ } else {
+ // bsul adr
+ u32 ea = ea_pre_0(opcode);
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(opcode);
+ pcs_push();
+ m_pc = v;
+ }
+ break;
- case 0x0a: /* RTUL */
- --GETPCSP();
- GETPC() = GETPCS()[GETPCSP()];
- break;
+ case 5: // rtif #adr
+ pcs_pop();
+ break;
- case 0x0c: /* LDUL */
- SETREGS(((data>>9)&0x7f), GETARAM()[data&0x1FF] );
- break;
+ case 6: { // ldif adr, rn
+ u32 ea = ea_pre_0(opcode);
+ u32 v = m_data->read_dword(ea);
+ if(m_stall) goto do_stall;
+ ea_post_0(opcode);
+ write_reg(opcode >> 9, v);
+ break;
+ }
- case 0x0e: /* RIUL */
- fatalerror( "TGP: RIUL unimplemented at PC:%04x\n", GETPC() );
+ default:
+ logerror("unimplemented branch subtype %x\n", subtype);
+ break;
+ }
+ }
- default:
- fatalerror( "TGP: Unknown Branch opcode (subtype=%d) at PC:%04x\n", subtype, GETPC() );
+ if(subtype < 2)
+ switch(cond) {
+ case 0x10:
+ if(m_c0 != 1) {
+ m_c0 --;
+ if(m_c0 == 1)
+ m_st |= F_ZC0;
}
+ break;
+
+ case 0x11:
+ if(m_c1 != 1) {
+ m_c1 --;
+ if(m_c1 == 1)
+ m_st |= F_ZC1;
+ }
+ break;
}
- }
+
break;
+ }
- case 0x1f:
- case 0x12:
- logerror( "TGP: unknown opcode %08x at PC:%04x (%02x)\n", opcode, GETPC(),(opcode >> 26) & 0x3f );
+ default:
+ logerror("unimplemented opcode type %02x\n", (opcode >> 26) & 0x3f);
break;
-
- default:
- fatalerror( "TGP: unknown opcode %08x at PC:%04x (%02x)\n", opcode, GETPC(),(opcode >> 26) & 0x3f );
}
- if ( GETFIFOWAIT() == 0 )
- {
- if( GETREPS() == 0 )
- GETPC()++;
- else
- --GETREPS();
-
- m_icount--;
+ if(m_r != 1) {
+ m_pc = m_ppc;
+ m_r --;
}
- else
- {
- m_icount = 0;
+
+ rep_start:
+ if(0) {
+ do_stall:
+ m_pc = m_ppc;
+ m_stall = false;
}
+ m_icount--;
}
}
diff --git a/src/devices/cpu/mb86233/mb86233.h b/src/devices/cpu/mb86233/mb86233.h
index 1d25be5eae4..255b16d16e4 100644
--- a/src/devices/cpu/mb86233/mb86233.h
+++ b/src/devices/cpu/mb86233/mb86233.h
@@ -1,143 +1,137 @@
// license:BSD-3-Clause
-// copyright-holders:Ernesto Corvi
+// copyright-holders:Olivier Galibert
+
#ifndef MAME_CPU_MB86233_MB86233_H
#define MAME_CPU_MB86233_MB86233_H
#pragma once
+class mb86233_device : public cpu_device
+{
+public:
+ enum address_space_ids {
+ AS_RF = 4,
+ AS_EXTERNAL = 5
+ };
-#define MCFG_MB86233_FIFO_READ_CB(_devcb) \
- devcb = &downcast<mb86233_cpu_device &>(*device).set_fifo_read_cb(DEVCB_##_devcb);
-#define MCFG_MB86233_FIFO_READ_OK_CB(_devcb) \
- devcb = &downcast<mb86233_cpu_device &>(*device).set_fifo_read_ok_cb(DEVCB_##_devcb);
-#define MCFG_MB86233_FIFO_WRITE_CB(_devcb) \
- devcb = &downcast<mb86233_cpu_device &>(*device).set_fifo_write_cb(DEVCB_##_devcb);
-#define MCFG_MB86233_TABLE_REGION(_region) \
- downcast<mb86233_cpu_device &>(*device).set_tablergn(_region);
+ enum regs_ids {
+ REG_A, REG_B, REG_D, REG_P,
+ REG_R, REG_C0, REG_C1,
+ REG_B0, REG_B1, REG_X0, REG_X1, REG_I0, REG_I1,
+ REG_SFT, REG_VSM, REG_MASK, REG_M,
+ REG_PCS0, REG_PCS1, REG_PCS2, REG_PCS3
+ };
+ enum st_flags {
+ F_ZRC = 0x00000001,
+ F_ZRD = 0x00000002,
+ F_SGC = 0x00000004,
+ F_SGD = 0x00000008,
+ F_CPC = 0x00000010,
+ F_CPD = 0x00000020,
+ F_OVC = 0x00000040,
+ F_OVD = 0x00000080,
+ F_UNC = 0x00000100,
+ F_UND = 0x00000200,
+ F_DVZC = 0x00000400,
+ F_DVZD = 0x00000800,
+ F_CA = 0x00001000,
+ F_CPP = 0x00002000,
+ F_OVM = 0x00004000,
+ F_UNM = 0x00008000,
+ F_SIF0 = 0x00010000,
+ F_SIF1 = 0x00020000,
+ F_SOF0 = 0x00040000,
+
+ F_PIF = 0x00100000,
+ F_POF = 0x00200000,
+ F_PAIF = 0x00400000,
+ F_PAOF = 0x00800000,
+ F_F0S = 0x01000000,
+ F_F1S = 0x02000000,
+ F_IT = 0x04000000,
+ F_ZX0 = 0x08000000,
+ F_ZX1 = 0x10000000,
+ F_ZX2 = 0x20000000,
+ F_ZC0 = 0x40000000,
+ F_ZC1 = 0x80000000
+ };
-class mb86233_cpu_device : public cpu_device
-{
-public:
- // construction/destruction
- mb86233_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ mb86233_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // configuration helpers
- template <class Object> devcb_base &set_fifo_read_cb(Object &&cb) { return m_fifo_read_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_fifo_read_ok_cb(Object &&cb) { return m_fifo_read_ok_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_fifo_write_cb(Object &&cb) { return m_fifo_write_cb.set_callback(std::forward<Object>(cb)); }
- void set_tablergn(const char *tablergn) { m_tablergn = tablergn; }
+ void stall() { m_stall = true; }
+
+ DECLARE_WRITE_LINE_MEMBER(gpio0_w);
+ DECLARE_WRITE_LINE_MEMBER(gpio1_w);
+ DECLARE_WRITE_LINE_MEMBER(gpio2_w);
+ DECLARE_WRITE_LINE_MEMBER(gpio3_w);
protected:
- // register enumeration
- enum
- {
- MB86233_PC=1,
- MB86233_A,
- MB86233_B,
- MB86233_D,
- MB86233_P,
- MB86233_REP,
- MB86233_SP,
- MB86233_EB,
- MB86233_SHIFT,
- MB86233_FLAGS,
- MB86233_R0,
- MB86233_R1,
- MB86233_R2,
- MB86233_R3,
- MB86233_R4,
- MB86233_R5,
- MB86233_R6,
- MB86233_R7,
- MB86233_R8,
- MB86233_R9,
- MB86233_R10,
- MB86233_R11,
- MB86233_R12,
- MB86233_R13,
- MB86233_R14,
- MB86233_R15
- };
+ mb86233_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
- // device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
- // device_execute_interface overrides
virtual uint32_t execute_min_cycles() const override { return 1; }
- virtual uint32_t execute_max_cycles() const override { return 2; }
- virtual uint32_t execute_input_lines() const override { return 0; }
+ virtual uint32_t execute_max_cycles() const override { return 1; }
+ virtual uint32_t execute_input_lines() const override { return 4; }
virtual void execute_run() override;
- // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
-
- // device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
- // device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
address_space_config m_program_config;
address_space_config m_data_config;
+ address_space_config m_io_config;
+ address_space_config m_rf_config;
- union MB86233_REG
- {
- int32_t i;
- uint32_t u;
- float f;
- };
-
- uint16_t m_pc;
- MB86233_REG m_a;
- MB86233_REG m_b;
- MB86233_REG m_d;
- MB86233_REG m_p;
-
- uint16_t m_reps;
- uint16_t m_pcs[4];
- uint8_t m_pcsp;
- uint32_t m_eb;
- uint32_t m_shift;
- uint32_t m_repcnt;
- uint16_t m_sr;
- uint8_t m_fpucontrol;
-
- uint32_t m_gpr[16];
- uint32_t m_extport[0x30];
-
- address_space *m_program;
+ address_space *m_program, *m_data, *m_io, *m_rf;
direct_read_data<-2> *m_direct;
int m_icount;
- /* FIFO */
- int m_fifo_wait;
- devcb_read32 m_fifo_read_cb;
- devcb_read_line m_fifo_read_ok_cb;
- devcb_write32 m_fifo_write_cb;
- const char *m_tablergn;
-
- /* internal RAM */
- uint32_t m_RAM[2 * 0x200];
- uint32_t *m_ARAM, *m_BRAM;
- uint32_t *m_Tables;
-
- void FLAGSF( float v );
- void FLAGSI( uint32_t v );
- int COND( uint32_t cond );
- void ALU( uint32_t alu);
- uint32_t ScaleExp(unsigned int v,int scale);
- uint32_t GETEXTERNAL( uint32_t EB, uint32_t offset );
- void SETEXTERNAL( uint32_t EB, uint32_t offset, uint32_t value );
- uint32_t GETREGS( uint32_t reg, int source );
- void SETREGS( uint32_t reg, uint32_t val );
- uint32_t INDIRECT( uint32_t reg, int source );
+ u32 m_st, m_a, m_b, m_d, m_p;
+ u32 m_alu_stmask, m_alu_stset, m_alu_r1, m_alu_r2;
+ u16 m_ppc, m_pc, m_sp, m_b0, m_b1, m_x0, m_x1, m_i0, m_i1, m_vsmr, m_pcs[4], m_mask, m_m;
+ u8 m_r, m_rpc, m_c0, m_c1, m_sft, m_vsm;
+ bool m_gpio0, m_gpio1, m_gpio2, m_gpio3;
+
+ bool m_stall;
+
+ static s32 s24_32(u32 val);
+ static u32 set_exp(u32 val, u32 exp);
+ static u32 set_mant(u32 val, u32 mant);
+ static u32 get_exp(u32 val);
+ static u32 get_mant(u32 val);
+
+ void testdz();
+ void alu_update_st();
+ void alu_pre(u32 alu);
+ void alu_post(u32 alu);
+ u16 ea_pre_0(u32 r);
+ void ea_post_0(u32 r);
+ u16 ea_pre_1(u32 r);
+ void ea_post_1(u32 r);
+ void pcs_push();
+ void pcs_pop();
+
+ u32 read_reg(u32 r);
+ void write_reg(u32 r, u32 v);
+ void write_mem_internal_1(u32 r, u32 v, bool bank);
+ void write_mem_external_1(u32 r, u32 v);
+ void write_mem_io_1(u32 r, u32 v);
+};
+class mb86234_device : public mb86233_device
+{
+public:
+ mb86234_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
-DECLARE_DEVICE_TYPE(MB86233, mb86233_cpu_device)
+DECLARE_DEVICE_TYPE(MB86233, mb86233_device)
+DECLARE_DEVICE_TYPE(MB86234, mb86234_device)
#endif // MAME_CPU_MB86233_MB86233_H
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:
diff --git a/src/devices/cpu/mb86233/mb86233d.h b/src/devices/cpu/mb86233/mb86233d.h
index 50a48a6f0a9..bd475e061b6 100644
--- a/src/devices/cpu/mb86233/mb86233d.h
+++ b/src/devices/cpu/mb86233/mb86233d.h
@@ -19,7 +19,7 @@ private:
static const char *const regnames[0x40];
static std::string condition(unsigned int cond, bool invert);
static std::string regs(u32 reg);
- static std::string memory(u32 reg, bool x1);
+ static std::string memory(u32 reg, bool x1, bool bank);
static std::string alu0_func(u32 alu);
};