mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Moved some devices back to MESS since they belong there and are not used by arcades. (no whatsnew)
Note that msm8251 would be nice to have on emu section but it depends of serial.c which needs to be rewritten in order to be useful. Also upd765 is used only by MESS and it's pain to keep it in emu since it is not yet bug free.
This commit is contained in:
parent
f7d01e8bf5
commit
df7401d0e2
6
.gitattributes
vendored
6
.gitattributes
vendored
@ -859,8 +859,6 @@ src/emu/machine/msm58321.c svneol=native#text/plain
|
||||
src/emu/machine/msm58321.h svneol=native#text/plain
|
||||
src/emu/machine/msm6242.c svneol=native#text/plain
|
||||
src/emu/machine/msm6242.h svneol=native#text/plain
|
||||
src/emu/machine/msm8251.c svneol=native#text/plain
|
||||
src/emu/machine/msm8251.h svneol=native#text/plain
|
||||
src/emu/machine/nmc9306.c svneol=native#text/plain
|
||||
src/emu/machine/nmc9306.h svneol=native#text/plain
|
||||
src/emu/machine/nvram.c svneol=native#text/plain
|
||||
@ -907,8 +905,6 @@ src/emu/machine/scsihd.c svneol=native#text/plain
|
||||
src/emu/machine/scsihd.h svneol=native#text/plain
|
||||
src/emu/machine/secflash.c svneol=native#text/plain
|
||||
src/emu/machine/secflash.h svneol=native#text/plain
|
||||
src/emu/machine/serial.c svneol=native#text/plain
|
||||
src/emu/machine/serial.h svneol=native#text/plain
|
||||
src/emu/machine/smc91c9x.c svneol=native#text/plain
|
||||
src/emu/machine/smc91c9x.h svneol=native#text/plain
|
||||
src/emu/machine/timekpr.c svneol=native#text/plain
|
||||
@ -923,8 +919,6 @@ src/emu/machine/upd4701.c svneol=native#text/plain
|
||||
src/emu/machine/upd4701.h svneol=native#text/plain
|
||||
src/emu/machine/upd7201.c svneol=native#text/plain
|
||||
src/emu/machine/upd7201.h svneol=native#text/plain
|
||||
src/emu/machine/upd765.c svneol=native#text/plain
|
||||
src/emu/machine/upd765.h svneol=native#text/plain
|
||||
src/emu/machine/wd17xx.c svneol=native#text/plain
|
||||
src/emu/machine/wd17xx.h svneol=native#text/plain
|
||||
src/emu/machine/wd33c93.c svneol=native#text/plain
|
||||
|
@ -207,7 +207,6 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/msm5832.o \
|
||||
$(EMUMACHINE)/msm58321.o \
|
||||
$(EMUMACHINE)/msm6242.o \
|
||||
$(EMUMACHINE)/msm8251.o \
|
||||
$(EMUMACHINE)/nmc9306.o \
|
||||
$(EMUMACHINE)/nvram.o \
|
||||
$(EMUMACHINE)/pc16552d.o \
|
||||
@ -229,7 +228,6 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/scsidev.o \
|
||||
$(EMUMACHINE)/scsihd.o \
|
||||
$(EMUMACHINE)/secflash.o \
|
||||
$(EMUMACHINE)/serial.o \
|
||||
$(EMUMACHINE)/smc91c9x.o \
|
||||
$(EMUMACHINE)/timekpr.o \
|
||||
$(EMUMACHINE)/tmp68301.o \
|
||||
@ -237,7 +235,6 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/upd1990a.o \
|
||||
$(EMUMACHINE)/upd4701.o \
|
||||
$(EMUMACHINE)/upd7201.o \
|
||||
$(EMUMACHINE)/upd765.o \
|
||||
$(EMUMACHINE)/wd17xx.o \
|
||||
$(EMUMACHINE)/wd33c93.o \
|
||||
$(EMUMACHINE)/x2212.o \
|
||||
|
@ -1,825 +0,0 @@
|
||||
/*********************************************************************
|
||||
|
||||
msm8251.c
|
||||
|
||||
MSM/Intel 8251 Universal Synchronous/Asynchronous Receiver Transmitter code
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "msm8251.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _msm8251_t msm8251_t;
|
||||
struct _msm8251_t
|
||||
{
|
||||
devcb_resolved_read_line in_rxd_func;
|
||||
devcb_resolved_write_line out_txd_func;
|
||||
devcb_resolved_read_line in_dsr_func;
|
||||
devcb_resolved_write_line out_dtr_func;
|
||||
devcb_resolved_write_line out_rts_func;
|
||||
devcb_resolved_write_line out_rxrdy_func;
|
||||
devcb_resolved_write_line out_txrdy_func;
|
||||
devcb_resolved_write_line out_txempty_func;
|
||||
devcb_resolved_write_line out_syndet_func;
|
||||
|
||||
/* flags controlling how msm8251_control_w operates */
|
||||
UINT8 flags;
|
||||
/* offset into sync_bytes used during sync byte transfer */
|
||||
UINT8 sync_byte_offset;
|
||||
/* number of sync bytes written so far */
|
||||
UINT8 sync_byte_count;
|
||||
/* the sync bytes written */
|
||||
UINT8 sync_bytes[2];
|
||||
/* status of msm8251 */
|
||||
UINT8 status;
|
||||
UINT8 command;
|
||||
/* mode byte - bit definitions depend on mode - e.g. synchronous, asynchronous */
|
||||
UINT8 mode_byte;
|
||||
|
||||
/* data being received */
|
||||
UINT8 data;
|
||||
|
||||
/* receive reg */
|
||||
serial_receive_register receive_reg;
|
||||
/* transmit reg */
|
||||
serial_transmit_register transmit_reg;
|
||||
|
||||
data_form form;
|
||||
|
||||
/* the serial connection that data is transfered over */
|
||||
/* this is usually connected to the serial device */
|
||||
serial_connection connection;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
static void msm8251_in_callback(running_machine &machine, int id, unsigned long state);
|
||||
static void msm8251_update_tx_empty(device_t *device);
|
||||
static void msm8251_update_tx_ready(device_t *device);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
INLINE msm8251_t *get_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == MSM8251);
|
||||
|
||||
return (msm8251_t *) downcast<legacy_device_base *>(device)->token();
|
||||
}
|
||||
|
||||
|
||||
INLINE const msm8251_interface *get_interface(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == MSM8251);
|
||||
|
||||
return (const msm8251_interface *) device->static_config();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
GLOBAL VARIABLES
|
||||
***************************************************************************/
|
||||
|
||||
const msm8251_interface default_msm8251_interface = { DEVCB_NULL, };
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_in_callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void msm8251_in_callback(running_machine &machine, int id, unsigned long state)
|
||||
{
|
||||
device_t *device;
|
||||
msm8251_t *uart;
|
||||
int changed;
|
||||
|
||||
/* NPW 29-Nov-2008 - These two lines are a hack and indicate why our "serial" infrastructure needs to be updated */
|
||||
device = machine.device("uart");
|
||||
uart = get_token(device);
|
||||
|
||||
changed = uart->connection.input_state^state;
|
||||
|
||||
uart->connection.input_state = state;
|
||||
|
||||
/* did cts change state? */
|
||||
if (changed & SERIAL_STATE_CTS)
|
||||
{
|
||||
/* yes */
|
||||
/* update tx ready */
|
||||
/* msm8251_update_tx_ready(device); */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_START( msm8251 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START( msm8251 )
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
const msm8251_interface *intf = get_interface(device);
|
||||
|
||||
serial_helper_setup();
|
||||
|
||||
// resolve callbacks
|
||||
uart->out_rxrdy_func.resolve(intf->out_rxrdy_func, *device);
|
||||
uart->out_txrdy_func.resolve(intf->out_txrdy_func, *device);
|
||||
uart->out_txempty_func.resolve(intf->out_txempty_func, *device);
|
||||
|
||||
/* setup this side of the serial connection */
|
||||
serial_connection_init(device->machine(),&uart->connection);
|
||||
serial_connection_set_in_callback(device->machine(),&uart->connection, msm8251_in_callback);
|
||||
uart->connection.input_state = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_update_rx_ready
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void msm8251_update_rx_ready(device_t *device)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
int state;
|
||||
|
||||
state = uart->status & MSM8251_STATUS_RX_READY;
|
||||
|
||||
/* masked? */
|
||||
if ((uart->command & (1<<2))==0)
|
||||
{
|
||||
state = 0;
|
||||
}
|
||||
|
||||
uart->out_rxrdy_func(state != 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_receive_clock
|
||||
-------------------------------------------------*/
|
||||
|
||||
void msm8251_receive_clock(device_t *device)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
/* receive enable? */
|
||||
if (uart->command & (1<<2))
|
||||
{
|
||||
//logerror("MSM8251\n");
|
||||
/* get bit received from other side and update receive register */
|
||||
receive_register_update_bit(&uart->receive_reg, get_in_data_bit(uart->connection.input_state));
|
||||
|
||||
if (uart->receive_reg.flags & RECEIVE_REGISTER_FULL)
|
||||
{
|
||||
receive_register_extract(&uart->receive_reg, &uart->form);
|
||||
msm8251_receive_character(device, uart->receive_reg.byte_received);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_transmit_clock
|
||||
-------------------------------------------------*/
|
||||
|
||||
void msm8251_transmit_clock(device_t *device)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
/* transmit enable? */
|
||||
if (uart->command & (1<<0))
|
||||
{
|
||||
|
||||
/* transmit register full? */
|
||||
if ((uart->status & MSM8251_STATUS_TX_READY)==0)
|
||||
{
|
||||
/* if transmit reg is empty */
|
||||
if ((uart->transmit_reg.flags & TRANSMIT_REGISTER_EMPTY)!=0)
|
||||
{
|
||||
/* set it up */
|
||||
transmit_register_setup(&uart->transmit_reg, &uart->form, uart->data);
|
||||
/* msm8251 transmit reg now empty */
|
||||
uart->status |=MSM8251_STATUS_TX_EMPTY;
|
||||
/* ready for next transmit */
|
||||
uart->status |=MSM8251_STATUS_TX_READY;
|
||||
|
||||
msm8251_update_tx_empty(device);
|
||||
msm8251_update_tx_ready(device);
|
||||
}
|
||||
}
|
||||
|
||||
/* if transmit is not empty... transmit data */
|
||||
if ((uart->transmit_reg.flags & TRANSMIT_REGISTER_EMPTY)==0)
|
||||
{
|
||||
// logerror("MSM8251\n");
|
||||
transmit_register_send_bit(device->machine(),&uart->transmit_reg, &uart->connection);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* hunt mode? */
|
||||
/* after each bit has been shifted in, it is compared against the current sync byte */
|
||||
if (uart->command & (1<<7))
|
||||
{
|
||||
/* data matches sync byte? */
|
||||
if (uart->data == uart->sync_bytes[uart->sync_byte_offset])
|
||||
{
|
||||
/* sync byte matches */
|
||||
/* update for next sync byte? */
|
||||
uart->sync_byte_offset++;
|
||||
|
||||
/* do all sync bytes match? */
|
||||
if (uart->sync_byte_offset == uart->sync_byte_count)
|
||||
{
|
||||
/* ent hunt mode */
|
||||
uart->command &=~(1<<7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if there is no match, reset */
|
||||
uart->sync_byte_offset = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_update_tx_ready
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void msm8251_update_tx_ready(device_t *device)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
/* clear tx ready state */
|
||||
int tx_ready;
|
||||
|
||||
/* tx ready output is set if:
|
||||
DB Buffer Empty &
|
||||
CTS is set &
|
||||
Transmit enable is 1
|
||||
*/
|
||||
|
||||
tx_ready = 0;
|
||||
|
||||
/* transmit enable? */
|
||||
if ((uart->command & (1<<0))!=0)
|
||||
{
|
||||
/* other side has rts set (comes in as CTS at this side) */
|
||||
if (uart->connection.input_state & SERIAL_STATE_CTS)
|
||||
{
|
||||
if (uart->status & MSM8251_STATUS_TX_EMPTY)
|
||||
{
|
||||
/* enable transfer */
|
||||
tx_ready = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uart->out_txrdy_func(tx_ready);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_update_tx_empty
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void msm8251_update_tx_empty(device_t *device)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
if (uart->status & MSM8251_STATUS_TX_EMPTY)
|
||||
{
|
||||
/* tx is in marking state (high) when tx empty! */
|
||||
set_out_data_bit(uart->connection.State, 1);
|
||||
serial_connection_out(device->machine(),&uart->connection);
|
||||
}
|
||||
|
||||
uart->out_txempty_func((uart->status & MSM8251_STATUS_TX_EMPTY) != 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_RESET( msm8251 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_RESET( msm8251 )
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
LOG(("MSM8251: Reset\n"));
|
||||
|
||||
/* what is the default setup when the 8251 has been reset??? */
|
||||
|
||||
/* msm8251 datasheet explains the state of tx pin at reset */
|
||||
/* tx is set to 1 */
|
||||
set_out_data_bit(uart->connection.State,1);
|
||||
|
||||
/* assumption, rts is set to 1 */
|
||||
uart->connection.State &= ~SERIAL_STATE_RTS;
|
||||
serial_connection_out(device->machine(), &uart->connection);
|
||||
|
||||
transmit_register_reset(&uart->transmit_reg);
|
||||
receive_register_reset(&uart->receive_reg);
|
||||
/* expecting mode byte */
|
||||
uart->flags |= MSM8251_EXPECTING_MODE;
|
||||
/* not expecting a sync byte */
|
||||
uart->flags &= ~MSM8251_EXPECTING_SYNC_BYTE;
|
||||
|
||||
/* no character to read by cpu */
|
||||
/* transmitter is ready and is empty */
|
||||
uart->status = MSM8251_STATUS_TX_EMPTY | MSM8251_STATUS_TX_READY;
|
||||
uart->mode_byte = 0;
|
||||
uart->command = 0;
|
||||
|
||||
/* update tx empty pin output */
|
||||
msm8251_update_tx_empty(device);
|
||||
/* update rx ready pin output */
|
||||
msm8251_update_rx_ready(device);
|
||||
/* update tx ready pin output */
|
||||
msm8251_update_tx_ready(device);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
WRITE8_DEVICE_HANDLER(msm8251_control_w)
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(msm8251_control_w)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
if (uart->flags & MSM8251_EXPECTING_MODE)
|
||||
{
|
||||
if (uart->flags & MSM8251_EXPECTING_SYNC_BYTE)
|
||||
{
|
||||
LOG(("MSM8251: Sync byte\n"));
|
||||
|
||||
LOG(("Sync byte: %02x\n", data));
|
||||
/* store sync byte written */
|
||||
uart->sync_bytes[uart->sync_byte_offset] = data;
|
||||
uart->sync_byte_offset++;
|
||||
|
||||
if (uart->sync_byte_offset == uart->sync_byte_count)
|
||||
{
|
||||
/* finished transfering sync bytes, now expecting command */
|
||||
uart->flags &= ~(MSM8251_EXPECTING_MODE | MSM8251_EXPECTING_SYNC_BYTE);
|
||||
uart->sync_byte_offset = 0;
|
||||
// uart->status = MSM8251_STATUS_TX_EMPTY | MSM8251_STATUS_TX_READY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("MSM8251: Mode byte\n"));
|
||||
|
||||
uart->mode_byte = data;
|
||||
|
||||
/* Synchronous or Asynchronous? */
|
||||
if ((data & 0x03)!=0)
|
||||
{
|
||||
/* Asynchronous
|
||||
|
||||
bit 7,6: stop bit length
|
||||
0 = inhibit
|
||||
1 = 1 bit
|
||||
2 = 1.5 bits
|
||||
3 = 2 bits
|
||||
bit 5: parity type
|
||||
0 = parity odd
|
||||
1 = parity even
|
||||
bit 4: parity test enable
|
||||
0 = disable
|
||||
1 = enable
|
||||
bit 3,2: character length
|
||||
0 = 5 bits
|
||||
1 = 6 bits
|
||||
2 = 7 bits
|
||||
3 = 8 bits
|
||||
bit 1,0: baud rate factor
|
||||
0 = defines command byte for synchronous or asynchronous
|
||||
1 = x1
|
||||
2 = x16
|
||||
3 = x64
|
||||
*/
|
||||
|
||||
LOG(("MSM8251: Asynchronous operation\n"));
|
||||
|
||||
LOG(("Character length: %d\n", (((data>>2) & 0x03)+5)));
|
||||
|
||||
if (data & (1<<4))
|
||||
{
|
||||
LOG(("enable parity checking\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("parity check disabled\n"));
|
||||
}
|
||||
|
||||
if (data & (1<<5))
|
||||
{
|
||||
LOG(("even parity\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("odd parity\n"));
|
||||
}
|
||||
|
||||
{
|
||||
UINT8 stop_bit_length;
|
||||
|
||||
stop_bit_length = (data>>6) & 0x03;
|
||||
|
||||
switch (stop_bit_length)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
/* inhibit */
|
||||
LOG(("stop bit: inhibit\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
/* 1 */
|
||||
LOG(("stop bit: 1 bit\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
/* 1.5 */
|
||||
LOG(("stop bit: 1.5 bits\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
/* 2 */
|
||||
LOG(("stop bit: 2 bits\n"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uart->form.word_length = ((data>>2) & 0x03)+5;
|
||||
uart->form.parity = SERIAL_PARITY_NONE;
|
||||
switch ((data>>6) & 0x03)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
uart->form.stop_bit_count = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
uart->form.stop_bit_count = 2;
|
||||
break;
|
||||
}
|
||||
receive_register_setup(&uart->receive_reg, &uart->form);
|
||||
|
||||
|
||||
#if 0
|
||||
/* data bits */
|
||||
uart->receive_char_length = (((data>>2) & 0x03)+5);
|
||||
|
||||
if (data & (1<<4))
|
||||
{
|
||||
/* parity */
|
||||
uart->receive_char_length++;
|
||||
}
|
||||
|
||||
/* stop bits */
|
||||
uart->receive_char_length++;
|
||||
|
||||
uart->receive_flags &=~MSM8251_TRANSFER_RECEIVE_SYNCHRONISED;
|
||||
uart->receive_flags |= MSM8251_TRANSFER_RECEIVE_WAITING_FOR_START_BIT;
|
||||
#endif
|
||||
/* not expecting mode byte now */
|
||||
uart->flags &= ~MSM8251_EXPECTING_MODE;
|
||||
// uart->status = MSM8251_STATUS_TX_EMPTY | MSM8251_STATUS_TX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bit 7: Number of sync characters
|
||||
0 = 1 character
|
||||
1 = 2 character
|
||||
bit 6: Synchronous mode
|
||||
0 = Internal synchronisation
|
||||
1 = External synchronisation
|
||||
bit 5: parity type
|
||||
0 = parity odd
|
||||
1 = parity even
|
||||
bit 4: parity test enable
|
||||
0 = disable
|
||||
1 = enable
|
||||
bit 3,2: character length
|
||||
0 = 5 bits
|
||||
1 = 6 bits
|
||||
2 = 7 bits
|
||||
3 = 8 bits
|
||||
bit 1,0 = 0
|
||||
*/
|
||||
LOG(("MSM8251: Synchronous operation\n"));
|
||||
|
||||
/* setup for sync byte(s) */
|
||||
uart->flags |= MSM8251_EXPECTING_SYNC_BYTE;
|
||||
uart->sync_byte_offset = 0;
|
||||
if (data & 0x07)
|
||||
{
|
||||
uart->sync_byte_count = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
uart->sync_byte_count = 2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* command */
|
||||
LOG(("MSM8251: Command byte\n"));
|
||||
|
||||
uart->command = data;
|
||||
|
||||
LOG(("Command byte: %02x\n", data));
|
||||
|
||||
if (data & (1<<7))
|
||||
{
|
||||
LOG(("hunt mode\n"));
|
||||
}
|
||||
|
||||
if (data & (1<<5))
|
||||
{
|
||||
LOG(("/rts set to 0\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("/rts set to 1\n"));
|
||||
}
|
||||
|
||||
if (data & (1<<2))
|
||||
{
|
||||
LOG(("receive enable\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("receive disable\n"));
|
||||
}
|
||||
|
||||
if (data & (1<<1))
|
||||
{
|
||||
LOG(("/dtr set to 0\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("/dtr set to 1\n"));
|
||||
}
|
||||
|
||||
if (data & (1<<0))
|
||||
{
|
||||
LOG(("transmit enable\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("transmit disable\n"));
|
||||
}
|
||||
|
||||
|
||||
/* bit 7:
|
||||
0 = normal operation
|
||||
1 = hunt mode
|
||||
bit 6:
|
||||
0 = normal operation
|
||||
1 = internal reset
|
||||
bit 5:
|
||||
0 = /RTS set to 1
|
||||
1 = /RTS set to 0
|
||||
bit 4:
|
||||
0 = normal operation
|
||||
1 = reset error flag
|
||||
bit 3:
|
||||
0 = normal operation
|
||||
1 = send break character
|
||||
bit 2:
|
||||
0 = receive disable
|
||||
1 = receive enable
|
||||
bit 1:
|
||||
0 = /DTR set to 1
|
||||
1 = /DTR set to 0
|
||||
bit 0:
|
||||
0 = transmit disable
|
||||
1 = transmit enable
|
||||
*/
|
||||
|
||||
uart->connection.State &=~SERIAL_STATE_RTS;
|
||||
if (data & (1<<5))
|
||||
{
|
||||
/* rts set to 0 */
|
||||
uart->connection.State |= SERIAL_STATE_RTS;
|
||||
}
|
||||
|
||||
uart->connection.State &=~SERIAL_STATE_DTR;
|
||||
if (data & (1<<1))
|
||||
{
|
||||
uart->connection.State |= SERIAL_STATE_DTR;
|
||||
}
|
||||
|
||||
if ((data & (1<<0))==0)
|
||||
{
|
||||
/* held in high state when transmit disable */
|
||||
set_out_data_bit(uart->connection.State,1);
|
||||
}
|
||||
|
||||
|
||||
/* refresh outputs */
|
||||
serial_connection_out(device->machine(), &uart->connection);
|
||||
|
||||
if (data & (1<<4))
|
||||
{
|
||||
uart->status &= ~(MSM8251_STATUS_PARITY_ERROR | MSM8251_STATUS_OVERRUN_ERROR | MSM8251_STATUS_FRAMING_ERROR);
|
||||
}
|
||||
|
||||
if (data & (1<<6))
|
||||
{
|
||||
device->reset();
|
||||
}
|
||||
|
||||
msm8251_update_rx_ready(device);
|
||||
msm8251_update_tx_ready(device);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
READ8_DEVICE_HANDLER(msm8251_status_r)
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER(msm8251_status_r)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
LOG(("status: %02x\n", uart->status));
|
||||
return uart->status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
WRITE8_DEVICE_HANDLER(msm8251_data_w)
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(msm8251_data_w)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
uart->data = data;
|
||||
|
||||
logerror("write data: %02x\n",data);
|
||||
|
||||
/* writing clears */
|
||||
uart->status &=~MSM8251_STATUS_TX_READY;
|
||||
|
||||
/* if transmitter is active, then tx empty will be signalled */
|
||||
|
||||
msm8251_update_tx_ready(device);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_receive_character - called when last
|
||||
bit of data has been received
|
||||
-------------------------------------------------*/
|
||||
|
||||
void msm8251_receive_character(device_t *device, UINT8 ch)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
logerror("msm8251 receive char: %02x\n",ch);
|
||||
|
||||
uart->data = ch;
|
||||
|
||||
/* char has not been read and another has arrived! */
|
||||
if (uart->status & MSM8251_STATUS_RX_READY)
|
||||
{
|
||||
uart->status |= MSM8251_STATUS_OVERRUN_ERROR;
|
||||
}
|
||||
uart->status |= MSM8251_STATUS_RX_READY;
|
||||
|
||||
msm8251_update_rx_ready(device);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
READ8_DEVICE_HANDLER(msm8251_data_r) - read data
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER(msm8251_data_r)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
|
||||
logerror("read data: %02x, STATUS=%02x\n",uart->data,uart->status);
|
||||
/* reading clears */
|
||||
uart->status &= ~MSM8251_STATUS_RX_READY;
|
||||
|
||||
msm8251_update_rx_ready(device);
|
||||
return uart->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_connect_to_serial_device - initialise
|
||||
transfer using serial device - set the callback
|
||||
which will be called when serial device has
|
||||
updated it's state
|
||||
-------------------------------------------------*/
|
||||
|
||||
void msm8251_connect_to_serial_device(device_t *device, device_t *image)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
serial_device_connect(image, &uart->connection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
msm8251_connect
|
||||
-------------------------------------------------*/
|
||||
|
||||
void msm8251_connect(device_t *device, serial_connection *other_connection)
|
||||
{
|
||||
msm8251_t *uart = get_token(device);
|
||||
serial_connection_link(device->machine(), &uart->connection, other_connection);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_GET_INFO( msm8251 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
DEVICE_GET_INFO( msm8251 )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(msm8251_t); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(msm8251); break;
|
||||
case DEVINFO_FCT_STOP: /* Nothing */ break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(msm8251); break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "Intel 8251 UART"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Intel 8251 UART"); break;
|
||||
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
case DEVINFO_STR_CREDITS: /* Nothing */ break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_DEVICE(MSM8251, msm8251);
|
@ -1,88 +0,0 @@
|
||||
/*********************************************************************
|
||||
|
||||
msm8251.h
|
||||
|
||||
MSM/Intel 8251 Universal Synchronous/Asynchronous Receiver Transmitter code
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __MSM8251_H__
|
||||
#define __MSM8251_H__
|
||||
|
||||
#include "machine/serial.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
DECLARE_LEGACY_DEVICE(MSM8251, msm8251);
|
||||
|
||||
#define MSM8251_EXPECTING_MODE 0x01
|
||||
#define MSM8251_EXPECTING_SYNC_BYTE 0x02
|
||||
|
||||
#define MSM8251_STATUS_FRAMING_ERROR 0x020
|
||||
#define MSM8251_STATUS_OVERRUN_ERROR 0x010
|
||||
#define MSM8251_STATUS_PARITY_ERROR 0x08
|
||||
#define MSM8251_STATUS_TX_EMPTY 0x04
|
||||
#define MSM8251_STATUS_RX_READY 0x02
|
||||
#define MSM8251_STATUS_TX_READY 0x01
|
||||
|
||||
#define MCFG_MSM8251_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, MSM8251, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_MSM8251_REMOVE(_tag) \
|
||||
MCFG_DEVICE_REMOVE(_tag)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _msm8251_interface msm8251_interface;
|
||||
struct _msm8251_interface
|
||||
{
|
||||
devcb_read_line in_rxd_func;
|
||||
devcb_write_line out_txd_func;
|
||||
devcb_read_line in_dsr_func;
|
||||
devcb_write_line out_dtr_func;
|
||||
devcb_write_line out_rts_func;
|
||||
devcb_write_line out_rxrdy_func;
|
||||
devcb_write_line out_txrdy_func;
|
||||
devcb_write_line out_txempty_func;
|
||||
devcb_write_line out_syndet_func;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
extern const msm8251_interface default_msm8251_interface;
|
||||
|
||||
/* read data register */
|
||||
READ8_DEVICE_HANDLER(msm8251_data_r);
|
||||
|
||||
/* read status register */
|
||||
READ8_DEVICE_HANDLER(msm8251_status_r);
|
||||
|
||||
/* write data register */
|
||||
WRITE8_DEVICE_HANDLER(msm8251_data_w);
|
||||
|
||||
/* write control word */
|
||||
WRITE8_DEVICE_HANDLER(msm8251_control_w);
|
||||
|
||||
/* The 8251 has seperate transmit and receive clocks */
|
||||
/* use these two functions to update the msm8251 for each clock */
|
||||
/* on NC100 system, the clocks are the same */
|
||||
void msm8251_transmit_clock(device_t *device);
|
||||
void msm8251_receive_clock(device_t *device);
|
||||
|
||||
/* connecting to serial output */
|
||||
void msm8251_connect_to_serial_device(device_t *device, device_t *image);
|
||||
void msm8251_connect(device_t *device, serial_connection *other_connection);
|
||||
|
||||
void msm8251_receive_character(device_t *device, UINT8 ch);
|
||||
|
||||
#endif /* __MSM8251_H__ */
|
@ -1,733 +0,0 @@
|
||||
/* internal serial transmission */
|
||||
|
||||
/* select a file on host filesystem to transfer using serial method,
|
||||
setup serial interface software in driver and let the transfer begin */
|
||||
|
||||
/* this is used in the Amstrad NC Notepad emulation */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
the output starts at 1 level. It changes to 0 when the start bit has been transmitted.
|
||||
This therefore signals that data is following.
|
||||
When all data bits have been received, stop bits are transmitted with a value of 1.
|
||||
|
||||
msm8251 expects this in asynchronous mode:
|
||||
packet format:
|
||||
|
||||
bit count function value
|
||||
1 start bit 0
|
||||
note 1 data bits x
|
||||
note 2 parity bit x
|
||||
note 3 stop bits 1
|
||||
|
||||
Note:
|
||||
1. Data size can be defined (usual value is 8)
|
||||
2. Parity bit (if parity is set to odd or even). Value of bit
|
||||
is defined by data parity.
|
||||
3. There should be at least 1 stop bit.
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "serial.h"
|
||||
|
||||
|
||||
#define VERBOSE 0
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
/* a read/write bit stream. used to transmit data and to receive data */
|
||||
typedef struct _data_stream data_stream;
|
||||
struct _data_stream
|
||||
{
|
||||
/* pointer to buffer */
|
||||
unsigned char *pData;
|
||||
/* length of buffer */
|
||||
unsigned long DataLength;
|
||||
|
||||
/* bit offset within current byte */
|
||||
unsigned long BitCount;
|
||||
/* byte offset within data */
|
||||
unsigned long ByteCount;
|
||||
};
|
||||
|
||||
typedef struct _serial_t serial_t;
|
||||
struct _serial_t
|
||||
{
|
||||
/* transmit data bit-stream */
|
||||
data_stream transmit;
|
||||
/* receive data bit-stream */
|
||||
data_stream receive;
|
||||
|
||||
/* register to receive data */
|
||||
serial_receive_register receive_reg;
|
||||
/* register to transmit data */
|
||||
serial_transmit_register transmit_reg;
|
||||
|
||||
/* connection to transmit/receive data over */
|
||||
serial_connection connection;
|
||||
|
||||
/* data form to transmit/receive */
|
||||
data_form form;
|
||||
|
||||
int transmit_state;
|
||||
|
||||
/* baud rate */
|
||||
unsigned long BaudRate;
|
||||
|
||||
/* baud rate timer */
|
||||
emu_timer *timer;
|
||||
};
|
||||
|
||||
INLINE serial_t *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
//assert(device->type() == SERIAL);
|
||||
|
||||
return (serial_t *)downcast<legacy_device_base *>(device)->token();
|
||||
}
|
||||
|
||||
|
||||
/* the serial streams */
|
||||
static TIMER_CALLBACK(serial_device_baud_rate_callback);
|
||||
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
static unsigned char serial_parity_table[256];
|
||||
|
||||
void serial_helper_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* if sum of all bits in the byte is even, then the data
|
||||
has even parity, otherwise it has odd parity */
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
int data;
|
||||
int sum;
|
||||
int b;
|
||||
|
||||
sum = 0;
|
||||
data = i;
|
||||
|
||||
for (b=0; b<8; b++)
|
||||
{
|
||||
sum+=data & 0x01;
|
||||
|
||||
data = data>>1;
|
||||
}
|
||||
|
||||
serial_parity_table[i] = sum & 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char serial_helper_get_parity(unsigned char data)
|
||||
{
|
||||
return serial_parity_table[data & 0x0ff];
|
||||
}
|
||||
|
||||
static void serial_device_in_callback(running_machine &machine, int id, unsigned long status)
|
||||
{
|
||||
/* serial_t *ser = get_safe_token(device);
|
||||
|
||||
ser->connection.input_state = status;*/
|
||||
}
|
||||
|
||||
/***** SERIAL DEVICE ******/
|
||||
void serial_device_setup(device_t *device, int baud_rate, int num_data_bits, int stop_bit_count, int parity_code)
|
||||
{
|
||||
serial_t *ser = get_safe_token(device);
|
||||
|
||||
ser->BaudRate = baud_rate;
|
||||
ser->form.word_length = num_data_bits;
|
||||
ser->form.stop_bit_count = stop_bit_count;
|
||||
ser->form.parity = parity_code;
|
||||
ser->timer = device->machine().scheduler().timer_alloc(FUNC(serial_device_baud_rate_callback), (void *)device);
|
||||
|
||||
serial_connection_init(device->machine(),&ser->connection);
|
||||
serial_connection_set_in_callback(device->machine(),&ser->connection, serial_device_in_callback);
|
||||
|
||||
/* signal to other end it is clear to send! */
|
||||
/* data is initially high state */
|
||||
/* set /rts */
|
||||
ser->connection.State |= SERIAL_STATE_RTS;
|
||||
/* signal to other end data is ready to be accepted */
|
||||
/* set /dtr */
|
||||
ser->connection.State |= SERIAL_STATE_DTR;
|
||||
set_out_data_bit(ser->connection.State, 1);
|
||||
serial_connection_out(device->machine(),&ser->connection);
|
||||
transmit_register_reset(&ser->transmit_reg);
|
||||
receive_register_reset(&ser->receive_reg);
|
||||
receive_register_setup(&ser->receive_reg, &ser->form);
|
||||
}
|
||||
|
||||
|
||||
unsigned long serial_device_get_state(device_t *device)
|
||||
{
|
||||
serial_t *ser = get_safe_token(device);
|
||||
|
||||
return ser->connection.State;
|
||||
}
|
||||
|
||||
void serial_device_set_transmit_state(device_t *device, int state)
|
||||
{
|
||||
int previous_state;
|
||||
serial_t *ser = get_safe_token(device);
|
||||
|
||||
previous_state = ser->transmit_state;
|
||||
|
||||
ser->transmit_state = state;
|
||||
|
||||
if ((state^previous_state)!=0)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
/* start timer */
|
||||
ser->timer->adjust(attotime::zero, 0, attotime::from_hz(ser->BaudRate));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove timer */
|
||||
ser->timer->reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* get a bit from input stream */
|
||||
static int data_stream_get_data_bit_from_data_byte(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 receive_register_setup(serial_receive_register *receive, data_form *data_form)
|
||||
{
|
||||
receive->bit_count = data_form->word_length + data_form->stop_bit_count;
|
||||
|
||||
if (data_form->parity != SERIAL_PARITY_NONE)
|
||||
{
|
||||
receive->bit_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* this is generic code to be used in serial chip implementations */
|
||||
/* the majority of serial chips work in the same way and this code will work */
|
||||
/* for them */
|
||||
|
||||
/* receive a bit */
|
||||
void receive_register_update_bit(serial_receive_register *receive, int bit)
|
||||
{
|
||||
int previous_bit;
|
||||
|
||||
LOG(("receive register receive bit: %1x\n",bit));
|
||||
previous_bit = receive->register_data & 1;
|
||||
|
||||
/* shift previous bit 7 out */
|
||||
receive->register_data = receive->register_data<<1;
|
||||
/* shift new bit in */
|
||||
receive->register_data = (receive->register_data & 0xfffe) | bit;
|
||||
/* update bit count received */
|
||||
receive->bit_count_received++;
|
||||
|
||||
/* asyncrhonouse mode */
|
||||
if (receive->flags & RECEIVE_REGISTER_WAITING_FOR_START_BIT)
|
||||
{
|
||||
/* the previous bit is stored in uart.receive char bit 0 */
|
||||
/* has the bit state changed? */
|
||||
if (((previous_bit ^ bit) & 0x01)!=0)
|
||||
{
|
||||
/* yes */
|
||||
if (bit==0)
|
||||
{
|
||||
//logerror("receive register saw start bit\n");
|
||||
|
||||
/* seen start bit! */
|
||||
/* not waiting for start bit now! */
|
||||
receive->flags &=~RECEIVE_REGISTER_WAITING_FOR_START_BIT;
|
||||
receive->flags |=RECEIVE_REGISTER_SYNCHRONISED;
|
||||
/* reset bit count received */
|
||||
receive->bit_count_received = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (receive->flags & RECEIVE_REGISTER_SYNCHRONISED)
|
||||
{
|
||||
/* received all bits? */
|
||||
if (receive->bit_count_received==receive->bit_count)
|
||||
{
|
||||
receive->bit_count_received = 0;
|
||||
receive->flags &=~RECEIVE_REGISTER_SYNCHRONISED;
|
||||
receive->flags |= RECEIVE_REGISTER_WAITING_FOR_START_BIT;
|
||||
//logerror("receive register full\n");
|
||||
receive->flags |= RECEIVE_REGISTER_FULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void receive_register_reset(serial_receive_register *receive_reg)
|
||||
{
|
||||
receive_reg->bit_count_received = 0;
|
||||
receive_reg->flags &=~RECEIVE_REGISTER_FULL;
|
||||
receive_reg->flags &=~RECEIVE_REGISTER_SYNCHRONISED;
|
||||
receive_reg->flags |= RECEIVE_REGISTER_WAITING_FOR_START_BIT;
|
||||
}
|
||||
|
||||
void receive_register_extract(serial_receive_register *receive_reg, data_form *data_form)
|
||||
{
|
||||
unsigned long data_shift;
|
||||
UINT8 data;
|
||||
|
||||
receive_register_reset(receive_reg);
|
||||
|
||||
data_shift = 0;
|
||||
|
||||
/* if parity is even or odd, there should be a parity bit in the stream! */
|
||||
if (data_form->parity!=SERIAL_PARITY_NONE)
|
||||
{
|
||||
data_shift++;
|
||||
}
|
||||
|
||||
data_shift+=data_form->stop_bit_count;
|
||||
|
||||
/* strip off stop bits and parity */
|
||||
data = receive_reg->register_data>>data_shift;
|
||||
|
||||
/* mask off other bits so data byte has 0's in unused bits */
|
||||
data = data & (0x0ff
|
||||
>>
|
||||
(8-(data_form->word_length)));
|
||||
|
||||
receive_reg->byte_received = data;
|
||||
|
||||
/* parity enable? */
|
||||
switch (data_form->parity)
|
||||
{
|
||||
case SERIAL_PARITY_NONE:
|
||||
break;
|
||||
|
||||
/* check parity */
|
||||
case SERIAL_PARITY_ODD:
|
||||
case SERIAL_PARITY_EVEN:
|
||||
{
|
||||
//unsigned char computed_parity;
|
||||
//unsigned char parity_received;
|
||||
|
||||
/* get state of parity bit received */
|
||||
//parity_received = (receive_reg->register_data>>data_form->stop_bit_count) & 0x01;
|
||||
|
||||
/* compute parity for received bits */
|
||||
//computed_parity = serial_helper_get_parity(data);
|
||||
|
||||
if (data_form->parity == SERIAL_PARITY_ODD)
|
||||
{
|
||||
/* odd parity */
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* even parity */
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/***** TRANSMIT REGISTER *****/
|
||||
|
||||
void transmit_register_reset(serial_transmit_register *transmit_reg)
|
||||
{
|
||||
transmit_reg->flags |=TRANSMIT_REGISTER_EMPTY;
|
||||
}
|
||||
|
||||
/* used to construct data in stream format */
|
||||
static void transmit_register_add_bit(serial_transmit_register *transmit_reg, int bit)
|
||||
{
|
||||
/* combine bit */
|
||||
transmit_reg->register_data = transmit_reg->register_data<<1;
|
||||
transmit_reg->register_data &=~1;
|
||||
transmit_reg->register_data|=(bit & 0x01);
|
||||
transmit_reg->bit_count++;
|
||||
}
|
||||
|
||||
|
||||
/* generate data in stream format ready for transfer */
|
||||
void transmit_register_setup(serial_transmit_register *transmit_reg, data_form *data_form,unsigned char data_byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char transmit_data;
|
||||
|
||||
|
||||
transmit_reg->bit_count_transmitted = 0;
|
||||
transmit_reg->bit_count = 0;
|
||||
transmit_reg->flags &=~TRANSMIT_REGISTER_EMPTY;
|
||||
|
||||
/* start bit */
|
||||
transmit_register_add_bit(transmit_reg,0);
|
||||
|
||||
/* data bits */
|
||||
transmit_data = data_byte;
|
||||
for (i=0; i<data_form->word_length; i++)
|
||||
{
|
||||
int databit;
|
||||
|
||||
/* get bit from data */
|
||||
databit = (transmit_data>>(data_form->word_length-1)) & 0x01;
|
||||
/* add bit to formatted byte */
|
||||
transmit_register_add_bit(transmit_reg, databit);
|
||||
transmit_data = transmit_data<<1;
|
||||
}
|
||||
|
||||
/* parity */
|
||||
if (data_form->parity!=SERIAL_PARITY_NONE)
|
||||
{
|
||||
/* odd or even parity */
|
||||
unsigned char parity;
|
||||
|
||||
/* get parity */
|
||||
/* if parity = 0, data has even parity - i.e. there is an even number of one bits in the data */
|
||||
/* if parity = 1, data has odd parity - i.e. there is an odd number of one bits in the data */
|
||||
parity = serial_helper_get_parity(data_byte);
|
||||
|
||||
transmit_register_add_bit(transmit_reg, parity);
|
||||
}
|
||||
|
||||
/* stop bit(s) */
|
||||
for (i=0; i<data_form->stop_bit_count; i++)
|
||||
{
|
||||
transmit_register_add_bit(transmit_reg,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* get a bit from the transmit register */
|
||||
static int transmit_register_get_data_bit(serial_transmit_register *transmit_reg)
|
||||
{
|
||||
int bit;
|
||||
|
||||
bit = (transmit_reg->register_data>>
|
||||
(transmit_reg->bit_count - 1 -
|
||||
transmit_reg->bit_count_transmitted)) & 0x01;
|
||||
|
||||
transmit_reg->bit_count_transmitted++;
|
||||
|
||||
/* have all bits of this stream formatted byte been sent? */
|
||||
if (transmit_reg->bit_count_transmitted==transmit_reg->bit_count)
|
||||
{
|
||||
/* yes - generate a new byte to send */
|
||||
transmit_reg->flags |= TRANSMIT_REGISTER_EMPTY;
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
|
||||
void transmit_register_send_bit(running_machine &machine, serial_transmit_register *transmit_reg, serial_connection *connection)
|
||||
{
|
||||
int data;
|
||||
|
||||
data = transmit_register_get_data_bit(transmit_reg);
|
||||
|
||||
/* set tx data bit */
|
||||
set_out_data_bit(connection->State, data);
|
||||
|
||||
/* state out through connection */
|
||||
serial_connection_out(machine, connection);
|
||||
}
|
||||
|
||||
static void serial_protocol_none_sent_char(device_t *device)
|
||||
{
|
||||
int i;
|
||||
int bit;
|
||||
unsigned char data_byte;
|
||||
serial_t *ser = get_safe_token(device);
|
||||
|
||||
/* generate byte to transmit */
|
||||
data_byte = 0;
|
||||
for (i=0; i<ser->form.word_length; i++)
|
||||
{
|
||||
data_byte = data_byte<<1;
|
||||
bit = data_stream_get_data_bit_from_data_byte(&ser->transmit);
|
||||
data_byte = data_byte|bit;
|
||||
}
|
||||
/* setup register */
|
||||
transmit_register_setup(&ser->transmit_reg,&ser->form, data_byte);
|
||||
|
||||
logerror("serial device transmitted char: %02x\n",data_byte);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK(serial_device_baud_rate_callback)
|
||||
{
|
||||
serial_t *ser = get_safe_token((device_t*)ptr);
|
||||
|
||||
/* receive data into receive register */
|
||||
receive_register_update_bit(&ser->receive_reg, get_in_data_bit(ser->connection.input_state));
|
||||
|
||||
if (ser->receive_reg.flags & RECEIVE_REGISTER_FULL)
|
||||
{
|
||||
//logerror("SERIAL DEVICE\n");
|
||||
receive_register_extract(&ser->receive_reg, &ser->form);
|
||||
|
||||
logerror("serial device receive char: %02x\n",ser->receive_reg.byte_received);
|
||||
}
|
||||
|
||||
/* is transmit empty? */
|
||||
if (ser->transmit_reg.flags & TRANSMIT_REGISTER_EMPTY)
|
||||
{
|
||||
/* char has been sent, execute callback */
|
||||
serial_protocol_none_sent_char((device_t*)ptr);
|
||||
}
|
||||
|
||||
/* other side says it is clear to send? */
|
||||
if (ser->connection.input_state & SERIAL_STATE_CTS)
|
||||
{
|
||||
/* send bit */
|
||||
transmit_register_send_bit(machine, &ser->transmit_reg, &ser->connection);
|
||||
}
|
||||
}
|
||||
|
||||
/* connect the specified connection to this serial device */
|
||||
void serial_device_connect(device_t *device, serial_connection *connection)
|
||||
{
|
||||
serial_t *ser = get_safe_token(device);
|
||||
serial_connection_link(device->machine(), connection, &ser->connection);
|
||||
}
|
||||
|
||||
|
||||
/* load image */
|
||||
static int serial_device_load_internal(device_image_interface &image, unsigned char **ptr, int *pDataSize)
|
||||
{
|
||||
int datasize;
|
||||
unsigned char *data;
|
||||
|
||||
/* get file size */
|
||||
datasize = image.length();
|
||||
|
||||
if (datasize!=0)
|
||||
{
|
||||
/* malloc memory for this data */
|
||||
data = (unsigned char *)malloc(datasize);
|
||||
|
||||
if (data!=NULL)
|
||||
{
|
||||
/* read whole file */
|
||||
image.fread(data, datasize);
|
||||
|
||||
*ptr = data;
|
||||
*pDataSize = datasize;
|
||||
|
||||
logerror("File loaded!\r\n");
|
||||
|
||||
/* ok! */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reset position in stream */
|
||||
static void data_stream_reset(data_stream *stream)
|
||||
{
|
||||
/* reset byte offset */
|
||||
stream->ByteCount= 0;
|
||||
/* reset bit count */
|
||||
stream->BitCount = 0;
|
||||
}
|
||||
|
||||
/* free stream */
|
||||
static void data_stream_free(data_stream *stream)
|
||||
{
|
||||
if (stream->pData!=NULL)
|
||||
{
|
||||
free(stream->pData);
|
||||
stream->pData = NULL;
|
||||
}
|
||||
stream->DataLength = 0;
|
||||
}
|
||||
|
||||
/* initialise stream */
|
||||
static void data_stream_init(data_stream *stream, unsigned char *pData, unsigned long DataLength)
|
||||
{
|
||||
stream->pData = pData;
|
||||
stream->DataLength = DataLength;
|
||||
data_stream_reset(stream);
|
||||
}
|
||||
|
||||
DEVICE_START(serial)
|
||||
{
|
||||
//serial_t *ser = get_safe_token(device);
|
||||
}
|
||||
|
||||
DEVICE_RESET(serial)
|
||||
{
|
||||
// serial_t *ser = get_safe_token(device);
|
||||
}
|
||||
|
||||
DEVICE_IMAGE_LOAD(serial)
|
||||
{
|
||||
int data_length;
|
||||
unsigned char *data;
|
||||
device_t *device = &image.device();
|
||||
|
||||
serial_t *ser = get_safe_token(device);
|
||||
|
||||
/* load file and setup transmit data */
|
||||
if (serial_device_load_internal(image, &data, &data_length))
|
||||
{
|
||||
data_stream_init(&ser->transmit, data, data_length);
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
|
||||
DEVICE_IMAGE_UNLOAD(serial)
|
||||
{
|
||||
device_t *device = &image.device();
|
||||
serial_t *ser = get_safe_token(device);
|
||||
|
||||
/* stop transmit */
|
||||
serial_device_set_transmit_state(device, 0);
|
||||
/* free streams */
|
||||
data_stream_free(&ser->transmit);
|
||||
data_stream_free(&ser->receive);
|
||||
}
|
||||
|
||||
|
||||
DEVICE_GET_INFO( serial )
|
||||
{
|
||||
switch ( state )
|
||||
{
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(serial_t); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
case DEVINFO_INT_IMAGE_TYPE: info->i = IO_SERIAL; break;
|
||||
case DEVINFO_INT_IMAGE_READABLE: info->i = 1; break;
|
||||
case DEVINFO_INT_IMAGE_WRITEABLE: info->i = 1; break;
|
||||
case DEVINFO_INT_IMAGE_CREATABLE: info->i = 1; break;
|
||||
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( serial ); break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( serial ); break;
|
||||
case DEVINFO_FCT_IMAGE_LOAD: info->f = (genf *) DEVICE_IMAGE_LOAD_NAME( serial ); break;
|
||||
case DEVINFO_FCT_IMAGE_UNLOAD: info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(serial ); break;
|
||||
case DEVINFO_STR_NAME: strcpy( info->s, "Serial port"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Serial port"); break;
|
||||
case DEVINFO_STR_IMAGE_FILE_EXTENSIONS: strcpy(info->s, ""); break;
|
||||
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/*******************************************************************************/
|
||||
/********* SERIAL CONNECTION ***********/
|
||||
|
||||
|
||||
/* this converts state at this end to a state the other end can accept */
|
||||
/* e.g. CTS at this end becomes RTS at other end.
|
||||
RTS at this end becomes CTS at other end.
|
||||
TX at this end becomes RX at other end.
|
||||
RX at this end becomes TX at other end.
|
||||
etc
|
||||
|
||||
The same thing is done inside the serial null-terminal lead */
|
||||
|
||||
static unsigned long serial_connection_spin_bits(unsigned long input_status)
|
||||
{
|
||||
|
||||
return
|
||||
/* cts -> rts */
|
||||
(((input_status & 0x01)<<1) |
|
||||
/* rts -> cts */
|
||||
((input_status>>1) & 0x01) |
|
||||
/* dsr -> dtr */
|
||||
(((input_status>>2) & 0x01)<<3) |
|
||||
/* dtr -> dsr */
|
||||
(((input_status>>3) & 0x01)<<2) |
|
||||
/* rx -> tx */
|
||||
(((input_status>>4) & 0x01)<<5) |
|
||||
/* tx -> rx */
|
||||
(((input_status>>5) & 0x01)<<4));
|
||||
}
|
||||
|
||||
|
||||
/* setup callbacks for connection */
|
||||
void serial_connection_init(running_machine &machine, serial_connection *connection)
|
||||
{
|
||||
connection->out_callback = NULL;
|
||||
connection->in_callback = NULL;
|
||||
}
|
||||
|
||||
/* set callback which will be executed when in status has changed */
|
||||
void serial_connection_set_in_callback(running_machine &machine, serial_connection *connection, void (*in_cb)(running_machine &machine, int id, unsigned long status))
|
||||
{
|
||||
connection->in_callback = in_cb;
|
||||
}
|
||||
|
||||
/* output new state through connection */
|
||||
void serial_connection_out(running_machine &machine, serial_connection *connection)
|
||||
{
|
||||
if (connection->out_callback!=NULL)
|
||||
{
|
||||
unsigned long state_at_other_end;
|
||||
|
||||
state_at_other_end = serial_connection_spin_bits(connection->State);
|
||||
|
||||
connection->out_callback(machine, connection->id, state_at_other_end);
|
||||
}
|
||||
}
|
||||
|
||||
/* join two serial connections together */
|
||||
void serial_connection_link(running_machine &machine, serial_connection *connection_a, serial_connection *connection_b)
|
||||
{
|
||||
/* both connections should have their in connection setup! */
|
||||
/* the in connection is the callback they use to update their state based
|
||||
on the output from the other side */
|
||||
connection_a->out_callback = connection_b->in_callback;
|
||||
connection_b->out_callback = connection_a->in_callback;
|
||||
|
||||
/* let b know the state of a */
|
||||
serial_connection_out(machine,connection_a);
|
||||
/* let a know the state of b */
|
||||
serial_connection_out(machine,connection_b);
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_IMAGE_DEVICE(SERIAL, serial);
|
@ -1,247 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* machine/serial.h
|
||||
*
|
||||
* internal serial transmission
|
||||
*
|
||||
* This code is used to transmit a file stored on the host filesystem
|
||||
* (e.g. PC harddrive) to an emulated system.
|
||||
*
|
||||
* The file is converted into a serial bit-stream which can be received
|
||||
* by the emulated serial chip in the emulated system.
|
||||
*
|
||||
* The file can be transmitted using different protocols.
|
||||
*
|
||||
* A and B are two computers linked with a serial connection
|
||||
* A and B can transmit and receive data, through the same connection
|
||||
*
|
||||
* These flags apply to A and B, and give the state of the input & output
|
||||
* signals at each side.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef SERIAL_H_
|
||||
#define SERIAL_H_
|
||||
|
||||
|
||||
/*
|
||||
CTS = Clear to Send. (INPUT)
|
||||
Other end of connection is ready to accept data
|
||||
|
||||
|
||||
NOTE:
|
||||
|
||||
This output is active low on serial chips (e.g. 0 is CTS is set),
|
||||
but here it is active high!
|
||||
*/
|
||||
#define SERIAL_STATE_CTS 0x0001
|
||||
|
||||
/*
|
||||
RTS = Request to Send. (OUTPUT)
|
||||
This end is ready to send data, and requests if the other
|
||||
end is ready to accept it
|
||||
|
||||
NOTE:
|
||||
|
||||
This output is active low on serial chips (e.g. 0 is RTS is set),
|
||||
but here it is active high!
|
||||
*/
|
||||
#define SERIAL_STATE_RTS 0x0002
|
||||
|
||||
/*
|
||||
DSR = Data Set ready. (INPUT)
|
||||
Other end of connection has data
|
||||
|
||||
|
||||
NOTE:
|
||||
|
||||
This output is active low on serial chips (e.g. 0 is DSR is set),
|
||||
but here it is active high!
|
||||
*/
|
||||
#define SERIAL_STATE_DSR 0x0004
|
||||
|
||||
/*
|
||||
DTR = Data terminal Ready. (OUTPUT)
|
||||
TX contains new data.
|
||||
|
||||
NOTE:
|
||||
|
||||
This output is active low on serial chips (e.g. 0 is DTR is set),
|
||||
but here it is active high!
|
||||
*/
|
||||
#define SERIAL_STATE_DTR 0x0008
|
||||
/* RX = Recieve data. (INPUT) */
|
||||
#define SERIAL_STATE_RX_DATA 0x00010
|
||||
/* TX = Transmit data. (OUTPUT) */
|
||||
#define SERIAL_STATE_TX_DATA 0x00020
|
||||
|
||||
/* parity selections */
|
||||
/* if all the bits are added in a byte, if the result is:
|
||||
even -> parity is even
|
||||
odd -> parity is odd
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SERIAL_PARITY_NONE, /* no parity. a parity bit will not be in the transmitted/received data */
|
||||
SERIAL_PARITY_ODD, /* odd parity */
|
||||
SERIAL_PARITY_EVEN /* even parity */
|
||||
};
|
||||
|
||||
/* this macro is used to extract the received data from the status */
|
||||
#define get_in_data_bit(x) ((x & SERIAL_STATE_RX_DATA)>>4)
|
||||
|
||||
/* this macro is used to set the transmitted data in the status */
|
||||
#define set_out_data_bit(x, data) \
|
||||
x&=~SERIAL_STATE_TX_DATA; \
|
||||
x|=(data<<5)
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/**** SERIAL CONNECTION ***/
|
||||
|
||||
|
||||
/* this structure represents a serial connection */
|
||||
typedef struct _serial_connection serial_connection;
|
||||
struct _serial_connection
|
||||
{
|
||||
int id;
|
||||
/* state of this side */
|
||||
unsigned long State;
|
||||
|
||||
/* state of other side - store here */
|
||||
unsigned long input_state;
|
||||
|
||||
/* this callback is executed when this side has refreshed it's state,
|
||||
to let the other end know */
|
||||
void (*out_callback)(running_machine &machine, int id, unsigned long state);
|
||||
/* this callback is executed when the other side has refreshed it's state,
|
||||
to let the other end know */
|
||||
void (*in_callback)(running_machine &machine, int id, unsigned long state);
|
||||
};
|
||||
|
||||
/*----------- defined in machine/serial.c -----------*/
|
||||
|
||||
/* setup out and in callbacks */
|
||||
void serial_connection_init(running_machine &machine, serial_connection *connection);
|
||||
|
||||
/* set callback which will be executed when in status has changed */
|
||||
void serial_connection_set_in_callback(running_machine &machine, serial_connection *connection, void (*in_cb)(running_machine &machine, int id, unsigned long status));
|
||||
|
||||
/* output status, if callback is setup it will be executed with the new status */
|
||||
void serial_connection_out(running_machine &machine, serial_connection *connection);
|
||||
|
||||
/* join two serial connections */
|
||||
void serial_connection_link(running_machine &machine, serial_connection *connection_a, serial_connection *connection_b);
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
/* form of data being transmitted and received */
|
||||
typedef struct _data_form data_form;
|
||||
struct _data_form
|
||||
{
|
||||
/* length of word in bits */
|
||||
unsigned long word_length;
|
||||
/* parity state */
|
||||
unsigned long parity;
|
||||
/* number of stop bits */
|
||||
unsigned long stop_bit_count;
|
||||
};
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
/*******************************************************************************/
|
||||
/**** RECEIVE AND TRANSMIT GENERIC CODE ****/
|
||||
|
||||
/* this can be used by most of the serial chip implementations,
|
||||
because they all work in roughly the same way.
|
||||
There is generic code to send and receive data in the specified form */
|
||||
|
||||
/* receive is waiting for start bit. The transition from high-low indicates
|
||||
start of start bit. This is used to synchronise with the data being transfered */
|
||||
#define RECEIVE_REGISTER_WAITING_FOR_START_BIT 0x01
|
||||
/* receive is synchronised with data, data bits will be clocked in */
|
||||
#define RECEIVE_REGISTER_SYNCHRONISED 0x02
|
||||
/* set if receive register has been filled */
|
||||
#define RECEIVE_REGISTER_FULL 0x04
|
||||
|
||||
|
||||
/* the receive register holds data in receive form! */
|
||||
/* this must be extracted to get the data byte received */
|
||||
typedef struct _serial_receive_register serial_receive_register;
|
||||
struct _serial_receive_register
|
||||
{
|
||||
/* data */
|
||||
unsigned long register_data;
|
||||
/* flags */
|
||||
unsigned long flags;
|
||||
/* bit count received */
|
||||
unsigned long bit_count_received;
|
||||
/* length of data to receive - includes data bits, parity bit and stop bit */
|
||||
unsigned long bit_count;
|
||||
|
||||
/* the byte of data received */
|
||||
unsigned char byte_received;
|
||||
};
|
||||
|
||||
void receive_register_setup(serial_receive_register *receive, data_form *data_form);
|
||||
void receive_register_update_bit(serial_receive_register *receive, int bit_state);
|
||||
void receive_register_extract(serial_receive_register *receive_reg, data_form *data_form);
|
||||
void receive_register_reset(serial_receive_register *receive_reg);
|
||||
|
||||
/* the transmit register is the final stage
|
||||
in the serial transmit procedure */
|
||||
/* normally, data is written to the transmit reg,
|
||||
then it is assembled into transmit form and transmitted */
|
||||
/* the transmit register holds data in transmit form */
|
||||
|
||||
/* register is empty and ready to be filled with data */
|
||||
#define TRANSMIT_REGISTER_EMPTY 0x0001
|
||||
|
||||
typedef struct _serial_transmit_register serial_transmit_register;
|
||||
struct _serial_transmit_register
|
||||
{
|
||||
/* data */
|
||||
unsigned long register_data;
|
||||
/* flags */
|
||||
unsigned long flags;
|
||||
/* number of bits transmitted */
|
||||
unsigned long bit_count_transmitted;
|
||||
/* length of data to send */
|
||||
unsigned long bit_count;
|
||||
};
|
||||
|
||||
/* setup transmit reg ready for transmit */
|
||||
void transmit_register_setup(serial_transmit_register *transmit_reg, data_form *data_form,unsigned char data_byte);
|
||||
void transmit_register_send_bit(running_machine &machine, serial_transmit_register *transmit_reg, serial_connection *connection);
|
||||
void transmit_register_reset(serial_transmit_register *transmit_reg);
|
||||
|
||||
/*******************************************************************************/
|
||||
/**** SERIAL HELPER ****/
|
||||
|
||||
void serial_helper_setup(void);
|
||||
|
||||
/*******************************************************************************/
|
||||
/**** SERIAL DEVICE ****/
|
||||
|
||||
unsigned long serial_device_get_state(device_t *device);
|
||||
|
||||
/* connect this device to the emulated serial chip */
|
||||
/* id is the serial device to connect to */
|
||||
/* connection is the serial connection to connect to the serial device */
|
||||
void serial_device_connect(device_t *image, serial_connection *connection);
|
||||
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(SERIAL, serial);
|
||||
|
||||
#define MCFG_SERIAL_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD(_tag, SERIAL, 0)
|
||||
|
||||
DEVICE_START(serial);
|
||||
DEVICE_IMAGE_LOAD(serial);
|
||||
|
||||
void serial_device_setup(device_t *image, int baud_rate, int num_data_bits, int stop_bit_count, int parity_code);
|
||||
|
||||
/* set the transmit state of the serial device */
|
||||
void serial_device_set_transmit_state(device_t *image, int state);
|
||||
|
||||
#endif /* SERIAL_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,161 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
machine/upd765.h
|
||||
|
||||
Functions to emulate a NEC upd765/Intel 8272 compatible
|
||||
floppy disk controller
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __UPD765_H__
|
||||
#define __UPD765_H__
|
||||
|
||||
#include "devcb.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MACROS
|
||||
***************************************************************************/
|
||||
|
||||
DECLARE_LEGACY_DEVICE(UPD765A, upd765a);
|
||||
DECLARE_LEGACY_DEVICE(UPD765B, upd765b);
|
||||
DECLARE_LEGACY_DEVICE(SMC37C78, smc37c78);
|
||||
DECLARE_LEGACY_DEVICE(UPD72065, upd72065);
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
/* RDY pin connected state */
|
||||
typedef enum
|
||||
{
|
||||
UPD765_RDY_PIN_NOT_CONNECTED = 0,
|
||||
UPD765_RDY_PIN_CONNECTED = 1
|
||||
} UPD765_RDY_PIN;
|
||||
|
||||
#define UPD765_DAM_DELETED_DATA 0x0f8
|
||||
#define UPD765_DAM_DATA 0x0fb
|
||||
|
||||
typedef device_t *(*upd765_get_image_func)(device_t *device, int floppy_index);
|
||||
#define UPD765_GET_IMAGE(name) device_t *name(device_t *device, int floppy_index )
|
||||
|
||||
|
||||
typedef struct upd765_interface
|
||||
{
|
||||
/* interrupt issued */
|
||||
devcb_write_line out_int_func;
|
||||
|
||||
/* dma data request */
|
||||
devcb_write_line out_drq_func;
|
||||
|
||||
/* image lookup */
|
||||
upd765_get_image_func get_image;
|
||||
|
||||
UPD765_RDY_PIN rdy_pin;
|
||||
|
||||
const char *floppy_drive_tags[4];
|
||||
} upd765_interface;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* read of data register */
|
||||
READ8_DEVICE_HANDLER(upd765_data_r);
|
||||
/* write to data register */
|
||||
WRITE8_DEVICE_HANDLER(upd765_data_w);
|
||||
/* read of main status register */
|
||||
READ8_DEVICE_HANDLER(upd765_status_r);
|
||||
|
||||
/* dma acknowledge with write */
|
||||
WRITE8_DEVICE_HANDLER(upd765_dack_w);
|
||||
/* dma acknowledge with read */
|
||||
READ8_DEVICE_HANDLER(upd765_dack_r);
|
||||
|
||||
/* reset upd765 */
|
||||
void upd765_reset(device_t *device, int);
|
||||
|
||||
/* reset pin of upd765 */
|
||||
WRITE_LINE_DEVICE_HANDLER(upd765_reset_w);
|
||||
|
||||
/* set upd765 terminal count input state */
|
||||
WRITE_LINE_DEVICE_HANDLER(upd765_tc_w);
|
||||
|
||||
/* set upd765 ready input*/
|
||||
WRITE_LINE_DEVICE_HANDLER(upd765_ready_w);
|
||||
|
||||
void upd765_idle(device_t *device);
|
||||
|
||||
/*********************/
|
||||
/* STATUS REGISTER 1 */
|
||||
|
||||
/* this is set if a TC signal was not received after the sector data was read */
|
||||
#define UPD765_ST1_END_OF_CYLINDER (1<<7)
|
||||
/* this is set if the sector ID being searched for is not found */
|
||||
#define UPD765_ST1_NO_DATA (1<<2)
|
||||
/* set if disc is write protected and a write/format operation was performed */
|
||||
#define UPD765_ST1_NOT_WRITEABLE (1<<1)
|
||||
|
||||
/*********************/
|
||||
/* STATUS REGISTER 2 */
|
||||
|
||||
/* C parameter specified did not match C value read from disc */
|
||||
#define UPD765_ST2_WRONG_CYLINDER (1<<4)
|
||||
/* C parameter specified did not match C value read from disc, and C read from disc was 0x0ff */
|
||||
#define UPD765_ST2_BAD_CYLINDER (1<<1)
|
||||
/* this is set if the FDC encounters a Deleted Data Mark when executing a read data
|
||||
command, or FDC encounters a Data Mark when executing a read deleted data command */
|
||||
#define UPD765_ST2_CONTROL_MARK (1<<6)
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MCFG_UPD765A_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, UPD765A, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_UPD765A_MODIFY(_tag, _intrf) \
|
||||
MCFG_DEVICE_MODIFY(_tag) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_UPD765A_REMOVE(_tag) \
|
||||
MCFG_DEVICE_REMOVE(_tag)
|
||||
|
||||
#define MCFG_UPD765B_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, UPD765B, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_UPD765B_MODIFY(_tag, _intrf) \
|
||||
MCFG_DEVICE_MODIFY(_tag) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_UPD765B_REMOVE(_tag) \
|
||||
MCFG_DEVICE_REMOVE(_tag)
|
||||
|
||||
#define MCFG_SMC37C78_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, SMC37C78, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_SMC37C78_MODIFY(_tag, _intrf) \
|
||||
MCFG_DEVICE_MODIFY(_tag) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_SMC37C78_REMOVE(_tag) \
|
||||
MCFG_DEVICE_REMOVE(_tag)
|
||||
|
||||
#define MCFG_UPD72065_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, UPD72065, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_UPD72065_MODIFY(_tag, _intrf) \
|
||||
MCFG_DEVICE_MODIFY(_tag) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#define MCFG_UPD72065_REMOVE(_tag) \
|
||||
MCFG_DEVICE_REMOVE(_tag)
|
||||
|
||||
|
||||
#endif /* __UPD765_H__ */
|
@ -66,18 +66,13 @@ Notes:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "imagedev/cartslot.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/ram.h"
|
||||
#include "imagedev/printer.h"
|
||||
#include "formats/basicdsk.h"
|
||||
#include "machine/ctronics.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/msm8251.h"
|
||||
#include "machine/upd765.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "video/tms9928a.h"
|
||||
#include "crsshair.h"
|
||||
#include "includes/sg1000.h"
|
||||
|
||||
@ -237,32 +232,6 @@ static ADDRESS_MAP_START( sc3000_io_map, AS_IO, 8, sg1000_state )
|
||||
ADDRESS_MAP_END
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
ADDRESS_MAP( sf7000_map )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static ADDRESS_MAP_START( sf7000_map, AS_PROGRAM, 8, sf7000_state )
|
||||
AM_RANGE(0x0000, 0x3fff) AM_READ_BANK("bank1") AM_WRITE_BANK("bank2")
|
||||
AM_RANGE(0x4000, 0xffff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/*-------------------------------------------------
|
||||
ADDRESS_MAP( sf7000_io_map )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static ADDRESS_MAP_START( sf7000_io_map, AS_IO, 8, sf7000_state )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||
AM_RANGE(0x7f, 0x7f) AM_DEVWRITE_LEGACY(SN76489A_TAG, sn76496_w)
|
||||
AM_RANGE(0xbe, 0xbe) AM_READWRITE_LEGACY(TMS9928A_vram_r, TMS9928A_vram_w)
|
||||
AM_RANGE(0xbf, 0xbf) AM_READWRITE_LEGACY(TMS9928A_register_r, TMS9928A_register_w)
|
||||
AM_RANGE(0xdc, 0xdf) AM_DEVREADWRITE(UPD9255_0_TAG, i8255_device, read, write)
|
||||
AM_RANGE(0xe0, 0xe0) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r)
|
||||
AM_RANGE(0xe1, 0xe1) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w)
|
||||
AM_RANGE(0xe4, 0xe7) AM_DEVREADWRITE(UPD9255_1_TAG, i8255_device, read, write)
|
||||
AM_RANGE(0xe8, 0xe8) AM_DEVREADWRITE_LEGACY(UPD8251_TAG, msm8251_data_r, msm8251_data_w)
|
||||
AM_RANGE(0xe9, 0xe9) AM_DEVREADWRITE_LEGACY(UPD8251_TAG, msm8251_status_r, msm8251_control_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/***************************************************************************
|
||||
INPUT PORTS
|
||||
***************************************************************************/
|
||||
@ -378,7 +347,7 @@ INPUT_PORTS_END
|
||||
INPUT_PORTS( sk1100 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static INPUT_PORTS_START( sk1100 )
|
||||
INPUT_PORTS_START( sk1100 )
|
||||
PORT_START("PA0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q')
|
||||
@ -509,23 +478,6 @@ static INPUT_PORTS_START( sc3000 )
|
||||
PORT_INCLUDE( tvdraw )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/*-------------------------------------------------
|
||||
INPUT_PORTS( sf7000 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static INPUT_PORTS_START( sf7000 )
|
||||
PORT_INCLUDE( sk1100 )
|
||||
|
||||
PORT_START("BAUD")
|
||||
PORT_CONFNAME( 0x05, 0x05, "Baud rate")
|
||||
PORT_CONFSETTING( 0x00, "9600 baud" )
|
||||
PORT_CONFSETTING( 0x01, "4800 baud" )
|
||||
PORT_CONFSETTING( 0x02, "2400 baud" )
|
||||
PORT_CONFSETTING( 0x03, "1200 baud" )
|
||||
PORT_CONFSETTING( 0x04, "600 baud" )
|
||||
PORT_CONFSETTING( 0x05, "300 baud" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION
|
||||
***************************************************************************/
|
||||
@ -534,7 +486,7 @@ INPUT_PORTS_END
|
||||
TMS9928a_interface tms9928a_interface
|
||||
-------------------------------------------------*/
|
||||
|
||||
static INTERRUPT_GEN( sg1000_int )
|
||||
INTERRUPT_GEN( sg1000_int )
|
||||
{
|
||||
TMS9928A_interrupt(device->machine());
|
||||
}
|
||||
@ -544,7 +496,7 @@ static void sg1000_vdp_interrupt(running_machine &machine, int state)
|
||||
cputag_set_input_line(machine, Z80_TAG, INPUT_LINE_IRQ0, state);
|
||||
}
|
||||
|
||||
static const TMS9928a_interface tms9928a_interface =
|
||||
const TMS9928a_interface tms9928a_interface =
|
||||
{
|
||||
TMS99x8A,
|
||||
0x4000,
|
||||
@ -632,7 +584,7 @@ WRITE8_MEMBER( sc3000_state::ppi_pc_w )
|
||||
/* TODO printer */
|
||||
}
|
||||
|
||||
static I8255_INTERFACE( sc3000_ppi_intf )
|
||||
I8255_INTERFACE( sc3000_ppi_intf )
|
||||
{
|
||||
DEVCB_DRIVER_MEMBER(sc3000_state, ppi_pa_r), // Port A read
|
||||
DEVCB_NULL, // Port A write
|
||||
@ -646,7 +598,7 @@ static I8255_INTERFACE( sc3000_ppi_intf )
|
||||
cassette_config sc3000_cassette_config
|
||||
-------------------------------------------------*/
|
||||
|
||||
static const cassette_config sc3000_cassette_config =
|
||||
const cassette_config sc3000_cassette_config =
|
||||
{
|
||||
cassette_default_formats,
|
||||
NULL,
|
||||
@ -654,126 +606,6 @@ static const cassette_config sc3000_cassette_config =
|
||||
NULL
|
||||
};
|
||||
|
||||
/*-------------------------------------------------
|
||||
I8255_INTERFACE( sf7000_ppi_intf )
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER( sf7000_state::ppi_pa_r )
|
||||
{
|
||||
/*
|
||||
Signal Description
|
||||
|
||||
PA0 INT from FDC
|
||||
PA1 BUSY from Centronics printer
|
||||
PA2 INDEX from FDD
|
||||
PA3
|
||||
PA4
|
||||
PA5
|
||||
PA6
|
||||
PA7
|
||||
*/
|
||||
|
||||
UINT8 data = 0;
|
||||
|
||||
data |= m_fdc_irq;
|
||||
data |= centronics_busy_r(m_centronics) << 1;
|
||||
data |= m_fdc_index << 2;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sf7000_state::ppi_pc_w )
|
||||
{
|
||||
/*
|
||||
Signal Description
|
||||
|
||||
PC0 /INUSE signal to FDD
|
||||
PC1 /MOTOR ON signal to FDD
|
||||
PC2 TC signal to FDC
|
||||
PC3 RESET signal to FDC
|
||||
PC4 not connected
|
||||
PC5 not connected
|
||||
PC6 /ROM SEL (switch between IPL ROM and RAM)
|
||||
PC7 /STROBE to Centronics printer
|
||||
*/
|
||||
|
||||
/* floppy motor */
|
||||
floppy_mon_w(m_floppy0, BIT(data, 1));
|
||||
floppy_drive_set_ready_state(m_floppy0, 1, 1);
|
||||
|
||||
/* FDC terminal count */
|
||||
upd765_tc_w(m_fdc, BIT(data, 2));
|
||||
|
||||
/* FDC reset */
|
||||
if (BIT(data, 3))
|
||||
{
|
||||
upd765_reset(m_fdc, 0);
|
||||
}
|
||||
|
||||
/* ROM selection */
|
||||
memory_set_bank(machine(), "bank1", BIT(data, 6));
|
||||
|
||||
/* printer strobe */
|
||||
centronics_strobe_w(m_centronics, BIT(data, 7));
|
||||
}
|
||||
|
||||
static I8255_INTERFACE( sf7000_ppi_intf )
|
||||
{
|
||||
DEVCB_DRIVER_MEMBER(sf7000_state, ppi_pa_r), // Port A read
|
||||
DEVCB_NULL, // Port A write
|
||||
DEVCB_NULL, // Port B read
|
||||
DEVCB_DEVICE_HANDLER(CENTRONICS_TAG, centronics_data_w), // Port B write
|
||||
DEVCB_NULL, // Port C read
|
||||
DEVCB_DRIVER_MEMBER(sf7000_state, ppi_pc_w) // Port C write
|
||||
};
|
||||
|
||||
/*-------------------------------------------------
|
||||
upd765_interface sf7000_upd765_interface
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE_LINE_MEMBER( sf7000_state::fdc_intrq_w )
|
||||
{
|
||||
m_fdc_irq = state;
|
||||
}
|
||||
|
||||
static const struct upd765_interface sf7000_upd765_interface =
|
||||
{
|
||||
DEVCB_DRIVER_LINE_MEMBER(sf7000_state, fdc_intrq_w),
|
||||
DEVCB_NULL,
|
||||
NULL,
|
||||
UPD765_RDY_PIN_CONNECTED,
|
||||
{ FLOPPY_0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_OPTIONS( sf7000 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static FLOPPY_OPTIONS_START( sf7000 )
|
||||
FLOPPY_OPTION(sf7000, "sf7", "SF7 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
|
||||
HEADS([1])
|
||||
TRACKS([40])
|
||||
SECTORS([16])
|
||||
SECTOR_LENGTH([256])
|
||||
FIRST_SECTOR_ID([1]))
|
||||
FLOPPY_OPTIONS_END
|
||||
|
||||
/*-------------------------------------------------
|
||||
floppy_config sf7000_floppy_config
|
||||
-------------------------------------------------*/
|
||||
|
||||
static const floppy_config sf7000_floppy_config =
|
||||
{
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
FLOPPY_STANDARD_5_25_DSHD,
|
||||
FLOPPY_OPTIONS_NAME(sf7000),
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
CARTRIDGE LOADING
|
||||
***************************************************************************/
|
||||
@ -994,50 +826,6 @@ void sc3000_state::machine_start()
|
||||
state_save_register_global(machine(), m_keylatch);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
sf7000_fdc_index_callback -
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void sf7000_fdc_index_callback(device_t *controller, device_t *img, int state)
|
||||
{
|
||||
sf7000_state *driver_state = img->machine().driver_data<sf7000_state>();
|
||||
|
||||
driver_state->m_fdc_index = state;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
MACHINE_START( sf7000 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
void sf7000_state::machine_start()
|
||||
{
|
||||
/* configure VDP */
|
||||
TMS9928A_configure(&tms9928a_interface);
|
||||
|
||||
/* configure FDC */
|
||||
floppy_drive_set_index_pulse_callback(m_floppy0, sf7000_fdc_index_callback);
|
||||
|
||||
/* configure memory banking */
|
||||
memory_configure_bank(machine(), "bank1", 0, 1, machine().region(Z80_TAG)->base(), 0);
|
||||
memory_configure_bank(machine(), "bank1", 1, 1, ram_get_ptr(m_ram), 0);
|
||||
memory_configure_bank(machine(), "bank2", 0, 1, ram_get_ptr(m_ram), 0);
|
||||
|
||||
/* register for state saving */
|
||||
state_save_register_global(machine(), m_keylatch);
|
||||
state_save_register_global(machine(), m_fdc_irq);
|
||||
state_save_register_global(machine(), m_fdc_index);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
MACHINE_RESET( sf7000 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
void sf7000_state::machine_reset()
|
||||
{
|
||||
memory_set_bank(machine(), "bank1", 0);
|
||||
memory_set_bank(machine(), "bank2", 0);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
MACHINE DRIVERS
|
||||
***************************************************************************/
|
||||
@ -1138,42 +926,6 @@ static MACHINE_CONFIG_START( sc3000, sc3000_state )
|
||||
MCFG_RAM_DEFAULT_SIZE("2K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/*-------------------------------------------------
|
||||
MACHINE_CONFIG_START( sf7000, sf7000_state )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static MACHINE_CONFIG_START( sf7000, sf7000_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_10_738635MHz/3)
|
||||
MCFG_CPU_PROGRAM_MAP(sf7000_map)
|
||||
MCFG_CPU_IO_MAP(sf7000_io_map)
|
||||
MCFG_CPU_VBLANK_INT(SCREEN_TAG, sg1000_int)
|
||||
|
||||
/* video hardware */
|
||||
MCFG_FRAGMENT_ADD(tms9928a)
|
||||
MCFG_SCREEN_MODIFY(SCREEN_TAG)
|
||||
MCFG_SCREEN_REFRESH_RATE((float)XTAL_10_738635MHz/2/342/262)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD(SN76489A_TAG, SN76489A, XTAL_10_738635MHz/3)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
/* devices */
|
||||
MCFG_I8255_ADD(UPD9255_0_TAG, sc3000_ppi_intf)
|
||||
MCFG_I8255_ADD(UPD9255_1_TAG, sf7000_ppi_intf)
|
||||
MCFG_MSM8251_ADD(UPD8251_TAG, default_msm8251_interface)
|
||||
MCFG_UPD765A_ADD(UPD765_TAG, sf7000_upd765_interface)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FLOPPY_0, sf7000_floppy_config)
|
||||
// MCFG_PRINTER_ADD("sp400") /* serial printer */
|
||||
MCFG_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics)
|
||||
MCFG_CASSETTE_ADD(CASSETTE_TAG, sc3000_cassette_config)
|
||||
|
||||
/* internal ram */
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("64K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/***************************************************************************
|
||||
ROMS
|
||||
@ -1202,11 +954,6 @@ ROM_START( omv2000 )
|
||||
ROM_LOAD( "omvbios.bin", 0x0000, 0x4000, CRC(c5a67b95) SHA1(6d7c64dd60dee4a33061d3d3a7c2ed190d895cdb) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( sf7000 )
|
||||
ROM_REGION( 0x10000, Z80_TAG, 0 )
|
||||
ROM_LOAD( "ipl.rom", 0x0000, 0x2000, CRC(d76810b8) SHA1(77339a6db2593aadc638bed77b8e9bed5d9d87e3) )
|
||||
ROM_END
|
||||
|
||||
/***************************************************************************
|
||||
SYSTEM DRIVERS
|
||||
***************************************************************************/
|
||||
@ -1216,6 +963,5 @@ CONS( 1983, sg1000, 0, 0, sg1000, sg1000, 0,
|
||||
CONS( 1984, sg1000m2, sg1000, 0, sc3000, sc3000, 0, "Sega", "SG-1000 II", GAME_SUPPORTS_SAVE )
|
||||
COMP( 1983, sc3000, 0, sg1000, sc3000, sc3000, 0, "Sega", "SC-3000", GAME_SUPPORTS_SAVE )
|
||||
COMP( 1983, sc3000h, sc3000, 0, sc3000, sc3000, 0, "Sega", "SC-3000H", GAME_SUPPORTS_SAVE )
|
||||
COMP( 1983, sf7000, sc3000, 0, sf7000, sf7000, 0, "Sega", "SC-3000/Super Control Station SF-7000", GAME_SUPPORTS_SAVE )
|
||||
CONS( 1984, omv1000, sg1000, 0, omv, omv, 0, "Tsukuda Original", "Othello Multivision FG-1000", GAME_SUPPORTS_SAVE )
|
||||
CONS( 1984, omv2000, sg1000, 0, omv, omv, 0, "Tsukuda Original", "Othello Multivision FG-2000", GAME_SUPPORTS_SAVE )
|
||||
|
@ -2,6 +2,8 @@
|
||||
#define __SG1000__
|
||||
|
||||
#include "machine/ram.h"
|
||||
#include "video/tms9928a.h"
|
||||
#include "imagedev/cassette.h"
|
||||
|
||||
#define SCREEN_TAG "screen"
|
||||
#define Z80_TAG "z80"
|
||||
@ -26,6 +28,12 @@
|
||||
#define IS_CARTRIDGE_MUSIC_EDITOR(ptr) \
|
||||
(!strncmp("PIANO", (const char *)&ptr[0x0841], 5))
|
||||
|
||||
extern const TMS9928a_interface tms9928a_interface;
|
||||
INPUT_PORTS_EXTERN( sk1100 );
|
||||
extern INTERRUPT_GEN( sg1000_int );
|
||||
extern const i8255_interface ( sc3000_ppi_intf );
|
||||
extern const cassette_config sc3000_cassette_config;
|
||||
|
||||
class sg1000_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -73,30 +81,4 @@ public:
|
||||
DECLARE_WRITE8_MEMBER( ppi_pc_w );
|
||||
};
|
||||
|
||||
class sf7000_state : public sc3000_state
|
||||
{
|
||||
public:
|
||||
sf7000_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: sc3000_state(mconfig, type, tag),
|
||||
m_fdc(*this, UPD765_TAG),
|
||||
m_centronics(*this, CENTRONICS_TAG),
|
||||
m_floppy0(*this, FLOPPY_0)
|
||||
{ }
|
||||
|
||||
required_device<device_t> m_fdc;
|
||||
required_device<device_t> m_centronics;
|
||||
required_device<device_t> m_floppy0;
|
||||
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
|
||||
DECLARE_READ8_MEMBER( ppi_pa_r );
|
||||
DECLARE_WRITE8_MEMBER( ppi_pc_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_intrq_w );
|
||||
|
||||
/* floppy state */
|
||||
int m_fdc_irq;
|
||||
int m_fdc_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user