Added serial image device, was in serial.c in mess/machine (no whatsnew)

This commit is contained in:
Miodrag Milanovic 2011-09-03 12:19:34 +00:00
parent 9ede250f57
commit 04169b13d4
4 changed files with 425 additions and 0 deletions

2
.gitattributes vendored
View File

@ -717,6 +717,8 @@ src/emu/imagedev/multcart.c svneol=native#text/plain
src/emu/imagedev/multcart.h svneol=native#text/plain
src/emu/imagedev/printer.c svneol=native#text/plain
src/emu/imagedev/printer.h svneol=native#text/plain
src/emu/imagedev/serial.c svneol=native#text/plain
src/emu/imagedev/serial.h svneol=native#text/plain
src/emu/imagedev/snapquik.c svneol=native#text/plain
src/emu/imagedev/snapquik.h svneol=native#text/plain
src/emu/info.c svneol=native#text/plain

View File

@ -293,6 +293,7 @@ EMUIMAGEDEVOBJS = \
$(EMUIMAGEDEV)/harddriv.o \
$(EMUIMAGEDEV)/multcart.o \
$(EMUIMAGEDEV)/printer.o \
$(EMUIMAGEDEV)/serial.o \
$(EMUIMAGEDEV)/snapquik.o \

312
src/emu/imagedev/serial.c Normal file
View File

@ -0,0 +1,312 @@
/****************************************************************************
serial.c
Code for handling serial port image devices
****************************************************************************/
#include "emu.h"
#include "serial.h"
// device type definition
const device_type SERIAL = &device_creator<serial_image_device>;
//-------------------------------------------------
// serial_image_device - constructor
//-------------------------------------------------
serial_image_device::serial_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, SERIAL, "Serial", tag, owner, clock),
device_serial_interface(mconfig, *this),
device_image_interface(mconfig, *this)
{
}
//-------------------------------------------------
// serial_image_device - destructor
//-------------------------------------------------
serial_image_device::~serial_image_device()
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void serial_image_device::device_config_complete()
{
// inherit a copy of the static data
const serial_image_interface *intf = reinterpret_cast<const serial_image_interface *>(static_config());
if (intf != NULL)
*static_cast<serial_image_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
m_baud_rate = 2400;
m_data_bits = 8;
m_stop_bits = 2;
m_parity = SERIAL_PARITY_NONE;
m_transmit_on_start = FALSE;
m_tag_connected = NULL;
}
// set brief and instance name
update_names();
}
static TIMER_CALLBACK(serial_device_baud_rate_callback)
{
reinterpret_cast<serial_image_device *>(ptr)->timer_callback();
}
/*-------------------------------------------------
input_callback - called when other side
has updated state
-------------------------------------------------*/
void serial_image_device::input_callback(UINT8 state)
{
m_input_state = state;
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void serial_image_device::device_start()
{
set_data_frame(m_data_bits, m_stop_bits,m_parity);
m_timer = machine().scheduler().timer_alloc(FUNC(serial_device_baud_rate_callback), this);
/* signal to other end it is clear to send! */
/* data is initially high state */
/* set /rts */
m_connection_state |= SERIAL_STATE_RTS;
/* signal to other end data is ready to be accepted */
/* set /dtr */
m_connection_state |= SERIAL_STATE_DTR;
set_out_data_bit(1);
serial_connection_out();
transmit_register_reset();
receive_register_reset();
set_transmit_state(m_transmit_on_start ? 1 :0);
device_serial_interface *intf = NULL;
device_t *dev = machine().device(m_tag_connected);
if (dev!=NULL && dev->interface(intf)) {
intf->connect(this);
}
}
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
/* reset position in stream */
void serial_image_device::data_stream_reset(serial_data_stream *stream)
{
/* reset byte offset */
stream->ByteCount= 0;
/* reset bit count */
stream->BitCount = 0;
}
/* free stream */
void serial_image_device::data_stream_free(serial_data_stream *stream)
{
if (stream->pData!=NULL)
{
free(stream->pData);
stream->pData = NULL;
}
stream->DataLength = 0;
}
/* initialise stream */
void serial_image_device::data_stream_init(serial_data_stream *stream, unsigned char *pData, unsigned long DataLength)
{
stream->pData = pData;
stream->DataLength = DataLength;
data_stream_reset(stream);
}
/* get a bit from input stream */
int serial_image_device::data_stream_get_data_bit_from_data_byte(serial_data_stream *stream)
{
int data_bit;
int data_byte;
if (stream->ByteCount<stream->DataLength)
{
/* get data from buffer */
data_byte= stream->pData[stream->ByteCount];
}
else
{
/* over end of buffer, so return 0 */
data_byte= 0;
}
/* get bit from data */
data_bit = (data_byte>>(7-stream->BitCount)) & 0x01;
/* update bit count */
stream->BitCount++;
/* ripple overflow onto byte count */
stream->ByteCount+=stream->BitCount>>3;
/* lock bit count into range */
stream->BitCount &=0x07;
/* do not let it read over end of data */
if (stream->ByteCount>=stream->DataLength)
{
stream->ByteCount = stream->DataLength-1;
}
return data_bit;
}
void serial_image_device::set_transmit_state(int state)
{
int previous_state = m_transmit_state;
m_transmit_state = state;
if ((state^previous_state)!=0)
{
if (state)
{
/* start timer */
m_timer->adjust(attotime::zero, 0, attotime::from_hz(m_baud_rate));
}
else
{
/* remove timer */
m_timer->reset();
}
}
}
void serial_image_device::sent_char()
{
int bit;
UINT8 data_byte;
/* generate byte to transmit */
data_byte = 0;
for (int i=0; i< m_data_bits; i++)
{
data_byte = data_byte<<1;
bit = data_stream_get_data_bit_from_data_byte(&m_transmit);
data_byte = data_byte|bit;
}
/* setup register */
transmit_register_setup(data_byte);
logerror("serial device transmitted char: %02x\n",data_byte);
}
/*-------------------------------------------------
timer_callback
-------------------------------------------------*/
void serial_image_device::timer_callback()
{
/* receive data into receive register */
receive_register_update_bit(get_in_data_bit());
if (is_receive_register_full())
{
//logerror("SERIAL DEVICE\n");
receive_register_extract();
logerror("serial device receive char: %02x\n",get_received_char());
}
/* is transmit empty? */
if (is_transmit_register_empty())
{
/* char has been sent, execute callback */
sent_char();
}
/* other side says it is clear to send? */
if (m_connection_state & SERIAL_STATE_CTS)
{
/* send bit */
transmit_register_send_bit();
}
}
int serial_image_device::load_internal(unsigned char **ptr, int *pDataSize)
{
int datasize;
unsigned char *data;
/* get file size */
datasize = length();
if (datasize!=0)
{
/* malloc memory for this data */
data = (unsigned char *)malloc(datasize);
if (data!=NULL)
{
/* read whole file */
fread(data, datasize);
*ptr = data;
*pDataSize = datasize;
logerror("File loaded!\r\n");
/* ok! */
return 1;
}
}
return 0;
}
/*-------------------------------------------------
call_load
-------------------------------------------------*/
bool serial_image_device::call_load()
{
int data_length;
unsigned char *data;
/* load file and setup transmit data */
if (load_internal(&data, &data_length))
{
data_stream_init(&m_transmit, data, data_length);
return IMAGE_INIT_PASS;
}
return IMAGE_INIT_FAIL;
}
/*-------------------------------------------------
call_unload
-------------------------------------------------*/
void serial_image_device::call_unload()
{
/* stop transmit */
set_transmit_state(0);
/* free streams */
data_stream_free(&m_transmit);
data_stream_free(&m_receive);
}

110
src/emu/imagedev/serial.h Normal file
View File

@ -0,0 +1,110 @@
/****************************************************************************
serial.h
Code for handling serial port image devices
****************************************************************************/
#ifndef __SERIAL_H__
#define __SERIAL_H__
#include "diimage.h"
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
// ======================> serial_data_stream
struct serial_data_stream
{
/* pointer to buffer */
UINT8 *pData;
/* length of buffer */
unsigned long DataLength;
/* bit offset within current byte */
unsigned long BitCount;
/* byte offset within data */
unsigned long ByteCount;
};
// ======================> serial_image_interface
struct serial_image_interface
{
int m_baud_rate;
int m_data_bits;
int m_stop_bits;
int m_parity;
bool m_transmit_on_start;
const char *m_tag_connected;
};
// ======================> serial_image_device
class serial_image_device : public device_t,
public serial_image_interface,
public device_serial_interface,
public device_image_interface
{
public:
// construction/destruction
serial_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~serial_image_device();
// image-level overrides
virtual bool call_load();
virtual void call_unload();
virtual iodevice_t image_type() const { return IO_SERIAL; }
virtual bool is_readable() const { return 1; }
virtual bool is_writeable() const { return 1; }
virtual bool is_creatable() const { return 1; }
virtual bool must_be_loaded() const { return 0; }
virtual bool is_reset_on_load() const { return 0; }
virtual const char *image_interface() const { return NULL; }
virtual const char *file_extensions() const { return ""; }
virtual const option_guide *create_option_guide() const { return NULL; }
// specific implementation
void timer_callback();
virtual void input_callback(UINT8 state);
void sent_char();
void set_transmit_state(int state);
int load_internal(unsigned char **ptr, int *pDataSize);
// data stream
int data_stream_get_data_bit_from_data_byte(serial_data_stream *stream);
void data_stream_reset(serial_data_stream *stream);
void data_stream_free(serial_data_stream *stream);
void data_stream_init(serial_data_stream *stream, unsigned char *pData, unsigned long DataLength) ;
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
private:
/* transmit data bit-stream */
serial_data_stream m_transmit;
/* receive data bit-stream */
serial_data_stream m_receive;
int m_transmit_state;
/* baud rate timer */
emu_timer *m_timer;
};
// device type definition
extern const device_type SERIAL;
#define MCFG_SERIAL_ADD(_tag,_config) \
MCFG_DEVICE_ADD(_tag, SERIAL, 0) \
MCFG_DEVICE_CONFIG(_config) \
#endif /* __SERIAL_H__ */