Permalink
Browse files

es5510, taito_en Updates (#3284)

* es5510.* Updates :
Add notes
Fix dram read/write
Convert gpr, instr, dram into std::unique_ptr
Add save states
Minor cleanup

taito_en.* Updates :
Add notes
Move imperfect_features() into es5510.h
Verify ESP Input clock/output channels(from GunBuster Schematics, same in other PCBs?)
Add m_bankmask instead runtime tag lookups

* es5510.h : Add notes

* es5510.h : Fix compile

* es5510.h : Compile fixes

* esqpump.cpp : Split ES5506 case of interface, Add imperfect_features Because it has not perfectly emulated
esqasr.cpp, esqkt.cpp : Add esqpump for es5510 interface
taito_en.h : Restore imperfect_features Because sound emulation has still not perfect

* es5510.h : Moved imperfect_feature into esqpump.h from this, Add notes

* Revert "Moved imperfect_feature into esqpump.h from this", Because the current ES5510 core still has emulation issue

* esqpump.cpp : Cleanup unused m_otis/m_otto, Convert e[0x4000] into std::unique_ptr if used

* Fix compile

* esqkt.cpp : Fix company tags
  • Loading branch information...
cam900 authored and rb6502 committed Mar 3, 2018
1 parent 6569aff commit 25472091b626bd01ef47f11389a4b2ebe0fc0008
@@ -1,11 +1,15 @@
// license:BSD-3-Clause
// copyright-holders:Christian Brunschen
/***************************************************************************
/***************************************************************************************
*
* es5510.c - Ensoniq ES5510 (ESP) emulation
* by Christian Brunschen
*
***************************************************************************/
* TODO
* ridingf, ringrage and clones: Exception after logo is displayed (MT #06894)
* DRAM Size isn't verified, differs per machines?
*
***************************************************************************************/
#include "emu.h"
#include "es5510.h"
@@ -15,7 +19,7 @@
#include "debugger.h"
#include <cstdio>
#include <algorithm>
static constexpr int32_t MIN_24 = -(1 << 23);
static constexpr int32_t MAX_24 = (1 << 23) - 1;
@@ -126,52 +130,48 @@ inline static int32_t asl(int32_t value, int shift, uint8_t &flags) {
return saturate(result, flags, signBefore != 0);
}
// Initialize ESP to mostly zeroed, configured for 64k samples of delay line memory, running (not halted)
es5510_device::es5510_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, ES5510, tag, owner, clock)
, icount(0)
, halt_asserted(false)
, pc(0)
, state(STATE_HALTED)
, gpr(nullptr)
, ser0r(0)
, ser0l(0)
, ser1r(0)
, ser1l(0)
, ser2r(0)
, ser2l(0)
, ser3r(0)
, ser3l(0)
, machl(0)
, dil(0)
, memsiz(0x00ffffff)
, memmask(0x00000000)
, memincrement(0x01000000)
, memshift(24)
, dlength(0)
, abase(0)
, bbase(0)
, dbase(0)
, sigreg(1)
, mulshift(1)
, ccr(0)
, cmr(0)
, dol_count(0)
, instr(nullptr)
, dram(nullptr)
, dol_latch(0)
, dil_latch(0)
, dadr_latch(0)
, gpr_latch(0)
, instr_latch(0)
, ram_sel(0)
, host_control(0)
{
// Initialize ESP to mostly zeroed, configured for 64k samples of delay line memory, running (not halted)
halt_asserted = false;
icount = 0;
pc = 0;
state = STATE_HALTED;
memset(gpr, 0, 0xc0 * sizeof(gpr[0]));
ser0r = 0;
ser0l = 0;
ser1r = 0;
ser1l = 0;
ser2r = 0;
ser2l = 0;
ser3r = 0;
ser3l = 0;
machl = 0;
dil = 0;
memsiz = 0x00ffffff;
memmask = 0x00000000;
memincrement = 0x01000000;
memshift = 24;
dlength = 0;
abase = 0;
bbase = 0;
dbase = 0;
sigreg = 1;
mulshift = 1;
ccr = 0;
cmr = 0;
dol[0] = dol[1] = 0;
dol_count = 0;
memset(instr, 0, 160 * sizeof(instr[0]));
memset(dram, 0, (1<<20) * sizeof(dram[0]));
dol_latch = 0;
dil_latch = 0;
dadr_latch = 0;
gpr_latch = 0;
instr_latch = 0;
ram_sel = 0;
host_control = 0;
pc = 0;
memset(&alu, 0, sizeof(alu));
memset(&mulacc, 0, sizeof(mulacc));
}
@@ -439,11 +439,11 @@ WRITE8_MEMBER(es5510_device::host_w)
dadr_latch = (dadr_latch&0x00ffff) | ((data&0xff)<<16);
if (ram_sel)
{
dil_latch = dram[dadr_latch] << 8;
dil_latch = dram_r(dadr_latch) << 8;
}
else
{
dram[dadr_latch] = dol_latch >> 8;
dram_w(dadr_latch, dol_latch >> 8);
}
break;
@@ -550,16 +550,87 @@ void es5510_device::ser_w(int offset, int16_t data)
}
void es5510_device::device_start() {
gpr = std::make_unique<int32_t[]>(0xc0); // 24 bits, right justified
instr = std::make_unique<uint64_t[]>(160); // 48 bits, right justified
dram = std::make_unique<int16_t[]>(DRAM_SIZE); // there are up to 20 address bits (at least 16 expected), left justified within the 24 bits of a gpr or dadr; we preallocate all of it.
m_icountptr = &icount;
state_add(STATE_GENPC,"GENPC", pc).noshow();
state_add(STATE_GENPCBASE, "CURPC", pc).noshow();
save_item(NAME(icount));
save_item(NAME(halt_asserted));
save_item(NAME(pc));
save_item(NAME(ser0r));
save_item(NAME(ser0l));
save_item(NAME(ser1r));
save_item(NAME(ser1l));
save_item(NAME(ser2r));
save_item(NAME(ser2l));
save_item(NAME(ser3r));
save_item(NAME(ser3l));
save_item(NAME(machl));
save_item(NAME(mac_overflow));
save_item(NAME(dil));
save_item(NAME(memsiz));
save_item(NAME(memmask));
save_item(NAME(memincrement));
save_item(NAME(memshift));
save_item(NAME(dlength));
save_item(NAME(abase));
save_item(NAME(bbase));
save_item(NAME(dbase));
save_item(NAME(sigreg));
save_item(NAME(mulshift));
save_item(NAME(ccr));
save_item(NAME(cmr));
save_item(NAME(dol));
save_item(NAME(dol_count));
save_pointer(NAME(gpr.get()), 0xc0);
save_pointer(NAME(instr.get()), 160);
save_pointer(NAME(dram.get()), DRAM_SIZE);
save_item(NAME(dol_latch));
save_item(NAME(dil_latch));
save_item(NAME(dadr_latch));
save_item(NAME(gpr_latch));
save_item(NAME(instr_latch));
save_item(NAME(ram_sel));
save_item(NAME(host_control));
save_item(NAME(alu.aReg));
save_item(NAME(alu.bReg));
save_item(NAME(alu.op));
save_item(NAME(alu.aValue));
save_item(NAME(alu.bValue));
save_item(NAME(alu.result));
save_item(NAME(alu.update_ccr));
save_item(NAME(alu.write_result));
save_item(NAME(mulacc.cReg));
save_item(NAME(mulacc.dReg));
save_item(NAME(mulacc.accumulate));
save_item(NAME(mulacc.cValue));
save_item(NAME(mulacc.dValue));
save_item(NAME(mulacc.product));
save_item(NAME(mulacc.result));
save_item(NAME(mulacc.write_result));
save_item(NAME(ram.address));
save_item(NAME(ram.io));
save_item(NAME(ram_p.address));
save_item(NAME(ram_p.io));
save_item(NAME(ram_pp.address));
save_item(NAME(ram_pp.io));
}
void es5510_device::device_reset() {
pc = 0x00;
memset(gpr, 0, sizeof(*gpr) * 0xc0);
memset(instr, 0, sizeof(*instr) * 0xa0);
memset(dram, 0, sizeof(*dram) * (1<<20));
std::fill(&gpr[0], &gpr[0xc0], 0);
std::fill(&instr[0], &instr[160], 0);
std::fill(&dram[0], &dram[DRAM_SIZE], 0);
state = STATE_RUNNING;
dil_latch = dol_latch = dadr_latch = gpr_latch = 0;
instr_latch = uint64_t(0);
@@ -724,7 +795,7 @@ void es5510_device::execute_run() {
if (ram_pp.io) { // read from I/O and store into DIL
dil = 0; // read_io(ram_pp.address);;
} else { // read from DRAM and store into DIL
dil = dram[ram_pp.address] << 8;
dil = dram_r(ram_pp.address) << 8;
LOG_EXEC((" . RAM: read %x (%d) from address %x\n", dil, dil, ram_pp.address));
}
}
@@ -897,7 +968,7 @@ void es5510_device::execute_run() {
if (ram_p.io) {
// write_io(ram_p.io, dol[0]);
} else {
dram[ram_p.address] = dol[0] >> 8;
dram_w(ram_p.address, dol[0] >> 8);
LOG_EXEC((" . RAM: writing %x (%d) [of %x (%d)] to address %x\n", dol[0]&0xffff00, SX(dol[0]&0xffff00), dol[0], SX(dol[0]), ram_p.address));
}
}
@@ -12,9 +12,13 @@
#pragma once
class es5510_device : public cpu_device {
public:
// TODO : Not verified, Most of games are using 128KB DRAM.
static constexpr uint32_t DRAM_SIZE = (1<<20);
static constexpr uint32_t DRAM_MASK = (DRAM_SIZE-1);
static constexpr feature_type imperfect_features() { return feature::SOUND; }
es5510_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(host_r);
@@ -114,7 +118,7 @@ class es5510_device : public cpu_device {
// for testing purposes
uint64_t &_instr(int pc) { return instr[pc % 160]; }
int16_t &_dram(int addr) { return dram[addr & 0xfffff]; }
int16_t &_dram(int addr) { return dram[addr & DRAM_MASK]; }
// publicly visible for testing purposes
int32_t read_reg(uint8_t reg);
@@ -142,7 +146,7 @@ class es5510_device : public cpu_device {
bool halt_asserted;
uint8_t pc;
state_t state;
int32_t gpr[0xc0]; // 24 bits, right justified
std::unique_ptr<int32_t[]> gpr;
int16_t ser0r;
int16_t ser0l;
int16_t ser1r;
@@ -169,8 +173,12 @@ class es5510_device : public cpu_device {
int32_t dol[2];
int dol_count;
uint64_t instr[160]; // 48 bits, right justified
int16_t dram[1<<20]; // there are up to 20 address bits (at least 16 expected), left justified within the 24 bits of a gpr or dadr; we preallocate all of it.
std::unique_ptr<uint64_t[]> instr;
std::unique_ptr<int16_t[]> dram;
// TODO : Masked address?
int16_t dram_r(int addr) { return dram[addr & DRAM_MASK]; }
void dram_w(int addr, int16_t data) { dram[addr & DRAM_MASK] = data; }
// latch registers for host interaction
int32_t dol_latch; // 24 bits
@@ -2,7 +2,7 @@
// copyright-holders:Christian Brunschen
/***************************************************************************
esqpump.c - Ensoniq 5505/5506 to 5510 interface.
esqpump.cpp - Ensoniq 5505/5506 to 5510 interface.
By Christian Brunschen
@@ -16,9 +16,12 @@ DEFINE_DEVICE_TYPE(ESQ_5505_5510_PUMP, esq_5505_5510_pump_device, "esq_5505_5510
esq_5505_5510_pump_device::esq_5505_5510_pump_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ESQ_5505_5510_PUMP, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, m_stream(nullptr), m_timer(nullptr), m_otis(nullptr), m_esp(nullptr)
, m_stream(nullptr), m_timer(nullptr), m_esp(nullptr)
, m_esp_halted(true), ticks_spent_processing(0), samples_processed(0)
{
#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
e = nullptr;
#endif
}
void esq_5505_5510_pump_device::device_start()
@@ -44,7 +47,7 @@ void esq_5505_5510_pump_device::device_start()
#endif
#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
memset(e, 0, 0x4000 * sizeof(e[0]));
e = make_unique_clear<int16_t[]>(0x4000);
ei = 0;
#endif
}
@@ -16,9 +16,10 @@
class esq_5505_5510_pump_device : public device_t, public device_sound_interface
{
public:
static constexpr feature_type imperfect_features() { return feature::SOUND; }
esq_5505_5510_pump_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void set_otis(es5505_device *otis) { m_otis = otis; }
void set_esp(es5510_device *esp) { m_esp = esp; }
void set_esp_halted(bool esp_halted) {
m_esp_halted = esp_halted;
@@ -86,9 +87,6 @@ class esq_5505_5510_pump_device : public device_t, public device_sound_interface
// per-sample timer
emu_timer *m_timer;
// OTIS sound generator
es5505_device *m_otis;
// ESP signal processor
es5510_device *m_esp;
@@ -112,7 +110,7 @@ class esq_5505_5510_pump_device : public device_t, public device_sound_interface
#endif
#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
int16_t e[0x4000];
std::unique_ptr<int16_t[]> e;
int ei;
#endif
};
Oops, something went wrong.

1 comment on commit 2547209

@jsjyqz

This comment has been minimized.

Show comment
Hide comment
@jsjyqz

jsjyqz Mar 14, 2018

nice work,hope this issue can be fixed someday

jsjyqz commented on 2547209 Mar 14, 2018

nice work,hope this issue can be fixed someday

Please sign in to comment.