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

View File

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

View File

@ -46,8 +46,8 @@
namespace { namespace {
static constexpr u32 C7M = 7833600; static constexpr XTAL C15M = 31.3344_MHz_XTAL / 2;
static constexpr u32 C15M = (C7M * 2); static constexpr XTAL C7M = 31.3344_MHz_XTAL / 4;
class maciici_state : public driver_device 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, "flop_mac35_clean").set_original("mac_flop_clcracked");
SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop"); 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->via6015_callback().set(m_via1, FUNC(via6522_device::write_ca1));
m_rbv->irq_callback().set(FUNC(maciici_state::set_via2_interrupt)); m_rbv->irq_callback().set(FUNC(maciici_state::set_via2_interrupt));

View File

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

View File

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