summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/6883sam.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/6883sam.cpp')
-rw-r--r--src/mame/machine/6883sam.cpp489
1 files changed, 0 insertions, 489 deletions
diff --git a/src/mame/machine/6883sam.cpp b/src/mame/machine/6883sam.cpp
deleted file mode 100644
index e9ddb12b170..00000000000
--- a/src/mame/machine/6883sam.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nathan Woods
-/***************************************************************************
-
- 6883sam.cpp
-
- Motorola 6883 Synchronous Address Multiplexer
-
- The Motorola 6883 SAM has 16 bits worth of state, but the state is changed
- by writing into a 32 byte address space; odd bytes set bits and even bytes
- clear bits. Here is the layout:
-
- 31 Set TY Map Type 0: RAM/ROM 1: All RAM
- 30 Clear TY Map Type
- 29 Set M1 Memory Size 00: 4K 10: 64K Dynamic
- 28 Clear M1 Memory Size 01: 16K 11: 64K Static
- 27 Set M0 Memory Size
- 26 Clear M0 Memory Size
- 25 Set R1 MPU Rate 00: Slow 10: Fast
- 24 Clear R1 MPU Rate 01: Dual 11: Fast
- 23 Set R0 MPU Rate
- 22 Clear R0 MPU Rate
- 21 Set P1 Page #1 0: Low 1: High
- 20 Clear P1 Page #1
- 19 Set F6 Display Offset
- 18 Clear F6 Display Offset
- 17 Set F5 Display Offset
- 16 Clear F5 Display Offset
- 15 Set F4 Display Offset
- 14 Clear F4 Display Offset
- 13 Set F3 Display Offset
- 12 Clear F3 Display Offset
- 11 Set F2 Display Offset
- 10 Clear F2 Display Offset
- 9 Set F1 Display Offset
- 8 Clear F1 Display Offset
- 7 Set F0 Display Offset
- 6 Clear F0 Display Offset
- 5 Set V2 VDG Mode
- 4 Clear V2 VDG Mode
- 3 Set V1 VDG Mode
- 2 Clear V1 VDG Mode
- 1 Set V0 VDG Mode
- 0 Clear V0 VDG Mode
-
- All parts of the SAM are fully emulated except R1/R0 (the changes in the
- MPU rate are approximated) and M1/M0
-
-***************************************************************************/
-
-
-#include "emu.h"
-#include "machine/6883sam.h"
-
-
-//**************************************************************************
-// CONSTANTS
-//**************************************************************************
-
-#define LOG_FBITS (1U << 1)
-#define LOG_VBITS (1U << 2)
-#define LOG_PBITS (1U << 3)
-#define LOG_TBITS (1U << 4)
-#define LOG_MBITS (1U << 5)
-#define LOG_RBITS (1U << 6)
-
-#define VERBOSE (0)
-// #define VERBOSE (LOG_FBITS)
-// #define VERBOSE (LOG_FBITS | LOG_VBITS | LOG_PBITS | LOG_TBITS | LOG_MBITS | LOG_RBITS)
-
-#include "logmacro.h"
-
-#define LOGFBITS(...) LOGMASKED(LOG_FBITS, __VA_ARGS__)
-#define LOGVBITS(...) LOGMASKED(LOG_VBITS, __VA_ARGS__)
-#define LOGPBITS(...) LOGMASKED(LOG_PBITS, __VA_ARGS__)
-#define LOGTBITS(...) LOGMASKED(LOG_TBITS, __VA_ARGS__)
-#define LOGMBITS(...) LOGMASKED(LOG_MBITS, __VA_ARGS__)
-#define LOGRBITS(...) LOGMASKED(LOG_RBITS, __VA_ARGS__)
-
-DEFINE_DEVICE_TYPE(SAM6883, sam6883_device, "sam6883", "MC6883 SAM")
-
-
-
-//**************************************************************************
-// DEVICE SETUP
-//**************************************************************************
-
-//-------------------------------------------------
-// constructor
-//-------------------------------------------------
-
-sam6883_device::sam6883_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, SAM6883, tag, owner, clock)
- , device_memory_interface(mconfig, *this)
- , sam6883_friend_device_interface(mconfig, *this, 4)
- , m_ram_config("ram", ENDIANNESS_BIG, 8, 16, 0)
- , m_rom0_config("rom0", ENDIANNESS_BIG, 8, 13, 0)
- , m_rom1_config("rom1", ENDIANNESS_BIG, 8, 13, 0)
- , m_rom2_config("rom2", ENDIANNESS_BIG, 8, 14, 0)
- , m_io0_config("io0", ENDIANNESS_BIG, 8, 5, 0)
- , m_io1_config("io1", ENDIANNESS_BIG, 8, 5, 0)
- , m_io2_config("io2", ENDIANNESS_BIG, 8, 5, 0)
- , m_boot_config("boot", ENDIANNESS_BIG, 8, 7, 0)
-{
-}
-
-sam6883_friend_device_interface::sam6883_friend_device_interface(const machine_config &mconfig, device_t &device, int divider)
- : device_interface(device, "sam6883")
- , m_cpu(device, finder_base::DUMMY_TAG)
- , m_sam_state(0x0000)
- , m_divider(divider)
-{
-}
-
-
-//-------------------------------------------------
-// memory_space_config - return the configuration
-// for the address spaces
-//-------------------------------------------------
-
-device_memory_interface::space_config_vector sam6883_device::memory_space_config() const
-{
- return space_config_vector {
- std::make_pair(0, &m_ram_config),
- std::make_pair(1, &m_rom0_config),
- std::make_pair(2, &m_rom1_config),
- std::make_pair(3, &m_rom2_config),
- std::make_pair(4, &m_io0_config),
- std::make_pair(5, &m_io1_config),
- std::make_pair(6, &m_io2_config),
- std::make_pair(7, &m_boot_config)
- };
-}
-
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void sam6883_device::device_start()
-{
- // get spaces
- space(0).cache(m_ram_space);
- for (int i = 0; i < 3; i++)
- space(i + 1).cache(m_rom_space[i]);
- for (int i = 0; i < 3; i++)
- space(i + 4).specific(m_io_space[i]);
- space(7).cache(m_boot_space);
-
- // save state support
- save_item(NAME(m_sam_state));
- save_item(NAME(m_counter));
- save_item(NAME(m_counter_xdiv));
- save_item(NAME(m_counter_ydiv));
-}
-
-
-//-------------------------------------------------
-// read - read from one of the eight spaces
-//-------------------------------------------------
-
-uint8_t sam6883_device::read(offs_t offset)
-{
- bool mode_64k = (m_sam_state & SAM_STATE_M1) == SAM_STATE_M1;
- if (offset < (mode_64k && (m_sam_state & SAM_STATE_TY) ? 0xff00 : 0x8000))
- {
- // RAM reads: 0000–7FFF or 0000–FEFF
- if (mode_64k && (m_sam_state & (SAM_STATE_TY|SAM_STATE_P1)) == SAM_STATE_P1)
- offset |= 0x8000;
- return m_ram_space.read_byte(offset);
- }
- else if (offset < 0xc000 || offset >= 0xffe0)
- {
- // ROM spaces: 8000–9FFF and A000–BFFF + FFE0–FFFF
- return m_rom_space[BIT(offset, 13)].read_byte(offset & 0x1fff);
- }
- else if (offset < 0xff00)
- {
- // ROM2 space: C000–FEFF
- return m_rom_space[2].read_byte(offset & 0x3fff);
- }
- else if (offset < 0xff60)
- {
- // I/O spaces: FF00–FF1F (slow), FF20–FF3F, FF40–FF5F
- return m_io_space[BIT(offset, 5, 2)].read_byte(offset & 0x1f);
- }
- else
- {
- // FF60–FFDF
- return m_boot_space.read_byte(offset - 0xff60);
- }
-}
-
-
-//-------------------------------------------------
-// write - write to RAM, I/O or internal register
-//-------------------------------------------------
-
-void sam6883_device::write(offs_t offset, uint8_t data)
-{
- bool mode_64k = (m_sam_state & SAM_STATE_M1) == SAM_STATE_M1;
- if (offset < 0x8000)
- {
- // RAM write space: 0000–7FFF (nominally space 7)
- if (mode_64k && (m_sam_state & (SAM_STATE_TY|SAM_STATE_P1)) == SAM_STATE_P1)
- offset |= 0x8000;
- m_ram_space.write_byte(offset, data);
- }
- else if (offset < 0xc000 || offset >= 0xffe0)
- {
- // ROM spaces: 8000–9FFF and A000–BFFF + FFE0–FFFF (may write through to RAM)
- if (offset < 0xc000 && mode_64k && (m_sam_state & SAM_STATE_TY))
- m_ram_space.write_byte(offset, data);
- m_rom_space[BIT(offset, 13)].write_byte(offset & 0x1fff, data);
- }
- else if (offset < 0xff00)
- {
- // ROM2 space: C000–FEFF (may write through to RAM)
- if (mode_64k && (m_sam_state & SAM_STATE_TY))
- m_ram_space.write_byte(offset, data);
- m_rom_space[2].write_byte(offset & 0x3fff, data);
- }
- else if (offset < 0xff60)
- {
- // I/O spaces: FF00–FF1F (slow), FF20–FF3F, FF40–FF5F
- m_io_space[BIT(offset, 5, 2)].write_byte(offset & 0x1f, data);
- }
- else
- {
- // FF60–FFDF
- m_boot_space.write_byte(offset - 0xff60, data);
- if (offset >= 0xffc0)
- internal_write(offset & 0x1f, data);
- }
-}
-
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void sam6883_device::device_reset()
-{
- m_counter = 0;
- m_counter_xdiv = 0;
- m_counter_ydiv = 0;
- m_sam_state = 0x0000;
- update_state();
-}
-
-
-
-//-------------------------------------------------
-// device_post_load - device-specific post load
-//-------------------------------------------------
-
-void sam6883_device::device_post_load()
-{
- device_t::device_post_load();
- update_state();
-}
-
-
-
-//-------------------------------------------------
-// update_state
-//-------------------------------------------------
-
-void sam6883_device::update_state()
-{
- update_memory();
- update_cpu_clock();
-}
-
-
-
-//-------------------------------------------------
-// update_memory
-//-------------------------------------------------
-
-void sam6883_device::update_memory()
-{
- // Memory size - allowed restricting memory accesses to something less than
- // 32k
- //
- // This was a SAM switch that occupied 4 addresses:
- //
- // $FFDD (set) R1
- // $FFDC (clear) R1
- // $FFDB (set) R0
- // $FFDA (clear) R0
- //
- // R1:R0 formed the following states:
- // 00 - 4k
- // 01 - 16k
- // 10 - 64k
- // 11 - static RAM (??)
- //
- // If something less than 64k was set, the low RAM would be smaller and
- // mirror the other parts of the RAM
- //
- // TODO: Find out what "static RAM" is
- // TODO: This should affect _all_ memory accesses, not just video ram
- // TODO: Verify that the CoCo 3 ignored this
-
- // switch depending on the M1/M0 variables
- switch(m_sam_state & (SAM_STATE_M1|SAM_STATE_M0))
- {
- case 0:
- // 4K mode
- m_counter_mask = 0x0FFF;
- break;
-
- case SAM_STATE_M0:
- // 16K mode
- m_counter_mask = 0x3FFF;
- break;
-
- case SAM_STATE_M1:
- // 64k mode (dynamic)
- case SAM_STATE_M1|SAM_STATE_M0:
- // 64k mode (static)
- // full 64k RAM or ROM/RAM
- // CoCo Max requires these two be treated the same
- m_counter_mask = 0xfFFF;
- break;
- }
-}
-
-
-
-//-------------------------------------------------
-// update_cpu_clock - adjusts the speed of the CPU
-// clock
-//-------------------------------------------------
-
-void sam6883_friend_device_interface::update_cpu_clock()
-{
- // The infamous speed up poke.
- //
- // This was a SAM switch that occupied 4 addresses:
- //
- // $FFD9 (set) R1
- // $FFD8 (clear) R1
- // $FFD7 (set) R0
- // $FFD6 (clear) R0
- //
- // R1:R0 formed the following states:
- // 00 - slow 0.89 MHz
- // 01 - dual speed ???
- // 1x - fast 1.78 MHz
- //
- // R1 controlled whether the video addressing was speeded up and R0
- // did the same for the CPU. On pre-CoCo 3 machines, setting R1 caused
- // the screen to display garbage because the M6847 could not display
- // fast enough.
- //
- // TODO: Make the overclock more accurate. In dual speed, ROM was a fast
- // access but RAM was not. I don't know how to simulate this.
-
- int speed = (m_sam_state & (SAM_STATE_R1|SAM_STATE_R0)) / SAM_STATE_R0;
- m_cpu->owner()->set_unscaled_clock(device().clock() / (m_divider * (speed ? 2 : 4)));
-}
-
-
-
-//-------------------------------------------------
-// internal_write
-//-------------------------------------------------
-
-void sam6883_device::internal_write(offs_t offset, uint8_t data)
-{
- // data is ignored
- (void)data;
-
- // alter the SAM state
- uint16_t xorval = alter_sam_state(offset);
-
- // based on the mask, apply effects
- if (xorval & (SAM_STATE_TY|SAM_STATE_M1|SAM_STATE_M0|SAM_STATE_P1))
- update_memory();
- if (xorval & (SAM_STATE_R1|SAM_STATE_R0))
- update_cpu_clock();
-
- if (xorval & (SAM_STATE_F6|SAM_STATE_F5|SAM_STATE_F4|SAM_STATE_F3|SAM_STATE_F2|SAM_STATE_F1|SAM_STATE_F0))
- {
- LOGFBITS("%s: SAM F Address: $%04x\n",
- machine().describe_context(),
- display_offset());
- }
-
- if (xorval & (SAM_STATE_V0|SAM_STATE_V1|SAM_STATE_V2))
- {
- LOGVBITS("%s: SAM V Bits: $%02x\n",
- machine().describe_context(),
- (m_sam_state & (SAM_STATE_V0|SAM_STATE_V1|SAM_STATE_V2)));
- }
-
- if (xorval & (SAM_STATE_P1))
- {
- LOGPBITS("%s: SAM P1 Bit: $%02x\n",
- machine().describe_context(),
- (m_sam_state & (SAM_STATE_P1)) >> 10);
- }
-
- if (xorval & (SAM_STATE_TY))
- {
- LOGTBITS("%s: SAM TY Bit: $%02x\n",
- machine().describe_context(),
- (m_sam_state & (SAM_STATE_TY)) >> 15);
- }
-
- if (xorval & (SAM_STATE_M0|SAM_STATE_M1))
- {
- LOGMBITS("%s: SAM M Bits: $%02x\n",
- machine().describe_context(),
- (m_sam_state & (SAM_STATE_M0|SAM_STATE_M1)) >> 13);
- }
-
- if (xorval & (SAM_STATE_R0|SAM_STATE_R1))
- {
- LOGRBITS("%s: SAM R Bits: $%02x\n",
- machine().describe_context(),
- (m_sam_state & (SAM_STATE_R0|SAM_STATE_R1)) >> 11);
- }
-}
-
-
-
-//-------------------------------------------------
-// horizontal_sync
-//-------------------------------------------------
-
-void sam6883_device::horizontal_sync()
-{
- bool carry;
-
- // When horizontal sync occurs, bits B1-B3 or B1-B4 may be cleared (except in DMA mode). The catch
- // is that the SAM's counter is a chain of flip-flops. Clearing the counter can cause carries to
- // occur just as they can when the counter is bumped.
- //
- // This is critical in getting certain semigraphics modes to work correctly. Guardian uses this
- // mode (see bug #1153). Special thanks to Ciaran Anscomb and Phill Harvey-Smith for figuring this
- // out
- switch((m_sam_state & (SAM_STATE_V2|SAM_STATE_V1|SAM_STATE_V0)) / SAM_STATE_V0)
- {
- case 0x01:
- case 0x03:
- case 0x05:
- // these SAM modes clear bits B1-B3
- carry = (m_counter & 0x0008) ? true : false;
- m_counter &= ~0x000F;
- if (carry)
- counter_carry_bit3();
- break;
-
- case 0x00:
- case 0x02:
- case 0x04:
- case 0x06:
- // clear bits B1-B4
- carry = (m_counter & 0x0010) ? true : false;
- m_counter &= ~0x001F;
- if (carry)
- counter_carry_bit4();
- break;
-
- case 0x07:
- // DMA mode - do nothing
- break;
-
- default:
- fatalerror("Should not get here\n");
- }
-}
-
-
-
-//-------------------------------------------------
-// hs_w
-//-------------------------------------------------
-
-WRITE_LINE_MEMBER( sam6883_device::hs_w )
-{
- if (state)
- {
- horizontal_sync();
- }
-}