made pla_device more generic

This commit is contained in:
hap 2014-11-14 23:25:53 +01:00
parent b46e9cf0cd
commit 67eaf1c268
8 changed files with 122 additions and 145 deletions

View File

@ -84,7 +84,7 @@ private:
required_device<tpi6525_device> m_tpi0;
required_device<tpi6525_device> m_tpi1;
required_device<c64h156_device> m_ga;
required_device<pls100_device> m_pla;
required_device<pla_device> m_pla;
required_device<floppy_image_device> m_floppy;
required_device<plus4_expansion_slot_device> m_exp;
required_ioport m_jp1;

View File

@ -2,7 +2,7 @@
// copyright-holders:Curt Coder
/**********************************************************************
PLS100 16x48x8 Programmable Logic Array emulation
PLA (Programmable Logic Array) emulation
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
@ -10,43 +10,23 @@
**********************************************************************/
#include "pla.h"
#include "jedparse.h"
#include "plaparse.h"
//**************************************************************************
// DEVICE TYPE DEFINITIONS
//**************************************************************************
const device_type PLS100 = &device_creator<pls100_device>;
const device_type MOS8721 = &device_creator<mos8721_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
const device_type PLA = &device_creator<pla_device>;
//-------------------------------------------------
// pla_device - constructor
//-------------------------------------------------
pla_device::pla_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int inputs, int outputs, int terms, UINT32 input_mask, const char *shortname, const char *source) :
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
m_inputs(inputs),
m_outputs(outputs),
m_terms(terms),
m_input_mask(((UINT64)input_mask << 32) | input_mask)
{
}
pls100_device::pls100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
pla_device(mconfig, PLS100, "PLS100", tag, owner, clock, 16, 8, 48, 0xffff, "pls100", __FILE__),
m_output(*this, "output")
{
}
mos8721_device::mos8721_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
pla_device(mconfig, MOS8721, "MOS8721", tag, owner, clock, 27, 18, 379, 0x7ffffff, "mos8721", __FILE__) // TODO actual number of terms is unknown
pla_device::pla_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, PLA, "PLA", tag, owner, clock, "pla", __FILE__),
m_format(PLA_FMT_JEDBIN),
m_inputs(0),
m_outputs(0),
m_terms(0),
m_input_mask(0)
{
}
@ -57,30 +37,29 @@ mos8721_device::mos8721_device(const machine_config &mconfig, const char *tag, d
void pla_device::device_start()
{
assert(machine().root_device().memregion(tag()) != NULL);
assert(*region() != NULL);
assert(m_terms < MAX_TERMS);
assert(m_inputs <= 32 && m_outputs <= 32);
if (m_input_mask == 0)
m_input_mask = ((UINT64)1 << m_inputs) - 1;
m_input_mask = ((UINT64)m_input_mask << 32) | m_input_mask;
// parse fusemap
parse_fusemap();
// clear cache
for (int i = 0; i < CACHE_SIZE; i++)
{
m_cache[i] = 0;
}
// initialize cache
m_cache2_ptr = 0;
for (int i = 0; i < CACHE2_SIZE; i++)
m_cache2[i] = 0;
m_cache_ptr = 0;
}
void pls100_device::device_start()
{
pla_device::device_start();
m_output.allocate(0x10000);
for (UINT32 input = 0; input < 0x10000; input++)
{
m_output[input] = pla_device::read(input);
}
m_cache_size = 0;
int csize = 1 << ((m_inputs > MAX_CACHE_BITS) ? MAX_CACHE_BITS : m_inputs);
m_cache.resize(csize);
for (int i = 0; i < csize; i++)
m_cache[i] = read(i);
m_cache_size = csize;
}
@ -90,11 +69,25 @@ void pls100_device::device_start()
void pla_device::parse_fusemap()
{
memory_region *region = machine().root_device().memregion(tag());
jed_data jed;
jedbin_parse(region->base(), region->bytes(), &jed);
int result = JEDERR_NONE;
// read pla file
switch (m_format)
{
case PLA_FMT_JEDBIN:
result = jedbin_parse(region()->base(), region()->bytes(), &jed);
break;
case PLA_FMT_BERKELEY:
result = pla_parse(region()->base(), region()->bytes(), &jed);
break;
}
if (result != JEDERR_NONE)
fatalerror("%s PLA parse error %d\n", tag(), result);
// parse it
UINT32 fusenum = 0;
for (int p = 0; p < m_terms; p++)
@ -143,14 +136,17 @@ void pla_device::parse_fusemap()
UINT32 pla_device::read(UINT32 input)
{
// try the cache first
for (int i = 0; i < CACHE_SIZE; ++i)
if (input < m_cache_size)
return m_cache[input];
for (int i = 0; i < CACHE2_SIZE; ++i)
{
UINT64 cache_entry = m_cache[i];
UINT64 cache2_entry = m_cache2[i];
if ((UINT32)cache_entry == input)
if ((UINT32)cache2_entry == input)
{
// cache hit
return cache_entry >> 32;
// cache2 hit
return cache2_entry >> 32;
}
}
@ -170,19 +166,9 @@ UINT32 pla_device::read(UINT32 input)
s ^= m_xor;
// store output in cache
m_cache[m_cache_ptr] = s | input;
++m_cache_ptr &= (CACHE_SIZE - 1);
// store output in cache2
m_cache2[m_cache2_ptr] = s | input;
++m_cache2_ptr &= (CACHE2_SIZE - 1);
return s >> 32;
}
//-------------------------------------------------
// read -
//-------------------------------------------------
UINT32 pls100_device::read(UINT32 input)
{
return m_output[input];
}

View File

@ -2,28 +2,11 @@
// copyright-holders:Curt Coder
/**********************************************************************
PLS100 16x48x8 Programmable Logic Array emulation
PLA (Programmable Logic Array) emulation
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
**********************************************************************
_____ _____
FE 1 |* \_/ | 28 Vcc
I7 2 | | 27 I8
I6 3 | | 26 I9
I5 4 | | 25 I10
I4 5 | | 24 I11
I3 6 | 82S100 | 23 I12
I2 7 | 82S101 | 22 I13
I1 8 | PLS100 | 21 I14
I0 9 | PLS101 | 20 I15
F7 10 | | 19 _CE
F6 11 | | 18 F0
F5 12 | | 17 F1
F4 13 | | 16 F2
GND 14 |_____________| 15 F3
**********************************************************************/
#pragma once
@ -32,7 +15,6 @@
#define __PLA__
#include "emu.h"
#include "jedparse.h"
@ -41,7 +23,14 @@
//**************************************************************************
#define MAX_TERMS 512
#define CACHE_SIZE 8
#define MAX_CACHE_BITS 16
#define CACHE2_SIZE 8
enum
{
PLA_FMT_JEDBIN = 0,
PLA_FMT_BERKELEY
};
@ -49,11 +38,31 @@
// INTERFACE CONFIGURATION MACROS
///*************************************************************************
#define MCFG_PLS100_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, PLS100, 0)
#define MCFG_PLA_ADD(_tag, _inputs, _outputs, _terms) \
MCFG_DEVICE_ADD(_tag, PLA, 0) \
pla_device::set_num_inputs(*device, _inputs); \
pla_device::set_num_outputs(*device, _outputs); \
pla_device::set_num_terms(*device, _terms);
#define MCFG_PLA_INPUTMASK(_mask) \
pla_device::set_inputmask(*device, _mask);
#define MCFG_PLA_FILEFORMAT(_format) \
pla_device::set_format(*device, _format);
// macros for known (and used) devices
// 82S100, 82S101, PLS100, PLS101
// 16x48x8 PLA, 28-pin
#define MCFG_PLS100_ADD(_tag) \
MCFG_PLA_ADD(_tag, 16, 8, 48)
// MOS 8721 PLA
// TODO: actual number of terms is unknown
#define MCFG_MOS8721_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, MOS8721, 0)
MCFG_PLA_ADD(_tag, 27, 18, 379)
///*************************************************************************
@ -62,69 +71,51 @@
// ======================> pla_device
class pla_device : public device_t
class pla_device : public device_t
{
public:
// construction/destruction
pla_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int inputs, int outputs, int terms, UINT32 output_mask, const char *shortname, const char *source);
pla_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual UINT32 read(UINT32 input);
// static configuration helpers
static void set_num_inputs(device_t &device, UINT32 i) { downcast<pla_device &>(device).m_inputs = i; }
static void set_num_outputs(device_t &device, UINT32 o) { downcast<pla_device &>(device).m_outputs = o; }
static void set_num_terms(device_t &device, UINT32 t) { downcast<pla_device &>(device).m_terms = t; }
static void set_inputmask(device_t &device, UINT32 mask) { downcast<pla_device &>(device).m_input_mask = mask; } // UINT32!
static void set_format(device_t &device, int format) { downcast<pla_device &>(device).m_format = format; }
UINT32 read(UINT32 input);
protected:
// device-level overrides
virtual void device_start();
private:
void parse_fusemap();
int m_inputs;
int m_outputs;
int m_terms;
int m_format;
UINT32 m_inputs;
UINT32 m_outputs;
UINT32 m_terms;
UINT64 m_input_mask;
UINT64 m_xor;
int m_cache_size;
dynamic_array<UINT32> m_cache;
UINT64 m_cache2[CACHE2_SIZE];
UINT8 m_cache2_ptr;
struct term
{
UINT64 m_and;
UINT64 m_or;
};
term m_term[MAX_TERMS];
UINT64 m_cache[CACHE_SIZE];
UINT8 m_cache_ptr;
};
// ======================> pls100_device
class pls100_device : public pla_device
{
public:
pls100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// device-level overrides
virtual void device_start();
virtual UINT32 read(UINT32 input);
private:
optional_shared_ptr<UINT8> m_output;
};
// ======================> mos8721_device
class mos8721_device : public pla_device
{
public:
mos8721_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
} m_term[MAX_TERMS];
};
// device type definition
extern const device_type PLS100;
extern const device_type MOS8721;
extern const device_type PLA;
#endif

View File

@ -105,7 +105,7 @@ public:
required_device<cpu_device> m_maincpu;
required_device<m8502_device> m_subcpu;
required_device<mos8722_device> m_mmu;
required_device<mos8721_device> m_pla;
required_device<pla_device> m_pla;
required_device<mos8563_device> m_vdc;
required_device<mos6566_device> m_vic;
required_device<mos6581_device> m_sid;

View File

@ -78,7 +78,7 @@ public:
UINT8 *m_charom;
required_device<m6510_device> m_maincpu;
required_device<pls100_device> m_pla;
required_device<pla_device> m_pla;
required_device<mos6566_device> m_vic;
required_device<mos6581_device> m_sid;
required_device<mos6526_device> m_cia1;

View File

@ -113,7 +113,7 @@ public:
{ }
required_device<cpu_device> m_maincpu;
required_device<pls100_device> m_pla1;
required_device<pla_device> m_pla1;
optional_device<mc6845_device> m_crtc;
optional_device<palette_device> m_palette;
required_device<mos6581_device> m_sid;
@ -274,7 +274,7 @@ public:
m_vic_irq(CLEAR_LINE)
{ }
required_device<pls100_device> m_pla2;
required_device<pla_device> m_pla2;
required_device<mos6566_device> m_vic;
optional_shared_ptr<UINT8> m_color_ram;

View File

@ -259,8 +259,8 @@ public:
required_memory_region m_editor_rom;
required_memory_region m_ue5_rom;
required_memory_region m_ue6_rom;
required_device<pls100_device> m_pla1;
required_device<pls100_device> m_pla2;
required_device<pla_device> m_pla1;
required_device<pla_device> m_pla2;
DECLARE_MACHINE_START( cbm8296 );
DECLARE_MACHINE_RESET( cbm8296 );

View File

@ -31,7 +31,7 @@
#define SCREEN_TAG "screen"
#define CONTROL1_TAG "joy1"
#define CONTROL2_TAG "joy2"
#define PET_USER_PORT_TAG "user"
#define PET_USER_PORT_TAG "user"
class plus4_state : public driver_device
{
@ -71,7 +71,7 @@ public:
{ }
required_device<m7501_device> m_maincpu;
required_device<pls100_device> m_pla;
required_device<pla_device> m_pla;
required_device<mos7360_device> m_ted;
optional_device<mos6551_device> m_acia;
optional_device<mos6529_device> m_spi_user;