Implemented Hercules overscan, closes #1638.

This commit is contained in:
OBattler
2021-09-05 20:30:43 +02:00
parent b834365f30
commit 6536a04590

View File

@@ -275,6 +275,38 @@ hercules_read(uint32_t addr, void *priv)
}
static void
hercules_render_overscan_left(hercules_t *dev)
{
int i;
if ((dev->displine + 14) < 0)
return;
if ((((uint32_t) dev->crtc[1]) * 9) == 0)
return;
for (i = 0; i < 8; i++)
buffer32->line[dev->displine + 14][i] = 0x00000000;
}
static void
hercules_render_overscan_right(hercules_t *dev)
{
int i;
if ((dev->displine + 14) < 0)
return;
if ((((uint32_t) dev->crtc[1]) * 9) == 0)
return;
for (i = 0; i < 8; i++)
buffer32->line[dev->displine + 14][8 + (((uint32_t) dev->crtc[1]) * 9) + i] = 0x00000000;
}
static void
hercules_poll(void *priv)
{
@@ -283,8 +315,9 @@ hercules_poll(void *priv)
uint16_t ca, dat;
uint16_t pa;
int oldsc, blink;
int x, c, oldvc;
int x, xx, y, yy, c, oldvc;
int drawcursor;
uint32_t *p;
ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
@@ -304,6 +337,8 @@ hercules_poll(void *priv)
}
dev->lastline = dev->displine;
hercules_render_overscan_left(dev);
if (dev->ctrl & 0x02) {
ca = (dev->sc & 3) * 0x2000;
if (dev->ctrl & 0x80)
@@ -316,9 +351,9 @@ hercules_poll(void *priv)
dat = 0;
dev->ma++;
for (c = 0; c < 16; c++)
buffer32->line[dev->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0;
buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0;
for (c = 0; c < 16; c += 8)
video_blend((x << 4) + c, dev->displine);
video_blend((x << 4) + c + 8, dev->displine + 14);
}
} else {
for (x = 0; x < dev->crtc[1]; x++) {
@@ -334,15 +369,15 @@ hercules_poll(void *priv)
if (dev->sc == 12 && ((attr & 7) == 1)) {
for (c = 0; c < 9; c++)
buffer32->line[dev->displine][(x * 9) + c] = dev->cols[attr][blink][1];
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1];
} else {
for (c = 0; c < 8; c++)
buffer32->line[dev->displine][(x * 9) + c] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0];
if ((chr & ~0x1f) == 0xc0)
buffer32->line[dev->displine][(x * 9) + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1];
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1];
else
buffer32->line[dev->displine][(x * 9) + 8] = dev->cols[attr][blink][0];
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0];
}
if (dev->ctrl2 & 0x01)
dev->ma = (dev->ma + 1) & 0x3fff;
@@ -351,10 +386,12 @@ hercules_poll(void *priv)
if (drawcursor) {
for (c = 0; c < 9; c++)
buffer32->line[dev->displine][(x * 9) + c] ^= dev->cols[attr][0][1];
buffer32->line[dev->displine + 14][(x * 9) + c + 8] ^= dev->cols[attr][0][1];
}
}
}
hercules_render_overscan_right(dev);
}
dev->sc = oldsc;
@@ -436,19 +473,41 @@ hercules_poll(void *priv)
x = dev->crtc[1] * 9;
dev->lastline++;
if ((dev->ctrl & 8) && x && (dev->lastline - dev->firstline) &&
((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) {
y = (dev->lastline - dev->firstline);
if ((dev->ctrl & 8) && x && y && ((x != xsize) || (y != ysize) || video_force_resize_get())) {
xsize = x;
ysize = dev->lastline - dev->firstline;
if (xsize < 64) xsize = 656;
ysize = y;
if (xsize < 64) xsize = enable_overscan ? 640 : 656;
if (ysize < 32) ysize = 200;
set_screen_size(xsize, ysize);
set_screen_size(xsize + (enable_overscan ? 16 : 0), ysize + (enable_overscan ? 28 : 0));
if (video_force_resize_get())
video_force_resize_set(0);
}
video_blit_memtoscreen_8(0, dev->firstline, 0, ysize, xsize, ysize);
if ((x >= 160) && ((y + 1) >= 120)) {
/* Draw (overscan_size) lines of overscan on top and bottom. */
for (yy = 0; yy < 14; yy++) {
p = &(buffer32->line[(dev->firstline + yy) & 0x7ff][0]);
for (xx = 0; xx < (x + 16); xx++)
p[xx] = 0x00000000;
}
for (yy = 0; yy < 14; yy++) {
p = &(buffer32->line[(dev->firstline + 14 + y + yy) & 0x7ff][0]);
for (xx = 0; xx < (x + 16); xx++)
p[xx] = 0x00000000;
}
}
if (enable_overscan)
video_blit_memtoscreen_8(0, dev->firstline, 0, ysize + 28, xsize + 16, ysize + 28);
else
video_blit_memtoscreen_8(8, dev->firstline + 14, 0, ysize + 14, xsize, ysize);
frames++;
// if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) {
if (dev->ctrl & 0x02) {
@@ -493,6 +552,9 @@ hercules_init(const device_t *info)
dev = (hercules_t *)malloc(sizeof(hercules_t));
memset(dev, 0x00, sizeof(hercules_t));
overscan_x = 16;
overscan_y = 28;
dev->vram = (uint8_t *)malloc(0x10000);
timer_add(&dev->timer, hercules_poll, dev, 1);