Compare commits

..

No commits in common. "5f37421ceb00ca1d96966e4bb8e53b2631f233a5" and "8d7ca7fb03c345ee890d76b8c831d76107472a8b" have entirely different histories.

9 changed files with 81 additions and 353 deletions

View File

@ -68,7 +68,9 @@ ViaCuda::ViaCuda() {
// intialize counters/timers
this->t1_counter = 0xFFFF;
this->t1_active = false;
this->t2_counter = 0xFFFF;
this->t2_active = false;
// calculate VIA clock duration in ns
this->via_clk_dur = 1.0f / VIA_CLOCK_HZ * NS_PER_SEC;
@ -100,17 +102,17 @@ ViaCuda::ViaCuda() {
ViaCuda::~ViaCuda()
{
if (this->sr_timer_id) {
if (this->sr_timer_on) {
TimerManager::get_instance()->cancel_timer(this->sr_timer_id);
this->sr_timer_id = 0;
this->sr_timer_on = false;
}
if (this->t1_timer_id) {
if (this->t1_active) {
TimerManager::get_instance()->cancel_timer(this->t1_timer_id);
this->t1_timer_id = 0;
this->t1_active = false;
}
if (this->t2_timer_id) {
if (this->t2_active) {
TimerManager::get_instance()->cancel_timer(this->t2_timer_id);
this->t2_timer_id = 0;
this->t2_active = false;
}
if (this->treq_timer_id) {
TimerManager::get_instance()->cancel_timer(this->treq_timer_id);
@ -224,9 +226,9 @@ void ViaCuda::write(int reg, uint8_t value) {
ABORT_F("Unsupported VIA T1 mode, ACR=0x%X", this->via_regs[VIA_ACR]);
}
// cancel active T1 timer task
if (this->t1_timer_id) {
if (this->t1_active) {
TimerManager::get_instance()->cancel_timer(this->t1_timer_id);
this->t1_timer_id = 0;
this->t1_active = false;
}
// clear T1 flag in IFR
this->_via_ifr &= ~VIA_IF_T1;
@ -240,19 +242,19 @@ void ViaCuda::write(int reg, uint8_t value) {
this->t1_timer_id = TimerManager::get_instance()->add_oneshot_timer(
static_cast<uint64_t>(this->via_clk_dur * (this->t1_counter + 3) + 0.5f),
[this]() {
this->t1_timer_id = 0;
this->assert_t1_int();
}
);
this->t1_active = true;
break;
case VIA_T2CH:
if (this->via_regs[VIA_ACR] & 0x20) {
ABORT_F("VIA T2 pulse count mode not supported!");
}
// cancel active T2 timer task
if (this->t2_timer_id) {
if (this->t2_active) {
TimerManager::get_instance()->cancel_timer(this->t2_timer_id);
this->t2_timer_id = 0;
this->t2_active = false;
}
// clear T2 flag in IFR
this->_via_ifr &= ~VIA_IF_T2;
@ -266,10 +268,10 @@ void ViaCuda::write(int reg, uint8_t value) {
this->t2_timer_id = TimerManager::get_instance()->add_oneshot_timer(
static_cast<uint64_t>(this->via_clk_dur * (this->t2_counter + 3) + 0.5f),
[this]() {
this->t2_timer_id = 0;
this->assert_t2_int();
}
);
this->t2_active = true;
break;
case VIA_SR:
this->_via_ifr &= ~VIA_IF_SR;
@ -308,17 +310,20 @@ void ViaCuda::update_irq()
}
void ViaCuda::assert_sr_int() {
this->sr_timer_on = false;
this->_via_ifr |= VIA_IF_SR;
update_irq();
}
void ViaCuda::assert_t1_int() {
this->_via_ifr |= VIA_IF_T1;
this->t1_active = false;
update_irq();
}
void ViaCuda::assert_t2_int() {
this->_via_ifr |= VIA_IF_T2;
this->t2_active = false;
update_irq();
}
@ -351,17 +356,14 @@ void ViaCuda::assert_ctrl_line(ViaLine line)
}
void ViaCuda::schedule_sr_int(uint64_t timeout_ns) {
if (this->sr_timer_id) {
if (this->sr_timer_on) {
TimerManager::get_instance()->cancel_timer(this->sr_timer_id);
this->sr_timer_id = 0;
this->sr_timer_on = false;
}
this->sr_timer_id = TimerManager::get_instance()->add_oneshot_timer(
timeout_ns,
[this]() {
this->sr_timer_id = 0;
this->assert_sr_int();
}
);
[this]() { this->assert_sr_int(); });
this->sr_timer_on = true;
}
void ViaCuda::write(uint8_t new_state) {

View File

@ -182,13 +182,16 @@ private:
// VIA internal state
uint32_t sr_timer_id = 0;
bool sr_timer_on = false;
// timer 1 state
bool t1_active;
uint16_t t1_counter;
uint32_t t1_timer_id = 0;
uint64_t t1_start_time = 0;
// timer 2 state
bool t2_active;
uint16_t t2_counter;
uint32_t t2_timer_id = 0;
uint64_t t2_start_time = 0;

View File

@ -34,7 +34,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
using namespace Platinum;
PlatinumCtrl::PlatinumCtrl() : MemCtrlBase(), VideoCtrlBase() {
PlatinumCtrl::PlatinumCtrl() : MemCtrlBase(), VideoCtrlBase(640, 480) {
set_name("Platinum");
supports_types(HWCompType::MEM_CTRL | HWCompType::MMIO_DEV);

View File

@ -123,7 +123,7 @@ static const std::map<uint16_t, std::string> rgb514_reg_names = {
};
AtiMach64Gx::AtiMach64Gx()
: PCIDevice("ati-mach64-gx"), VideoCtrlBase()
: PCIDevice("ati-mach64-gx"), VideoCtrlBase(1024, 768)
{
supports_types(HWCompType::MMIO_DEV | HWCompType::PCI_DEV);
@ -148,10 +148,10 @@ AtiMach64Gx::AtiMach64Gx()
}
// initialize display identification
this->disp_id = std::unique_ptr<DisplayID> (new DisplayID());
this->disp_id = std::unique_ptr<DisplayID> (new DisplayID(0x07, 0x3A));
// allocate video RAM
this->vram_size = GET_INT_PROP("gfxmem_size") << 20; // convert MBs to bytes
this->vram_size = 2 << 20; // 2MB ; up to 6MB supported
this->vram_ptr = std::unique_ptr<uint8_t[]> (new uint8_t[this->vram_size]);
// set up RAMDAC identification
@ -362,15 +362,6 @@ uint32_t AtiMach64Gx::read_reg(uint32_t reg_offset, uint32_t size)
return static_cast<uint32_t>(result);
}
#define WRITE_VALUE_AND_LOG() \
do { \
this->regs[reg_num] = new_value; \
LOG_F(9, "%s: write %s %04x.%c = %0*x = %08x", this->name.c_str(), \
get_reg_name(reg_num), reg_offset, SIZE_ARG(size), size * 2, \
(uint32_t)extract_bits<uint64_t>(value, offset * 8, size * 8), new_value \
); \
} while (0)
void AtiMach64Gx::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size)
{
uint32_t reg_num = reg_offset >> 2;
@ -398,7 +389,6 @@ void AtiMach64Gx::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size)
break;
case ATI_CRTC_OFF_PITCH:
new_value = value;
WRITE_VALUE_AND_LOG();
this->crtc_update();
return;
case ATI_CRTC_INT_CNTL:
@ -512,44 +502,6 @@ void AtiMach64Gx::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size)
}
break;
}
case ATI_OVR_CLR:
case ATI_OVR_WID_LEFT_RIGHT:
case ATI_OVR_WID_TOP_BOTTOM:
new_value = value;
WRITE_VALUE_AND_LOG();
if (value != 0) {
LOG_F(ERROR, "%s: Unhandled value 0x%08x.", this->name.c_str(), value);
}
return;
case ATI_CUR_CLR0:
case ATI_CUR_CLR1:
new_value = value;
this->cursor_dirty = true;
draw_fb = true;
WRITE_VALUE_AND_LOG();
return;
case ATI_CUR_OFFSET:
new_value = value;
if (old_value != new_value)
this->cursor_dirty = true;
draw_fb = true;
WRITE_VALUE_AND_LOG();
return;
case ATI_CUR_HORZ_VERT_OFF:
new_value = value;
if (
extract_bits<uint32_t>(new_value, ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size) !=
extract_bits<uint32_t>(old_value, ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size)
)
this->cursor_dirty = true;
draw_fb = true;
WRITE_VALUE_AND_LOG();
return;
case ATI_CUR_HORZ_VERT_POSN:
new_value = value;
draw_fb = true;
WRITE_VALUE_AND_LOG();
return;
case ATI_DAC_REGS:
new_value = old_value; // no change
if (size == 1) { // only byte accesses are allowed for DAC registers
@ -587,7 +539,7 @@ uint32_t AtiMach64Gx::read(uint32_t rgn_start, uint32_t offset, int size)
if (offset < this->vram_size) {
return read_mem(&this->vram_ptr[offset], size);
}
if (offset >= this->mm_regs_offset && offset < this->mm_regs_offset + 0x400) {
if (offset >= this->mm_regs_offset) {
return BYTESWAP_SIZED(read_reg(offset - this->mm_regs_offset, size), size);
}
return 0;
@ -607,10 +559,9 @@ void AtiMach64Gx::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int
{
if (rgn_start == this->aperture_base[0]) {
if (offset < this->vram_size) {
draw_fb = true;
return write_mem(&this->vram_ptr[offset], value, size);
}
if (offset >= this->mm_regs_offset && offset < this->mm_regs_offset + 0x400) {
if (offset >= this->mm_regs_offset) {
return write_reg(offset - this->mm_regs_offset, BYTESWAP_SIZED(value, size), size);
}
return;
@ -623,6 +574,9 @@ void AtiMach64Gx::verbose_pixel_format(int crtc_index) {
return;
}
/*
int fmt = extract_bits<uint32_t>(this->regs[ATI_CRTC_GEN_CNTL], ATI_CRTC_PIX_WIDTH, ATI_CRTC_PIX_WIDTH_size);
*/
int pix_fmt = this->pixel_format;
const char* what = "Pixel format:";
@ -726,8 +680,6 @@ void AtiMach64Gx::crtc_update()
if (!need_recalc)
return;
this->draw_fb = true;
// calculate display refresh rate
this->refresh_rate = this->pixel_clock / this->hori_total / this->vert_total;
@ -741,31 +693,26 @@ void AtiMach64Gx::crtc_update()
switch (this->pixel_format) {
case 2:
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
draw_fb = false;
this->convert_frame_4bpp_indexed(dst_buf, dst_pitch);
};
break;
case 3:
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
draw_fb = false;
this->convert_frame_8bpp_indexed(dst_buf, dst_pitch);
};
break;
case 4:
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
draw_fb = false;
this->convert_frame_15bpp_BE(dst_buf, dst_pitch);
};
break;
case 5:
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
draw_fb = false;
this->convert_frame_24bpp(dst_buf, dst_pitch);
};
break;
case 6:
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
draw_fb = false;
this->convert_frame_32bpp_BE(dst_buf, dst_pitch);
};
break;
@ -868,7 +815,6 @@ void AtiMach64Gx::rgb514_write_reg(uint8_t reg_addr, uint8_t value)
clut_color[1], clut_color[2], 0xFF);
this->clut_index++;
this->comp_index = 0;
draw_fb = true;
}
break;
case Rgb514::CLUT_MASK:
@ -918,15 +864,8 @@ void AtiMach64Gx::rgb514_write_ind_reg(uint8_t reg_addr, uint8_t value)
}
}
static const PropMap AtiMach64gx_Properties = {
{"gfxmem_size",
new IntProperty( 2, vector<uint32_t>({2, 4, 6}))},
{"mon_id",
new StrProperty("")},
};
static const DeviceDescription AtiMach64Gx_Descriptor = {
AtiMach64Gx::create, {}, AtiMach64gx_Properties
AtiMach64Gx::create, {}, {}
};
REGISTER_DEVICE(AtiMach64Gx, AtiMach64Gx_Descriptor);

View File

@ -89,7 +89,7 @@ static const std::map<uint16_t, std::string> mach64_reg_names = {
};
ATIRage::ATIRage(uint16_t dev_id)
: PCIDevice("ati-rage"), VideoCtrlBase()
: PCIDevice("ati-rage"), VideoCtrlBase(640, 480)
{
uint8_t asic_id;
@ -275,17 +275,6 @@ uint32_t ATIRage::read_reg(uint32_t reg_offset, uint32_t size) {
return static_cast<uint32_t>(result);
}
#define WRITE_VALUE_AND_LOG(level) \
do { \
this->regs[reg_num] = new_value; \
if (reg_num != ATI_CRTC_INT_CNTL) { \
LOG_F(level, "%s: write %s %04x.%c = %0*x = %08x", this->name.c_str(), \
get_reg_name(reg_num), reg_offset, SIZE_ARG(size), size * 2, \
(uint32_t)extract_bits<uint64_t>(value, offset * 8, size * 8), new_value \
); \
} \
} while (0)
void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
uint32_t reg_num = reg_offset >> 2;
uint32_t offset = reg_offset & 3;
@ -312,9 +301,11 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
break;
case ATI_CRTC_OFF_PITCH:
new_value = value;
WRITE_VALUE_AND_LOG(9);
this->crtc_update();
return;
if (old_value != new_value) {
this->regs[reg_num] = new_value;
this->crtc_update();
}
break;
case ATI_CRTC_INT_CNTL: {
uint32_t bits_read_only =
(1 << ATI_CRTC_VBLANK) |
@ -404,29 +395,11 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
break;
case ATI_CUR_CLR0:
case ATI_CUR_CLR1:
new_value = value;
this->cursor_dirty = true;
draw_fb = true;
WRITE_VALUE_AND_LOG(9);
return;
this->setup_hw_cursor();
// fallthrough
case ATI_CUR_OFFSET:
new_value = value;
if (old_value != new_value)
this->cursor_dirty = true;
draw_fb = true;
WRITE_VALUE_AND_LOG(9);
return;
case ATI_CUR_HORZ_VERT_OFF:
new_value = value;
if (
extract_bits<uint32_t>(new_value, ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size) !=
extract_bits<uint32_t>(old_value, ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size)
)
this->cursor_dirty = true;
draw_fb = true;
WRITE_VALUE_AND_LOG(9);
return;
case ATI_CUR_HORZ_VERT_POSN:
case ATI_CUR_HORZ_VERT_OFF:
new_value = value;
draw_fb = true;
break;
@ -490,7 +463,7 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
new_value = value;
if (bit_changed(old_value, new_value, ATI_GEN_CUR_ENABLE)) {
if (bit_set(new_value, ATI_GEN_CUR_ENABLE))
this->cursor_on = true;
this->setup_hw_cursor();
else
this->cursor_on = false;
draw_fb = true;
@ -530,7 +503,7 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
break;
}
WRITE_VALUE_AND_LOG(9);
this->regs[reg_num] = new_value;
}
bool ATIRage::io_access_allowed(uint32_t offset) {
@ -591,15 +564,6 @@ uint32_t ATIRage::read(uint32_t rgn_start, uint32_t offset, int size)
return 0;
}
// memory mapped expansion ROM region
if (rgn_start == this->exp_rom_addr) {
if (offset < this->exp_rom_size)
return read_mem(&this->exp_rom_data[offset], size);
LOG_F(WARNING, "%s: read unmapped ROM region %08x.%c",
this->name.c_str(), offset, SIZE_ARG(size));
return 0;
}
LOG_F(WARNING, "%s: read unmapped aperture region %08x.%c",
this->name.c_str(), offset, SIZE_ARG(size));
return 0;
@ -735,21 +699,6 @@ void ATIRage::crtc_update() {
need_recalc = true;
}
static uint8_t bits_per_pixel[8] = {0, 4, 8, 16, 16, 24, 32, 0};
int new_fb_pitch = extract_bits<uint32_t>(this->regs[ATI_CRTC_OFF_PITCH],
ATI_CRTC_PITCH, ATI_CRTC_PITCH_size) * bits_per_pixel[this->pixel_format];
if (new_fb_pitch != this->fb_pitch) {
this->fb_pitch = new_fb_pitch;
need_recalc = true;
}
uint8_t* new_fb_ptr = &this->vram_ptr[extract_bits<uint32_t>(this->regs[ATI_CRTC_OFF_PITCH],
ATI_CRTC_OFFSET, ATI_CRTC_OFFSET_size) * 8];
if (new_fb_ptr != this->fb_ptr) {
this->fb_ptr = new_fb_ptr;
need_recalc = true;
}
// look up which VPLL ouput is requested
int clock_sel = extract_bits<uint32_t>(this->regs[ATI_CLOCK_CNTL], ATI_CLOCK_SEL,
ATI_CLOCK_SEL_size);
@ -832,6 +781,14 @@ void ATIRage::crtc_update() {
LOG_F(ERROR, "%s: unsupported pixel format %d", this->name.c_str(), this->pixel_format);
}
static uint8_t bits_per_pixel[8] = {0, 4, 8, 16, 16, 24, 32, 0};
this->fb_pitch = extract_bits<uint32_t>(this->regs[ATI_CRTC_OFF_PITCH],
ATI_CRTC_PITCH, ATI_CRTC_PITCH_size) * (bits_per_pixel[this->pixel_format & 7] * 8) >> 3;
this->fb_ptr = &this->vram_ptr[extract_bits<uint32_t>(this->regs[ATI_CRTC_OFF_PITCH],
ATI_CRTC_OFFSET, ATI_CRTC_OFFSET_size) * 8];
LOG_F(INFO, "%s: primary CRT controller enabled:", this->name.c_str());
LOG_F(INFO, "Video mode: %s",
bit_set(this->regs[ATI_CRTC_GEN_CNTL], ATI_CRTC_EXT_DISP_EN) ? "extended" : "VGA");

View File

@ -0,0 +1 @@

View File

@ -57,7 +57,7 @@ namespace loguru {
}
ControlVideo::ControlVideo()
: PCIDevice("Control-Video"), VideoCtrlBase()
: PCIDevice("Control-Video"), VideoCtrlBase(640, 480)
{
supports_types(HWCompType::PCI_HOST | HWCompType::PCI_DEV);

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-24 divingkatae and maximum
Copyright (C) 2018-23 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -29,197 +29,26 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <map>
#include <string>
typedef struct {
uint16_t h;
uint16_t v;
float pixel_clock; // MHz
float h_freq; // kHz
float refresh; // Hz
} MonitorRes;
typedef struct {
uint8_t std_sense_code;
uint8_t ext_sense_code;
const char * apple_enum;
const char * name;
const char * description;
MonitorRes resolutions[4];
} MonitorInfo;
/** Mapping between monitor IDs and their sense codes. */
static const std::map<std::string, MonitorInfo> MonitorIdToCode = {
{ "MacColor21in", {
0, 0x00,
"kESCZero21Inch",
"21\" RGB",
"RGB 21\", 21\" Color, Apple 21S Color", {
{1152, 870, 100 , 68.7 , 75 }
}
}},
{ "PortraitGS", {
1, 0x14,
"kESCOnePortraitMono",
"Portrait Monochrome",
"B&W 15\", Apple Portrait", {
{ 640, 870, 57.2832, 68.9 , 75 }
}
}},
{ "MacRGB12in", {
2, 0x21,
"kESCTwo12Inch",
"12\" RGB",
"12\" Apple RGB", {
{ 512, 384, 15.6672, 24.48 , 60.15}
}
}},
{ "Radius21in", {
3, 0x31,
"kESCThree21InchRadius",
"21\" RGB (Radius)",
"", {
{1152, 870, 100 , 68.7 , 75 }
}
}},
{ "Radius21inGS", {
3, 0x34,
"kESCThree21InchMonoRadius",
"21\" Monochrome (Radius)",
"", {
{1152, 870, 100 , 68.7 , 75 }
}
}},
{ "TwoPageGS", {
3, 0x35,
"kESCThree21InchMono",
"21\" Monochrome",
"B&W 21\", Apple 2 Page Mono", {
{1152, 870, 100 , 68.7 , 75 }
}
}},
{ "NTSC", {
4, 0x0A,
"kESCFourNTSC",
"NTSC",
"NTSC underscan 512x384, overscan", {
{ 640, 480, 12.2727, 15.7 , 59.94}
}
}},
{ "MacRGB15in", {
5, 0x1E,
"kESCFivePortrait",
"Portrait RGB",
"RGB 15\", 15\" Tilt", {
{ 640, 870, 57.2834, 0 , 0 }
}
}},
{ "Multiscan15in", {
6, 0x03,
"kESCSixMSB1",
"MultiScan Band-1 (12\" thru 16\")",
"Multiple Scan 13, 14\"", {
{ 640, 480, 67 , 0 , 0 },
{ 832, 624, 75 , 0 , 0 }
}
}},
{ "Multiscan17in", {
6, 0x0B,
"kESCSixMSB2",
"MultiScan Band-2 (13\" thru 19\")",
"Multiple Scan 16, 17\"", {
{ 640, 480, 67 , 0 , 0 },
{ 832, 624, 75 , 0 , 0 },
{1024, 768, 75 , 0 , 0 }
}
}},
{ "Multiscan20in", {
6, 0x23,
"kESCSixMSB3",
"MultiScan Band-3 (13\" thru 21\")",
"Multiple Scan 20, 21\"", {
{ 640, 480, 67 , 0 , 0 },
{ 832, 624, 75 , 0 , 0 },
{1024, 768, 75 , 0 , 0 },
{1152, 870, 75 , 0 , 0 }
}
}},
{ "HiRes12-14in", {
6, 0x2B,
"kESCSixStandard",
"13\"/14\" RGB or 12\" Monochrome",
"B&W 12\", 12\" Apple Monochrome, 13\" Apple RGB, Hi-Res 12-14\"", {
{ 640, 480, 30.24 , 35.0 , 66.7 },
}
}},
{ "PALEncoder", {
7, 0x00,
"kESCSevenPAL",
"PAL",
"PAL, NTSC/PAL (Option 1)", {
{ 640, 480, 14.75 , 15.625, 50 },
{ 768, 576, 14.75 , 15.625, 50 }
}
}},
{ "NTSCEncoder", {
7, 0x14,
"kESCSevenNTSC",
"NTSC",
"NTSC w/convolution (Alternate)", {
{ 640, 480, 12.2727, 0 , 0 }
}
}},
{ "VGA-SVGA", {
7, 0x17,
"kESCSevenVGA",
"VGA",
"VGA", {
{ 640, 480, 25.175 , 31.47 , 59.95},
{ 800, 600, 36 , 35.16 , 56 },
{1024, 768, 35.16 , 60 }
}
}},
{ "MacRGB16in", {
7, 0x2D,
"kESCSeven16Inch",
"16\" RGB (GoldFish)",
"RGB 16\", 16\" Color", {
{ 832, 624, 57.2832, 49.7 , 75 }
}
}},
{ "PAL", {
7, 0x30,
"kESCSevenPALAlternate",
"PAL (Alternate)",
"PAL w/convolution (Alternate) (Option 2)", {
{ 640, 480, 14.75 , 15.625, 50 },
{ 768, 576, 14.75 , 15.625, 50 }
}
}},
{ "MacRGB19in", {
7, 0x3A,
"kESCSeven19Inch",
"Third-Party 19",
"RGB 19\", 19\" Color", {
{1024, 768, 80 , 0 , 0 }
}
}},
{ "DDC", {
7, 0x3E,
"kESCSevenDDC",
"DDC display",
"EDID", {
{1024, 768, 80 , 0 , 0 }
}
}},
{ "NotConnected", {
7, 0x3F,
"kESCSevenNoDisplay",
"No display connected",
"no-connect"
}},
};
static const std::map<std::string, std::string> MonitorAliasToId = {
{ "AppleVision1710", "HiRes12-14in" }
static const std::map<std::string, uint16_t> MonitorIdToCode = {
{ "MacColor21in" , 0x00FF },
{ "PortraitGS" , 0x01FF },
{ "MacRGB12in" , 0x02FF },
{ "TwoPageGS" , 0x03FF },
{ "NTSC" , 0x04FF },
{ "MacRGB15in" , 0x05FF },
{ "HiRes12-14in" , 0x06FF },
{ "Multiscan15in" , 0x0603 },
{ "Multiscan17in" , 0x060B },
{ "Multiscan20in" , 0x0623 },
{ "AppleVision1710" , 0x062B }, // this code is assigned to several different monitors!
{ "PALEncoder" , 0x0700 }, // no clue what it means
{ "NTSCEncoder" , 0x0714 }, // no clue what it means
{ "VGA-SVGA" , 0x0717 },
{ "MacRGB16in" , 0x072D },
{ "MacRGB19in" , 0x073A },
{ "PAL" , 0x0730 },
{ "NotConnected" , 0x07FF }
};
DisplayID::DisplayID()
@ -229,17 +58,14 @@ DisplayID::DisplayID()
std::string mon_id = GET_STR_PROP("mon_id");
if (!mon_id.empty()) {
if (MonitorAliasToId.count(mon_id)) {
mon_id = MonitorAliasToId.at(mon_id);
}
if (MonitorIdToCode.count(mon_id)) {
auto monitor = MonitorIdToCode.at(mon_id);
this->std_sense_code = monitor.std_sense_code;
this->ext_sense_code = monitor.ext_sense_code;
auto sense_code = MonitorIdToCode.at(mon_id);
this->std_sense_code = (sense_code >> 8) & 0xFFU;
this->ext_sense_code = (sense_code >> 0) & 0xFFU;
this->id_kind = Disp_Id_Kind::AppleSense;
LOG_F(INFO, "DisplayID mode set to AppleSense");
LOG_F(INFO, "Standard sense code: %d", this->std_sense_code);
LOG_F(INFO, "Extended sense code: 0x%02X", this->ext_sense_code);
LOG_F(INFO, "Standard sense code: 0x%d", this->std_sense_code);
LOG_F(INFO, "Extended sense code: 0x%X", this->ext_sense_code);
}
}

View File

@ -33,7 +33,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <string>
TaosVideo::TaosVideo() : VideoCtrlBase() {
TaosVideo::TaosVideo() : VideoCtrlBase(640, 480) {
set_name("Taos");
supports_types(HWCompType::MMIO_DEV);