diff options
Diffstat (limited to 'src/mame/machine/micro3d.cpp')
-rw-r--r-- | src/mame/machine/micro3d.cpp | 538 |
1 files changed, 0 insertions, 538 deletions
diff --git a/src/mame/machine/micro3d.cpp b/src/mame/machine/micro3d.cpp deleted file mode 100644 index e30e9361b5d..00000000000 --- a/src/mame/machine/micro3d.cpp +++ /dev/null @@ -1,538 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Philip Bennett -/*************************************************************************** - - Microprose Games machine hardware - -****************************************************************************/ - -#include "emu.h" -#include "includes/micro3d.h" -#include "audio/micro3d.h" - -#include "cpu/m68000/m68000.h" -#include "cpu/tms34010/tms34010.h" -#include "cpu/am29000/am29000.h" -#include "cpu/mcs51/mcs51.h" - - -/************************************* - * - * Defines - * - *************************************/ - -#define MAC_CLK XTAL(10'000'000) -#define VTXROM_FMT(x) (((x) << 14) | ((x) & (1 << 15) ? 0xc0000000 : 0)) - - -/************************************* - * - * 68681 DUART - * - *************************************/ - -WRITE_LINE_MEMBER(micro3d_state::duart_irq_handler) -{ - m_maincpu->set_input_line(3, state); -} - -WRITE_LINE_MEMBER(micro3d_state::duart_txb) -{ - m_m68681_tx0 = state; - m_audiocpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - // TODO: next line should be behind a timer callback which lasts one audiocpu clock cycle - m_audiocpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); -} - -READ8_MEMBER(micro3d_state::data_to_i8031) -{ - return m_m68681_tx0; -} - -WRITE8_MEMBER(micro3d_state::data_from_i8031) -{ - m_duart->rx_b_w(data); -} - -/* - * 0: Monitor port P4 - * 1: 5V - * 2: /AM29000 present - * 3: /TMS34010 present - * 4: - - * 5: - - */ -READ8_MEMBER(micro3d_state::duart_input_r) -{ - return 0x2; -} - -/* - * 5: /I8051 reset - * 7: Status LED -*/ -WRITE8_MEMBER(micro3d_state::duart_output_w) -{ - m_audiocpu->set_input_line(INPUT_LINE_RESET, data & 0x20 ? CLEAR_LINE : ASSERT_LINE); -} - - -/************************************* - * - * SCN2651 (TMS34010) - * - *************************************/ - -READ8_MEMBER( micro3d_state::vgb_uart_r ) -{ - // the mode and sync registers switched places? - if (offset == 1 || offset == 2) - offset ^= 3; - - return m_vgb_uart->read(offset); -} - -WRITE8_MEMBER( micro3d_state::vgb_uart_w ) -{ - // the mode and sync registers switched places? - if (offset == 1 || offset == 2) - offset ^= 3; - - m_vgb_uart->write(offset, data); -} - - -/************************************* - * - * Math unit - * - *************************************/ - -inline constexpr int64_t micro3d_state::micro3d_vtx::dot_product(micro3d_vtx const &that) const -{ - return - (int64_t(x) * int64_t(that.x)) + - (int64_t(y) * int64_t(that.y)) + - (int64_t(z) * int64_t(that.z)); -} - -static inline int64_t normalised_multiply(int32_t a, int32_t b) -{ - int64_t result; - - result = (int64_t)a * (int64_t)b; - return result >> 14; -} - -void micro3d_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_MAC_DONE: - mac_done_callback(ptr, param); - break; - default: - throw emu_fatalerror("Unknown id in micro3d_state::device_timer"); - } -} - -TIMER_CALLBACK_MEMBER(micro3d_state::mac_done_callback) -{ - m_drmath->set_input_line(AM29000_INTR0, ASSERT_LINE); - m_mac_stat = 0; -} - -WRITE32_MEMBER(micro3d_state::micro3d_mac1_w) -{ - m_vtx_addr = (data & 0x3ffff); - m_sram_w_addr = (data >> 18) & 0xfff; -} - -READ32_MEMBER(micro3d_state::micro3d_mac2_r) -{ - return (m_mac_inst << 1) | m_mac_stat; -} - -WRITE32_MEMBER(micro3d_state::micro3d_mac2_w) -{ - uint32_t cnt = data & 0xff; - uint32_t inst = (data >> 8) & 0x1f; - uint32_t mac_cycles = 1; - - uint32_t mrab11; - uint32_t vtx_addr; - uint32_t sram_r_addr; - uint32_t sram_w_addr; - uint32_t *mac_sram; - - m_mac_stat = BIT(data, 13); - m_mac_inst = inst & 0x7; - m_mrab11 = (data >> 18) & (1 << 11); - m_sram_r_addr = (data >> 18) & 0xfff; - - mrab11 = m_mrab11; - vtx_addr = m_vtx_addr; - sram_r_addr = m_sram_r_addr; - sram_w_addr = m_sram_w_addr; - mac_sram = m_mac_sram; - - if (data & (1 << 14)) - m_drmath->set_input_line(AM29000_INTR0, CLEAR_LINE); - - switch (inst) - { - case 0x00: break; - case 0x04: break; - - case 0x0b: cnt += 0x100; - case 0x0a: cnt += 0x100; - case 0x09: cnt += 0x100; - case 0x08: - { - int i; - const uint16_t *rom = (uint16_t*)m_vertex->base(); - - for (i = 0; i <= cnt; ++i) - { - int64_t acc; - micro3d_vtx v1; - - v1.x = VTXROM_FMT(rom[vtx_addr]); vtx_addr++; - v1.y = VTXROM_FMT(rom[vtx_addr]); vtx_addr++; - v1.z = VTXROM_FMT(rom[vtx_addr]); vtx_addr++; - - acc = normalised_multiply(mac_sram[mrab11 + 0x7f0], v1.x); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f1], v1.y); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f2], v1.z); - acc += mac_sram[mrab11 + 0x7f3]; - mac_sram[sram_w_addr++] = acc; - - acc = normalised_multiply(mac_sram[mrab11 + 0x7f4], v1.x); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f5], v1.y); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f6], v1.z); - acc += mac_sram[mrab11 + 0x7f7]; - mac_sram[sram_w_addr++] = acc; - - acc = normalised_multiply(mac_sram[mrab11 + 0x7f8], v1.x); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f9], v1.y); - acc += normalised_multiply(mac_sram[mrab11 + 0x7fa], v1.z); - acc += mac_sram[mrab11 + 0x7fb]; - mac_sram[sram_w_addr++] = acc; - - mac_cycles = 16 * cnt; - } - - break; - } - case 0x0e: cnt += 0x100; - case 0x0d: cnt += 0x100; - case 0x0c: - { - int i; - const uint16_t *rom = (uint16_t*)m_vertex->base(); - - for (i = 0; i <= cnt; ++i) - { - int64_t acc; - micro3d_vtx v1; - - v1.x = VTXROM_FMT(rom[vtx_addr]); vtx_addr++; - v1.y = VTXROM_FMT(rom[vtx_addr]); vtx_addr++; - v1.z = VTXROM_FMT(rom[vtx_addr]); vtx_addr++; - - acc = normalised_multiply(mac_sram[mrab11 + 0x7f0], v1.x); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f1], v1.y); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f2], v1.z); - mac_sram[sram_w_addr++] = acc; - - acc = normalised_multiply(mac_sram[mrab11 + 0x7f4], v1.x); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f5], v1.y); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f6], v1.z); - mac_sram[sram_w_addr++] = acc; - - acc = normalised_multiply(mac_sram[mrab11 + 0x7f8], v1.x); - acc += normalised_multiply(mac_sram[mrab11 + 0x7f9], v1.y); - acc += normalised_multiply(mac_sram[mrab11 + 0x7fa], v1.z); - mac_sram[sram_w_addr++] = acc; - - mac_cycles = 12 * cnt; - } - break; - } - case 0x0f: - { - int i; - const uint16_t *rom = (uint16_t*)m_vertex->base(); - - for (i = 0; i <= cnt; ++i, vtx_addr += 4) - { - mac_sram[sram_w_addr++] = VTXROM_FMT(rom[vtx_addr + 0]); - mac_sram[sram_w_addr++] = VTXROM_FMT(rom[vtx_addr + 1]); - mac_sram[sram_w_addr++] = VTXROM_FMT(rom[vtx_addr + 2]); - mac_sram[sram_w_addr++] = VTXROM_FMT(rom[vtx_addr + 3]); - } - - mac_cycles = 8 * cnt; - break; - } - /* Dot product of SRAM vectors with single SRAM vector */ - case 0x11: cnt += 0x100; - case 0x10: - { - micro3d_vtx v2; - v2.x = mac_sram[mrab11 + 0x7fc]; - v2.y = mac_sram[mrab11 + 0x7fd]; - v2.z = mac_sram[mrab11 + 0x7fe]; - - for (int i = 0; i <= cnt; ++i) - { - micro3d_vtx v1; - v1.x = mac_sram[sram_r_addr++]; - v1.y = mac_sram[sram_r_addr++]; - v1.z = mac_sram[sram_r_addr++]; - - int64_t const dp = v1.dot_product(v2); - mac_sram[sram_w_addr++] = dp >> 32; - mac_sram[sram_w_addr++] = dp & 0xffffffff; - mac_sram[sram_w_addr++] = 0; - } - - mac_cycles = 10 * cnt; - break; - } - /* Dot product of SRAM vectors with SRAM vectors */ - case 0x16: cnt += 0x100; - case 0x15: cnt += 0x100; - case 0x14: - { - for (int i = 0; i <= cnt; ++i) - { - micro3d_vtx v1; - v1.x = mac_sram[sram_r_addr++]; - v1.y = mac_sram[sram_r_addr++]; - v1.z = mac_sram[sram_r_addr++]; - - micro3d_vtx v2; - v2.x = mac_sram[vtx_addr++]; - v2.y = mac_sram[vtx_addr++]; - v2.z = mac_sram[vtx_addr++]; - - int64_t const dp = v1.dot_product(v2); - mac_sram[sram_w_addr++] = dp >> 32; - mac_sram[sram_w_addr++] = dp & 0xffffffff; - mac_sram[sram_w_addr++] = 0; - } - - mac_cycles = 10 * cnt; - break; - } - default: - logerror("Unknown MAC instruction : %x\n", inst); - break; - } - - /* TODO: Calculate a better estimate for timing */ - if (m_mac_stat) - timer_set(attotime::from_hz(MAC_CLK) * mac_cycles, TIMER_MAC_DONE); - - m_mrab11 = mrab11; - m_vtx_addr = vtx_addr; - m_sram_r_addr = sram_r_addr; - m_sram_w_addr = sram_w_addr; -} - - -/************************************* - * - * Analog controls - * - *************************************/ - -READ16_MEMBER(micro3d_state::micro3d_encoder_h_r) -{ - uint16_t x_encoder = m_joystick_x.read_safe(0); - uint16_t y_encoder = m_joystick_y.read_safe(0); - - return (y_encoder & 0xf00) | ((x_encoder & 0xf00) >> 8); -} - -READ16_MEMBER(micro3d_state::micro3d_encoder_l_r) -{ - uint16_t x_encoder = m_joystick_x.read_safe(0); - uint16_t y_encoder = m_joystick_y.read_safe(0); - - return ((y_encoder & 0xff) << 8) | (x_encoder & 0xff); -} - -READ8_MEMBER( micro3d_state::adc_volume_r ) -{ - return (uint8_t)((255.0/100.0) * m_volume->read() + 0.5); -} - -READ_LINE_MEMBER(micro3d_state::botss_hwchk_r) -{ - return m_botss_latch; -} - -READ16_MEMBER(micro3d_state::botss_140000_r) -{ - m_botss_latch = 0; - return 0xffff; -} - -READ16_MEMBER(micro3d_state::botss_180000_r) -{ - m_botss_latch = 1; - return 0xffff; -} - -/************************************* - * - * CPU control - * - *************************************/ - -WRITE16_MEMBER(micro3d_state::micro3d_reset_w) -{ - data >>= 8; - m_drmath->set_input_line(INPUT_LINE_RESET, data & 1 ? CLEAR_LINE : ASSERT_LINE); - m_vgb->set_input_line(INPUT_LINE_RESET, data & 2 ? CLEAR_LINE : ASSERT_LINE); - /* TODO: Joystick reset? */ -} - -WRITE16_MEMBER(micro3d_state::host_drmath_int_w) -{ - m_drmath->set_input_line(AM29000_INTR2, ASSERT_LINE); - machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(10)); -} - - -/************************************* - * - * - * - *************************************/ - -WRITE32_MEMBER(micro3d_state::micro3d_shared_w) -{ - m_shared_ram[offset * 2 + 1] = data & 0xffff; - m_shared_ram[offset * 2 + 0] = data >> 16; -} - -READ32_MEMBER(micro3d_state::micro3d_shared_r) -{ - return (m_shared_ram[offset * 2] << 16) | m_shared_ram[offset * 2 + 1]; -} - -WRITE32_MEMBER(micro3d_state::drmath_int_w) -{ - m_maincpu->set_input_line(5, HOLD_LINE); -} - -WRITE32_MEMBER(micro3d_state::drmath_intr2_ack) -{ - m_drmath->set_input_line(AM29000_INTR2, CLEAR_LINE); -} - - -/*************************************************************************** - - 8031 port mappings: - - Port 1 Port 2 - ======= ====== - 0: S/H sel A (O) 0: - 1: S/H sel B (O) 1: - 2: S/H sel C (O) 2: uPD bank select (O) - 3: S/H en (O) 3: /uPD busy (I) - 4: DS1267 data (O) 4: /uPD reset (O) - 5: DS1267 clock (O) 5: Watchdog reset (O) - 6: /DS1267 reset (O) 6: - 7: Test SW (I) 7: - -***************************************************************************/ - - -WRITE8_MEMBER(micro3d_state::micro3d_snd_dac_a) -{ - m_noise_1->dac_w(data); - m_noise_2->dac_w(data); -} - -WRITE8_MEMBER(micro3d_state::micro3d_snd_dac_b) -{ - /* TODO: This controls upd7759 volume */ -} - -WRITE8_MEMBER(micro3d_state::micro3d_sound_p1_w) -{ - m_sound_port_latch[1] = data; - - micro3d_sound_device *noise = (data & 4) ? m_noise_2 : m_noise_1; - noise->noise_sh_w(data); -} - -WRITE8_MEMBER(micro3d_state::micro3d_sound_p3_w) -{ - m_sound_port_latch[3] = data; - - m_upd7759->set_rom_bank(BIT(data, 2)); - m_upd7759->reset_w(!BIT(data, 4)); -} - -READ8_MEMBER(micro3d_state::micro3d_sound_p1_r) -{ - return (m_sound_port_latch[1] & 0x7f) | m_sound_sw->read(); -} - -READ8_MEMBER(micro3d_state::micro3d_sound_p3_r) -{ - return (m_sound_port_latch[3] & 0xf7) | (m_upd7759->busy_r() ? 0x08 : 0); -} - -WRITE8_MEMBER(micro3d_state::micro3d_upd7759_w) -{ - m_upd7759->port_w(data); - m_upd7759->start_w(0); - m_upd7759->start_w(1); -} - - -/************************************* - * - * Driver initialisation - * - *************************************/ - -void micro3d_state::init_micro3d() -{ - address_space &space = m_drmath->space(AS_DATA); - - /* The Am29000 program seems to rely on RAM from 0x00470000 onwards being - non-zero on a reset, otherwise the 3D object data doesn't get uploaded! */ - space.write_dword(0x00470000, 0xa5a5a5a5); - - /* TODO? BOTSS crashes when starting the final stage because the 68000 - overwrites memory in use by the Am29000. Slowing down the 68000 slightly - avoids this */ - m_maincpu->set_clock_scale(0.945f); -} - -void micro3d_state::init_botss() -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - - /* Required to pass the hardware version check */ - space.install_read_handler(0x140000, 0x140001, read16_delegate(FUNC(micro3d_state::botss_140000_r),this)); - space.install_read_handler(0x180000, 0x180001, read16_delegate(FUNC(micro3d_state::botss_180000_r),this)); - - init_micro3d(); -} - -void micro3d_state::machine_reset() -{ - m_vgb->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - m_drmath->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); -} |