Modernized er59256 device. (nw)

This commit is contained in:
Ivan Vangelista 2013-10-07 18:07:11 +00:00
parent dac9a98a31
commit 2aba7da865
5 changed files with 213 additions and 247 deletions

View File

@ -9,7 +9,6 @@
#include "emu.h"
#include "er59256.h"
#include "devlegcy.h"
/* LOGLEVEL 0=no logging, 1=just commands and data, 2=everything ! */
@ -18,212 +17,19 @@
#define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__)
#define LOG_BITS(bits) logerror("CS=%d CK=%d DI=%d DO=%d", (bits&CS_MASK) ? 1 : 0, (bits&CK_MASK) ? 1 : 0, (bits&DI_MASK) ? 1 : 0, (bits&DO_MASK) ? 1 : 0)
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
struct er59256_t
{
/* The actual memory */
UINT16 eerom[EEROM_WORDS];
/* Bits as they appear on the io pins, current state */
UINT8 io_bits;
/* Bits as they appear on the io pins, previous state */
UINT8 old_io_bits;
/* the 16 bit shift in/out reg */
UINT16 in_shifter;
UINT32 out_shifter;
/* Count of bits received since last CS low->high */
UINT8 bitcount;
/* Command & addresss */
UINT8 command;
/* Write enable and write in progress flags */
UINT8 flags;
};
/***************************************************************************
FUNCTION PROTOTYPES
************************************************************************/
static void decode_command(er59256_t *er59256);
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
INLINE er59256_t *get_token(device_t *device)
{
assert(device->type() == ER59256);
return (er59256_t *) downcast<er59256_device *>(device)->token();
}
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
void er59256_preload_rom(device_t *device, const UINT16 *rom_data, int count)
{
er59256_t *er59256 = get_token(device);
int WordNo;
logerror("Preloading %d words of data\n",count);
if(count>EEROM_WORDS)
memcpy(&er59256->eerom,rom_data,count*2);
else
memcpy(&er59256->eerom,rom_data,EEROM_WORDS*2);
for(WordNo=0;WordNo<EEROM_WORDS;WordNo++)
logerror("%04X ",er59256->eerom[WordNo]);
logerror("\n");
}
UINT8 er59256_data_loaded(device_t *device)
{
er59256_t *er59256 = get_token(device);
return (er59256->flags & FLAG_DATA_LOADED) ? 1 : 0;
}
/*-------------------------------------------------
DEVICE_START( er59256 )
-------------------------------------------------*/
static DEVICE_START( er59256 )
{
er59256_t *er59256 = get_token(device);
memset(er59256, 0x00, sizeof(er59256_t));
// Start with rom defaulted to erased
memset(&er59256->eerom, 0xFF, EEROM_WORDS*2);
er59256->command=CMD_INVALID;
er59256->flags&= ~FLAG_DATA_LOADED;
}
void er59256_set_iobits(device_t *device, UINT8 newbits)
{
er59256_t *er59256 = get_token(device);
//UINT32 bit;
// Make sure we only apply valid bits
newbits&=ALL_MASK;
if(LOGLEVEL>1)
{
logerror("er59256:newbits=%02X : ",newbits);
LOG_BITS(newbits);
logerror(" io_bits=%02X : ",er59256->io_bits);
LOG_BITS(er59256->io_bits);
logerror(" old_io_bits=%02X : ",er59256->old_io_bits);
LOG_BITS(er59256->old_io_bits);
logerror(" bitcount=%d, in_shifter=%04X, out_shifter=%05X, flags=%02X\n",er59256->bitcount,er59256->in_shifter,er59256->out_shifter,er59256->flags);
}
// Only do anything if the inputs have changed
if((newbits&IN_MASK)!=(er59256->io_bits&IN_MASK))
{
// save the current state, then set the new one, remembering to preserve data out
er59256->old_io_bits=er59256->io_bits;
er59256->io_bits=(newbits & ~DO_MASK) | (er59256->old_io_bits&DO_MASK);
if(CS_RISE(er59256))
{
er59256->flags&=~FLAG_START_BIT;
er59256->command=CMD_INVALID;
}
if(LOGLEVEL>1)
{
if(CK_RISE(er59256)) logerror("er59256:CK rise\n");
if(CS_RISE(er59256)) logerror("er59256:CS rise\n");
if(CK_FALL(er59256)) logerror("er59256:CK fall\n");
if(CS_FALL(er59256)) logerror("er59256:CS fall\n");
}
if(CK_RISE(er59256) && CS_VALID(er59256))
{
if((STARTED(er59256)==0) && (GET_DI(er59256)==1))
{
er59256->bitcount=0;
er59256->flags|=FLAG_START_BIT;
}
else
{
SHIFT_IN(er59256);
er59256->bitcount++;
if(er59256->bitcount==CMD_BITLEN)
decode_command(er59256);
if((er59256->bitcount==WRITE_BITLEN) && ((er59256->command & CMD_MASK)==CMD_WRITE))
{
er59256->eerom[er59256->command & ADDR_MASK]=er59256->in_shifter;
LOG(1,"er59256:write[%02X]=%04X\n",(er59256->command & ADDR_MASK),er59256->in_shifter);
er59256->command=CMD_INVALID;
}
LOG(1,"out_shifter=%05X, io_bits=%02X\n",er59256->out_shifter,er59256->io_bits);
SHIFT_OUT(er59256);
}
LOG(2,"io_bits:out=%02X\n",er59256->io_bits);
}
}
}
UINT8 er59256_get_iobits(device_t *device)
{
er59256_t *er59256 = get_token(device);
return er59256->io_bits;
}
static void decode_command(er59256_t *er59256)
{
er59256->out_shifter=0x0000;
er59256->command=(er59256->in_shifter & (CMD_MASK | ADDR_MASK));
switch(er59256->command & CMD_MASK)
{
case CMD_READ : er59256->out_shifter=er59256->eerom[er59256->command & ADDR_MASK];
LOG(1,"er59256:read[%02X]=%04X\n",(er59256->command&ADDR_MASK),er59256->eerom[er59256->command & ADDR_MASK]);
break;
case CMD_WRITE : break;
case CMD_ERASE : if (WRITE_ENABLED(er59256)) er59256->eerom[er59256->command & ADDR_MASK]=0xFF;
LOG(1,"er59256:erase[%02X]\n",(er59256->command&ADDR_MASK));
break;
case CMD_EWEN : er59256->flags|=FLAG_WRITE_EN;
LOG(1,"er59256:erase/write enabled\n");
break;
case CMD_EWDS : er59256->flags&=~FLAG_WRITE_EN;
LOG(1,"er59256:erase/write disabled\n");
break;
case CMD_ERAL : if (WRITE_ENABLED(er59256)) memset(&er59256->eerom, 0xFF, EEROM_WORDS*2);
LOG(1,"er59256:erase all\n");
break;
}
if ((er59256->command & CMD_MASK)!=CMD_WRITE)
er59256->command=CMD_INVALID;
}
const device_type ER59256 = &device_creator<er59256_device>;
er59256_device::er59256_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, ER59256, "Microchip ER59256 serial eeprom.", tag, owner, clock, "er59256", __FILE__)
: device_t(mconfig, ER59256, "Microchip ER59256 serial eeprom.", tag, owner, clock, "er59256", __FILE__),
m_io_bits(0),
m_old_io_bits(0),
m_in_shifter(0),
m_out_shifter(0),
m_bitcount(0),
m_command(0),
m_flags(0)
{
m_token = global_alloc_clear(er59256_t);
}
//-------------------------------------------------
@ -242,7 +48,21 @@ void er59256_device::device_config_complete()
void er59256_device::device_start()
{
DEVICE_START_NAME( er59256 )(this);
// Start with rom defaulted to erased
memset(&m_eerom, 0xFF, EEROM_WORDS*2);
m_command=CMD_INVALID;
m_flags&= ~FLAG_DATA_LOADED;
save_item(NAME(m_eerom));
save_item(NAME(m_io_bits));
save_item(NAME(m_old_io_bits));
save_item(NAME(m_in_shifter));
save_item(NAME(m_out_shifter));
save_item(NAME(m_bitcount));
save_item(NAME(m_command));
save_item(NAME(m_flags));
}
//-------------------------------------------------
@ -253,3 +73,132 @@ void er59256_device::device_stop()
{
/* Save contents of eerom */
}
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
void er59256_device::preload_rom(const UINT16 *rom_data, int count)
{
int WordNo;
logerror("Preloading %d words of data\n",count);
if(count>EEROM_WORDS)
memcpy(&m_eerom,rom_data,count*2);
else
memcpy(&m_eerom,rom_data,EEROM_WORDS*2);
for(WordNo=0;WordNo<EEROM_WORDS;WordNo++)
logerror("%04X ",m_eerom[WordNo]);
logerror("\n");
}
UINT8 er59256_device::data_loaded()
{
return (m_flags & FLAG_DATA_LOADED) ? 1 : 0;
}
void er59256_device::set_iobits(UINT8 newbits)
{
//UINT32 bit;
// Make sure we only apply valid bits
newbits&=ALL_MASK;
if(LOGLEVEL>1)
{
logerror("er59256:newbits=%02X : ",newbits);
LOG_BITS(newbits);
logerror(" io_bits=%02X : ",m_io_bits);
LOG_BITS(m_io_bits);
logerror(" old_io_bits=%02X : ",m_old_io_bits);
LOG_BITS(m_old_io_bits);
logerror(" bitcount=%d, in_shifter=%04X, out_shifter=%05X, flags=%02X\n",m_bitcount,m_in_shifter,m_out_shifter,m_flags);
}
// Only do anything if the inputs have changed
if((newbits&IN_MASK)!=(m_io_bits&IN_MASK))
{
// save the current state, then set the new one, remembering to preserve data out
m_old_io_bits=m_io_bits;
m_io_bits=(newbits & ~DO_MASK) | (m_old_io_bits&DO_MASK);
if(CS_RISE())
{
m_flags&=~FLAG_START_BIT;
m_command=CMD_INVALID;
}
if(LOGLEVEL>1)
{
if(CK_RISE()) logerror("er59256:CK rise\n");
if(CS_RISE()) logerror("er59256:CS rise\n");
if(CK_FALL()) logerror("er59256:CK fall\n");
if(CS_FALL()) logerror("er59256:CS fall\n");
}
if(CK_RISE() && CS_VALID())
{
if((STARTED()==0) && (GET_DI()==1))
{
m_bitcount=0;
m_flags|=FLAG_START_BIT;
}
else
{
SHIFT_IN();
m_bitcount++;
if(m_bitcount==CMD_BITLEN)
decode_command();
if((m_bitcount==WRITE_BITLEN) && ((m_command & CMD_MASK)==CMD_WRITE))
{
m_eerom[m_command & ADDR_MASK]=m_in_shifter;
LOG(1,"er59256:write[%02X]=%04X\n",(m_command & ADDR_MASK),m_in_shifter);
m_command=CMD_INVALID;
}
LOG(1,"out_shifter=%05X, io_bits=%02X\n",m_out_shifter,m_io_bits);
SHIFT_OUT();
}
LOG(2,"io_bits:out=%02X\n",m_io_bits);
}
}
}
UINT8 er59256_device::get_iobits()
{
return m_io_bits;
}
void er59256_device::decode_command()
{
m_out_shifter=0x0000;
m_command=(m_in_shifter & (CMD_MASK | ADDR_MASK));
switch(m_command & CMD_MASK)
{
case CMD_READ : m_out_shifter=m_eerom[m_command & ADDR_MASK];
LOG(1,"er59256:read[%02X]=%04X\n",(m_command&ADDR_MASK),m_eerom[m_command & ADDR_MASK]);
break;
case CMD_WRITE : break;
case CMD_ERASE : if (WRITE_ENABLED()) m_eerom[m_command & ADDR_MASK]=0xFF;
LOG(1,"er59256:erase[%02X]\n",(m_command&ADDR_MASK));
break;
case CMD_EWEN : m_flags|=FLAG_WRITE_EN;
LOG(1,"er59256:erase/write enabled\n");
break;
case CMD_EWDS : m_flags&=~FLAG_WRITE_EN;
LOG(1,"er59256:erase/write disabled\n");
break;
case CMD_ERAL : if (WRITE_ENABLED()) memset(&m_eerom, 0xFF, EEROM_WORDS*2);
LOG(1,"er59256:erase all\n");
break;
}
if ((m_command & CMD_MASK)!=CMD_WRITE)
m_command=CMD_INVALID;
}

View File

@ -10,6 +10,8 @@
#ifndef _ER59256_H_
#define _ER59256_H_
#define EEROM_WORDS 0x10
/***************************************************************************
MACROS
***************************************************************************/
@ -18,18 +20,46 @@ class er59256_device : public device_t
{
public:
er59256_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~er59256_device() { global_free(m_token); }
~er59256_device() {}
void set_iobits(UINT8 newbits);
UINT8 get_iobits();
void preload_rom(const UINT16 *rom_data, int count);
UINT8 data_loaded();
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_stop();
private:
// internal state
void *m_token;
/* The actual memory */
UINT16 m_eerom[EEROM_WORDS];
/* Bits as they appear on the io pins, current state */
UINT8 m_io_bits;
/* Bits as they appear on the io pins, previous state */
UINT8 m_old_io_bits;
/* the 16 bit shift in/out reg */
UINT16 m_in_shifter;
UINT32 m_out_shifter;
/* Count of bits received since last CS low->high */
UINT8 m_bitcount;
/* Command & addresss */
UINT8 m_command;
/* Write enable and write in progress flags */
UINT8 m_flags;
void decode_command();
};
extern const device_type ER59256;
@ -42,8 +72,6 @@ extern const device_type ER59256;
CONSTANTS
***************************************************************************/
#define EEROM_WORDS 0x10
#define CK_SHIFT 0x00
#define DI_SHIFT 0x01
#define DO_SHIFT 0x02
@ -57,26 +85,26 @@ extern const device_type ER59256;
#define ALL_MASK (CK_MASK | DI_MASK | DO_MASK | CS_MASK)
#define IN_MASK (CK_MASK | DI_MASK | CS_MASK)
#define GET_CK(eep) ((eep->io_bits & CK_MASK) >> CK_SHIFT)
#define GET_DI(eep) ((eep->io_bits & DI_MASK) >> DI_SHIFT)
#define GET_DO(eep) ((eep->io_bits & DO_MASK) >> DO_SHIFT)
#define GET_CS(eep) ((eep->io_bits & CS_MASK) >> CS_SHIFT)
#define GET_CK() ((m_io_bits & CK_MASK) >> CK_SHIFT)
#define GET_DI() ((m_io_bits & DI_MASK) >> DI_SHIFT)
#define GET_DO() ((m_io_bits & DO_MASK) >> DO_SHIFT)
#define GET_CS() ((m_io_bits & CS_MASK) >> CS_SHIFT)
#define SET_CK(eep,data) eep->io_bits=((eep->io_bits & ~CK_MASK) | ((data & 0x01) << CK_SHIFT))
#define SET_DI(eep,data) eep->io_bits=((eep->io_bits & ~DI_MASK) | ((data & 0x01) << DI_SHIFT))
#define SET_DO(eep,data) eep->io_bits=((eep->io_bits & ~DO_MASK) | ((data & 0x01) << DO_SHIFT))
#define SET_CS(eep,data) eep->io_bits=((eep->io_bits & ~CS_MASK) | ((data & 0x01) << CS_SHIFT))
#define SET_CK(data) m_io_bits=((m_io_bits & ~CK_MASK) | ((data & 0x01) << CK_SHIFT))
#define SET_DI(data) m_io_bits=((m_io_bits & ~DI_MASK) | ((data & 0x01) << DI_SHIFT))
#define SET_DO(data) m_io_bits=((m_io_bits & ~DO_MASK) | ((data & 0x01) << DO_SHIFT))
#define SET_CS(data) m_io_bits=((m_io_bits & ~CS_MASK) | ((data & 0x01) << CS_SHIFT))
#define CK_RISE(eep) ((eep->io_bits & CK_MASK) & ~(eep->old_io_bits & CK_MASK))
#define CS_RISE(eep) ((eep->io_bits & CS_MASK) & ~(eep->old_io_bits & CS_MASK))
#define CS_VALID(eep) ((eep->io_bits & CS_MASK) & (eep->old_io_bits & CS_MASK))
#define CK_RISE() ((m_io_bits & CK_MASK) & ~(m_old_io_bits & CK_MASK))
#define CS_RISE() ((m_io_bits & CS_MASK) & ~(m_old_io_bits & CS_MASK))
#define CS_VALID() ((m_io_bits & CS_MASK) & (m_old_io_bits & CS_MASK))
#define CK_FALL(eep) (~(eep->io_bits & CK_MASK) & (eep->old_io_bits & CK_MASK))
#define CS_FALL(eep) (~(eep->io_bits & CS_MASK) & (eep->old_io_bits & CS_MASK))
#define CK_FALL() (~(m_io_bits & CK_MASK) & (m_old_io_bits & CK_MASK))
#define CS_FALL() (~(m_io_bits & CS_MASK) & (m_old_io_bits & CS_MASK))
#define SHIFT_IN(eep) eep->in_shifter=(eep->in_shifter<<1) | GET_DI(eep)
#define SHIFT_OUT(eep) SET_DO(eep,(eep->out_shifter & 0x10000)>>16); eep->out_shifter=(eep->out_shifter<<1)
#define SHIFT_IN() m_in_shifter=(m_in_shifter<<1) | GET_DI()
#define SHIFT_OUT() SET_DO((m_out_shifter & 0x10000)>>16); m_out_shifter=(m_out_shifter<<1)
#define CMD_READ 0x80
#define CMD_WRITE 0x40
@ -98,15 +126,7 @@ extern const device_type ER59256;
#define FLAG_START_BIT 0x02
#define FLAG_DATA_LOADED 0x04
#define WRITE_ENABLED(eep) ((eep->flags & FLAG_WRITE_EN) ? 1 : 0)
#define STARTED(eep) ((eep->flags & FLAG_START_BIT) ? 1 : 0)
#define WRITE_ENABLED() ((m_flags & FLAG_WRITE_EN) ? 1 : 0)
#define STARTED() ((m_flags & FLAG_START_BIT) ? 1 : 0)
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
void er59256_set_iobits(device_t *device, UINT8 newbits);
UINT8 er59256_get_iobits(device_t *device);
void er59256_preload_rom(device_t *device, const UINT16 *rom_data, int count);
UINT8 er59256_data_loaded(device_t *device);
#endif

View File

@ -14,7 +14,6 @@
#include "machine/ram.h"
#include "formats/pc_dsk.h"
#include "includes/rmnimbus.h"
#include "machine/er59256.h"
#include "machine/scsibus.h"
#include "machine/scsicb.h"
#include "machine/scsihd.h"

View File

@ -12,6 +12,7 @@
#include "machine/scsicb.h"
#include "machine/6522via.h"
#include "machine/ram.h"
#include "machine/er59256.h"
#include "sound/ay8910.h"
#include "sound/msm5205.h"
@ -400,7 +401,8 @@ public:
m_msm(*this, MSM5205_TAG),
m_ay8910(*this, AY8910_TAG),
m_scsibus(*this, SCSIBUS_TAG ":host"),
m_ram(*this, RAM_TAG)
m_ram(*this, RAM_TAG),
m_eeprom(*this, ER59256_TAG)
{
}
@ -409,6 +411,7 @@ public:
required_device<ay8910_device> m_ay8910;
required_device<scsicb_device> m_scsibus;
required_device<ram_device> m_ram;
required_device<er59256_device> m_eeprom;
UINT32 m_debug_machine;
// i186_state m_i186;

View File

@ -61,7 +61,6 @@ chdman createhd -o ST125N.chd -chs 407,4,26 -ss 512
#include "debug/debugcon.h"
#include "imagedev/flopdrv.h"
#include "machine/ram.h"
#include "machine/er59256.h"
#include "machine/pic8259.h"
#include "machine/pit8253.h"
#include "machine/i8251.h"
@ -2491,14 +2490,12 @@ void rmnimbus_state::nimbus_scsi_linechange( UINT8 mask, UINT8 state )
void rmnimbus_state::pc8031_reset()
{
device_t *er59256 = machine().device(ER59256_TAG);
logerror("peripheral controler reset\n");
memset(&m_ipc_interface,0,sizeof(m_ipc_interface));
if(!er59256_data_loaded(er59256))
er59256_preload_rom(er59256,def_config,ARRAY_LENGTH(def_config));
if(!m_eeprom->data_loaded())
m_eeprom->preload_rom(def_config,ARRAY_LENGTH(def_config));
}
@ -2628,7 +2625,6 @@ WRITE8_MEMBER(rmnimbus_state::nimbus_pc8031_iou_w)
READ8_MEMBER(rmnimbus_state::nimbus_pc8031_port_r)
{
device_t *er59256 = machine().device(ER59256_TAG);
int pc=space.device().safe_pc();
UINT8 result = 0;
@ -2637,7 +2633,7 @@ READ8_MEMBER(rmnimbus_state::nimbus_pc8031_port_r)
switch(offset)
{
case 0x01 : result=er59256_get_iobits(er59256);
case 0x01 : result=m_eeprom->get_iobits();
}
return result;
@ -2645,12 +2641,11 @@ READ8_MEMBER(rmnimbus_state::nimbus_pc8031_port_r)
WRITE8_MEMBER(rmnimbus_state::nimbus_pc8031_port_w)
{
device_t *er59256 = machine().device(ER59256_TAG);
int pc=space.device().safe_pc();
switch (offset)
{
case 0x01 : er59256_set_iobits(er59256,(data&0x0F));
case 0x01 : m_eeprom->set_iobits((data&0x0F));
}
if(LOG_PC8031_PORT)