diff --git a/src/Makefile.am b/src/Makefile.am index cf2f63b..cb5293c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 4aa3c3c..36bc323 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -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 diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 14155ac..c3ce59b 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -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 diff --git a/src/dosbox/vid_cga_comp.c b/src/dosbox/vid_cga_comp.c new file mode 100644 index 0000000..ec5584f --- /dev/null +++ b/src/dosbox/vid_cga_comp.c @@ -0,0 +1,325 @@ +/* Code borrowed from DOSBox and adapted by OBattler. + Original author: reenigne. */ + +#include +#include +#include + +#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); +} diff --git a/src/dosbox/vid_cga_comp.h b/src/dosbox/vid_cga_comp.h new file mode 100644 index 0000000..cccd9bd --- /dev/null +++ b/src/dosbox/vid_cga_comp.h @@ -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); diff --git a/src/vid_cga.c b/src/vid_cga.c index f0cf151..247dbf3 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -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 }; diff --git a/src/vid_cga.h b/src/vid_cga.h index ef6481b..d13d02a 100644 --- a/src/vid_cga.h +++ b/src/vid_cga.h @@ -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);