From c1bf2b99cb92ffe8760715e238bbb853bf7a7697 Mon Sep 17 00:00:00 2001 From: Furrtek Date: Thu, 15 Apr 2021 01:09:22 +0200 Subject: Added Konami 007452 multiplier/divider (#7951) * Added 007452 multiplier/divider, fixes rolling mines trajectories in contra * Plugged k007452 in combatsc, flkatck, wecleman --- scripts/target/mame/arcade.lua | 2 + src/mame/drivers/combatsc.cpp | 23 ++-------- src/mame/drivers/contra.cpp | 4 +- src/mame/drivers/flkatck.cpp | 27 ++--------- src/mame/drivers/wecleman.cpp | 18 ++------ src/mame/includes/combatsc.h | 7 ++- src/mame/includes/contra.h | 5 +- src/mame/includes/flkatck.h | 6 +-- src/mame/includes/wecleman.h | 6 +-- src/mame/machine/k007452.cpp | 101 +++++++++++++++++++++++++++++++++++++++++ src/mame/machine/k007452.h | 46 +++++++++++++++++++ 11 files changed, 176 insertions(+), 69 deletions(-) create mode 100644 src/mame/machine/k007452.cpp create mode 100644 src/mame/machine/k007452.h diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index b61d57dee0a..d3c9c290125 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -2558,6 +2558,8 @@ files { MAME_DIR .. "src/mame/machine/k573msu.h", MAME_DIR .. "src/mame/machine/k573npu.cpp", MAME_DIR .. "src/mame/machine/k573npu.h", + MAME_DIR .. "src/mame/machine/k007452.cpp", + MAME_DIR .. "src/mame/machine/k007452.h", MAME_DIR .. "src/mame/machine/zs01.cpp", MAME_DIR .. "src/mame/machine/zs01.h", MAME_DIR .. "src/mame/drivers/labyrunr.cpp", diff --git a/src/mame/drivers/combatsc.cpp b/src/mame/drivers/combatsc.cpp index 8e9c21df0fa..d354b057cc3 100644 --- a/src/mame/drivers/combatsc.cpp +++ b/src/mame/drivers/combatsc.cpp @@ -292,21 +292,6 @@ uint8_t combatsc_state::trackball_r(offs_t offset) } -/* the protection is a simple multiply */ -void combatsc_state::protection_w(offs_t offset, uint8_t data) -{ - m_prot[offset] = data; -} -uint8_t combatsc_state::protection_r(offs_t offset) -{ - return ((m_prot[0] * m_prot[1]) >> (offset * 8)) & 0xff; -} -void combatsc_state::protection_clock_w(uint8_t data) -{ - /* 0x3f is written here every time before accessing the other registers */ -} - - /****************************************************************************/ void combatsc_state::combatsc_sh_irqtrigger_w(uint8_t data) @@ -353,8 +338,7 @@ void combatsc_state::combatsc_map(address_map &map) map(0x0020, 0x005f).rw(FUNC(combatsc_state::combatsc_scrollram_r), FUNC(combatsc_state::combatsc_scrollram_w)); // map(0x0060, 0x00ff).writeonly(); /* RAM */ - map(0x0200, 0x0201).rw(FUNC(combatsc_state::protection_r), FUNC(combatsc_state::protection_w)); - map(0x0206, 0x0206).w(FUNC(combatsc_state::protection_clock_w)); + map(0x0200, 0x0207).rw("k007452", FUNC(k007452_device::read), FUNC(k007452_device::write)); map(0x0400, 0x0400).portr("IN0"); map(0x0401, 0x0401).portr("DSW3"); /* DSW #3 */ @@ -660,7 +644,6 @@ MACHINE_START_MEMBER(combatsc_state,combatsc) save_item(NAME(m_bank_select)); save_item(NAME(m_video_circuit)); save_item(NAME(m_boost)); - save_item(NAME(m_prot)); save_item(NAME(m_pos)); save_item(NAME(m_sign)); save_pointer(NAME(m_page[0]),0x2000); @@ -684,8 +667,6 @@ void combatsc_state::machine_reset() m_vreg = -1; m_boost = 1; m_bank_select = -1; - m_prot[0] = 0; - m_prot[1] = 0; for (int i = 0; i < 4; i++) { @@ -713,6 +694,8 @@ void combatsc_state::combatsc(machine_config &config) WATCHDOG_TIMER(config, "watchdog"); + KONAMI_007452_MATH(config, "k007452"); + /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // m_screen->set_refresh_hz(60); diff --git a/src/mame/drivers/contra.cpp b/src/mame/drivers/contra.cpp index 79379fc66ab..6214f6392f6 100644 --- a/src/mame/drivers/contra.cpp +++ b/src/mame/drivers/contra.cpp @@ -25,6 +25,7 @@ Dip locations and factory settings verified with manual #include "cpu/m6809/hd6309.h" #include "cpu/m6809/m6809.h" #include "machine/gen_latch.h" +#include "machine/k007452.h" #include "sound/ym2151.h" #include "speaker.h" @@ -59,10 +60,10 @@ void contra_state::contra_coin_counter_w(uint8_t data) machine().bookkeeping().coin_counter_w(1, (data & 0x02) >> 1); } - void contra_state::contra_map(address_map &map) { map(0x0000, 0x0007).w(FUNC(contra_state::contra_K007121_ctrl_0_w)); + map(0x0008, 0x000f).rw("k007452", FUNC(k007452_device::read), FUNC(k007452_device::write)); map(0x0010, 0x0010).portr("SYSTEM"); map(0x0011, 0x0011).portr("P1"); map(0x0012, 0x0012).portr("P2"); @@ -217,6 +218,7 @@ void contra_state::contra(machine_config &config) config.set_maximum_quantum(attotime::from_hz(6000)); /* enough for the sound CPU to read all commands */ + KONAMI_007452_MATH(config, "k007452"); /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); diff --git a/src/mame/drivers/flkatck.cpp b/src/mame/drivers/flkatck.cpp index 1268a2c4317..bba5e533fdc 100644 --- a/src/mame/drivers/flkatck.cpp +++ b/src/mame/drivers/flkatck.cpp @@ -7,9 +7,6 @@ Driver by: Manuel Abadia - TO DO: - -What does 0x900X do? (Z80) - NOTE: There is known to exist a USA version of Flak Attack - currently not dumped 24MHz & 3.579545MHz OSCs @@ -22,6 +19,7 @@ NOTE: There is known to exist a USA version of Flak Attack - currently not dumpe #include "cpu/z80/z80.h" #include "cpu/m6809/hd6309.h" +#include "machine/k007452.h" #include "sound/ym2151.h" #include "screen.h" #include "speaker.h" @@ -84,18 +82,6 @@ void flkatck_state::flkatck_ls138_w(offs_t offset, uint8_t data) } } -/* Protection - an external multiplier connected to the sound CPU */ -uint8_t flkatck_state::multiply_r() -{ - return (m_multiply_reg[0] * m_multiply_reg[1]) & 0xff; -} - -void flkatck_state::multiply_w(offs_t offset, uint8_t data) -{ - m_multiply_reg[offset] = data; -} - - void flkatck_state::flkatck_map(address_map &map) { map(0x0000, 0x0007).ram().w(FUNC(flkatck_state::flkatck_k007121_regs_w)); /* 007121 registers */ @@ -113,11 +99,7 @@ void flkatck_state::flkatck_sound_map(address_map &map) { map(0x0000, 0x7fff).rom(); /* ROM */ map(0x8000, 0x87ff).ram(); /* RAM */ - map(0x9000, 0x9000).r(FUNC(flkatck_state::multiply_r)); // 007452: Protection (see wecleman, but unused here?) - map(0x9001, 0x9001).nopr(); // 007452: ? - map(0x9000, 0x9001).w(FUNC(flkatck_state::multiply_w)); // 007452: Protection (see wecleman, but unused here?) - map(0x9004, 0x9004).nopr(); // 007452: ? - map(0x9006, 0x9006).nopw(); // 007452: ? + map(0x9000, 0x9007).rw("k007452", FUNC(k007452_device::read), FUNC(k007452_device::write)); // Protection (see wecleman, but unused here?) map(0xa000, 0xa000).r(m_soundlatch, FUNC(generic_latch_8_device::read)); map(0xb000, 0xb00d).rw(m_k007232, FUNC(k007232_device::read), FUNC(k007232_device::write)); /* 007232 registers */ map(0xc000, 0xc001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write)); /* YM2151 */ @@ -201,7 +183,6 @@ void flkatck_state::machine_start() membank("bank1")->configure_entries(0, 3, &ROM[0x10000], 0x2000); save_item(NAME(m_irq_enabled)); - save_item(NAME(m_multiply_reg)); save_item(NAME(m_flipscreen)); } @@ -210,8 +191,6 @@ void flkatck_state::machine_reset() m_k007232->set_bank(0, 1); m_irq_enabled = 0; - m_multiply_reg[0] = 0; - m_multiply_reg[1] = 0; m_flipscreen = 0; } @@ -228,6 +207,8 @@ void flkatck_state::flkatck(machine_config &config) config.set_maximum_quantum(attotime::from_hz(600)); WATCHDOG_TIMER(config, m_watchdog); + + KONAMI_007452_MATH(config, "k007452"); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); diff --git a/src/mame/drivers/wecleman.cpp b/src/mame/drivers/wecleman.cpp index 65118646066..634585520c0 100644 --- a/src/mame/drivers/wecleman.cpp +++ b/src/mame/drivers/wecleman.cpp @@ -278,6 +278,7 @@ TODO: #include "cpu/z80/z80.h" #include "machine/adc0804.h" #include "machine/gen_latch.h" +#include "machine/k007452.h" #include "sound/ym2151.h" #include "speaker.h" @@ -608,17 +609,6 @@ void hotchase_state::hotchase_sub_map(address_map &map) WEC Le Mans 24 Sound CPU Handlers ***************************************************************************/ -/* Protection - an external multiplier connected to the sound CPU */ -uint8_t wecleman_state::multiply_r() -{ - return (m_multiply_reg[0] * m_multiply_reg[1]) & 0xFF; -} - -void wecleman_state::multiply_w(offs_t offset, uint8_t data) -{ - m_multiply_reg[offset] = data; -} - /* K007232 registers reminder: [Ch A] [Ch B] [Meaning] @@ -651,9 +641,7 @@ void wecleman_state::wecleman_sound_map(address_map &map) map(0x0000, 0x7fff).rom(); map(0x8000, 0x83ff).ram(); map(0x8500, 0x8500).nopw(); // increased with speed (global volume)? - map(0x9000, 0x9000).r(FUNC(wecleman_state::multiply_r)); // 007452: Protection - map(0x9000, 0x9001).w(FUNC(wecleman_state::multiply_w)); // 007452: Protection - map(0x9006, 0x9006).nopw(); // 007452: ? + map(0x9000, 0x9007).rw("k007452", FUNC(k007452_device::read), FUNC(k007452_device::write)); // Protection map(0xa000, 0xa000).r("soundlatch", FUNC(generic_latch_8_device::read)); // From main CPU map(0xb000, 0xb00d).rw("k007232_1", FUNC(k007232_device::read), FUNC(k007232_device::write)); // K007232 (Reading offset 5/b triggers the sample) map(0xc000, 0xc001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write)); @@ -1068,6 +1056,8 @@ void wecleman_state::wecleman(machine_config &config) adc0804_device &adc(ADC0804(config, "adc", 640000)); // unknown "ADCCLK" (generated on video board?) adc.vin_callback().set(FUNC(wecleman_state::selected_ip_r)); + KONAMI_007452_MATH(config, "k007452"); + /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); diff --git a/src/mame/includes/combatsc.h b/src/mame/includes/combatsc.h index 0f4ac2db76c..6cd256c1454 100644 --- a/src/mame/includes/combatsc.h +++ b/src/mame/includes/combatsc.h @@ -14,6 +14,7 @@ #include "sound/upd7759.h" #include "sound/msm5205.h" #include "video/k007121.h" +#include "machine/k007452.h" #include "emupal.h" #include "screen.h" #include "tilemap.h" @@ -27,6 +28,7 @@ public: m_audiocpu(*this, "audiocpu"), m_k007121_1(*this, "k007121_1"), m_k007121_2(*this, "k007121_2"), + m_k007452(*this, "k007452"), m_upd7759(*this, "upd"), m_msm(*this, "msm"), m_screen(*this, "screen"), @@ -59,7 +61,6 @@ public: /* misc */ uint8_t m_pos[4]; uint8_t m_sign[4]; - int m_prot[2]; int m_boost; emu_timer *m_interleave_timer; @@ -69,6 +70,7 @@ public: required_device m_audiocpu; optional_device m_k007121_1; optional_device m_k007121_2; + optional_device m_k007452; optional_device m_upd7759; optional_device m_msm; required_device m_screen; @@ -86,10 +88,7 @@ public: void combatscb_bankselect_w(address_space &space, uint8_t data); void combatsc_coin_counter_w(uint8_t data); uint8_t trackball_r(offs_t offset); - void protection_w(offs_t offset, uint8_t data); - uint8_t protection_r(offs_t offset); uint8_t unk_r(); - void protection_clock_w(uint8_t data); void combatsc_sh_irqtrigger_w(uint8_t data); uint8_t combatsc_video_r(offs_t offset); void combatsc_video_w(offs_t offset, uint8_t data); diff --git a/src/mame/includes/contra.h b/src/mame/includes/contra.h index 5ec2cde2f89..b29c52bff00 100644 --- a/src/mame/includes/contra.h +++ b/src/mame/includes/contra.h @@ -11,6 +11,7 @@ #pragma once #include "video/k007121.h" +#include "machine/k007452.h" #include "emupal.h" #include "screen.h" #include "tilemap.h" @@ -31,12 +32,13 @@ public: m_audiocpu(*this, "audiocpu"), m_k007121_1(*this, "k007121_1"), m_k007121_2(*this, "k007121_2"), + m_k007452(*this, "k007452"), m_maincpu(*this, "maincpu"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette") { } - + /* memory pointers */ std::unique_ptr m_buffered_spriteram; std::unique_ptr m_buffered_spriteram_2; @@ -61,6 +63,7 @@ public: required_device m_audiocpu; required_device m_k007121_1; required_device m_k007121_2; + required_device m_k007452; void contra_bankswitch_w(uint8_t data); void contra_sh_irqtrigger_w(uint8_t data); void sirq_clear_w(uint8_t data); diff --git a/src/mame/includes/flkatck.h b/src/mame/includes/flkatck.h index ead8d0fbea1..4f2d01a8516 100644 --- a/src/mame/includes/flkatck.h +++ b/src/mame/includes/flkatck.h @@ -12,6 +12,7 @@ #include "machine/gen_latch.h" #include "machine/watchdog.h" +#include "machine/k007452.h" #include "sound/k007232.h" #include "video/k007121.h" #include "tilemap.h" @@ -27,6 +28,7 @@ public: m_audiocpu(*this, "audiocpu"), m_k007121(*this, "k007121"), m_k007232(*this, "k007232"), + m_k007452(*this, "k007452"), m_watchdog(*this, "watchdog"), m_gfxdecode(*this, "gfxdecode"), m_soundlatch(*this, "soundlatch") @@ -45,13 +47,13 @@ private: /* misc */ int m_irq_enabled; - int m_multiply_reg[2]; /* devices */ required_device m_maincpu; required_device m_audiocpu; required_device m_k007121; required_device m_k007232; + required_device m_k007452; required_device m_watchdog; required_device m_gfxdecode; required_device m_soundlatch; @@ -59,8 +61,6 @@ private: void flkatck_bankswitch_w(uint8_t data); uint8_t flkatck_ls138_r(offs_t offset); void flkatck_ls138_w(offs_t offset, uint8_t data); - uint8_t multiply_r(); - void multiply_w(offs_t offset, uint8_t data); void vram_w(offs_t offset, uint8_t data); void flkatck_k007121_regs_w(offs_t offset, uint8_t data); TILE_GET_INFO_MEMBER(get_tile_info_A); diff --git a/src/mame/includes/wecleman.h b/src/mame/includes/wecleman.h index fd2070bc679..6b067ec34db 100644 --- a/src/mame/includes/wecleman.h +++ b/src/mame/includes/wecleman.h @@ -8,6 +8,7 @@ #include "machine/timer.h" #include "sound/k007232.h" #include "video/k051316.h" +#include "machine/k007452.h" #include "emupal.h" #include "screen.h" #include "tilemap.h" @@ -31,6 +32,7 @@ public: , m_subcpu(*this, "sub") , m_k051316(*this, "k051316_%u", 1) , m_k007232(*this, "k007232_%u", 1) + , m_k007452(*this, "k007452") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") , m_screen(*this, "screen") @@ -65,7 +67,6 @@ protected: required_region_ptr m_sprite_region; - int m_multiply_reg[2]; int m_spr_color_offs; int m_prot_state; int m_selected_ip; @@ -97,8 +98,6 @@ protected: void selected_ip_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); uint8_t selected_ip_r(); void blitter_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint8_t multiply_r(); - void multiply_w(offs_t offset, uint8_t data); void wecleman_txtram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void wecleman_pageram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); @@ -125,6 +124,7 @@ protected: required_device m_subcpu; optional_device_array m_k051316; optional_device_array m_k007232; + optional_device m_k007452; required_device m_gfxdecode; required_device m_palette; required_device m_screen; diff --git a/src/mame/machine/k007452.cpp b/src/mame/machine/k007452.cpp new file mode 100644 index 00000000000..3f6a3202d61 --- /dev/null +++ b/src/mame/machine/k007452.cpp @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Sean Gonsalves +/*************************************************************************** + + Konami 007452 multiplier/divider + +***************************************************************************/ + +#include "emu.h" +#include "k007452.h" + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(KONAMI_007452_MATH, k007452_device, "konami_007452", "Konami 007452 math chip") + +//------------------------------------------------- +// k007452_device - constructor +//------------------------------------------------- + +k007452_device::k007452_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, KONAMI_007452_MATH, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// read - read the registers +//------------------------------------------------- + +uint8_t k007452_device::read(offs_t offset) +{ + switch (offset & 7) + { + case 0: return m_multiply_result & 0xff; + case 1: return (m_multiply_result >> 8) & 0xff; + case 2: return m_divide_remainder & 0xff; + case 3: return (m_divide_remainder >> 8) & 0xff; + case 4: return m_divide_quotient & 0xff; + case 5: return (m_divide_quotient >> 8) & 0xff; + default: return 0; + } +} + + +//------------------------------------------------- +// write - write to the registers +//------------------------------------------------- + +void k007452_device::write(offs_t offset, u8 data) +{ + if (offset < 6) m_math_regs[offset] = data; + + if (offset == 1) + { + // Starts multiplication process + m_multiply_result = m_math_regs[0] * m_math_regs[1]; + } + else if (offset == 5) + { + // Starts division process + u16 dividend = (m_math_regs[4]<<8) + m_math_regs[5]; + u16 divisor = (m_math_regs[2]<<8) + m_math_regs[3]; + if (!divisor) { + m_divide_quotient = 0xffff; + m_divide_remainder = 0x0000; + } else { + m_divide_quotient = dividend / divisor; + m_divide_remainder = dividend % divisor; + } + } +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void k007452_device::device_start() +{ + save_item(NAME(m_math_regs)); + save_item(NAME(m_multiply_result)); + save_item(NAME(m_divide_quotient)); + save_item(NAME(m_divide_remainder)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void k007452_device::device_reset() +{ + std::fill(std::begin(m_math_regs), std::end(m_math_regs), 0); + m_multiply_result = 0; + m_divide_quotient = 0; + m_divide_remainder = 0; +} + diff --git a/src/mame/machine/k007452.h b/src/mame/machine/k007452.h new file mode 100644 index 00000000000..a5eccb8f794 --- /dev/null +++ b/src/mame/machine/k007452.h @@ -0,0 +1,46 @@ +// license:BSD-3-Clause +// copyright-holders:Sean Gonsalves +/*************************************************************************** + + Konami 007452 multiplier/divider + +***************************************************************************/ + +#ifndef MAME_MACHINE_K007452_H +#define MAME_MACHINE_K007452_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class k007452_device : public device_t +{ +public: + // construction/destruction + k007452_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // public interface + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + // internal state + u32 m_math_regs[6]; + u16 m_multiply_result; + u16 m_divide_quotient; + u16 m_divide_remainder; +}; + +// device type definition +DECLARE_DEVICE_TYPE(KONAMI_007452_MATH, k007452_device) + + +#endif // MAME_MACHINE_K007452_H -- cgit v1.2.3