mirror of
https://github.com/holub/mame
synced 2025-07-02 08:39:21 +03:00
Imported Z80 DART and Z80 STI from MESS. (no whatsnew)
This commit is contained in:
parent
aac8859b80
commit
5826c45ea4
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -756,12 +756,16 @@ src/emu/machine/x76f100.c svneol=native#text/plain
|
||||
src/emu/machine/x76f100.h svneol=native#text/plain
|
||||
src/emu/machine/z80ctc.c svneol=native#text/plain
|
||||
src/emu/machine/z80ctc.h svneol=native#text/plain
|
||||
src/emu/machine/z80dart.c svneol=native#text/plain
|
||||
src/emu/machine/z80dart.h svneol=native#text/plain
|
||||
src/emu/machine/z80dma.c svneol=native#text/plain
|
||||
src/emu/machine/z80dma.h svneol=native#text/plain
|
||||
src/emu/machine/z80pio.c svneol=native#text/plain
|
||||
src/emu/machine/z80pio.h svneol=native#text/plain
|
||||
src/emu/machine/z80sio.c svneol=native#text/plain
|
||||
src/emu/machine/z80sio.h svneol=native#text/plain
|
||||
src/emu/machine/z80sti.c svneol=native#text/plain
|
||||
src/emu/machine/z80sti.h svneol=native#text/plain
|
||||
src/emu/mame.c svneol=native#text/plain
|
||||
src/emu/mame.h svneol=native#text/plain
|
||||
src/emu/mconfig.c svneol=native#text/plain
|
||||
|
@ -179,9 +179,11 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/x76f041.o \
|
||||
$(EMUMACHINE)/x76f100.o \
|
||||
$(EMUMACHINE)/z80ctc.o \
|
||||
$(EMUMACHINE)/z80dart.o \
|
||||
$(EMUMACHINE)/z80dma.o \
|
||||
$(EMUMACHINE)/z80pio.o \
|
||||
$(EMUMACHINE)/z80sio.o \
|
||||
$(EMUMACHINE)/z80sti.o \
|
||||
|
||||
EMUVIDEOOBJS = \
|
||||
$(EMUVIDEO)/generic.o \
|
||||
|
1504
src/emu/machine/z80dart.c
Normal file
1504
src/emu/machine/z80dart.c
Normal file
File diff suppressed because it is too large
Load Diff
132
src/emu/machine/z80dart.h
Normal file
132
src/emu/machine/z80dart.h
Normal file
@ -0,0 +1,132 @@
|
||||
/***************************************************************************
|
||||
|
||||
Z80 DART Dual Asynchronous Receiver/Transmitter implementation
|
||||
|
||||
Copyright (c) 2008, The MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
****************************************************************************
|
||||
_____ _____
|
||||
D1 1 |* \_/ | 40 D0
|
||||
D3 2 | | 39 D2
|
||||
D5 3 | | 38 D4
|
||||
D7 4 | | 37 D6
|
||||
_INT 5 | | 36 _IORQ
|
||||
IEI 6 | | 35 _CE
|
||||
IEO 7 | | 34 B/_A
|
||||
_M1 8 | | 33 C/_D
|
||||
Vdd 9 | | 32 _RD
|
||||
_W/RDYA 10 | Z80-DART | 31 GND
|
||||
_RIA 11 | | 30 _W/RDYB
|
||||
RxDA 12 | | 29 _RIB
|
||||
_RxCA 13 | | 28 RxDB
|
||||
_TxCA 14 | | 27 _RxTxCB
|
||||
TxDA 15 | | 26 TxDB
|
||||
_DTRA 16 | | 25 _DTRB
|
||||
_RTSA 17 | | 24 _RTSB
|
||||
_CTSA 18 | | 23 _CTSB
|
||||
_DCDA 19 | | 22 _DCDB
|
||||
CLK 20 |_____________| 21 _RESET
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __Z80DART_H_
|
||||
#define __Z80DART_H_
|
||||
|
||||
#include "devcb.h"
|
||||
|
||||
/***************************************************************************
|
||||
MACROS / CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define Z80DART DEVICE_GET_INFO_NAME(z80dart)
|
||||
/*
|
||||
#define Z8470 DEVICE_GET_INFO_NAME(z8470)
|
||||
#define LH0081 DEVICE_GET_INFO_NAME(lh0088)
|
||||
#define MK3881 DEVICE_GET_INFO_NAME(mk3888)
|
||||
*/
|
||||
|
||||
#define MDRV_Z80DART_ADD(_tag, _clock, _config) \
|
||||
MDRV_DEVICE_ADD(_tag, Z80DART, _clock) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
#define MDRV_Z80DART_REMOVE(_tag) \
|
||||
MDRV_DEVICE_REMOVE(_tag)
|
||||
|
||||
#define Z80DART_INTERFACE(_name) \
|
||||
const z80dart_interface (_name) =
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
Z80DART_CH_A = 0,
|
||||
Z80DART_CH_B
|
||||
};
|
||||
|
||||
typedef struct _z80dart_interface z80dart_interface;
|
||||
struct _z80dart_interface
|
||||
{
|
||||
int rx_clock_a; /* channel A receive clock */
|
||||
int tx_clock_a; /* channel A transmit clock */
|
||||
int rx_tx_clock_b; /* channel B receive/transmit clock */
|
||||
|
||||
devcb_read_line in_rxda_func;
|
||||
devcb_write_line out_txda_func;
|
||||
devcb_write_line out_dtra_func;
|
||||
devcb_write_line out_rtsa_func;
|
||||
devcb_write_line out_wrdya_func;
|
||||
|
||||
devcb_read_line in_rxdb_func;
|
||||
devcb_write_line out_txdb_func;
|
||||
devcb_write_line out_dtrb_func;
|
||||
devcb_write_line out_rtsb_func;
|
||||
devcb_write_line out_wrdyb_func;
|
||||
|
||||
devcb_write_line out_int_func;
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* register access */
|
||||
READ8_DEVICE_HANDLER( z80dart_cd_ba_r );
|
||||
WRITE8_DEVICE_HANDLER( z80dart_cd_ba_w );
|
||||
|
||||
READ8_DEVICE_HANDLER( z80dart_ba_cd_r );
|
||||
WRITE8_DEVICE_HANDLER( z80dart_ba_cd_w );
|
||||
|
||||
/* control register access */
|
||||
WRITE8_DEVICE_HANDLER( z80dart_c_w );
|
||||
READ8_DEVICE_HANDLER( z80dart_c_r );
|
||||
|
||||
/* data register access */
|
||||
WRITE8_DEVICE_HANDLER( z80dart_d_w );
|
||||
READ8_DEVICE_HANDLER( z80dart_d_r );
|
||||
|
||||
/* serial clocks */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w );
|
||||
|
||||
/* ring indicator */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_ria_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rib_w );
|
||||
|
||||
/* data carrier detected */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_dcda_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w );
|
||||
|
||||
/* clear to send */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_ctsa_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_ctsb_w );
|
||||
|
||||
/* receive data byte HACK */
|
||||
void z80dart_receive_data(running_device *device, int channel, UINT8 data);
|
||||
|
||||
DEVICE_GET_INFO( z80dart );
|
||||
|
||||
#endif
|
849
src/emu/machine/z80sti.c
Normal file
849
src/emu/machine/z80sti.c
Normal file
@ -0,0 +1,849 @@
|
||||
/***************************************************************************
|
||||
|
||||
Mostek MK3801 Serial Timer Interrupt Controller (Z80-STI) emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- timers (other than delay mode)
|
||||
- serial I/O
|
||||
- reset behavior
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "z80sti.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/z80/z80daisy.h"
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
/* registers */
|
||||
enum
|
||||
{
|
||||
Z80STI_REGISTER_IR = 0,
|
||||
Z80STI_REGISTER_GPIP,
|
||||
Z80STI_REGISTER_IPRB,
|
||||
Z80STI_REGISTER_IPRA,
|
||||
Z80STI_REGISTER_ISRB,
|
||||
Z80STI_REGISTER_ISRA,
|
||||
Z80STI_REGISTER_IMRB,
|
||||
Z80STI_REGISTER_IMRA,
|
||||
Z80STI_REGISTER_PVR,
|
||||
Z80STI_REGISTER_TABC,
|
||||
Z80STI_REGISTER_TBDR,
|
||||
Z80STI_REGISTER_TADR,
|
||||
Z80STI_REGISTER_UCR,
|
||||
Z80STI_REGISTER_RSR,
|
||||
Z80STI_REGISTER_TSR,
|
||||
Z80STI_REGISTER_UDR
|
||||
};
|
||||
|
||||
/* variable registers */
|
||||
enum
|
||||
{
|
||||
Z80STI_REGISTER_IR_SCR = 0,
|
||||
Z80STI_REGISTER_IR_TDDR,
|
||||
Z80STI_REGISTER_IR_TCDR,
|
||||
Z80STI_REGISTER_IR_AER,
|
||||
Z80STI_REGISTER_IR_IERB,
|
||||
Z80STI_REGISTER_IR_IERA,
|
||||
Z80STI_REGISTER_IR_DDR,
|
||||
Z80STI_REGISTER_IR_TCDC
|
||||
};
|
||||
|
||||
/* timers */
|
||||
enum
|
||||
{
|
||||
TIMER_A = 0,
|
||||
TIMER_B,
|
||||
TIMER_C,
|
||||
TIMER_D,
|
||||
TIMER_COUNT
|
||||
};
|
||||
|
||||
/* interrupt levels */
|
||||
enum
|
||||
{
|
||||
Z80STI_IR_P0 = 0,
|
||||
Z80STI_IR_P1,
|
||||
Z80STI_IR_P2,
|
||||
Z80STI_IR_P3,
|
||||
Z80STI_IR_TD,
|
||||
Z80STI_IR_TC,
|
||||
Z80STI_IR_P4,
|
||||
Z80STI_IR_P5,
|
||||
Z80STI_IR_TB,
|
||||
Z80STI_IR_XE,
|
||||
Z80STI_IR_XB,
|
||||
Z80STI_IR_RE,
|
||||
Z80STI_IR_RB,
|
||||
Z80STI_IR_TA,
|
||||
Z80STI_IR_P6,
|
||||
Z80STI_IR_P7
|
||||
};
|
||||
|
||||
/* timer C/D control register */
|
||||
#define Z80STI_TCDC_TARS 0x80
|
||||
#define Z80STI_TCDC_TBRS 0x08
|
||||
|
||||
/* interrupt vector register */
|
||||
#define Z80STI_PVR_ISE 0x08
|
||||
#define Z80STI_PVR_VR4 0x10
|
||||
|
||||
/* general purpose I/O interrupt levels */
|
||||
static const int INT_LEVEL_GPIP[] =
|
||||
{
|
||||
Z80STI_IR_P0, Z80STI_IR_P1, Z80STI_IR_P2, Z80STI_IR_P3, Z80STI_IR_P4, Z80STI_IR_P5, Z80STI_IR_P6, Z80STI_IR_P7
|
||||
};
|
||||
|
||||
/* timer interrupt levels */
|
||||
static const int INT_LEVEL_TIMER[] =
|
||||
{
|
||||
Z80STI_IR_TA, Z80STI_IR_TB, Z80STI_IR_TC, Z80STI_IR_TD
|
||||
};
|
||||
|
||||
/* interrupt vectors */
|
||||
static const UINT8 INT_VECTOR[] =
|
||||
{
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
|
||||
0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e
|
||||
};
|
||||
|
||||
/* timer prescaler divisors */
|
||||
static const int PRESCALER[] = { 0, 4, 10, 16, 50, 64, 100, 200 };
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _z80sti_t z80sti_t;
|
||||
struct _z80sti_t
|
||||
{
|
||||
/* device callbacks */
|
||||
devcb_resolved_read8 in_gpio_func;
|
||||
devcb_resolved_write8 out_gpio_func;
|
||||
devcb_resolved_read_line in_si_func;
|
||||
devcb_resolved_write_line out_so_func;
|
||||
devcb_resolved_write_line out_tao_func;
|
||||
devcb_resolved_write_line out_tbo_func;
|
||||
devcb_resolved_write_line out_tco_func;
|
||||
devcb_resolved_write_line out_tdo_func;
|
||||
devcb_resolved_write_line out_int_func;
|
||||
|
||||
/* I/O state */
|
||||
UINT8 gpip; /* general purpose I/O register */
|
||||
UINT8 aer; /* active edge register */
|
||||
UINT8 ddr; /* data direction register */
|
||||
|
||||
/* interrupt state */
|
||||
UINT16 ier; /* interrupt enable register */
|
||||
UINT16 ipr; /* interrupt pending register */
|
||||
UINT16 isr; /* interrupt in-service register */
|
||||
UINT16 imr; /* interrupt mask register */
|
||||
UINT8 pvr; /* interrupt vector register */
|
||||
int int_state[16]; /* interrupt state */
|
||||
|
||||
/* timer state */
|
||||
UINT8 tabc; /* timer A/B control register */
|
||||
UINT8 tcdc; /* timer C/D control register */
|
||||
UINT8 tdr[TIMER_COUNT]; /* timer data registers */
|
||||
UINT8 tmc[TIMER_COUNT]; /* timer main counters */
|
||||
int to[TIMER_COUNT]; /* timer out latch */
|
||||
|
||||
/* serial state */
|
||||
UINT8 scr; /* synchronous character register */
|
||||
UINT8 ucr; /* USART control register */
|
||||
UINT8 tsr; /* transmitter status register */
|
||||
UINT8 rsr; /* receiver status register */
|
||||
UINT8 udr; /* USART data register */
|
||||
|
||||
/* timers */
|
||||
emu_timer *timer[TIMER_COUNT]; /* counter timers */
|
||||
emu_timer *rx_timer; /* serial receive timer */
|
||||
emu_timer *tx_timer; /* serial transmit timer */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
static int z80sti_irq_state(running_device *device);
|
||||
static void z80sti_irq_reti(running_device *device);
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
INLINE z80sti_t *get_safe_token(running_device *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->token != NULL);
|
||||
assert(device->type == Z80STI);
|
||||
return (z80sti_t *)device->token;
|
||||
}
|
||||
|
||||
INLINE const z80sti_interface *get_interface(running_device *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert((device->type == Z80STI));
|
||||
return (const z80sti_interface *) device->baseconfig().static_config;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
check_interrupts - set the interrupt request
|
||||
line state
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void check_interrupts(z80sti_t *z80sti)
|
||||
{
|
||||
if (z80sti->ipr & z80sti->imr)
|
||||
{
|
||||
devcb_call_write_line(&z80sti->out_int_func, ASSERT_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
devcb_call_write_line(&z80sti->out_int_func, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
take_interrupt - mark an interrupt pending
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void take_interrupt(z80sti_t *z80sti, int level)
|
||||
{
|
||||
/* set interrupt pending register bit */
|
||||
z80sti->ipr |= 1 << level;
|
||||
|
||||
/* trigger interrupt */
|
||||
z80sti->int_state[level] |= Z80_DAISY_INT;
|
||||
|
||||
check_interrupts(z80sti);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
serial_receive - receive serial bit
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void serial_receive(z80sti_t *z80sti)
|
||||
{
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
TIMER_CALLBACK( rx_tick )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( rx_tick )
|
||||
{
|
||||
running_device *device = (running_device *)ptr;
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
serial_receive(z80sti);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
serial_transmit - transmit serial bit
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void serial_transmit(z80sti_t *z80sti)
|
||||
{
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
TIMER_CALLBACK( tx_tick )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( tx_tick )
|
||||
{
|
||||
running_device *device = (running_device *)ptr;
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
serial_transmit(z80sti);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_r - register read
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER( z80sti_r )
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
switch (offset & 0x0f)
|
||||
{
|
||||
case Z80STI_REGISTER_IR:
|
||||
switch (z80sti->pvr & 0x07)
|
||||
{
|
||||
case Z80STI_REGISTER_IR_SCR: return z80sti->scr;
|
||||
case Z80STI_REGISTER_IR_TDDR: return z80sti->tmc[TIMER_D];
|
||||
case Z80STI_REGISTER_IR_TCDR: return z80sti->tmc[TIMER_C];
|
||||
case Z80STI_REGISTER_IR_AER: return z80sti->aer;
|
||||
case Z80STI_REGISTER_IR_IERB: return z80sti->ier & 0xff;
|
||||
case Z80STI_REGISTER_IR_IERA: return z80sti->ier >> 8;
|
||||
case Z80STI_REGISTER_IR_DDR: return z80sti->ddr;
|
||||
case Z80STI_REGISTER_IR_TCDC: return z80sti->tcdc;
|
||||
}
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_GPIP: z80sti->gpip = (devcb_call_read8(&z80sti->in_gpio_func, 0) & ~z80sti->ddr) | (z80sti->gpip & z80sti->ddr); return z80sti->gpip;
|
||||
case Z80STI_REGISTER_IPRB: return z80sti->ipr & 0xff;
|
||||
case Z80STI_REGISTER_IPRA: return z80sti->ipr >> 8;
|
||||
case Z80STI_REGISTER_ISRB: return z80sti->isr & 0xff;
|
||||
case Z80STI_REGISTER_ISRA: return z80sti->isr >> 8;
|
||||
case Z80STI_REGISTER_IMRB: return z80sti->imr & 0xff;
|
||||
case Z80STI_REGISTER_IMRA: return z80sti->imr >> 8;
|
||||
case Z80STI_REGISTER_PVR: return z80sti->pvr;
|
||||
case Z80STI_REGISTER_TABC: return z80sti->tabc;
|
||||
case Z80STI_REGISTER_TBDR: return z80sti->tmc[TIMER_B];
|
||||
case Z80STI_REGISTER_TADR: return z80sti->tmc[TIMER_A];
|
||||
case Z80STI_REGISTER_UCR: return z80sti->ucr;
|
||||
case Z80STI_REGISTER_RSR: return z80sti->rsr;
|
||||
case Z80STI_REGISTER_TSR: return z80sti->tsr;
|
||||
case Z80STI_REGISTER_UDR: return z80sti->udr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_w - register write
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER( z80sti_w )
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
switch (offset & 0x0f)
|
||||
{
|
||||
case Z80STI_REGISTER_IR:
|
||||
switch (z80sti->pvr & 0x07)
|
||||
{
|
||||
case Z80STI_REGISTER_IR_SCR:
|
||||
LOG(("Z80STI '%s' Sync Character Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->scr = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_TDDR:
|
||||
LOG(("Z80STI '%s' Timer D Data Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->tdr[TIMER_D] = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_TCDR:
|
||||
LOG(("Z80STI '%s' Timer C Data Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->tdr[TIMER_C] = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_AER:
|
||||
LOG(("Z80STI '%s' Active Edge Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->aer = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_IERB:
|
||||
LOG(("Z80STI '%s' Interrupt Enable Register B: %x\n", device->tag.cstr(), data));
|
||||
z80sti->ier = (z80sti->ier & 0xff00) | data;
|
||||
check_interrupts(z80sti);
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_IERA:
|
||||
LOG(("Z80STI '%s' Interrupt Enable Register A: %x\n", device->tag.cstr(), data));
|
||||
z80sti->ier = (data << 8) | (z80sti->ier & 0xff);
|
||||
check_interrupts(z80sti);
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_DDR:
|
||||
LOG(("Z80STI '%s' Data Direction Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->ddr = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IR_TCDC:
|
||||
{
|
||||
int tcc = PRESCALER[(data >> 4) & 0x07];
|
||||
int tdc = PRESCALER[data & 0x07];
|
||||
|
||||
z80sti->tcdc = data;
|
||||
|
||||
LOG(("Z80STI '%s' Timer C Prescaler: %u\n", device->tag.cstr(), tcc));
|
||||
LOG(("Z80STI '%s' Timer D Prescaler: %u\n", device->tag.cstr(), tdc));
|
||||
|
||||
if (tcc)
|
||||
timer_adjust_periodic(z80sti->timer[TIMER_C], ATTOTIME_IN_HZ(device->clock / tcc), 0, ATTOTIME_IN_HZ(device->clock / tcc));
|
||||
else
|
||||
timer_enable(z80sti->timer[TIMER_C], 0);
|
||||
|
||||
if (tdc)
|
||||
timer_adjust_periodic(z80sti->timer[TIMER_D], ATTOTIME_IN_HZ(device->clock / tdc), 0, ATTOTIME_IN_HZ(device->clock / tdc));
|
||||
else
|
||||
timer_enable(z80sti->timer[TIMER_D], 0);
|
||||
|
||||
if (BIT(data, 7))
|
||||
{
|
||||
LOG(("Z80STI '%s' Timer A Reset\n", device->tag.cstr()));
|
||||
z80sti->to[TIMER_A] = 0;
|
||||
|
||||
devcb_call_write_line(&z80sti->out_tao_func, z80sti->to[TIMER_A]);
|
||||
}
|
||||
|
||||
if (BIT(data, 3))
|
||||
{
|
||||
LOG(("Z80STI '%s' Timer B Reset\n", device->tag.cstr()));
|
||||
z80sti->to[TIMER_B] = 0;
|
||||
|
||||
devcb_call_write_line(&z80sti->out_tbo_func, z80sti->to[TIMER_B]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_GPIP:
|
||||
LOG(("Z80STI '%s' General Purpose I/O Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->gpip = data & z80sti->ddr;
|
||||
devcb_call_write8(&z80sti->out_gpio_func, 0, z80sti->gpip);
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IPRB:
|
||||
{
|
||||
int i;
|
||||
LOG(("Z80STI '%s' Interrupt Pending Register B: %x\n", device->tag.cstr(), data));
|
||||
z80sti->ipr &= (z80sti->ipr & 0xff00) | data;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (!BIT(z80sti->ipr, i) && (z80sti->int_state[i] == Z80_DAISY_INT)) z80sti->int_state[i] = 0;
|
||||
}
|
||||
|
||||
check_interrupts(z80sti);
|
||||
}
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IPRA:
|
||||
{
|
||||
int i;
|
||||
LOG(("Z80STI '%s' Interrupt Pending Register A: %x\n", device->tag.cstr(), data));
|
||||
z80sti->ipr &= (data << 8) | (z80sti->ipr & 0xff);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (!BIT(z80sti->ipr, i) && (z80sti->int_state[i] == Z80_DAISY_INT)) z80sti->int_state[i] = 0;
|
||||
}
|
||||
|
||||
check_interrupts(z80sti);
|
||||
}
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_ISRB:
|
||||
LOG(("Z80STI '%s' Interrupt In-Service Register B: %x\n", device->tag.cstr(), data));
|
||||
z80sti->isr &= (z80sti->isr & 0xff00) | data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_ISRA:
|
||||
LOG(("Z80STI '%s' Interrupt In-Service Register A: %x\n", device->tag.cstr(), data));
|
||||
z80sti->isr &= (data << 8) | (z80sti->isr & 0xff);
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IMRB:
|
||||
LOG(("Z80STI '%s' Interrupt Mask Register B: %x\n", device->tag.cstr(), data));
|
||||
z80sti->imr = (z80sti->imr & 0xff00) | data;
|
||||
z80sti->isr &= z80sti->imr;
|
||||
check_interrupts(z80sti);
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_IMRA:
|
||||
LOG(("Z80STI '%s' Interrupt Mask Register A: %x\n", device->tag.cstr(), data));
|
||||
z80sti->imr = (data << 8) | (z80sti->imr & 0xff);
|
||||
z80sti->isr &= z80sti->imr;
|
||||
check_interrupts(z80sti);
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_PVR:
|
||||
LOG(("Z80STI '%s' Interrupt Vector: %02x\n", device->tag.cstr(), data & 0xe0));
|
||||
LOG(("Z80STI '%s' IR Address: %01x\n", device->tag.cstr(), data & 0x07));
|
||||
z80sti->pvr = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_TABC:
|
||||
{
|
||||
int tac = PRESCALER[(data >> 4) & 0x07];
|
||||
int tbc = PRESCALER[data & 0x07];
|
||||
|
||||
z80sti->tabc = data;
|
||||
|
||||
LOG(("Z80STI '%s' Timer A Prescaler: %u\n", device->tag.cstr(), tac));
|
||||
LOG(("Z80STI '%s' Timer B Prescaler: %u\n", device->tag.cstr(), tbc));
|
||||
|
||||
if (tac)
|
||||
timer_adjust_periodic(z80sti->timer[TIMER_A], ATTOTIME_IN_HZ(device->clock / tac), 0, ATTOTIME_IN_HZ(device->clock / tac));
|
||||
else
|
||||
timer_enable(z80sti->timer[TIMER_A], 0);
|
||||
|
||||
if (tbc)
|
||||
timer_adjust_periodic(z80sti->timer[TIMER_B], ATTOTIME_IN_HZ(device->clock / tbc), 0, ATTOTIME_IN_HZ(device->clock / tbc));
|
||||
else
|
||||
timer_enable(z80sti->timer[TIMER_B], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_TBDR:
|
||||
LOG(("Z80STI '%s' Timer B Data Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->tdr[TIMER_B] = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_TADR:
|
||||
LOG(("Z80STI '%s' Timer A Data Register: %x\n", device->tag.cstr(), data));
|
||||
z80sti->tdr[TIMER_A] = data;
|
||||
break;
|
||||
#if 0
|
||||
case Z80STI_REGISTER_UCR:
|
||||
z80sti->ucr = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_RSR:
|
||||
z80sti->rsr = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_TSR:
|
||||
z80sti->tsr = data;
|
||||
break;
|
||||
|
||||
case Z80STI_REGISTER_UDR:
|
||||
z80sti->udr = data;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG(("Z80STI '%s' Unsupported Register %x\n", device->tag.cstr(), offset & 0x0f));
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_rc_w - receiver clock write
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_rc_w )
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
if (state)
|
||||
{
|
||||
serial_receive(z80sti);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_tc_w - transmitter clock write
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_tc_w )
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
if (state)
|
||||
{
|
||||
serial_transmit(z80sti);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
timer_count - timer count down
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void timer_count(running_device *device, int index)
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
if (z80sti->tmc[index] == 0x01)
|
||||
{
|
||||
//LOG(("Z80STI '%s' Timer %c Expired\n", device->tag, 'A' + index));
|
||||
|
||||
/* toggle timer output signal */
|
||||
z80sti->to[index] = !z80sti->to[index];
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case TIMER_A: devcb_call_write_line(&z80sti->out_tao_func, z80sti->to[index]); break;
|
||||
case TIMER_B: devcb_call_write_line(&z80sti->out_tbo_func, z80sti->to[index]); break;
|
||||
case TIMER_C: devcb_call_write_line(&z80sti->out_tco_func, z80sti->to[index]); break;
|
||||
case TIMER_D: devcb_call_write_line(&z80sti->out_tdo_func, z80sti->to[index]); break;
|
||||
}
|
||||
|
||||
if (z80sti->ier & (1 << INT_LEVEL_TIMER[index]))
|
||||
{
|
||||
LOG(("Z80STI '%s' Interrupt Pending for Timer %c\n", device->tag.cstr(), 'A' + index));
|
||||
|
||||
/* signal timer elapsed interrupt */
|
||||
take_interrupt(z80sti, INT_LEVEL_TIMER[index]);
|
||||
}
|
||||
|
||||
/* load timer main counter */
|
||||
z80sti->tmc[index] = z80sti->tdr[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* count down */
|
||||
z80sti->tmc[index]--;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
TIMER_CALLBACK( timer_# )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( timer_a ) { timer_count((running_device *)ptr, TIMER_A); }
|
||||
static TIMER_CALLBACK( timer_b ) { timer_count((running_device *)ptr, TIMER_B); }
|
||||
static TIMER_CALLBACK( timer_c ) { timer_count((running_device *)ptr, TIMER_C); }
|
||||
static TIMER_CALLBACK( timer_d ) { timer_count((running_device *)ptr, TIMER_D); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
gpip_input - GPIP input line write
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void gpip_input(running_device *device, int bit, int state)
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
|
||||
int aer = BIT(z80sti->aer, bit);
|
||||
int old_state = BIT(z80sti->gpip, bit);
|
||||
|
||||
if ((old_state ^ aer) && !(state ^ aer))
|
||||
{
|
||||
LOG(("Z80STI '%s' Edge Transition Detected on Bit: %u\n", device->tag.cstr(), bit));
|
||||
|
||||
if (z80sti->ier & (1 << INT_LEVEL_GPIP[bit]))
|
||||
{
|
||||
LOG(("Z80STI '%s' Interrupt Pending for P%u\n", device->tag.cstr(), bit));
|
||||
|
||||
take_interrupt(z80sti, INT_LEVEL_GPIP[bit]);
|
||||
}
|
||||
}
|
||||
|
||||
z80sti->gpip = (z80sti->gpip & ~(1 << bit)) | (state << bit);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_i#_w - GPIP input line # write
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i0_w ) { gpip_input(device, 0, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i1_w ) { gpip_input(device, 1, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i2_w ) { gpip_input(device, 2, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i3_w ) { gpip_input(device, 3, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i4_w ) { gpip_input(device, 4, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i5_w ) { gpip_input(device, 5, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i6_w ) { gpip_input(device, 6, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i7_w ) { gpip_input(device, 7, state); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_irq_state - get interrupt status
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int z80sti_irq_state(running_device *device)
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
int state = 0, i;
|
||||
|
||||
/* loop over all interrupt sources */
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
/* if we're servicing a request, don't indicate more interrupts */
|
||||
if (z80sti->int_state[i] & Z80_DAISY_IEO)
|
||||
{
|
||||
state |= Z80_DAISY_IEO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (BIT(z80sti->imr, i))
|
||||
{
|
||||
state |= z80sti->int_state[i];
|
||||
}
|
||||
}
|
||||
|
||||
LOG(("Z80STI '%s' Interrupt State: %u\n", device->tag.cstr(), state));
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_irq_ack - interrupt acknowledge
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int z80sti_irq_ack(running_device *device)
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
int i;
|
||||
|
||||
/* loop over all interrupt sources */
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
/* find the first channel with an interrupt requested */
|
||||
if (z80sti->int_state[i] & Z80_DAISY_INT)
|
||||
{
|
||||
UINT8 vector = (z80sti->pvr & 0xe0) | INT_VECTOR[i];
|
||||
|
||||
/* clear interrupt, switch to the IEO state, and update the IRQs */
|
||||
z80sti->int_state[i] = Z80_DAISY_IEO;
|
||||
|
||||
/* clear interrupt pending register bit */
|
||||
z80sti->ipr &= ~(1 << i);
|
||||
|
||||
/* set interrupt in-service register bit */
|
||||
z80sti->isr |= (1 << i);
|
||||
|
||||
check_interrupts(z80sti);
|
||||
|
||||
LOG(("Z80STI '%s' Interrupt Acknowledge Vector: %02x\n", device->tag.cstr(), vector));
|
||||
|
||||
return vector;
|
||||
}
|
||||
}
|
||||
|
||||
logerror("z80sti_irq_ack: failed to find an interrupt to ack!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
z80sti_irq_reti - return from interrupt
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void z80sti_irq_reti(running_device *device)
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
int i;
|
||||
|
||||
LOG(("Z80STI '%s' Return from Interrupt\n", device->tag.cstr()));
|
||||
|
||||
/* loop over all interrupt sources */
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
/* find the first channel with an IEO pending */
|
||||
if (z80sti->int_state[i] & Z80_DAISY_IEO)
|
||||
{
|
||||
/* clear the IEO state and update the IRQs */
|
||||
z80sti->int_state[i] &= ~Z80_DAISY_IEO;
|
||||
|
||||
/* clear interrupt in-service register bit */
|
||||
z80sti->isr &= ~(1 << i);
|
||||
|
||||
check_interrupts(z80sti);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
logerror("z80sti_irq_reti: failed to find an interrupt to clear IEO on!\n");
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_START( z80sti )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START( z80sti )
|
||||
{
|
||||
z80sti_t *z80sti = get_safe_token(device);
|
||||
const z80sti_interface *intf = (const z80sti_interface *)device->baseconfig().static_config;
|
||||
|
||||
/* resolve callbacks */
|
||||
devcb_resolve_read8(&z80sti->in_gpio_func, &intf->in_gpio_func, device);
|
||||
devcb_resolve_write8(&z80sti->out_gpio_func, &intf->out_gpio_func, device);
|
||||
devcb_resolve_read_line(&z80sti->in_si_func, &intf->in_si_func, device);
|
||||
devcb_resolve_write_line(&z80sti->out_so_func, &intf->out_so_func, device);
|
||||
devcb_resolve_write_line(&z80sti->out_tao_func, &intf->out_tao_func, device);
|
||||
devcb_resolve_write_line(&z80sti->out_tbo_func, &intf->out_tbo_func, device);
|
||||
devcb_resolve_write_line(&z80sti->out_tco_func, &intf->out_tco_func, device);
|
||||
devcb_resolve_write_line(&z80sti->out_tdo_func, &intf->out_tdo_func, device);
|
||||
devcb_resolve_write_line(&z80sti->out_int_func, &intf->out_int_func, device);
|
||||
|
||||
/* create the counter timers */
|
||||
z80sti->timer[TIMER_A] = timer_alloc(device->machine, timer_a, (void *)device);
|
||||
z80sti->timer[TIMER_B] = timer_alloc(device->machine, timer_b, (void *)device);
|
||||
z80sti->timer[TIMER_C] = timer_alloc(device->machine, timer_c, (void *)device);
|
||||
z80sti->timer[TIMER_D] = timer_alloc(device->machine, timer_d, (void *)device);
|
||||
|
||||
/* create serial receive clock timer */
|
||||
if (intf->rx_clock > 0)
|
||||
{
|
||||
z80sti->rx_timer = timer_alloc(device->machine, rx_tick, (void *)device);
|
||||
timer_adjust_periodic(z80sti->rx_timer, attotime_zero, 0, ATTOTIME_IN_HZ(intf->rx_clock));
|
||||
}
|
||||
|
||||
/* create serial transmit clock timer */
|
||||
if (intf->tx_clock > 0)
|
||||
{
|
||||
z80sti->tx_timer = timer_alloc(device->machine, tx_tick, (void *)device);
|
||||
timer_adjust_periodic(z80sti->tx_timer, attotime_zero, 0, ATTOTIME_IN_HZ(intf->tx_clock));
|
||||
}
|
||||
|
||||
/* register for state saving */
|
||||
state_save_register_device_item(device, 0, z80sti->gpip);
|
||||
state_save_register_device_item(device, 0, z80sti->aer);
|
||||
state_save_register_device_item(device, 0, z80sti->ddr);
|
||||
state_save_register_device_item(device, 0, z80sti->ier);
|
||||
state_save_register_device_item(device, 0, z80sti->ipr);
|
||||
state_save_register_device_item(device, 0, z80sti->isr);
|
||||
state_save_register_device_item(device, 0, z80sti->imr);
|
||||
state_save_register_device_item(device, 0, z80sti->pvr);
|
||||
state_save_register_device_item_array(device, 0, z80sti->int_state);
|
||||
state_save_register_device_item(device, 0, z80sti->tabc);
|
||||
state_save_register_device_item(device, 0, z80sti->tcdc);
|
||||
state_save_register_device_item_array(device, 0, z80sti->tdr);
|
||||
state_save_register_device_item_array(device, 0, z80sti->tmc);
|
||||
state_save_register_device_item_array(device, 0, z80sti->to);
|
||||
state_save_register_device_item(device, 0, z80sti->scr);
|
||||
state_save_register_device_item(device, 0, z80sti->ucr);
|
||||
state_save_register_device_item(device, 0, z80sti->rsr);
|
||||
state_save_register_device_item(device, 0, z80sti->tsr);
|
||||
state_save_register_device_item(device, 0, z80sti->udr);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_RESET( z80sti )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_RESET( z80sti )
|
||||
{
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_GET_INFO( z80sti )
|
||||
-------------------------------------------------*/
|
||||
|
||||
DEVICE_GET_INFO( z80sti )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(z80sti_t); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(z80sti); break;
|
||||
case DEVINFO_FCT_STOP: /* Nothing */ break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(z80sti); break;
|
||||
case DEVINFO_FCT_IRQ_STATE: info->f = (genf *)z80sti_irq_state; break;
|
||||
case DEVINFO_FCT_IRQ_ACK: info->f = (genf *)z80sti_irq_ack; break;
|
||||
case DEVINFO_FCT_IRQ_RETI: info->f = (genf *)z80sti_irq_reti; break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "Mostek MK3801"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Z80-STI"); 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;
|
||||
}
|
||||
}
|
116
src/emu/machine/z80sti.h
Normal file
116
src/emu/machine/z80sti.h
Normal file
@ -0,0 +1,116 @@
|
||||
/**********************************************************************
|
||||
|
||||
Mostek MK3801 Serial Timer Interrupt Controller (Z80-STI) emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
TAO 1 |* \_/ | 40 Vcc
|
||||
TBO 2 | | 39 RC
|
||||
TCO 3 | | 38 SI
|
||||
TDO 4 | | 37 SO
|
||||
TCK 5 | | 36 TC
|
||||
_M1 6 | | 35 A0
|
||||
_RES 7 | | 34 A1
|
||||
I0 8 | | 33 A2
|
||||
I1 9 | | 32 A3
|
||||
I2 10 | MK3801 | 31 _WR
|
||||
I3 11 | Z80-STI | 30 _CE
|
||||
I4 12 | | 29 _RD
|
||||
I5 13 | | 28 D7
|
||||
I6 14 | | 27 D6
|
||||
I7 15 | | 26 D5
|
||||
IEI 16 | | 25 D4
|
||||
_INT 17 | | 24 D3
|
||||
IEO 18 | | 23 D2
|
||||
_IORQ 19 | | 22 D1
|
||||
Vss 20 |_____________| 21 D0
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __Z80STI__
|
||||
#define __Z80STI__
|
||||
|
||||
#include "emu.h"
|
||||
#include "devcb.h"
|
||||
|
||||
/***************************************************************************
|
||||
MACROS / CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define Z80STI DEVICE_GET_INFO_NAME( z80sti )
|
||||
|
||||
#define MDRV_Z80STI_ADD(_tag, _clock, _config) \
|
||||
MDRV_DEVICE_ADD((_tag), Z80STI, _clock) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
#define Z80STI_INTERFACE(name) const z80sti_interface (name) =
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _z80sti_interface z80sti_interface;
|
||||
struct _z80sti_interface
|
||||
{
|
||||
int rx_clock; /* serial receive clock */
|
||||
int tx_clock; /* serial transmit clock */
|
||||
|
||||
/* this gets called on each change of the _INT pin (pin 17) */
|
||||
devcb_write_line out_int_func;
|
||||
|
||||
/* this is called on each read of the GPIO pins */
|
||||
devcb_read8 in_gpio_func;
|
||||
|
||||
/* this is called on each write of the GPIO pins */
|
||||
devcb_write8 out_gpio_func;
|
||||
|
||||
/* this gets called for each read of the SI pin (pin 38) */
|
||||
devcb_read_line in_si_func;
|
||||
|
||||
/* this gets called for each change of the SO pin (pin 37) */
|
||||
devcb_write_line out_so_func;
|
||||
|
||||
/* this gets called for each change of the TAO pin (pin 1) */
|
||||
devcb_write_line out_tao_func;
|
||||
|
||||
/* this gets called for each change of the TBO pin (pin 2) */
|
||||
devcb_write_line out_tbo_func;
|
||||
|
||||
/* this gets called for each change of the TCO pin (pin 3) */
|
||||
devcb_write_line out_tco_func;
|
||||
|
||||
/* this gets called for each change of the TDO pin (pin 4) */
|
||||
devcb_write_line out_tdo_func;
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* device interface */
|
||||
DEVICE_GET_INFO( z80sti );
|
||||
|
||||
/* register access */
|
||||
READ8_DEVICE_HANDLER( z80sti_r );
|
||||
WRITE8_DEVICE_HANDLER( z80sti_w );
|
||||
|
||||
/* receive clock */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_rc_w );
|
||||
|
||||
/* transmit clock */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_tc_w );
|
||||
|
||||
/* GPIP input lines */
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i0_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i1_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i2_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i3_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i4_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i5_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i6_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80sti_i7_w );
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user