mirror of
https://github.com/holub/mame
synced 2025-07-03 00:56:03 +03:00
machine/mv_sonora.cpp: Sonora/Ardbeg use an external pixel clock (PDM does not). Also fixed monochrome mode. [R. Belmont]
apple/omega.cpp: Add "Omega" programmable PLL chip to generate the pixel clock for LC III/LC 520/LC 550. [R. Belmont]
This commit is contained in:
parent
f443505d3c
commit
a7738bb241
@ -5,6 +5,11 @@
|
||||
Mac video support, "Sonora" edition
|
||||
Supports 5 different modelines at up to 16bpp
|
||||
|
||||
The original Sonora ASIC and its follow-on Ardbeg require an
|
||||
external pixel clock source, while the version used in the PDM
|
||||
machines has an internal clock source that automatically is set
|
||||
appropriately for the video mode.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -13,11 +18,11 @@
|
||||
DEFINE_DEVICE_TYPE(MAC_VIDEO_SONORA, mac_video_sonora_device, "mv_sonora", "Mac Sonora video support")
|
||||
|
||||
const mac_video_sonora_device::modeline mac_video_sonora_device::modelines[5] = {
|
||||
{ 0x02, "512x384 12\" RGB", 15667200, 640, 16, 32, 80, 407, 1, 3, 19, true },
|
||||
{ 0x06, "640x480 13\" RGB", 31334400, 896, 80, 64, 112, 525, 3, 3, 39, true },
|
||||
{ 0x01, "640x870 15\" Portrait", 57283200, 832, 32, 80, 80, 918, 3, 3, 42, false },
|
||||
{ 0x09, "832x624 16\" RGB", 57283200, 1152, 32, 64, 224, 667, 1, 3, 39, false },
|
||||
{ 0x0b, "640x480 VGA", 25175000, 800, 16, 96, 48, 525, 10, 2, 33, false },
|
||||
{ 0x02, "512x384 12\" RGB", 15667200, 640, 16, 32, 80, 407, 1, 3, 19, true, false },
|
||||
{ 0x06, "640x480 13\" RGB", 31334400, 896, 80, 64, 112, 525, 3, 3, 39, true, false },
|
||||
{ 0x01, "640x870 15\" Portrait", 57283200, 832, 32, 80, 80, 918, 3, 3, 42, false, true },
|
||||
{ 0x09, "832x624 16\" RGB", 57283200, 1152, 32, 64, 224, 667, 1, 3, 39, false, false },
|
||||
{ 0x0b, "640x480 VGA", 25175000, 800, 16, 96, 48, 525, 10, 2, 33, false, false },
|
||||
};
|
||||
|
||||
mac_video_sonora_device::mac_video_sonora_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
@ -26,6 +31,7 @@ mac_video_sonora_device::mac_video_sonora_device(const machine_config &mconfig,
|
||||
m_palette(*this, "palette"),
|
||||
m_monitor_config(*this, "monitor"),
|
||||
m_screen_vblank(*this),
|
||||
m_isPDM(false),
|
||||
m_is32bit(false)
|
||||
{
|
||||
}
|
||||
@ -272,7 +278,11 @@ void mac_video_sonora_device::vctrl_w(offs_t offset, uint8_t data)
|
||||
if(m_modeline_id != -1 && m_modeline_id != prev_modeline) {
|
||||
const modeline &m = modelines[m_modeline_id];
|
||||
rectangle visarea(0, m.htot - m.hfp - m.hs - m.hbp - 1, 0, m.vtot - m.vfp - m.vs - m.vbp - 1);
|
||||
m_screen->configure(m.htot, m.vtot, visarea, attotime::from_ticks(m.htot*m.vtot, m.dotclock).as_attoseconds());
|
||||
if (m_isPDM) {
|
||||
m_screen->configure(m.htot, m.vtot, visarea, attotime::from_ticks(m.htot*m.vtot, m.dotclock).as_attoseconds());
|
||||
} else {
|
||||
m_screen->configure(m.htot, m.vtot, visarea, attotime::from_ticks(m.htot * m.vtot, m_extPixelClock).as_attoseconds());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -305,7 +315,7 @@ uint8_t mac_video_sonora_device::dac_r(offs_t offset)
|
||||
return m_pal_control;
|
||||
|
||||
default:
|
||||
logerror("dac_r %x\n", offset);
|
||||
// logerror("dac_r %x\n", offset);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -322,7 +332,18 @@ void mac_video_sonora_device::dac_w(offs_t offset, uint8_t data)
|
||||
switch(m_pal_idx) {
|
||||
case 0: m_palette->set_pen_red_level(m_pal_address, data); break;
|
||||
case 1: m_palette->set_pen_green_level(m_pal_address, data); break;
|
||||
case 2: m_palette->set_pen_blue_level(m_pal_address, data); break;
|
||||
case 2:
|
||||
// monochrome monitors use the blue line as the video, so duplicate blue to all 3 primaries
|
||||
if (modelines[m_modeline_id].monochrome) {
|
||||
m_palette->set_pen_red_level(m_pal_address, data);
|
||||
m_palette->set_pen_green_level(m_pal_address, data);
|
||||
m_palette->set_pen_blue_level(m_pal_address, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_palette->set_pen_blue_level(m_pal_address, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_pal_idx ++;
|
||||
if(m_pal_idx == 3) {
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
void set_vram_base(const uint64_t *vram) { m_vram = vram; }
|
||||
void set_vram_offset(uint32_t offset) { m_vram_offset = offset; }
|
||||
void set_32bit() { m_is32bit = true; }
|
||||
void set_PDM() { m_isPDM = true; }
|
||||
void set_pixel_clock(uint32_t pclk) { m_extPixelClock = pclk; }
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
@ -48,6 +50,7 @@ private:
|
||||
uint32_t htot, hfp, hs, hbp;
|
||||
uint32_t vtot, vfp, vs, vbp;
|
||||
bool supports_16bpp;
|
||||
bool monochrome;
|
||||
};
|
||||
|
||||
static const modeline modelines[5];
|
||||
@ -58,10 +61,11 @@ private:
|
||||
devcb_write_line m_screen_vblank;
|
||||
|
||||
const uint64_t *m_vram;
|
||||
uint32_t m_vram_offset;
|
||||
uint32_t m_vram_offset, m_extPixelClock;
|
||||
uint8_t m_mode, m_depth, m_monitor_id, m_vtest;
|
||||
uint8_t m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey;
|
||||
int m_modeline_id;
|
||||
bool m_isPDM;
|
||||
bool m_is32bit;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "macadb.h"
|
||||
#include "macscsi.h"
|
||||
#include "mactoolbox.h"
|
||||
#include "omega.h"
|
||||
#include "sonora.h"
|
||||
|
||||
#include "bus/nscsi/cd.h"
|
||||
@ -57,6 +58,7 @@ public:
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_sonora(*this, "sonora"),
|
||||
m_dfac(*this, "dfac"),
|
||||
m_omega(*this, "omega"),
|
||||
m_scsibus1(*this, "scsi"),
|
||||
m_ncr5380(*this, "scsi:7:ncr5380"),
|
||||
m_scsihelp(*this, "scsihelp"),
|
||||
@ -83,6 +85,7 @@ private:
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<sonora_device> m_sonora;
|
||||
optional_device<dfac_device> m_dfac;
|
||||
required_device<omega_device> m_omega;
|
||||
required_device<nscsi_bus_device> m_scsibus1;
|
||||
required_device<ncr5380_device> m_ncr5380;
|
||||
required_device<mac_scsi_helper_device> m_scsihelp;
|
||||
@ -298,6 +301,9 @@ void macvail_state::maclc3_base(machine_config &config)
|
||||
m_dfac->add_route(0, "lspeaker", 1.0);
|
||||
m_dfac->add_route(1, "rspeaker", 1.0);
|
||||
|
||||
APPLE_OMEGA(config, m_omega, 31.3344_MHz_XTAL);
|
||||
m_omega->pclock_changed().set(m_sonora, FUNC(sonora_device::pixel_clock_w));
|
||||
|
||||
SONORA(config, m_sonora, C15M);
|
||||
m_sonora->set_maincpu_tag("maincpu");
|
||||
m_sonora->set_rom_tag("bootrom");
|
||||
@ -324,8 +330,11 @@ void macvail_state::maclc3(machine_config &config)
|
||||
m_egret->set_default_bios_tag("341s0851");
|
||||
m_egret->reset_callback().set(FUNC(macvail_state::cuda_reset_w));
|
||||
m_egret->dfac_scl_callback().set(m_dfac, FUNC(dfac_device::clock_write));
|
||||
m_egret->dfac_scl_callback().append(m_omega, FUNC(omega_device::clock_write));
|
||||
m_egret->dfac_sda_callback().set(m_dfac, FUNC(dfac_device::data_write));
|
||||
m_egret->dfac_sda_callback().append(m_omega, FUNC(omega_device::data_write));
|
||||
m_egret->dfac_latch_callback().set(m_dfac, FUNC(dfac_device::latch_write));
|
||||
m_egret->dfac_latch_callback().append(m_omega, FUNC(omega_device::latch_write));
|
||||
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_egret->via_clock_callback().set(m_sonora, FUNC(sonora_device::cb1_w));
|
||||
m_egret->via_data_callback().set(m_sonora, FUNC(sonora_device::cb2_w));
|
||||
@ -356,6 +365,9 @@ void macvail_state::maclc520(machine_config &config)
|
||||
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_cuda->via_clock_callback().set(m_sonora, FUNC(sonora_device::cb1_w));
|
||||
m_cuda->via_data_callback().set(m_sonora, FUNC(sonora_device::cb2_w));
|
||||
m_cuda->iic_scl_callback().set(m_omega, FUNC(omega_device::clock_write));
|
||||
m_cuda->iic_sda_callback().set(m_omega, FUNC(omega_device::data_write));
|
||||
m_cuda->dfac_latch_callback().set(m_omega, FUNC(omega_device::latch_write));
|
||||
m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line));
|
||||
config.set_perfect_quantum(m_maincpu);
|
||||
|
||||
|
141
src/mame/apple/omega.cpp
Normal file
141
src/mame/apple/omega.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
omega.cpp - Apple PLL clock synthesizer, used with Sonora and Ardbeg
|
||||
based machines to generate the system clock and video dot clock.
|
||||
|
||||
Omega is intended to share the 3-wire clock/data/latch serial bus
|
||||
with DFAC. On the rising edge of the latch, it takes note of the
|
||||
next 16 bits. The first 7 are the N parameter, the next 7 bits are
|
||||
the D parameter, and the final 2 are the P parameter. The actual
|
||||
formula is identical to the Gazelle chip and the Sierra Semiconductor
|
||||
SC11412.
|
||||
|
||||
Pixel clock = (31.3344 MHz * (N / D)) / P;
|
||||
|
||||
________________________
|
||||
/ 4 3 2 1 28 27 26 |
|
||||
| * |
|
||||
| 5 25 |
|
||||
| 6 344S1060-A N 24 |
|
||||
| 7 23 |
|
||||
| 8 (C)1991 APPLE 22 |
|
||||
| 9 21 |
|
||||
| 10 20 |
|
||||
| 11 19 |
|
||||
|____12_13_14_15_16_17_18__|
|
||||
|
||||
1, 7, 13, 16, 19, 20 = DGND, digital ground
|
||||
2, 28 = AGND, analog ground
|
||||
3 = DOTFLTR, filter for the DOTCLK output
|
||||
4, 26 = AVDD, analog +5 volt supply (connected to VDD in LC 520)
|
||||
5 - OESYSCLK - 1 to enable the SYSCLK output on pin 15
|
||||
6 - OEALL - 1 to enable both the pixel and system clocks?
|
||||
8 - SLATCH - serial latch
|
||||
9 - SDATA - serial data
|
||||
10 - SCLK - serial bit clock
|
||||
11, 14, 17, 23 = VDD, main +5 volt supply
|
||||
12 - DOTCLK - video dot clock output
|
||||
15 - SYSCLK - system clock output
|
||||
18 - C32M - outputs a mirror of the reference crystal clock
|
||||
21 - XTALOUT
|
||||
22 - XTALIN - connect the 31.3344 MHz reference crystal between XTALIN and XTALOUT
|
||||
24 - S1 - selects one of the canned system clock freqencies (24 is VDD, 25 is GND in LC III = 25 MHz)
|
||||
25 - S0 - " " " " " " " "
|
||||
27 - SYSFLTR - filter for the SYSCLK output
|
||||
|
||||
SYSFLTR and DOTFLTR are connected like this:
|
||||
|
||||
604 ohms? 0.1uF
|
||||
(pin 3 or 27) ----/\/\/\----||-----|
|
||||
| |-----GND
|
||||
|---||-------------|
|
||||
0.002uF
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "omega.h"
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(APPLE_OMEGA, omega_device, "aplomega", "Apple Omega PLL Clock Synthesizer")
|
||||
|
||||
omega_device::omega_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, APPLE_OMEGA, tag, owner, clock),
|
||||
m_write_pclock(*this),
|
||||
m_data(false),
|
||||
m_clock(false),
|
||||
m_latch(false),
|
||||
m_latch_byte(0),
|
||||
m_N(0),
|
||||
m_D(0),
|
||||
m_P(0),
|
||||
m_bit(0)
|
||||
{
|
||||
}
|
||||
|
||||
void omega_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_clock));
|
||||
save_item(NAME(m_data));
|
||||
save_item(NAME(m_latch));
|
||||
save_item(NAME(m_latch_byte));
|
||||
save_item(NAME(m_N));
|
||||
save_item(NAME(m_D));
|
||||
save_item(NAME(m_P));
|
||||
save_item(NAME(m_bit));
|
||||
}
|
||||
|
||||
void omega_device::clock_write(int state)
|
||||
{
|
||||
// take a bit on the rising edge of SCL
|
||||
if (state && !m_clock)
|
||||
{
|
||||
m_latch_byte <<= 1;
|
||||
m_latch_byte |= m_data & 1;
|
||||
|
||||
switch (m_bit)
|
||||
{
|
||||
case 6:
|
||||
m_N = m_latch_byte;
|
||||
m_latch_byte = 0;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
m_D = m_latch_byte;
|
||||
m_latch_byte = 0;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
m_P = m_latch_byte & 3;
|
||||
|
||||
const u32 pclock = (u32)(31334400.0f * ((double)m_N / (double)m_D)) / (double)m_P;
|
||||
m_write_pclock(pclock);
|
||||
|
||||
LOG("%s: N = %d, D = %d, P = %d, pixel clock = %d\n", tag(), m_N, m_D, m_P, pclock);
|
||||
break;
|
||||
}
|
||||
|
||||
m_bit++;
|
||||
}
|
||||
|
||||
m_clock = state;
|
||||
}
|
||||
|
||||
void omega_device::latch_write(int state)
|
||||
{
|
||||
// start counting bits on the falling edge of the latch
|
||||
if (state && !m_latch)
|
||||
{
|
||||
LOG("%s: latch rising edge, resetting bit count\n", tag());
|
||||
m_bit = 0;
|
||||
m_latch_byte = 0;
|
||||
}
|
||||
|
||||
m_latch = state;
|
||||
}
|
||||
|
34
src/mame/apple/omega.h
Normal file
34
src/mame/apple/omega.h
Normal file
@ -0,0 +1,34 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
#ifndef MAME_APPLE_OMEGA_H
|
||||
#define MAME_APPLE_OMEGA_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class omega_device : public device_t
|
||||
{
|
||||
public:
|
||||
omega_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto pclock_changed() { return m_write_pclock.bind(); }
|
||||
|
||||
// Omega uses the same 3-wire serial interface as DFAC, and is intended
|
||||
// to share the bus with DFAC.
|
||||
void data_write(int state) { m_data = state; }
|
||||
void clock_write(int state);
|
||||
void latch_write(int state);
|
||||
|
||||
protected:
|
||||
// device_r overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
devcb_write32 m_write_pclock;
|
||||
bool m_data, m_clock, m_latch;
|
||||
u8 m_latch_byte, m_N, m_D, m_P;
|
||||
u32 m_bit;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(APPLE_OMEGA, omega_device)
|
||||
|
||||
#endif // MAME_APPLE_OMEGA_H
|
@ -43,6 +43,8 @@ public:
|
||||
template <u8 mask> void slot_irq_w(int state);
|
||||
void scc_irq_w(int state);
|
||||
|
||||
void pixel_clock_w(u32 pclk) { m_video->set_pixel_clock(pclk); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
Loading…
Reference in New Issue
Block a user