summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-04-03 05:26:47 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-04-03 05:26:47 +0000
commitca3d7d01e65af55c7d3e568dddd79149bc532649 (patch)
tree85fa73fc303e7760278637e979f0560f4ad05251
parent39d36956d2344d2da1e625c9dd25a921c33b52ea (diff)
From: Wilbert Pol
Subject: pit8253 device I have converted the pit8253 implementation into a device. To make it easier to use I've also created a src/emu/devconv.h in the same style as src/emu/memconv.h. I do not have all roms/disk images to test all drivers. I have only been able to test pf2012, filetto, and topgunnr.
-rw-r--r--.gitattributes1
-rw-r--r--src/emu/devconv.h1020
-rw-r--r--src/emu/machine/pit8253.c485
-rw-r--r--src/emu/machine/pit8253.h68
-rw-r--r--src/mame/audio/tx1.c4
-rw-r--r--src/mame/drivers/filetto.c9
-rw-r--r--src/mame/drivers/gamecstl.c36
-rw-r--r--src/mame/drivers/mediagx.c37
-rw-r--r--src/mame/drivers/taitowlf.c36
-rw-r--r--src/mame/drivers/tx1.c4
-rw-r--r--src/mame/drivers/vertigo.c8
-rw-r--r--src/mame/includes/tx1.h4
-rw-r--r--src/mame/includes/vertigo.h2
-rw-r--r--src/mame/machine/pcshare.c68
-rw-r--r--src/mame/machine/pcshare.h3
-rw-r--r--src/mame/machine/vertigo.c20
16 files changed, 1438 insertions, 367 deletions
diff --git a/.gitattributes b/.gitattributes
index a40205cf5e4..4ab2ae1a782 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -499,6 +499,7 @@ src/emu/debug/textbuf.c svneol=native#text/plain
src/emu/debug/textbuf.h svneol=native#text/plain
src/emu/debugger.h svneol=native#text/plain
src/emu/deprecat.h svneol=native#text/plain
+src/emu/devconv.h svneol=native#text/plain
src/emu/devintrf.c svneol=native#text/plain
src/emu/devintrf.h svneol=native#text/plain
src/emu/drawgfx.c svneol=native#text/plain
diff --git a/src/emu/devconv.h b/src/emu/devconv.h
new file mode 100644
index 00000000000..1980f7b0206
--- /dev/null
+++ b/src/emu/devconv.h
@@ -0,0 +1,1020 @@
+/***************************************************************************
+
+ devconv.h
+
+ Functions which help convert between different device handlers.
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+****************************************************************************
+
+ ***** VERY IMPORTANT NOTICE *****
+
+ These functions and macros are provided to facilitate the mapping
+ of devices on cpus with different data bus widths.
+ Devices should be implemented using their native data bus width,
+ since that ensures that read/write operations are kept atomic.
+ If we discover you have abused the functionality presented in this
+ file, you *will* be publicly humiliated and your code submission
+ will probably not be accepted. Seriously, please do not abuse these
+ functions/macros.
+
+****************************************************************************
+
+ Conversions supported:
+
+ CW = CPU Data Bus Width in bits
+ CBO = CPU Byte Order
+ DW = Device Data Bus Width in bits
+ DBO = Device Byte Order
+
+ CW | CBO | DW | DBO | Functions to use
+ ---+--------+----+--------+-----------------------------------------------------------
+ 16 | Big | 8 | N/A | read16be_with_read8_device_handler,write16be_with_write8_device_handler
+ 16 | Little | 8 | N/A | read16le_with_read8_device_handler,write16le_with_write8_device_handler
+ ---+--------+----+--------+-----------------------------------------------------------
+ 32 | Big | 8 | N/A | read32be_with_read8_device_handler,write32be_with_write8_device_handler
+ 32 | Little | 8 | N/A | read32le_with_read8_device_handler,write32le_with_write8_device_handler
+ 32 | Big | 16 | Big | read32be_with_16be_device_handler,write32be_with_16be_device_handler
+ 32 | Little | 16 | Little | read32le_with_16le_device_handler,write32le_with_16le_device_handler
+ 32 | Big | 16 | Little | read32be_with_16le_device_handler,write32be_with_16le_device_handler
+ 32 | Little | 16 | Big | read32le_with_16be_device_handler,write32le_with_16be_device_handler
+ ---+--------+----+--------+-----------------------------------------------------------
+ 64 | Big | 8 | N/A | read64be_with_read8_device_handler,write64be_with_write8_device_handler
+ 64 | Little | 8 | N/A | read64le_with_read8_device_handler,write64le_with_write8_device_handler
+ 64 | Big | 16 | Big | read64be_with_16be_device_handler,write64be_with_16be_device_handler
+ 64 | Little | 16 | Little | read64le_with_16le_device_handler,write64le_with_16le_device_handler
+ 64 | Big | 16 | Little | read64be_with_16le_device_handler,write64be_with_16le_device_handler
+ 64 | Little | 16 | Big | read64le_with_16be_device_handler,write64le_with_16be_device_handler
+ 64 | Big | 32 | Big | read64be_with_32be_device_handler,write64be_with_32be_device_handler
+ 64 | Little | 32 | Little | read64le_with_32le_device_handler,write64le_with_32le_device_handler
+ 64 | Big | 32 | Little | read64be_with_32le_device_handler,write64be_with_32le_device_handler
+ 64 | Little | 32 | Big | read64le_with_32be_device_handler,write64le_with_32be_device_handler
+
+ You can also find at the bottom of this file a few convernient
+ macros that will create the stub read and/or write handlers for
+ the most common mappings, that will use the functions above.
+ Here's an example on how to use them: Say you have a 8 bit device
+ whose handlers are device8_r and device8_w, and you want to connect
+ it to a 16 bit, big endian cpu. We'll say the device is mapped on
+ the least significant byte of the data bus (LSB).
+
+ In your driver, you would add:
+
+ DEV_READWRITE8TO16BE_LSB( device16, device8_r, device8_w )
+
+ which will create two 16 bit memory handlers, one for read, called
+ device16_r, and one for write, called device16_w, with the proper
+ mapping.
+
+ then in the MEMORY_MAP you would specify:
+
+ AM_RANGE(0x000000, 0x0000ff) AM_DEVREADWRITE( DEVICE, "device", device16_r, device16_w )
+
+ And that is all. Your device should be mapped properly.
+ If you need to do custom mappings, or a mapping that is not currently
+ supported in this file, you can always write the stub yourself, and
+ call the above functions to invoke the base handlers.
+
+***************************************************************************/
+
+/*************************************
+ *
+ * 16-bit BE using 8-bit handlers
+ *
+ *************************************/
+
+INLINE UINT16 read16be_with_read8_device_handler(read8_device_func handler, void *param, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 result = 0;
+ if ((mem_mask & 0xff00) != 0xff00)
+ result |= ((UINT16)(*handler)(param, offset * 2 + 0)) << 8;
+ if ((mem_mask & 0x00ff) != 0x00ff)
+ result |= ((UINT16)(*handler)(param, offset * 2 + 1)) << 0;
+ return result;
+}
+
+
+INLINE void write16be_with_write8_device_handler(write8_device_func handler, void *param, offs_t offset, UINT16 data, UINT16 mem_mask)
+{
+ if ((mem_mask & 0xff00) != 0xff00)
+ (*handler)(param, offset * 2 + 0, data >> 8);
+ if ((mem_mask & 0x00ff) != 0x00ff)
+ (*handler)(param, offset * 2 + 1, data >> 0);
+}
+
+
+/*************************************
+ *
+ * 16-bit LE using 8-bit handlers
+ *
+ *************************************/
+
+INLINE UINT16 read16le_with_read8_device_handler(read8_device_func handler, void *param, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 result = 0;
+ if ((mem_mask & 0x00ff) != 0x00ff)
+ result |= ((UINT16) (*handler)(param, offset * 2 + 0)) << 0;
+ if ((mem_mask & 0xff00) != 0xff00)
+ result |= ((UINT16) (*handler)(param, offset * 2 + 1)) << 8;
+ return result;
+}
+
+
+INLINE void write16le_with_write8_device_handler(write8_device_func handler, void *param, offs_t offset, UINT16 data, UINT16 mem_mask)
+{
+ if ((mem_mask & 0x00ff) != 0x00ff)
+ (*handler)(param, offset * 2 + 0, data >> 0);
+ if ((mem_mask & 0xff00) != 0xff00)
+ (*handler)(param, offset * 2 + 1, data >> 8);
+}
+
+
+/*************************************
+ *
+ * 32-bit BE using 8-bit handlers
+ *
+ *************************************/
+
+INLINE UINT32 read32be_with_read8_device_handler(read8_device_func handler, void *param, offs_t offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ result |= read16be_with_read8_device_handler(handler, param, offset * 2 + 0, mem_mask >> 16) << 16;
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ result |= read16be_with_read8_device_handler(handler, param, offset * 2 + 1, mem_mask) << 0;
+ return result;
+}
+
+
+INLINE void write32be_with_write8_device_handler(write8_device_func handler, void *param, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ write16be_with_write8_device_handler(handler, param, offset * 2 + 0, data >> 16, mem_mask >> 16);
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ write16be_with_write8_device_handler(handler, param, offset * 2 + 1, data, mem_mask);
+}
+
+
+/*************************************
+ *
+ * 32-bit LE using 8-bit handlers
+ *
+ *************************************/
+
+INLINE UINT32 read32le_with_read8_device_handler(read8_device_func handler, void *param, offs_t offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ result |= read16le_with_read8_device_handler(handler, param, offset * 2 + 0, mem_mask) << 0;
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ result |= read16le_with_read8_device_handler(handler, param, offset * 2 + 1, mem_mask >> 16) << 16;
+ return result;
+}
+
+
+INLINE void write32le_with_write8_device_handler(write8_device_func handler, void *param, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ write16le_with_write8_device_handler(handler, param, offset * 2 + 0, data, mem_mask);
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ write16le_with_write8_device_handler(handler, param, offset * 2 + 1, data >> 16, mem_mask >> 16);
+}
+
+
+/*************************************
+ *
+ * 32-bit BE using 16-bit BE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read32be_with_16be_device_handler(read16_device_func handler, void *param, offs_t offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ result |= (*handler)(param, offset * 2 + 0, mem_mask >> 16) << 16;
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ result |= (*handler)(param, offset * 2 + 1, mem_mask) << 0;
+ return result;
+}
+
+
+INLINE void write32be_with_16be_device_handler(write16_device_func handler, void *param, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ (*handler)(param, offset * 2 + 0, data >> 16, mem_mask >> 16);
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ (*handler)(param, offset * 2 + 1, data, mem_mask);
+}
+
+
+/*************************************
+ *
+ * 32-bit LE using 16-bit LE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read32le_with_16le_device_handler(read16_device_func handler, void *param, offs_t offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ result |= (*handler)(param, offset * 2 + 0, mem_mask) << 0;
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ result |= (*handler)(param, offset * 2 + 1, mem_mask >> 16) << 16;
+ return result;
+}
+
+
+INLINE void write32le_with_16le_device_handler(write16_device_func handler, void *param, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ if ((mem_mask & 0x0000ffff) != 0x0000ffff)
+ (*handler)(param, offset * 2 + 0, data, mem_mask);
+ if ((mem_mask & 0xffff0000) != 0xffff0000)
+ (*handler)(param, offset * 2 + 1, data >> 16, mem_mask >> 16);
+}
+
+
+/*************************************
+ *
+ * 32-bit BE using 16-bit LE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read32be_with_16le_device_handler(read16_device_func handler, void *param, offs_t offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+ mem_mask = FLIPENDIAN_INT32(mem_mask);
+ result = read32le_with_16le_device_handler(handler, param, offset, mem_mask);
+ return FLIPENDIAN_INT32(result);
+}
+
+
+INLINE void write32be_with_16le_device_handler(write16_device_func handler, void *param, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ data = FLIPENDIAN_INT32(data);
+ mem_mask = FLIPENDIAN_INT32(mem_mask);
+ write32le_with_16le_device_handler(handler, param, offset, data, mem_mask);
+}
+
+
+/*************************************
+ *
+ * 32-bit LE using 16-bit BE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read32le_with_16be_device_handler(read16_device_func handler, void *param, offs_t offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+ mem_mask = FLIPENDIAN_INT32(mem_mask);
+ result = read32be_with_16be_device_handler(handler, param, offset, mem_mask);
+ return FLIPENDIAN_INT32(result);
+}
+
+
+INLINE void write32le_with_16be_device_handler(write16_device_func handler, void *param, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ data = FLIPENDIAN_INT32(data);
+ mem_mask = FLIPENDIAN_INT32(mem_mask);
+ write32be_with_16be_device_handler(handler, param, offset, data, mem_mask);
+}
+
+
+/*************************************
+ *
+ * 64-bit BE using 8-bit handlers
+ *
+ *************************************/
+
+INLINE UINT64 read64be_with_read8_device_handler(read8_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)read32be_with_read8_device_handler(handler, param, offset * 2 + 0, mem_mask >> 32) << 32;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)read32be_with_read8_device_handler(handler, param, offset * 2 + 1, mem_mask) << 0;
+ return result;
+}
+
+
+INLINE void write64be_with_write8_device_handler(write8_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ write32be_with_write8_device_handler(handler, param, offset * 2 + 0, data >> 32, mem_mask >> 32);
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ write32be_with_write8_device_handler(handler, param, offset * 2 + 1, data, mem_mask);
+}
+
+
+/*************************************
+ *
+ * 64-bit LE using 8-bit handlers
+ *
+ *************************************/
+
+INLINE UINT64 read64le_with_read8_device_handler(read8_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)read32le_with_read8_device_handler(handler, param, offset * 2 + 0, mem_mask >> 0) << 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)read32le_with_read8_device_handler(handler, param, offset * 2 + 1, mem_mask >> 32) << 32;
+ return result;
+}
+
+
+INLINE void write64le_with_write8_device_handler(write8_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ write32le_with_write8_device_handler(handler, param, offset * 2 + 0, data >> 0, mem_mask >> 0);
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ write32le_with_write8_device_handler(handler, param, offset * 2 + 1, data >> 32, mem_mask >> 32);
+}
+
+
+/*************************************
+ *
+ * 64-bit BE using 16-bit BE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read64be_with_16be_device_handler(read16_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)read32be_with_16be_device_handler(handler, param, offset * 2 + 0, mem_mask >> 32) << 32;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)read32be_with_16be_device_handler(handler, param, offset * 2 + 1, mem_mask >> 0) << 0;
+ return result;
+}
+
+
+INLINE void write64be_with_16be_device_handler(write16_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ write32be_with_16be_device_handler(handler, param, offset * 2 + 0, data >> 32, mem_mask >> 32);
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ write32be_with_16be_device_handler(handler, param, offset * 2 + 1, data >> 0, mem_mask >> 0);
+}
+
+
+/*************************************
+ *
+ * 64-bit LE using 16-bit LE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read64le_with_16le_device_handler(read16_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)read32le_with_16le_device_handler(handler, param, offset * 2 + 0, mem_mask >> 0) << 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)read32le_with_16le_device_handler(handler, param, offset * 2 + 1, mem_mask >> 32) << 32;
+ return result;
+}
+
+
+INLINE void write64le_with_16le_device_handler(write16_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ write32le_with_16le_device_handler(handler, param, offset * 2 + 0, data >> 0, mem_mask >> 0);
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ write32le_with_16le_device_handler(handler, param, offset * 2 + 1, data >> 32, mem_mask >> 32);
+}
+
+
+/*************************************
+ *
+ * 64-bit BE using 16-bit LE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read64be_with_16le_device_handler(read16_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)read32be_with_16le_device_handler(handler, param, offset * 2 + 0, mem_mask >> 32) << 32;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)read32be_with_16le_device_handler(handler, param, offset * 2 + 1, mem_mask >> 0) << 0;
+ return result;
+}
+
+
+INLINE void write64be_with_16le_device_handler(write16_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ write32be_with_16le_device_handler(handler, param, offset * 2 + 0, data >> 32, mem_mask >> 32);
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ write32be_with_16le_device_handler(handler, param, offset * 2 + 1, data >> 0, mem_mask >> 0);
+}
+
+
+/*************************************
+ *
+ * 64-bit LE using 16-bit BE handlers
+ *
+ *************************************/
+
+INLINE UINT32 read64le_with_16be_device_handler(read16_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)read32le_with_16be_device_handler(handler, param, offset * 2 + 0, mem_mask >> 0) << 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)read32le_with_16be_device_handler(handler, param, offset * 2 + 1, mem_mask >> 32) << 32;
+ return result;
+}
+
+
+INLINE void write64le_with_16be_device_handler(write16_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ write32le_with_16be_device_handler(handler, param, offset * 2 + 0, data >> 0, mem_mask >> 0);
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ write32le_with_16be_device_handler(handler, param, offset * 2 + 1, data >> 32, mem_mask >> 32);
+}
+
+
+/*************************************
+ *
+ * 64-bit BE using 32-bit BE handlers
+ *
+ *************************************/
+
+INLINE UINT64 read64be_with_32be_device_handler(read32_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)(*handler)(param, offset * 2 + 0, mem_mask >> 32) << 32;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)(*handler)(param, offset * 2 + 1, mem_mask >> 0) << 0;
+ return result;
+}
+
+
+INLINE void write64be_with_32be_device_handler(write32_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ (*handler)(param, offset * 2 + 0, data >> 32, mem_mask >> 32);
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ (*handler)(param, offset * 2 + 1, data >> 0, mem_mask >> 0);
+}
+
+
+/*************************************
+ *
+ * 64-bit LE using 32-bit LE handlers
+ *
+ *************************************/
+
+INLINE UINT64 read64le_with_32le_device_handler(read32_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result = 0;
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ result |= (UINT64)(*handler)(param, offset * 2 + 0, mem_mask >> 0) << 0;
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ result |= (UINT64)(*handler)(param, offset * 2 + 1, mem_mask >> 32) << 32;
+ return result;
+}
+
+
+INLINE void write64le_with_32le_device_handler(write32_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ (*handler)(param, offset * 2 + 0, data >> 0, mem_mask >> 0);
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ (*handler)(param, offset * 2 + 1, data >> 32, mem_mask >> 32);
+}
+
+
+/*************************************
+ *
+ * 64-bit BE using 32-bit LE handlers
+ *
+ *************************************/
+
+INLINE UINT64 read64be_with_32le_device_handler(read32_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result;
+ mem_mask = FLIPENDIAN_INT64(mem_mask);
+ result = read64le_with_32le_device_handler(handler, param, offset, mem_mask);
+ return FLIPENDIAN_INT64(result);
+}
+
+
+INLINE void write64be_with_32le_device_handler(write32_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ data = FLIPENDIAN_INT64(data);
+ mem_mask = FLIPENDIAN_INT64(mem_mask);
+ write64le_with_32le_device_handler(handler, param, offset, data, mem_mask);
+}
+
+
+/*************************************
+ *
+ * 64-bit LE using 32-bit BE handlers
+ *
+ *************************************/
+
+INLINE UINT64 read64le_with_32be_device_handler(read32_device_func handler, void *param, offs_t offset, UINT64 mem_mask)
+{
+ UINT64 result;
+ mem_mask = FLIPENDIAN_INT64(mem_mask);
+ result = read64be_with_32be_device_handler(handler, param, offset, mem_mask);
+ return FLIPENDIAN_INT64(result);
+}
+
+
+INLINE void write64le_with_32be_device_handler(write32_device_func handler, void *param, offs_t offset, UINT64 data, UINT64 mem_mask)
+{
+ data = FLIPENDIAN_INT64(data);
+ mem_mask = FLIPENDIAN_INT64(mem_mask);
+ write64be_with_32be_device_handler(handler, param, offset, data, mem_mask);
+}
+
+
+
+/**************************************************************************
+
+ Utility macros
+
+**************************************************************************/
+
+#define DEV_READ_TEMPLATE(bits, name, handler, func) \
+READ##bits##_DEVICE_HANDLER( name##_r ) \
+{ \
+ return func(handler, device, offset, mem_mask); \
+}
+
+#define DEV_READ_TEMPLATE_COND(bits, name, handler, func, cond) \
+READ##bits##_DEVICE_HANDLER( name##_r ) \
+{ \
+ if (cond) \
+ return func(handler, device, offset, mem_mask); \
+ return 0; \
+}
+
+#define DEV_WRITE_TEMPLATE(bits, name, handler, func) \
+WRITE##bits##_DEVICE_HANDLER( name##_w ) \
+{ \
+ func(handler, device, offset, data, mem_mask); \
+}
+
+#define DEV_WRITE_TEMPLATE_COND(bits, name, handler, func, cond) \
+WRITE##bits##_DEVICE_HANDLER( name##_w ) \
+{ \
+ if (cond) \
+ return func(handler, device, offset, data, mem_mask); \
+}
+
+
+
+/**************************************************************************
+
+ Generic conversions macros
+
+**************************************************************************/
+
+
+/*************************************
+ * 8->16be, 1:1 mapping
+ ************************************/
+
+#define DEV_READ8TO16BE( name, read8 ) \
+DEV_READ_TEMPLATE( 16, name, read8, read16be_with_read8_device_handler )
+
+
+#define DEV_WRITE8TO16BE( name, write8 ) \
+DEV_WRITE_TEMPLATE( 16, name, write8, write16be_with_write8_device_handler )
+
+
+#define DEV_READWRITE8TO16BE( name, read8, write8 ) \
+DEV_READ8TO16BE(name,read8) \
+DEV_WRITE8TO16BE(name,write8)
+
+
+/*************************************
+ * 8->16le, 1:1 mapping
+ ************************************/
+
+#define DEV_READ8TO16LE( name, read8 ) \
+DEV_READ_TEMPLATE( 16, name, read8, read16le_with_read8_device_handler )
+
+
+#define DEV_WRITE8TO16LE( name, write8 ) \
+DEV_WRITE_TEMPLATE( 16, name, write8, write16le_with_write8_device_handler )
+
+
+#define DEV_READWRITE8TO16LE( name, read8, write8 ) \
+DEV_READ8TO16LE(name,read8) \
+DEV_WRITE8TO16LE(name,write8)
+
+
+/*************************************
+ * 8->16be, MSB mapping
+ ************************************/
+
+#define DEV_READ8TO16BE_MSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 16, name, read8, read16be_with_read8_device_handler, ACCESSING_MSB )
+
+
+#define DEV_WRITE8TO16BE_MSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 16, name, write8, write16be_with_write8_device_handler, ACCESSING_MSB )
+
+
+#define DEV_READWRITE8TO16BE_MSB( name, read8, write8 ) \
+DEV_READ8TO16BE_MSB(name,read8) \
+DEV_WRITE8TO16BE_MSB(name,write8)
+
+
+/*************************************
+ * 8->16le, MSB mapping
+ ************************************/
+
+#define DEV_READ8TO16LE_MSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 16, name, read8, read16le_with_read8_device_handler, ACCESSING_MSB )
+
+
+#define DEV_WRITE8TO16LE_MSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 16, name, write8, write16le_with_write8_device_handler, ACCESSING_MSB )
+
+
+#define DEV_READWRITE8TO16LE_MSB( name, read8, write8 ) \
+DEV_READ8TO16LE_MSB(name,read8) \
+DEV_WRITE8TO16LE_MSB(name,write8)
+
+
+/*************************************
+ * 8->16be, LSB mapping
+ ************************************/
+
+#define DEV_READ8TO16BE_LSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 16, name, read8, read16be_with_read8_device_handler, ACCESSING_LSB )
+
+
+#define DEV_WRITE8TO16BE_LSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 16, name, write8, write16be_with_write8_device_handler, ACCESSING_LSB )
+
+
+#define DEV_READWRITE8TO16BE_LSB( name, read8, write8 ) \
+DEV_READ8TO16BE_LSB(name,read8) \
+DEV_WRITE8TO16BE_LSB(name,write8)
+
+
+/*************************************
+ * 8->16le, LSB mapping
+ ************************************/
+
+#define DEV_READ8TO16LE_LSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 16, name, read8, read16le_with_read8_device_handler, ACCESSING_LSB )
+
+
+#define DEV_WRITE8TO16LE_LSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 16, name, write8, write16le_with_write8_device_handler, ACCESSING_LSB )
+
+
+#define DEV_READWRITE8TO16LE_LSB( name, read8, write8 ) \
+DEV_READ8TO16LE_LSB(name,read8) \
+DEV_WRITE8TO16LE_LSB(name,write8)
+
+
+/*************************************
+ * 8->32be, 1:1 mapping
+ ************************************/
+
+#define DEV_READ8TO32BE( name, read8 ) \
+DEV_READ_TEMPLATE( 32, name, read8, read32be_with_read8_device_handler )
+
+
+#define DEV_WRITE8TO32BE( name, write8 ) \
+DEV_WRITE_TEMPLATE( 32, name, write8, write32be_with_write8_device_handler )
+
+
+#define DEV_READWRITE8TO32BE( name, read8, write8 ) \
+DEV_READ8TO32BE(name,read8) \
+DEV_WRITE8TO32BE(name,write8)
+
+
+/*************************************
+ * 8->32le, 1:1 mapping
+ ************************************/
+
+#define DEV_READ8TO32LE( name, read8 ) \
+DEV_READ_TEMPLATE( 32, name, read8, read32le_with_read8_device_handler )
+
+
+#define DEV_WRITE8TO32LE( name, write8 ) \
+DEV_WRITE_TEMPLATE( 32, name, write8, write32le_with_write8_device_handler )
+
+
+#define DEV_READWRITE8TO32LE( name, read8, write8 ) \
+DEV_READ8TO32LE(name,read8) \
+DEV_WRITE8TO32LE(name,write8)
+
+
+/*************************************
+ * 8->32be, MSB mapping
+ ************************************/
+
+#define DEV_READ8TO32BE_MSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read8, read32be_with_read8_device_handler, ACCESSING_MSB32 )
+
+
+#define DEV_WRITE8TO32BE_MSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write8, write32be_with_write8_device_handler, ACCESSING_MSB32 )
+
+
+#define DEV_READWRITE8TO32BE_MSB( name, read8, write8 ) \
+DEV_READ8TO32BE_MSB(name,read8) \
+DEV_WRITE8TO32BE_MSB(name,write8)
+
+
+/*************************************
+ * 8->32le, MSB mapping
+ ************************************/
+
+#define DEV_READ8TO32LE_MSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read8, read32le_with_read8_device_handler, ACCESSING_MSB32 )
+
+
+#define DEV_WRITE8TO32LE_MSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write8, write32le_with_write8_device_handler, ACCESSING_MSB32 )
+
+
+#define DEV_READWRITE8TO32LE_MSB( name, read8, write8 ) \
+DEV_READ8TO32LE_MSB(name,read8) \
+DEV_WRITE8TO32LE_MSB(name,write8)
+
+
+/*************************************
+ * 8->32be, LSB mapping
+ ************************************/
+
+#define DEV_READ8TO32BE_LSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read8, read32be_with_read8_device_handler, ACCESSING_LSB32 )
+
+
+#define DEV_WRITE8TO32BE_LSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write8, write32be_with_write8_device_handler, ACCESSING_LSB32 )
+
+
+#define DEV_READWRITE8TO32BE_LSB( name, read8, write8 ) \
+DEV_READ8TO32BE_LSB(name,read8) \
+DEV_WRITE8TO32BE_LSB(name,write8)
+
+
+/*************************************
+ * 8->32le, LSB mapping
+ ************************************/
+
+#define DEV_READ8TO32LE_LSB( name, read8 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read8, read32le_with_read8_device_handler, ACCESSING_LSB32 )
+
+
+#define DEV_WRITE8TO32LE_LSB( name, write8 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write8, write32le_with_write8_device_handler, ACCESSING_LSB32 )
+
+
+#define DEV_READWRITE8TO32LE_LSB( name, read8, write8 ) \
+DEV_READ8TO32LE_LSB(name,read8) \
+DEV_WRITE8TO32LE_LSB(name,write8)
+
+
+/*************************************
+ * 8->64be, 1:1 mapping
+ ************************************/
+
+#define DEV_READ8TO64BE( name, read8 ) \
+DEV_READ_TEMPLATE( 64, name, read8, read64be_with_read8_device_handler )
+
+
+#define DEV_WRITE8TO64BE( name, write8 ) \
+DEV_WRITE_TEMPLATE( 64, name, write8, write64be_with_write8_device_handler )
+
+
+#define DEV_READWRITE8TO64BE( name, read8, write8 ) \
+DEV_READ8TO64BE(name,read8) \
+DEV_WRITE8TO64BE(name,write8)
+
+
+/*************************************
+ * 8->64le, 1:1 mapping
+ ************************************/
+
+#define DEV_READ8TO64LE( name, read8 ) \
+DEV_READ_TEMPLATE( 64, name, read8, read64le_with_read8_device_handler )
+
+
+#define DEV_WRITE8TO64LE( name, write8 ) \
+DEV_WRITE_TEMPLATE( 64, name, write8, write64le_with_write8_device_handler )
+
+
+#define DEV_READWRITE8TO64LE( name, read8, write8 ) \
+DEV_READ8TO64LE(name,read8) \
+DEV_WRITE8TO64LE(name,write8)
+
+
+/*************************************
+ * 16be->32be, 1:1 mapping
+ *************************************/
+
+#define DEV_READ16BETO32BE( name, read16 ) \
+DEV_READ_TEMPLATE( 32, name, read16, read32be_with_16be_device_handler )
+
+
+#define DEV_WRITE16BETO32BE( name, write16 ) \
+DEV_WRITE_TEMPLATE( 32, name, write16, write32be_with_16be_device_handler )
+
+
+#define DEV_READWRITE16BETO32BE( name, read16, write16 ) \
+DEV_READ16BETO32BE(name,read16) \
+DEV_WRITE16BETO32BE(name,write16)
+
+
+/*************************************
+ * 16le->32be, 1:1 mapping
+ *************************************/
+
+#define DEV_READ16LETO32BE( name, read16 ) \
+DEV_READ_TEMPLATE( 32, name, read16, read32be_with_16le_device_handler )
+
+
+#define DEV_WRITE16LETO32BE( name, write16 ) \
+DEV_WRITE_TEMPLATE( 32, name, write16, write32be_with_16le_device_handler )
+
+
+#define DEV_READWRITE16LETO32BE( name, read16, write16 ) \
+DEV_READ16LETO32BE(name,read16) \
+DEV_WRITE16LETO32BE(name,write16)
+
+
+/*************************************
+ * 16be->32le, 1:1 mapping
+ *************************************/
+
+#define DEV_READ16BETO32LE( name, read16 ) \
+DEV_READ_TEMPLATE( 32, name, read16, read32le_with_16be_device_handler )
+
+
+#define DEV_WRITE16BETO32LE( name, write16 ) \
+DEV_WRITE_TEMPLATE( 32, name, write16, write32le_with_16be_device_handler )
+
+
+#define DEV_READWRITE16BETO32LE( name, read16, write16 ) \
+DEV_READ16BETO32LE(name,read16) \
+DEV_WRITE16BETO32LE(name,write16)
+
+
+/*************************************
+ * 16le->32le, 1:1 mapping
+ *************************************/
+
+#define DEV_READ16LETO32LE( name, read16 ) \
+DEV_READ_TEMPLATE( 32, name, read16, read32le_with_16le_device_handler )
+
+
+#define DEV_WRITE16LETO32LE( name, write16 ) \
+DEV_WRITE_TEMPLATE( 32, name, write16, write32le_with_16le_device_handler )
+
+
+#define DEV_READWRITE16LETO32LE( name, read16, write16 ) \
+DEV_READ16LETO32LE(name,read16) \
+DEV_WRITE16LETO32LE(name,write16)
+
+
+/*************************************
+ * 16be->32be, MSW mapping
+ *************************************/
+
+#define DEV_READ16BETO32BE_MSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32be_with_16be_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_WRITE16BETO32BE_MSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32be_with_16be_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_READWRITE16BETO32BE_MSW( name, read16, write16 ) \
+DEV_READ16BETO32BE_MSW(name,read16) \
+DEV_WRITE16BETO32BE_MSW(name,write16)
+
+
+/*************************************
+ * 16le->32be, MSW mapping
+ *************************************/
+
+#define DEV_READ16LETO32BE_MSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32be_with_16le_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_WRITE16LETO32BE_MSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32be_with_16le_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_READWRITE16LETO32BE_MSW( name, read16, write16 ) \
+DEV_READ16LETO32BE_MSW(name,read16) \
+DEV_WRITE16LETO32BE_MSW(name,write16)
+
+
+/*************************************
+ * 16be->32le, MSW mapping
+ *************************************/
+
+#define DEV_READ16BETO32LE_MSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32le_with_16be_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_WRITE16BETO32LE_MSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32le_with_16be_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_READWRITE16BETO32LE_MSW( name, read16, write16 ) \
+DEV_READ16BETO32LE_MSW(name,read16) \
+DEV_WRITE16BETO32LE_MSW(name,write16)
+
+
+/*************************************
+ * 16le->32le, MSW mapping
+ *************************************/
+
+#define DEV_READ16LETO32LE_MSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32le_with_16le_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_WRITE16LETO32LE_MSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32le_with_16le_device_handler, ACCESSING_MSW32 )
+
+
+#define DEV_READWRITE16LETO32LE_MSW( name, read16, write16 ) \
+DEV_READ16LETO32LE_MSW(name,read16) \
+DEV_WRITE16LETO32LE_MSW(name,write16)
+
+/*************************************
+ * 16be->32be, LSW mapping
+ *************************************/
+
+#define DEV_READ16BETO32BE_LSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32be_with_16be_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_WRITE16BETO32BE_LSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32be_with_16be_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_READWRITE16BETO32BE_LSW( name, read16, write16 ) \
+DEV_READ16BETO32BE_LSW(name,read16) \
+DEV_WRITE16BETO32BE_LSW(name,write16)
+
+
+/*************************************
+ * 16le->32be, LSW mapping
+ *************************************/
+
+#define DEV_READ16LETO32BE_LSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32be_with_16le_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_WRITE16LETO32BE_LSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32be_with_16le_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_READWRITE16LETO32BE_LSW( name, read16, write16 ) \
+DEV_READ16LETO32BE_LSW(name,read16) \
+DEV_WRITE16LETO32BE_LSW(name,write16)
+
+
+/*************************************
+ * 16be->32le, LSW mapping
+ *************************************/
+
+#define DEV_READ16BETO32LE_LSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32le_with_16be_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_WRITE16BETO32LE_LSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32le_with_16be_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_READWRITE16BETO32LE_LSW( name, read16, write16 ) \
+DEV_READ16BETO32LE_LSW(name,read16) \
+DEV_WRITE16BETO32LE_LSW(name,write16)
+
+
+/*************************************
+ * 16le->32le, LSW mapping
+ *************************************/
+
+#define DEV_READ16LETO32LE_LSW( name, read16 ) \
+DEV_READ_TEMPLATE_COND( 32, name, read16, read32le_with_16le_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_WRITE16LETO32LE_LSW( name, write16 ) \
+DEV_WRITE_TEMPLATE_COND( 32, name, write16, write32le_with_16le_device_handler, ACCESSING_LSW32 )
+
+
+#define DEV_READWRITE16LETO32LE_LSW( name, read16, write16 ) \
+DEV_READ16LETO32LE_LSW(name,read16) \
+DEV_WRITE16LETO32LE_LSW(name,write16)
+
diff --git a/src/emu/machine/pit8253.c b/src/emu/machine/pit8253.c
index d8f7251898e..f4ff14e5d52 100644
--- a/src/emu/machine/pit8253.c
+++ b/src/emu/machine/pit8253.c
@@ -8,6 +8,7 @@
* 8254 has an additional readback feature
*
* Revision History
+ * 1-Apr-2008 - WFP: Changed the implementation into a device.
* 8-Jul-2004 - AJ: Fixed some bugs. Styx now runs correctly.
* Implemented 8254 features.
* 1-Mar-2004 - NPW: Did an almost total rewrite and cleaned out much
@@ -19,7 +20,7 @@
#include <math.h>
#include "driver.h"
-#include "memconv.h"
+#include "devconv.h"
#include "machine/pit8253.h"
@@ -41,12 +42,25 @@
#define CYCLES_NEVER ((UINT32) -1)
+/* device types */
+enum {
+ TYPE_PIT8253 = 0,
+ TYPE_PIT8254,
+
+ NUM_TYPES
+};
+
+
+/* device tags */
+static const char * const device_tags[NUM_TYPES] = { "pit8253", "pit8254" };
+
+
struct pit8253_timer
{
double clockin; /* input clock frequency in Hz */
- void (*output_callback_func)(int); /* callback function for when output changes */
- void (*freq_callback)(double); /* callback function for when output frequency changes */
+ pit8253_output_changed_func output_changed; /* callback function for when output changes */
+ pit8253_frequency_changed_func frequency_changed; /* callback function for when output frequency changes */
attotime last_updated; /* time when last updated */
@@ -74,9 +88,11 @@ struct pit8253_timer
UINT32 freq_count; /* counter period for periodic modes, 0 if counter non-periodic */
};
-struct pit8253
+typedef struct _pit8253_t pit8253_t;
+struct _pit8253_t
{
const struct pit8253_config *config;
+ int device_type;
struct pit8253_timer timers[MAX_TIMER];
};
@@ -85,24 +101,23 @@ struct pit8253
#define CTRL_BCD(control) (((control) >> 0) & 0x01)
-static int pit_count;
-static struct pit8253 *pits;
-
-
-
/***************************************************************************
Functions
***************************************************************************/
-static struct pit8253 *get_pit(int which)
-{
- return &pits[which];
+/* makes sure that the passed in device is of the right type */
+INLINE pit8253_t *get_safe_token(const device_config *device) {
+ assert( device != NULL );
+ assert( device->token != NULL );
+ assert( ( device->type == DEVICE_GET_INFO_NAME(pit8253) ) ||
+ ( device->type == DEVICE_GET_INFO_NAME(pit8254) ) );
+ return ( pit8253_t * ) device->token;
}
-static struct pit8253_timer *get_timer(struct pit8253 *pit,int which)
+static struct pit8253_timer *get_timer(struct _pit8253_t *pit,int which)
{
which &= 3;
if (which < MAX_TIMER)
@@ -111,7 +126,7 @@ static struct pit8253_timer *get_timer(struct pit8253 *pit,int which)
}
-static UINT32 decimal_from_bcd(UINT16 val)
+INLINE UINT32 decimal_from_bcd(UINT16 val)
{
/* In BCD mode, a nybble loaded with value A-F counts down the same as in
binary mode, but wraps around to 9 instead of F after 0, so loading the
@@ -208,7 +223,7 @@ static void freq_callback_in(struct pit8253_timer *timer,UINT32 cycles)
{
LOG2(("pit8253: freq_callback_in(): %d cycles\n",cycles));
- if (timer->freq_callback == NULL)
+ if (timer->frequency_changed == NULL)
{
return;
}
@@ -225,7 +240,7 @@ static void freq_callback_in(struct pit8253_timer *timer,UINT32 cycles)
}
-static void set_freq_count(struct pit8253_timer *timer)
+static void set_freq_count(const device_config *device, struct pit8253_timer *timer)
{
int mode = CTRL_MODE(timer->control);
UINT32 freq_count;
@@ -242,9 +257,9 @@ static void set_freq_count(struct pit8253_timer *timer)
if (freq_count != timer->freq_count)
{
timer->freq_count = freq_count;
- if (timer->freq_callback != NULL)
+ if (timer->frequency_changed != NULL)
{
- timer->freq_callback(get_frequency(timer));
+ timer->frequency_changed(device, get_frequency(timer));
freq_callback_in(timer,CYCLES_NEVER);
}
}
@@ -254,7 +269,7 @@ static void set_freq_count(struct pit8253_timer *timer)
/* Call the output callback in "cycles" cycles */
-static void trigger_countdown(struct pit8253_timer *timer)
+static void trigger_countdown(const device_config *device, struct pit8253_timer *timer)
{
LOG2(("pit8253: trigger_countdown()\n"));
@@ -263,18 +278,18 @@ static void trigger_countdown(struct pit8253_timer *timer)
if (CTRL_MODE(timer->control) == 3 && timer->output == 0)
timer->value &= 0xfffe;
- set_freq_count(timer);
+ set_freq_count(device, timer);
}
-static void set_output(struct pit8253_timer *timer,int output)
+static void set_output(const device_config *device, struct pit8253_timer *timer,int output)
{
if (output != timer->output)
{
timer->output = output;
- if (timer->output_callback_func != NULL)
+ if (timer->output_changed != NULL)
{
- timer->output_callback_func(output);
+ timer->output_changed(device, output);
}
}
}
@@ -282,7 +297,7 @@ static void set_output(struct pit8253_timer *timer,int output)
/* This emulates timer "timer" for "elapsed_cycles" cycles and assumes no
callbacks occur during that time. */
-static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
+static void simulate2(const device_config *device, struct pit8253_timer *timer,UINT64 elapsed_cycles)
{
UINT32 adjusted_value;
int bcd = CTRL_BCD(timer->control);
@@ -358,7 +373,7 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
}
}
- set_output(timer,timer->phase == 3 ? 1 : 0);
+ set_output(device, timer, timer->phase == 3 ? 1 : 0);
break;
@@ -397,7 +412,7 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
decrease_counter_value(timer,elapsed_cycles);
cycles_to_output = CYCLES_NEVER;
}
- set_output(timer,timer->phase == 0 ? 1 : 0);
+ set_output(device, timer, timer->phase == 0 ? 1 : 0);
break;
@@ -427,7 +442,7 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
if (timer->gate == 0 || timer->phase == 0)
{
/* Gate low or mode control write forces output high */
- set_output(timer,1);
+ set_output(device, timer, 1);
cycles_to_output = CYCLES_NEVER;
}
else
@@ -442,12 +457,12 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
{
/* Counter wrapped around one or more times */
elapsed_cycles -= adjusted_value;
- trigger_countdown(timer);
+ trigger_countdown(device, timer);
decrease_counter_value(timer,elapsed_cycles % adjusted_count(bcd,timer->count));
}
cycles_to_output = (timer->value == 1 ? 1 : (adjusted_count(bcd,timer->value) - 1));
- set_output(timer,timer->value != 1 ? 1 : 0);
+ set_output(device, timer, timer->value != 1 ? 1 : 0);
}
break;
@@ -477,7 +492,7 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
if (timer->gate == 0 || timer->phase == 0)
{
/* Gate low or mode control write forces output high */
- set_output(timer,1);
+ set_output(device, timer, 1);
cycles_to_output = CYCLES_NEVER;
}
else
@@ -493,8 +508,8 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
/* Counter wrapped around one or more times */
elapsed_cycles -= ((adjusted_value+1)>>1);
- set_output(timer,1 - timer->output);
- trigger_countdown(timer);
+ set_output(device, timer, 1 - timer->output);
+ trigger_countdown(device, timer);
elapsed_cycles %= adjusted_count(bcd,timer->count);
adjusted_value = adjusted_count(bcd,timer->value);
@@ -503,8 +518,8 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
/* Counter wrapped around an even number of times */
elapsed_cycles -= ((adjusted_value+1)>>1);
- set_output(timer,1 - timer->output);
- trigger_countdown(timer);
+ set_output(device, timer, 1 - timer->output);
+ trigger_countdown(device, timer);
}
decrease_counter_value(timer,elapsed_cycles<<1);
}
@@ -598,11 +613,11 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
break;
}
}
- set_output(timer,timer->phase != 3 ? 1 : 0);
+ set_output(device, timer, timer->phase != 3 ? 1 : 0);
break;
}
- if (timer->output_callback_func != NULL)
+ if (timer->output_changed != NULL)
{
timer->cycles_to_output = cycles_to_output;
if (cycles_to_output == CYCLES_NEVER || timer->clockin == 0)
@@ -638,7 +653,7 @@ static void simulate2(struct pit8253_timer *timer,UINT64 elapsed_cycles)
inaccurate by more than one cycle, and the output changed multiple
times during the discrepancy. In practice updates should still be O(1).
*/
-static void simulate(struct pit8253_timer *timer,UINT64 elapsed_cycles)
+static void simulate(const device_config *device, struct pit8253_timer *timer,UINT64 elapsed_cycles)
{
while ((timer->cycles_to_output != CYCLES_NEVER &&
timer->cycles_to_output <= elapsed_cycles) ||
@@ -657,15 +672,15 @@ static void simulate(struct pit8253_timer *timer,UINT64 elapsed_cycles)
cycles_to_callback = timer->cycles_to_freq;
}
- simulate2(timer,cycles_to_callback);
+ simulate2(device, timer, cycles_to_callback);
elapsed_cycles -= cycles_to_callback;
}
- simulate2(timer,elapsed_cycles);
+ simulate2(device, timer, elapsed_cycles);
}
/* This brings timer "timer" up to date */
-static void update(struct pit8253_timer *timer)
+static void update(const device_config *device, struct pit8253_timer *timer)
{
/* With the 82C54's maximum clockin of 10MHz, 64 bits is nearly 60,000
years of time. Should be enough for now. */
@@ -675,51 +690,21 @@ static void update(struct pit8253_timer *timer)
timer->last_updated = attotime_add(timer->last_updated,double_to_attotime(elapsed_cycles/timer->clockin));
- simulate(timer,elapsed_cycles);
+ simulate(device, timer,elapsed_cycles);
}
-void pit8253_reset(int which)
+static TIMER_CALLBACK( frequency_changed )
{
- struct pit8253 *pit = get_pit(which);
- struct pit8253_timer *timer;
- int i;
-
- LOG1(("pit8253_reset(): resetting pit %d\n", which));
-
- for (i = 0; i < MAX_TIMER; i++)
- {
- timer = get_timer(pit,i);
- /* According to Intel's 8254 docs, the state of a timer is undefined
- until the first mode control word is written. Here we define this
- undefined behaviour */
- timer->control = timer->status = 0x30;
- timer->rmsb = timer->wmsb = 0;
- timer->count = timer->value = timer->latch = 0;
- timer->lowcount = 0;
- timer->gate = 1;
- timer->output = 0;
- timer->latched_count = 0;
- timer->latched_status = 0;
- timer->null_count = 1;
- timer->cycles_to_output = timer->cycles_to_freq = CYCLES_NEVER;
-
- timer->last_updated = timer_get_time();
-
- update(timer);
- }
-}
-
-
-static TIMER_CALLBACK( freqcallback )
-{
- struct pit8253_timer *timer = get_timer(get_pit(param & 0x0F),(param >> 4) & 0x0F);
+ const device_config *device = ptr;
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,param);
INT64 cycles = timer->cycles_to_freq;
double t;
- LOG2(("pit8253: freqcallback(): pit %d, timer %d, %d cycles\n",param & 0xf,(param >> 4) & 0xf,(UINT32)cycles));
+ LOG2(("pit8253: frequency_changed(): timer %d, %d cycles\n",param,(UINT32)cycles));
- simulate(timer,cycles);
+ simulate(device, timer,cycles);
t = cycles / timer->clockin;
@@ -727,15 +712,17 @@ static TIMER_CALLBACK( freqcallback )
}
-static TIMER_CALLBACK( outputcallback )
+static TIMER_CALLBACK( output_changed )
{
- struct pit8253_timer *timer = get_timer(get_pit(param & 0x0F),(param >> 4) & 0x0F);
+ const device_config *device = ptr;
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,param);
INT64 cycles = timer->cycles_to_output;
double t;
- LOG2(("pit8253: outputcallback(): pit %d, timer %d, %d cycles\n",param & 0xf,(param >> 4) & 0xf,(UINT32)cycles));
+ LOG2(("pit8253: output_changed(): timer %d, %d cycles\n",param,(UINT32)cycles));
- simulate(timer,cycles);
+ simulate(device, timer,cycles);
t = cycles / timer->clockin;
@@ -743,79 +730,6 @@ static TIMER_CALLBACK( outputcallback )
}
-int pit8253_init(int count, const struct pit8253_config *config)
-{
- int i, timerno, n=0;
- struct pit8253 *pit;
- struct pit8253_timer *timer;
-
- LOG2(("pit8253_init(): initializing %d pit(s)\n", count));
-
- pit_count = count;
- pits = auto_malloc(count * sizeof(struct pit8253));
-
- memset(pits, 0, count * sizeof(struct pit8253));
-
- for (i = 0; i < count; i++)
- {
- pit = get_pit(i);
- pit->config = &config[i];
-
- for (timerno = 0; timerno < MAX_TIMER; timerno++)
- {
- timer = get_timer(pit,timerno);
-
- timer->clockin = pit->config->timer[timerno].clockin;
- timer->output_callback_func = pit->config->timer[timerno].output_callback_func;
- timer->freq_callback = pit->config->timer[timerno].clock_callback;
-
- if (timer->output_callback_func == NULL)
- timer->outputtimer = NULL;
- else
- {
- timer->outputtimer = timer_alloc(outputcallback, NULL);
- timer_adjust_oneshot(timer->outputtimer, attotime_never, i | (timerno<<4));
- }
- if (timer->freq_callback == NULL)
- timer->freqtimer = NULL;
- else
- {
- timer->freqtimer = timer_alloc(freqcallback, NULL);
- timer_adjust_oneshot(timer->freqtimer, attotime_never, i | (timerno<<4));
- }
-
- /* set up state save values */
- state_save_register_item("pit8253", n, timer->clockin);
- state_save_register_item("pit8253", n, timer->control);
- state_save_register_item("pit8253", n, timer->status);
- state_save_register_item("pit8253", n, timer->lowcount);
- state_save_register_item("pit8253", n, timer->latch);
- state_save_register_item("pit8253", n, timer->count);
- state_save_register_item("pit8253", n, timer->value);
- state_save_register_item("pit8253", n, timer->wmsb);
- state_save_register_item("pit8253", n, timer->rmsb);
- state_save_register_item("pit8253", n, timer->output);
- state_save_register_item("pit8253", n, timer->gate);
- state_save_register_item("pit8253", n, timer->latched_count);
- state_save_register_item("pit8253", n, timer->latched_status);
- state_save_register_item("pit8253", n, timer->null_count);
- state_save_register_item("pit8253", n, timer->phase);
- state_save_register_item("pit8253", n, timer->cycles_to_output);
- state_save_register_item("pit8253", n, timer->cycles_to_freq);
- state_save_register_item("pit8253", n, timer->freq_count);
- state_save_register_item("pit8253", n, timer->last_updated.seconds);
- state_save_register_item("pit8253", n, timer->last_updated.attoseconds);
- ++n;
- }
- pit8253_reset(i);
- }
-
- LOG1(("pit8253_init(): initialized successfully\n"));
-
- return 0;
-}
-
-
/* We recycle bit 0 of timer->value to hold the phase in mode 3 when count is
odd. Since read commands in mode 3 always return even numbers, we need to
mask this bit off. */
@@ -833,14 +747,14 @@ static UINT16 masked_value(struct pit8253_timer *timer)
latched_count
rmsb
so they don't affect any timer operations except other reads. */
-static UINT8 pit8253_read(int which,offs_t offset)
+READ8_DEVICE_HANDLER( pit8253_r )
{
- struct pit8253 *pit = get_pit(which);
- struct pit8253_timer *timer = get_timer(pit,offset);
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,offset);
UINT8 data;
UINT16 value;
- LOG2(("pit8253_read(): pit %d, offset %d\n",which,offset));
+ LOG2(("pit8253_r(): offset %d\n", offset));
if (timer == NULL)
{
@@ -850,7 +764,7 @@ static UINT8 pit8253_read(int which,offs_t offset)
}
else
{
- update(timer);
+ update(device, timer);
if (timer->latched_status)
{
@@ -898,13 +812,13 @@ static UINT8 pit8253_read(int which,offs_t offset)
}
}
- LOG2(("pit8253_read(): PIT #%d offset=%d data=0x%02x\n", which, (int) offset, (unsigned) data));
+ LOG2(("pit8253_r(): offset=%d data=0x%02x\n", offset, data));
return data;
}
/* Loads a new value from the bus to the count register (CR) */
-static void load_count(struct pit8253_timer *timer, UINT16 newcount)
+static void load_count(const device_config *device, struct pit8253_timer *timer, UINT16 newcount)
{
int mode = CTRL_MODE(timer->control);
@@ -925,7 +839,7 @@ static void load_count(struct pit8253_timer *timer, UINT16 newcount)
{
if (timer->phase == 0)
{
- trigger_countdown(timer);
+ trigger_countdown(device, timer);
}
else
{
@@ -944,16 +858,16 @@ static void load_count(struct pit8253_timer *timer, UINT16 newcount)
{
if (mode == 0 || mode == 4)
{
- trigger_countdown(timer);
+ trigger_countdown(device, timer);
}
}
}
-static void readback(struct pit8253_timer *timer,int command)
+static void readback(const device_config *device, struct pit8253_timer *timer,int command)
{
UINT16 value;
- update(timer);
+ update(device, timer);
if ((command & 1) == 0)
{
@@ -1002,62 +916,62 @@ static void readback(struct pit8253_timer *timer,int command)
}
-static void pit8253_write(int which, offs_t offset, int data)
+WRITE8_DEVICE_HANDLER( pit8253_w )
{
- struct pit8253 *pit = get_pit(which);
- struct pit8253_timer *timer = get_timer(pit,offset);
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,offset);
int read_command;
- LOG2(("pit8253_write(): PIT #%d offset=%d data=0x%02x\n", which, (int) offset, (unsigned) data));
+ LOG2(("pit8253_w(): offset=%d data=0x%02x\n", offset, data));
if (timer == NULL) {
/* Write to mode control register */
- timer = get_timer(pit, (data >> 6) & 3);
+ timer = get_timer(pit8253, (data >> 6) & 3);
if (timer == NULL)
{
/* Readback command. Illegal on 8253 */
/* Todo: find out what (if anything) the 8253 hardware actually does here. */
- if (pit->config->type == TYPE8254)
+ if (pit8253->device_type == TYPE_PIT8254)
{
- LOG1(("pit8253_write(): PIT #%d readback %02x\n", which, data & 0x3f));
+ LOG1(("pit8253_w(): readback %02x\n", data & 0x3f));
/* Bit 0 of data must be 0. Todo: find out what the hardware does if it isn't. */
read_command = (data >> 4) & 3;
if ((data & 2) != 0)
- readback(get_timer(pit,0),read_command);
+ readback(device, get_timer(pit8253,0), read_command);
if ((data & 4) != 0)
- readback(get_timer(pit,1),read_command);
+ readback(device, get_timer(pit8253,1), read_command);
if ((data & 8) != 0)
- readback(get_timer(pit,2),read_command);
+ readback(device, get_timer(pit8253,2), read_command);
}
return;
}
- update(timer);
+ update(device, timer);
if (CTRL_ACCESS(data) == 0)
{
- LOG1(("pit8253_write(): PIT #%d timer=%d readback\n", which, (data >> 6) & 3));
+ LOG1(("pit8253_write(): timer=%d readback\n", (data >> 6) & 3));
/* Latch current timer value */
/* Experimentally verified: this command does not affect the mode control register */
- readback(timer,1);
+ readback(device, timer, 1);
}
else {
- LOG1(("pit8253_write(): PIT #%d timer=%d bytes=%d mode=%d bcd=%d\n", which, (data >> 6) & 3, (data >> 4) & 3, (data >> 1) & 7,data & 1));
+ LOG1(("pit8253_write(): timer=%d bytes=%d mode=%d bcd=%d\n", (data >> 6) & 3, (data >> 4) & 3, (data >> 1) & 7,data & 1));
timer->control = (data & 0x3f);
timer->null_count = 1;
timer->wmsb = timer->rmsb = 0;
/* Phase 0 is always the phase after a mode control write */
timer->phase = 0;
- set_output(timer,1);
- set_freq_count(timer);
+ set_output(device, timer, 1);
+ set_freq_count(device, timer);
}
}
else
{
- update(timer);
+ update(device, timer);
switch(CTRL_ACCESS(timer->control)) {
case 0:
@@ -1066,19 +980,19 @@ static void pit8253_write(int which, offs_t offset, int data)
case 1:
/* read/write counter bits 0-7 only */
- load_count(timer,data);
+ load_count(device, timer, data);
break;
case 2:
/* read/write counter bits 8-15 only */
- load_count(timer,data << 8);
+ load_count(device, timer, data << 8);
break;
case 3:
/* read/write bits 0-7 first, then 8-15 */
if (timer->wmsb != 0)
{
- load_count(timer,timer->lowcount | (data << 8));
+ load_count(device, timer,timer->lowcount | (data << 8));
}
else
{
@@ -1095,17 +1009,18 @@ static void pit8253_write(int which, offs_t offset, int data)
break;
}
}
- update(timer);
+ update(device, timer);
}
-static void pit8253_gate_write(int which,int offset,int data)
+WRITE8_DEVICE_HANDLER( pit8253_gate_w )
{
- struct pit8253_timer *timer = get_timer(get_pit(which),offset);
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,offset);
int mode;
int gate = (data!=0 ? 1 : 0);
- LOG2(("pit8253_gate_write(): PIT #%d offset=%d gate=%d\n", which, (int) offset, (unsigned) data));
+ LOG2(("pit8253_gate_w(): offset=%d gate=%d\n", offset, data));
if (timer == NULL)
return;
@@ -1114,16 +1029,16 @@ static void pit8253_gate_write(int which,int offset,int data)
if (gate != timer->gate)
{
- update(timer);
+ update(device, timer);
timer->gate = gate;
- set_freq_count(timer);
+ set_freq_count(device, timer);
if (gate != 0 &&
(mode == 1 || mode == 5 ||
(timer->phase == 1 && (mode == 2 || mode == 3))))
{
- trigger_countdown(timer);
+ trigger_countdown(device, timer);
}
- update(timer);
+ update(device, timer);
}
}
@@ -1131,42 +1046,45 @@ static void pit8253_gate_write(int which,int offset,int data)
/* ----------------------------------------------------------------------- */
-int pit8253_get_frequency(int which, int timerno)
+int pit8253_get_frequency(const device_config *device, int timerno)
{
- struct pit8253_timer *timer = get_timer(get_pit(which),timerno);
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,timerno);
- update(timer);
+ update(device, timer);
return get_frequency(timer);
}
-int pit8253_get_output(int which, int timerno)
+int pit8253_get_output(const device_config *device, int timerno)
{
- struct pit8253_timer *timer = get_timer(get_pit(which),timerno);
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,timerno);
int result;
- update(timer);
+ update(device, timer);
result = timer->output;
- LOG2(("pit8253_get_output(): PIT #%d timer=%d result=%d\n", which, timerno, result));
+ LOG2(("pit8253_get_output(): PIT timer=%d result=%d\n", timerno, result));
return result;
}
-void pit8253_set_clockin(int which, int timerno, double new_clockin)
+void pit8253_set_clockin(const device_config *device, int timerno, double new_clockin)
{
- struct pit8253_timer *timer = get_timer(get_pit(which),timerno);
+ pit8253_t *pit8253 = get_safe_token(device);
+ struct pit8253_timer *timer = get_timer(pit8253,timerno);
- LOG2(("pit8253_set_clockin(): PIT #%d timer=%d, clockin = %lf\n", which, (int) timerno,new_clockin));
+ LOG2(("pit8253_set_clockin(): PIT timer=%d, clockin = %lf\n", timerno,new_clockin));
- update(timer);
+ update(device, timer);
timer->clockin = new_clockin;
- update(timer);
+ update(device, timer);
- if (timer->freq_callback != NULL)
+ if (timer->frequency_changed != NULL)
{
- timer->freq_callback(get_frequency(timer));
+ timer->frequency_changed(device, get_frequency(timer));
if (timer->cycles_to_freq != CYCLES_NEVER)
{
freq_callback_in(timer,timer->cycles_to_freq);
@@ -1175,34 +1093,141 @@ void pit8253_set_clockin(int which, int timerno, double new_clockin)
}
+static void common_start( const device_config *device, int device_type ) {
+ pit8253_t *pit8253 = get_safe_token(device);
+ char unique_tag[30];
+ int timerno;
+
+ pit8253->config = device->static_config;
+ pit8253->device_type = device_type;
+
+ /* register for state saving */
+ state_save_combine_module_and_tag(unique_tag, device_tags[device_type], device->tag);
+
+ for (timerno = 0; timerno < MAX_TIMER; timerno++)
+ {
+ struct pit8253_timer *timer = get_timer(pit8253,timerno);
+
+ timer->clockin = pit8253->config->timer[timerno].clockin;
+ timer->output_changed = pit8253->config->timer[timerno].output_changed;
+ timer->frequency_changed = pit8253->config->timer[timerno].frequency_changed;
+
+ if (timer->output_changed == NULL)
+ timer->outputtimer = NULL;
+ else
+ {
+ timer->outputtimer = timer_alloc(output_changed, (void *)device);
+ timer_adjust_oneshot(timer->outputtimer, attotime_never, timerno);
+ }
+ if (timer->frequency_changed == NULL)
+ timer->freqtimer = NULL;
+ else
+ {
+ timer->freqtimer = timer_alloc(frequency_changed, (void *)device);
+ timer_adjust_oneshot(timer->freqtimer, attotime_never, timerno);
+ }
+
+ /* set up state save values */
+ state_save_register_item(unique_tag, timerno, timer->clockin);
+ state_save_register_item(unique_tag, timerno, timer->control);
+ state_save_register_item(unique_tag, timerno, timer->status);
+ state_save_register_item(unique_tag, timerno, timer->lowcount);
+ state_save_register_item(unique_tag, timerno, timer->latch);
+ state_save_register_item(unique_tag, timerno, timer->count);
+ state_save_register_item(unique_tag, timerno, timer->value);
+ state_save_register_item(unique_tag, timerno, timer->wmsb);
+ state_save_register_item(unique_tag, timerno, timer->rmsb);
+ state_save_register_item(unique_tag, timerno, timer->output);
+ state_save_register_item(unique_tag, timerno, timer->gate);
+ state_save_register_item(unique_tag, timerno, timer->latched_count);
+ state_save_register_item(unique_tag, timerno, timer->latched_status);
+ state_save_register_item(unique_tag, timerno, timer->null_count);
+ state_save_register_item(unique_tag, timerno, timer->phase);
+ state_save_register_item(unique_tag, timerno, timer->cycles_to_output);
+ state_save_register_item(unique_tag, timerno, timer->cycles_to_freq);
+ state_save_register_item(unique_tag, timerno, timer->freq_count);
+ state_save_register_item(unique_tag, timerno, timer->last_updated.seconds);
+ state_save_register_item(unique_tag, timerno, timer->last_updated.attoseconds);
+ }
+}
+
+
+static DEVICE_START( pit8253 ) {
+ common_start( device, TYPE_PIT8253 );
+}
-/* ----------------------------------------------------------------------- */
-READ8_HANDLER ( pit8253_0_r ) { return pit8253_read(0, offset); }
-READ8_HANDLER ( pit8253_1_r ) { return pit8253_read(1, offset); }
-WRITE8_HANDLER ( pit8253_0_w ) { pit8253_write(0, offset, data); }
-WRITE8_HANDLER ( pit8253_1_w ) { pit8253_write(1, offset, data); }
+static DEVICE_START( pit8254 ) {
+ common_start( device, TYPE_PIT8254 );
+}
-READ16_HANDLER ( pit8253_0_lsb_r ) { return pit8253_read(0, offset); }
-READ16_HANDLER ( pit8253_1_lsb_r ) { return pit8253_read(1, offset); }
-WRITE16_HANDLER ( pit8253_0_lsb_w ) { if (ACCESSING_BYTE_0) pit8253_write(0, offset, data); }
-WRITE16_HANDLER ( pit8253_1_lsb_w ) { if (ACCESSING_BYTE_0) pit8253_write(1, offset, data); }
-READ16_HANDLER ( pit8253_16le_0_r ) { return read16le_with_read8_handler(pit8253_0_r, machine, offset, mem_mask); }
-READ16_HANDLER ( pit8253_16le_1_r ) { return read16le_with_read8_handler(pit8253_1_r, machine, offset, mem_mask); }
-WRITE16_HANDLER ( pit8253_16le_0_w ) { write16le_with_write8_handler(pit8253_0_w, machine, offset, data, mem_mask); }
-WRITE16_HANDLER ( pit8253_16le_1_w ) { write16le_with_write8_handler(pit8253_1_w, machine, offset, data, mem_mask); }
+static DEVICE_RESET( pit8253 ) {
+ pit8253_t *pit = get_safe_token(device);
+ int i;
-READ32_HANDLER ( pit8253_32le_0_r ) { return read32le_with_read8_handler(pit8253_0_r, machine, offset, mem_mask); }
-READ32_HANDLER ( pit8253_32le_1_r ) { return read32le_with_read8_handler(pit8253_1_r, machine, offset, mem_mask); }
-WRITE32_HANDLER ( pit8253_32le_0_w ) { write32le_with_write8_handler(pit8253_0_w, machine, offset, data, mem_mask); }
-WRITE32_HANDLER ( pit8253_32le_1_w ) { write32le_with_write8_handler(pit8253_1_w, machine, offset, data, mem_mask); }
+ for (i = 0; i < MAX_TIMER; i++)
+ {
+ struct pit8253_timer *timer = get_timer(pit,i);
+ /* According to Intel's 8254 docs, the state of a timer is undefined
+ until the first mode control word is written. Here we define this
+ undefined behaviour */
+ timer->control = timer->status = 0x30;
+ timer->rmsb = timer->wmsb = 0;
+ timer->count = timer->value = timer->latch = 0;
+ timer->lowcount = 0;
+ timer->gate = 1;
+ timer->output = 0;
+ timer->latched_count = 0;
+ timer->latched_status = 0;
+ timer->null_count = 1;
+ timer->cycles_to_output = timer->cycles_to_freq = CYCLES_NEVER;
+
+ timer->last_updated = timer_get_time();
+
+ update(device, timer);
+ }
+}
-READ64_HANDLER ( pit8253_64be_0_r ) { return read64be_with_read8_handler(pit8253_0_r, machine, offset, mem_mask); }
-READ64_HANDLER ( pit8253_64be_1_r ) { return read64be_with_read8_handler(pit8253_1_r, machine, offset, mem_mask); }
-WRITE64_HANDLER ( pit8253_64be_0_w ) { write64be_with_write8_handler(pit8253_0_w, machine, offset, data, mem_mask); }
-WRITE64_HANDLER ( pit8253_64be_1_w ) { write64be_with_write8_handler(pit8253_1_w, machine, offset, data, mem_mask); }
-WRITE8_HANDLER ( pit8253_0_gate_w ) { pit8253_gate_write(0, offset, data); }
-WRITE8_HANDLER ( pit8253_1_gate_w ) { pit8253_gate_write(1, offset, data); }
+static DEVICE_SET_INFO( pit8253 ) {
+ switch ( state ) {
+ /* no parameters to set */
+ }
+}
+
+DEVICE_GET_INFO( pit8253 ) {
+ switch ( state ) {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(pit8253_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_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(pit8253); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(pit8253); break;
+ case DEVINFO_FCT_STOP: /* nothing */ break;
+ case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(pit8253); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: info->s = "Intel PIT8253"; break;
+ case DEVINFO_STR_FAMILY: info->s = "PIT8253"; break;
+ case DEVINFO_STR_VERSION: info->s = "1.00"; break;
+ case DEVINFO_STR_SOURCE_FILE: info->s = __FILE__; break;
+ case DEVINFO_STR_CREDITS: info->s = "Copyright the MAME and MESS Teams"; break;
+ }
+}
+
+
+DEVICE_GET_INFO( pit8254 ) {
+ switch ( state ) {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_STR_NAME: info->s = "Intel PIT8254"; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(pit8254); break;
+
+ default: DEVICE_GET_INFO_CALL(pit8253); break;
+ }
+}
diff --git a/src/emu/machine/pit8253.h b/src/emu/machine/pit8253.h
index 34d0dbcb6b0..189140229cb 100644
--- a/src/emu/machine/pit8253.h
+++ b/src/emu/machine/pit8253.h
@@ -4,59 +4,51 @@
*
*****************************************************************************/
-#ifndef PIT8253_H
-#define PIT8253_H
+#ifndef __PIT8253_H_
+#define __PIT8253_H_
+
+#define PIT8253 DEVICE_GET_INFO_NAME(pit8253)
+#define PIT8254 DEVICE_GET_INFO_NAME(pit8254)
+
+
+typedef void (*pit8253_output_changed_func)(const device_config *device, int state);
+#define PIT8253_OUTPUT_CHANGED(name) void name(const device_config *device, int state )
+
+typedef void (*pit8253_frequency_changed_func)(const device_config *device, double frequency);
+#define PIT8253_FREQUENCY_CHANGED(name) void name(const device_config *device, double frequency)
-typedef enum { TYPE8253, TYPE8254 } PIT8253_TYPE;
struct pit8253_config
{
- PIT8253_TYPE type;
struct
{
+ /* Input clock for this timer */
double clockin;
- void (*output_callback_func)(int state);
- void (*clock_callback)(double clockout);
- } timer[3];
-};
-
-
-int pit8253_init(int count, const struct pit8253_config *config);
-void pit8253_reset(int which);
+ /* If specified, this gets called whenever the output for this timer changes */
+ pit8253_output_changed_func output_changed;
-READ8_HANDLER ( pit8253_0_r );
-READ8_HANDLER ( pit8253_1_r );
-WRITE8_HANDLER ( pit8253_0_w );
-WRITE8_HANDLER ( pit8253_1_w );
+ /* If specified, this gets called whenever the frequency of the output for this
+ timer changes. */
+ pit8253_frequency_changed_func frequency_changed;
+ } timer[3];
+};
-READ16_HANDLER ( pit8253_0_lsb_r );
-READ16_HANDLER ( pit8253_1_lsb_r );
-WRITE16_HANDLER ( pit8253_0_lsb_w );
-WRITE16_HANDLER ( pit8253_1_lsb_w );
-READ16_HANDLER ( pit8253_16le_0_r );
-READ16_HANDLER ( pit8253_16le_1_r );
-WRITE16_HANDLER ( pit8253_16le_0_w );
-WRITE16_HANDLER ( pit8253_16le_1_w );
+/* device interface */
+DEVICE_GET_INFO( pit8253 );
+DEVICE_GET_INFO( pit8254 );
-READ32_HANDLER ( pit8253_32le_0_r );
-READ32_HANDLER ( pit8253_32le_1_r );
-WRITE32_HANDLER ( pit8253_32le_0_w );
-WRITE32_HANDLER ( pit8253_32le_1_w );
+READ8_DEVICE_HANDLER( pit8253_r );
+WRITE8_DEVICE_HANDLER( pit8253_w );
-READ64_HANDLER ( pit8253_64be_0_r );
-READ64_HANDLER ( pit8253_64be_1_r );
-WRITE64_HANDLER ( pit8253_64be_0_w );
-WRITE64_HANDLER ( pit8253_64be_1_w );
+WRITE8_DEVICE_HANDLER( pit8253_gate_w );
-WRITE8_HANDLER ( pit8253_0_gate_w );
-WRITE8_HANDLER ( pit8253_1_gate_w );
-int pit8253_get_frequency(int which, int timer);
-int pit8253_get_output(int which, int timer);
-void pit8253_set_clockin(int which, int timer, double new_clockin);
+int pit8253_get_frequency(const device_config *device, int timer);
+int pit8253_get_output(const device_config *device, int timer);
+void pit8253_set_clockin(const device_config *device, int timer, double new_clockin);
-#endif /* PIT8253_H */
+#endif /* __PIT8253_H_ */
diff --git a/src/mame/audio/tx1.c b/src/mame/audio/tx1.c
index 83f1889c032..ae008576021 100644
--- a/src/mame/audio/tx1.c
+++ b/src/mame/audio/tx1.c
@@ -43,7 +43,7 @@ static struct
} pit8253;
-WRITE8_HANDLER( pit8253_w )
+WRITE8_HANDLER( tx1_pit8253_w )
{
stream_update(stream);
@@ -75,7 +75,7 @@ WRITE8_HANDLER( pit8253_w )
}
}
-READ8_HANDLER( pit8253_r )
+READ8_HANDLER( tx1_pit8253_r )
{
mame_printf_debug("PIT R: %x", offset);
return 0;
diff --git a/src/mame/drivers/filetto.c b/src/mame/drivers/filetto.c
index 91ff270e2cc..46aeee10951 100644
--- a/src/mame/drivers/filetto.c
+++ b/src/mame/drivers/filetto.c
@@ -384,7 +384,7 @@ static READ8_HANDLER( kludge_r )
return mame_rand(Machine);
}
-static void pc_timer0_w(int state)
+static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
{
//if (state)
// pic8259_0_issue_irq(0);
@@ -392,7 +392,6 @@ static void pc_timer0_w(int state)
static const struct pit8253_config pc_pit8253_config =
{
- TYPE8253,
{
{
4772720/4, /* heartbeat IRQ */
@@ -405,7 +404,7 @@ static const struct pit8253_config pc_pit8253_config =
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
NULL,
- NULL//pc_sh_speaker_change_clock
+ NULL
}
}
};
@@ -654,7 +653,6 @@ GFXDECODE_END
static MACHINE_RESET(filetto)
{
ppi8255_init(&filetto_ppi8255_intf);
- pit8253_init(1, &pc_pit8253_config);
}
/*
@@ -739,6 +737,9 @@ static MACHINE_DRIVER_START( filetto )
MDRV_CPU_IO_MAP(filetto_io,0)
MDRV_CPU_VBLANK_INT_HACK(filetto_irq,200)
+ MDRV_DEVICE_ADD( "pit8253", PIT8253 )
+ MDRV_DEVICE_CONFIG( pc_pit8253_config )
+
MDRV_GFXDECODE(filetto)
MDRV_SCREEN_ADD("main", RASTER)
diff --git a/src/mame/drivers/gamecstl.c b/src/mame/drivers/gamecstl.c
index 7453fe8f969..37da6f30db7 100644
--- a/src/mame/drivers/gamecstl.c
+++ b/src/mame/drivers/gamecstl.c
@@ -40,6 +40,7 @@
#include "driver.h"
#include "memconv.h"
+#include "devconv.h"
#include "deprecat.h"
#include "machine/8237dma.h"
#include "machine/pic8259.h"
@@ -332,6 +333,10 @@ static WRITE32_HANDLER(bios_ram_w)
}
}
+
+DEV_READWRITE8TO32LE( gamecstl_pit8254_32le, pit8253_r, pit8253_w )
+
+
/*****************************************************************************/
static ADDRESS_MAP_START( gamecstl_map, ADDRESS_SPACE_PROGRAM, 32 )
@@ -348,7 +353,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(gamecstl_io, ADDRESS_SPACE_IO, 32)
AM_RANGE(0x0000, 0x001f) AM_READWRITE(dma8237_32le_0_r, dma8237_32le_0_w)
AM_RANGE(0x0020, 0x003f) AM_READWRITE(pic8259_32le_0_r, pic8259_32le_0_w)
- AM_RANGE(0x0040, 0x005f) AM_READWRITE(pit8253_32le_0_r, pit8253_32le_0_w)
+ AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE(PIT8254, "pit8254", gamecstl_pit8254_32le_r, gamecstl_pit8254_32le_w)
AM_RANGE(0x0060, 0x006f) AM_READWRITE(kbdc8042_32le_r, kbdc8042_32le_w)
AM_RANGE(0x0070, 0x007f) AM_READWRITE(mc146818_port32le_r, mc146818_port32le_w)
AM_RANGE(0x0080, 0x009f) AM_READWRITE(at_page32_r, at_page32_w)
@@ -441,6 +446,30 @@ static MACHINE_RESET(gamecstl)
cpunum_set_irq_callback(0, irq_callback);
}
+static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
+{
+ pic8259_set_irq_line(0, 0, state);
+}
+
+static const struct pit8253_config gamecstl_pit8254_config =
+{
+ {
+ {
+ 4772720/4, /* heartbeat IRQ */
+ pc_timer0_w,
+ NULL
+ }, {
+ 4772720/4, /* dram refresh */
+ NULL,
+ NULL
+ }, {
+ 4772720/4, /* pio port c pin 4, and speaker polling enough */
+ NULL,
+ NULL
+ }
+ }
+};
+
static MACHINE_DRIVER_START(gamecstl)
/* basic machine hardware */
@@ -450,6 +479,9 @@ static MACHINE_DRIVER_START(gamecstl)
MDRV_MACHINE_RESET(gamecstl)
+ MDRV_DEVICE_ADD( "pit8254", PIT8254 )
+ MDRV_DEVICE_CONFIG( gamecstl_pit8254_config )
+
MDRV_NVRAM_HANDLER( mc146818 )
/* video hardware */
@@ -509,7 +541,7 @@ static DRIVER_INIT( gamecstl )
{
bios_ram = auto_malloc(0x10000);
- init_pc_common(PCCOMMON_KEYBOARD_AT | PCCOMMON_DMA8237_AT | PCCOMMON_TIMER_8254);
+ init_pc_common(PCCOMMON_KEYBOARD_AT | PCCOMMON_DMA8237_AT);
mc146818_init(MC146818_STANDARD);
intel82439tx_init();
diff --git a/src/mame/drivers/mediagx.c b/src/mame/drivers/mediagx.c
index 8b42f45dd68..cf234b58788 100644
--- a/src/mame/drivers/mediagx.c
+++ b/src/mame/drivers/mediagx.c
@@ -66,6 +66,7 @@
#include "driver.h"
#include "deprecat.h"
#include "memconv.h"
+#include "devconv.h"
#include "machine/8237dma.h"
#include "machine/pic8259.h"
#include "machine/pit8253.h"
@@ -718,6 +719,9 @@ static WRITE32_HANDLER( ad1847_w )
}
}
+DEV_READWRITE8TO32LE( mediagx_pit8254_32le, pit8253_r, pit8253_w )
+
+
/*****************************************************************************/
static ADDRESS_MAP_START( mediagx_map, ADDRESS_SPACE_PROGRAM, 32 )
@@ -736,7 +740,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(mediagx_io, ADDRESS_SPACE_IO, 32)
AM_RANGE(0x0000, 0x001f) AM_READWRITE(dma8237_32le_0_r, dma8237_32le_0_w)
AM_RANGE(0x0020, 0x0023) AM_READWRITE(io20_r, io20_w)
- AM_RANGE(0x0040, 0x005f) AM_READWRITE(pit8253_32le_0_r, pit8253_32le_0_w)
+ AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE(PIT8254, "pit8254", mediagx_pit8254_32le_r, mediagx_pit8254_32le_w)
AM_RANGE(0x0060, 0x006f) AM_READWRITE(kbdc8042_32le_r, kbdc8042_32le_w)
AM_RANGE(0x0070, 0x007f) AM_READWRITE(mc146818_port32le_r, mc146818_port32le_w)
AM_RANGE(0x0080, 0x009f) AM_READWRITE(at_page32_r, at_page32_w)
@@ -860,6 +864,32 @@ static MACHINE_RESET(mediagx)
ide_controller_reset(0);
}
+static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
+{
+ pic8259_set_irq_line(0, 0, state);
+}
+
+
+static const struct pit8253_config mediagx_pit8254_config =
+{
+ {
+ {
+ 4772720/4, /* heartbeat IRQ */
+ pc_timer0_w,
+ NULL
+ }, {
+ 4772720/4, /* dram refresh */
+ NULL,
+ NULL
+ }, {
+ 4772720/4, /* pio port c pin 4, and speaker polling enough */
+ NULL,
+ NULL
+ }
+ }
+};
+
+
static MACHINE_DRIVER_START(mediagx)
/* basic machine hardware */
@@ -869,6 +899,9 @@ static MACHINE_DRIVER_START(mediagx)
MDRV_MACHINE_RESET(mediagx)
+ MDRV_DEVICE_ADD( "pit8254", PIT8254 )
+ MDRV_DEVICE_CONFIG( mediagx_pit8254_config )
+
MDRV_NVRAM_HANDLER( mc146818 )
/* video hardware */
@@ -927,7 +960,7 @@ static const struct pci_device_info cx5510 =
static void init_mediagx(running_machine *machine)
{
- init_pc_common(PCCOMMON_KEYBOARD_AT | PCCOMMON_DMA8237_AT | PCCOMMON_TIMER_8254);
+ init_pc_common(PCCOMMON_KEYBOARD_AT | PCCOMMON_DMA8237_AT);
mc146818_init(MC146818_STANDARD);
pci_init();
diff --git a/src/mame/drivers/taitowlf.c b/src/mame/drivers/taitowlf.c
index 6171c658a75..a012daa9bd9 100644
--- a/src/mame/drivers/taitowlf.c
+++ b/src/mame/drivers/taitowlf.c
@@ -5,6 +5,7 @@
#include "driver.h"
#include "memconv.h"
+#include "devconv.h"
#include "deprecat.h"
#include "machine/8237dma.h"
#include "machine/pic8259.h"
@@ -298,6 +299,10 @@ static WRITE32_HANDLER(bios_ram_w)
}
}
+
+DEV_READWRITE8TO32LE( taitowlf_pit8254_32le, pit8253_r, pit8253_w )
+
+
/*****************************************************************************/
static ADDRESS_MAP_START( taitowlf_map, ADDRESS_SPACE_PROGRAM, 32 )
@@ -314,7 +319,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(taitowlf_io, ADDRESS_SPACE_IO, 32)
AM_RANGE(0x0000, 0x001f) AM_READWRITE(dma8237_32le_0_r, dma8237_32le_0_w)
AM_RANGE(0x0020, 0x003f) AM_READWRITE(pic8259_32le_0_r, pic8259_32le_0_w)
- AM_RANGE(0x0040, 0x005f) AM_READWRITE(pit8253_32le_0_r, pit8253_32le_0_w)
+ AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE(PIT8254, "pit8254", taitowlf_pit8254_32le_r, taitowlf_pit8254_32le_w)
AM_RANGE(0x0060, 0x006f) AM_READWRITE(kbdc8042_32le_r, kbdc8042_32le_w)
AM_RANGE(0x0070, 0x007f) AM_READWRITE(mc146818_port32le_r, mc146818_port32le_w)
AM_RANGE(0x0080, 0x009f) AM_READWRITE(at_page32_r, at_page32_w)
@@ -407,6 +412,30 @@ static MACHINE_RESET(taitowlf)
cpunum_set_irq_callback(0, irq_callback);
}
+static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
+{
+ pic8259_set_irq_line(0, 0, state);
+}
+
+static const struct pit8253_config taitowlf_pit8254_config =
+{
+ {
+ {
+ 4772720/4, /* heartbeat IRQ */
+ pc_timer0_w,
+ NULL
+ }, {
+ 4772720/4, /* dram refresh */
+ NULL,
+ NULL
+ }, {
+ 4772720/4, /* pio port c pin 4, and speaker polling enough */
+ NULL,
+ NULL
+ }
+ }
+};
+
static MACHINE_DRIVER_START(taitowlf)
/* basic machine hardware */
@@ -416,6 +445,9 @@ static MACHINE_DRIVER_START(taitowlf)
MDRV_MACHINE_RESET(taitowlf)
+ MDRV_DEVICE_ADD( "pit8254", PIT8254 )
+ MDRV_DEVICE_CONFIG( taitowlf_pit8254_config )
+
MDRV_NVRAM_HANDLER( mc146818 )
/* video hardware */
@@ -475,7 +507,7 @@ static DRIVER_INIT( taitowlf )
{
bios_ram = auto_malloc(0x10000);
- init_pc_common(PCCOMMON_KEYBOARD_AT | PCCOMMON_DMA8237_AT | PCCOMMON_TIMER_8254);
+ init_pc_common(PCCOMMON_KEYBOARD_AT | PCCOMMON_DMA8237_AT);
mc146818_init(MC146818_STANDARD);
intel82439tx_init();
diff --git a/src/mame/drivers/tx1.c b/src/mame/drivers/tx1.c
index 3212d45ee86..fb1c44cf91f 100644
--- a/src/mame/drivers/tx1.c
+++ b/src/mame/drivers/tx1.c
@@ -467,7 +467,7 @@ static ADDRESS_MAP_START( tx1_sound_prg, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x3000, 0x37ff) AM_RAM AM_MIRROR(0x800) AM_BASE(&z80_ram)
AM_RANGE(0x4000, 0x4000) AM_WRITE(z80_intreq_w)
AM_RANGE(0x5000, 0x5003) AM_READWRITE(ppi8255_0_r, ppi8255_0_w)
- AM_RANGE(0x6000, 0x6003) AM_READWRITE(pit8253_r, pit8253_w)
+ AM_RANGE(0x6000, 0x6003) AM_READWRITE(tx1_pit8253_r, tx1_pit8253_w)
AM_RANGE(0x7000, 0x7fff) AM_WRITE(tx1_ppi_latch_w)
AM_RANGE(0xb000, 0xbfff) AM_READWRITE(ts_r, ts_w)
ADDRESS_MAP_END
@@ -570,7 +570,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( buggybjr_sound_prg, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x3fff) AM_ROM
AM_RANGE(0x4000, 0x47ff) AM_RAM AM_BASE(&z80_ram)
- AM_RANGE(0x5000, 0x5003) AM_READWRITE(pit8253_r, pit8253_w)
+ AM_RANGE(0x5000, 0x5003) AM_READWRITE(tx1_pit8253_r, tx1_pit8253_w)
AM_RANGE(0x6000, 0x6001) AM_READ(bbjr_analog_r)
AM_RANGE(0x7000, 0x7000) AM_WRITE(z80_intreq_w)
AM_RANGE(0xc000, 0xc7ff) AM_READWRITE(ts_r, ts_w)
diff --git a/src/mame/drivers/vertigo.c b/src/mame/drivers/vertigo.c
index 89eb7e21226..9ffb9097c8e 100644
--- a/src/mame/drivers/vertigo.c
+++ b/src/mame/drivers/vertigo.c
@@ -23,6 +23,9 @@
*
*************************************/
+static READ16_DEVICE_HANDLER( vertigo_pit8254_lsb_r ) { return pit8253_r( device, offset ); }
+static WRITE16_DEVICE_HANDLER( vertigo_pit8254_lsb_w ) { if (ACCESSING_BYTE_0) pit8253_w(device, offset, data); }
+
static ADDRESS_MAP_START( vertigo_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x000007) AM_ROM
AM_RANGE(0x000008, 0x001fff) AM_RAM AM_MIRROR(0x010000)
@@ -35,7 +38,7 @@ static ADDRESS_MAP_START( vertigo_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x004050, 0x00405f) AM_READWRITE(SMH_RAM, vertigo_audio_w) AM_MIRROR(0x001000)
AM_RANGE(0x004060, 0x00406f) AM_WRITE(vertigo_motor_w) AM_MIRROR(0x001000)
AM_RANGE(0x004070, 0x00407f) AM_WRITE(vertigo_wsot_w) AM_MIRROR(0x001000)
- AM_RANGE(0x006000, 0x006007) AM_READWRITE(pit8253_0_lsb_r, pit8253_0_lsb_w)
+ AM_RANGE(0x006000, 0x006007) AM_DEVREADWRITE(PIT8254, "pit8254", vertigo_pit8254_lsb_r, vertigo_pit8254_lsb_w)
AM_RANGE(0x007000, 0x0073ff) AM_RAM AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size)
AM_RANGE(0x800000, 0x81ffff) AM_ROM
ADDRESS_MAP_END
@@ -108,6 +111,9 @@ static MACHINE_DRIVER_START( vertigo )
MDRV_IMPORT_FROM(exidy440_audio)
+ MDRV_DEVICE_ADD( "pit8254", PIT8254 )
+ MDRV_DEVICE_CONFIG( vertigo_pit8254_config )
+
/* motor controller */
/*
MDRV_CPU_ADD(M6805, 1000000)
diff --git a/src/mame/includes/tx1.h b/src/mame/includes/tx1.h
index 01517ba8dff..41153970351 100644
--- a/src/mame/includes/tx1.h
+++ b/src/mame/includes/tx1.h
@@ -53,8 +53,8 @@ MACHINE_START( buggybjr );
MACHINE_START( buggyboy );
/*----------- defined in audio/tx1.c -----------*/
-READ8_HANDLER( pit8253_r );
-WRITE8_HANDLER( pit8253_w );
+READ8_HANDLER( tx1_pit8253_r );
+WRITE8_HANDLER( tx1_pit8253_w );
WRITE8_HANDLER( bb_ym1_a_w );
WRITE8_HANDLER( bb_ym1_b_w );
diff --git a/src/mame/includes/vertigo.h b/src/mame/includes/vertigo.h
index 50c0cbc9a01..607b1a722c7 100644
--- a/src/mame/includes/vertigo.h
+++ b/src/mame/includes/vertigo.h
@@ -6,6 +6,8 @@
/*----------- defined in machine/vertigo.c -----------*/
+extern const struct pit8253_config vertigo_pit8254_config;
+
READ16_HANDLER( vertigo_io_convert );
READ16_HANDLER( vertigo_io_adc );
READ16_HANDLER( vertigo_coin_r );
diff --git a/src/mame/machine/pcshare.c b/src/mame/machine/pcshare.c
index 0fca92be613..cdf040ffac2 100644
--- a/src/mame/machine/pcshare.c
+++ b/src/mame/machine/pcshare.c
@@ -36,7 +36,6 @@
#ifdef MESS
#include "machine/pc_fdc.h"
#include "machine/pc_hdc.h"
-#include "audio/pc.h"
#endif /* MESS */
#define VERBOSE_DBG 0 /* general debug messages */
@@ -55,67 +54,6 @@ static TIMER_CALLBACK( pc_keyb_timer );
#define LOG_PORT80 0
-static void pc_timer0_w(int state)
-{
- pic8259_set_irq_line(0, 0, state);
-}
-
-
-/*
- * timer0 heartbeat IRQ
- * timer1 DRAM refresh (ignored)
- * timer2 PIO port C pin 4 and speaker polling
- */
-static const struct pit8253_config pc_pit8253_config =
-{
- TYPE8253,
- {
- {
- 4772720/4, /* heartbeat IRQ */
- pc_timer0_w,
- NULL
- }, {
- 4772720/4, /* dram refresh */
- NULL,
- NULL
- }, {
- 4772720/4, /* pio port c pin 4, and speaker polling enough */
- NULL,
-#ifdef MESS
- pc_sh_speaker_change_clock
-#else
- NULL //pc_sh_speaker_change_clock
-#endif /* MESS */
- }
- }
-};
-
-static const struct pit8253_config pc_pit8254_config =
-{
- TYPE8254,
- {
- {
- 4772720/4, /* heartbeat IRQ */
- pc_timer0_w,
- NULL
- }, {
- 4772720/4, /* dram refresh */
- NULL,
- NULL
- }, {
- 4772720/4, /* pio port c pin 4, and speaker polling enough */
- NULL,
-#ifdef MESS
- pc_sh_speaker_change_clock
-#else
- NULL //pc_sh_speaker_change_clock
-#endif /* MESS */
- }
- }
-};
-
-
-
/*************************************************************************
*
* PC DMA stuff
@@ -289,12 +227,6 @@ static void pc_pic_set_int_line(int which, int interrupt)
void init_pc_common(UINT32 flags)
{
- /* PIT */
- if (flags & PCCOMMON_TIMER_8254)
- pit8253_init(1, &pc_pit8254_config);
- else if (flags & PCCOMMON_TIMER_8253)
- pit8253_init(1, &pc_pit8253_config);
-
/* PC-XT keyboard */
if (flags & PCCOMMON_KEYBOARD_AT)
at_keyboard_init(AT_KEYBOARD_TYPE_AT);
diff --git a/src/mame/machine/pcshare.h b/src/mame/machine/pcshare.h
index e97c9cdb7d3..5f8f81ad0a7 100644
--- a/src/mame/machine/pcshare.h
+++ b/src/mame/machine/pcshare.h
@@ -5,9 +5,6 @@
#define PCCOMMON_KEYBOARD_AT 1
#define PCCOMMON_DMA8237_PC 0
#define PCCOMMON_DMA8237_AT 2
-#define PCCOMMON_TIMER_NONE 0
-#define PCCOMMON_TIMER_8253 4
-#define PCCOMMON_TIMER_8254 8
#define PCCOMMON_NEC765_RDY_NC 16
void init_pc_common(UINT32 flags);
diff --git a/src/mame/machine/vertigo.c b/src/mame/machine/vertigo.c
index 15fface8b46..a387eb8139f 100644
--- a/src/mame/machine/vertigo.c
+++ b/src/mame/machine/vertigo.c
@@ -19,8 +19,8 @@
*
*************************************/
-static void v_irq4_w(int level);
-static void v_irq3_w(int level);
+static PIT8253_OUTPUT_CHANGED( v_irq4_w );
+static PIT8253_OUTPUT_CHANGED( v_irq3_w );
static void update_irq(void);
@@ -43,9 +43,8 @@ static UINT8 irq_state;
static UINT8 adc_result;
/* 8254 timer config */
-static const struct pit8253_config pit8254_config =
+const struct pit8253_config vertigo_pit8254_config =
{
- TYPE8254,
{
{
240000,
@@ -98,20 +97,20 @@ static void update_irq_encoder(int line, int state)
}
-static void v_irq4_w(int level)
+static PIT8253_OUTPUT_CHANGED( v_irq4_w )
{
- update_irq_encoder(INPUT_LINE_IRQ4, level);
- vertigo_vproc(ATTOTIME_TO_CYCLES(0, attotime_sub(timer_get_time(), irq4_time)), level);
+ update_irq_encoder(INPUT_LINE_IRQ4, state);
+ vertigo_vproc(ATTOTIME_TO_CYCLES(0, attotime_sub(timer_get_time(), irq4_time)), state);
irq4_time = timer_get_time();
}
-static void v_irq3_w(int level)
+static PIT8253_OUTPUT_CHANGED( v_irq3_w )
{
- if (level)
+ if (state)
cpunum_set_input_line(Machine, 1, INPUT_LINE_IRQ0, ASSERT_LINE);
- update_irq_encoder(INPUT_LINE_IRQ3, level);
+ update_irq_encoder(INPUT_LINE_IRQ3, state);
}
@@ -221,7 +220,6 @@ MACHINE_RESET( vertigo )
TTL74148_input_line_w(0, i, 1);
TTL74148_update(0);
- pit8253_init(1, &pit8254_config);
vertigo_vproc_init();
irq4_time = timer_get_time();