summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2009-01-04 03:35:12 +0000
committer Aaron Giles <aaron@aarongiles.com>2009-01-04 03:35:12 +0000
commit41879d052ab09d40ca49dbc14ebf32cec6b2d1c1 (patch)
treeda325b14bb9b4f846fac4f2c15c314268c7e8ad5
parenta4455577a044a74ec9899a310697dcce13107766 (diff)
Removed bogus port 4-7 definitions from MCS-48. Added i8243
implementation. Connected 8243 properly to monsterb and system 16a sound. Changed draw80pkr to connect the PROG line like videopkr.
-rw-r--r--.gitattributes2
-rw-r--r--src/emu/cpu/mcs48/mcs48.h4
-rw-r--r--src/emu/emu.mak1
-rw-r--r--src/emu/machine/i8243.c187
-rw-r--r--src/emu/machine/i8243.h62
-rw-r--r--src/mame/audio/segag80r.c66
-rw-r--r--src/mame/drivers/drw80pkr.c19
-rw-r--r--src/mame/drivers/segas16a.c25
8 files changed, 318 insertions, 48 deletions
diff --git a/.gitattributes b/.gitattributes
index 2c305c141cc..3e29e7d41e7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -612,6 +612,8 @@ src/emu/machine/generic.c svneol=native#text/plain
src/emu/machine/generic.h svneol=native#text/plain
src/emu/machine/i2cmem.c svneol=native#text/plain
src/emu/machine/i2cmem.h svneol=native#text/plain
+src/emu/machine/i8243.c svneol=native#text/plain
+src/emu/machine/i8243.h svneol=native#text/plain
src/emu/machine/idectrl.c svneol=native#text/plain
src/emu/machine/idectrl.h svneol=native#text/plain
src/emu/machine/intelfsh.c svneol=native#text/plain
diff --git a/src/emu/cpu/mcs48/mcs48.h b/src/emu/cpu/mcs48/mcs48.h
index d6d686023eb..50d7616a6d1 100644
--- a/src/emu/cpu/mcs48/mcs48.h
+++ b/src/emu/cpu/mcs48/mcs48.h
@@ -66,10 +66,6 @@ enum
MCS48_PORT_P0 = 0x100, /* Not used */
MCS48_PORT_P1 = 0x101,
MCS48_PORT_P2 = 0x102,
- MCS48_PORT_P4 = 0x104,
- MCS48_PORT_P5 = 0x105,
- MCS48_PORT_P6 = 0x106,
- MCS48_PORT_P7 = 0x107,
MCS48_PORT_T0 = 0x110,
MCS48_PORT_T1 = 0x111,
MCS48_PORT_BUS = 0x120,
diff --git a/src/emu/emu.mak b/src/emu/emu.mak
index e24c54e3245..df398533d1c 100644
--- a/src/emu/emu.mak
+++ b/src/emu/emu.mak
@@ -134,6 +134,7 @@ EMUMACHINEOBJS = \
$(EMUMACHINE)/eeprom.o \
$(EMUMACHINE)/f3853.o \
$(EMUMACHINE)/generic.o \
+ $(EMUMACHINE)/i8243.o \
$(EMUMACHINE)/i2cmem.o \
$(EMUMACHINE)/idectrl.o \
$(EMUMACHINE)/intelfsh.o \
diff --git a/src/emu/machine/i8243.c b/src/emu/machine/i8243.c
new file mode 100644
index 00000000000..71d086087f4
--- /dev/null
+++ b/src/emu/machine/i8243.c
@@ -0,0 +1,187 @@
+/***************************************************************************
+
+ i8243.c
+
+ Intel 8243 Port Expander
+
+ Copyright Aaron Giles
+
+***************************************************************************/
+
+#include "i8243.h"
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* live processor state */
+typedef struct _i8243_state i8243_state;
+struct _i8243_state
+{
+ UINT8 p[4]; /* 4 ports' worth of data */
+ UINT8 p2out; /* port 2 bits that will be returned */
+ UINT8 p2; /* most recent port 2 value */
+ UINT8 opcode; /* latched opcode */
+ UINT8 prog; /* previous PROG state */
+};
+
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+INLINE i8243_state *get_safe_token(const device_config *device)
+{
+ assert(device != NULL);
+ assert(device->type == I8243);
+ return (i8243_state *)device->token;
+}
+
+
+INLINE i8243_config *get_safe_config(const device_config *device)
+{
+ assert(device != NULL);
+ assert(device->type == I8243);
+ return (i8243_config *)device->inline_config;
+}
+
+
+
+/***************************************************************************
+ DEVICE INTERFACE
+***************************************************************************/
+
+/*-------------------------------------------------
+ i8243_p2_r - handle a read from port 2
+-------------------------------------------------*/
+
+READ8_DEVICE_HANDLER( i8243_p2_r )
+{
+ i8243_state *i8243 = get_safe_token(device);
+ return i8243->p2out;
+}
+
+
+/*-------------------------------------------------
+ i8243_p2_r - handle a write to port 2
+-------------------------------------------------*/
+
+WRITE8_DEVICE_HANDLER( i8243_p2_w )
+{
+ i8243_state *i8243 = get_safe_token(device);
+ i8243->p2 = data & 0x0f;
+}
+
+
+/*-------------------------------------------------
+ i8243_prog_w - handle a change in the PROG
+ line state
+-------------------------------------------------*/
+
+WRITE8_DEVICE_HANDLER( i8243_prog_w )
+{
+ i8243_state *i8243 = get_safe_token(device);
+ i8243_config *config = get_safe_config(device);
+
+ /* only care about low bit */
+ data &= 1;
+
+ /* on high->low transition state, latch opcode/port */
+ if (i8243->prog && !data)
+ {
+ i8243->opcode = i8243->p2;
+
+ /* if this is a read opcode, copy result to p2out */
+ if ((i8243->opcode >> 2) == MCS48_EXPANDER_OP_READ)
+ {
+ if (config->readhandler != NULL)
+ i8243->p[i8243->opcode & 3] = (*config->readhandler)(device, i8243->opcode & 3);
+ i8243->p2out = i8243->p[i8243->opcode & 3] & 0x0f;
+ }
+ }
+
+ /* on low->high transition state, act on opcode */
+ else if (!i8243->prog && data)
+ {
+ switch (i8243->opcode >> 2)
+ {
+ case MCS48_EXPANDER_OP_WRITE:
+ i8243->p[i8243->opcode & 3] = i8243->p2 & 0x0f;
+ if (config->writehandler != NULL)
+ (*config->writehandler)(device, i8243->opcode & 3, i8243->p[i8243->opcode & 3]);
+ break;
+
+ case MCS48_EXPANDER_OP_OR:
+ i8243->p[i8243->opcode & 3] |= i8243->p2 & 0x0f;
+ if (config->writehandler != NULL)
+ (*config->writehandler)(device, i8243->opcode & 3, i8243->p[i8243->opcode & 3]);
+ break;
+
+ case MCS48_EXPANDER_OP_AND:
+ i8243->p[i8243->opcode & 3] &= i8243->p2 & 0x0f;
+ if (config->writehandler != NULL)
+ (*config->writehandler)(device, i8243->opcode & 3, i8243->p[i8243->opcode & 3]);
+ break;
+ }
+ }
+
+ /* remember the state */
+ i8243->prog = data;
+}
+
+
+
+/***************************************************************************
+ DEVICE INTERFACE
+***************************************************************************/
+
+/*-------------------------------------------------
+ DEVICE_START( i8243 )
+-------------------------------------------------*/
+
+static DEVICE_START( i8243 )
+{
+ return DEVICE_START_OK;
+}
+
+
+/*-------------------------------------------------
+ DEVICE_RESET( i8243 )
+-------------------------------------------------*/
+
+static DEVICE_RESET( i8243 )
+{
+ i8243_state *i8243 = get_safe_token(device);
+
+ i8243->p2 = 0x0f;
+ i8243->p2out = 0x0f;
+ i8243->prog = 1;
+}
+
+
+/*-------------------------------------------------
+ DEVICE_GET_INFO( i8243 )
+-------------------------------------------------*/
+
+DEVICE_GET_INFO( i8243 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(i8243_state); break;
+ case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(i8243_config); 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(i8243); break;
+ case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(i8243); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "I8243"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "MCS-48"); 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;
+ }
+}
diff --git a/src/emu/machine/i8243.h b/src/emu/machine/i8243.h
new file mode 100644
index 00000000000..97d148dbf5a
--- /dev/null
+++ b/src/emu/machine/i8243.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+
+ i8243.h
+
+ Intel 8243 Port Expander
+
+ Copyright Aaron Giles
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __I8243_H__
+#define __I8243_H__
+
+#include "devintrf.h"
+#include "cpu/mcs48/mcs48.h"
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+typedef struct _i8243_config i8243_config;
+struct _i8243_config
+{
+ read8_device_func readhandler;
+ write8_device_func writehandler;
+};
+
+
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+#define I8243 DEVICE_GET_INFO_NAME( i8243 )
+
+
+#define MDRV_I8243_ADD(_tag, _read, _write) \
+ MDRV_DEVICE_ADD(_tag, I8243, 0) \
+ MDRV_DEVICE_CONFIG_DATAPTR(i8243_config, readhandler, _read) \
+ MDRV_DEVICE_CONFIG_DATAPTR(i8243_config, writehandler, _write)
+
+#define MDRV_I8243_REMOVE(_tag) \
+ MDRV_DEVICE_REMOVE(_tag, I8243)
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+DEVICE_GET_INFO( i8243 );
+
+READ8_DEVICE_HANDLER( i8243_p2_r );
+WRITE8_DEVICE_HANDLER( i8243_p2_w );
+
+WRITE8_DEVICE_HANDLER( i8243_prog_w );
+
+
+#endif /* __I8243_H__ */
diff --git a/src/mame/audio/segag80r.c b/src/mame/audio/segag80r.c
index 3bd26cfe8f6..ed229058583 100644
--- a/src/mame/audio/segag80r.c
+++ b/src/mame/audio/segag80r.c
@@ -12,6 +12,7 @@
#include "cpu/mcs48/mcs48.h"
#include "segag80r.h"
#include "machine/8255ppi.h"
+#include "machine/i8243.h"
#include "sound/samples.h"
#include "sound/tms36xx.h"
#include "sound/dac.h"
@@ -753,11 +754,10 @@ static WRITE8_DEVICE_HANDLER( monsterb_sound_a_w );
static WRITE8_DEVICE_HANDLER( monsterb_sound_b_w );
static READ8_DEVICE_HANDLER( n7751_status_r );
static WRITE8_DEVICE_HANDLER( n7751_command_w );
-static WRITE8_HANDLER( n7751_rom_offset_w );
-static WRITE8_HANDLER( n7751_rom_select_w );
+static WRITE8_DEVICE_HANDLER( n7751_rom_control_w );
static READ8_HANDLER( n7751_rom_r );
static READ8_HANDLER( n7751_command_r );
-static WRITE8_HANDLER( n7751_busy_w );
+static WRITE8_DEVICE_HANDLER( n7751_p2_w );
static READ8_HANDLER( n7751_t1_r );
/*
@@ -802,13 +802,12 @@ static const tms36xx_interface monsterb_tms3617_interface =
*************************************/
static ADDRESS_MAP_START( monsterb_7751_portmap, ADDRESS_SPACE_IO, 8 )
- AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(n7751_t1_r)
- AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READ(n7751_command_r)
- AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(n7751_rom_r)
- AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(dac_0_data_w)
- AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(n7751_busy_w)
- AM_RANGE(MCS48_PORT_P4, MCS48_PORT_P6) AM_WRITE(n7751_rom_offset_w)
- AM_RANGE(MCS48_PORT_P7, MCS48_PORT_P7) AM_WRITE(n7751_rom_select_w)
+ AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(n7751_t1_r)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READ(n7751_command_r)
+ AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(n7751_rom_r)
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(dac_0_data_w)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_DEVWRITE(I8243, "audio_8243", n7751_p2_w)
+ AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_DEVWRITE(I8243, "audio_8243", i8243_prog_w)
ADDRESS_MAP_END
@@ -837,6 +836,8 @@ MACHINE_DRIVER_START( monsterb_sound_board )
/* basic machine hardware */
MDRV_CPU_ADD("audio", N7751, 6000000)
MDRV_CPU_IO_MAP(monsterb_7751_portmap,0)
+
+ MDRV_I8243_ADD("audio_8243", NULL, n7751_rom_control_w)
/* sound hardware */
MDRV_SOUND_START(monsterb)
@@ -939,26 +940,37 @@ static WRITE8_DEVICE_HANDLER( n7751_command_w )
}
-static WRITE8_HANDLER( n7751_rom_offset_w )
+static WRITE8_DEVICE_HANDLER( n7751_rom_control_w )
{
/* P4 - address lines 0-3 */
/* P5 - address lines 4-7 */
/* P6 - address lines 8-11 */
- int mask = (0xf << (4 * offset)) & 0x3fff;
- int newdata = (data << (4 * offset)) & mask;
- sound_addr = (sound_addr & ~mask) | newdata;
-}
+ /* P7 - ROM selects */
+ switch (offset)
+ {
+ case 0:
+ sound_addr = (sound_addr & ~0x00f) | ((data & 0x0f) << 0);
+ break;
+ case 1:
+ sound_addr = (sound_addr & ~0x0f0) | ((data & 0x0f) << 4);
+ break;
-static WRITE8_HANDLER( n7751_rom_select_w )
-{
- /* P7 - ROM selects */
- int numroms = memory_region_length(space->machine, "n7751") / 0x1000;
- sound_addr &= 0xfff;
- if (!(data & 0x01) && numroms >= 1) sound_addr |= 0x0000;
- if (!(data & 0x02) && numroms >= 2) sound_addr |= 0x1000;
- if (!(data & 0x04) && numroms >= 3) sound_addr |= 0x2000;
- if (!(data & 0x08) && numroms >= 4) sound_addr |= 0x3000;
+ case 2:
+ sound_addr = (sound_addr & ~0xf00) | ((data & 0x0f) << 8);
+ break;
+
+ case 3:
+ sound_addr &= 0xfff;
+ {
+ int numroms = memory_region_length(device->machine, "n7751") / 0x1000;
+ if (!(data & 0x01) && numroms >= 1) sound_addr |= 0x0000;
+ if (!(data & 0x02) && numroms >= 2) sound_addr |= 0x1000;
+ if (!(data & 0x04) && numroms >= 3) sound_addr |= 0x2000;
+ if (!(data & 0x08) && numroms >= 4) sound_addr |= 0x3000;
+ }
+ break;
+ }
}
@@ -977,9 +989,11 @@ static READ8_HANDLER( n7751_command_r )
}
-static WRITE8_HANDLER( n7751_busy_w )
+static WRITE8_DEVICE_HANDLER( n7751_p2_w )
{
- /* write to P2 */
+ /* write to P2; low 4 bits go to 8243 */
+ i8243_p2_w(device, offset, data & 0x0f);
+
/* output of bit $80 indicates we are ready (1) or busy (0) */
/* no other outputs are used */
n7751_busy = data >> 7;
diff --git a/src/mame/drivers/drw80pkr.c b/src/mame/drivers/drw80pkr.c
index 2dd56f51224..eee278fdb68 100644
--- a/src/mame/drivers/drw80pkr.c
+++ b/src/mame/drivers/drw80pkr.c
@@ -32,7 +32,7 @@
static tilemap *bg_tilemap;
-static UINT8 p1, p2, p4, bus;
+static UINT8 p1, p2, prog, bus;
static UINT8 *pkr_cmos_ram;
@@ -51,9 +51,12 @@ static WRITE8_HANDLER( p2_w )
p2 = data;
}
-static WRITE8_HANDLER( p4_w )
+static WRITE8_HANDLER( prog_w )
{
- p4 = data;
+ /* this is written via an out to port 4, but unless there is an 8243 port expander,
+ it is more likely that the port 4 output is used to toggle the PROG line; see
+ videopkr */
+ prog = data;
}
static WRITE8_HANDLER( bus_w )
@@ -199,11 +202,11 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( drw80pkr_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x00, 0xff) AM_READWRITE(drw80pkr_cmos_r, drw80pkr_cmos_w) AM_BASE(&pkr_cmos_ram)
- AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_RAM
- AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(p1_r, p1_w)
- AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_r, p2_w)
- AM_RANGE(MCS48_PORT_P4, MCS48_PORT_P4) AM_RAM_WRITE(p4_w)
- AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_r, bus_w)
+ AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_RAM
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(p1_r, p1_w)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_r, p2_w)
+ AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_RAM_WRITE(prog_w)
+ AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_r, bus_w)
ADDRESS_MAP_END
/*************************
diff --git a/src/mame/drivers/segas16a.c b/src/mame/drivers/segas16a.c
index 8d9a6ccf176..ba7560ed3bb 100644
--- a/src/mame/drivers/segas16a.c
+++ b/src/mame/drivers/segas16a.c
@@ -150,6 +150,7 @@ Tetris - - - - EPR12169 EPR12170 -
#include "system16.h"
#include "machine/8255ppi.h"
#include "machine/fd1089.h"
+#include "machine/i8243.h"
#include "cpu/mcs48/mcs48.h"
#include "sound/dac.h"
#include "sound/2151intf.h"
@@ -445,7 +446,7 @@ static WRITE8_HANDLER( n7751_control_w )
}
-static WRITE8_HANDLER( n7751_rom_offset_w )
+static WRITE8_DEVICE_HANDLER( n7751_rom_offset_w )
{
/* P4 - address lines 0-3 */
/* P5 - address lines 4-7 */
@@ -464,17 +465,19 @@ static READ8_HANDLER( n7751_rom_r )
}
-static READ8_HANDLER( n7751_command_r )
+static READ8_DEVICE_HANDLER( n7751_p2_r )
{
/* read from P2 - 8255's PC0-2 connects to 7751's S0-2 (P24-P26 on an 8048) */
/* bit 0x80 is an alternate way to control the sample on/off; doesn't appear to be used */
- return 0x80 | ((n7751_command & 0x07) << 4);
+ return 0x80 | ((n7751_command & 0x07) << 4) | (i8243_p2_r(device, offset) & 0x0f);
}
-static WRITE8_HANDLER( n7751_busy_w )
+static WRITE8_DEVICE_HANDLER( n7751_p2_w )
{
- /* write to P2 */
+ /* write to P2; low 4 bits go to 8243 */
+ i8243_p2_w(device, offset, data & 0x0f);
+
/* output of bit $80 indicates we are ready (1) or busy (0) */
/* no other outputs are used */
}
@@ -861,11 +864,11 @@ ADDRESS_MAP_END
*************************************/
static ADDRESS_MAP_START( n7751_portmap, ADDRESS_SPACE_IO, 8 )
- AM_RANGE(MCS48_PORT_BUS,MCS48_PORT_BUS) AM_READ(n7751_rom_r)
- AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(n7751_t1_r)
- AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(dac_0_data_w)
- AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(n7751_command_r, n7751_busy_w)
- AM_RANGE(MCS48_PORT_P4, MCS48_PORT_P7) AM_WRITE(n7751_rom_offset_w)
+ AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(n7751_rom_r)
+ AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(n7751_t1_r)
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(dac_0_data_w)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_DEVREADWRITE(I8243, "n7751_8243", n7751_p2_r, n7751_p2_w)
+ AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_DEVWRITE(I8243, "n7751_8243", i8243_prog_w)
ADDRESS_MAP_END
@@ -1783,6 +1786,8 @@ static MACHINE_DRIVER_START( system16a )
MDRV_CPU_ADD("n7751", N7751, 6000000)
MDRV_CPU_IO_MAP(n7751_portmap,0)
+
+ MDRV_I8243_ADD("n7751_8243", NULL, n7751_rom_offset_w)
MDRV_MACHINE_RESET(system16a)
MDRV_NVRAM_HANDLER(system16a)