diff options
author | 2024-12-17 11:42:45 +0100 | |
---|---|---|
committer | 2024-12-17 11:42:58 +0100 | |
commit | f32a8202fcdd8128eea7d115b824e9eeabd68ad8 (patch) | |
tree | 8b134881707905e51a1ac543471567cc276fd73a /src/devices/video/pc_vga_cirrus.cpp | |
parent | 1aafded4a2dfe999c9a1a4901b5a74883df76c29 (diff) |
video/pc_vga_cirrus: workaround crash for zorro/picasso2, fix bit 3 in blitting status
Diffstat (limited to 'src/devices/video/pc_vga_cirrus.cpp')
-rw-r--r-- | src/devices/video/pc_vga_cirrus.cpp | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/src/devices/video/pc_vga_cirrus.cpp b/src/devices/video/pc_vga_cirrus.cpp index a33eb1edf28..475018b6a87 100644 --- a/src/devices/video/pc_vga_cirrus.cpp +++ b/src/devices/video/pc_vga_cirrus.cpp @@ -8,6 +8,8 @@ * - Original Acumos AVGA1/2 chipsets (Cirrus Logic eventually bought Acumos and rebranded); * - Fix or implement hidden DAC modes (15bpp + mixed, true color, others); * - bebox: logo at startup is squashed; + * - zorro/picasso2: many blitting errors, verify HW cursor; + * - zorro/picasso2: segmentation fault on exit * - Merge with trs/vis.cpp implementation (CL-GD5200 RAMDAC with custom VGA controller) * */ @@ -24,7 +26,7 @@ #define LOG_BANK (1U << 4) // log offset registers #define LOG_PLL (1U << 5) -#define VERBOSE (LOG_GENERAL | LOG_HDAC | LOG_REG | LOG_PLL) +#define VERBOSE (LOG_GENERAL | LOG_HDAC | LOG_REG | LOG_BLIT) //#define LOG_OUTPUT_FUNC osd_printf_info #include "logmacro.h" @@ -331,6 +333,7 @@ void cirrus_gd5428_vga_device::gc_map(address_map &map) }), NAME([this](offs_t offset, u8 data) { m_blt_width = (m_blt_width & 0xff00) | data; + LOGMASKED(LOG_BLIT, "CL: blt_width %02x [0] (%04x)\n", data, m_blt_width); }) ); // BLT Width 1 @@ -340,6 +343,7 @@ void cirrus_gd5428_vga_device::gc_map(address_map &map) }), NAME([this](offs_t offset, u8 data) { m_blt_width = (m_blt_width & 0x00ff) | (data << 8); + LOGMASKED(LOG_BLIT, "CL: blt_width %02x [1] (%04x)\n", data, m_blt_width); }) ); // BLT Height 0 @@ -349,6 +353,7 @@ void cirrus_gd5428_vga_device::gc_map(address_map &map) }), NAME([this](offs_t offset, u8 data) { m_blt_height = (m_blt_height & 0xff00) | data; + LOGMASKED(LOG_BLIT, "CL: m_blt_height %02x [0] (%04x)\n", data, m_blt_height); }) ); // BLT Height 1 @@ -358,6 +363,7 @@ void cirrus_gd5428_vga_device::gc_map(address_map &map) }), NAME([this](offs_t offset, u8 data) { m_blt_height = (m_blt_height & 0x00ff) | (data << 8); + LOGMASKED(LOG_BLIT, "CL: m_blt_height %02x [1] (%04x)\n", data, m_blt_height); }) ); // BLT Destination Pitch 0 @@ -436,6 +442,8 @@ void cirrus_gd5428_vga_device::gc_map(address_map &map) }), NAME([this](offs_t offset, u8 data) { m_blt_status = data & ~0xf2; + if (BIT(data, 2)) + m_blt_status &= ~9; if(data & 0x02) { if(m_blt_mode & 0x04) // blit source is system memory @@ -625,6 +633,7 @@ void cirrus_gd5428_vga_device::sequencer_map(address_map &map) void cirrus_gd5428_vga_device::device_start() { + svga_device::device_start(); zero(); for (int i = 0; i < 0x100; i++) @@ -634,10 +643,10 @@ void cirrus_gd5428_vga_device::device_start() vga.crtc.maximum_scan_line = 1; // copy over interfaces - vga.memory = std::make_unique<uint8_t []>(vga.svga_intf.vram_size); - memset(&vga.memory[0], 0, vga.svga_intf.vram_size); + //vga.memory = std::make_unique<uint8_t []>(vga.svga_intf.vram_size); + //memset(&vga.memory[0], 0, vga.svga_intf.vram_size); - save_pointer(NAME(vga.memory), vga.svga_intf.vram_size); + //save_pointer(NAME(vga.memory), vga.svga_intf.vram_size); save_pointer(vga.crtc.data,"CRTC Registers",0x100); save_pointer(vga.sequencer.data,"Sequencer Registers",0x100); save_pointer(vga.attribute.data,"Attribute Registers", 0x15); @@ -666,7 +675,7 @@ void cirrus_gd5446_vga_device::device_start() void cirrus_gd5428_vga_device::device_reset() { - vga_device::device_reset(); + svga_device::device_reset(); gc_locked = true; gc_mode_ext = 0; gc_bank[0] = gc_bank[1] = 0; @@ -945,7 +954,7 @@ void cirrus_gd5428_vga_device::start_bitblt() m_blt_source_current = m_blt_source + (m_blt_source_pitch*(y+1)); m_blt_dest_current = m_blt_dest + (m_blt_dest_pitch*(y+1)); } - m_blt_status &= ~0x02; + m_blt_status &= ~0x09; } void cirrus_gd5428_vga_device::start_reverse_bitblt() @@ -1020,7 +1029,7 @@ void cirrus_gd5428_vga_device::start_reverse_bitblt() m_blt_source_current = m_blt_source - (m_blt_source_pitch*(y+1)); m_blt_dest_current = m_blt_dest - (m_blt_dest_pitch*(y+1)); } - m_blt_status &= ~0x02; + m_blt_status &= ~0x09; } void cirrus_gd5428_vga_device::start_system_bitblt() @@ -1111,9 +1120,17 @@ void cirrus_gd5428_vga_device::copy_pixel(uint8_t src, uint8_t dst) case 0x0e: // WHITE res = 0xff; break; + case 0x50: // DSna / DPna + // used by picasso2, unknown purpose + res = (dst & (~src)); + break; case 0x59: // SRCINVERT res = src ^ dst; break; + case 0x6d: // SRCPAINT / DSo + // picasso2 on VGA Workbench (upper right icon) + res = src | dst; + break; default: popmessage("pc_vga_cirrus: Unsupported BitBLT ROP mode %02x",m_blt_rop); } @@ -1169,11 +1186,21 @@ uint8_t cirrus_gd5428_vga_device::mem_r(offs_t offset) uint32_t addr; uint8_t cur_mode = pc_vga_choosevideomode(); - if(gc_locked || offset >= 0x10000 || cur_mode == TEXT_MODE || cur_mode == SCREEN_OFF) - return vga_device::mem_r(offset); - const uint8_t bank = offset_select(offset); + // FIXME: workaround crash behaviour in picasso2 + // it will otherwise provide an offset of 0x1fxxxx in the gc_locked below + // causing a crash during adapter init + if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) + { + return svga_device::mem_linear_r((offset & 0xffff) + bank * 0x10000); + } + + if(gc_locked || offset >= 0x10000 || cur_mode == TEXT_MODE || cur_mode == SCREEN_OFF) + { + return vga_device::mem_r(offset & 0x1ffff); + } + if(gc_mode_ext & 0x20) // 16kB bank granularity addr = bank * 0x4000; else // 4kB bank granularity @@ -1320,13 +1347,20 @@ void cirrus_gd5428_vga_device::mem_w(offs_t offset, uint8_t data) return; } - if(gc_locked || offset >= 0x10000 || cur_mode == TEXT_MODE || cur_mode == SCREEN_OFF) + const uint8_t bank = offset_select(offset); + + // FIXME: as above + if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en) { - vga_device::mem_w(offset,data); + svga_device::mem_linear_w((offset + bank * 0x10000), data); return; } - const uint8_t bank = offset_select(offset); + if(gc_locked || offset >= 0x10000 || cur_mode == TEXT_MODE || cur_mode == SCREEN_OFF) + { + vga_device::mem_w(offset & 0x1ffff,data); + return; + } if(gc_mode_ext & 0x20) // 16kB bank granularity addr = bank * 0x4000; |