aboutsummaryrefslogtreecommitdiff
path: root/hw/vga.c
diff options
context:
space:
mode:
authorMatthew Ogilvie <mmogilvi_qemu@miniinfo.net>2012-08-23 00:24:42 -0600
committermalc <av1474@comtv.ru>2012-08-24 07:44:39 +0400
commit482f7bf86b43af9f6903c52726fedf82b28bf953 (patch)
treea7c926204eeb43cc3f9b3d15f39c05f6c0717613 /hw/vga.c
parent39dda260628e5f2a3fd2ce2ec8a71f3d5ca309a9 (diff)
vga: add some optional CGA compatibility hacks
This patch adds some optional compatibility hacks (default disabled) to allow Microport UNIX to function under qemu. I've tried to structure it to be easy to add more hacks for other old CGA programs, if anyone ever needs them. Microport UNIX System V/386 v 2.1 (ca 1987) tries to program the CGA registers directly with neither the assistance of BIOS, nor with proper handling of EGA/VGA-only registers. Note that it didn't work on real VGA hardware, either (although in that case, the most obvious problems seemed to be out-of-range hsync and/or vsync signalling, rather than the issues in this patch). Eventually real MDA and/or CGA support might provide an alternative to this patch, although a hybrid approach like this patch might still be useful in marginal cases. Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net> Signed-off-by: malc <av1474@comtv.ru>
Diffstat (limited to 'hw/vga.c')
-rw-r--r--hw/vga.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/hw/vga.c b/hw/vga.c
index f82ced8e66..a65fc26ab7 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -547,14 +547,31 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
#endif
/* handle CR0-7 protection */
- if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
- s->cr_index <= VGA_CRTC_OVERFLOW) {
- /* can always write bit 4 of CR7 */
- if (s->cr_index == VGA_CRTC_OVERFLOW) {
- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
- (val & 0x10);
+ if (s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) {
+ if (s->cr_index <= VGA_CRTC_OVERFLOW) {
+ /* can always write bit 4 of CR7 */
+ if (s->cr_index == VGA_CRTC_OVERFLOW) {
+ s->cr[VGA_CRTC_OVERFLOW] =
+ (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | (val & 0x10);
+ }
+ return;
+ } else if ((vga_cga_hacks & VGA_CGA_HACK_FONT_HEIGHT) &&
+ !(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
+ /* extra CGA compatibility hacks (not in standard VGA) */
+ if (s->cr_index == VGA_CRTC_MAX_SCAN &&
+ val == 7 &&
+ (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) {
+ return;
+ } else if (s->cr_index == VGA_CRTC_CURSOR_START &&
+ val == 6 &&
+ (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) {
+ val = 0xd;
+ } else if (s->cr_index == VGA_CRTC_CURSOR_END &&
+ val == 7 &&
+ (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) {
+ val = 0xe;
+ }
}
- return;
}
s->cr[s->cr_index] = val;
@@ -1886,7 +1903,10 @@ static void vga_update_display(void *opaque)
/* nothing to do */
} else {
full_update = 0;
- if (!(s->ar_index & 0x20)) {
+ if (!(s->ar_index & 0x20) &&
+ /* extra CGA compatibility hacks (not in standard VGA */
+ (!(vga_cga_hacks & VGA_CGA_HACK_PALETTE_BLANKING) ||
+ (s->ar_index != 0 && s->ar_flip_flop))) {
graphic_mode = GMODE_BLANK;
} else {
graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;