diff options
Diffstat (limited to 'src/emu/machine')
-rw-r--r-- | src/emu/machine/64h156.c | 778 | ||||
-rw-r--r-- | src/emu/machine/64h156.h | 210 | ||||
-rw-r--r-- | src/emu/machine/machine.mak | 36 | ||||
-rw-r--r-- | src/emu/machine/mos6702.c | 71 | ||||
-rw-r--r-- | src/emu/machine/mos6702.h | 69 | ||||
-rw-r--r-- | src/emu/machine/mos8706.c | 81 | ||||
-rw-r--r-- | src/emu/machine/mos8706.h | 73 | ||||
-rw-r--r-- | src/emu/machine/mos8722.c | 429 | ||||
-rw-r--r-- | src/emu/machine/mos8722.h | 119 |
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 |