-apple/rbv.cpp, apple/maciici.cpp: Implemented monochrome mode, cleaned up clocks.

* apple/rbv.cpp: Send blue channel to all outputs when a monochrome
  monitor is connected.
* apple/rbv.cpp: Implement device_palette_interface rathr than using a
  separate palette device.
* apple/rbv.cpp: Derive 60.15 Hz timer and pseudo-VIA clock from clock
  input.
* apple/maciici.cpp: Derive clocks from RBV clock crystal.

-docs: Link more configuration options to their descriptions.
This commit is contained in:
Vas Crabb 2025-04-14 03:31:55 +10:00
parent d406685313
commit 50178bb8a0
5 changed files with 95 additions and 70 deletions

View File

@ -20,18 +20,20 @@ arcade-style controllers.
Controller configuration files are an XML application, using the ``.cfg``
filename extension. MAME searches for controller configuration files in the
directories specified using the ``ctrlrpath`` option. A controller
configuration file is selected by setting the ``ctrlr`` option to its filename,
excluding the ``.cfg`` extension (e.g. set the ``ctrlr`` option to
``scorpionxg`` to use **scorpionxg.cfg**). It is an error if the specified
controller configuration file does not exist, or if it contains no sections
applicable to the emulated system.
directories specified using the :ref:`ctrlrpath <mame-commandline-ctrlrpath>`
option. A controller configuration file is selected by setting the ``ctrlr``
option to its filename, excluding the ``.cfg`` extension (e.g. set the ``ctrlr``
option to ``scorpionxg`` to use **scorpionxg.cfg**). It is an error if the
specified controller configuration file does not exist, or if it contains no
sections applicable to the emulated system.
Controller configuration files use implementation-dependent input tokens. The
values available and their precise meanings depend on the exact version of MAME
used, the input devices connected, the selected input provider modules
(``keyboardprovider``, ``mouseprovider``, ``lightgunprovider`` and
``joystickprovider`` options), and possibly other settings.
(:ref:`keyboardprovider <mame-commandline-keyboardprovider>`,
:ref:`mouseprovider <mame-commandline-mouseprovider>`, :ref:`lightgunprovider
<mame-commandline-lightgunprovider>` and :ref:`joystickprovider
<mame-commandline-joystickprovider>` options), and possibly other settings.
.. _ctrlrcfg-structure:

View File

@ -91,14 +91,12 @@ protected:
// construction/destruction
jmfb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
// device_t implementation
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
// palette implementation
// device_palette_interface implementation
uint32_t palette_entries() const noexcept override;
private:

View File

@ -46,8 +46,8 @@
namespace {
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
static constexpr XTAL C15M = 31.3344_MHz_XTAL / 2;
static constexpr XTAL C7M = 31.3344_MHz_XTAL / 4;
class maciici_state : public driver_device
{
@ -597,7 +597,7 @@ void maciici_state::maciixi_base(machine_config &config)
SOFTWARE_LIST(config, "flop_mac35_clean").set_original("mac_flop_clcracked");
SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop");
RBV(config, m_rbv, C15M);
RBV(config, m_rbv, 31.3344_MHz_XTAL); // main clock input - additional 30.24MHz and 57.2832MHz pixel clock inputs
m_rbv->via6015_callback().set(m_via1, FUNC(via6522_device::write_ca1));
m_rbv->irq_callback().set(FUNC(maciici_state::set_via2_interrupt));

View File

@ -14,9 +14,6 @@
#include "layout/generic.h"
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
@ -40,6 +37,15 @@ ioport_constructor rbv_device::device_input_ports() const
return INPUT_PORTS_NAME(rbv);
}
//-------------------------------------------------
// palette_entries - palette size
//-------------------------------------------------
u32 rbv_device::palette_entries() const noexcept
{
return 256;
}
//-------------------------------------------------
// ADDRESS_MAP
//-------------------------------------------------
@ -62,9 +68,7 @@ void rbv_device::device_add_mconfig(machine_config &config)
m_screen->screen_vblank().set(m_pseudovia, FUNC(pseudovia_device::slot_irq_w<0x40>));
config.set_default_layout(layout_monitors);
PALETTE(config, m_palette).set_entries(256);
APPLE_PSEUDOVIA(config, m_pseudovia, C15M);
APPLE_PSEUDOVIA(config, m_pseudovia, DERIVED_CLOCK(1, 2));
m_pseudovia->readvideo_handler().set(FUNC(rbv_device::via2_video_config_r));
m_pseudovia->writevideo_handler().set(FUNC(rbv_device::via2_video_config_w));
m_pseudovia->irq_callback().set(FUNC(rbv_device::via2_irq_w));
@ -74,13 +78,13 @@ void rbv_device::device_add_mconfig(machine_config &config)
// rbv_device - constructor
//-------------------------------------------------
rbv_device::rbv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
rbv_device::rbv_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, RBV, tag, owner, clock),
device_palette_interface(mconfig, *this),
write_6015(*this),
write_irq(*this),
m_io_montype(*this, "MONTYPE"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_pseudovia(*this, "pseudovia")
{
}
@ -97,10 +101,12 @@ void rbv_device::device_start()
m_configured = false;
m_hres = m_vres = 0;
m_montype = 0;
m_monochrome = false;
save_item(NAME(m_hres));
save_item(NAME(m_vres));
save_item(NAME(m_montype));
save_item(NAME(m_monochrome));
save_item(NAME(m_pal_address));
save_item(NAME(m_pal_idx));
@ -114,7 +120,7 @@ void rbv_device::device_start()
void rbv_device::device_reset()
{
// start 60.15 Hz timer
m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15));
m_6015_timer->adjust(attotime::from_ticks(2 * 640 * 407, clock()), 0, attotime::from_ticks(2 * 640 * 407, 31.3344_MHz_XTAL));
if (!m_configured)
{
@ -124,19 +130,22 @@ void rbv_device::device_reset()
case 1: // 15" portrait display
m_hres = 640;
m_vres = 870;
m_monochrome = true;
m_screen->configure(832, 918, rectangle(0, 639, 0, 869), HZ_TO_ATTOSECONDS(57.2832_MHz_XTAL / (832 * 918)));
break;
case 2: // 12" RGB
m_hres = 512;
m_vres = 384;
m_screen->configure(640, 407, rectangle(0, 511, 0, 383), HZ_TO_ATTOSECONDS(31.3344_MHz_XTAL / (2 * 640 * 407)));
m_monochrome = false;
m_screen->configure(640, 407, rectangle(0, 511, 0, 383), HZ_TO_ATTOSECONDS(double(clock()) / (2 * 640 * 407)));
break;
case 6: // 13" RGB
default:
m_hres = 640;
m_vres = 480;
m_monochrome = false;
m_screen->configure(864, 525, rectangle(0, 639, 0, 479), HZ_TO_ATTOSECONDS(30.24_MHz_XTAL / (864 * 525)));
break;
}
@ -178,7 +187,7 @@ void rbv_device::asc_irq_w(int state)
void rbv_device::pseudovia_recalc_irqs()
{
// check slot interrupts and bubble them down to IFR
uint8_t slot_irqs = (~m_pseudovia_regs[2]) & 0x78;
u8 slot_irqs = (~m_pseudovia_regs[2]) & 0x78;
slot_irqs &= (m_pseudovia_regs[0x12] & 0x78);
if (slot_irqs)
@ -190,7 +199,7 @@ void rbv_device::pseudovia_recalc_irqs()
m_pseudovia_regs[3] &= ~2; // any slot
}
uint8_t ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b;
u8 ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b;
if (ifr != 0)
{
@ -220,7 +229,7 @@ void rbv_device::via2_irq_w(int state)
write_irq(state);
}
uint8_t rbv_device::pseudovia_r(offs_t offset)
u8 rbv_device::pseudovia_r(offs_t offset)
{
int data = 0;
@ -262,7 +271,7 @@ uint8_t rbv_device::pseudovia_r(offs_t offset)
return data;
}
void rbv_device::pseudovia_w(offs_t offset, uint8_t data)
void rbv_device::pseudovia_w(offs_t offset, u8 data)
{
if (offset < 0x100)
{
@ -380,13 +389,13 @@ void rbv_device::dac_w(offs_t offset, u8 data)
switch (m_pal_idx)
{
case 0:
m_palette->set_pen_red_level(m_pal_address, data);
set_pen_red_level(m_pal_address, data);
break;
case 1:
m_palette->set_pen_green_level(m_pal_address, data);
set_pen_green_level(m_pal_address, data);
break;
case 2:
m_palette->set_pen_blue_level(m_pal_address, data);
set_pen_blue_level(m_pal_address, data);
break;
}
m_pal_idx++;
@ -401,7 +410,16 @@ void rbv_device::dac_w(offs_t offset, u8 data)
u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
auto const vram8 = util::big_endian_cast<uint8_t const>(m_ram_ptr);
if (m_monochrome)
return update_screen<true>(screen, bitmap, cliprect);
else
return update_screen<false>(screen, bitmap, cliprect);
}
template <bool Mono>
u32 rbv_device::update_screen(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
auto const vram8 = util::big_endian_cast<u8 const>(m_ram_ptr);
// video disabled?
if (m_video_config & 0x40)
@ -410,26 +428,34 @@ u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
return 0;
}
const pen_t *pens = m_palette->pens();
auto const pen =
[this] (unsigned n) -> rgb_t
{
rgb_t const val = pen_color(n);
if (Mono)
return rgb_t(val.b(), val.b(), val.b());
else
return val;
};
switch (m_video_config & 7)
{
case 0: // 1bpp
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
uint32_t *scanline = &bitmap.pix(y, cliprect.left() & ~7);
u32 *scanline = &bitmap.pix(y, cliprect.left() & ~7);
for (int x = cliprect.left() / 8; x <= cliprect.right() / 8; x++)
{
uint8_t const pixels = vram8[(y * (m_hres / 8)) + x];
u8 const pixels = vram8[(y * (m_hres / 8)) + x];
*scanline++ = pens[0xfe | (pixels >> 7)];
*scanline++ = pens[0xfe | ((pixels >> 6) & 1)];
*scanline++ = pens[0xfe | ((pixels >> 5) & 1)];
*scanline++ = pens[0xfe | ((pixels >> 4) & 1)];
*scanline++ = pens[0xfe | ((pixels >> 3) & 1)];
*scanline++ = pens[0xfe | ((pixels >> 2) & 1)];
*scanline++ = pens[0xfe | ((pixels >> 1) & 1)];
*scanline++ = pens[0xfe | (pixels & 1)];
*scanline++ = pen(0xfe | BIT(pixels, 7));
*scanline++ = pen(0xfe | BIT(pixels, 6));
*scanline++ = pen(0xfe | BIT(pixels, 5));
*scanline++ = pen(0xfe | BIT(pixels, 4));
*scanline++ = pen(0xfe | BIT(pixels, 3));
*scanline++ = pen(0xfe | BIT(pixels, 2));
*scanline++ = pen(0xfe | BIT(pixels, 1));
*scanline++ = pen(0xfe | BIT(pixels, 0));
}
}
break;
@ -437,15 +463,15 @@ u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
case 1: // 2bpp
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
uint32_t *scanline = &bitmap.pix(y, cliprect.left() & ~3);
u32 *scanline = &bitmap.pix(y, cliprect.left() & ~3);
for (int x = cliprect.left() / 4; x <= cliprect.right() / 4; x++)
{
uint8_t const pixels = vram8[(y * (m_hres / 4)) + x];
u8 const pixels = vram8[(y * (m_hres / 4)) + x];
*scanline++ = pens[0xfc | ((pixels >> 6) & 3)];
*scanline++ = pens[0xfc | ((pixels >> 4) & 3)];
*scanline++ = pens[0xfc | ((pixels >> 2) & 3)];
*scanline++ = pens[0xfc | (pixels & 3)];
*scanline++ = pen(0xfc | ((pixels >> 6) & 3));
*scanline++ = pen(0xfc | ((pixels >> 4) & 3));
*scanline++ = pen(0xfc | ((pixels >> 2) & 3));
*scanline++ = pen(0xfc | (pixels & 3));
}
}
break;
@ -453,13 +479,13 @@ u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
case 2: // 4bpp
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
uint32_t *scanline = &bitmap.pix(y, cliprect.left() & ~1);
u32 *scanline = &bitmap.pix(y, cliprect.left() & ~1);
for (int x = cliprect.left() / 2; x <= cliprect.right() / 2; x++)
{
uint8_t const pixels = vram8[(y * (m_hres / 2)) + x];
u8 const pixels = vram8[(y * (m_hres / 2)) + x];
*scanline++ = pens[0xf0 | (pixels >> 4)];
*scanline++ = pens[0xf0 | (pixels & 0xf)];
*scanline++ = pen(0xf0 | (pixels >> 4));
*scanline++ = pen(0xf0 | (pixels & 0xf));
}
}
break;
@ -467,11 +493,11 @@ u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
case 3: // 8bpp
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
uint32_t *scanline = &bitmap.pix(y, cliprect.left());
u32 *scanline = &bitmap.pix(y, cliprect.left());
for (int x = cliprect.left(); x <= cliprect.right(); x++)
{
uint8_t const pixels = vram8[(y * m_hres) + x];
*scanline++ = pens[pixels];
u8 const pixels = vram8[(y * m_hres) + x];
*scanline++ = pen(pixels);
}
}
break;

View File

@ -8,21 +8,16 @@
#include "pseudovia.h"
#include "emupal.h"
#include "screen.h"
// ======================> rbv_device
class rbv_device : public device_t
class rbv_device : public device_t, public device_palette_interface
{
public:
// construction/destruction
rbv_device(const machine_config &mconfig, const char *tag, device_t *owner)
: rbv_device(mconfig, tag, owner, (uint32_t)0)
{
}
rbv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
rbv_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void map(address_map &map) ATTR_COLD;
@ -35,18 +30,20 @@ public:
void asc_irq_w(int state);
protected:
// device-level overrides
// device_t implementation
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
// device_palette_interface implementation
u32 palette_entries() const noexcept override;
private:
devcb_write_line write_6015, write_irq;
required_ioport m_io_montype;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<pseudovia_device> m_pseudovia;
emu_timer *m_6015_timer;
@ -54,6 +51,7 @@ private:
bool m_configured;
s32 m_hres, m_vres;
u8 m_montype;
bool m_monochrome;
u8 m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr;
u8 m_pal_address, m_pal_idx;
@ -61,8 +59,8 @@ private:
u32 m_ram_size;
u8 m_video_config;
uint8_t pseudovia_r(offs_t offset);
void pseudovia_w(offs_t offset, uint8_t data);
u8 pseudovia_r(offs_t offset);
void pseudovia_w(offs_t offset, u8 data);
void pseudovia_recalc_irqs();
u8 via2_video_config_r();
@ -75,6 +73,7 @@ private:
void dac_w(offs_t offset, u8 data);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
template <bool Mono> u32 update_screen(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
};
// device type definition