summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2022-06-24 08:27:32 +1000
committer Vas Crabb <vas@vastheman.com>2022-06-24 08:27:32 +1000
commitae46009f50f2edcf52448858c442b24ba75a2145 (patch)
tree39ef6818ef301795270c017ca2b60291e5ce7158 /src/devices
parentaf97d42dd31cdd7da154108562bb9d08043757b5 (diff)
bus/nubus: Properly generate pixel clocks for the Macintosh Display Cards.
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/bus/nubus/nubus_48gc.cpp43
-rw-r--r--src/devices/bus/nubus/nubus_48gc.h1
2 files changed, 28 insertions, 16 deletions
diff --git a/src/devices/bus/nubus/nubus_48gc.cpp b/src/devices/bus/nubus/nubus_48gc.cpp
index fefaf8ad35d..899910b52c6 100644
--- a/src/devices/bus/nubus/nubus_48gc.cpp
+++ b/src/devices/bus/nubus/nubus_48gc.cpp
@@ -7,8 +7,6 @@
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.
@@ -92,11 +90,9 @@ void jmfb_device::device_add_mconfig(machine_config &config)
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);
-// screen.set_size(1152, 870);
-// screen.set_visarea(0, 1152-1, 0, 870-1);
-// screen.set_refresh_hz(75);
-// screen.set_vblank_time(ATTOSECONDS_IN_USEC(1260));
+ screen.set_raw(20_MHz_XTAL / 21 * 127 / 4, 864, 0, 640, 525, 0, 480);
+ //screen.set_raw(20_MHz_XTAL / 19 * 190 / 2, 1'456, 0, 1'152, 915, 0, 870);
+ screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
}
//-------------------------------------------------
@@ -214,6 +210,7 @@ void jmfb_device::device_start()
save_item(NAME(m_vbporch));
save_item(NAME(m_vsync));
save_item(NAME(m_vfporch));
+ save_item(NAME(m_multiplier));
save_item(NAME(m_modulus));
save_item(NAME(m_pdiv));
}
@@ -266,6 +263,7 @@ void jmfb_device::device_reset()
m_vbporch = 78;
m_vsync = 6;
m_vfporch = 6;
+ m_multiplier = 190;
m_modulus = 19;
m_pdiv = 1;
}
@@ -283,7 +281,8 @@ TIMER_CALLBACK_MEMBER(jmfb_device::vbl_tick)
raise_slot_irq();
}
- m_timer->adjust(screen().time_until_pos(479, 0), 0);
+ // TODO: determine correct timing for vertical blanking interrupt
+ m_timer->adjust(screen().time_until_pos(screen().visible_area().bottom()));
}
uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -379,10 +378,12 @@ 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)
+ if (vtotal && height && m_multiplier)
{
+ // FIXME: where does this multiply/divide by 2 come from?
+ // This is obviously not correct by any definition.
int scale = 0;
- switch (m_modulus) // FIXME: hacky - I'm missing something
+ switch (m_modulus)
{
case 15:
scale = -1;
@@ -421,14 +422,14 @@ void jmfb_device::update_crtc()
width >>= 2;
break;
}
- rectangle const active(0, width - 1, 0, height - 1);
+ XTAL const pixclock = 20_MHz_XTAL / m_modulus * m_multiplier / (1 << m_pdiv);
screen().configure(
htotal, vtotal,
- active,
- HZ_TO_ATTOSECONDS(75)); // FIXME: not correct in any sense
+ rectangle(0, width - 1, 0, height - 1),
+ attotime::from_ticks(htotal * vtotal, pixclock).attoseconds());
- // TODO: work out how this is configured
- m_timer->adjust(screen().time_until_pos(height - 1, 0), 0);
+ // TODO: determine correct timing for vertical blanking interrupt
+ m_timer->adjust(screen().time_until_pos(height - 1, 0));
}
}
@@ -539,6 +540,16 @@ void jmfb_device::jmfb_w(offs_t offset, uint32_t data, uint32_t mem_mask)
}
break;
+ case 0x300/4:
+ case 0x304/4:
+ case 0x308/4:
+ case 0x30c/4:
+ m_multiplier &= ~(0x0f << ((offset & 3) * 4));
+ m_multiplier |= (data & 0x0f) << ((offset & 3) * 4);
+ LOG("%s: %d to multiplier\n", machine().describe_context(), m_multiplier);
+ update_crtc();
+ break;
+
case 0x310/4:
case 0x314/4:
case 0x318/4:
@@ -551,7 +562,7 @@ void jmfb_device::jmfb_w(offs_t offset, uint32_t data, uint32_t mem_mask)
case 0x324/4:
LOG("%s: 1<<%d to pixel cell divider\n", machine().describe_context(), data);
- m_pdiv = data;
+ m_pdiv = data & 0x0f;
update_crtc();
break;
diff --git a/src/devices/bus/nubus/nubus_48gc.h b/src/devices/bus/nubus/nubus_48gc.h
index 8f69e115d4e..d0b433bf1a6 100644
--- a/src/devices/bus/nubus/nubus_48gc.h
+++ b/src/devices/bus/nubus/nubus_48gc.h
@@ -62,6 +62,7 @@ private:
uint16_t m_hactive, m_hbporch, m_hsync, m_hfporch;
uint16_t m_vactive, m_vbporch, m_vsync, m_vfporch;
+ uint16_t m_multiplier;
uint16_t m_modulus;
uint8_t m_pdiv;
};