nv2a: Fix VGA get_bpp for X1R5G5B5

This commit is contained in:
Jannik Vogel 2019-06-26 08:07:24 +02:00 committed by mborgerson
parent f9b9a9bad8
commit 2dc570561e
4 changed files with 39 additions and 4 deletions

View File

@ -317,10 +317,37 @@ static void nv2a_overlay_draw_line(VGACommonState *vga, uint8_t *line, int y)
static int nv2a_get_bpp(VGACommonState *s)
{
if ((s->cr[0x28] & 3) == 3) {
return 32;
NV2AState *d = container_of(s, NV2AState, vga);
int depth = s->cr[0x28] & 3;
int bpp;
switch (depth) {
case 0:
/* FIXME: This case is sometimes hit during early Xbox startup.
* Presumably a race-condition where VGA isn't initialized, yet.
* `bpp = 0` mimics old code that did `bpp = depth * 8;`.
* This works around the issue of this mode being unhandled.
* However, QEMU VGA uses a 4bpp mode if `bpp = 0`.
* We don't know if Xbox hardware would do the same. */
bpp = 0;
break;
case 2:
bpp = d->pramdac.general_control &
NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL ? 16 : 15;
break;
case 3:
bpp = 32;
break;
default:
/* This is only a fallback path */
bpp = depth * 8;
fprintf(stderr, "Unknown VGA depth: %d\n", depth);
assert(false);
break;
}
return (s->cr[0x28] & 3) * 8;
return bpp;
}
static void nv2a_get_offsets(VGACommonState *s,

View File

@ -330,6 +330,7 @@ typedef struct NV2AState {
uint64_t core_clock_freq;
uint32_t memory_clock_coeff;
uint32_t video_clock_coeff;
uint32_t general_control;
} pramdac;
} NV2AState;

View File

@ -41,6 +41,9 @@ uint64_t pramdac_read(void *opaque, hwaddr addr, unsigned int size)
| NV_PRAMDAC_PLL_TEST_COUNTER_MPLL_LOCK
| NV_PRAMDAC_PLL_TEST_COUNTER_VPLL_LOCK;
break;
case NV_PRAMDAC_GENERAL_CONTROL:
r = d->pramdac.general_control;
break;
default:
break;
}
@ -81,6 +84,9 @@ void pramdac_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size)
case NV_PRAMDAC_VPLL_COEFF:
d->pramdac.video_clock_coeff = val;
break;
case NV_PRAMDAC_GENERAL_CONTROL:
d->pramdac.general_control = val;
break;
default:
break;
}

View File

@ -678,7 +678,8 @@
# define NV_PRAMDAC_PLL_TEST_COUNTER_NVPLL_LOCK (1 << 29)
# define NV_PRAMDAC_PLL_TEST_COUNTER_MPLL_LOCK (1 << 30)
# define NV_PRAMDAC_PLL_TEST_COUNTER_VPLL_LOCK (1 << 31)
#define NV_PRAMDAC_GENERAL_CONTROL 0x00000600
# define NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL (1 << 12)
#define NV_USER_DMA_PUT 0x40
#define NV_USER_DMA_GET 0x44