diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 792d31d..8805f72 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -11,7 +11,7 @@ * Version: @(#)808x.c 1.0.14 2019/02/28 * * Authors: Miran Grca, - * Andrew Jenner, + * Andrew Jenner (reenigne), * Sarah Walker, * * Copyright 2016-2019 Fred N. van Kempen. diff --git a/src/devices/video/vid_cga.c b/src/devices/video/vid_cga.c index e6613a2..dc42e4d 100644 --- a/src/devices/video/vid_cga.c +++ b/src/devices/video/vid_cga.c @@ -8,7 +8,7 @@ * * Emulation of the old and new IBM CGA graphics cards. * - * Version: @(#)vid_cga.c 1.0.12 2019/03/03 + * Version: @(#)vid_cga.c 1.0.12 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -171,7 +171,7 @@ cga_out(uint16_t port, uint8_t val, void *priv) dev->cgamode = val; if (old ^ val) { if ((old ^ val) & 0x05) - update_cga16_color(val); + cga_comp_update(dev->cpriv, val); cga_recalctimings(dev); } return; @@ -462,8 +462,8 @@ cga_poll(void *priv) else border = dev->cgacol & 0x0f; - Composite_Process(dev->cgamode, border, x >> 2, buffer32->line[(dev->displine << 1)]); - Composite_Process(dev->cgamode, border, x >> 2, buffer32->line[(dev->displine << 1) + 1]); + cga_comp_process(dev->cpriv, dev->cgamode, border, x >> 2, buffer32->line[(dev->displine << 1)]); + cga_comp_process(dev->cpriv, dev->cgamode, border, x >> 2, buffer32->line[(dev->displine << 1) + 1]); } dev->sc = oldsc; @@ -612,6 +612,10 @@ void cga_init(cga_t *dev) { dev->composite = 0; + if (dev->cpriv != NULL) { + cga_comp_close(dev->cpriv); + dev->cpriv = NULL; + } } @@ -633,7 +637,7 @@ cga_standalone_init(const device_t *info) dev->vram = (uint8_t *)mem_alloc(0x4000); - cga_comp_init(dev->revision); + dev->cpriv = cga_comp_init(dev->revision); timer_add(cga_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev); @@ -663,6 +667,10 @@ cga_close(void *priv) cga_t *dev = (cga_t *)priv; free(dev->vram); + + if (dev->cpriv != NULL) + cga_comp_close(dev->cpriv); + free(dev); } diff --git a/src/devices/video/vid_cga.h b/src/devices/video/vid_cga.h index a89257a..3e11a76 100644 --- a/src/devices/video/vid_cga.h +++ b/src/devices/video/vid_cga.h @@ -8,7 +8,7 @@ * * Definitions for the CGA driver. * - * Version: @(#)vid_cga.h 1.0.6 2019/03/01 + * Version: @(#)vid_cga.h 1.0.7 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -78,10 +78,12 @@ typedef struct { uint8_t charbuffer[256]; int revision; - int composite; int snow_enabled; int rgb_type; int font_type; + + int composite; + void *cpriv; } cga_t; diff --git a/src/devices/video/vid_cga_comp.c b/src/devices/video/vid_cga_comp.c index 5e0772e..59dc2de 100644 --- a/src/devices/video/vid_cga_comp.c +++ b/src/devices/video/vid_cga_comp.c @@ -9,14 +9,20 @@ * IBM CGA composite filter, borrowed from reenigne's DOSBox * patch and ported to C. * - * Version: @(#)vid_cga_comp.c 1.0.5 2018/10/05 + * New algorithm by reenigne. + * Works in all CGA modes/color settings and can simulate + * older and newer CGA revisions. + * + * Reworked to have its data on the heap. + * + * Version: @(#)vid_cga_comp.c 1.0.6 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, - * reengine, + * Andrew Jenner (reenigne), * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2015-2018 reenigne. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2015-2018 Andrew Jenner. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -50,158 +56,78 @@ #include "vid_cga_comp.h" -int CGA_Composite_Table[1024]; - - -static double brightness = 0; -static double contrast = 100; -static double saturation = 100; -static double sharpness = 0; -static double hue_offset = 0; - -/* New algorithm by reenigne - Works in all CGA modes/color settings and can simulate older and newer CGA revisions */ - static const double tau = 6.28318531; /* == 2*pi */ -static unsigned char chroma_multiplexer[256] = { - 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, - 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, - 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, - 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, - 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, - 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, - 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, - 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, - 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, - 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, - 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, - 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, - 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, - 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, - 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, - 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252}; - -static double intensity[4] = { - 77.175381, 88.654656, 166.564623, 174.228438}; +static const uint8_t chroma_multiplexer[256] = { + 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, + 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, + 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, + 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, + 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, + 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, + 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, + 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, + 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, + 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, + 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, + 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, + 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, + 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, + 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, + 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 +}; +static const double intensity[4] = { + 77.175381, 88.654656, 166.564623, 174.228438 +}; #define NEW_CGA(c,i,r,g,b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07) -double mode_brightness; -double mode_contrast; -double mode_hue; -double min_v; -double max_v; - -double video_ri, video_rq, video_gi, video_gq, video_bi, video_bq; -int video_sharpness; -int tandy_mode_control = 0; - -static bool new_cga = 0; - -void update_cga16_color(uint8_t cgamode) { - int x; - double c, i, v; - double q, a, s, r; - double iq_adjust_i, iq_adjust_q; - double i0, i3, mode_saturation; - - static const double ri = 0.9563; - static const double rq = 0.6210; - static const double gi = -0.2721; - static const double gq = -0.6474; - static const double bi = -1.1069; - static const double bq = 1.7046; - - if (!new_cga) { - min_v = chroma_multiplexer[0] + intensity[0]; - max_v = chroma_multiplexer[255] + intensity[3]; - } - else { - i0 = intensity[0]; - i3 = intensity[3]; - min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); - max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); - } - mode_contrast = 256/(max_v - min_v); - mode_brightness = -min_v*mode_contrast; - if ((cgamode & 3) == 1) - mode_hue = 14; - else - mode_hue = 4; - - mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; /* new CGA: 120% */ - mode_brightness += (new_cga ? brightness-10 : brightness)*5; /* new CGA: -10 */ - mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; /* new CGA: 150% */ - - for (x = 0; x < 1024; ++x) { - int phase = x & 3; - int right = (x >> 2) & 15; - int left = (x >> 6) & 15; - int rc = right; - int lc = left; - if ((cgamode & 4) != 0) { - rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); - lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); - } - c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; - i = intensity[(left >> 3) | ((right >> 2) & 2)]; - if (!new_cga) - v = c + i; - else { - double d_r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; - double d_g = intensity[((left >> 1) & 1) | (right & 2)]; - double d_b = intensity[(left & 1) | ((right << 1) & 2)]; - v = NEW_CGA(c, i, d_r, d_g, d_b); - } - CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness); - } - - i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2]; - q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3]; - - a = tau*(33 + 90 + hue_offset + mode_hue)/360.0; - c = cos(a); - s = sin(a); - r = 256*mode_saturation/sqrt(i*i+q*q); - - iq_adjust_i = -(i*c + q*s)*r; - iq_adjust_q = (q*c - i*s)*r; - - video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q); - video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i); - video_gi = (int) (gi*iq_adjust_i + gq*iq_adjust_q); - video_gq = (int) (-gi*iq_adjust_q + gq*iq_adjust_i); - video_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q); - video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i); - video_sharpness = (int) (sharpness*256/100); -} - -static Bit8u byte_clamp(int v) { - v >>= 13; - return v < 0 ? 0 : (v > 255 ? 255 : v); -} - /* 2048x1536 is the maximum we can possibly support. */ #define SCALER_MAXWIDTH 2048 -static int temp[SCALER_MAXWIDTH + 10]={0}; -static int atemp[SCALER_MAXWIDTH + 2]={0}; -static int btemp[SCALER_MAXWIDTH + 2]={0}; -Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine) +typedef struct { + int new_cga; + + int video_sharpness; + double mode_brightness, + mode_contrast, + mode_hue, + min_v, max_v; + double video_ri, video_rq, video_gi, + video_gq, video_bi, video_bq; + double brightness, + contrast, + saturation, + sharpness, + hue_offset; + + int temp[SCALER_MAXWIDTH + 10]; + int atemp[SCALER_MAXWIDTH + 2]; + int btemp[SCALER_MAXWIDTH + 2]; + + int table[1024]; +} cga_comp_t; + + +static uint8_t +byte_clamp(int v) { - int x; - Bit32u x2; + v >>= 13; - int w = blocks*4; + return v < 0 ? 0 : (v > 255 ? 255 : v); +} - int *o; - Bit8u *rgbi; - int *b2; - int *i; - Bit32u* srgb; - int *ap, *bp; + +uint8_t * +cga_comp_process(void *priv, uint8_t cgamode, uint8_t border, + uint32_t blocks/*, int8_t doublewidth*/, uint8_t *TempLine) +{ + cga_comp_t *state = (cga_comp_t *)priv; + uint32_t x2, *srgb; + int x, w = blocks*4; + int *o, *b2, *i, *ap, *bp; + uint8_t *rgbi; #define COMPOSITE_CONVERT(I, Q) do { \ i[1] = (i[1]<<3) - ap[1]; \ @@ -209,157 +135,294 @@ Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool d b = bp[0]; \ c = i[0]+i[0]; \ d = i[-1]+i[1]; \ - y = ((c+d)<<8) + video_sharpness*(c-d); \ - rr = (int)(y + video_ri*(I) + video_rq*(Q)); \ - gg = (int)(y + video_gi*(I) + video_gq*(Q)); \ - bb = (int)(y + video_bi*(I) + video_bq*(Q)); \ + y = ((c+d)<<8) + state->video_sharpness*(c-d); \ + rr = (int)(y + state->video_ri*(I) + state->video_rq*(Q)); \ + gg = (int)(y + state->video_gi*(I) + state->video_gq*(Q)); \ + bb = (int)(y + state->video_bi*(I) + state->video_bq*(Q)); \ ++i; \ ++ap; \ ++bp; \ *srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \ ++srgb; \ -} while (0) + } while (0) #define OUT(v) do { *o = (v); ++o; } while (0) - /* Simulate CGA composite output */ - o = temp; - rgbi = TempLine; - b2 = &CGA_Composite_Table[border*68]; - for (x = 0; x < 4; ++x) - OUT(b2[(x+3)&3]); - OUT(CGA_Composite_Table[(border<<6) | ((*rgbi)<<2) | 3]); - for (x = 0; x < w-1; ++x) { - OUT(CGA_Composite_Table[(rgbi[0]<<6) | (rgbi[1]<<2) | (x&3)]); - ++rgbi; - } - OUT(CGA_Composite_Table[((*rgbi)<<6) | (border<<2) | 3]); - for (x = 0; x < 5; ++x) - OUT(b2[x&3]); + /* Simulate CGA composite output. */ + o = state->temp; + rgbi = TempLine; + b2 = &state->table[border * 68]; + for (x = 0; x < 4; ++x) + OUT(b2[(x+3)&3]); + OUT(state->table[(border<<6) | ((*rgbi)<<2) | 3]); - if ((cgamode & 4) != 0) { - /* Decode */ - i = temp + 5; - srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks*4; ++x2) { - int c = (i[0]+i[0])<<3; - int d = (i[-1]+i[1])<<3; - int y = ((c+d)<<8) + video_sharpness*(c-d); - ++i; - *srgb = byte_clamp(y)*0x10101; - ++srgb; - } - } - else { - /* Store chroma */ - i = temp + 4; - ap = atemp + 1; - bp = btemp + 1; - for (x = -1; x < w + 1; ++x) { - ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4]; - bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1; - ++i; - } + for (x = 0; x < w-1; ++x) { + OUT(state->table[(rgbi[0]<<6) | (rgbi[1]<<2) | (x&3)]); + ++rgbi; + } + OUT(state->table[((*rgbi)<<6) | (border<<2) | 3]); - /* Decode */ - i = temp + 5; - i[-1] = (i[-1]<<3) - ap[-1]; - i[0] = (i[0]<<3) - ap[0]; - srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks; ++x2) { - int y,a,b,c,d,rr,gg,bb; - COMPOSITE_CONVERT(a, b); - COMPOSITE_CONVERT(-b, a); - COMPOSITE_CONVERT(-a, -b); - COMPOSITE_CONVERT(b, -a); - } - } -#undef COMPOSITE_CONVERT -#undef OUT + for (x = 0; x < 5; ++x) + OUT(b2[x&3]); - return TempLine; + if ((cgamode & 4) != 0) { + /* Decode. */ + i = state->temp + 5; + srgb = (uint32_t *)TempLine; + for (x2 = 0; x2 < blocks*4; ++x2) { + int c = (i[0]+i[0])<<3; + int d = (i[-1]+i[1])<<3; + int y = ((c+d)<<8) + state->video_sharpness*(c-d); + ++i; + *srgb = byte_clamp(y)*0x10101; + ++srgb; + } + } else { + /* Store chroma. */ + i = state->temp + 4; + ap = state->atemp + 1; + bp = state->btemp + 1; + for (x = -1; x < w + 1; ++x) { + ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4]; + bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1; + ++i; + } + + /* Decode. */ + i = state->temp + 5; + i[-1] = (i[-1]<<3) - ap[-1]; + i[0] = (i[0]<<3) - ap[0]; + srgb = (uint32_t *)TempLine; + for (x2 = 0; x2 < blocks; ++x2) { + int y,a,b,c,d,rr,gg,bb; + + COMPOSITE_CONVERT(a, b); + COMPOSITE_CONVERT(-b, a); + COMPOSITE_CONVERT(-a, -b); + COMPOSITE_CONVERT(b, -a); + } + } + + return TempLine; } -void IncreaseHue(uint8_t cgamode) + +void +cga_comp_update(void *priv, uint8_t cgamode) { - hue_offset += 5.0; + static const double ri = 0.9563; + static const double rq = 0.6210; + static const double gi = -0.2721; + static const double gq = -0.6474; + static const double bi = -1.1069; + static const double bq = 1.7046; + cga_comp_t *state = (cga_comp_t *)priv; + double iq_adjust_i, iq_adjust_q; + double i0, i3, mode_saturation; + double q, a, s, r; + double c, i, v; + int x; - update_cga16_color(cgamode); + if (state->new_cga) { + i0 = intensity[0]; + i3 = intensity[3]; + state->min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); + state->max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); + } else { + state->min_v = chroma_multiplexer[0] + intensity[0]; + state->max_v = chroma_multiplexer[255] + intensity[3]; + } + state->mode_contrast = 256 / (state->max_v - state->min_v); + state->mode_brightness = -state->min_v * state->mode_contrast; + + if ((cgamode & 3) == 1) + state->mode_hue = 14; + else + state->mode_hue = 4; + + state->mode_contrast *= state->contrast * (state->new_cga ? 1.2 : 1)/100; /* new CGA: 120% */ + state->mode_brightness += (state->new_cga ? state->brightness-10 : state->brightness)*5; /* new CGA: -10 */ + mode_saturation = (state->new_cga ? 4.35 : 2.9)*state->saturation/100; /* new CGA: 150% */ + + for (x = 0; x < 1024; ++x) { + int phase = x & 3; + int right = (x >> 2) & 15; + int left = (x >> 6) & 15; + int rc = right; + int lc = left; + + if ((cgamode & 4) != 0) { + rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); + lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); + } + c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; + i = intensity[(left >> 3) | ((right >> 2) & 2)]; + if (state->new_cga) { + double d_r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; + double d_g = intensity[((left >> 1) & 1) | (right & 2)]; + double d_b = intensity[(left & 1) | ((right << 1) & 2)]; + v = NEW_CGA(c, i, d_r, d_g, d_b); + } else + v = c + i; + state->table[x] = (int) (v*state->mode_contrast + state->mode_brightness); + } + + i = state->table[6*68] - state->table[6*68 + 2]; + q = state->table[6*68 + 1] - state->table[6*68 + 3]; + + a = tau*(33 + 90 + state->hue_offset + state->mode_hue)/360.0; + c = cos(a); + s = sin(a); + r = 256*mode_saturation/sqrt(i*i+q*q); + + iq_adjust_i = -(i*c + q*s)*r; + iq_adjust_q = (q*c - i*s)*r; + + state->video_ri = (int) (ri * iq_adjust_i + rq * iq_adjust_q); + state->video_rq = (int) (-ri * iq_adjust_q + rq * iq_adjust_i); + state->video_gi = (int) (gi * iq_adjust_i + gq * iq_adjust_q); + state->video_gq = (int) (-gi * iq_adjust_q + gq * iq_adjust_i); + state->video_bi = (int) (bi * iq_adjust_i + bq * iq_adjust_q); + state->video_bq = (int) (-bi * iq_adjust_q + bq * iq_adjust_i); + state->video_sharpness = (int) ((state->sharpness * 256) / 100); } -void DecreaseHue(uint8_t cgamode) + +void * +cga_comp_init(int revision) { - hue_offset -= 5.0; + cga_comp_t *state; - update_cga16_color(cgamode); + state = (cga_comp_t *)mem_alloc(sizeof(cga_comp_t)); + memset(state, 0x00, sizeof(cga_comp_t)); + state->new_cga = revision; + + /* Making sure this gets reset after reset. */ + state->contrast = 100; + state->saturation = 100; + + cga_comp_update(state, 0); + + return(state); } -void IncreaseSaturation(uint8_t cgamode) + +void +cga_comp_close(void *priv) { - saturation += 5; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + free(state); } -void DecreaseSaturation(uint8_t cgamode) + +#if 0 /*NOT_USED*/ +void +IncreaseHue(void *priv, uint8_t cgamode) { - saturation -= 5; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->hue_offset += 5.0; + + cga_comp_update(state, cgamode); } -void IncreaseContrast(uint8_t cgamode) + +void +DecreaseHue(void *priv, uint8_t cgamode) { - contrast += 5; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->hue_offset -= 5.0; + + cga_comp_update(state, cgamode); } -void DecreaseContrast(uint8_t cgamode) + +void +IncreaseSaturation(void *priv, uint8_t cgamode) { - contrast -= 5; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->saturation += 5; + + cga_comp_update(state, cgamode); } -void IncreaseBrightness(uint8_t cgamode) + +void +DecreaseSaturation(void *priv, uint8_t cgamode) { - brightness += 5; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->saturation -= 5; + + cga_comp_update(state, cgamode); } -void DecreaseBrightness(uint8_t cgamode) + +void +IncreaseContrast(void *priv, uint8_t cgamode) { - brightness -= 5; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->contrast += 5; + + cga_comp_update(state, cgamode); } -void IncreaseSharpness(uint8_t cgamode) + +void +DecreaseContrast(void *priv, uint8_t cgamode) { - sharpness += 10; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->contrast -= 5; + + cga_comp_update(state, cgamode); } -void DecreaseSharpness(uint8_t cgamode) + +void +IncreaseBrightness(void *priv, uint8_t cgamode) { - sharpness -= 10; + cga_comp_t *state = (cga_comp_t *)priv; - update_cga16_color(cgamode); + state->brightness += 5; + + cga_comp_update(state, cgamode); } -void cga_comp_init(int revision) + +void +DecreaseBrightness(void *priv, uint8_t cgamode) { - new_cga = revision; + cga_comp_t *state = (cga_comp_t *)priv; - /* Making sure this gets reset after reset. */ - brightness = 0; - contrast = 100; - saturation = 100; - sharpness = 0; - hue_offset = 0; + state->brightness -= 5; - update_cga16_color(0); + cga_comp_update(state, cgamode); } + + +void +IncreaseSharpness(void *priv, uint8_t cgamode) +{ + cga_comp_t *state = (cga_comp_t *)priv; + + state->sharpness += 10; + + cga_comp_update(state, cgamode); +} + + +void +DecreaseSharpness(void *priv, uint8_t cgamode) +{ + cga_comp_t *state = (cga_comp_t *)priv; + + state->sharpness -= 10; + + cga_comp_update(state, cgamode); +} +#endif /*NOT_USED*/ diff --git a/src/devices/video/vid_cga_comp.h b/src/devices/video/vid_cga_comp.h index 21b79ab..dfdbf27 100644 --- a/src/devices/video/vid_cga_comp.h +++ b/src/devices/video/vid_cga_comp.h @@ -8,13 +8,13 @@ * * Definitions for the IBM CGA composite filter. * - * Version: @(#)vid_cga_comp.h 1.0.1 2018/02/14 + * Version: @(#)vid_cga_comp.h 1.0.2 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, - * reengine, + * Andrew Jenner (reenigne), * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -39,14 +39,13 @@ # define VIDEO_CGA_COMP_H -#define Bit8u uint8_t -#define Bit32u uint32_t -#define Bitu unsigned int -#define bool uint8_t +extern void *cga_comp_init(int revision); +extern void cga_comp_close(void *); -void update_cga16_color(uint8_t cgamode); -void cga_comp_init(int revision); -Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine); +extern void cga_comp_update(void *, uint8_t cgamode); +extern uint8_t *cga_comp_process(void *, uint8_t cgamode, uint8_t border, + uint32_t blocks, /*int8_t doublewidth,*/ + uint8_t *TempLine); #endif /*VIDEO_CGA_COMP_H*/ diff --git a/src/devices/video/vid_cga_compaq.c b/src/devices/video/vid_cga_compaq.c index 1854986..03e83cf 100644 --- a/src/devices/video/vid_cga_compaq.c +++ b/src/devices/video/vid_cga_compaq.c @@ -8,7 +8,7 @@ * * Implementation of CGA used by Compaq PC's. * - * Version: @(#)vid_cga_compaq.c 1.0.5 2019/02/10 + * Version: @(#)vid_cga_compaq.c 1.0.6 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -112,7 +112,7 @@ compaq_poll(void *priv) oldsc = dev->cga.sc; if ((dev->cga.crtc[8] & 3) == 3) - dev->cga.sc = ((dev->cga.sc << 1) + dev->cga.oddeven) & 7; + dev->cga.sc = ((dev->cga.sc << 1) + dev->cga.oddeven) & 7; if (dev->cga.cgadispon) { if (dev->cga.displine < dev->cga.firstline) { @@ -120,7 +120,7 @@ compaq_poll(void *priv) video_wait_for_buffer(); } dev->cga.lastline = dev->cga.displine; - + cols[0] = (dev->cga.cgacol & 15); for (c = 0; c < 8; c++) { @@ -232,9 +232,9 @@ compaq_poll(void *priv) buffer32->line[dev->cga.displine][c] = ((uint32_t *)buffer32->line[dev->cga.displine])[c] & 0xf; if (dev->flags) - Composite_Process(dev->cga.cgamode & 0x7F, 0, x >> 2, buffer32->line[dev->cga.displine]); + cga_comp_process(dev->cga.cpriv, dev->cga.cgamode & 0x7F, 0, x >> 2, buffer32->line[dev->cga.displine]); else - Composite_Process(dev->cga.cgamode, 0, x >> 2, buffer32->line[dev->cga.displine]); + cga_comp_process(dev->cga.cpriv, dev->cga.cgamode, 0, x >> 2, buffer32->line[dev->cga.displine]); } else { for (c = 0; c < x; c++) buffer->line[dev->cga.displine][c] = ((uint32_t *)buffer32->line[dev->cga.displine])[c]; @@ -381,7 +381,7 @@ compaq_cga_init(const device_t *info) dev->cga.vram = (uint8_t *)mem_alloc(0x4000); - cga_comp_init(dev->cga.revision); + dev->cga.cpriv = cga_comp_init(dev->cga.revision); timer_add(compaq_poll, &dev->cga.vidtime, TIMER_ALWAYS_ENABLED, dev); @@ -432,7 +432,11 @@ compaq_cga_close(void *priv) { compaq_cga_t *dev = (compaq_cga_t *)priv; + if (dev->cga.cpriv != NULL) + cga_comp_close(dev->cga.cpriv); + free(dev->cga.vram); + free(dev); } diff --git a/src/devices/video/vid_colorplus.c b/src/devices/video/vid_colorplus.c index 5ece008..06b592e 100644 --- a/src/devices/video/vid_colorplus.c +++ b/src/devices/video/vid_colorplus.c @@ -8,13 +8,13 @@ * * Plantronics ColorPlus emulation. * - * Version: @(#)vid_colorplus.c 1.0.9 2018/11/11 + * Version: @(#)vid_colorplus.c 1.0.10 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -251,7 +251,7 @@ colorplus_poll(void *priv) for (c = 0; c < x; c++) buffer32->line[dev->cga.displine][c] = buffer->line[dev->cga.displine][c] & 0xf; - Composite_Process(dev->cga.cgamode, 0, x >> 2, buffer32->line[dev->cga.displine]); + cga_comp_process(dev->cga.cpriv, dev->cga.cgamode, 0, x >> 2, buffer32->line[dev->cga.displine]); } dev->cga.sc = oldsc; @@ -395,8 +395,8 @@ colorplus_init(const device_t *info) dev->cga.snow_enabled = device_get_config_int("snow_enabled"); dev->cga.vram = (uint8_t *)mem_alloc(0x8000); - - cga_comp_init(1); + + dev->cga.cpriv = cga_comp_init(1); timer_add(colorplus_poll, &dev->cga.vidtime, TIMER_ALWAYS_ENABLED, dev); @@ -422,7 +422,11 @@ colorplus_close(void *priv) { colorplus_t *dev = (colorplus_t *)priv; + if (dev->cga.cpriv != NULL) + cga_comp_close(dev->cga.cpriv); + free(dev->cga.vram); + free(dev); } diff --git a/src/machines/m_pcjr.c b/src/machines/m_pcjr.c index 3f3cb98..f85b305 100644 --- a/src/machines/m_pcjr.c +++ b/src/machines/m_pcjr.c @@ -8,7 +8,7 @@ * * Emulation of the IBM PCjr. * - * Version: @(#)m_pcjr.c 1.0.13 2019/02/16 + * Version: @(#)m_pcjr.c 1.0.14 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -102,6 +102,7 @@ typedef struct { int64_t dispontime, dispofftime, vidtime; int firstline, lastline; int composite; + void *cpriv; /* Keyboard Controller stuff. */ int latched; @@ -188,7 +189,7 @@ vid_out(uint16_t addr, uint8_t val, void *p) val &= 0x0f; pcjr->array[pcjr->array_index & 0x1f] = val; if (!(pcjr->array_index & 0x1f)) - update_cga16_color(val); + cga_comp_update(pcjr->cpriv, val); } pcjr->array_ff = !pcjr->array_ff; break; @@ -460,7 +461,7 @@ vid_poll(void *p) for (c = 0; c < x; c++) buffer32->line[pcjr->displine][c] = buffer->line[pcjr->displine][c] & 0xf; - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]); + cga_comp_process(pcjr->cpriv, pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]); } pcjr->sc = oldsc; if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { @@ -706,6 +707,18 @@ kbd_adddata_ex(uint16_t val) } +static void +pcjr_close(void *priv) +{ + pcjr_t *pcjr = (pcjr_t *)priv; + + if (pcjr->composite && pcjr->cpriv) + cga_comp_close(pcjr->cpriv); + + free(pcjr); +} + + static void speed_changed(void *priv) { @@ -741,7 +754,7 @@ static const video_timings_t pcjr_timings = { VID_BUS,0,0,0,0,0,0 }; const device_t m_pcjr_device = { "IBM PCjr", 0, 0, - NULL, NULL, NULL, + NULL, pcjr_close, NULL, NULL, speed_changed, NULL, @@ -761,6 +774,8 @@ m_pcjr_init(const machine_t *model, UNUSED(void *arg)) dev->memctrl = -1; display_type = machine_get_config_int("display_type"); dev->composite = (display_type != PCJR_RGB); + if (dev->composite) + dev->cpriv = cga_comp_init(0); pic_init(); pit_init(); diff --git a/src/machines/m_tandy.c b/src/machines/m_tandy.c index 9e1e61c..f9217ee 100644 --- a/src/machines/m_tandy.c +++ b/src/machines/m_tandy.c @@ -11,7 +11,7 @@ * NOTE: It might be better (after all..) to split off the video * driver from the main code, to keep it a little cleaner. * - * Version: @(#)m_tandy.c 1.0.15 2019/02/16 + * Version: @(#)m_tandy.c 1.0.16 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -116,6 +116,7 @@ typedef struct { lastline; int composite; + void *cpriv; } t1kvid_t; typedef struct { @@ -554,7 +555,7 @@ vid_out(uint16_t addr, uint8_t val, void *priv) case 0x03d8: vid->mode = val; if (dev->type != 2) - update_cga16_color(vid->mode); + cga_comp_update(vid->cpriv, vid->mode); break; case 0x03d9: @@ -879,7 +880,7 @@ vid_poll(void *priv) for (c = 0; c < x; c++) buffer32->line[vid->displine][c] = buffer->line[vid->displine][c] & 0xf; - Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine]); + cga_comp_process(vid->cpriv, vid->mode, 0, x >> 2, buffer32->line[vid->displine]); } vid->sc = oldsc; if (vid->vc == vid->crtc[7] && !vid->sc) @@ -1355,6 +1356,12 @@ static void vid_close(void *priv) { tandy_t *dev = (tandy_t *)priv; + t1kvid_t *vid = dev->vid; + + if (vid->cpriv != NULL) { + cga_comp_close(vid->cpriv); + vid->cpriv = NULL; + } free(dev->vid); dev->vid = NULL; @@ -1374,8 +1381,7 @@ vid_init(tandy_t *dev) display_type = machine_get_config_int("display_type"); vid->composite = (display_type != TANDY_RGB); - - cga_comp_init(1); + vid->cpriv = cga_comp_init(1); if (dev->type == 2) { vid->b8000_limit = 0x8000; diff --git a/src/machines/machine_table.c b/src/machines/machine_table.c index 46ef9d7..b847f00 100644 --- a/src/machines/machine_table.c +++ b/src/machines/machine_table.c @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine_table.c 1.0.35 2019/03/03 + * Version: @(#)machine_table.c 1.0.36 2019/03/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -137,9 +137,9 @@ const machine_t machines[] = { { "[386SX MCA] IBM PS/2 model 55SX", "ibm_ps2_m55sx", L"ibm/ps2_m55sx", 16, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC_PS2, 1, 8, 1, 64, m_ps2_model_55sx_init, NULL, NULL }, /* 80386DX */ - { "[386DX ISA] AMI 386DX (Opti495)", "ami_386dx_opti495", L"opti495/ami", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, m_at_opti495_ami_init, NULL, NULL }, - { "[386DX ISA] Award 386DX (Opti495)", "award_386dx_opti495", L"opti495/award", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, m_at_opti495_award_init, NULL, NULL }, - { "[386DX ISA] MR 386DX (Opti495)", "mr_386dx_opti495", L"opti495/mr", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, m_at_opti495_mr_init, NULL, NULL }, + { "[386DX ISA] AMI 386DX (Opti495)", "ami_386dx_opti495", L"opti495/ami", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 128, m_at_opti495_ami_init, NULL, NULL }, + { "[386DX ISA] Award 386DX (Opti495)", "award_386dx_opti495", L"opti495/award", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 128, m_at_opti495_award_init, NULL, NULL }, + { "[386DX ISA] MR 386DX (Opti495)", "mr_386dx_opti495", L"opti495/mr", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 128, m_at_opti495_mr_init, NULL, NULL }, { "[386DX ISA] Amstrad MegaPC 386DX", "amstrad_megapc_dx", L"amstrad/megapc", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 128, m_at_wd76c10_init, NULL, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) @@ -156,9 +156,9 @@ const machine_t machines[] = { #if defined(DEV_BRANCH) && defined(USE_SIS471) { "[486 ISA] AMI 486 (SiS471)", "ami_486_sis471", L"sis471/ami", 0, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 128, m_at_sis471_ami_init, NULL, NULL }, #endif - { "[486 ISA] AMI WinBIOS486 (ALi1429)", "ami_win486_ali1429", L"ali1429/ami_win", 0, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, m_at_ali1429_init, NULL, NULL }, - { "[486 ISA] Award 486 (Opti495)", "award_486_opti495", L"opti495/award", 0, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, m_at_opti495_award_init, NULL, NULL }, - { "[486 ISA] MR 486 (Opti495)", "mr_486dx_opti495", L"opti495/mr", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, m_at_opti495_mr_init, NULL, NULL }, + { "[486 ISA] AMI WinBIOS486 (ALi1429)", "ami_win486_ali1429", L"ali1429/ami_win", 0, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 128, m_at_ali1429_init, NULL, NULL }, + { "[486 ISA] Award 486 (Opti495)", "award_486_opti495", L"opti495/award", 0, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 128, m_at_opti495_award_init, NULL, NULL }, + { "[486 ISA] MR 486 (Opti495)", "mr_486dx_opti495", L"opti495/mr", 0, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 128, m_at_opti495_mr_init, NULL, NULL }, { "[486 ISA] DTK PKM-0038S E-2", "dtk_486", L"dtk/486", 0, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 128, m_at_dtk486_init, NULL, NULL },