Improved CGA composite filter. Filter by reengine, patch from Battler.

This commit is contained in:
SarahW 2016-07-08 19:57:47 +01:00
commit 7818f459ee
7 changed files with 421 additions and 86 deletions

View file

@ -33,7 +33,7 @@ vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c \
x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \
resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \
dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \
resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc \
resid-fp/voice.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \
resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc resid-fp/wave8580_PS_.cc \

View file

@ -21,14 +21,14 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = dbopl.o
DBOBJ = dbopl.o vid_cga_comp.o
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
LIBS = -mwindows -lwinmm -lalut -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lstdc++
PCem.exe: $(OBJ) $(FMOBJ) $(SIDOBJ)
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) -o "PCem.exe" $(LIBS)
PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ)
$(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem.exe" $(LIBS)
all : PCem.exe

View file

@ -21,14 +21,14 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = dbopl.o
DBOBJ = dbopl.o vid_cga_comp.o
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
LIBS = -mwindows -lwinmm -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lstdc++
PCem64.exe: $(OBJ) $(FMOBJ) $(SIDOBJ)
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) -o "PCem64.exe" $(LIBS)
PCem64.exe: $(OBJ) $(DBOBJ) $(SIDOBJ)
$(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64.exe" $(LIBS)
all : PCem64.exe

325
src/dosbox/vid_cga_comp.c Normal file
View file

@ -0,0 +1,325 @@
/* Code borrowed from DOSBox and adapted by OBattler.
Original author: reenigne. */
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include "../ibm.h"
#include "../device.h"
#include "../mem.h"
#include "../vid_cga.h"
#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};
#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;
static bool is_bw = 0;
static bool is_bpp1 = 0;
static uint8_t comp_pal[256][3];
static Bit8u byte_clamp_other(int v) { return v < 0 ? 0 : (v > 255 ? 255 : v); }
FILE *df;
void update_cga16_color(cga_t *cga) {
int x;
Bit32u x2;
if (!new_cga) {
min_v = chroma_multiplexer[0] + intensity[0];
max_v = chroma_multiplexer[255] + intensity[3];
}
else {
double i0 = intensity[0];
double 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 ((cga->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
double 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 ((cga->cgamode & 4) != 0) {
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
}
double c =
chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase];
double i = intensity[(left >> 3) | ((right >> 2) & 2)];
double v;
if (!new_cga)
v = c + i;
else {
double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)];
double g = intensity[((left >> 1) & 1) | (right & 2)];
double b = intensity[(left & 1) | ((right << 1) & 2)];
v = NEW_CGA(c, i, r, g, b);
}
CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness);
}
double i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2];
double q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3];
double a = tau*(33 + 90 + hue_offset + mode_hue)/360.0;
double c = cos(a);
double s = sin(a);
double r = 256*mode_saturation/sqrt(i*i+q*q);
double iq_adjust_i = -(i*c + q*s)*r;
double iq_adjust_q = (q*c - i*s)*r;
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;
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(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine)
{
int x;
Bit32u x2;
int w = blocks*4;
#define COMPOSITE_CONVERT(I, Q) do { \
i[1] = (i[1]<<3) - ap[1]; \
a = ap[0]; \
b = bp[0]; \
c = i[0]+i[0]; \
d = i[-1]+i[1]; \
y = ((c+d)<<8) + video_sharpness*(c-d); \
rr = y + video_ri*(I) + video_rq*(Q); \
gg = y + video_gi*(I) + video_gq*(Q); \
bb = y + video_bi*(I) + video_bq*(Q); \
++i; \
++ap; \
++bp; \
*srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \
++srgb; \
} while (0)
#define OUT(v) do { *o = (v); ++o; } while (0)
// Simulate CGA composite output
int* o = temp;
Bit8u* rgbi = TempLine;
int* b = &CGA_Composite_Table[border*68];
for (x = 0; x < 4; ++x)
OUT(b[(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(b[x&3]);
if ((cga->cgamode & 4) != 0) {
// Decode
int* i = temp + 5;
Bit32u* 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
int* i = temp + 4;
int* ap = atemp + 1;
int* 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;
}
// Decode
i = temp + 5;
i[-1] = (i[-1]<<3) - ap[-1];
i[0] = (i[0]<<3) - ap[0];
Bit32u* 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
return TempLine;
}
void IncreaseHue(cga_t *cga)
{
hue_offset += 5.0;
update_cga16_color(cga);
}
void DecreaseHue(cga_t *cga)
{
hue_offset -= 5.0;
update_cga16_color(cga);
}
void IncreaseSaturation(cga_t *cga)
{
saturation += 5;
update_cga16_color(cga);
}
void DecreaseSaturation(cga_t *cga)
{
saturation -= 5;
update_cga16_color(cga);
}
void IncreaseContrast(cga_t *cga)
{
contrast += 5;
update_cga16_color(cga);
}
void DecreaseContrast(cga_t *cga)
{
contrast -= 5;
update_cga16_color(cga);
}
void IncreaseBrightness(cga_t *cga)
{
brightness += 5;
update_cga16_color(cga);
}
void DecreaseBrightness(cga_t *cga)
{
brightness -= 5;
update_cga16_color(cga);
}
void IncreaseSharpness(cga_t *cga)
{
sharpness += 10;
update_cga16_color(cga);
}
void DecreaseSharpness(cga_t *cga)
{
sharpness -= 10;
update_cga16_color(cga);
}
void cga_comp_init(cga_t *cga)
{
new_cga = cga->revision;
/* Making sure this gets reset after reset. */
brightness = 0;
contrast = 100;
saturation = 100;
sharpness = 0;
hue_offset = 0;
update_cga16_color(cga);
}

View file

@ -0,0 +1,8 @@
#define Bit8u uint8_t
#define Bit32u uint32_t
#define Bitu unsigned int
#define bool uint8_t
void update_cga16_color(cga_t *cga);
void cga_comp_init(cga_t *cga);
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine);

View file

@ -8,8 +8,13 @@
#include "timer.h"
#include "video.h"
#include "vid_cga.h"
#include "dosbox/vid_cga_comp.h"
static int i_filt[8],q_filt[8];
#define CGA_RGB 0
#define CGA_COMPOSITE 1
#define COMPOSITE_OLD 0
#define COMPOSITE_NEW 1
static uint8_t crtcmask[32] =
{
@ -42,6 +47,11 @@ void cga_out(uint16_t addr, uint8_t val, void *p)
}
return;
case 0x3D8:
if (((cga->cgamode ^ val) & 5) != 0)
{
cga->cgamode = val;
update_cga16_color(cga);
}
cga->cgamode = val;
return;
case 0x3D9:
@ -112,18 +122,6 @@ void cga_recalctimings(cga_t *cga)
cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
}
static int ntsc_col[8][8]=
{
{0,0,0,0,0,0,0,0}, /*Black*/
{0,0,1,1,1,1,0,0}, /*Blue*/
{1,0,0,0,0,1,1,1}, /*Green*/
{0,0,0,0,1,1,1,1}, /*Cyan*/
{1,1,1,1,0,0,0,0}, /*Red*/
{0,1,1,1,1,0,0,0}, /*Magenta*/
{1,1,0,0,0,0,1,1}, /*Yellow*/
{1,1,1,1,1,1,1,1} /*White*/
};
void cga_poll(void *p)
{
cga_t *cga = (cga_t *)p;
@ -136,10 +134,7 @@ void cga_poll(void *p)
int cols[4];
int col;
int oldsc;
int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot;
int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot;
int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
int r, g, b;
if (!cga->linepos)
{
cga->vidtime += cga->dispofftime;
@ -292,59 +287,13 @@ void cga_poll(void *p)
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
else x = (cga->crtc[1] << 4) + 16;
if (cga_comp)
if (cga->composite)
{
for (c = 0; c < x; c++)
{
y_buf[(c << 1) & 6] = ntsc_col[buffer->line[cga->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
y_buf[(c << 1) & 6] += (buffer->line[cga->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];
for (c = 0; c < x; c++)
buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf;
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;
y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[cga->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
y_buf[((c << 1) & 6) + 1] += (buffer->line[cga->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[cga->displine])[c] = makecol32(r / 2, g / 2, b / 2);
}
Composite_Process(cga, 0, x >> 2, buffer32->line[cga->displine]);
}
cga->sc = oldsc;
@ -357,7 +306,6 @@ void cga_poll(void *p)
else
{
cga->vidtime += cga->dispontime;
if (cga->cgadispon) cga->cgastat &= ~1;
cga->linepos = 0;
if (cga->vsynctime)
{
@ -410,7 +358,7 @@ void cga_poll(void *p)
{
cga->cgadispon = 0;
cga->displine = 0;
cga->vsynctime = (cga->crtc[3] >> 4) + 1;
cga->vsynctime = 16;
if (cga->crtc[7])
{
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
@ -426,7 +374,7 @@ void cga_poll(void *p)
}
startblit();
if (cga_comp)
if (cga->composite)
video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8);
else
video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8);
@ -468,6 +416,8 @@ endblit();
cga->sc &= 31;
cga->ma = cga->maback;
}
if (cga->cgadispon)
cga->cgastat &= ~1;
if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
cga->con = 1;
if (cga->cgadispon && (cga->cgamode & 1))
@ -480,25 +430,26 @@ endblit();
void cga_init(cga_t *cga)
{
cga->composite = 0;
}
void *cga_standalone_init()
{
int c;
int cga_tint = -2;
int display_type;
cga_t *cga = malloc(sizeof(cga_t));
memset(cga, 0, sizeof(cga_t));
display_type = device_get_config_int("display_type");
cga->composite = (display_type != CGA_RGB);
cga->revision = device_get_config_int("composite_type");
cga->vram = malloc(0x4000);
for (c = 0; c < 8; c++)
{
i_filt[c] = 512.0 * cos((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
}
cga_comp_init(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);
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
return cga;
}
@ -517,6 +468,53 @@ void cga_speed_changed(void *p)
cga_recalctimings(cga);
}
static device_config_t cga_config[] =
{
{
.name = "display_type",
.description = "Display type",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "RGB",
.value = CGA_RGB
},
{
.description = "Composite",
.value = CGA_COMPOSITE
},
{
.description = ""
}
},
.default_int = CGA_RGB
},
{
.name = "composite_type",
.description = "Composite type",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "Old",
.value = COMPOSITE_OLD
},
{
.description = "New",
.value = COMPOSITE_NEW
},
{
.description = ""
}
},
.default_int = COMPOSITE_OLD
},
{
.type = -1
}
};
device_t cga_device =
{
"CGA",
@ -526,5 +524,6 @@ device_t cga_device =
NULL,
cga_speed_changed,
NULL,
NULL
NULL,
cga_config
};

View file

@ -27,6 +27,9 @@ typedef struct cga_t
uint8_t *vram;
uint8_t charbuffer[256];
int revision;
int composite;
} cga_t;
void cga_init(cga_t *cga);