From: Toni Wilen Date: Sat, 2 May 2015 16:17:07 +0000 (+0300) Subject: Newtronic Technologies Video DAC 18 and Archos AVideo 12 emulation. X-Git-Tag: 3100~44 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=b154e333321ed71a2f2a1052cd052ceaa14de2df;p=francis%2Fwinuae.git Newtronic Technologies Video DAC 18 and Archos AVideo 12 emulation. --- diff --git a/custom.cpp b/custom.cpp index b3cfa4dd..91914c6d 100644 --- a/custom.cpp +++ b/custom.cpp @@ -45,6 +45,7 @@ #include "luascript.h" #include "devices.h" #include "rommgr.h" +#include "specialmonitors.h" #define CUSTOM_DEBUG 0 #define SPRITE_DEBUG 0 @@ -3747,6 +3748,13 @@ void compute_vsynctime (void) devices_update_sync(svpos, syncadjust); } +void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop) +{ + *phsstrt = hsstrt; + *phsstop = hsstop; + *pvsstrt = vsstrt; + *pvsstop = vsstop; +} static void dumpsync (void) { @@ -4965,12 +4973,12 @@ static void ADKCON (int hpos, uae_u16 v) static void BEAMCON0 (uae_u16 v) { if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) - v &= 0x20; if (v != new_beamcon0) { new_beamcon0 = v; - if (v & ~0x20) + if (v & ~0x20) { write_log (_T("warning: %04X written to BEAMCON0 PC=%08X\n"), v, M68K_GETPC); + dumpsync(); + } } calcdiw(); } @@ -5357,6 +5365,8 @@ static void DDFSTOP (int hpos, uae_u16 v) static void FMODE (int hpos, uae_u16 v) { + if (currprefs.monitoremu) + specialmonitor_store_fmode(vpos, hpos, v); if (! (currprefs.chipset_mask & CSMASK_AGA)) v = 0; v &= 0xC00F; @@ -7422,7 +7432,7 @@ static void vsync_handler_post (void) devices_vsync_post(); - if (varsync_changed || (beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80))) { + if (varsync_changed || (beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200)) != (new_beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200))) { init_hz (); } else if (vpos_count > 0 && abs (vpos_count - vpos_count_diff) > 1 && vposw_change < 4) { init_hz (); @@ -7763,8 +7773,14 @@ static void hsync_handler_post (bool onvsync) bool ciavsyncs = !(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock && genlockvtoggle); CIA_hsync_posthandler (ciahsyncs); - if (ciahsyncs) - CIAB_tod_handler ((beamcon0 & 0x80) ? hsstop : 18); + if (ciahsyncs) { + if (beamcon0 & (0x80 | 0x100)) { + if (hsstop < (maxhpos & ~1) && hsstrt < maxhpos) + CIAB_tod_handler(hsstop); + } else { + CIAB_tod_handler(18); + } + } if (currprefs.cs_ciaatod > 0) { #if 0 static uae_s32 oldtick; @@ -7791,8 +7807,8 @@ static void hsync_handler_post (bool onvsync) #endif } else if (currprefs.cs_ciaatod == 0 && ciavsyncs) { // CIA-A TOD counter increases when vsync pulse ends - if (beamcon0 & 0x80) { - if (vpos == vsstop) + if (beamcon0 & (0x80 | 0x200)) { + if (vpos == vsstop && vsstrt <= maxvpos) CIAA_tod_inc (lof_store ? hsstop : hsstop + hcenter); } else { if (vpos == (currprefs.ntscmode ? VSYNC_ENDLINE_NTSC : VSYNC_ENDLINE_PAL)) { diff --git a/drawing.cpp b/drawing.cpp index efa16872..e73c7254 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -50,8 +50,7 @@ happening, all ports should restrict window widths to be multiples of 16 pixels. #include "inputdevice.h" #include "debug.h" #include "cd32_fmv.h" - -extern bool emulate_specialmonitors (struct vidbuffer*, struct vidbuffer*); +#include "specialmonitors.h" extern int sprite_buffer_res; int lores_factor, lores_shift; @@ -2788,6 +2787,9 @@ static void init_drawing_frame (void) int i, maxline; static int frame_res_old; + if (currprefs.gfx_resolution != changed_prefs.gfx_resolution) + return; + if (lines_count > 0) { int largest_count = 0; int largest_count_res = 0; @@ -2819,10 +2821,16 @@ static void init_drawing_frame (void) autoswitch_old_resolution = RES_HIRES; write_log(_T("Programmed mode autores = %d -> %d (%d)\n"), changed_prefs.gfx_resolution, newres, largest_res); changed_prefs.gfx_resolution = newres; + set_config_changed(); + return; } - } else if (autoswitch_old_resolution == 1) { - changed_prefs.gfx_resolution = RES_HIRES; + } else if (autoswitch_old_resolution == RES_HIRES) { autoswitch_old_resolution = 0; + if (changed_prefs.gfx_resolution != RES_HIRES) { + changed_prefs.gfx_resolution = RES_HIRES; + set_config_changed(); + return; + } } if (currprefs.gfx_autoresolution) { diff --git a/include/custom.h b/include/custom.h index d3d8a9d3..4ab06035 100644 --- a/include/custom.h +++ b/include/custom.h @@ -237,5 +237,6 @@ extern bool isvga (void); extern int current_maxvpos (void); extern struct chipset_refresh *get_chipset_refresh (void); extern void compute_framesync (void); +extern void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop); #endif /* CUSTOM_H */ diff --git a/include/drawing.h b/include/drawing.h index 319f86ca..847551f7 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -45,6 +45,7 @@ before it appears on-screen. (TW: display emulation now does this automatically) extern int lores_factor, lores_shift, interlace_seen; extern bool aga_mode, direct_rgb; +extern int visible_left_border, visible_right_border; STATIC_INLINE int coord_hw_to_window_x (int x) { diff --git a/include/specialmonitors.h b/include/specialmonitors.h new file mode 100644 index 00000000..a21e4338 --- /dev/null +++ b/include/specialmonitors.h @@ -0,0 +1,3 @@ + +bool emulate_specialmonitors (struct vidbuffer*, struct vidbuffer*); +void specialmonitor_store_fmode(int vpos, int hpos, uae_u16 fmode); diff --git a/specialmonitors.cpp b/specialmonitors.cpp index cc9ad213..310a9b56 100755 --- a/specialmonitors.cpp +++ b/specialmonitors.cpp @@ -7,15 +7,38 @@ #include "options.h" #include "xwin.h" #include "custom.h" +#include "drawing.h" +#include "specialmonitors.h" static bool automatic; static int monitor; extern unsigned int bplcon0; -extern int interlace_seen; static uae_u8 graffiti_palette[256 * 4]; +STATIC_INLINE uae_u8 FVR(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return dataline[2]; + else + return ((((uae_u16*)dataline)[0] >> 11) & 31) << 3; +} +STATIC_INLINE uae_u8 FVG(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return dataline[1]; + else + return ((((uae_u16*)dataline)[0] >> 5) & 63) << 2; +} +STATIC_INLINE uae_u8 FVB(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return dataline[0]; + else + return ((((uae_u16*)dataline)[0] >> 0) & 31) << 2; +} + STATIC_INLINE bool FR(struct vidbuffer *src, uae_u8 *dataline) { if (src->pixbytes == 4) @@ -70,7 +93,6 @@ STATIC_INLINE uae_u8 FIRGB(struct vidbuffer *src, uae_u8 *dataline) return v; } - STATIC_INLINE void PRGB(struct vidbuffer *dst, uae_u8 *dataline, uae_u8 r, uae_u8 g, uae_u8 b) { if (dst->pixbytes == 4) { @@ -85,6 +107,52 @@ STATIC_INLINE void PRGB(struct vidbuffer *dst, uae_u8 *dataline, uae_u8 r, uae_u } } +STATIC_INLINE void PUT_PRGB(uae_u8 *d, uae_u8 *d2, struct vidbuffer *dst, uae_u8 r, uae_u8 g, uae_u8 b, int xadd, int doublelines, bool hdouble) +{ + if (hdouble) + PRGB(dst, d - dst->pixbytes, r, g, b); + PRGB(dst, d, r, g, b); + if (xadd > 4) { + PRGB(dst, d + 1 * dst->pixbytes, r, g, b); + if (hdouble) + PRGB(dst, d + 2 * dst->pixbytes, r, g, b); + } + if (doublelines) { + if (hdouble) + PRGB(dst, d2 - dst->pixbytes, r, g, b); + PRGB(dst, d2, r, g, b); + if (xadd > 4) { + PRGB(dst, d2 + 1 * dst->pixbytes, r, g, b); + if (hdouble) + PRGB(dst, d2 + 2 * dst->pixbytes, r, g, b); + } + } +} + +STATIC_INLINE void PUT_AMIGARGB(uae_u8 *d, uae_u8 *s, uae_u8 *d2, uae_u8 *s2, struct vidbuffer *dst, int xadd, int doublelines, bool hdouble) +{ + if (dst->pixbytes == 4) { + if (hdouble) + ((uae_u32*)d)[-1] = ((uae_u32*)s)[-1]; + ((uae_u32*)d)[0] = ((uae_u32*)s)[0]; + } else { + if (hdouble) + ((uae_u16*)d)[-1] = ((uae_u16*)s)[-1]; + ((uae_u16*)d)[0] = ((uae_u16*)s)[0]; + } + if (doublelines) { + if (dst->pixbytes == 4) { + if (hdouble) + ((uae_u32*)d2)[-1] = ((uae_u32*)s2)[-1]; + ((uae_u32*)d2)[0] = ((uae_u32*)s2)[0]; + } else { + if (hdouble) + ((uae_u16*)d2)[-1] = ((uae_u16*)s2)[-1]; + ((uae_u16*)d2)[0] = ((uae_u16*)s2)[0]; + } + } +} + static void clearmonitor(struct vidbuffer *dst) { uae_u8 *p = dst->bufmem; @@ -161,6 +229,304 @@ static bool dctv(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, return true; } +static uae_u16 avideo_previous_fmode[2]; + +static uae_u8 *avideo_buffer; +static int av24_offset; +#define AVIDEO_VRAM_WIDTH 800 +#define AVIDEO_VRAM_HEIGHT 800 +#define AVIDEO_VRAM_BYTES 4 + +static bool avideo(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) +{ + int y, x, vdbl, hdbl; + int ystart, yend, isntsc; + int xadd; + int mode; + int offset = -1; + bool writetovram; + bool av24 = currprefs.monitoremu == MONITOREMU_AVIDEO24; + bool lownybble = false; + bool doublebuffer = false; + uae_u16 fmode; + + fmode = avideo_previous_fmode[oddlines]; + + if (currprefs.chipset_mask & CSMASK_AGA) + return false; + + if (av24) { + if (fmode & 0x40) + mode = 6; + else + mode = 0; + writetovram = (fmode & (0x08 | 0x10 | 0x20)) != 0; + } else { + mode = fmode & 7; + if (mode == 1) + offset = 0; + else if (mode == 3) + offset = 1; + else if (mode == 2) + offset = 2; + writetovram = offset >= 0; + } + + if (!mode) + return false; + + if (!avideo_buffer) { + avideo_buffer = xcalloc(uae_u8, AVIDEO_VRAM_WIDTH * AVIDEO_VRAM_HEIGHT * AVIDEO_VRAM_BYTES); + } + + //write_log(_T("%04x %d %d %d\n"), avideo_previous_fmode[oddlines], mode, offset, writetovram); + + isntsc = (beamcon0 & 0x20) ? 0 : 1; + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + isntsc = currprefs.ntscmode ? 1 : 0; + + vdbl = gfxvidinfo.ychange; + hdbl = gfxvidinfo.xchange; + + xadd = ((1 << 1) / hdbl) * src->pixbytes; + + ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL; + yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL; + + for (y = ystart; y < yend; y++) { + int oddeven = 0; + uae_u8 prev = 0; + int yoff = (((y * 2 + oddlines) - src->yoffset) / vdbl); + if (yoff < 0) + continue; + if (yoff >= src->inheight) + continue; + uae_u8 *line = src->bufmem + yoff * src->rowbytes; + uae_u8 *dstline = dst->bufmem + (((y * 2 + oddlines) - dst->yoffset) / vdbl) * dst->rowbytes; + uae_u8 *vramline = avideo_buffer + y * 2 * AVIDEO_VRAM_WIDTH * AVIDEO_VRAM_BYTES; + + if (av24) { + vramline += av24_offset; + } else { + if (fmode & 0x10) + vramline += AVIDEO_VRAM_WIDTH * AVIDEO_VRAM_BYTES; + } + + for (x = 0; x < src->inwidth; x++) { + uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes; + uae_u8 *d = dstline + ((x << 1) / hdbl) * dst->pixbytes; + uae_u8 *vramptr = vramline + ((x << 1) / hdbl) * AVIDEO_VRAM_BYTES; + uae_u8 *s2 = s + src->rowbytes; + uae_u8 *d2 = d + dst->rowbytes; + if (writetovram) { + uae_u8 val[3]; + val[0] = FVR(src, s) >> 4; + val[1] = FVG(src, s) >> 4; + val[2] = FVB(src, s) >> 4; + if (av24) { // 021 012 102 120 210 201 + uae_u8 v; + + if (fmode & 0x08) { + v = (((val[0] >> 0) & 1) << 3) | (((val[0] >> 1) & 1) << 0); + vramptr[0] &= ~(0x08 | 0x01); + vramptr[0] |= v; + v = (((val[1] >> 0) & 1) << 2); + vramptr[1] &= ~(0x04); + vramptr[1] |= v; + v = (((val[2] >> 0) & 1) << 1); + vramptr[2] &= ~(0x02); + vramptr[2] |= v; + } + + if (fmode & 0x10) { + v = (((val[1] >> 1) & 1) << 3) | (((val[1] >> 2) & 1) << 0); + vramptr[1] &= ~(0x08 | 0x01); + vramptr[1] |= v; + v = (((val[2] >> 1) & 1) << 2); + vramptr[2] &= ~(0x04); + vramptr[2] |= v; + v = (((val[0] >> 2) & 1) << 1); + vramptr[0] &= ~(0x02); + vramptr[0] |= v; + } + + if (fmode & 0x20) { + v = (((val[2] >> 2) & 1) << 3) | (((val[2] >> 3) & 1) << 0); + vramptr[2] &= ~(0x08 | 0x01); + vramptr[2] |= v; + v = (((val[0] >> 3) & 1) << 2); + vramptr[0] &= ~(0x04); + vramptr[0] |= v; + v = (((val[2] >> 3) & 1) << 1); + vramptr[1] &= ~(0x02); + vramptr[1] |= v; + } + + } else { + + uae_u8 v = val[offset]; + vramptr[offset] = (v << 4) | (v & 15); + + } + } + if (writetovram || mode == 7 || (mode == 6 && FVR(src, s) == 0 && FVG(src, s) == 0 && FVB(src, s) == 0)) { + uae_u8 r, g, b; + if (av24) { + r = vramptr[0] << 4; + g = vramptr[1] << 4; + b = vramptr[2] << 4; + } else { + r = vramptr[0]; + g = vramptr[1]; + b = vramptr[2]; + } + if (doublebuffer) { + r = (r << 4) | (r & 15); + g = (g << 4) | (g & 15); + b = (b << 4) | (b & 15); + } + PUT_PRGB(d, d2, dst, r, g, b, xadd, doublelines, false); + } else { + PUT_AMIGARGB(d, s, d2, s2, dst, xadd, doublelines, false); + } + } + } + + dst->nativepositioning = true; + if (monitor != MONITOREMU_AVIDEO12 && monitor != MONITOREMU_AVIDEO24) { + monitor = av24 ? MONITOREMU_AVIDEO24 : MONITOREMU_AVIDEO12; + write_log (_T("AVIDEO mode\n")); + } + + return true; +} + +void specialmonitor_store_fmode(int vpos, int hpos, uae_u16 fmode) +{ + write_log(_T("%04x\n"), fmode); + fmode &= 0xff; + if (fmode == 0x91) + av24_offset = AVIDEO_VRAM_WIDTH * AVIDEO_VRAM_BYTES; + else if (fmode == 0x92) + av24_offset = 0; + avideo_previous_fmode[lof_store ? 0 : 1] = fmode; +} + +static bool do_avideo(struct vidbuffer *src, struct vidbuffer *dst) +{ + bool v; + if (interlace_seen) { + if (currprefs.gfx_iscanlines) { + v = avideo(src, dst, false, lof_store ? 0 : 1); + } else { + v = avideo(src, dst, false, 0); + v |= avideo(src, dst, false, 1); + } + } else { + v = avideo(src, dst, true, 0); + } + return v; +} + + +static bool videodac18(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) +{ + int y, x, vdbl, hdbl; + int ystart, yend, isntsc; + int xadd; + uae_u16 hsstrt, hsstop, vsstrt, vsstop; + int xstart, xstop; + + if ((beamcon0 & (0x80 | 0x100 | 0x200 | 0x10)) != 0x300) + return false; + getsyncregisters(&hsstrt, &hsstop, &vsstrt, &vsstop); + + if (hsstop >= (maxhpos & ~1)) + hsstrt = 0; + xstart = ((hsstrt * 2) << RES_MAX) - src->xoffset; + xstop = ((hsstop * 2) << RES_MAX) - src->xoffset; + + isntsc = (beamcon0 & 0x20) ? 0 : 1; + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + isntsc = currprefs.ntscmode ? 1 : 0; + + vdbl = gfxvidinfo.ychange; + hdbl = gfxvidinfo.xchange; + + xadd = ((1 << 1) / hdbl) * src->pixbytes; + + ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL; + yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL; + + uae_u8 r = 0, g = 0, b = 0; + for (y = ystart; y < yend; y++) { + int oddeven = 0; + uae_u8 prev = 0; + int yoff = (((y * 2 + oddlines) - src->yoffset) / vdbl); + if (yoff < 0) + continue; + if (yoff >= src->inheight) + continue; + uae_u8 *line = src->bufmem + yoff * src->rowbytes; + uae_u8 *dstline = dst->bufmem + (((y * 2 + oddlines) - dst->yoffset) / vdbl) * dst->rowbytes; + r = g = b = 0; + for (x = 0; x < src->inwidth; x++) { + uae_u8 *s = line + ((x << 1) / hdbl) * src->pixbytes; + uae_u8 *d = dstline + ((x << 1) / hdbl) * dst->pixbytes; + uae_u8 *s2 = s + src->rowbytes; + uae_u8 *d2 = d + dst->rowbytes; + uae_u8 newval = FIRGB(src, s); + uae_u8 val = prev | (newval << 4); + if (oddeven) { + int mode = val >> 6; + int data = (val & 63) << 2; + if (mode == 0) { + r = data; + g = data; + b = data; + } else if (mode == 1) { + b = data; + } else if (mode == 2) { + r = data; + } else { + g = data; + } + if (y >= vsstrt && y < vsstop && x >= xstart && y < xstop) { + PUT_PRGB(d, d2, dst, r, g, b, xadd, doublelines, true); + } else { + PUT_AMIGARGB(d, s, d2, s2, dst, xadd, doublelines, true); + } + } + oddeven = oddeven ? 0 : 1; + prev = val >> 4; + } + } + + dst->nativepositioning = true; + if (monitor != MONITOREMU_VIDEODAC18) { + monitor = MONITOREMU_VIDEODAC18; + write_log (_T("Video DAC 18 mode\n")); + } + + return true; +} + +static bool do_videodac18(struct vidbuffer *src, struct vidbuffer *dst) +{ + bool v; + if (interlace_seen) { + if (currprefs.gfx_iscanlines) { + v = videodac18(src, dst, false, lof_store ? 0 : 1); + } else { + v = videodac18(src, dst, false, 0); + v |= videodac18(src, dst, false, 1); + } + } else { + v = videodac18(src, dst, true, 0); + } + return v; +} + static const uae_u8 ham_e_magic_cookie[] = { 0xa2, 0xf5, 0x84, 0xdc, 0x6d, 0xb0, 0x7f }; static const uae_u8 ham_e_magic_cookie_reg = 0x14; static const uae_u8 ham_e_magic_cookie_ham = 0x18; @@ -283,17 +649,11 @@ static bool ham_e(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines if (hameplus) { uae_u8 ar, ag, ab; - if (abs(r - or) < 64 && abs(g - og) < 64 && abs(b - ob) < 64) { - ar = (r + or) / 2; - ag = (g + og) / 2; - ab = (b + ob) / 2; - } else { - ar = r; - ag = g; - ab = b; - } + ar = (r + or) / 2; + ag = (g + og) / 2; + ab = (b + ob) / 2; - if (xadd > 2) { + if (xadd > 4) { PRGB(dst, d - dst->pixbytes, ar, ag, ab); PRGB(dst, d, ar, ag, ab); PRGB(dst, d + 1 * dst->pixbytes, r, g, b); @@ -316,38 +676,10 @@ static bool ham_e(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines og = g; ob = b; } else { - PRGB(dst, d - dst->pixbytes, r, g, b); - PRGB(dst, d, r, g, b); - if (xadd > 2) { - PRGB(dst, d + 1 * dst->pixbytes, r, g, b); - PRGB(dst, d + 2 * dst->pixbytes, r, g, b); - } - if (doublelines) { - PRGB(dst, d2 - dst->pixbytes, r, g, b); - PRGB(dst, d2, r, g, b); - if (xadd > 2) { - PRGB(dst, d2 + 1 * dst->pixbytes, r, g, b); - PRGB(dst, d2 + 2 * dst->pixbytes, r, g, b); - } - } + PUT_PRGB(d, d2, dst, r, g, b, xadd, doublelines, true); } } else { - if (dst->pixbytes == 4) { - ((uae_u32*)d)[-1] = ((uae_u32*)s)[-1]; - ((uae_u32*)d)[0] = ((uae_u32*)s)[0]; - } else { - ((uae_u16*)d)[-1] = ((uae_u16*)s)[-1]; - ((uae_u16*)d)[0] = ((uae_u16*)s)[0]; - } - if (doublelines) { - if (dst->pixbytes == 4) { - ((uae_u32*)d2)[-1] = ((uae_u32*)s2)[-1]; - ((uae_u32*)d2)[0] = ((uae_u32*)s2)[0]; - } else { - ((uae_u16*)d2)[-1] = ((uae_u16*)s2)[-1]; - ((uae_u16*)d2)[0] = ((uae_u16*)s2)[0]; - } - } + PUT_AMIGARGB(d, s, d2, s2, dst, xadd, doublelines, true); } } @@ -746,31 +1078,38 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) static bool emulate_specialmonitors2(struct vidbuffer *src, struct vidbuffer *dst) { + automatic = false; if (currprefs.monitoremu == MONITOREMU_AUTO) { automatic = true; bool v = a2024(src, dst); if (!v) v = graffiti(src, dst); + if (!v) + v = do_videodac18(src, dst); return v; } else if (currprefs.monitoremu == MONITOREMU_A2024) { - automatic = false; return a2024(src, dst); } else if (currprefs.monitoremu == MONITOREMU_GRAFFITI) { - automatic = false; return graffiti(src, dst); } else if (currprefs.monitoremu == MONITOREMU_DCTV) { - automatic = false; return dctv(src, dst, false, 0); } else if (currprefs.monitoremu == MONITOREMU_HAM_E || currprefs.monitoremu == MONITOREMU_HAM_E_PLUS) { bool v; - automatic = false; if (interlace_seen) { - v = ham_e(src, dst, false, 0); - v |= ham_e(src, dst, false, 1); + if (currprefs.gfx_iscanlines) { + v = ham_e(src, dst, false, lof_store ? 0 : 1); + } else { + v = ham_e(src, dst, false, 0); + v |= ham_e(src, dst, false, 1); + } } else { v = ham_e(src, dst, true, 0); } return v; + } else if (currprefs.monitoremu == MONITOREMU_VIDEODAC18) { + return do_videodac18(src, dst); + } else if (currprefs.monitoremu == MONITOREMU_AVIDEO12 || currprefs.monitoremu == MONITOREMU_AVIDEO24) { + return do_avideo(src, dst); } return false; }