Update tandy shake code for latest master changes

This commit is contained in:
pixel-jupiter
2025-09-02 02:02:01 +03:00
parent c351d5cbee
commit aa5a7e4079
4 changed files with 136 additions and 48 deletions

View File

@@ -36,6 +36,15 @@ typedef struct t1kvid_t {
uint8_t planar_ctrl;
uint8_t lp_strobe;
uint8_t baseline_hsyncpos;
uint8_t baseline_vsyncpos;
uint8_t last_hdisp;
uint8_t last_vdisp;
int calib_countdown;
int baseline_ready;
int hsync_offset;
int vsync_offset;
int linepos;
int displine;
int scanline;

View File

@@ -125,6 +125,7 @@ extern void cga_recalctimings(cga_t *cga);
extern void cga_interpolate_init(void);
extern void cga_blit_memtoscreen(int x, int y, int w, int h, int double_type);
extern void cga_do_blit(int vid_xsize, int firstline, int lastline, int double_type);
extern void cga_do_blit_tandy(int vid_xsize, int firstline, int lastline, int double_type, int hsync_offset, int vsync_offset);
extern void cga_poll(void *priv);
//#ifdef EMU_DEVICE_H

View File

@@ -545,6 +545,34 @@ cga_do_blit(int vid_xsize, int firstline, int lastline, int double_type)
}
}
void
cga_do_blit_tandy(int vid_xsize, int firstline, int lastline, int double_type, int hsync_offset, int vsync_offset)
{
if (double_type > DOUBLE_NONE) {
if (enable_overscan) {
cga_blit_memtoscreen(0 + hsync_offset, ((firstline - 8) << 1) + (vsync_offset << 1),
vid_xsize, ((lastline - firstline) + 16) << 1,
double_type
);
} else {
cga_blit_memtoscreen(16 + hsync_offset, (firstline << 1) + (vsync_offset << 1),
vid_xsize, (lastline - firstline) << 1,
double_type
);
}
} else {
if (enable_overscan) {
video_blit_memtoscreen(0 + hsync_offset, (firstline - 8) + vsync_offset,
vid_xsize, (lastline - firstline) + 8
);
} else {
video_blit_memtoscreen(16 + hsync_offset, firstline + vsync_offset,
vid_xsize, lastline - firstline
);
}
}
}
void
cga_poll(void *priv)
{

View File

@@ -164,6 +164,47 @@ vid_update_latch(t1kvid_t *vid)
vid->crtc[0x11] = lp_latch & 0xff;
}
static void
vid_update_display_offset(t1kvid_t *vid)
{
const int calib_frames = 12;
const int hsync_scale = 16;
const int vsync_scale = 4;
if (vid->crtc[1] != vid->last_hdisp || vid->crtc[6] != vid->last_vdisp) {
vid->last_hdisp = vid->crtc[1];
vid->last_vdisp = vid->crtc[6];
vid->calib_countdown = calib_frames;
vid->baseline_ready = 0;
vid->hsync_offset = 0;
vid->vsync_offset = 0;
return;
}
if (vid->calib_countdown > 0) {
vid->calib_countdown--;
vid->baseline_hsyncpos = vid->crtc[2];
vid->baseline_vsyncpos = vid->crtc[7];
vid->hsync_offset = 0;
vid->vsync_offset = 0;
if (vid->calib_countdown == 0)
vid->baseline_ready = 1;
return;
}
if (!vid->baseline_ready) {
vid->hsync_offset = 0;
vid->vsync_offset = 0;
return;
}
int hsync_deviation = (int)vid->baseline_hsyncpos - (int)vid->crtc[2];
int vsync_deviation = (int)vid->baseline_vsyncpos - (int)vid->crtc[7];
vid->hsync_offset = hsync_deviation * hsync_scale;
vid->vsync_offset = vsync_deviation * vsync_scale;
}
void
tandy_vid_out(uint16_t addr, uint8_t val, void *priv)
{
@@ -190,6 +231,7 @@ tandy_vid_out(uint16_t addr, uint8_t val, void *priv)
vid->fullchange = changeframecount;
recalc_timings(dev);
}
vid_update_display_offset(vid);
}
break;
@@ -354,25 +396,25 @@ vid_render(tandy_t *dev, int line)
cols[0] = (vid->array[2] & 0xf) + 16;
for (c = 0; c < 8; c++) {
for (c = 0; c < 16; c++) {
if (vid->array[3] & 4) {
buffer32->line[line][c] = cols[0];
if (vid->mode & 1)
buffer32->line[line][c + (vid->crtc[1] << 3) + 8] = cols[0];
buffer32->line[line][c + (vid->crtc[1] << 3) + 16] = cols[0];
else
buffer32->line[line][c + (vid->crtc[1] << 4) + 8] = cols[0];
buffer32->line[line][c + (vid->crtc[1] << 4) + 16] = cols[0];
} else if ((vid->mode & 0x12) == 0x12) {
buffer32->line[line][c] = 0;
if (vid->mode & 1)
buffer32->line[line][c + (vid->crtc[1] << 3) + 8] = 0;
buffer32->line[line][c + (vid->crtc[1] << 3) + 16] = 0;
else
buffer32->line[line][c + (vid->crtc[1] << 4) + 8] = 0;
buffer32->line[line][c + (vid->crtc[1] << 4) + 16] = 0;
} else {
buffer32->line[line][c] = buffer32->line[(line) + 1][c] = (vid->col & 15) + 16;
if (vid->mode & 1)
buffer32->line[line][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16;
buffer32->line[line][c + (vid->crtc[1] << 3) + 16] = (vid->col & 15) + 16;
else
buffer32->line[line][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16;
buffer32->line[line][c + (vid->crtc[1] << 4) + 16] = (vid->col & 15) + 16;
}
}
@@ -380,23 +422,23 @@ vid_render(tandy_t *dev, int line)
for (x = 0; x < vid->crtc[1] * 2; x++) {
dat = (vid->vram[(vid->memaddr << 1) & 0xffff] << 8) | vid->vram[((vid->memaddr << 1) + 1) & 0xffff];
vid->memaddr++;
buffer32->line[line][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 11] = vid->array[(dat & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 16] = vid->array[((dat >> 12) & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 17] = vid->array[((dat >> 8) & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 18] = vid->array[((dat >> 4) & 0xf) + 16] + 16;
buffer32->line[line][(x << 2) + 19] = vid->array[(dat & 0xf) + 16] + 16;
}
} else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/
for (x = 0; x < vid->crtc[1]; x++) {
dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) |
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1];
vid->memaddr++;
buffer32->line[line][(x << 3) + 8] = buffer32->line[line][(x << 3) + 9] =
buffer32->line[line][(x << 3) + 16] = buffer32->line[line][(x << 3) + 17] =
vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 3) + 10] = buffer32->line[line][(x << 3) + 11] =
buffer32->line[line][(x << 3) + 18] = buffer32->line[line][(x << 3) + 19] =
vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 3) + 12] = buffer32->line[line][(x << 3) + 13] =
buffer32->line[line][(x << 3) + 20] = buffer32->line[line][(x << 3) + 21] =
vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 3) + 14] = buffer32->line[line][(x << 3) + 15] =
buffer32->line[line][(x << 3) + 22] = buffer32->line[line][(x << 3) + 23] =
vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
}
} else if (vid->array[3] & 0x10) { /*160x200x16*/
@@ -408,17 +450,17 @@ vid_render(tandy_t *dev, int line)
dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) |
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1];
vid->memaddr++;
buffer32->line[line][(x << 4) + 8] = buffer32->line[line][(x << 4) + 9] =
buffer32->line[line][(x << 4) + 10] = buffer32->line[line][(x << 4) + 11] =
vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 4) + 12] = buffer32->line[line][(x << 4) + 13] =
buffer32->line[line][(x << 4) + 14] = buffer32->line[line][(x << 4) + 15] =
vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 4) + 16] = buffer32->line[line][(x << 4) + 17] =
buffer32->line[line][(x << 4) + 18] = buffer32->line[line][(x << 4) + 19] =
vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 4) + 20] = buffer32->line[line][(x << 4) + 21] =
buffer32->line[line][(x << 4) + 22] = buffer32->line[line][(x << 4) + 23] =
vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 4) + 24] = buffer32->line[line][(x << 4) + 25] =
buffer32->line[line][(x << 4) + 26] = buffer32->line[line][(x << 4) + 27] =
vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
buffer32->line[line][(x << 4) + 28] = buffer32->line[line][(x << 4) + 29] =
buffer32->line[line][(x << 4) + 30] = buffer32->line[line][(x << 4) + 31] =
vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
}
} else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/
@@ -429,7 +471,7 @@ vid_render(tandy_t *dev, int line)
for (c = 0; c < 8; c++) {
chr = (dat >> 6) & 2;
chr |= ((dat >> 15) & 1);
buffer32->line[line][(x << 3) + 8 + c] =
buffer32->line[line][(x << 3) + 16 + c] =
vid->array[(chr & vid->array[1]) + 16] + 16;
dat <<= 1;
}
@@ -449,16 +491,16 @@ vid_render(tandy_t *dev, int line)
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
}
if (vid->scanline & 8) for (c = 0; c < 8; c++)
buffer32->line[line][(x << 3) + c + 8] =
buffer32->line[line][(x << 3) + c + 16] =
((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0];
else for (c = 0; c < 8; c++) {
if (vid->scanline == 8)
buffer32->line[line][(x << 3) + c + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[line][(x << 3) + c + 16] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
else
buffer32->line[line][(x << 3) + c + 8] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[line][(x << 3) + c + 16] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
if (drawcursor) for (c = 0; c < 8; c++)
buffer32->line[line][(x << 3) + c + 8] ^= 15;
buffer32->line[line][(x << 3) + c + 16] ^= 15;
vid->memaddr++;
}
} else if (!(vid->mode & 2)) {
@@ -477,21 +519,21 @@ vid_render(tandy_t *dev, int line)
}
vid->memaddr++;
if (vid->scanline & 8) for (c = 0; c < 8; c++)
buffer32->line[line][(x << 4) + (c << 1) + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 16] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 16] =
((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0];
else for (c = 0; c < 8; c++) {
if (vid->scanline == 8)
buffer32->line[line][(x << 4) + (c << 1) + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 16] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 16] =
cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
else
buffer32->line[line][(x << 4) + (c << 1) + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 16] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 16] =
cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
if (drawcursor) for (c = 0; c < 16; c++)
buffer32->line[line][(x << 4) + c + 8] ^= 15;
buffer32->line[line][(x << 4) + c + 16] ^= 15;
}
} else if (!(vid->mode & 16)) {
cols[0] = (vid->col & 15);
@@ -518,8 +560,8 @@ vid_render(tandy_t *dev, int line)
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1];
vid->memaddr++;
for (c = 0; c < 8; c++) {
buffer32->line[line][(x << 4) + (c << 1) + 8] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
buffer32->line[line][(x << 4) + (c << 1) + 16] =
buffer32->line[line][(x << 4) + (c << 1) + 1 + 16] = cols[dat >> 14];
dat <<= 2;
}
}
@@ -531,7 +573,7 @@ vid_render(tandy_t *dev, int line)
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1];
vid->memaddr++;
for (c = 0; c < 16; c++) {
buffer32->line[line][(x << 4) + c + 8] = buffer32->line[(line) + 1][(x << 4) + c + 8] = cols[dat >> 15];
buffer32->line[line][(x << 4) + c + 16] = buffer32->line[(line) + 1][(x << 4) + c + 16] = cols[dat >> 15];
dat <<= 1;
}
}
@@ -545,16 +587,16 @@ vid_render_blank(tandy_t *dev, int line)
if (vid->array[3] & 4) {
if (vid->mode & 1)
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 32, (vid->array[2] & 0xf) + 16);
else
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 32, (vid->array[2] & 0xf) + 16);
} else {
int cols = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16;
if (vid->mode & 1)
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, cols);
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 32, cols);
else
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 16, cols);
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 32, cols);
}
}
@@ -565,9 +607,9 @@ vid_render_process(tandy_t *dev, int line)
int x;
if (vid->mode & 1)
x = (vid->crtc[1] << 3) + 16;
x = (vid->crtc[1] << 3) + 32;
else
x = (vid->crtc[1] << 4) + 16;
x = (vid->crtc[1] << 4) + 32;
if (!dev->is_sl2 && vid->composite)
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[line]);
@@ -704,9 +746,9 @@ vid_poll(void *priv)
picint(1 << 5);
if (vid->crtc[7]) {
if (vid->mode & 1)
x = (vid->crtc[1] << 3) + 16;
x = (vid->crtc[1] << 3) + 32;
else
x = (vid->crtc[1] << 4) + 16;
x = (vid->crtc[1] << 4) + 32;
vid->lastline++;
xs_temp = x;
@@ -718,18 +760,18 @@ vid_poll(void *priv)
if (ys_temp < 32)
ys_temp = 400;
if (!enable_overscan)
xs_temp -= 16;
xs_temp -= 32;
if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) {
xsize = xs_temp;
ysize = ys_temp;
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
set_screen_size(xsize, ysize + (enable_overscan ? 32 : 0));
if (video_force_resize_get())
video_force_resize_set(0);
}
cga_do_blit(xsize, vid->firstline, vid->lastline, vid->double_type);
cga_do_blit_tandy(xsize, vid->firstline, vid->lastline, vid->double_type, vid->hsync_offset, vid->vsync_offset);
}
frames++;
@@ -797,6 +839,14 @@ tandy_vid_init(tandy_t *dev)
t1kvid_t *vid;
vid = calloc(1, sizeof(t1kvid_t));
vid->baseline_hsyncpos = 0;
vid->baseline_vsyncpos = 0;
vid->last_hdisp = 0xFF;
vid->last_vdisp = 0xFF;
vid->calib_countdown = 0;
vid->baseline_ready = 0;
vid->hsync_offset = 0;
vid->vsync_offset = 0;
vid->memctrl = -1;
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);