Tandy 1000 and PCjr now use reengine's composite emulation

This commit is contained in:
SarahW 2016-12-14 21:10:17 +00:00
commit bdbbf687af
5 changed files with 47 additions and 154 deletions

View file

@ -67,7 +67,7 @@ static Bit8u byte_clamp_other(int v) { return v < 0 ? 0 : (v > 255 ? 255 : v); }
FILE *df; FILE *df;
void update_cga16_color(cga_t *cga) { void update_cga16_color(uint8_t cgamode) {
int x; int x;
Bit32u x2; Bit32u x2;
@ -83,7 +83,7 @@ void update_cga16_color(cga_t *cga) {
} }
mode_contrast = 256/(max_v - min_v); mode_contrast = 256/(max_v - min_v);
mode_brightness = -min_v*mode_contrast; mode_brightness = -min_v*mode_contrast;
if ((cga->cgamode & 3) == 1) if ((cgamode & 3) == 1)
mode_hue = 14; mode_hue = 14;
else else
mode_hue = 4; mode_hue = 4;
@ -98,7 +98,7 @@ void update_cga16_color(cga_t *cga) {
int left = (x >> 6) & 15; int left = (x >> 6) & 15;
int rc = right; int rc = right;
int lc = left; int lc = left;
if ((cga->cgamode & 4) != 0) { if ((cgamode & 4) != 0) {
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
} }
@ -156,7 +156,7 @@ static int temp[SCALER_MAXWIDTH + 10]={0};
static int atemp[SCALER_MAXWIDTH + 2]={0}; static int atemp[SCALER_MAXWIDTH + 2]={0};
static int btemp[SCALER_MAXWIDTH + 2]={0}; static int btemp[SCALER_MAXWIDTH + 2]={0};
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine) Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine)
{ {
int x; int x;
Bit32u x2; Bit32u x2;
@ -197,7 +197,7 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
for (x = 0; x < 5; ++x) for (x = 0; x < 5; ++x)
OUT(b[x&3]); OUT(b[x&3]);
if ((cga->cgamode & 4) != 0) { if ((cgamode & 4) != 0) {
// Decode // Decode
int* i = temp + 5; int* i = temp + 5;
Bit32u* srgb = (Bit32u *)TempLine; Bit32u* srgb = (Bit32u *)TempLine;
@ -240,79 +240,79 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
return TempLine; return TempLine;
} }
void IncreaseHue(cga_t *cga) void IncreaseHue(uint8_t cgamode)
{ {
hue_offset += 5.0; hue_offset += 5.0;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void DecreaseHue(cga_t *cga) void DecreaseHue(uint8_t cgamode)
{ {
hue_offset -= 5.0; hue_offset -= 5.0;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void IncreaseSaturation(cga_t *cga) void IncreaseSaturation(uint8_t cgamode)
{ {
saturation += 5; saturation += 5;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void DecreaseSaturation(cga_t *cga) void DecreaseSaturation(uint8_t cgamode)
{ {
saturation -= 5; saturation -= 5;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void IncreaseContrast(cga_t *cga) void IncreaseContrast(uint8_t cgamode)
{ {
contrast += 5; contrast += 5;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void DecreaseContrast(cga_t *cga) void DecreaseContrast(uint8_t cgamode)
{ {
contrast -= 5; contrast -= 5;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void IncreaseBrightness(cga_t *cga) void IncreaseBrightness(uint8_t cgamode)
{ {
brightness += 5; brightness += 5;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void DecreaseBrightness(cga_t *cga) void DecreaseBrightness(uint8_t cgamode)
{ {
brightness -= 5; brightness -= 5;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void IncreaseSharpness(cga_t *cga) void IncreaseSharpness(uint8_t cgamode)
{ {
sharpness += 10; sharpness += 10;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void DecreaseSharpness(cga_t *cga) void DecreaseSharpness(uint8_t cgamode)
{ {
sharpness -= 10; sharpness -= 10;
update_cga16_color(cga); update_cga16_color(cgamode);
} }
void cga_comp_init(cga_t *cga) void cga_comp_init(int revision)
{ {
new_cga = cga->revision; new_cga = revision;
/* Making sure this gets reset after reset. */ /* Making sure this gets reset after reset. */
brightness = 0; brightness = 0;
@ -321,5 +321,5 @@ void cga_comp_init(cga_t *cga)
sharpness = 0; sharpness = 0;
hue_offset = 0; hue_offset = 0;
update_cga16_color(cga); update_cga16_color(0);
} }

View file

@ -3,6 +3,6 @@
#define Bitu unsigned int #define Bitu unsigned int
#define bool uint8_t #define bool uint8_t
void update_cga16_color(cga_t *cga); void update_cga16_color(uint8_t cgamode);
void cga_comp_init(cga_t *cga); void cga_comp_init(int revision);
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine); Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine);

View file

@ -50,7 +50,7 @@ void cga_out(uint16_t addr, uint8_t val, void *p)
if (((cga->cgamode ^ val) & 5) != 0) if (((cga->cgamode ^ val) & 5) != 0)
{ {
cga->cgamode = val; cga->cgamode = val;
update_cga16_color(cga); update_cga16_color(cga->cgamode);
} }
cga->cgamode = val; cga->cgamode = val;
return; return;
@ -300,7 +300,7 @@ void cga_poll(void *p)
for (c = 0; c < x; c++) for (c = 0; c < x; c++)
buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf; buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf;
Composite_Process(cga, 0, x >> 2, buffer32->line[cga->displine]); Composite_Process(cga->cgamode, 0, x >> 2, buffer32->line[cga->displine]);
} }
cga->sc = oldsc; cga->sc = oldsc;
@ -452,7 +452,7 @@ void *cga_standalone_init()
cga->vram = malloc(0x4000); cga->vram = malloc(0x4000);
cga_comp_init(cga); cga_comp_init(cga->revision);
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga);
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);

View file

@ -11,8 +11,6 @@
#define PCJR_RGB 0 #define PCJR_RGB 0
#define PCJR_COMPOSITE 1 #define PCJR_COMPOSITE 1
static int i_filt[8],q_filt[8];
typedef struct pcjr_t typedef struct pcjr_t
{ {
mem_mapping_t mapping; mem_mapping_t mapping;
@ -83,6 +81,8 @@ void pcjr_out(uint16_t addr, uint8_t val, void *p)
if (pcjr->array_index & 0x10) if (pcjr->array_index & 0x10)
val &= 0x0f; val &= 0x0f;
pcjr->array[pcjr->array_index & 0x1f] = val; pcjr->array[pcjr->array_index & 0x1f] = val;
if (!(pcjr->array_index & 0x1f))
update_cga16_color(val);
} }
pcjr->array_ff = !pcjr->array_ff; pcjr->array_ff = !pcjr->array_ff;
break; break;
@ -434,57 +434,10 @@ void pcjr_poll(void *p)
else x = (pcjr->crtc[1] << 4) + 16; else x = (pcjr->crtc[1] << 4) + 16;
if (pcjr->composite) if (pcjr->composite)
{ {
for (c = 0; c < x; c++) for (c = 0; c < x; c++)
{ buffer32->line[pcjr->displine][c] = buffer->line[pcjr->displine][c] & 0xf;
y_buf[(c << 1) & 6] = ntsc_col[buffer->line[pcjr->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
y_buf[(c << 1) & 6] += (buffer->line[pcjr->displine][c] & 8) ? 0x3000 : 0;
i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6];
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
y_val = y_tot >> 10; Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]);
if (y_val > 255) y_val = 255;
y_val <<= 16;
i_val = i_tot >> 12;
if (i_val > 39041) i_val = 39041;
if (i_val < -39041) i_val = -39041;
q_val = q_tot >> 12;
if (q_val > 34249) q_val = 34249;
if (q_val < -34249) q_val = -34249;
r = (y_val + 249*i_val + 159*q_val) >> 16;
g = (y_val - 70*i_val - 166*q_val) >> 16;
b = (y_val - 283*i_val + 436*q_val) >> 16;
y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[pcjr->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
y_buf[((c << 1) & 6) + 1] += (buffer->line[pcjr->displine][c] & 8) ? 0x3000 : 0;
i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1];
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
y_val = y_tot >> 10;
if (y_val > 255) y_val = 255;
y_val <<= 16;
i_val = i_tot >> 12;
if (i_val > 39041) i_val = 39041;
if (i_val < -39041) i_val = -39041;
q_val = q_tot >> 12;
if (q_val > 34249) q_val = 34249;
if (q_val < -34249) q_val = -34249;
r = (y_val + 249*i_val + 159*q_val) >> 16;
g = (y_val - 70*i_val - 166*q_val) >> 16;
b = (y_val - 283*i_val + 436*q_val) >> 16;
if (r > 511) r = 511;
if (g > 511) g = 511;
if (b > 511) b = 511;
((uint32_t *)buffer32->line[pcjr->displine])[c] = makecol32(r / 2, g / 2, b / 2);
}
} }
pcjr->sc = oldsc; pcjr->sc = oldsc;
if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc)
@ -609,23 +562,15 @@ void pcjr_poll(void *p)
static void *pcjr_video_init() static void *pcjr_video_init()
{ {
int c;
int pcjr_tint = -2;
int display_type; int display_type;
pcjr_t *pcjr = malloc(sizeof(pcjr_t)); pcjr_t *pcjr = malloc(sizeof(pcjr_t));
memset(pcjr, 0, sizeof(pcjr_t)); memset(pcjr, 0, sizeof(pcjr_t));
display_type = model_get_config_int("display_type"); display_type = model_get_config_int("display_type");
pcjr->composite = (display_type != PCJR_RGB); pcjr->composite = (display_type != PCJR_RGB);
pclog("display_type = %i\n", display_type);
pcjr->memctrl = -1; pcjr->memctrl = -1;
for (c = 0; c < 8; c++)
{
i_filt[c] = 512.0 * cos((3.14 * (pcjr_tint + c * 4) / 16.0) - 33.0 / 180.0);
q_filt[c] = 512.0 * sin((3.14 * (pcjr_tint + c * 4) / 16.0) - 33.0 / 180.0);
}
timer_add(pcjr_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr); timer_add(pcjr_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr);
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr); mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr);
io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr); io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr);

View file

@ -7,12 +7,11 @@
#include "timer.h" #include "timer.h"
#include "video.h" #include "video.h"
#include "vid_tandy.h" #include "vid_tandy.h"
#include "dosbox/vid_cga_comp.h"
#define TANDY_RGB 0 #define TANDY_RGB 0
#define TANDY_COMPOSITE 1 #define TANDY_COMPOSITE 1
static int i_filt[8],q_filt[8];
typedef struct tandy_t typedef struct tandy_t
{ {
mem_mapping_t mapping; mem_mapping_t mapping;
@ -77,6 +76,7 @@ void tandy_out(uint16_t addr, uint8_t val, void *p)
return; return;
case 0x3d8: case 0x3d8:
tandy->mode = val; tandy->mode = val;
update_cga16_color(tandy->mode);
return; return;
case 0x3d9: case 0x3d9:
tandy->col = val; tandy->col = val;
@ -472,60 +472,15 @@ void tandy_poll(void *p)
} }
if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16;
else x = (tandy->crtc[1] << 4) + 16; else x = (tandy->crtc[1] << 4) + 16;
if (tandy->composite) if (tandy->composite)
{ {
for (c = 0; c < x; c++) for (c = 0; c < x; c++)
{ buffer32->line[tandy->displine][c] = buffer->line[tandy->displine][c] & 0xf;
y_buf[(c << 1) & 6] = ntsc_col[buffer->line[tandy->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
y_buf[(c << 1) & 6] += (buffer->line[tandy->displine][c] & 8) ? 0x3000 : 0;
i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6];
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
y_val = y_tot >> 10; Composite_Process(tandy->mode, 0, x >> 2, buffer32->line[tandy->displine]);
if (y_val > 255) y_val = 255;
y_val <<= 16;
i_val = i_tot >> 12;
if (i_val > 39041) i_val = 39041;
if (i_val < -39041) i_val = -39041;
q_val = q_tot >> 12;
if (q_val > 34249) q_val = 34249;
if (q_val < -34249) q_val = -34249;
r = (y_val + 249*i_val + 159*q_val) >> 16;
g = (y_val - 70*i_val - 166*q_val) >> 16;
b = (y_val - 283*i_val + 436*q_val) >> 16;
y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[tandy->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
y_buf[((c << 1) & 6) + 1] += (buffer->line[tandy->displine][c] & 8) ? 0x3000 : 0;
i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1];
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
y_val = y_tot >> 10;
if (y_val > 255) y_val = 255;
y_val <<= 16;
i_val = i_tot >> 12;
if (i_val > 39041) i_val = 39041;
if (i_val < -39041) i_val = -39041;
q_val = q_tot >> 12;
if (q_val > 34249) q_val = 34249;
if (q_val < -34249) q_val = -34249;
r = (y_val + 249*i_val + 159*q_val) >> 16;
g = (y_val - 70*i_val - 166*q_val) >> 16;
b = (y_val - 283*i_val + 436*q_val) >> 16;
if (r > 511) r = 511;
if (g > 511) g = 511;
if (b > 511) b = 511;
((uint32_t *)buffer32->line[tandy->displine])[c] = makecol32(r / 2, g / 2, b / 2);
}
} }
tandy->sc = oldsc; tandy->sc = oldsc;
if (tandy->vc == tandy->crtc[7] && !tandy->sc) if (tandy->vc == tandy->crtc[7] && !tandy->sc)
{ {
@ -678,24 +633,17 @@ void tandy_poll(void *p)
void *tandy_init() void *tandy_init()
{ {
int c;
int tandy_tint = -2;
int display_type; int display_type;
tandy_t *tandy = malloc(sizeof(tandy_t)); tandy_t *tandy = malloc(sizeof(tandy_t));
memset(tandy, 0, sizeof(tandy_t)); memset(tandy, 0, sizeof(tandy_t));
display_type = model_get_config_int("display_type"); display_type = model_get_config_int("display_type");
tandy->composite = (display_type != TANDY_RGB); tandy->composite = (display_type != TANDY_RGB);
pclog("display_type = %i\n", display_type);
cga_comp_init(1);
tandy->memctrl = -1; tandy->memctrl = -1;
tandy->base = (mem_size - 128) * 1024; tandy->base = (mem_size - 128) * 1024;
for (c = 0; c < 8; c++)
{
i_filt[c] = 512.0 * cos((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
q_filt[c] = 512.0 * sin((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
}
timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy); timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy);
mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, tandy); mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, tandy);
mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandy_ram_read, NULL, NULL, tandy_ram_write, NULL, NULL, NULL, 0, tandy); mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandy_ram_read, NULL, NULL, tandy_ram_write, NULL, NULL, NULL, 0, tandy);