diff options
-rw-r--r-- | scripts/src/emu.lua | 6 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus.cpp | 11 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus.h | 2 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus_48gc.cpp | 496 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus_48gc.h | 55 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus_spec8.cpp | 62 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus_specpdq.cpp | 198 | ||||
-rw-r--r-- | src/devices/bus/nubus/nubus_specpdq.h | 15 | ||||
-rw-r--r-- | src/devices/bus/nubus/supermac.cpp | 7 | ||||
-rw-r--r-- | src/devices/bus/nubus/supermac.h | 10 | ||||
-rw-r--r-- | src/emu/layout/generic.h | 3 | ||||
-rw-r--r-- | src/emu/layout/monitors.lay | 41 | ||||
-rw-r--r-- | src/emu/rendlay.cpp | 3 | ||||
-rw-r--r-- | src/mame/drivers/mac.cpp | 17 | ||||
-rw-r--r-- | src/mame/drivers/macquadra700.cpp | 9 | ||||
-rw-r--r-- | src/mame/layout/mac.lay | 16 |
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> |