summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/emu.lua6
-rw-r--r--src/devices/bus/nubus/nubus.cpp11
-rw-r--r--src/devices/bus/nubus/nubus.h2
-rw-r--r--src/devices/bus/nubus/nubus_48gc.cpp496
-rw-r--r--src/devices/bus/nubus/nubus_48gc.h55
-rw-r--r--src/devices/bus/nubus/nubus_spec8.cpp62
-rw-r--r--src/devices/bus/nubus/nubus_specpdq.cpp198
-rw-r--r--src/devices/bus/nubus/nubus_specpdq.h15
-rw-r--r--src/devices/bus/nubus/supermac.cpp7
-rw-r--r--src/devices/bus/nubus/supermac.h10
-rw-r--r--src/emu/layout/generic.h3
-rw-r--r--src/emu/layout/monitors.lay41
-rw-r--r--src/emu/rendlay.cpp3
-rw-r--r--src/mame/drivers/mac.cpp17
-rw-r--r--src/mame/drivers/macquadra700.cpp9
-rw-r--r--src/mame/layout/mac.lay16
16 files changed, 674 insertions, 277 deletions
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua
index 06b92469c25..ef708b93d03 100644
--- a/scripts/src/emu.lua
+++ b/scripts/src/emu.lua
@@ -281,12 +281,13 @@ dependency {
-------------------------------------------------
-- core layouts
--------------------------------------------------
+ { MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/noscreens.lh" },
+ { MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/monitors.lh" },
{ MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/dualhovu.lh" },
{ MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/dualhsxs.lh" },
{ MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/dualhuov.lh" },
{ MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/triphsxs.lh" },
{ MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/quadhsxs.lh" },
- { MAME_DIR .. "src/emu/rendlay.cpp", GEN_DIR .. "emu/layout/noscreens.lh" },
}
custombuildtask {
@@ -296,12 +297,13 @@ custombuildtask {
custombuildtask {
{ MAME_DIR .. "src/frontend/mame/ui/uicmd14.png", GEN_DIR .. "emu/ui/uicmd14.fh", { MAME_DIR.. "scripts/build/png2bdc.py", MAME_DIR .. "scripts/build/file2str.py" }, { "@echo Converting uicmd14.png...", PYTHON .. " $(1) $(<) temp_cmd.bdc", PYTHON .. " $(2) temp_cmd.bdc $(@) font_uicmd14 uint8_t" } },
+ layoutbuildtask("emu/layout", "noscreens"),
+ layoutbuildtask("emu/layout", "monitors"),
layoutbuildtask("emu/layout", "dualhovu"),
layoutbuildtask("emu/layout", "dualhsxs"),
layoutbuildtask("emu/layout", "dualhuov"),
layoutbuildtask("emu/layout", "triphsxs"),
layoutbuildtask("emu/layout", "quadhsxs"),
- layoutbuildtask("emu/layout", "noscreens"),
}
project ("precompile")
diff --git a/src/devices/bus/nubus/nubus.cpp b/src/devices/bus/nubus/nubus.cpp
index 4cf28122207..4f712861714 100644
--- a/src/devices/bus/nubus/nubus.cpp
+++ b/src/devices/bus/nubus/nubus.cpp
@@ -193,6 +193,12 @@ void nubus_device::install_bank(offs_t start, offs_t end, void *data)
m_space->install_ram(start, end, data);
}
+void nubus_device::install_view(offs_t start, offs_t end, memory_view &view)
+{
+// printf("install_view: %s @ %x->%x\n", tag, start, end);
+ m_space->install_view(start, end, view);
+}
+
void nubus_device::set_irq_line(int slot, int state)
{
switch (slot)
@@ -284,6 +290,11 @@ void device_nubus_card_interface::install_bank(offs_t start, offs_t end, void *d
nubus().install_bank(start, end, data);
}
+void device_nubus_card_interface::install_view(offs_t start, offs_t end, memory_view &view)
+{
+ nubus().install_view(start, end, view);
+}
+
void device_nubus_card_interface::install_declaration_rom(const char *romregion, bool mirror_all_mb, bool reverse_rom)
{
bool inverted = false;
diff --git a/src/devices/bus/nubus/nubus.h b/src/devices/bus/nubus/nubus.h
index cc9a434d205..198f5b115eb 100644
--- a/src/devices/bus/nubus/nubus.h
+++ b/src/devices/bus/nubus/nubus.h
@@ -38,6 +38,7 @@ public:
// helper functions for card devices
void install_declaration_rom(const char *romregion, bool mirror_all_mb = false, bool reverse_rom = false);
void install_bank(offs_t start, offs_t end, void *data);
+ void install_view(offs_t start, offs_t end, memory_view &view);
uint32_t get_slotspace() { return 0xf0000000 | (m_slot<<24); }
uint32_t get_super_slotspace() { return m_slot<<28; }
@@ -126,6 +127,7 @@ public:
void install_readonly_device(offs_t start, offs_t end, read32_delegate rhandler, uint32_t mask=0xffffffff);
void install_writeonly_device(offs_t start, offs_t end, write32_delegate whandler, uint32_t mask=0xffffffff);
void install_bank(offs_t start, offs_t end, void *data);
+ void install_view(offs_t start, offs_t end, memory_view &view);
void set_irq_line(int slot, int state);
DECLARE_WRITE_LINE_MEMBER( irq9_w );
diff --git a/src/devices/bus/nubus/nubus_48gc.cpp b/src/devices/bus/nubus/nubus_48gc.cpp
index 3b6896e578d..fefaf8ad35d 100644
--- a/src/devices/bus/nubus/nubus_48gc.cpp
+++ b/src/devices/bus/nubus/nubus_48gc.cpp
@@ -1,15 +1,29 @@
// license:BSD-3-Clause
-// copyright-holders:R. Belmont
+// copyright-holders:R. Belmont, Vas Crabb
/***************************************************************************
Apple 4*8 Graphics Card (model 630-0400) emulation
Apple 8*24 Graphics Card emulation (cards have the same framebuffer chip
w/different ROMs and RAMDACs, apparently)
+ TODO:
+ * Proper clock generation to calculate frame rate - it's pretty easy to
+ find where it's writing PLL parameters.
+ * Work out why some monitors need magic multiply or divide by two to
+ get the right RAMDAC clock - inferring it from the reference clock
+ modulus is definitely wrong.
+ * When a monochrome monitor is connected, it sends the intensity to the
+ blue channel - maybe detect this and map blue channel to white?
+ * The 8•24 card uses a strange off-white palette with some monitors,
+ including the 21" and 16" RGB displays.
+ * Interlaced modes.
+
***************************************************************************/
#include "emu.h"
#include "nubus_48gc.h"
+
+#include "layout/generic.h"
#include "screen.h"
#include <algorithm>
@@ -18,11 +32,38 @@
#include "logmacro.h"
-#define VRAM_SIZE (0x200000) // 2 megs, maxed out
+#define VRAM_SIZE (0x20'0000) // 2 megs, maxed out
-#define GC48_SCREEN_NAME "48gc_screen"
+#define GC48_SCREEN_NAME "screen"
#define GC48_ROM_REGION "48gc_rom"
+
+static INPUT_PORTS_START( 48gc )
+ PORT_START("MONITOR")
+ PORT_CONFNAME(0x07, 0x06, u8"Attached monitor")
+ PORT_CONFSETTING( 0x00, u8"Macintosh Two-Page Monitor (1152\u00d7870)")
+ PORT_CONFSETTING( 0x01, u8"Macintosh Portrait Display (B&W 15\" 640\u00d7870)")
+ PORT_CONFSETTING( 0x02, u8"Macintosh RGB Display (12\" 512\u00d7384)")
+ PORT_CONFSETTING( 0x03, u8"Macintosh Two-Page Monitor (B&W 21\" 1152\u00d7870)")
+ //PORT_CONFSETTING( 0x04, u8"NTSC Monitor") requires implementing interlace modes
+ PORT_CONFSETTING( 0x05, u8"Macintosh Portrait Display (640\u00d7870)")
+ PORT_CONFSETTING( 0x06, u8"Macintosh Hi-Res Display (12-14\" 640\u00d7480)")
+INPUT_PORTS_END
+
+
+static INPUT_PORTS_START( 824gc )
+ PORT_START("MONITOR")
+ PORT_CONFNAME(0x07, 0x06, u8"Attached monitor")
+ PORT_CONFSETTING( 0x00, u8"Mac 21\" Color Display (1152\u00d7870)")
+ PORT_CONFSETTING( 0x01, u8"Mac Portrait Display (B&W 15\" 640\u00d7870)")
+ PORT_CONFSETTING( 0x02, u8"Mac RGB Display (12\" 512\u00d7384)")
+ PORT_CONFSETTING( 0x03, u8"Mac Two-Page Display (B&W 21\" 1152\u00d7870)")
+ //PORT_CONFSETTING( 0x04, u8"NTSC Monitor") requires implementing interlace modes
+ PORT_CONFSETTING( 0x05, u8"Mac 16\" Color Display (832\u00d7624)")
+ PORT_CONFSETTING( 0x06, u8"Mac Hi-Res Display (12-14\" 640\u00d7480)")
+INPUT_PORTS_END
+
+
ROM_START( gc48 )
ROM_REGION(0x8000, GC48_ROM_REGION, 0)
ROM_LOAD( "3410801.bin", 0x0000, 0x8000, CRC(e283da91) SHA1(4ae21d6d7bbaa6fc7aa301bee2b791ed33b1dcf9) )
@@ -47,6 +88,8 @@ DEFINE_DEVICE_TYPE(NUBUS_824GC, nubus_824gc_device, "nb_824gc", "Apple Macintosh
void jmfb_device::device_add_mconfig(machine_config &config)
{
+ config.set_default_layout(layout_monitors);
+
screen_device &screen(SCREEN(config, GC48_SCREEN_NAME, SCREEN_TYPE_RASTER));
screen.set_screen_update(FUNC(jmfb_device::screen_update));
screen.set_raw(25175000, 800, 0, 640, 525, 0, 480);
@@ -60,7 +103,7 @@ void jmfb_device::device_add_mconfig(machine_config &config)
// rom_region - device-specific ROM region
//-------------------------------------------------
-const tiny_rom_entry *jmfb_device::device_rom_region() const
+const tiny_rom_entry *nubus_48gc_device::device_rom_region() const
{
return ROM_NAME( gc48 );
}
@@ -71,6 +114,20 @@ const tiny_rom_entry *nubus_824gc_device::device_rom_region() const
}
//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor nubus_48gc_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( 48gc );
+}
+
+ioport_constructor nubus_824gc_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( 824gc );
+}
+
+//-------------------------------------------------
// palette_entries - entries in color palette
//-------------------------------------------------
@@ -88,26 +145,27 @@ uint32_t jmfb_device::palette_entries() const
// jmfb_device - constructor
//-------------------------------------------------
-jmfb_device::jmfb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is824) :
+jmfb_device::jmfb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_nubus_card_interface(mconfig, *this),
device_video_interface(mconfig, *this),
device_palette_interface(mconfig, *this),
- m_timer(nullptr), m_mode(0), m_vbl_disable(0), m_toggle(0), m_stride(0), m_base(0),
- m_count(0), m_clutoffs(0),
- m_xres(0), m_yres(0),
- m_is824(is824)
+ m_monitor(*this, "MONITOR"),
+ m_vram_view(*this, "vram"),
+ m_timer(nullptr),
+ m_vbl_disable(0), m_toggle(0), m_stride(0), m_base(0),
+ m_count(0), m_clutoffs(0), m_mode(0)
{
set_screen(*this, GC48_SCREEN_NAME);
}
nubus_48gc_device::nubus_48gc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- jmfb_device(mconfig, NUBUS_48GC, tag, owner, clock, false)
+ jmfb_device(mconfig, NUBUS_48GC, tag, owner, clock)
{
}
nubus_824gc_device::nubus_824gc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- jmfb_device(mconfig, NUBUS_824GC, tag, owner, clock, true)
+ jmfb_device(mconfig, NUBUS_824GC, tag, owner, clock)
{
}
@@ -117,20 +175,67 @@ nubus_824gc_device::nubus_824gc_device(const machine_config &mconfig, const char
void jmfb_device::device_start()
{
- uint32_t slotspace;
-
install_declaration_rom(GC48_ROM_REGION);
- slotspace = get_slotspace();
+ uint32_t const slotspace = get_slotspace();
-// printf("[JMFB %p] slotspace = %x\n", this, slotspace);
+ LOG("[JMFB %p] slotspace = %x\n", this, slotspace);
m_vram.resize(VRAM_SIZE / sizeof(uint32_t));
- install_bank(slotspace, slotspace+VRAM_SIZE-1, &m_vram[0]);
-
- nubus().install_device(slotspace+0x200000, slotspace+0x2003ff, read32s_delegate(*this, FUNC(jmfb_device::mac_48gc_r)), write32s_delegate(*this, FUNC(jmfb_device::mac_48gc_w)));
+ install_view(
+ slotspace, slotspace + VRAM_SIZE - 1,
+ m_vram_view);
+ m_vram_view[0].install_ram(
+ slotspace, slotspace + VRAM_SIZE - 1,
+ &m_vram[0]);
+ m_vram_view[1].install_readwrite_handler(
+ slotspace, slotspace + VRAM_SIZE - 1,
+ read32s_delegate(*this, FUNC(jmfb_device::rgb_unpack)), write32s_delegate(*this, FUNC(jmfb_device::rgb_pack)));
+ m_vram_view.select(0);
m_timer = timer_alloc(FUNC(jmfb_device::vbl_tick), this);
+
+ save_item(NAME(m_vram));
+ save_item(NAME(m_vbl_disable));
+ save_item(NAME(m_toggle));
+ save_item(NAME(m_stride));
+ save_item(NAME(m_base));
+ save_item(NAME(m_registers));
+ save_item(NAME(m_preload));
+ save_item(NAME(m_colors));
+ save_item(NAME(m_count));
+ save_item(NAME(m_clutoffs));
+ save_item(NAME(m_mode));
+ save_item(NAME(m_hactive));
+ save_item(NAME(m_hbporch));
+ save_item(NAME(m_hsync));
+ save_item(NAME(m_hfporch));
+ save_item(NAME(m_vactive));
+ save_item(NAME(m_vbporch));
+ save_item(NAME(m_vsync));
+ save_item(NAME(m_vfporch));
+ save_item(NAME(m_modulus));
+ save_item(NAME(m_pdiv));
+}
+
+void nubus_48gc_device::device_start()
+{
+ jmfb_device::device_start();
+
+ uint32_t const slotspace = get_slotspace();
+ nubus().install_device(
+ slotspace + 0x200000, slotspace + 0x2003ff,
+ read32s_delegate(*this, FUNC(nubus_48gc_device::jmfb_r)), write32s_delegate(*this, FUNC(nubus_48gc_device::mac_48gc_w)));
+}
+
+void nubus_824gc_device::device_start()
+{
+ jmfb_device::device_start();
+
+ uint32_t const slotspace = get_slotspace();
+ nubus().install_device(
+ slotspace + 0x200000, slotspace + 0x2003ff,
+ read32s_delegate(*this, FUNC(nubus_824gc_device::jmfb_r)), write32s_delegate(*this, FUNC(nubus_824gc_device::mac_824gc_w)));
}
//-------------------------------------------------
@@ -139,18 +244,30 @@ void jmfb_device::device_start()
void jmfb_device::device_reset()
{
+ m_vram_view.select(0);
+
+ std::fill(m_vram.begin(), m_vram.end(), 0);
+ m_vbl_disable = 1;
m_toggle = 0;
+ m_stride = 80 / 4;
+ m_base = 0;
+ m_preload = 256 - 8;
+
m_clutoffs = 0;
m_count = 0;
- m_vbl_disable = 1;
- m_stride = 80/4;
- m_base = 0;
- m_xres = 640;
- m_yres = 480;
m_mode = 0;
- std::fill(m_vram.begin(), m_vram.end(), 0);
- m_timer->adjust(screen().time_until_pos(479, 0), 0);
+ m_hactive = 286;
+ m_hbporch = 22;
+ m_hsync = 30;
+ m_hfporch = 18;
+
+ m_vactive = 1740;
+ m_vbporch = 78;
+ m_vsync = 6;
+ m_vfporch = 6;
+ m_modulus = 19;
+ m_pdiv = 1;
}
/***************************************************************************
@@ -171,17 +288,19 @@ TIMER_CALLBACK_MEMBER(jmfb_device::vbl_tick)
uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]) + (m_base << 5);
+ auto const screenbase = util::big_endian_cast<uint8_t const>(&m_vram[0]) + (m_base << 5);
+ int const xres = screen.visible_area().right();
switch (m_mode)
{
case 0: // 1bpp
- for (int y = 0; y < m_yres; y++)
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
+ auto const rowbase = screenbase + (y * m_stride * 4);
uint32_t *scanline = &bitmap.pix(y);
- for (int x = 0; x < m_xres/8; x++)
+ for (int x = 0; x <= xres/8; x++)
{
- uint8_t const pixels = vram8[(y * m_stride * 4) + x];
+ uint8_t const pixels = rowbase[x];
*scanline++ = pen_color(BIT(pixels, 7));
*scanline++ = pen_color(BIT(pixels, 6));
@@ -196,12 +315,13 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
break;
case 1: // 2bpp
- for (int y = 0; y < m_yres; y++)
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
+ auto const rowbase = screenbase + (y * m_stride * 4);
uint32_t *scanline = &bitmap.pix(y);
- for (int x = 0; x < m_xres/4; x++)
+ for (int x = 0; x <= xres/4; x++)
{
- uint8_t const pixels = vram8[(y * m_stride * 4) + x];
+ uint8_t const pixels = rowbase[x];
*scanline++ = pen_color(BIT(pixels, 6, 2));
*scanline++ = pen_color(BIT(pixels, 4, 2));
@@ -212,12 +332,13 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
break;
case 2: // 4 bpp
- for (int y = 0; y < m_yres; y++)
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
+ auto const rowbase = screenbase + (y * m_stride * 4);
uint32_t *scanline = &bitmap.pix(y);
- for (int x = 0; x < m_xres/2; x++)
+ for (int x = 0; x <= xres/2; x++)
{
- uint8_t const pixels = vram8[(y * m_stride * 4) + x];
+ uint8_t const pixels = rowbase[x];
*scanline++ = pen_color(BIT(pixels, 4, 4));
*scanline++ = pen_color(BIT(pixels, 0, 4));
@@ -226,24 +347,26 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
break;
case 3: // 8 bpp
- for (int y = 0; y < m_yres; y++)
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
+ auto const rowbase = screenbase + (y * m_stride * 4);
uint32_t *scanline = &bitmap.pix(y);
- for (int x = 0; x < m_xres; x++)
+ for (int x = 0; x <= xres; x++)
{
- uint8_t const pixels = vram8[(y * m_stride * 4) + x];
- *scanline++ = pen_color(pixels);
+ *scanline++ = pen_color(rowbase[x]);
}
}
break;
case 4: // 24 bpp
+ for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
- uint32_t const base = (m_base * 8 / 3) << 3;
- uint32_t const stride = m_stride * 8 / 3;
- for (int y = 0; y < m_yres; y++)
+ auto source = util::big_endian_cast<uint8_t const>(&m_vram[0]) + (m_base << 6) + (y * m_stride * 8);
+ uint32_t *scanline = &bitmap.pix(y);
+ for (int x = 0; x <= xres; x++)
{
- std::copy_n(&m_vram[base + (y * stride)], m_xres, &bitmap.pix(y));
+ *scanline++ = rgb_t(source[0], source[1], source[2]);
+ source += 3;
}
}
break;
@@ -252,12 +375,100 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
return 0;
}
-void jmfb_device::mac_48gc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+void jmfb_device::update_crtc()
+{
+ int const vtotal = (m_vactive + m_vbporch + m_vsync + m_vfporch) / 2;
+ int const height = m_vactive / 2;
+ if (vtotal && height)
+ {
+ int scale = 0;
+ switch (m_modulus) // FIXME: hacky - I'm missing something
+ {
+ case 15:
+ scale = -1;
+ break;
+ case 21:
+ scale = 0;
+ break;
+ case 19:
+ case 22:
+ scale = 1;
+ break;
+ default:
+ throw emu_fatalerror("%s: Unknown clock modulus %d\n", tag(), m_modulus);
+ }
+ int const divider = 256 - unsigned(m_preload);
+ int htotal = ((m_hactive + m_hbporch + m_hsync + m_hfporch + 8) << (m_pdiv + scale)) / divider;
+ int width = ((m_hactive + 2) << (m_pdiv + scale)) / divider;
+ switch (m_mode)
+ {
+ case 0: // 1bpp:
+ htotal <<= 3;
+ width <<= 3;
+ break;
+ case 1: // 2bpp:
+ htotal <<= 2;
+ width <<= 2;
+ break;
+ case 2: // 4bpp:
+ htotal <<= 1;
+ width <<= 1;
+ break;
+ case 3: // 8bpp:
+ break;
+ case 4: // 24bpp:
+ htotal >>= 2;
+ width >>= 2;
+ break;
+ }
+ rectangle const active(0, width - 1, 0, height - 1);
+ screen().configure(
+ htotal, vtotal,
+ active,
+ HZ_TO_ATTOSECONDS(75)); // FIXME: not correct in any sense
+
+ // TODO: work out how this is configured
+ m_timer->adjust(screen().time_until_pos(height - 1, 0), 0);
+ }
+}
+
+uint32_t jmfb_device::jmfb_r(offs_t offset, uint32_t mem_mask)
+{
+// printf("%s 48gc_r: @ %x, mask %08x\n", machine().describe_context().c_str(), offset, mem_mask);
+
+ switch (offset)
+ {
+ case 0x000/4:
+ return m_monitor->read() << 9;
+
+ case 0x1c0/4:
+ m_toggle ^= 0xffffffff;
+ return m_toggle;
+ }
+
+ return 0;
+}
+
+void jmfb_device::jmfb_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
COMBINE_DATA(&m_registers[offset & 0xff]);
switch (offset)
{
+ case 0x000/4: // control
+ LOG("%s: %04x to control\n", machine().describe_context(), data);
+ if (BIT(data, 7))
+ {
+ m_vram_view.select(BIT(data, 2)); // packed RGB mode
+ }
+ break;
+
+ case 0x004/4:
+ LOG("%s: %02x to preload\n", machine().describe_context(), data);
+ m_preload = data;
+ update_crtc();
+ break;
+
case 0x008/4: // base
LOG("%s: %x to base\n", machine().describe_context(), data);
m_base = data;
@@ -269,91 +480,170 @@ void jmfb_device::mac_48gc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
m_stride = data;
break;
- case 0x200/4: // DAC control
- LOG("%s: %08x to DAC control\n", machine().describe_context(), data);
- if (m_is824)
- {
- m_clutoffs = data & 0xff;
- }
- else
- {
- m_clutoffs = data >> 24;
- }
- m_count = 0;
+ case 0x10c/4: // active pixel cells - 2
+ LOG("%s: %d-2 to active cells\n", machine().describe_context(), data + 2);
+ m_hactive = data;
+ update_crtc();
break;
- case 0x204/4: // DAC data
- if (m_is824)
- {
- m_colors[m_count++] = data & 0xff;
- }
- else
- {
- m_colors[m_count++] = data >> 24;
- }
+ case 0x110/4: // horizontal back porch
+ LOG("%s: %d to horizontal back porch\n", machine().describe_context(), data + 2);
+ m_hbporch = data;
+ update_crtc();
+ break;
- if (m_count == 3)
- {
- LOG("%s: RAMDAC: color %d = %02x %02x %02x\n", machine().describe_context(), m_clutoffs, m_colors[0], m_colors[1], m_colors[2]);
- set_pen_color(m_clutoffs, rgb_t(m_colors[0], m_colors[1], m_colors[2]));
- m_clutoffs++;
- m_count = 0;
- }
+ case 0x114/4: // horizontal sync pulse
+ LOG("%s: %d-2 to horizontal sync pulse\n", machine().describe_context(), data + 2);
+ m_hsync = data;
+ update_crtc();
break;
- case 0x208/4: // mode control
- m_mode = (data>>3)&3;
- if (m_mode == 3) // this can be 8 or 24 bpp
- {
- // check pixel format for 24bpp
- if (m_is824)
- {
- if (data & 2)
- {
- m_mode = 4; // 24bpp
- }
- }
- else
- {
- if (((data>>5)&3) == 0)
- {
- m_mode = 4; // 24bpp
- }
- }
- }
-// printf("%02x to mode (m_mode = %d)\n", data, m_mode);
+ case 0x118/4: // horizontal front porch
+ LOG("%s: %d-2 to horizontal front porch\n", machine().describe_context(), data + 2);
+ m_hfporch = data;
+ update_crtc();
+ break;
+
+ case 0x124/4: // active lines * 2
+ LOG("%s: %d*2 to active lines\n", machine().describe_context(), data / 2);
+ m_vactive = data;
+ update_crtc();
+ break;
+
+ case 0x128/4: // vertical back porch * 2
+ LOG("%s: %d*2 to vertical back porch\n", machine().describe_context(), data / 2);
+ m_vbporch = data;
+ update_crtc();
+ break;
+
+ case 0x12c/4: // vertical sync width * 2
+ LOG("%s: %d*2 to vertical sync pulse width\n", machine().describe_context(), data / 2);
+ m_vsync = data;
+ update_crtc();
+ break;
+
+ case 0x130/4: // vertical front porch * 2
+ LOG("%s: %d*2 to vertical front porch\n", machine().describe_context(), data / 2);
+ m_vfporch = data;
+ update_crtc();
break;
- case 0x13c/4: // bit 1 = VBL disable (1=no interrupts)
+ case 0x13c/4: // bit 1 = VBL disable (1=no interrupts)
m_vbl_disable = (data & 2) ? 1 : 0;
break;
- case 0x148/4: // write 1 here to clear interrupt
+ case 0x148/4: // write 1 here to clear interrupt
if (data == 1)
{
lower_slot_irq();
}
break;
+ case 0x310/4:
+ case 0x314/4:
+ case 0x318/4:
+ m_modulus &= ~(0x0f << ((offset & 3) * 4));
+ m_modulus |= (data & 0x0f) << ((offset & 3) * 4);
+ LOG("%s: %d to modulus\n", machine().describe_context(), m_modulus);
+ if (offset == 0x318/4) // avoid bad intermediate values
+ update_crtc();
+ break;
+
+ case 0x324/4:
+ LOG("%s: 1<<%d to pixel cell divider\n", machine().describe_context(), data);
+ m_pdiv = data;
+ update_crtc();
+ break;
+
default:
break;
}
}
-uint32_t jmfb_device::mac_48gc_r(offs_t offset, uint32_t mem_mask)
+void nubus_48gc_device::mac_48gc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
-// printf("%s 48gc_r: @ %x, mask %08x\n", machine().describe_context().c_str(), offset, mem_mask);
+ switch (offset)
+ {
+ case 0x200/4: // DAC control
+ dac_ctrl_w(data >> 24);
+ break;
+
+ case 0x204/4: // DAC data
+ dac_data_w(data >> 24);
+ break;
+
+ case 0x208/4: // mode control
+ mode_w(data, !((data >> 5) & 0x3));
+ break;
+ default:
+ jmfb_w(offset, data, mem_mask);
+ }
+}
+
+void nubus_824gc_device::mac_824gc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
switch (offset)
{
- case 0:
- return 0x0c00; // sense 13" RGB for now
-// return 0x0000; // sense "RGB Kong" monitor
+ case 0x200/4: // DAC control
+ dac_ctrl_w(data & 0xff);
+ break;
- case 0x1c0/4:
- m_toggle ^= 0xffffffff;
- return m_toggle;
+ case 0x204/4: // DAC data
+ dac_data_w(data & 0xff);
+ break;
+
+ case 0x208/4: // mode control
+ mode_w(data, BIT(data, 1));
+ break;
+
+ default:
+ jmfb_w(offset, data, mem_mask);
+ }
+}
+
+void jmfb_device::dac_ctrl_w(uint8_t data)
+{
+ LOG("%s: %02x to DAC control\n", machine().describe_context(), data);
+ m_clutoffs = data;
+ m_count = 0;
+}
+
+void jmfb_device::dac_data_w(uint8_t data)
+{
+ m_colors[m_count++] = data;
+
+ if (m_count == 3)
+ {
+ LOG("%s: RAMDAC: color %d = %02x %02x %02x\n", machine().describe_context(), m_clutoffs, m_colors[0], m_colors[1], m_colors[2]);
+ set_pen_color(m_clutoffs, rgb_t(m_colors[0], m_colors[1], m_colors[2]));
+ m_clutoffs++;
+ m_count = 0;
}
+}
- return 0;
+void jmfb_device::mode_w(uint32_t data, bool rgb)
+{
+ m_mode = (data >> 3) & 0x3;
+ if ((m_mode == 3) & rgb) // mode 3 can be 8 or 24 bpp
+ m_mode = 4;
+ LOG("%s: %02x to mode (m_mode = %d)\n", machine().describe_context(), data, m_mode);
+ update_crtc();
+}
+
+uint32_t jmfb_device::rgb_unpack(offs_t offset, uint32_t mem_mask)
+{
+ auto const color = util::big_endian_cast<uint8_t const>(&m_vram[0]) + (offset * 3);
+ return (uint32_t(color[0]) << 16) | (uint32_t(color[1]) << 8) | uint32_t(color[2]);
+}
+
+void jmfb_device::rgb_pack(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ auto const color = util::big_endian_cast<uint8_t>(&m_vram[0]) + (offset * 3);
+ if (ACCESSING_BITS_16_23)
+ color[0] = uint8_t(data >> 16);
+ if (ACCESSING_BITS_8_15)
+ color[1] = uint8_t(data >> 8);
+ if (ACCESSING_BITS_0_7)
+ color[2] = uint8_t(data);
}
diff --git a/src/devices/bus/nubus/nubus_48gc.h b/src/devices/bus/nubus/nubus_48gc.h
index 78cf5f6d90e..8f69e115d4e 100644
--- a/src/devices/bus/nubus/nubus_48gc.h
+++ b/src/devices/bus/nubus/nubus_48gc.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:R. Belmont
+// copyright-holders:R. Belmont, Vas Crabb
#ifndef MAME_BUS_NUBUS_NUBUS_48GC_H
#define MAME_BUS_NUBUS_NUBUS_48GC_H
@@ -21,7 +21,7 @@ class jmfb_device :
{
protected:
// construction/destruction
- jmfb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is824);
+ jmfb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
@@ -29,40 +29,75 @@ protected:
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
- virtual const tiny_rom_entry *device_rom_region() const override;
// palette implementation
uint32_t palette_entries() const override;
TIMER_CALLBACK_MEMBER(vbl_tick);
-private:
- uint32_t mac_48gc_r(offs_t offset, uint32_t mem_mask = ~0);
- void mac_48gc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ uint32_t jmfb_r(offs_t offset, uint32_t mem_mask = ~0);
+ void jmfb_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+
+ void dac_ctrl_w(uint8_t data);
+ void dac_data_w(uint8_t data);
+ void mode_w(uint32_t data, bool rgb);
+private:
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ void update_crtc();
+
+ uint32_t rgb_unpack(offs_t offset, uint32_t mem_mask = ~0);
+ void rgb_pack(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ required_ioport m_monitor;
+ memory_view m_vram_view;
emu_timer *m_timer;
std::vector<uint32_t> m_vram;
- uint32_t m_mode, m_vbl_disable, m_toggle, m_stride, m_base;
- uint32_t m_colors[3], m_count, m_clutoffs;
+ uint32_t m_vbl_disable, m_toggle, m_stride, m_base;
uint32_t m_registers[0x100];
- int m_xres, m_yres;
- const bool m_is824;
+ uint8_t m_preload;
+
+ uint8_t m_colors[3], m_count, m_clutoffs, m_mode;
+
+ uint16_t m_hactive, m_hbporch, m_hsync, m_hfporch;
+ uint16_t m_vactive, m_vbporch, m_vsync, m_vfporch;
+ uint16_t m_modulus;
+ uint8_t m_pdiv;
};
class nubus_48gc_device : public jmfb_device
{
public:
nubus_48gc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+ // optional information overrides
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ void mac_48gc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
};
class nubus_824gc_device : public jmfb_device
{
public:
nubus_824gc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+ // optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ void mac_824gc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
};
// device type definition
diff --git a/src/devices/bus/nubus/nubus_spec8.cpp b/src/devices/bus/nubus/nubus_spec8.cpp
index 1135a3bd442..ee3549a2572 100644
--- a/src/devices/bus/nubus/nubus_spec8.cpp
+++ b/src/devices/bus/nubus/nubus_spec8.cpp
@@ -21,17 +21,34 @@
Configuration settings, you need to zap the PRAM before it will be
recognised properly.
+ Set breakpoint at 0x2d1e on Mac II with Ver. 1.3 card in slot 9 to catch
+ user oscillator measurement. See the measured value in D0.b when
+ PC = 0x2d6c.
+
+ Expected:
+ 2- 5 57.28 MHz
+ 6-19 bad
+ 20-22 14.32 MHz
+ 23-24 15.67 MHz
+ 25-27 17.73 MHz
+ 27- bad
+
+ Measured:
+ 14.32 MHz 20
+ 15.67 MHz 23
+ 17.73 MHz 26
+ 57.28 MHz 5
+
TODO:
* Having no oscillator installed at Y1 is not emulated.
* Interlaced modes are not understood.
- * There are lines of garbage at the bottom of the screen in some high-
- resolution modes (bottom of the virtual desktop if virtual desktop is
- enabled).
***************************************************************************/
#include "emu.h"
#include "nubus_spec8.h"
+
+#include "layout/generic.h"
#include "screen.h"
#include <algorithm>
@@ -40,10 +57,10 @@
#include "logmacro.h"
-#define SPEC8S3_SCREEN_NAME "spec8s3_screen"
+#define SPEC8S3_SCREEN_NAME "screen"
#define SPEC8S3_ROM_REGION "spec8s3_rom"
-#define VRAM_SIZE (0xc0000) // 768k of VRAM for 1024x768 @ 8 bit
+#define VRAM_SIZE (0x10'0000) // 1M of VRAM for 1024x768 @ 8 bit
static INPUT_PORTS_START( spec8s3 )
@@ -79,9 +96,12 @@ DEFINE_DEVICE_TYPE(NUBUS_SPEC8S3, nubus_spec8s3_device, "nb_sp8s3", "SuperMac Sp
void nubus_spec8s3_device::device_add_mconfig(machine_config &config)
{
+ config.set_default_layout(layout_monitors);
+
screen_device &screen(SCREEN(config, SPEC8S3_SCREEN_NAME, SCREEN_TYPE_RASTER));
screen.set_screen_update(FUNC(nubus_spec8s3_device::screen_update));
screen.set_raw(80.000_MHz_XTAL, 332*4, 64*4, 320*4, 804, 33, 801);
+ screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
}
//-------------------------------------------------
@@ -496,38 +516,10 @@ uint32_t nubus_spec8s3_device::spec8s3_r(offs_t offset, uint32_t mem_mask)
case 0x382c:
case 0x382e:
{
- /*
- * Set breakpoint at 0x2d1e on Mac II with Ver. 1.3 card in
- * slot 9 to catch user oscillator measurement. See the
- * measured value in D0.b when PC = 0x2d6c.
- *
- * Expected:
- * 2- 5 57.28 MHz
- * 6-19 bad
- * 20-22 14.32 MHz
- * 23-24 15.67 MHz
- * 25-27 17.73 MHz
- * 27- bad
- *
- * Measured:
- * 14.32 MHz 20
- * 15.67 MHz 23
- * 17.73 MHz 26
- * 57.28 MHz 5
- */
- int vpos;
+ // hack for interlace modes because screen_device doesn't support them
+ int vpos = screen().vpos();
if (m_interlace)
- {
- // hack for interlace modes because screen_device doesn't support them
- vpos = screen().vpos() - (m_crtc.v_sync() * 2);
- if (vpos >= (m_crtc.v_total() * 2))
- vpos -= m_crtc.v_total() * 2;
vpos /= 2;
- }
- else
- {
- vpos = m_crtc.v_pos(screen());
- }
return ~((vpos >> (BIT(offset, 1) ? 8 : 0)) & 0xff);
}
diff --git a/src/devices/bus/nubus/nubus_specpdq.cpp b/src/devices/bus/nubus/nubus_specpdq.cpp
index 651d7b19023..62c1aec9e29 100644
--- a/src/devices/bus/nubus/nubus_specpdq.cpp
+++ b/src/devices/bus/nubus/nubus_specpdq.cpp
@@ -21,10 +21,18 @@
There is 256 bytes of pattern RAM arranged as 32 pixels horizontally by
8 vertically.
+ TODO:
+ * Having no alternate oscillator installed is not emulated.
+ * Work out how active line length is configured.
+ * Alternate oscillator calibration is currently failing. Fixing this
+ probably requires a complete cycle-accurate Mac II.
+
***************************************************************************/
#include "emu.h"
#include "nubus_specpdq.h"
+
+#include "layout/generic.h"
#include "screen.h"
#include <algorithm>
@@ -33,10 +41,10 @@
#include "logmacro.h"
-#define SPECPDQ_SCREEN_NAME "specpdq_screen"
+#define SPECPDQ_SCREEN_NAME "screen"
#define SPECPDQ_ROM_REGION "specpdq_rom"
-#define VRAM_SIZE (0x400000)
+#define VRAM_SIZE (0x40'0000)
static INPUT_PORTS_START( specpdq )
@@ -65,9 +73,12 @@ DEFINE_DEVICE_TYPE(NUBUS_SPECPDQ, nubus_specpdq_device, "nb_spdq", "SuperMac Spe
void nubus_specpdq_device::device_add_mconfig(machine_config &config)
{
+ config.set_default_layout(layout_monitors);
+
screen_device &screen(SCREEN(config, SPECPDQ_SCREEN_NAME, SCREEN_TYPE_RASTER));
screen.set_screen_update(FUNC(nubus_specpdq_device::screen_update));
screen.set_raw(100.000_MHz_XTAL, 1'456, 108, 1'260, 915, 39, 909);
+ screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
}
//-------------------------------------------------
@@ -118,9 +129,7 @@ nubus_specpdq_device::nubus_specpdq_device(const machine_config &mconfig, device
device_palette_interface(mconfig, *this),
m_userosc(*this, "USEROSC"),
m_timer(nullptr),
- m_mode(0), m_vbl_disable(0),
- m_count(0), m_clutoffs(0),
- m_width(0), m_height(0), m_patofsx(0), m_patofsy(0), m_vram_addr(0), m_vram_src(0)
+ m_mode(0)
{
set_screen(*this, SPECPDQ_SCREEN_NAME);
}
@@ -155,14 +164,14 @@ void nubus_specpdq_device::device_start()
save_item(NAME(m_vint));
save_item(NAME(m_hdelay));
save_item(NAME(m_osc));
+ save_item(NAME(m_blit_stride));
+ save_item(NAME(m_blit_src));
+ save_item(NAME(m_blit_dst));
+ save_item(NAME(m_blit_width));
+ save_item(NAME(m_blit_height));
+ save_item(NAME(m_blit_patoffs));
+ save_item(NAME(m_blit_pat));
save_item(NAME(m_7xxxxx_regs));
- save_item(NAME(m_width));
- save_item(NAME(m_height));
- save_item(NAME(m_patofsx));
- save_item(NAME(m_patofsy));
- save_item(NAME(m_vram_addr));
- save_item(NAME(m_vram_src));
- save_item(NAME(m_pattern));
}
//-------------------------------------------------
@@ -180,18 +189,21 @@ void nubus_specpdq_device::device_reset()
std::fill(std::begin(m_colors), std::end(m_colors), 0);
m_count = 0;
m_clutoffs = 0;
- m_stride = 512 / 4;
+
+ m_stride = 0;
m_vint = 0;
m_hdelay = 0;
m_osc = 0;
+ m_blit_stride = 0;
+ m_blit_src = 0;
+ m_blit_dst = 0;
+ m_blit_width = 0;
+ m_blit_height = 0;
+ m_blit_patoffs = 0;
+ std::fill(std::begin(m_blit_pat), std::end(m_blit_pat), 0);
+
std::fill(std::begin(m_7xxxxx_regs), std::end(m_7xxxxx_regs), 0);
- m_width = 0;
- m_height = 0;
- m_patofsx = 0;
- m_patofsy = 0;
- m_vram_addr = 0;
- m_vram_src = 0;
}
@@ -202,10 +214,7 @@ TIMER_CALLBACK_MEMBER(nubus_specpdq_device::vbl_tick)
raise_slot_irq();
}
- m_timer->adjust(
- screen().time_until_pos(
- m_vint + m_crtc.v_start() - 1,
- m_crtc.h_total(16) - m_crtc.h_sync(16)));
+ m_timer->adjust(screen().time_until_pos(m_vint));
}
/***************************************************************************
@@ -272,10 +281,7 @@ void nubus_specpdq_device::update_crtc()
active,
m_crtc.frame_time(16, oscillator));
- m_timer->adjust(
- screen().time_until_pos(
- m_vint + m_crtc.v_start() - 1,
- m_crtc.h_total(16) - m_crtc.h_sync(16)));
+ m_timer->adjust(screen().time_until_pos(m_vint + m_crtc.v_start() - 1));
}
}
@@ -410,7 +416,7 @@ void nubus_specpdq_device::specpdq_w(offs_t offset, uint32_t data, uint32_t mem_
else if ((offset >= 0x181000) && (offset <= 0x18103f))
{
// 256 pixels worth at 8 bpp
- m_pattern[offset & 0x3f] = ~data;
+ m_blit_pat[offset & 0x3f] = ~data;
}
else switch (offset)
{
@@ -424,7 +430,6 @@ void nubus_specpdq_device::specpdq_w(offs_t offset, uint32_t data, uint32_t mem_
case 0xc0054:
case 0xc0056:
- // same value written here and to c007a:c0078
m_stride &= BIT(offset, 1) ? 0x00ff : 0xff00;
m_stride |= (~data & 0xff000000) >> (BIT(offset, 1) ? 16 : 24);
LOG("%s: %u to stride\n", machine().describe_context(), m_stride);
@@ -451,6 +456,13 @@ void nubus_specpdq_device::specpdq_w(offs_t offset, uint32_t data, uint32_t mem_
update_crtc();
break;
+ case 0xc0078:
+ case 0xc007a:
+ m_blit_stride &= BIT(offset, 1) ? 0x00ff : 0xff00;
+ m_blit_stride |= (~data & 0xff000000) >> (BIT(offset, 1) ? 16 : 24);
+ LOG("%s: %u to blitter stride\n", machine().describe_context(), m_blit_stride);
+ break;
+
case 0x120000: // DAC address
LOG("%s: %08x to DAC control\n", machine().describe_context(), data);
m_clutoffs = ~data & 0xff;
@@ -496,7 +508,6 @@ void nubus_specpdq_device::specpdq_w(offs_t offset, uint32_t data, uint32_t mem_
m_shiftreg.write_control(*this, data);
break;
- // blitter control
case 0x182006:
data = ~data;
LOG("%08x (%d) to blitter ctrl 1 %s rectangle\n", data, data, machine().describe_context());
@@ -505,55 +516,18 @@ void nubus_specpdq_device::specpdq_w(offs_t offset, uint32_t data, uint32_t mem_
case 0x182007:
data = ~data;
LOG("%s: %08x to blitter command\n", machine().describe_context(), data);
-
- if (data == 2)
- {
- // fill rectangle
- auto const source = util::big_endian_cast<uint8_t const>(m_pattern);
- auto dest = util::big_endian_cast<uint8_t>(&m_vram[0]) + m_vram_addr;
- uint32_t const patofsx = (m_vram_addr & 0x3) + m_patofsx;
- LOG("Fill rectangle with %02x %02x %02x %02x, adr %x (%d, %d) width %d height %d delta %d %d\n", source[0], source[1], source[2], source[3], m_vram_addr, m_vram_addr % 1152, m_vram_addr / 1152, m_width, m_height, m_patofsx, m_patofsy);
- for (int y = 0; y <= m_height; y++)
- {
- for (int x = 0; x < m_width; x++)
- {
- dest[x] = source[(((m_patofsy + y) & 0x7) << 5) + ((patofsx + x) & 0x1f)];
- }
- dest += m_stride * 4;
- }
- }
- else if (data == 0x100)
- {
- LOG("Copy rectangle forwards, width %d height %d dst %x (%d, %d) src %x (%d, %d)\n", m_width, m_height, m_vram_addr, m_vram_addr % 1152, m_vram_addr / 1152, m_vram_src, m_vram_src % 1152, m_vram_src / 1152);
- auto source = util::big_endian_cast<uint8_t const>(&m_vram[0]) + m_vram_src;
- auto dest = util::big_endian_cast<uint8_t>(&m_vram[0]) + m_vram_addr;
- for (int y = 0; y <= m_height; y++)
- {
- for (int x = 0; x < m_width; x++)
- {
- dest[x] = source[x];
- }
- source += m_stride * 4;
- dest += m_stride * 4;
- }
- }
- else if (data == 0x101)
- {
- LOG("Copy rectangle backwards, width %d height %d dst %x (%d, %d) src %x (%d, %d)\n", m_width, m_height, m_vram_addr, m_vram_addr % 1152, m_vram_addr / 1152, m_vram_src, m_vram_src % 1152, m_vram_src / 1152);
- auto source = util::big_endian_cast<uint8_t const>(&m_vram[0]) + m_vram_src;
- auto dest = util::big_endian_cast<uint8_t>(&m_vram[0]) + m_vram_addr;
- for (int y = 0; y <= m_height; y++)
- {
- for (int x = 0; x < m_width; x++)
- {
- dest[-x] = source[-x];
- }
- source -= m_stride * 4;
- dest -= m_stride * 4;
- }
- }
- else
+ switch (data)
{
+ case 0x002:
+ blitter_pattern_fill();
+ break;
+ case 0x100:
+ blitter_copy_forward();
+ break;
+ case 0x101:
+ blitter_copy_backward();
+ break;
+ default:
logerror("Unknown blitter command %08x\n", data);
}
break;
@@ -561,32 +535,31 @@ void nubus_specpdq_device::specpdq_w(offs_t offset, uint32_t data, uint32_t mem_
case 0x182008:
data = ~data;
LOG("%s: %08x (%d) to blitter ctrl 2 rectangle\n", machine().describe_context(), data, data);
- m_patofsx = BIT(data, 0, 3);
- m_patofsy = BIT(data, 3, 3);
+ m_blit_patoffs = (data >> 3) & 0x1fff;
break;
case 0x182009:
data = ~data;
LOG("%s: %08x to blitter destination\n", machine().describe_context(), data);
- m_vram_addr = data >> 2;
+ m_blit_dst = (data >> 2) & 0x3fffff;
break;
case 0x18200a:
data = ~data;
LOG("%s: %08x to blitter source\n", machine().describe_context(), data);
- m_vram_src = data >> 2;
+ m_blit_src = (data >> 2) & 0x3fffff;
break;
case 0x18200b:
data = ~data;
LOG("%s: %08x (%d) to blitter height\n", machine().describe_context(), data, data);
- m_height = data & 0xffff;
+ m_blit_height = data;
break;
case 0x18200e:
data = ~data;
LOG("%s: %08x (%d) to blitter width\n", machine().describe_context(), data, data);
- m_width = data;
+ m_blit_width = data;
break;
default:
@@ -614,7 +587,7 @@ uint32_t nubus_specpdq_device::specpdq_r(offs_t offset, uint32_t mem_mask)
* 57.28 MHz 1 detected as 55.00 MHz
* 64.00 MHz 9 detected as 57.28 MHz
*/
- return ~((u32(m_crtc.v_pos(screen())) << (BIT(offset, 1) ? 16 : 24)) & 0xff000000);
+ return ~((u32(screen().vpos()) << (BIT(offset, 1) ? 16 : 24)) & 0xff000000);
}
if (offset >= 0xc0000 && offset < 0x100000)
@@ -635,3 +608,58 @@ uint32_t nubus_specpdq_device::vram_r(offs_t offset, uint32_t mem_mask)
{
return ~m_vram[offset];
}
+
+void nubus_specpdq_device::blitter_pattern_fill()
+{
+ auto const source = util::big_endian_cast<uint8_t const>(m_blit_pat);
+ auto const dest = util::big_endian_cast<uint8_t>(&m_vram[0]);
+ uint32_t const patofsx = m_blit_dst & 0x3;
+ uint32_t const stride = m_blit_stride * 4;
+ LOG("Fill rectangle with %02x %02x %02x %02x, adr %x (%d, %d) width %d height %d delta %d\n",
+ source[0], source[1], source[2], source[3],
+ m_blit_dst, m_blit_dst % (m_blit_stride * 4), m_blit_dst / (m_blit_stride * 4),
+ m_blit_width, m_blit_height, m_blit_patoffs);
+ for (int y = 0; y <= m_blit_height; y++)
+ {
+ for (int x = 0; x < m_blit_width; x++)
+ {
+ dest[(m_blit_dst + (y * stride) + x) & (VRAM_SIZE - 1)] = source[(((m_blit_patoffs + y) & 0x7) << 5) | ((patofsx + x) & 0x1f)];
+ }
+ }
+}
+
+void nubus_specpdq_device::blitter_copy_forward()
+{
+ LOG("Copy rectangle forwards, width %d height %d dst %x (%d, %d) src %x (%d, %d)\n",
+ m_blit_width, m_blit_height,
+ m_blit_dst, m_blit_dst % (m_blit_stride * 4), m_blit_dst / (m_blit_stride * 4),
+ m_blit_src, m_blit_src % (m_blit_stride * 4), m_blit_src / (m_blit_stride * 4));
+ auto const source = util::big_endian_cast<uint8_t const>(&m_vram[0]);
+ auto const dest = util::big_endian_cast<uint8_t>(&m_vram[0]);
+ uint32_t const stride = m_blit_stride * 4;
+ for (int y = 0; y <= m_blit_height; y++)
+ {
+ for (int x = 0; x < m_blit_width; x++)
+ {
+ dest[(m_blit_dst + (y * stride) + x) & (VRAM_SIZE - 1)] = source[(m_blit_src + (y * stride) + x) & (VRAM_SIZE - 1)];
+ }
+ }
+}
+
+void nubus_specpdq_device::blitter_copy_backward()
+{
+ LOG("Copy rectangle backwards, width %d height %d dst %x (%d, %d) src %x (%d, %d)\n",
+ m_blit_width, m_blit_height,
+ m_blit_dst, m_blit_dst % (m_blit_stride * 4), m_blit_dst / (m_blit_stride * 4),
+ m_blit_src, m_blit_src % (m_blit_stride * 4), m_blit_src / (m_blit_stride * 4));
+ auto const source = util::big_endian_cast<uint8_t const>(&m_vram[0]);
+ auto const dest = util::big_endian_cast<uint8_t>(&m_vram[0]);
+ uint32_t const stride = m_blit_stride * 4;
+ for (int y = 0; y <= m_blit_height; y++)
+ {
+ for (int x = 0; x < m_blit_width; x++)
+ {
+ dest[(m_blit_dst - (y * stride) - x) & (VRAM_SIZE - 1)] = source[(m_blit_src - (y * stride) - x) & (VRAM_SIZE - 1)];
+ }
+ }
+}
diff --git a/src/devices/bus/nubus/nubus_specpdq.h b/src/devices/bus/nubus/nubus_specpdq.h
index 53c3b9feb30..62b24c062b5 100644
--- a/src/devices/bus/nubus/nubus_specpdq.h
+++ b/src/devices/bus/nubus/nubus_specpdq.h
@@ -46,6 +46,10 @@ private:
uint32_t vram_r(offs_t offset, uint32_t mem_mask = ~0);
void vram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ void blitter_pattern_fill();
+ void blitter_copy_forward();
+ void blitter_copy_backward();
+
void update_crtc();
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -65,10 +69,13 @@ private:
uint8_t m_hdelay;
uint8_t m_osc;
- uint32_t m_7xxxxx_regs[0x100000/4];
- uint32_t m_width, m_height, m_patofsx, m_patofsy;
- uint32_t m_vram_addr, m_vram_src;
- uint32_t m_pattern[64];
+ uint16_t m_blit_stride;
+ uint32_t m_blit_src, m_blit_dst;
+ uint32_t m_blit_width, m_blit_height;
+ uint8_t m_blit_patoffs;
+ uint32_t m_blit_pat[64];
+
+ uint32_t m_7xxxxx_regs[0x100000 / 4];
};
diff --git a/src/devices/bus/nubus/supermac.cpp b/src/devices/bus/nubus/supermac.cpp
index af7ba20e9c1..c8f00e81003 100644
--- a/src/devices/bus/nubus/supermac.cpp
+++ b/src/devices/bus/nubus/supermac.cpp
@@ -131,13 +131,6 @@ bool supermac_spec_crtc::valid(device_t &device) const
}
-int supermac_spec_crtc::v_pos(screen_device const &screen) const
-{
- int const vpos = screen.vpos() + m_vsync + 1;
- return (vpos <= m_vtotal) ? vpos : (vpos - m_vtotal - 1);
-}
-
-
void supermac_spec_shift_reg::register_save(device_t &device)
{
device.save_item(NAME(m_shift_data));
diff --git a/src/devices/bus/nubus/supermac.h b/src/devices/bus/nubus/supermac.h
index d656eb6c4af..9fb4c93f326 100644
--- a/src/devices/bus/nubus/supermac.h
+++ b/src/devices/bus/nubus/supermac.h
@@ -24,9 +24,9 @@ public:
uint32_t h_active(uint32_t scale) const noexcept
{ return (m_hend - m_hstart) * scale; }
uint32_t h_start(uint32_t scale) const noexcept
- { return (m_hstart - m_hsync) * scale; }
+ { return (m_hstart + 1) * scale; }
uint32_t h_end(uint32_t scale) const noexcept
- { return (m_hend - m_hsync) * scale; }
+ { return (m_hend + 1) * scale; }
uint16_t v_sync() const noexcept
{ return m_vsync + 1; }
@@ -35,15 +35,13 @@ public:
uint32_t v_active() const noexcept
{ return (m_vend - m_vstart); }
uint16_t v_start() const noexcept
- { return m_vstart - m_vsync; }
+ { return m_vstart + 1; }
uint16_t v_end() const noexcept
- { return m_vend - m_vsync; }
+ { return m_vend + 1; }
attoseconds_t frame_time(uint32_t scale, XTAL const &osc) const noexcept
{ return attotime::from_ticks((m_htotal + 1) * (m_vtotal + 1) * scale, osc).attoseconds(); }
- int v_pos(screen_device const &screen) const;
-
private:
uint16_t m_hsync, m_hstart, m_hend, m_htotal;
uint16_t m_vsync, m_vstart, m_vend, m_vtotal;
diff --git a/src/emu/layout/generic.h b/src/emu/layout/generic.h
index 502e38e0765..4249c3ef68b 100644
--- a/src/emu/layout/generic.h
+++ b/src/emu/layout/generic.h
@@ -21,6 +21,9 @@
// no screens layouts
extern const internal_layout layout_noscreens; // for screenless systems
+// single screen layouts
+extern const internal_layout layout_monitors; // common monitor aspect ratios
+
// dual screen layouts
extern const internal_layout layout_dualhsxs; // dual 4:3 screens side-by-side
extern const internal_layout layout_dualhovu; // dual 4:3 screens above and below
diff --git a/src/emu/layout/monitors.lay b/src/emu/layout/monitors.lay
new file mode 100644
index 00000000000..c6391b16a12
--- /dev/null
+++ b/src/emu/layout/monitors.lay
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+license:CC0
+-->
+<mamelayout version="2">
+ <view name="4:3 Standard">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="4" bottom="3" />
+ </screen>
+ </view>
+ <view name="3:4 Portrait">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="3" bottom="4" />
+ </screen>
+ </view>
+ <view name="5:4 Two-Page">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="5" bottom="4" />
+ </screen>
+ </view>
+ <view name="16:9 Widescreen">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="16" bottom="9" />
+ </screen>
+ </view>
+ <view name="21:9 UltraWide">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="21" bottom="9" />
+ </screen>
+ </view>
+ <view name="32:9 Super UltraWide">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="32" bottom="9" />
+ </screen>
+ </view>
+ <view name="1:1 Air Traffic Control">
+ <screen tag="screen">
+ <bounds left="0" top="0" right="32" bottom="9" />
+ </screen>
+ </view>
+</mamelayout>
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index ffe680fa625..c0a9b040b50 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -59,6 +59,9 @@
// screenless layouts
#include "noscreens.lh"
+// single screen layouts
+#include "monitors.lh"
+
// dual screen layouts
#include "dualhsxs.lh"
#include "dualhovu.lh"
diff --git a/src/mame/drivers/mac.cpp b/src/mame/drivers/mac.cpp
index 3cdf7aaace7..e22f94a3105 100644
--- a/src/mame/drivers/mac.cpp
+++ b/src/mame/drivers/mac.cpp
@@ -14,14 +14,15 @@
#include "emu.h"
#include "includes/mac.h"
+#include "machine/macadb.h"
+
+#include "bus/nscsi/devices.h"
#include "cpu/m68000/m68000.h"
#include "cpu/m6805/m6805.h"
-#include "formats/ap_dsk35.h"
#include "machine/applepic.h"
#include "machine/iwm.h"
#include "machine/swim1.h"
#include "machine/swim2.h"
-#include "bus/nscsi/devices.h"
// NuBus and 030/040 PDS cards
#include "bus/nubus/nubus_48gc.h"
@@ -44,10 +45,12 @@
#include "bus/nubus/pds30_30hr.h"
#include "bus/nubus/pds30_mc30.h"
-#include "machine/macadb.h"
+#include "layout/generic.h"
#include "softlist_dev.h"
#include "speaker.h"
-#include "mac.lh"
+
+#include "formats/ap_dsk35.h"
+
#define C32M (31.3344_MHz_XTAL)
#define C15M (C32M/2)
@@ -928,7 +931,7 @@ void mac_state::maclc(machine_config &config, bool cpu, bool egret, asc_device::
m_screen->set_visarea(0, 640-1, 0, 480-1);
m_screen->set_screen_update(FUNC(mac_state::screen_update_macv8));
m_screen->screen_vblank().set(FUNC(mac_state::mac_rbv_vbl));
- config.set_default_layout(layout_mac);
+ config.set_default_layout(layout_monitors);
m_ram->set_default_size("2M");
m_ram->set_extra_options("4M,6M,8M,10M");
@@ -1134,7 +1137,7 @@ void mac_state::maciici(machine_config &config)
m_screen->set_visarea(0, 640-1, 0, 480-1);
m_screen->set_screen_update(FUNC(mac_state::screen_update_macrbv));
m_screen->screen_vblank().set(FUNC(mac_state::mac_rbv_vbl));
- config.set_default_layout(layout_mac);
+ config.set_default_layout(layout_monitors);
/* internal ram */
m_ram->set_default_size("2M");
@@ -1158,7 +1161,7 @@ void mac_state::maciisi(machine_config &config)
m_screen->set_visarea(0, 640-1, 0, 480-1);
m_screen->set_screen_update(FUNC(mac_state::screen_update_macrbv));
m_screen->screen_vblank().set(FUNC(mac_state::mac_rbv_vbl));
- config.set_default_layout(layout_mac);
+ config.set_default_layout(layout_monitors);
m_ram->set_default_size("2M");
m_ram->set_extra_options("4M,8M,16M,32M,48M,64M,128M");
diff --git a/src/mame/drivers/macquadra700.cpp b/src/mame/drivers/macquadra700.cpp
index d9b0ea00c91..84d2c23e2d2 100644
--- a/src/mame/drivers/macquadra700.cpp
+++ b/src/mame/drivers/macquadra700.cpp
@@ -53,6 +53,9 @@
#define C15M (C7M*2)
#define C32M (C15M*2)
+
+namespace {
+
class macquadra_state : public driver_device
{
public:
@@ -142,9 +145,9 @@ private:
int m_adb_irq_pending = 0;
DECLARE_WRITE_LINE_MEMBER(irq_539x_1_w);
- DECLARE_WRITE_LINE_MEMBER(irq_539x_2_w);
+ [[maybe_unused]] DECLARE_WRITE_LINE_MEMBER(irq_539x_2_w);
DECLARE_WRITE_LINE_MEMBER(drq_539x_1_w);
- DECLARE_WRITE_LINE_MEMBER(drq_539x_2_w);
+ [[maybe_unused]] DECLARE_WRITE_LINE_MEMBER(drq_539x_2_w);
floppy_image_device *m_cur_floppy = nullptr;
int m_hdsel = 0;
@@ -1053,4 +1056,6 @@ ROM_START( macqd700 )
ROM_LOAD( "420dbff3.rom", 0x000000, 0x100000, CRC(88ea2081) SHA1(7a8ee468d16e64f2ad10cb8d1a45e6f07cc9e212) )
ROM_END
+} // anonymous namespace
+
COMP( 1991, macqd700, 0, 0, macqd700, macadb, macquadra_state, init_macqd700, "Apple Computer", "Macintosh Quadra 700", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE)
diff --git a/src/mame/layout/mac.lay b/src/mame/layout/mac.lay
deleted file mode 100644
index 94eb2ff41d3..00000000000
--- a/src/mame/layout/mac.lay
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<!--
-license:CC0
--->
-<mamelayout version="2">
- <view name="Landscape (4:3)">
- <screen index="0">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
- <view name="Portrait (3:4)">
- <screen index="0">
- <bounds left="0" top="0" right="3" bottom="4" />
- </screen>
- </view>
-</mamelayout>