mirror of
https://github.com/xemu-project/xemu.git
synced 2025-03-05 19:17:48 +00:00
vga: use constants from vga.h
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
0dad6c35fc
commit
5e55efc9e7
362
hw/vga.c
362
hw/vga.c
@ -22,6 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "vga.h"
|
||||
#include "console.h"
|
||||
#include "pc.h"
|
||||
#include "pci.h"
|
||||
@ -160,9 +161,10 @@ static void vga_update_memory_access(VGACommonState *s)
|
||||
|
||||
s->chain4_alias = NULL;
|
||||
|
||||
if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
|
||||
if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
|
||||
VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
|
||||
offset = 0;
|
||||
switch ((s->gr[6] >> 2) & 3) {
|
||||
switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
|
||||
case 0:
|
||||
base = 0xa0000;
|
||||
size = 0x20000;
|
||||
@ -223,22 +225,20 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
|
||||
int64_t chars_per_sec;
|
||||
struct vga_precise_retrace *r = &s->retrace_info.precise;
|
||||
|
||||
htotal_chars = s->cr[0x00] + 5;
|
||||
hretr_start_char = s->cr[0x04];
|
||||
hretr_skew_chars = (s->cr[0x05] >> 5) & 3;
|
||||
hretr_end_char = s->cr[0x05] & 0x1f;
|
||||
htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
|
||||
hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
|
||||
hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
|
||||
hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
|
||||
|
||||
vtotal_lines = (s->cr[0x06]
|
||||
| (((s->cr[0x07] & 1) | ((s->cr[0x07] >> 4) & 2)) << 8)) + 2
|
||||
;
|
||||
vretr_start_line = s->cr[0x10]
|
||||
| ((((s->cr[0x07] >> 2) & 1) | ((s->cr[0x07] >> 6) & 2)) << 8)
|
||||
;
|
||||
vretr_end_line = s->cr[0x11] & 0xf;
|
||||
vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
|
||||
(((s->cr[VGA_CRTC_OVERFLOW] & 1) |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
|
||||
vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
|
||||
((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
|
||||
vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
|
||||
|
||||
|
||||
|
||||
clocking_mode = (s->sr[0x01] >> 3) & 1;
|
||||
clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
|
||||
clock_sel = (s->msr >> 2) & 3;
|
||||
dots = (s->msr & 1) ? 8 : 9;
|
||||
|
||||
@ -261,8 +261,8 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
|
||||
r->htotal = htotal_chars;
|
||||
|
||||
#if 0
|
||||
div2 = (s->cr[0x17] >> 2) & 1;
|
||||
sldiv2 = (s->cr[0x17] >> 3) & 1;
|
||||
div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
|
||||
sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
|
||||
printf (
|
||||
"hz=%f\n"
|
||||
"htotal = %d\n"
|
||||
@ -332,7 +332,7 @@ static uint8_t vga_dumb_retrace(VGACommonState *s)
|
||||
|
||||
int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
|
||||
{
|
||||
if (s->msr & MSR_COLOR_EMULATION) {
|
||||
if (s->msr & VGA_MIS_COLOR) {
|
||||
/* Color */
|
||||
return (addr >= 0x3b0 && addr <= 0x3bf);
|
||||
} else {
|
||||
@ -350,73 +350,74 @@ uint32_t vga_ioport_read(void *opaque, uint32_t addr)
|
||||
val = 0xff;
|
||||
} else {
|
||||
switch(addr) {
|
||||
case 0x3c0:
|
||||
case VGA_ATT_W:
|
||||
if (s->ar_flip_flop == 0) {
|
||||
val = s->ar_index;
|
||||
} else {
|
||||
val = 0;
|
||||
}
|
||||
break;
|
||||
case 0x3c1:
|
||||
case VGA_ATT_R:
|
||||
index = s->ar_index & 0x1f;
|
||||
if (index < 21)
|
||||
if (index < VGA_ATT_C) {
|
||||
val = s->ar[index];
|
||||
else
|
||||
} else {
|
||||
val = 0;
|
||||
}
|
||||
break;
|
||||
case 0x3c2:
|
||||
case VGA_MIS_W:
|
||||
val = s->st00;
|
||||
break;
|
||||
case 0x3c4:
|
||||
case VGA_SEQ_I:
|
||||
val = s->sr_index;
|
||||
break;
|
||||
case 0x3c5:
|
||||
case VGA_SEQ_D:
|
||||
val = s->sr[s->sr_index];
|
||||
#ifdef DEBUG_VGA_REG
|
||||
printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
|
||||
#endif
|
||||
break;
|
||||
case 0x3c7:
|
||||
case VGA_PEL_IR:
|
||||
val = s->dac_state;
|
||||
break;
|
||||
case 0x3c8:
|
||||
case VGA_PEL_IW:
|
||||
val = s->dac_write_index;
|
||||
break;
|
||||
case 0x3c9:
|
||||
case VGA_PEL_D:
|
||||
val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
|
||||
if (++s->dac_sub_index == 3) {
|
||||
s->dac_sub_index = 0;
|
||||
s->dac_read_index++;
|
||||
}
|
||||
break;
|
||||
case 0x3ca:
|
||||
case VGA_FTC_R:
|
||||
val = s->fcr;
|
||||
break;
|
||||
case 0x3cc:
|
||||
case VGA_MIS_R:
|
||||
val = s->msr;
|
||||
break;
|
||||
case 0x3ce:
|
||||
case VGA_GFX_I:
|
||||
val = s->gr_index;
|
||||
break;
|
||||
case 0x3cf:
|
||||
case VGA_GFX_D:
|
||||
val = s->gr[s->gr_index];
|
||||
#ifdef DEBUG_VGA_REG
|
||||
printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
|
||||
#endif
|
||||
break;
|
||||
case 0x3b4:
|
||||
case 0x3d4:
|
||||
case VGA_CRT_IM:
|
||||
case VGA_CRT_IC:
|
||||
val = s->cr_index;
|
||||
break;
|
||||
case 0x3b5:
|
||||
case 0x3d5:
|
||||
case VGA_CRT_DM:
|
||||
case VGA_CRT_DC:
|
||||
val = s->cr[s->cr_index];
|
||||
#ifdef DEBUG_VGA_REG
|
||||
printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
|
||||
#endif
|
||||
break;
|
||||
case 0x3ba:
|
||||
case 0x3da:
|
||||
case VGA_IS1_RM:
|
||||
case VGA_IS1_RC:
|
||||
/* just toggle to fool polling */
|
||||
val = s->st01 = s->retrace(s);
|
||||
s->ar_flip_flop = 0;
|
||||
@ -446,29 +447,29 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
#endif
|
||||
|
||||
switch(addr) {
|
||||
case 0x3c0:
|
||||
case VGA_ATT_W:
|
||||
if (s->ar_flip_flop == 0) {
|
||||
val &= 0x3f;
|
||||
s->ar_index = val;
|
||||
} else {
|
||||
index = s->ar_index & 0x1f;
|
||||
switch(index) {
|
||||
case 0x00 ... 0x0f:
|
||||
case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
|
||||
s->ar[index] = val & 0x3f;
|
||||
break;
|
||||
case 0x10:
|
||||
case VGA_ATC_MODE:
|
||||
s->ar[index] = val & ~0x10;
|
||||
break;
|
||||
case 0x11:
|
||||
case VGA_ATC_OVERSCAN:
|
||||
s->ar[index] = val;
|
||||
break;
|
||||
case 0x12:
|
||||
case VGA_ATC_PLANE_ENABLE:
|
||||
s->ar[index] = val & ~0xc0;
|
||||
break;
|
||||
case 0x13:
|
||||
case VGA_ATC_PEL:
|
||||
s->ar[index] = val & ~0xf0;
|
||||
break;
|
||||
case 0x14:
|
||||
case VGA_ATC_COLOR_PAGE:
|
||||
s->ar[index] = val & ~0xf0;
|
||||
break;
|
||||
default:
|
||||
@ -477,32 +478,34 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
}
|
||||
s->ar_flip_flop ^= 1;
|
||||
break;
|
||||
case 0x3c2:
|
||||
case VGA_MIS_W:
|
||||
s->msr = val & ~0x10;
|
||||
s->update_retrace_info(s);
|
||||
break;
|
||||
case 0x3c4:
|
||||
case VGA_SEQ_I:
|
||||
s->sr_index = val & 7;
|
||||
break;
|
||||
case 0x3c5:
|
||||
case VGA_SEQ_D:
|
||||
#ifdef DEBUG_VGA_REG
|
||||
printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
|
||||
#endif
|
||||
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
|
||||
if (s->sr_index == 1) s->update_retrace_info(s);
|
||||
if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
|
||||
s->update_retrace_info(s);
|
||||
}
|
||||
vga_update_memory_access(s);
|
||||
break;
|
||||
case 0x3c7:
|
||||
case VGA_PEL_IR:
|
||||
s->dac_read_index = val;
|
||||
s->dac_sub_index = 0;
|
||||
s->dac_state = 3;
|
||||
break;
|
||||
case 0x3c8:
|
||||
case VGA_PEL_IW:
|
||||
s->dac_write_index = val;
|
||||
s->dac_sub_index = 0;
|
||||
s->dac_state = 0;
|
||||
break;
|
||||
case 0x3c9:
|
||||
case VGA_PEL_D:
|
||||
s->dac_cache[s->dac_sub_index] = val;
|
||||
if (++s->dac_sub_index == 3) {
|
||||
memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
|
||||
@ -510,48 +513,51 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
s->dac_write_index++;
|
||||
}
|
||||
break;
|
||||
case 0x3ce:
|
||||
case VGA_GFX_I:
|
||||
s->gr_index = val & 0x0f;
|
||||
break;
|
||||
case 0x3cf:
|
||||
case VGA_GFX_D:
|
||||
#ifdef DEBUG_VGA_REG
|
||||
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
|
||||
#endif
|
||||
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
|
||||
vga_update_memory_access(s);
|
||||
break;
|
||||
case 0x3b4:
|
||||
case 0x3d4:
|
||||
case VGA_CRT_IM:
|
||||
case VGA_CRT_IC:
|
||||
s->cr_index = val;
|
||||
break;
|
||||
case 0x3b5:
|
||||
case 0x3d5:
|
||||
case VGA_CRT_DM:
|
||||
case VGA_CRT_DC:
|
||||
#ifdef DEBUG_VGA_REG
|
||||
printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
|
||||
#endif
|
||||
/* handle CR0-7 protection */
|
||||
if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
|
||||
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 == 7)
|
||||
s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
|
||||
if (s->cr_index == VGA_CRTC_OVERFLOW) {
|
||||
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
|
||||
(val & 0x10);
|
||||
}
|
||||
return;
|
||||
}
|
||||
s->cr[s->cr_index] = val;
|
||||
|
||||
switch(s->cr_index) {
|
||||
case 0x00:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x11:
|
||||
case 0x17:
|
||||
case VGA_CRTC_H_TOTAL:
|
||||
case VGA_CRTC_H_SYNC_START:
|
||||
case VGA_CRTC_H_SYNC_END:
|
||||
case VGA_CRTC_V_TOTAL:
|
||||
case VGA_CRTC_OVERFLOW:
|
||||
case VGA_CRTC_V_SYNC_END:
|
||||
case VGA_CRTC_MODE:
|
||||
s->update_retrace_info(s);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3ba:
|
||||
case 0x3da:
|
||||
case VGA_IS1_RM:
|
||||
case VGA_IS1_RC:
|
||||
s->fcr = val & 0x10;
|
||||
break;
|
||||
}
|
||||
@ -681,31 +687,37 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
|
||||
/* we initialize the VGA graphic mode (should be done
|
||||
in BIOS) */
|
||||
s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
|
||||
s->cr[0x17] |= 3; /* no CGA modes */
|
||||
s->cr[0x13] = s->vbe_line_offset >> 3;
|
||||
/* graphic mode + memory map 1 */
|
||||
s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
|
||||
VGA_GR06_GRAPHICS_MODE;
|
||||
s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
|
||||
s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
|
||||
/* width */
|
||||
s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
|
||||
s->cr[VGA_CRTC_H_DISP] =
|
||||
(s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
|
||||
/* height (only meaningful if < 1024) */
|
||||
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
|
||||
s->cr[0x12] = h;
|
||||
s->cr[0x07] = (s->cr[0x07] & ~0x42) |
|
||||
s->cr[VGA_CRTC_V_DISP_END] = h;
|
||||
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
|
||||
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
|
||||
/* line compare to 1023 */
|
||||
s->cr[0x18] = 0xff;
|
||||
s->cr[0x07] |= 0x10;
|
||||
s->cr[0x09] |= 0x40;
|
||||
s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
|
||||
s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
|
||||
s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
||||
shift_control = 0;
|
||||
s->sr[0x01] &= ~8; /* no double line */
|
||||
s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
|
||||
} else {
|
||||
shift_control = 2;
|
||||
s->sr[4] |= 0x08; /* set chain 4 mode */
|
||||
s->sr[2] |= 0x0f; /* activate all planes */
|
||||
/* set chain 4 mode */
|
||||
s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
|
||||
/* activate all planes */
|
||||
s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
|
||||
}
|
||||
s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
|
||||
s->cr[0x09] &= ~0x9f; /* no double scan */
|
||||
s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
|
||||
(shift_control << 5);
|
||||
s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
|
||||
} else {
|
||||
/* XXX: the bios should do that */
|
||||
s->bank_offset = 0;
|
||||
@ -762,7 +774,7 @@ uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
|
||||
uint32_t ret;
|
||||
|
||||
/* convert to VGA memory offset */
|
||||
memory_map_mode = (s->gr[6] >> 2) & 3;
|
||||
memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
|
||||
addr &= 0x1ffff;
|
||||
switch(memory_map_mode) {
|
||||
case 0:
|
||||
@ -785,24 +797,25 @@ uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (s->sr[4] & 0x08) {
|
||||
if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
|
||||
/* chain 4 mode : simplest access */
|
||||
ret = s->vram_ptr[addr];
|
||||
} else if (s->gr[5] & 0x10) {
|
||||
} else if (s->gr[VGA_GFX_MODE] & 0x10) {
|
||||
/* odd/even mode (aka text mode mapping) */
|
||||
plane = (s->gr[4] & 2) | (addr & 1);
|
||||
plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
|
||||
ret = s->vram_ptr[((addr & ~1) << 1) | plane];
|
||||
} else {
|
||||
/* standard VGA latched access */
|
||||
s->latch = ((uint32_t *)s->vram_ptr)[addr];
|
||||
|
||||
if (!(s->gr[5] & 0x08)) {
|
||||
if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
|
||||
/* read mode 0 */
|
||||
plane = s->gr[4];
|
||||
plane = s->gr[VGA_GFX_PLANE_READ];
|
||||
ret = GET_PLANE(s->latch, plane);
|
||||
} else {
|
||||
/* read mode 1 */
|
||||
ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
|
||||
ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
|
||||
mask16[s->gr[VGA_GFX_COMPARE_MASK]];
|
||||
ret |= ret >> 16;
|
||||
ret |= ret >> 8;
|
||||
ret = (~ret) & 0xff;
|
||||
@ -821,7 +834,7 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
|
||||
printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
|
||||
#endif
|
||||
/* convert to VGA memory offset */
|
||||
memory_map_mode = (s->gr[6] >> 2) & 3;
|
||||
memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
|
||||
addr &= 0x1ffff;
|
||||
switch(memory_map_mode) {
|
||||
case 0:
|
||||
@ -844,11 +857,11 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
|
||||
break;
|
||||
}
|
||||
|
||||
if (s->sr[4] & 0x08) {
|
||||
if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
|
||||
/* chain 4 mode : simplest access */
|
||||
plane = addr & 3;
|
||||
mask = (1 << plane);
|
||||
if (s->sr[2] & mask) {
|
||||
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
|
||||
s->vram_ptr[addr] = val;
|
||||
#ifdef DEBUG_VGA_MEM
|
||||
printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
|
||||
@ -856,11 +869,11 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
|
||||
s->plane_updated |= mask; /* only used to detect font change */
|
||||
memory_region_set_dirty(&s->vram, addr, 1);
|
||||
}
|
||||
} else if (s->gr[5] & 0x10) {
|
||||
} else if (s->gr[VGA_GFX_MODE] & 0x10) {
|
||||
/* odd/even mode (aka text mode mapping) */
|
||||
plane = (s->gr[4] & 2) | (addr & 1);
|
||||
plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
|
||||
mask = (1 << plane);
|
||||
if (s->sr[2] & mask) {
|
||||
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
|
||||
addr = ((addr & ~1) << 1) | plane;
|
||||
s->vram_ptr[addr] = val;
|
||||
#ifdef DEBUG_VGA_MEM
|
||||
@ -871,40 +884,41 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
|
||||
}
|
||||
} else {
|
||||
/* standard VGA latched access */
|
||||
write_mode = s->gr[5] & 3;
|
||||
write_mode = s->gr[VGA_GFX_MODE] & 3;
|
||||
switch(write_mode) {
|
||||
default:
|
||||
case 0:
|
||||
/* rotate */
|
||||
b = s->gr[3] & 7;
|
||||
b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
|
||||
val = ((val >> b) | (val << (8 - b))) & 0xff;
|
||||
val |= val << 8;
|
||||
val |= val << 16;
|
||||
|
||||
/* apply set/reset mask */
|
||||
set_mask = mask16[s->gr[1]];
|
||||
val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
|
||||
bit_mask = s->gr[8];
|
||||
set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
|
||||
val = (val & ~set_mask) |
|
||||
(mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
|
||||
bit_mask = s->gr[VGA_GFX_BIT_MASK];
|
||||
break;
|
||||
case 1:
|
||||
val = s->latch;
|
||||
goto do_write;
|
||||
case 2:
|
||||
val = mask16[val & 0x0f];
|
||||
bit_mask = s->gr[8];
|
||||
bit_mask = s->gr[VGA_GFX_BIT_MASK];
|
||||
break;
|
||||
case 3:
|
||||
/* rotate */
|
||||
b = s->gr[3] & 7;
|
||||
b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
|
||||
val = (val >> b) | (val << (8 - b));
|
||||
|
||||
bit_mask = s->gr[8] & val;
|
||||
val = mask16[s->gr[0]];
|
||||
bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
|
||||
val = mask16[s->gr[VGA_GFX_SR_VALUE]];
|
||||
break;
|
||||
}
|
||||
|
||||
/* apply logical operation */
|
||||
func_select = s->gr[3] >> 3;
|
||||
func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
|
||||
switch(func_select) {
|
||||
case 0:
|
||||
default:
|
||||
@ -931,7 +945,7 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
|
||||
|
||||
do_write:
|
||||
/* mask data according to sr[2] */
|
||||
mask = s->sr[2];
|
||||
mask = s->sr[VGA_SEQ_PLANE_WRITE];
|
||||
s->plane_updated |= mask; /* only used to detect font change */
|
||||
write_mask = mask16[mask];
|
||||
((uint32_t *)s->vram_ptr)[addr] =
|
||||
@ -1045,10 +1059,11 @@ static int update_palette16(VGACommonState *s)
|
||||
palette = s->last_palette;
|
||||
for(i = 0; i < 16; i++) {
|
||||
v = s->ar[i];
|
||||
if (s->ar[0x10] & 0x80)
|
||||
v = ((s->ar[0x14] & 0xf) << 4) | (v & 0xf);
|
||||
else
|
||||
v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
|
||||
if (s->ar[VGA_ATC_MODE] & 0x80) {
|
||||
v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
|
||||
} else {
|
||||
v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
|
||||
}
|
||||
v = v * 3;
|
||||
col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
|
||||
c6_to_8(s->palette[v + 1]),
|
||||
@ -1104,16 +1119,17 @@ static void vga_get_offsets(VGACommonState *s,
|
||||
#endif
|
||||
{
|
||||
/* compute line_offset in bytes */
|
||||
line_offset = s->cr[0x13];
|
||||
line_offset = s->cr[VGA_CRTC_OFFSET];
|
||||
line_offset <<= 3;
|
||||
|
||||
/* starting address */
|
||||
start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
|
||||
start_addr = s->cr[VGA_CRTC_START_LO] |
|
||||
(s->cr[VGA_CRTC_START_HI] << 8);
|
||||
|
||||
/* line compare */
|
||||
line_compare = s->cr[0x18] |
|
||||
((s->cr[0x07] & 0x10) << 4) |
|
||||
((s->cr[0x09] & 0x40) << 3);
|
||||
line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
|
||||
((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
|
||||
}
|
||||
*pline_offset = line_offset;
|
||||
*pstart_addr = start_addr;
|
||||
@ -1216,20 +1232,22 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight
|
||||
int width, cwidth, height, cheight;
|
||||
|
||||
/* total width & height */
|
||||
cheight = (s->cr[9] & 0x1f) + 1;
|
||||
cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
|
||||
cwidth = 8;
|
||||
if (!(s->sr[1] & 0x01))
|
||||
if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
|
||||
cwidth = 9;
|
||||
if (s->sr[1] & 0x08)
|
||||
}
|
||||
if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
|
||||
cwidth = 16; /* NOTE: no 18 pixel wide */
|
||||
width = (s->cr[0x01] + 1);
|
||||
if (s->cr[0x06] == 100) {
|
||||
}
|
||||
width = (s->cr[VGA_CRTC_H_DISP] + 1);
|
||||
if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
|
||||
/* ugly hack for CGA 160x100x16 - explain me the logic */
|
||||
height = 100;
|
||||
} else {
|
||||
height = s->cr[0x12] |
|
||||
((s->cr[0x07] & 0x02) << 7) |
|
||||
((s->cr[0x07] & 0x40) << 3);
|
||||
height = s->cr[VGA_CRTC_V_DISP_END] |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
|
||||
height = (height + 1) / cheight;
|
||||
}
|
||||
|
||||
@ -1273,7 +1291,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
|
||||
vga_draw_glyph9_func *vga_draw_glyph9;
|
||||
|
||||
/* compute font data address (in plane 2) */
|
||||
v = s->sr[3];
|
||||
v = s->sr[VGA_SEQ_CHARACTER_MAP];
|
||||
offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
|
||||
if (offset != s->font_offsets[0]) {
|
||||
s->font_offsets[0] = offset;
|
||||
@ -1321,10 +1339,11 @@ static void vga_draw_text(VGACommonState *s, int full_update)
|
||||
palette = s->last_palette;
|
||||
x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
|
||||
|
||||
cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
|
||||
cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
|
||||
s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
|
||||
if (cursor_offset != s->cursor_offset ||
|
||||
s->cr[0xa] != s->cursor_start ||
|
||||
s->cr[0xb] != s->cursor_end) {
|
||||
s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
|
||||
s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
|
||||
/* if the cursor position changed, we update the old and new
|
||||
chars */
|
||||
if (s->cursor_offset < CH_ATTR_SIZE)
|
||||
@ -1332,8 +1351,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
|
||||
if (cursor_offset < CH_ATTR_SIZE)
|
||||
s->last_ch_attr[cursor_offset] = -1;
|
||||
s->cursor_offset = cursor_offset;
|
||||
s->cursor_start = s->cr[0xa];
|
||||
s->cursor_end = s->cr[0xb];
|
||||
s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
|
||||
s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
|
||||
}
|
||||
cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
|
||||
|
||||
@ -1378,17 +1397,19 @@ static void vga_draw_text(VGACommonState *s, int full_update)
|
||||
font_ptr, cheight, fgcol, bgcol);
|
||||
} else {
|
||||
dup9 = 0;
|
||||
if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
|
||||
if (ch >= 0xb0 && ch <= 0xdf &&
|
||||
(s->ar[VGA_ATC_MODE] & 0x04)) {
|
||||
dup9 = 1;
|
||||
}
|
||||
vga_draw_glyph9(d1, linesize,
|
||||
font_ptr, cheight, fgcol, bgcol, dup9);
|
||||
}
|
||||
if (src == cursor_ptr &&
|
||||
!(s->cr[0x0a] & 0x20)) {
|
||||
!(s->cr[VGA_CRTC_CURSOR_START] & 0x20)) {
|
||||
int line_start, line_last, h;
|
||||
/* draw the cursor */
|
||||
line_start = s->cr[0x0a] & 0x1f;
|
||||
line_last = s->cr[0x0b] & 0x1f;
|
||||
line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
|
||||
line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
|
||||
/* XXX: check that */
|
||||
if (line_last > cheight - 1)
|
||||
line_last = cheight - 1;
|
||||
@ -1544,10 +1565,10 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
width = (s->cr[0x01] + 1) * 8;
|
||||
height = s->cr[0x12] |
|
||||
((s->cr[0x07] & 0x02) << 7) |
|
||||
((s->cr[0x07] & 0x40) << 3);
|
||||
width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
|
||||
height = s->cr[VGA_CRTC_V_DISP_END] |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
|
||||
height = (height + 1);
|
||||
}
|
||||
*pwidth = width;
|
||||
@ -1602,10 +1623,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
s->get_resolution(s, &width, &height);
|
||||
disp_width = width;
|
||||
|
||||
shift_control = (s->gr[0x05] >> 5) & 3;
|
||||
double_scan = (s->cr[0x09] >> 7);
|
||||
shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
|
||||
double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
|
||||
if (shift_control != 1) {
|
||||
multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
|
||||
multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
|
||||
- 1;
|
||||
} else {
|
||||
/* in CGA modes, multi_scan is ignored */
|
||||
/* XXX: is it correct ? */
|
||||
@ -1620,11 +1642,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
}
|
||||
|
||||
if (shift_control == 0) {
|
||||
if (s->sr[0x01] & 8) {
|
||||
if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
|
||||
disp_width <<= 1;
|
||||
}
|
||||
} else if (shift_control == 1) {
|
||||
if (s->sr[0x01] & 8) {
|
||||
if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
|
||||
disp_width <<= 1;
|
||||
}
|
||||
}
|
||||
@ -1668,7 +1690,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
|
||||
if (shift_control == 0) {
|
||||
full_update |= update_palette16(s);
|
||||
if (s->sr[0x01] & 8) {
|
||||
if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
|
||||
v = VGA_DRAW_LINE4D2;
|
||||
} else {
|
||||
v = VGA_DRAW_LINE4;
|
||||
@ -1676,7 +1698,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
bits = 4;
|
||||
} else if (shift_control == 1) {
|
||||
full_update |= update_palette16(s);
|
||||
if (s->sr[0x01] & 8) {
|
||||
if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
|
||||
v = VGA_DRAW_LINE2D2;
|
||||
} else {
|
||||
v = VGA_DRAW_LINE2;
|
||||
@ -1721,7 +1743,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
line_offset = s->line_offset;
|
||||
#if 0
|
||||
printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
|
||||
width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
|
||||
width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
|
||||
s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
|
||||
#endif
|
||||
addr1 = (s->start_addr * 4);
|
||||
bwidth = (width * bits + 7) / 8;
|
||||
@ -1733,13 +1756,13 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
y1 = 0;
|
||||
for(y = 0; y < height; y++) {
|
||||
addr = addr1;
|
||||
if (!(s->cr[0x17] & 1)) {
|
||||
if (!(s->cr[VGA_CRTC_MODE] & 1)) {
|
||||
int shift;
|
||||
/* CGA compatibility handling */
|
||||
shift = 14 + ((s->cr[0x17] >> 6) & 1);
|
||||
shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
|
||||
addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
|
||||
}
|
||||
if (!(s->cr[0x17] & 2)) {
|
||||
if (!(s->cr[VGA_CRTC_MODE] & 2)) {
|
||||
addr = (addr & ~0x8000) | ((y1 & 2) << 14);
|
||||
}
|
||||
page0 = addr;
|
||||
@ -1769,7 +1792,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
}
|
||||
}
|
||||
if (!multi_run) {
|
||||
mask = (s->cr[0x17] & 3) ^ 3;
|
||||
mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
|
||||
if ((y1 & mask) == mask)
|
||||
addr1 += line_offset;
|
||||
y1++;
|
||||
@ -1841,7 +1864,7 @@ static void vga_update_display(void *opaque)
|
||||
if (!(s->ar_index & 0x20)) {
|
||||
graphic_mode = GMODE_BLANK;
|
||||
} else {
|
||||
graphic_mode = s->gr[6] & 1;
|
||||
graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
|
||||
}
|
||||
if (graphic_mode != s->graphic_mode) {
|
||||
s->graphic_mode = graphic_mode;
|
||||
@ -1959,7 +1982,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
|
||||
if (!(s->ar_index & 0x20)) {
|
||||
graphic_mode = GMODE_BLANK;
|
||||
} else {
|
||||
graphic_mode = s->gr[6] & 1;
|
||||
graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
|
||||
}
|
||||
if (graphic_mode != s->graphic_mode) {
|
||||
s->graphic_mode = graphic_mode;
|
||||
@ -1976,20 +1999,22 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
|
||||
full_update |= update_basic_params(s);
|
||||
|
||||
/* total width & height */
|
||||
cheight = (s->cr[9] & 0x1f) + 1;
|
||||
cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
|
||||
cw = 8;
|
||||
if (!(s->sr[1] & 0x01))
|
||||
if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
|
||||
cw = 9;
|
||||
if (s->sr[1] & 0x08)
|
||||
}
|
||||
if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
|
||||
cw = 16; /* NOTE: no 18 pixel wide */
|
||||
width = (s->cr[0x01] + 1);
|
||||
if (s->cr[0x06] == 100) {
|
||||
}
|
||||
width = (s->cr[VGA_CRTC_H_DISP] + 1);
|
||||
if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
|
||||
/* ugly hack for CGA 160x100x16 - explain me the logic */
|
||||
height = 100;
|
||||
} else {
|
||||
height = s->cr[0x12] |
|
||||
((s->cr[0x07] & 0x02) << 7) |
|
||||
((s->cr[0x07] & 0x40) << 3);
|
||||
height = s->cr[VGA_CRTC_V_DISP_END] |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
|
||||
((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
|
||||
height = (height + 1) / cheight;
|
||||
}
|
||||
|
||||
@ -2018,11 +2043,12 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
|
||||
}
|
||||
|
||||
/* Update "hardware" cursor */
|
||||
cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
|
||||
cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
|
||||
s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
|
||||
if (cursor_offset != s->cursor_offset ||
|
||||
s->cr[0xa] != s->cursor_start ||
|
||||
s->cr[0xb] != s->cursor_end || full_update) {
|
||||
cursor_visible = !(s->cr[0xa] & 0x20);
|
||||
s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
|
||||
s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
|
||||
cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
|
||||
if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
|
||||
dpy_cursor(s->ds,
|
||||
TEXTMODE_X(cursor_offset),
|
||||
@ -2030,8 +2056,8 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
|
||||
else
|
||||
dpy_cursor(s->ds, -1, -1);
|
||||
s->cursor_offset = cursor_offset;
|
||||
s->cursor_start = s->cr[0xa];
|
||||
s->cursor_end = s->cr[0xb];
|
||||
s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
|
||||
s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
|
||||
}
|
||||
|
||||
src = (uint32_t *) s->vram_ptr + s->start_addr;
|
||||
|
@ -25,9 +25,6 @@
|
||||
#include <hw/hw.h>
|
||||
#include "memory.h"
|
||||
|
||||
#define MSR_COLOR_EMULATION 0x01
|
||||
#define MSR_PAGE_SELECT 0x20
|
||||
|
||||
#define ST01_V_RETRACE 0x08
|
||||
#define ST01_DISP_ENABLE 0x01
|
||||
|
||||
|
@ -161,7 +161,7 @@ static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d,
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[0x12] & 0xf];
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
@ -203,7 +203,7 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[0x12] & 0xf];
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
@ -236,7 +236,7 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[0x12] & 0xf];
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
@ -268,7 +268,7 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[0x12] & 0xf];
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
|
Loading…
x
Reference in New Issue
Block a user