summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/machine')
-rw-r--r--src/emu/machine/64h156.c778
-rw-r--r--src/emu/machine/64h156.h210
-rw-r--r--src/emu/machine/machine.mak36
-rw-r--r--src/emu/machine/mos6702.c71
-rw-r--r--src/emu/machine/mos6702.h69
-rw-r--r--src/emu/machine/mos8706.c81
-rw-r--r--src/emu/machine/mos8706.h73
-rw-r--r--src/emu/machine/mos8722.c429
-rw-r--r--src/emu/machine/mos8722.h119
9 files changed, 1866 insertions, 0 deletions
diff --git a/src/emu/machine/64h156.c b/src/emu/machine/64h156.c
new file mode 100644
index 00000000000..8a32a9cca29
--- /dev/null
+++ b/src/emu/machine/64h156.c
@@ -0,0 +1,778 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore 64H156 Gate Array emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ http://staff.washington.edu/rrcc/uwweb/1541early/1540-2.GIF
+
+ - model disk rotation for proper track alignment
+ - write circuitry
+ - cycle exact M6502
+ - cycle exact VIA
+ - refactor to use modern floppy system
+
+ - get these running and we're golden
+ - Quiwi (speed change within track)
+ - Defender of the Crown (V-MAX! v2, density checks)
+ - Test Drive / Cabal (HLS, sub-cycle jitter)
+ - Galaxian (?, needs 100% accurate VIA)
+
+*/
+
+#include "emu.h"
+#include "64h156.h"
+#include "formats/g64_dsk.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+#define ATN (m_atni ^ m_atna)
+
+#define CYCLES_UNTIL_ANALOG_DESYNC 288 // 18 us
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type C64H156 = &device_creator<c64h156_device>;
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void c64h156_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const c64h156_interface *intf = reinterpret_cast<const c64h156_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<c64h156_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_atn_cb, 0, sizeof(m_out_atn_cb));
+ memset(&m_out_sync_cb, 0, sizeof(m_out_sync_cb));
+ memset(&m_out_byte_cb, 0, sizeof(m_out_byte_cb));
+ }
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_atn_line -
+//-------------------------------------------------
+
+inline void c64h156_device::set_atn_line()
+{
+ m_out_atn_func(ATN);
+}
+
+
+//-------------------------------------------------
+// read_current_track -
+//-------------------------------------------------
+
+inline void c64h156_device::read_current_track()
+{
+ int track_length = G64_BUFFER_SIZE;
+
+ // read track data
+ floppy_drive_read_track_data_info_buffer(m_floppy, m_side, m_track_buffer, &track_length);
+
+ // extract track length
+ m_track_len = floppy_drive_get_current_track_size(m_floppy, m_side);
+
+ // set bit pointer to track start
+ m_buffer_pos = 0;
+ m_bit_pos = 7;
+ m_bit_count = 0;
+ m_zero_count = 0;
+
+ if (m_track_len)
+ {
+ memcpy(m_speed_buffer, m_track_buffer + m_track_len, G64_SPEED_BLOCK_SIZE);
+
+ update_cycles_until_next_bit();
+ }
+}
+
+
+//-------------------------------------------------
+// update_cycles_until_next_bit -
+//-------------------------------------------------
+
+inline void c64h156_device::update_cycles_until_next_bit()
+{
+ int speed_offset = m_buffer_pos / 4;
+ int speed_shift = (3 - (m_buffer_pos % 4)) * 2;
+
+ UINT8 speed = m_speed_buffer[speed_offset];
+
+ int ds = (speed >> speed_shift) & 0x03;
+
+ m_cycles_until_next_bit = (16 - ds) * 4;
+
+ if (LOG) logerror("buff %04x:%u speed %04x shift %u ds %u cycles %u\n", m_buffer_pos, m_bit_pos, speed_offset, speed_shift, ds, m_cycles_until_next_bit);
+}
+
+
+//-------------------------------------------------
+// receive_bit - receive bit
+//-------------------------------------------------
+
+inline void c64h156_device::receive_bit()
+{
+ if (!m_track_len)
+ {
+ m_bit_sync = 0;
+ }
+ else
+ {
+ if (m_cycles_until_next_bit == 0)
+ {
+ m_bit_sync = BIT(m_track_buffer[m_buffer_pos], m_bit_pos);
+
+ if (m_bit_sync)
+ {
+ m_zero_count = 0;
+ m_cycles_until_random_flux = (rand() % 31) + 289;
+ }
+ else
+ {
+ m_zero_count++;
+ }
+
+ if (m_zero_count >= m_cycles_until_random_flux)
+ {
+ // receive phantom bit
+ if (LOG) logerror("PHANTOM BIT SYNC 1 after %u cycles\n", m_zero_count);
+
+ m_bit_sync = 1;
+
+ m_zero_count = 0;
+ m_cycles_until_random_flux = (rand() % 367) + 33;
+ }
+ else
+ {
+ if (LOG) logerror("BIT SYNC %u\n", m_bit_sync);
+ }
+
+ m_shift <<= 1;
+ m_shift |= m_bit_sync;
+
+ m_bit_pos--;
+ m_bit_count++;
+
+ if (m_bit_pos < 0)
+ {
+ m_bit_pos = 7;
+ m_buffer_pos++;
+
+ if (m_buffer_pos >= m_track_len)
+ {
+ // loop to the start of the track
+ m_buffer_pos = 0;
+ }
+ }
+
+ update_cycles_until_next_bit();
+ }
+
+ m_cycles_until_next_bit--;
+ }
+}
+
+
+//-------------------------------------------------
+// decode_bit -
+//-------------------------------------------------
+
+inline void c64h156_device::decode_bit()
+{
+ // UE7
+
+ bool ue7_tc = false;
+
+ if (!m_last_bit_sync && m_bit_sync)
+ {
+ m_ue7 = m_ds;
+ }
+ else
+ {
+ m_ue7++;
+
+ if (m_ue7 == 16)
+ {
+ m_ue7 = m_ds;
+ ue7_tc = true;
+ }
+ }
+
+ if (LOG) logerror("UE7 CTR %01x TC %u, ", m_ue7, ue7_tc);
+
+ // UF4
+
+ if (!m_last_bit_sync && m_bit_sync)
+ {
+ m_uf4 = 0;
+
+ if (LOG) logerror("--");
+ }
+ else
+ {
+ if (!m_ue7_tc && ue7_tc)
+ {
+ m_uf4++;
+ m_uf4 &= 0x0f;
+
+ if (LOG) logerror("++");
+ }
+ else
+ {
+ if (LOG) logerror(" ");
+ }
+ }
+
+ m_last_bit_sync = m_bit_sync;
+ m_ue7_tc = ue7_tc;
+
+ int uf4_qa = BIT(m_uf4, 0);
+ int uf4_qb = BIT(m_uf4, 1);
+ int uf4_qc = BIT(m_uf4, 2);
+ int uf4_qd = BIT(m_uf4, 3);
+
+ int ue5a = !(uf4_qc || uf4_qd);
+
+ if (LOG) logerror("UF4 CTR %01x %u%u%u%u UE5A %u, ", m_uf4, uf4_qd, uf4_qc, uf4_qb, uf4_qa, ue5a);
+
+ if (!m_uf4_qb && uf4_qb)
+ {
+ // shift bits thru flip-flops
+ m_u4b = m_u4a;
+ m_u4a = BIT(m_ud2, 7);
+
+ // shift in data bit
+ m_ud2 <<= 1;
+ m_ud2 |= ue5a;
+
+ if (LOG) logerror("<<");
+ }
+ else
+ {
+ if (LOG) logerror(" ");
+ }
+
+ if (LOG) logerror("UD2 %u%u%u%u%u%u%u%u%u%u : %02x (%02x), ", m_u4b, m_u4a, BIT(m_ud2, 7), BIT(m_ud2, 6), BIT(m_ud2, 5), BIT(m_ud2, 4), BIT(m_ud2, 3), BIT(m_ud2, 2), BIT(m_ud2, 1), BIT(m_ud2, 0), m_ud2, m_shift & 0xff);
+
+ // UE3
+
+ int block_sync = !(m_oe && (m_ud2 == 0xff) && m_u4a && m_u4b);
+
+ if (LOG) logerror("SYNC %u, ", block_sync);
+
+ if (!block_sync)
+ {
+ // load UE3
+ m_ue3 = 8; // pin D is floating and TTL inputs float high
+
+ if (LOG) logerror("--");
+ }
+ else
+ {
+ if (m_block_sync && !m_uf4_qb && uf4_qb)
+ {
+ // clock UE3
+ m_ue3++;
+
+ if (m_ue3 == 16)
+ {
+ m_ue3 = 0;
+ }
+
+ if (LOG) logerror("++");
+ }
+ else
+ {
+ if (LOG) logerror(" ");
+ }
+ }
+
+ int ue3_qa = BIT(m_ue3, 0);
+ int ue3_qb = BIT(m_ue3, 1);
+ int ue3_qc = BIT(m_ue3, 2);
+
+ int uf3a = !(ue3_qa && ue3_qb && ue3_qc);
+ int uc1b = !uf3a; // schmitt trigger
+
+ if (LOG) logerror("UE3 CTR %01x UF3A %u UC1B %u, ", m_ue3, uf3a, uc1b);
+
+ int byte_sync = !(uc1b && m_soe && !uf4_qb);
+
+ if (LOG) logerror("BYTE %u SOE %u\n", byte_sync, m_soe);
+
+ // UD3
+
+ int uf3b = !(uc1b && uf4_qa && uf4_qb);
+
+ if (!uf3b)
+ {
+ m_ud3 = m_via_pa;
+ }
+ else if (!m_uf4_qb && uf4_qb)
+ {
+ // shift out bits
+ int ud3_qh = BIT(m_ud3, 0);
+ m_ud3 >>= 1;
+
+ int uf5b = !(!uf4_qb && ud3_qh);
+
+ if (!m_oe && m_wp)
+ {
+ // TODO write bit to disk
+ if (LOG) logerror("WRITE BIT %u\n", uf5b);
+ }
+ }
+
+ // prepare for next cycle
+
+ if (m_block_sync != block_sync)
+ {
+ m_block_sync = block_sync;
+ m_out_sync_func(m_block_sync);
+ }
+
+ if (m_byte_sync != byte_sync)
+ {
+ m_byte_sync = byte_sync;
+
+ if (m_accl)
+ {
+ if (!byte_sync)
+ {
+ m_accl_yb = m_ud2;
+ m_accl_byte_sync = byte_sync;
+ m_out_byte_func(m_accl_byte_sync);
+ }
+ }
+ else
+ {
+ m_out_byte_func(m_byte_sync);
+ }
+ }
+
+ m_uf4_qb = uf4_qb;
+
+ m_bit_sync = 0;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// c64h156_device - constructor
+//-------------------------------------------------
+
+c64h156_device::c64h156_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, C64H156, "64H156", tag, owner, clock, "c64h156", __FILE__),
+ device_execute_interface(mconfig, *this),
+ m_icount(0),
+ m_floppy(NULL),
+ m_track_buffer(*this, "track_buffer"),
+ m_speed_buffer(*this, "speed_buffer"),
+ m_side(0),
+ m_track_len(0),
+ m_buffer_pos(0),
+ m_bit_pos(0),
+ m_bit_count(0),
+ m_mtr(0),
+ m_accl(0),
+ m_ds(0),
+ m_soe(0),
+ m_oe(0),
+ m_atni(1),
+ m_atna(1),
+ m_last_bit_sync(0),
+ m_bit_sync(0),
+ m_byte_sync(1),
+ m_accl_byte_sync(1),
+ m_block_sync(1),
+ m_ue7(0),
+ m_ue7_tc(0),
+ m_uf4(0),
+ m_uf4_qb(0),
+ m_ud2(0),
+ m_accl_yb(0),
+ m_u4a(0),
+ m_u4b(0),
+ m_ue3(0),
+ m_uc1b(0),
+ m_wp(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void c64h156_device::device_start()
+{
+ // set our instruction counter
+ m_icountptr = &m_icount;
+
+ // allocate track buffer
+ m_track_buffer.allocate(G64_BUFFER_SIZE);
+ m_speed_buffer.allocate(G64_SPEED_BLOCK_SIZE);
+
+ // resolve callbacks
+ m_out_atn_func.resolve(m_out_atn_cb, *this);
+ m_out_sync_func.resolve(m_out_sync_cb, *this);
+ m_out_byte_func.resolve(m_out_byte_cb, *this);
+
+ // register for state saving
+ save_item(NAME(m_shift));
+ save_item(NAME(m_side));
+ save_item(NAME(m_track_len));
+ save_item(NAME(m_buffer_pos));
+ save_item(NAME(m_bit_pos));
+ save_item(NAME(m_bit_count));
+ save_item(NAME(m_cycles_until_next_bit));
+ save_item(NAME(m_zero_count));
+ save_item(NAME(m_cycles_until_random_flux));
+ save_item(NAME(m_mtr));
+ save_item(NAME(m_accl));
+ save_item(NAME(m_ds));
+ save_item(NAME(m_soe));
+ save_item(NAME(m_oe));
+ save_item(NAME(m_atni));
+ save_item(NAME(m_atna));
+ save_item(NAME(m_last_bit_sync));
+ save_item(NAME(m_bit_sync));
+ save_item(NAME(m_byte_sync));
+ save_item(NAME(m_accl_byte_sync));
+ save_item(NAME(m_block_sync));
+ save_item(NAME(m_ue7));
+ save_item(NAME(m_ue7_tc));
+ save_item(NAME(m_uf4));
+ save_item(NAME(m_uf4_qb));
+ save_item(NAME(m_ud2));
+ save_item(NAME(m_accl_yb));
+ save_item(NAME(m_u4a));
+ save_item(NAME(m_u4b));
+ save_item(NAME(m_ue3));
+ save_item(NAME(m_uc1b));
+ save_item(NAME(m_via_pa));
+ save_item(NAME(m_ud3));
+ save_item(NAME(m_wp));
+}
+
+
+//-------------------------------------------------
+// execute_run -
+//-------------------------------------------------
+
+void c64h156_device::execute_run()
+{
+ do
+ {
+ if (m_mtr)
+ {
+ receive_bit();
+ }
+
+ decode_bit();
+
+ m_icount--;
+ } while (m_icount > 0);
+}
+
+
+//-------------------------------------------------
+// yb_r -
+//-------------------------------------------------
+
+READ8_MEMBER( c64h156_device::yb_r )
+{
+ UINT8 data = 0;
+
+ if (m_soe)
+ {
+ if (m_accl)
+ {
+ data = m_accl_yb;
+ }
+ else
+ {
+ data = m_ud2;
+ }
+ }
+
+ if (LOG) logerror("%s YB read %02x:%02x\n", machine().describe_context(), m_ud2, data);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// yb_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( c64h156_device::yb_w )
+{
+ m_via_pa = data;
+}
+
+
+//-------------------------------------------------
+// test_w - test write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::test_w )
+{
+}
+
+
+//-------------------------------------------------
+// accl_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::accl_w )
+{
+ m_accl = state;
+}
+
+
+//-------------------------------------------------
+// sync_r - sync read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( c64h156_device::sync_r )
+{
+ return m_block_sync;
+}
+
+
+//-------------------------------------------------
+// byte_r - byte ready read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( c64h156_device::byte_r )
+{
+ int state = 1;
+
+ if (m_accl)
+ {
+ state = m_accl_byte_sync;
+ }
+ else
+ {
+ state = m_byte_sync;
+ }
+
+ return state;
+}
+
+
+//-------------------------------------------------
+// ted_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::ted_w )
+{
+ if (m_accl && !m_accl_byte_sync && !state)
+ {
+ m_accl_byte_sync = 1;
+ m_out_byte_func(m_accl_byte_sync);
+ }
+}
+
+
+//-------------------------------------------------
+// mtr_w - motor write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::mtr_w )
+{
+ if (m_mtr != state)
+ {
+ if (LOG) logerror("MTR %u\n", state);
+
+ if (state)
+ {
+ // read track data
+ read_current_track();
+ }
+
+ floppy_mon_w(m_floppy, !state);
+
+ m_mtr = state;
+ }
+}
+
+
+//-------------------------------------------------
+// oe_w - output enable write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::oe_w )
+{
+ if (LOG) logerror("OE %u\n", state);
+
+ m_oe = state;
+}
+
+
+//-------------------------------------------------
+// soe_w - SO enable write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::soe_w )
+{
+ if (LOG) logerror("SOE %u\n", state);
+
+ m_soe = state;
+}
+
+
+//-------------------------------------------------
+// atn_r - serial attention read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( c64h156_device::atn_r )
+{
+ return ATN;
+}
+
+
+//-------------------------------------------------
+// atni_w - serial attention input write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::atni_w )
+{
+ if (LOG) logerror("ATNI %u\n", state);
+
+ m_atni = state;
+
+ set_atn_line();
+}
+
+
+//-------------------------------------------------
+// atna_w - serial attention acknowledge write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::atna_w )
+{
+ if (LOG) logerror("ATNA %u\n", state);
+
+ m_atna = state;
+
+ set_atn_line();
+}
+
+
+//-------------------------------------------------
+// set_floppy -
+//-------------------------------------------------
+
+void c64h156_device::set_floppy(legacy_floppy_image_device *floppy)
+{
+ m_floppy = floppy;
+
+ // install image callbacks
+ floppy_install_unload_proc(m_floppy, c64h156_device::on_disk_change);
+ floppy_install_load_proc(m_floppy, c64h156_device::on_disk_change);
+}
+
+
+//-------------------------------------------------
+// stp_w -
+//-------------------------------------------------
+
+void c64h156_device::stp_w(int data)
+{
+ if (m_mtr)
+ {
+ int track = floppy_drive_get_current_track(m_floppy);
+ int tracks = (data - track) & 0x03;
+
+ if (tracks == 3)
+ {
+ tracks = -1;
+ }
+
+ if (tracks == -1 || tracks == 1)
+ {
+ // step read/write head
+ floppy_drive_seek(m_floppy, tracks);
+
+ // read new track data
+ read_current_track();
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// ds_w - density select
+//-------------------------------------------------
+
+void c64h156_device::ds_w(int data)
+{
+ m_ds = data;
+}
+
+
+//-------------------------------------------------
+// set_side -
+//-------------------------------------------------
+
+void c64h156_device::set_side(int side)
+{
+ if (m_side != side)
+ {
+ m_side = side;
+
+ // read new track data
+ read_current_track();
+ }
+}
+
+
+//-------------------------------------------------
+// on_disk_change -
+//-------------------------------------------------
+
+void c64h156_device::on_disk_change(device_image_interface &image)
+{
+ //m_wp = !floppy_wpt_r(image);
+
+ //read_current_track();
+}
diff --git a/src/emu/machine/64h156.h b/src/emu/machine/64h156.h
new file mode 100644
index 00000000000..bd1bd327c0c
--- /dev/null
+++ b/src/emu/machine/64h156.h
@@ -0,0 +1,210 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore 64H156 Gate Array emulation
+
+ Used in 1541B/1541C/1541-II/1551/1571
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ TEST 1 |* \_/ | 40 _BYTE
+ YB0 2 | | 39 SOE
+ YB1 3 | | 38 B
+ YB2 4 | | 37 CK
+ YB3 5 | | 36 _QX
+ YB4 6 | | 35 Q
+ YB5 7 | | 34 R/_W
+ YB6 8 | | 33 LOCK
+ YB7 9 | | 32 PLL
+ Vss 10 | 64H156-01 | 31 CLR
+ STP1 11 | 251828-01 | 30 Vcc
+ STP0 12 | | 29 _XRW
+ MTR 13 | | 28 Y3
+ _A 14 | | 27 Y2
+ DS0 15 | | 26 Y1
+ DS1 16 | | 25 Y0
+ _SYNC 17 | | 24 ATN
+ TED 18 | | 23 ATNI
+ OE 19 | | 22 ATNA
+ _ACCL 20 |_____________| 21 OSC
+
+ _____ _____
+ TEST 1 |* \_/ | 42 _BYTE
+ YB0 2 | | 41 SOE
+ YB1 3 | | 40 B
+ YB2 4 | | 39 CK
+ YB3 5 | | 38 _QX
+ YB4 6 | | 37 Q
+ YB5 7 | | 36 R/_W
+ YB6 8 | | 35 LOCK
+ YB7 9 | | 34 PLL
+ Vss 10 | 64H156-02 | 33 CLR
+ STP1 11 | 251828-02 | 32 Vcc
+ STP0 12 | | 31 _XRW
+ MTR 13 | | 30 Y3
+ _A 14 | | 29 Y2
+ DS0 15 | | 28 Y1
+ DS1 16 | | 27 Y0
+ _SYNC 17 | | 26 ATN
+ TED 18 | | 25 ATNI
+ OE 19 | | 24 ATNA
+ _ACCL 20 | | 23 OSC
+ Vcc 21 |_____________| 22 Vss
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __C64H156__
+#define __C64H156__
+
+
+#include "emu.h"
+#include "imagedev/flopdrv.h"
+#include "formats/d64_dsk.h"
+#include "formats/g64_dsk.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_64H156_ADD(_tag, _clock, _config) \
+ MCFG_DEVICE_ADD(_tag, C64H156, _clock) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define C64H156_INTERFACE(_name) \
+ const c64h156_interface (_name) =
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> c64h156_interface
+
+struct c64h156_interface
+{
+ devcb_write_line m_out_atn_cb;
+ devcb_write_line m_out_sync_cb;
+ devcb_write_line m_out_byte_cb;
+};
+
+// ======================> c64h156_device
+
+class c64h156_device : public device_t,
+ public device_execute_interface,
+ public c64h156_interface
+{
+public:
+ // construction/destruction
+ c64h156_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ8_MEMBER( yb_r );
+ DECLARE_WRITE8_MEMBER( yb_w );
+ DECLARE_WRITE_LINE_MEMBER( test_w );
+ DECLARE_WRITE_LINE_MEMBER( accl_w );
+ DECLARE_READ_LINE_MEMBER( sync_r );
+ DECLARE_READ_LINE_MEMBER( byte_r );
+ DECLARE_WRITE_LINE_MEMBER( ted_w );
+ DECLARE_WRITE_LINE_MEMBER( mtr_w );
+ DECLARE_WRITE_LINE_MEMBER( oe_w );
+ DECLARE_WRITE_LINE_MEMBER( soe_w );
+ DECLARE_READ_LINE_MEMBER( atn_r );
+ DECLARE_WRITE_LINE_MEMBER( atni_w );
+ DECLARE_WRITE_LINE_MEMBER( atna_w );
+
+ void set_floppy(legacy_floppy_image_device *floppy);
+
+ void stp_w(int data);
+ void ds_w(int data);
+ void set_side(int side);
+
+ static void on_disk_change(device_image_interface &image);
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+
+ // device_execute_interface overrides
+ virtual void execute_run();
+
+ int m_icount;
+
+ inline void set_atn_line();
+ inline void read_current_track();
+ inline void update_cycles_until_next_bit();
+ inline void receive_bit();
+ inline void decode_bit();
+
+private:
+ devcb_resolved_write_line m_out_atn_func;
+ devcb_resolved_write_line m_out_sync_func;
+ devcb_resolved_write_line m_out_byte_func;
+
+ legacy_floppy_image_device *m_floppy;
+ optional_shared_ptr<UINT8> m_track_buffer; // track data buffer
+ optional_shared_ptr<UINT8> m_speed_buffer; // speed block buffer
+
+ // track
+ UINT16 m_shift;
+ int m_side; // disk side
+ int m_track_len; // track length
+ offs_t m_buffer_pos; // current byte position within track buffer
+ int m_bit_pos; // current bit position within track buffer byte
+ int m_bit_count; // current data byte bit counter
+ int m_cycles_until_next_bit;
+ int m_zero_count;
+ int m_cycles_until_random_flux;
+
+ // motors
+ int m_mtr; // spindle motor on
+
+ // signals
+ int m_accl; // 1/2 MHz select
+ int m_ds; // density select
+ int m_soe; // serial output enable
+ int m_oe; // output enable (0 = write, 1 = read)
+
+ // IEC
+ int m_atni; // attention input
+ int m_atna; // attention acknowledge
+
+ // read logic
+ int m_last_bit_sync;
+ int m_bit_sync;
+ int m_byte_sync;
+ int m_accl_byte_sync;
+ int m_block_sync;
+ int m_ue7;
+ int m_ue7_tc;
+ int m_uf4;
+ int m_uf4_qb;
+ UINT8 m_ud2;
+ UINT8 m_accl_yb;
+ int m_u4a;
+ int m_u4b;
+ int m_ue3;
+ int m_uc1b;
+
+ // write logic
+ UINT8 m_via_pa;
+ UINT8 m_ud3;
+ int m_wp;
+};
+
+
+
+// device type definition
+extern const device_type C64H156;
+
+
+
+#endif
diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak
index 94e1ffb9fab..00ddeace905 100644
--- a/src/emu/machine/machine.mak
+++ b/src/emu/machine/machine.mak
@@ -921,6 +921,33 @@ endif
#-------------------------------------------------
#
+#@src/emu/machine/mos6702.h,MACHINES += MOS6702
+#-------------------------------------------------
+
+ifneq ($(filter MOS6702,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/mos6702.o
+endif
+
+#-------------------------------------------------
+#
+#@src/emu/machine/mos8706.h,MACHINES += MOS8706
+#-------------------------------------------------
+
+ifneq ($(filter MOS8706,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/mos8706.o
+endif
+
+#-------------------------------------------------
+#
+#@src/emu/machine/mos8722.h,MACHINES += MOS8722
+#-------------------------------------------------
+
+ifneq ($(filter MOS8722,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/mos8722.o
+endif
+
+#-------------------------------------------------
+#
#@src/emu/machine/mos8726.h,MACHINES += MOS8726
#-------------------------------------------------
@@ -1116,6 +1143,15 @@ endif
#-------------------------------------------------
#
+#@src/emu/machine/64h156.h,MACHINES += RP5C15
+#-------------------------------------------------
+
+ifneq ($(filter R64H156,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/64h156.o
+endif
+
+#-------------------------------------------------
+#
#@src/emu/machine/rtc4543.h,MACHINES += RTC4543
#-------------------------------------------------
diff --git a/src/emu/machine/mos6702.c b/src/emu/machine/mos6702.c
new file mode 100644
index 00000000000..b6e1aeb1f20
--- /dev/null
+++ b/src/emu/machine/mos6702.c
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 6702 Mystery Device emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "mos6702.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type MOS6702 = &device_creator<mos6702_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mos6702_device - constructor
+//-------------------------------------------------
+
+mos6702_device::mos6702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MOS6702, "MOS6702", tag, owner, clock, "mos6702", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mos6702_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( mos6702_device::read )
+{
+ return 0;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( mos6702_device::write )
+{
+}
diff --git a/src/emu/machine/mos6702.h b/src/emu/machine/mos6702.h
new file mode 100644
index 00000000000..879f90df2bf
--- /dev/null
+++ b/src/emu/machine/mos6702.h
@@ -0,0 +1,69 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 6702 Mystery Device emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ R/_W 1 |* \_/ | 20 Vcc
+ D7 2 | | 19 CS0
+ D6 3 | | 18 CS1
+ D5 4 | | 17 CS2
+ D4 5 | MOS6702 | 16 CS3
+ D3 6 | | 15 _CS4
+ D2 7 | | 14 _CS5
+ D1 8 | | 13 _CS5
+ D0 9 | | 12 _RTS
+ Vss 10 |_____________| 11 phi2
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __MOS6702__
+#define __MOS6702__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS6702_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD(_tag, MOS6702, _clock)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mos6702_device
+
+class mos6702_device : public device_t
+{
+public:
+ // construction/destruction
+ mos6702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+};
+
+
+// device type definition
+extern const device_type MOS6702;
+
+
+
+#endif
diff --git a/src/emu/machine/mos8706.c b/src/emu/machine/mos8706.c
new file mode 100644
index 00000000000..699aa6e7bc7
--- /dev/null
+++ b/src/emu/machine/mos8706.c
@@ -0,0 +1,81 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS 8706 Speech Glue Logic ASIC emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "mos8706.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+// device type definition
+const device_type MOS8706 = &device_creator<mos8706_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mos8706_device - constructor
+//-------------------------------------------------
+
+mos8706_device::mos8706_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MOS8706, "MOS8706", tag, owner, clock, "mos8706", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mos8706_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mos8706_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( mos8706_device::read )
+{
+ return 0;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( mos8706_device::write )
+{
+}
diff --git a/src/emu/machine/mos8706.h b/src/emu/machine/mos8706.h
new file mode 100644
index 00000000000..1138dab0f8b
--- /dev/null
+++ b/src/emu/machine/mos8706.h
@@ -0,0 +1,73 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS 8706 Speech Glue Logic ASIC emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ _RES 1 |* \_/ | 28 Vdd
+ _IRQ 2 | | 27 D0
+ R/_W 3 | | 26 T6721A D0
+ phi0 4 | | 25 D1
+ _CS 5 | | 24 T6721A D1
+ A0 6 | | 23 D2
+ A1 7 | MOS8706 | 22 T6721A D2
+ 8 | | 21 D3
+ _EOS 9 | | 20 T6721A D3
+ APD 10 | | 19 D4
+ phi2 11 | | 18 D5
+ DI 12 | | 17 D6
+ DTRD 13 | | 16 D7
+ GND 14 |_____________| 15 _WR
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __MOS8706__
+#define __MOS8706__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS8706_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD((_tag), MOS8706, _clock)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mos8706_device
+
+class mos8706_device : public device_t
+{
+public:
+ mos8706_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+};
+
+
+// device type definition
+extern const device_type MOS8706;
+
+
+
+#endif
diff --git a/src/emu/machine/mos8722.c b/src/emu/machine/mos8722.c
new file mode 100644
index 00000000000..b74f0e0815c
--- /dev/null
+++ b/src/emu/machine/mos8722.c
@@ -0,0 +1,429 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 8722 Memory Management Unit emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "mos8722.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+// registers
+enum
+{
+ CR = 0,
+ PCRA, LCRA = PCRA,
+ PCRB, LCRB = PCRB,
+ PCRC, LCRC = PCRC,
+ PCRD, LCRD = PCRD,
+ MCR,
+ RCR,
+ P0L,
+ P0H,
+ P1L,
+ P1H,
+ VR
+};
+
+
+// configuration register
+enum
+{
+ CR_IO_SYSTEM_IO = 0,
+ CR_IO_HI_ROM
+};
+
+enum
+{
+ CR_ROM_SYSTEM_ROM = 0,
+ CR_ROM_INT_FUNC_ROM,
+ CR_ROM_EXT_FUNC_ROM,
+ CR_ROM_RAM
+};
+
+#define CR_IO BIT(m_reg[CR], 0)
+#define CR_ROM_LO BIT(m_reg[CR], 1)
+#define CR_ROM_MID ((m_reg[CR] >> 2) & 0x03)
+#define CR_ROM_HI ((m_reg[CR] >> 4) & 0x03)
+#define CR_A16 BIT(m_reg[CR], 6)
+
+
+// mode configuration register
+#define MCR_8500 BIT(m_reg[MCR], 0)
+#define MCR_FSDIR BIT(m_reg[MCR], 3)
+#define MCR_GAME BIT(m_reg[MCR], 4)
+#define MCR_EXROM BIT(m_reg[MCR], 5)
+#define MCR_C64 BIT(m_reg[MCR], 6)
+#define MCR_40_80 BIT(m_reg[MCR], 7)
+
+
+// RAM configuration register
+static const offs_t RCR_BOTTOM_ADDRESS[4] = { 0x0400, 0x1000, 0x0400, 0x1000 };
+static const offs_t RCR_TOP_ADDRESS[4] = { 0xf000, 0xf000, 0xe000, 0xc000 };
+
+enum
+{
+ RCR_SHARE_1K = 0,
+ RCR_SHARE_4K,
+ RCR_SHARE_8K,
+ RCR_SHARE_16K
+};
+
+#define RCR_SHARE (m_reg[RCR] & 0x03)
+#define RCR_BOTTOM BIT(m_reg[RCR], 2)
+#define RCR_TOP BIT(m_reg[RCR], 3)
+#define RCR_VA16 BIT(m_reg[RCR], 6)
+
+
+// page 0 pointer register
+#define P0H_A16 BIT(m_reg[P0H], 0)
+
+
+// page 1 pointer register
+#define P1H_A16 BIT(m_reg[P1H], 0)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type MOS8722 = &device_creator<mos8722_device>;
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mos8722_device - constructor
+//-------------------------------------------------
+
+mos8722_device::mos8722_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MOS8722, "MOS8722", tag, owner, clock, "mos8722", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void mos8722_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const mos8722_interface *intf = reinterpret_cast<const mos8722_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<mos8722_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_z80en_cb, 0, sizeof(m_out_z80en_cb));
+ memset(&m_out_fsdir_cb, 0, sizeof(m_out_fsdir_cb));
+ memset(&m_in_game_cb, 0, sizeof(m_in_game_cb));
+ memset(&m_in_exrom_cb, 0, sizeof(m_in_exrom_cb));
+ memset(&m_in_sense40_cb, 0, sizeof(m_in_sense40_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mos8722_device::device_start()
+{
+ // resolve callbacks
+ m_out_z80en_func.resolve(m_out_z80en_cb, *this);
+ m_out_fsdir_func.resolve(m_out_fsdir_cb, *this);
+ m_in_game_func.resolve(m_in_game_cb, *this);
+ m_in_exrom_func.resolve(m_in_exrom_cb, *this);
+ m_in_sense40_func.resolve(m_in_sense40_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mos8722_device::device_reset()
+{
+ for (int i = 0; i < 16; i++)
+ {
+ m_reg[i] = 0;
+ }
+
+ m_reg[P1L] = 0x01;
+
+ m_p0h_latch = 0;
+ m_p1h_latch = 0;
+
+ m_out_z80en_func(MCR_8500);
+ m_out_fsdir_func(MCR_FSDIR);
+}
+
+
+//-------------------------------------------------
+// read - register read
+//-------------------------------------------------
+
+UINT8 mos8722_device::read(offs_t offset, UINT8 data)
+{
+ if (MCR_C64) return data;
+
+ if (!CR_IO && offset >= 0xd500 && offset < 0xd50c)
+ {
+ switch (offset & 0x0f)
+ {
+ case CR:
+ data = m_reg[CR] | 0x80;
+ break;
+
+ case MCR:
+ data = m_reg[MCR] | 0x06;
+
+ data &= ((m_in_game_func() << 4) | ~0x10);
+ data &= ((m_in_exrom_func() << 5) | ~0x20);
+ data &= ((m_in_sense40_func() << 7) | ~0x80);
+ break;
+
+ case VR:
+ data = 0x20;
+ break;
+
+ default:
+ data = m_reg[offset & 0x0f];
+ break;
+ }
+ }
+ else if (offset >= 0xff00 && offset < 0xff05)
+ {
+ switch (offset & 0x0f)
+ {
+ case CR:
+ data = m_reg[CR] | 0x80;
+ break;
+
+ default:
+ data = m_reg[offset & 0x0f];
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write - register write
+//-------------------------------------------------
+
+WRITE8_MEMBER( mos8722_device::write )
+{
+ if (MCR_C64) return;
+
+ if (!CR_IO && offset >= 0xd500 && offset < 0xd50c)
+ {
+ if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data);
+
+ switch (offset & 0x0f)
+ {
+ case CR:
+ m_reg[CR] = data & 0x7f;
+ break;
+
+ case PCRA:
+ case PCRB:
+ case PCRC:
+ case PCRD:
+ m_reg[offset & 0x0f] = data & 0x7f;
+ break;
+
+ case MCR:
+ {
+ int _8500 = MCR_8500;
+ int fsdir = MCR_FSDIR;
+
+ m_reg[MCR] = data;
+
+ if (_8500 != MCR_8500) m_out_z80en_func(MCR_8500);
+ if (fsdir != MCR_FSDIR) m_out_fsdir_func(MCR_FSDIR);
+ break;
+ }
+
+ case RCR:
+ m_reg[RCR] = data & 0x4f;
+ break;
+
+ case P0L:
+ m_reg[P0L] = data;
+ m_reg[P0H] = m_p0h_latch;
+ break;
+
+ case P0H:
+ m_p0h_latch = data & 0x01;
+ break;
+
+ case P1L:
+ m_reg[P1L] = data;
+ m_reg[P1H] = m_p1h_latch;
+ break;
+
+ case P1H:
+ m_p1h_latch = data & 0x01;
+ break;
+
+ default:
+ m_reg[offset & 0x0f] = data;
+ }
+ }
+ else if (offset >= 0xff00 && offset < 0xff05)
+ {
+ if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data);
+
+ switch (offset & 0x0f)
+ {
+ case CR:
+ m_reg[CR] = data & 0x7f;
+ break;
+
+ default:
+ m_reg[CR] = m_reg[offset & 0x0f];
+ break;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// fsdir_r - fast serial direction read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( mos8722_device::fsdir_r )
+{
+ return MCR_FSDIR;
+}
+
+
+//-------------------------------------------------
+// ta_r - translated address read
+//-------------------------------------------------
+
+offs_t mos8722_device::ta_r(offs_t offset, int aec, int *ms0, int *ms1, int *ms2, int *ms3, int *cas0, int *cas1)
+{
+ offs_t ta;
+
+ *ms0 = 1;
+ *ms1 = 1;
+ *ms2 = CR_IO;
+ *ms3 = !MCR_C64;
+
+ if (aec)
+ {
+ // CPU access
+ ta = offset & 0xff00;
+
+ *cas0 = CR_A16;
+ *cas1 = !*cas0;
+
+ if (!MCR_C64)
+ {
+ if (offset >= 0xff00 && offset < 0xff05)
+ {
+ // MMU registers
+ *cas0 = 1;
+ *cas1 = 1;
+ }
+ else if (!MCR_8500 && !CR_A16 && offset < 0x1000)
+ {
+ // Z80 ROM
+ ta = 0xd000 | (offset & 0xf00);
+
+ *ms0 = 0;
+ *ms1 = 0;
+ }
+ else
+ {
+ if (offset < 0x0100)
+ {
+ // page 0 pointer
+ ta = m_reg[P0L] << 8;
+
+ *cas0 = P0H_A16;
+ *cas1 = !*cas0;
+ }
+ else if (offset < 0x0200)
+ {
+ // page 1 pointer
+ ta = m_reg[P1L] << 8;
+
+ *cas0 = P1H_A16;
+ *cas1 = !*cas0;
+ }
+ else if (offset >= 0x4000 && offset < 0x8000)
+ {
+ // low ROM
+ *ms0 = CR_ROM_LO;
+ *ms1 = CR_ROM_LO;
+ }
+ else if (offset >= 0x8000 && offset < 0xc000)
+ {
+ // middle ROM
+ *ms0 = BIT(CR_ROM_MID, 1);
+ *ms1 = BIT(CR_ROM_MID, 0);
+ }
+ else if (offset >= 0xc000)
+ {
+ // high ROM
+ *ms0 = BIT(CR_ROM_HI, 1);
+ *ms1 = BIT(CR_ROM_HI, 0);
+ }
+
+ if (*ms0 && *ms1)
+ {
+ if ((offset >> 8) == m_reg[P0L])
+ {
+ ta = 0x0000;
+ }
+ else if ((offset >> 8) == m_reg[P1L])
+ {
+ ta = 0x0100;
+ }
+ }
+
+ if ((RCR_BOTTOM && offset < RCR_BOTTOM_ADDRESS[RCR_SHARE]) ||
+ (RCR_TOP && offset >= RCR_TOP_ADDRESS[RCR_SHARE]))
+ {
+ // RAM sharing
+ *cas0 = 0;
+ *cas1 = !*cas0;
+ }
+ }
+ }
+ }
+ else
+ {
+ // VIC access
+ ta = 0xf000 | (offset & 0xf00);
+
+ *cas0 = RCR_VA16;
+ *cas1 = !*cas0;
+ }
+
+ return ta;
+}
diff --git a/src/emu/machine/mos8722.h b/src/emu/machine/mos8722.h
new file mode 100644
index 00000000000..b4dc13c8c9b
--- /dev/null
+++ b/src/emu/machine/mos8722.h
@@ -0,0 +1,119 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 8722 Memory Management Unit emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ Vdd 1 |* \_/ | 48 SENSE40
+ _RESET 2 | | 47 (MS3) 128/64
+ TA15 3 | | 46 _EXROM
+ TA14 4 | | 45 _GAME
+ TA13 5 | | 44 FSDIR
+ TA12 6 | | 43 _Z80EN
+ TA11 7 | | 42 D7
+ TA10 8 | | 41 D6
+ TA9 9 | | 40 D5
+ TA8 10 | | 39 D4
+ _CAS1 11 | | 38 D3
+ _CAS0 12 | MOS8722 | 37 D2
+ I/O SEL (MS2) 13 | | 36 D1
+ ROMBANK1 (MS1) 14 | | 35 D0
+ ROMBANK0 (MS0) 15 | | 34 Vss
+ AEC 16 | | 33 phi0
+ MUX 17 | | 32 R/_W
+ A0 18 | | 31 A15
+ A1 19 | | 30 A14
+ A2 20 | | 29 A13
+ A3 21 | | 28 A12
+ A4/A5 22 | | 27 A11
+ A6/A7 23 | | 26 A10
+ A8 24 |_____________| 25 A9
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __MOS8722__
+#define __MOS8722__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS8722_ADD(_tag, _config) \
+ MCFG_DEVICE_ADD(_tag, MOS8722, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+
+#define MOS8722_INTERFACE(name) \
+ const mos8722_interface (name) =
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mos8722_interface
+
+struct mos8722_interface
+{
+ devcb_write_line m_out_z80en_cb;
+ devcb_write_line m_out_fsdir_cb;
+ devcb_read_line m_in_game_cb;
+ devcb_read_line m_in_exrom_cb;
+ devcb_read_line m_in_sense40_cb;
+};
+
+
+// ======================> mos8722_device
+
+class mos8722_device : public device_t,
+ public mos8722_interface
+{
+public:
+ // construction/destruction
+ mos8722_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ UINT8 read(offs_t offset, UINT8 data);
+ DECLARE_WRITE8_MEMBER( write );
+
+ DECLARE_READ_LINE_MEMBER( fsdir_r );
+
+ offs_t ta_r(offs_t offset, int aec, int *ms0, int *ms1, int *ms2, int *ms3, int *cas0, int *cas1);
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+
+private:
+ devcb_resolved_write_line m_out_z80en_func;
+ devcb_resolved_write_line m_out_fsdir_func;
+ devcb_resolved_read_line m_in_game_func;
+ devcb_resolved_read_line m_in_exrom_func;
+ devcb_resolved_read_line m_in_sense40_func;
+
+ UINT8 m_reg[16];
+
+ UINT8 m_p0h_latch;
+ UINT8 m_p1h_latch;
+};
+
+
+// device type definition
+extern const device_type MOS8722;
+
+
+
+#endif