From: Toni Wilen Date: Tue, 4 Mar 2014 18:43:42 +0000 (+0200) Subject: 2710b10 X-Git-Tag: 2800~25 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=86a152119d853f91d60d1681b23f6a0c23de5708;p=francis%2Fwinuae.git 2710b10 --- diff --git a/cfgfile.cpp b/cfgfile.cpp index aa5c5e25..051bbaed 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -1060,6 +1060,35 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write_bool (f, _T("bsdsocket_emu"), p->socket_emu); if (p->a2065name[0]) cfgfile_write_str (f, _T("a2065"), p->a2065name); + tmp[0] = 0; + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto && !sr->srcport) { + TCHAR *p = tmp + _tcslen (tmp); + if (p > tmp) + *p++ = ','; + _stprintf (p, _T("%d"), sr->dstport); + } + } + if (tmp[0]) + cfgfile_write_str (f, _T("slirp_ports"), tmp); + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto && sr->srcport) { + uae_u32 v = htonl (sr->addr); + if (v) { + _stprintf (tmp, _T("%s:%d:%d:%d.%d.%d.%d"), + sr->proto == 1 ? _T("tcp") : _T("udp"), + sr->dstport, sr->srcport, + (v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff); + } else { + _stprintf (tmp, _T("%s:%d:%d"), + sr->proto == 1 ? _T("tcp") : _T("udp"), + sr->dstport, sr->srcport); + } + cfgfile_write_str (f, _T("slirp_redir"), tmp); + } + } cfgfile_write_bool (f, _T("synchronize_clock"), p->tod_hack); cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom); @@ -2591,6 +2620,74 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } +#ifdef WITH_SLIRP + if (cfgfile_string (option, value, _T("slirp_ports"), tmpbuf, sizeof (tmpbuf) / sizeof TCHAR)) { + TCHAR *tmpp2 = tmpbuf; + _tcscat (tmpbuf, _T(",")); + for (;;) { + tmpp = _tcschr (tmpp2, ','); + if (!tmpp) + break; + *tmpp++= 0; + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto == 0) { + sr->dstport = _tstol (tmpp2); + sr->proto = 1; + break; + } + } + tmpp2 = tmpp; + } + return 1; + } + if (cfgfile_string (option, value, _T("slirp_redir"), tmpbuf, sizeof (tmpbuf) / sizeof TCHAR)) { + TCHAR *tmpp2 = tmpbuf; + _tcscat (tmpbuf, _T(":")); + for (i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &p->slirp_redirs[i]; + if (sr->proto == 0) { + char *s; + tmpp = _tcschr (tmpp2, ':'); + if (!tmpp) + break; + *tmpp++= 0; + if (!_tcsicmp (tmpp2, _T("tcp"))) + sr->proto = 1; + else if (!_tcsicmp (tmpp2, _T("udp"))) + sr->proto = 2; + else + break; + tmpp2 = tmpp; + tmpp = _tcschr (tmpp2, ':'); + if (!tmpp) { + sr->proto = 0; + break; + } + *tmpp++= 0; + sr->dstport = _tstol (tmpp2); + tmpp2 = tmpp; + tmpp = _tcschr (tmpp2, ':'); + if (!tmpp) { + sr->proto = 0; + break; + } + *tmpp++= 0; + sr->srcport = _tstol (tmpp2); + tmpp2 = tmpp; + tmpp = _tcschr (tmpp2, ':'); + if (!tmpp) + break; + *tmpp++= 0; + s = ua (tmpp2); + sr->addr = inet_addr (s); + xfree (s); + } + } + return 1; + } +#endif + return 0; } diff --git a/custom.cpp b/custom.cpp index af803d7b..a55b665f 100644 --- a/custom.cpp +++ b/custom.cpp @@ -207,6 +207,7 @@ bool programmedmode; int syncbase; static int fmode; uae_u16 beamcon0, new_beamcon0; +static bool varsync_changed; uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL; static int maxvpos_stored, maxhpos_stored; static uae_u16 hsstop, hbstrt, hbstop, vsstop, vbstrt, vbstop, hsstrt, vsstrt, hcenter; @@ -296,9 +297,15 @@ static int last_fetch_hpos, last_sprite_hpos; static int diwfirstword, diwlastword; static int last_hdiw; static enum diw_states diwstate, hdiwstate, ddfstate; + int first_planes_vpos, last_planes_vpos; +static int first_bplcon0, first_bplcon0_old; +static int first_planes_vpos_old, last_planes_vpos_old; int diwfirstword_total, diwlastword_total; int ddffirstword_total, ddflastword_total; +static int diwfirstword_total_old, diwlastword_total_old; +static int ddffirstword_total_old, ddflastword_total_old; +bool vertical_changed, horizontal_changed; int firstword_bplcon1; static int last_copper_hpos; @@ -2019,8 +2026,6 @@ static void finish_last_fetch (int pos, int fm, bool reallylast) { if (thisline_decision.plfleft < 0) return; -// if (reallylast) -// plf_state = plf_end; if (plfr_state >= plfr_end) return; plfr_state = plfr_end; @@ -2110,6 +2115,9 @@ end: /* make sure fetch that goes beyond maxhpos is finished */ static void finish_final_fetch (void) { + if (thisline_decision.plfleft < 0) + return; + if (plfr_state < plf_end) finish_last_fetch (maxhpos, fetchmode, true); plfr_state = plfr_finished; @@ -2565,9 +2573,7 @@ static void maybe_start_bpl_dma (int hpos) STATIC_INLINE bool cant_this_last_line (void) { - if (currprefs.chipset_mask & CSMASK_AGA) - return false; - return vpos >= maxvpos + lof_store - 1; + return vpos + 1 >= maxvpos + lof_store; } /* This function is responsible for turning on datafetch if necessary. */ @@ -2638,9 +2644,9 @@ STATIC_INLINE void decide_line (int hpos) if (plf_state == plf_active && (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) || hpos >= 0x18 || HARD_DDF_LIMITS_DISABLED)) { start_bpl_dma (hpos, bplstart); last_decide_line_hpos = hpos; - #ifndef CUSTOM_SIMPLE +#ifndef CUSTOM_SIMPLE do_sprites (hpos); - #endif +#endif return; } } @@ -3358,6 +3364,8 @@ static void finish_decisions (void) if (changed) { thisline_changed = 1; *dp = thisline_decision; +// if (vpos >= maxvpos) +// dp[1].plfleft = -2; } else /* The only one that may differ: */ dp->ctable = thisline_decision.ctable; @@ -3713,7 +3721,7 @@ void compute_framesync (void) int start = hsyncstartpos; //hbstrt; int stop = hsyncendpos; //hbstop; - gfxvidinfo.drawbuffer.inwidth = ((maxhpos - (maxhpos - start + stop) + 1) * 2) << res2; + gfxvidinfo.drawbuffer.inwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; gfxvidinfo.drawbuffer.inxoffset = stop * 2; gfxvidinfo.drawbuffer.extrawidth = 0; @@ -3832,7 +3840,7 @@ void init_hz (bool fullinit) // (someone poked VPOSW) if (vpos_count < 10) vpos_count = 10; - vblank_hz = (isntsc ? 15734 : 15625.0) / vpos_count; + vblank_hz = (isntsc ? 15734.0 : 15625.0) / vpos_count; vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = vblank_hz; maxvpos_nom = vpos_count - (lof_current ? 1 : 0); if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) { @@ -3843,7 +3851,12 @@ void init_hz (bool fullinit) maxvpos_display = 313; } reset_drawing (); + } else if (vpos_count == 0) { + // mode reset + vpos_count = maxvpos; + vpos_count_diff = maxvpos; } + if (beamcon0 & 0x80) { // programmable scanrates (ECS Agnus) if (vtotal >= MAXVPOS) @@ -3869,7 +3882,9 @@ void init_hz (bool fullinit) equ_vblank_endline = -1; doublescan = htotal <= 164 ? 1 : 0; programmedmode = true; - dumpsync (); + varsync_changed = true; + vpos_count = maxvpos_nom; + vpos_count_diff = maxvpos_nom; hzc = 1; } if (maxvpos_nom >= MAXVPOS) @@ -3889,13 +3904,13 @@ void init_hz (bool fullinit) set_delay_lastcycle (); if (beamcon0 & 0x80) { if (hbstrt > maxhpos) - hsyncstartpos = hbstrt + 1; + hsyncstartpos = hbstrt; else - hsyncstartpos = maxhpos + hbstrt + 1; + hsyncstartpos = maxhpos + hbstrt; if (hbstop > maxhpos) - hsyncendpos = maxhpos - hbstop - 1; + hsyncendpos = maxhpos - hbstop - 2; else - hsyncendpos = hbstop - 1; + hsyncendpos = hbstop - 2; if (hsyncendpos < 2) hsyncendpos = 2; } else { @@ -3930,6 +3945,11 @@ void init_hz (bool fullinit) updatedisplayarea (); inputdevice_tablet_strobe (); + if (varsync_changed) { + varsync_changed = false; + dumpsync (); + } + if (fullinit) vpos_count_diff = maxvpos_nom; } @@ -4485,16 +4505,8 @@ int intlev (void) #define INT_PROCESSING_DELAY (3 * CYCLE_UNIT) STATIC_INLINE int use_eventmode (uae_u16 v) { - if (!currprefs.cpu_cycle_exact) - return 0; - if (currprefs.cachesize || currprefs.m68k_speed < 0) - return 0; if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68020) return 1; - if (v & 0x8000) - return 1; - if (event2_count) - return 1; return 0; } @@ -4675,8 +4687,7 @@ static void varsync (void) #endif if (!(beamcon0 & 0x80)) return; - vpos_count = 0; - dumpsync (); + varsync_changed = true; } #ifdef PICASSO96 @@ -6370,6 +6381,30 @@ static void init_hardware_frame (void) nextline_how = nln_normal; diwstate = DIW_waiting_start; ddfstate = DIW_waiting_start; + + if (first_bplcon0 != first_bplcon0_old) { + vertical_changed = horizontal_changed = true; + } + first_bplcon0_old = first_bplcon0; + + if (first_planes_vpos != first_planes_vpos_old || + last_planes_vpos != last_planes_vpos_old) { + vertical_changed = true; + } + first_planes_vpos_old = first_planes_vpos; + last_planes_vpos_old = last_planes_vpos; + + if (diwfirstword_total != diwfirstword_total_old || + diwlastword_total != diwlastword_total_old || + ddffirstword_total != ddffirstword_total_old || + ddflastword_total != ddflastword_total_old) { + horizontal_changed = true; + } + diwfirstword_total_old = diwfirstword_total; + diwlastword_total_old = diwlastword_total; + ddffirstword_total_old = ddffirstword_total; + ddflastword_total_old = ddflastword_total; + first_planes_vpos = 0; last_planes_vpos = 0; diwfirstword_total = max_diwlastword; @@ -6378,7 +6413,9 @@ static void init_hardware_frame (void) ddflastword_total = 0; plflastline_total = 0; plffirstline_total = current_maxvpos (); + first_bplcon0 = 0; autoscale_bordercolors = 0; + for (i = 0; i < MAX_SPRITES; i++) spr[i].ptxhpos = MAXHPOS; plf_state = plf_end; @@ -7040,7 +7077,7 @@ static void vsync_handler_post (void) gfxboard_vsync_handler (); #endif - if ((beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80))) { + if (varsync_changed || (beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80))) { init_hz (); } else if (vpos_count > 0 && abs (vpos_count - vpos_count_diff) > 1) { init_hz (); @@ -7093,6 +7130,9 @@ static void hsync_scandoubler (void) struct draw_info *dip1; uaecptr bpltmp[8], bpltmpx[8]; + if (vpos >= maxvpos - 1) + return; + next_lineno++; scandoubled_line = 1; #ifdef DEBUGGER @@ -7560,7 +7600,7 @@ static void hsync_handler_post (bool onvsync) nextline_how = nln_normal; if (doflickerfix () && interlace_seen > 0) { lineno *= 2; - } else if (currprefs.gfx_vresolution && currprefs.gfx_scanlines >= 2) { + } else if ((doublescan <= 0 || interlace_seen > 0) && currprefs.gfx_vresolution && currprefs.gfx_scanlines >= 2) { lineno *= 2; nextline_how = currprefs.gfx_vresolution > VRES_NONDOUBLE && (currprefs.gfx_scanlines & 1) == 0 ? nln_doubled : nln_nblack; if (interlace_seen) { @@ -7627,6 +7667,8 @@ static void hsync_handler_post (bool onvsync) //copper_check (2); if (GET_PLANES (bplcon0) > 0 && dmaen (DMA_BITPLANE)) { + if (first_bplcon0 == 0) + first_bplcon0 = bplcon0; if (vpos > last_planes_vpos) last_planes_vpos = vpos; if (vpos >= minfirstline && first_planes_vpos == 0) { diff --git a/drawing.cpp b/drawing.cpp index 0e463f90..3a6663ec 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -84,7 +84,7 @@ static int linedbl, linedbld; int interlace_seen = 0; #define AUTO_LORES_FRAMES 10 -static int can_use_lores = 0, frame_res, frame_res_lace, last_max_ypos; +static int can_use_lores = 0, frame_res, frame_res_lace; static int resolution_count[RES_MAX + 1]; static bool center_reset; @@ -204,7 +204,6 @@ static int hblank_left_start, hblank_right_stop; static int linetoscr_x_adjust_bytes; static int thisframe_y_adjust; static int thisframe_y_adjust_real, max_ypos_thisframe, min_ypos_for_screen; -static int extra_y_adjust; int thisframe_first_drawn_line, thisframe_last_drawn_line; /* A frame counter that forces a redraw after at least one skipped frame in @@ -358,6 +357,7 @@ extern int plffirstline_total, plflastline_total; extern int first_planes_vpos, last_planes_vpos; extern int diwfirstword_total, diwlastword_total; extern int ddffirstword_total, ddflastword_total; +extern bool vertical_changed, horizontal_changed; extern int firstword_bplcon1; extern int lof_store; @@ -399,6 +399,7 @@ static void reset_custom_limits (void) { gclow = gcloh = gclox = gcloy = 0; gclorealh = -1; + center_reset = true; } static void set_blanking_limits (void) @@ -1051,9 +1052,11 @@ STATIC_INLINE void fill_line2 (int startpos, int len) static void fill_line (void) { int hs = coord_hw_to_window_x (hsyncstartpos * 2); - if (hs >= gfxvidinfo.drawbuffer.inwidth || hposblank) { + if (hposblank) { hposblank = 3; fill_line2 (visible_left_border, gfxvidinfo.drawbuffer.inwidth); + } else if (hs >= gfxvidinfo.drawbuffer.inwidth) { + fill_line2 (visible_left_border, gfxvidinfo.drawbuffer.inwidth); } else { fill_line2 (visible_left_border, hs); hposblank = 2; @@ -2056,22 +2059,17 @@ void init_aspect_maps (void) for (i = 0; i < maxl; i++) { int v = i - min_ypos_for_screen; if (v >= h && max_drawn_amiga_line < 0) - max_drawn_amiga_line = i - min_ypos_for_screen; + max_drawn_amiga_line = v; if (i < min_ypos_for_screen || v >= h) v = -1; amiga2aspect_line_map[i] = v; } if (max_drawn_amiga_line < 0) max_drawn_amiga_line = maxl - min_ypos_for_screen; + if (max_drawn_amiga_line > gfxvidinfo.drawbuffer.inheight) + max_drawn_amiga_line = gfxvidinfo.drawbuffer.inheight; max_drawn_amiga_line >>= linedbl; - if (currprefs.gfx_ycenter && !currprefs.gfx_filter_autoscale) { - /* @@@ verify maxvpos vs. MAXVPOS */ - extra_y_adjust = (h - (maxvpos_display << linedbl)) >> 1; - if (extra_y_adjust < 0) - extra_y_adjust = 0; - } - for (i = 0; i < h; i++) native2amiga_line_map[i] = -1; @@ -2400,6 +2398,9 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in break; } + if (border && dp_for_drawing->plfleft < -1) + border = -1; // interlace mode missing odd line = blank + dh = dh_line; xlinebuffer = gfxvidinfo.drawbuffer.linemem; if (xlinebuffer == 0 && do_double @@ -2551,7 +2552,6 @@ static void center_image (void) { int prev_x_adjust = visible_left_border; int prev_y_adjust = thisframe_y_adjust; - int tmp; int w = gfxvidinfo.drawbuffer.inwidth; if (currprefs.gfx_xcenter && !currprefs.gfx_filter_autoscale && max_diwstop > 0) { @@ -2562,13 +2562,13 @@ static void center_image (void) else visible_left_border = max_diwstop - w - (max_diwstop - min_diwstart - w) / 2; visible_left_border &= ~((xshift (1, lores_shift)) - 1); - -#if 0 - /* Would the old value be good enough? If so, leave it as it is if we want to - * be clever. */ - if (currprefs.gfx_xcenter == 2) { - if (center_reset || (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart && min_diwstart - visible_left_border <= 32)) - visible_left_border = prev_x_adjust; +#if 1 + if (!center_reset && !vertical_changed) { + /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */ + if (currprefs.gfx_xcenter == 2) { + if (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart && min_diwstart - visible_left_border <= 32) + visible_left_border = prev_x_adjust; + } } #endif } else if (gfxvidinfo.drawbuffer.extrawidth) { @@ -2603,44 +2603,39 @@ static void center_image (void) if (thisframe_last_drawn_line - thisframe_first_drawn_line < max_drawn_amiga_line && currprefs.gfx_ycenter == 2) thisframe_y_adjust = (thisframe_last_drawn_line - thisframe_first_drawn_line - max_drawn_amiga_line) / 2 + thisframe_first_drawn_line; else - thisframe_y_adjust = thisframe_first_drawn_line + ((thisframe_last_drawn_line - thisframe_first_drawn_line) - max_drawn_amiga_line) / 2; - -#if 0 - /* Would the old value be good enough? If so, leave it as it is if we want to - * be clever. */ - if (currprefs.gfx_ycenter == 2 && thisframe_y_adjust != prev_y_adjust) { - if (center_reset || (prev_y_adjust <= thisframe_first_drawn_line && prev_y_adjust + max_drawn_amiga_line > thisframe_last_drawn_line)) - thisframe_y_adjust = prev_y_adjust; + thisframe_y_adjust = thisframe_first_drawn_line; +#if 1 + /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */ + if (!center_reset && !horizontal_changed) { + if (currprefs.gfx_ycenter == 2 && thisframe_y_adjust != prev_y_adjust) { + if (prev_y_adjust <= thisframe_first_drawn_line && prev_y_adjust + max_drawn_amiga_line > thisframe_last_drawn_line) + thisframe_y_adjust = prev_y_adjust; + } } #endif } /* Make sure the value makes sense */ - if (thisframe_y_adjust + max_drawn_amiga_line > maxvpos_display) - thisframe_y_adjust = maxvpos_display - max_drawn_amiga_line; - if (thisframe_y_adjust < minfirstline) - thisframe_y_adjust = minfirstline; + if (thisframe_y_adjust + max_drawn_amiga_line > maxvpos + maxvpos / 2) + thisframe_y_adjust = maxvpos + maxvpos / 2 - max_drawn_amiga_line; + if (thisframe_y_adjust < 0) + thisframe_y_adjust = 0; thisframe_y_adjust_real = thisframe_y_adjust << linedbl; - tmp = (maxvpos_display - thisframe_y_adjust + 1) << linedbl; - if (tmp != max_ypos_thisframe) { - last_max_ypos = tmp; - if (last_max_ypos < 0) - last_max_ypos = 0; - } - max_ypos_thisframe = tmp; + max_ypos_thisframe = (maxvpos_display - minfirstline + 1) << linedbl; - /* @@@ interlace_seen used to be (bplcon0 & 4), but this is probably - * better. */ if (prev_x_adjust != visible_left_border || prev_y_adjust != thisframe_y_adjust) - frame_redraw_necessary |= (interlace_seen > 0 && linedbl) ? 2 : 1; + frame_redraw_necessary |= interlace_seen > 0 && linedbl ? 2 : 1; max_diwstop = 0; min_diwstart = MAX_STOP; gfxvidinfo.drawbuffer.xoffset = (DISPLAY_LEFT_SHIFT << RES_MAX) + (visible_left_border << (RES_MAX - currprefs.gfx_resolution)); gfxvidinfo.drawbuffer.yoffset = thisframe_y_adjust << VRES_MAX; + center_reset = false; + horizontal_changed = false; + vertical_changed = false; } static int frame_res_cnt; @@ -2649,7 +2644,7 @@ static void init_drawing_frame (void) int i, maxline; static int frame_res_old; - if (currprefs.gfx_autoresolution && !specialmonitoron) { + if (currprefs.gfx_autoresolution) { int frame_res_detected; int frame_res_lace_detected = frame_res_lace; @@ -2935,57 +2930,28 @@ static void lightpen_update (struct vidbuffer *vb) lightpen_active = 0; } -static int lasti, lastwhere2, lastline; struct vidbuffer *xvbin, *xvbout; static void draw_frame2 (struct vidbuffer *vbin, struct vidbuffer *vbout) { + int i; + xvbin = vbin; xvbout = vbout; - for (int i = 0; i < max_ypos_thisframe; i++) { + for (i = 0; i < max_ypos_thisframe; i++) { int i1 = i + min_ypos_for_screen; int line = i + thisframe_y_adjust_real; - int where2; + int where2 = amiga2aspect_line_map[i1]; - where2 = amiga2aspect_line_map[i1]; if (where2 >= vbin->inheight) break; if (where2 < 0) continue; - lasti = i; - lastline = line; - lastwhere2 = where2; - hposblank = 0; pfield_draw_line (vbout, line, where2, amiga2aspect_line_map[i1 + 1]); } - -#if 0 - /* clear possible old garbage at the bottom if emulated area become smaller */ - for (i = last_max_ypos; i < vb->outheight; i++) { - int i1 = i + min_ypos_for_screen; - int line = i + thisframe_y_adjust_real; - int where2 = amiga2aspect_line_map[i1]; - - if (where2 >= gfxvidinfo.drawbuffer.outheight) - break; - if (where2 < 0) - continue; - - hposblank = i > last_max_ypos || i >= max_ypos_thisframe; - - xlinebuffer = vb->linemem; - if (xlinebuffer == 0) - xlinebuffer = row_map[where2]; - xlinebuffer -= linetoscr_x_adjust_bytes; - fill_line (); - if (line < max_ypos_thisframe) - linestate[line] = LINE_UNDECIDED; - do_flush_line (vb, where2); - } -#endif } bool draw_frame (struct vidbuffer *vb) diff --git a/ethernet.cpp b/ethernet.cpp index ac4c09aa..8684b0db 100644 --- a/ethernet.cpp +++ b/ethernet.cpp @@ -16,27 +16,31 @@ struct ethernet_data ethernet_getfunc *getfunc; }; +#define SLIRP_PORT_OFFSET 0 -static int getmode (void) -{ - if (!_tcsicmp (currprefs.a2065name, _T("none")) || currprefs.a2065name[0] == 0) - return UAENET_NONE; - if (!_tcsicmp (currprefs.a2065name, _T("slirp"))) - return UAENET_SLIRP; - return UAENET_PCAP; -} +static const int slirp_ports[] = { 21, 22, 23, 80, 0 }; static struct ethernet_data *slirp_data; +static bool slirp_inited; uae_sem_t slirp_sem1, slirp_sem2; static int netmode; -static struct netdriverdata slirpd = { +static struct netdriverdata slirpd = +{ UAENET_SLIRP, _T("slirp"), _T("SLIRP User Mode NAT"), 1500, { 0x00,0x80,0x10,50,51,52 }, 1 }; +static struct netdriverdata slirpd2 = +{ + UAENET_SLIRP_INBOUND, + _T("slirp_inbound"), _T("SLIRP + Open ports (21-23,80)"), + 1500, + { 0x00,0x80,0x10,50,51,52 }, + 1 +}; int slirp_can_output(void) { @@ -57,6 +61,7 @@ void ethernet_trigger (void *vsd) switch (netmode) { case UAENET_SLIRP: + case UAENET_SLIRP_INBOUND: { struct ethernet_data *ed = (struct ethernet_data*)vsd; if (slirp_data) { @@ -85,6 +90,7 @@ int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_go switch (ndd->type) { case UAENET_SLIRP: + case UAENET_SLIRP_INBOUND: { struct ethernet_data *ed = (struct ethernet_data*)vsd; ed->gotfunc = gotfunc; @@ -93,6 +99,34 @@ int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_go uae_sem_init (&slirp_sem1, 0, 1); uae_sem_init (&slirp_sem2, 0, 1); slirp_init (); + for (int i = 0; i < MAX_SLIRP_REDIRS; i++) { + struct slirp_redir *sr = &currprefs.slirp_redirs[i]; + if (sr->proto) { + struct in_addr a; + if (sr->srcport == 0) { + inet_aton("10.0.2.15", &a); + slirp_redir (0, sr->dstport, a, sr->dstport); + } else { + a.S_un.S_addr = sr->addr; + slirp_redir (sr->proto == 1 ? 0 : 1, sr->dstport, a, sr->srcport); + } + } + } + if (ndd->type == UAENET_SLIRP_INBOUND) { + struct in_addr a; + inet_aton("10.0.2.15", &a); + for (int i = 0; slirp_ports[i]; i++) { + int port = slirp_ports[i]; + int j; + for (j = 0; j < MAX_SLIRP_REDIRS; j++) { + struct slirp_redir *sr = &currprefs.slirp_redirs[j]; + if (sr->proto && sr->dstport == port) + break; + } + if (j == MAX_SLIRP_REDIRS) + slirp_redir (0, port + SLIRP_PORT_OFFSET, a, port); + } + } slirp_start (); } return 1; @@ -109,8 +143,14 @@ void ethernet_close (struct netdriverdata *ndd, void *vsd) switch (ndd->type) { case UAENET_SLIRP: - slirp_end (); - slirp_data = NULL; + case UAENET_SLIRP_INBOUND: + if (slirp_data) { + slirp_data = NULL; + slirp_end (); + slirp_cleanup (); + uae_sem_destroy (&slirp_sem1); + uae_sem_destroy (&slirp_sem2); + } return; case UAENET_PCAP: return uaenet_close (vsd); @@ -131,6 +171,8 @@ bool ethernet_enumerate (struct netdriverdata **nddp, const TCHAR *name) *nddp = NULL; if (!_tcsicmp (slirpd.name, name)) *nddp = &slirpd; + if (!_tcsicmp (slirpd2.name, name)) + *nddp = &slirpd2; if (*nddp == NULL) *nddp = uaenet_enumerate (name); if (*nddp) { @@ -141,6 +183,7 @@ bool ethernet_enumerate (struct netdriverdata **nddp, const TCHAR *name) } j = 0; nddp[j++] = &slirpd; + nddp[j++] = &slirpd2; nd = uaenet_enumerate (NULL); if (nd) { for (int i = 0; i < nd[i].active; i++) { @@ -156,6 +199,7 @@ void ethernet_close_driver (struct netdriverdata *ndd) switch (ndd->type) { case UAENET_SLIRP: + case UAENET_SLIRP_INBOUND: return; case UAENET_PCAP: return uaenet_close_driver (ndd); @@ -168,6 +212,7 @@ int ethernet_getdatalenght (struct netdriverdata *ndd) switch (ndd->type) { case UAENET_SLIRP: + case UAENET_SLIRP_INBOUND: return sizeof (struct ethernet_data); case UAENET_PCAP: return uaenet_getdatalenght (); diff --git a/fpp.cpp b/fpp.cpp index 8cdf63d1..e6e1606a 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -27,6 +27,11 @@ #include "cpummu030.h" #include "debug.h" +#ifdef X86_MSVC_ASSEMBLY +#define X86_MSVC_ASSEMBLY_FPU +#define NATIVE_FPUCW +#endif + #define DEBUG_FPP 0 #define EXCEPTION_FPP 1 @@ -134,6 +139,7 @@ static void fpset (fpdata *fpd, fptype f) static __inline__ void native_set_fpucw (uae_u32 m68k_cw) { +#ifdef NATIVE_FPUCW #ifdef _WIN32 static int ex = 0; // RN, RZ, RM, RP @@ -175,6 +181,7 @@ static uae_u16 x87_cw_tab[] = { #endif #endif #endif +#endif } #if defined(uae_s64) /* Close enough for government work? */ @@ -211,7 +218,7 @@ static void fpu_format_error (void) #define FPU_EXP_DISABLED 1 #define FPU_EXP_UNIMP_DATATYPE 2 -static void fpu_op_unimp (uae_u16 opcode, uae_u32 ea, uaecptr oldpc, int type) +static void fpu_op_unimp (uae_u16 opcode, uae_u16 extra, uae_u32 ea, uaecptr oldpc, int type) { /* 68040 unimplemented/68060 FPU disabled exception. * Line F exception with different stack frame.. */ @@ -283,11 +290,11 @@ static void fpu_op_unimp (uae_u16 opcode, uae_u32 ea, uaecptr oldpc, int type) #endif } -static void fpu_op_illg2 (uae_u16 opcode, uae_u32 ea, uaecptr oldpc) +static void fpu_op_illg2 (uae_u16 opcode, uae_u16 extra, uae_u32 ea, uaecptr oldpc) { if ((currprefs.cpu_model == 68060 && (currprefs.fpu_model == 0 || (regs.pcr & 2))) || (currprefs.cpu_model == 68040 && currprefs.fpu_model == 0)) { - fpu_op_unimp (opcode, ea, oldpc, FPU_EXP_DISABLED); + fpu_op_unimp (opcode, extra, ea, oldpc, FPU_EXP_DISABLED); return; } regs.fp_exception = true; @@ -295,9 +302,9 @@ static void fpu_op_illg2 (uae_u16 opcode, uae_u32 ea, uaecptr oldpc) op_illg (opcode); } -static void fpu_op_illg (uae_u16 opcode, uaecptr oldpc) +static void fpu_op_illg (uae_u16 opcode, uae_u16 extra, uaecptr oldpc) { - fpu_op_illg2 (opcode, 0, oldpc); + fpu_op_illg2 (opcode, extra, 0, oldpc); } @@ -311,19 +318,19 @@ static void fpu_noinst (uae_u16 opcode, uaecptr pc) op_illg (opcode); } -static bool fault_if_no_fpu (uae_u16 opcode, uae_u32 extra, uaecptr ea, uaecptr oldpc) +static bool fault_if_no_fpu (uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc) { if ((regs.pcr & 2) || currprefs.fpu_model <= 0) { #if EXCEPTION_FPP write_log (_T("no FPU: %04x %08x PC=%08x\n"), opcode, extra, oldpc); #endif - fpu_op_illg2 (opcode, ea, oldpc); + fpu_op_illg2 (opcode, extra, ea, oldpc); return true; } return false; } -static bool fault_if_unimplemented_680x0 (uae_u16 opcode, uae_u32 extra, uaecptr ea, uaecptr oldpc) +static bool fault_if_unimplemented_680x0 (uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc) { if (fault_if_no_fpu (opcode, extra, ea, oldpc)) return true; @@ -335,7 +342,7 @@ static bool fault_if_unimplemented_680x0 (uae_u16 opcode, uae_u32 extra, uaecptr case 0x03: /* FINTRZ */ // Unimplemented only in 68040. if (currprefs.cpu_model == 68040) { - fpu_op_unimp (opcode, ea, oldpc, FPU_EXP_UNIMP_INS); + fpu_op_unimp (opcode, extra, ea, oldpc, FPU_EXP_UNIMP_INS); return true; } return false; @@ -371,14 +378,14 @@ static bool fault_if_unimplemented_680x0 (uae_u16 opcode, uae_u32 extra, uaecptr case 0x21: /* FMOD */ case 0x25: /* FREM */ case 0x26: /* FSCALE */ - fpu_op_unimp (opcode, ea, oldpc, FPU_EXP_UNIMP_INS); + fpu_op_unimp (opcode, extra, ea, oldpc, FPU_EXP_UNIMP_INS); return true; } } return false; } -static bool fault_if_unimplemented_6888x (uae_u16 opcode, uae_u32 extra, uaecptr oldpc) +static bool fault_if_unimplemented_6888x (uae_u16 opcode, uae_u16 extra, uaecptr oldpc) { if ((currprefs.fpu_model == 68881 || currprefs.fpu_model == 68882) && currprefs.fpu_no_unimplemented) { uae_u16 v = extra & 0x7f; @@ -404,32 +411,32 @@ static bool fault_if_unimplemented_6888x (uae_u16 opcode, uae_u32 extra, uaecptr return false; } -static bool fault_if_4060 (uae_u16 opcode, uae_u32 extra, uaecptr ea, uaecptr oldpc, int type) +static bool fault_if_4060 (uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc, int type) { if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) { // do not emulate missing datatype yet, much more complex // requires pre and post exceptions.. if (type == FPU_EXP_UNIMP_DATATYPE) return false; - fpu_op_unimp (opcode, ea, oldpc, type); + fpu_op_unimp (opcode, extra, ea, oldpc, type); return true; } return false; } -static bool fault_if_no_fpu_u (uae_u16 opcode, uae_u32 extra, uaecptr ea, uaecptr oldpc) +static bool fault_if_no_fpu_u (uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc) { if (fault_if_no_fpu (opcode, extra, ea, oldpc)) return true; if (currprefs.cpu_model == 68060 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) { // 68060 FTRAP, FDBcc or FScc are not implemented. - fpu_op_unimp (opcode, ea, m68k_getpc (), FPU_EXP_UNIMP_INS); + fpu_op_unimp (opcode, extra, ea, m68k_getpc (), FPU_EXP_UNIMP_INS); return true; } return false; } -static bool fault_if_no_6888x (uae_u16 opcode, uae_u32 extra, uaecptr oldpc) +static bool fault_if_no_6888x (uae_u16 opcode, uae_u16 extra, uaecptr oldpc) { if (currprefs.cpu_model < 68040 && currprefs.fpu_model <= 0) { #if EXCEPTION_FPP @@ -475,10 +482,10 @@ static void fpu_null (void) fpclear (®s.fp[i]); } -#define fp_round_to_minus_infinity(x) fp_floor(x) -#define fp_round_to_plus_infinity(x) fp_ceil(x) +#define fp_round_to_minus_infinity(x) floor(x) +#define fp_round_to_plus_infinity(x) ceil(x) #define fp_round_to_zero(x) ((x) >= 0.0 ? floor(x) : ceil(x)) -#define fp_round_to_nearest(x) ((int)((x) + 0.5)) +#define fp_round_to_nearest(x) ((x) >= 0.0 ? (int)((x) + 0.5) : (int)((x) - 0.5)) STATIC_INLINE tointtype toint (fptype src, fptype minval, fptype maxval) { @@ -486,7 +493,7 @@ STATIC_INLINE tointtype toint (fptype src, fptype minval, fptype maxval) src = minval; if (src > maxval) src = maxval; -#if defined(X86_MSVC_ASSEMBLY) +#if defined(X86_MSVC_ASSEMBLY_FPU) { fptype tmp_fp; __asm { @@ -498,34 +505,27 @@ STATIC_INLINE tointtype toint (fptype src, fptype minval, fptype maxval) } #else /* no X86_MSVC */ { - int result = src; -#if 0 - switch (get_fpcr () & 0x30) { - case FPCR_ROUND_ZERO: - result = fp_round_to_zero (src); - break; - case FPCR_ROUND_MINF: - result = fp_round_to_minus_infinity (src); - break; - case FPCR_ROUND_NEAR: - result = fp_round_to_nearest (src); - break; - case FPCR_ROUND_PINF: - result = fp_round_to_plus_infinity (src); - break; - default: - result = src; /* should never be reached */ - break; -#endif + int result = (int)src; + switch (regs.fpcr & 0x30) + { + case FPCR_ROUND_ZERO: + result = (int)fp_round_to_zero (src); + break; + case FPCR_ROUND_MINF: + result = (int)fp_round_to_minus_infinity (src); + break; + case FPCR_ROUND_NEAR: + result = fp_round_to_nearest (src); + break; + case FPCR_ROUND_PINF: + result = (int)fp_round_to_plus_infinity (src); + break; + } return result; } #endif } -#ifndef HAVE_ISINF -extern int isinf (double x); -#endif - uae_u32 get_fpsr (void) { uae_u32 answer = regs.fpsr & 0x00ffffff; @@ -539,8 +539,11 @@ uae_u32 get_fpsr (void) answer |= 0x04000000; else if (regs.fp_result.fp < 0) answer |= 0x08000000; -#ifdef HAVE_ISINF - if (isinf (regs.fp_result)) +#ifdef _MSC_VER + if (!_finite (regs.fp_result.fp)) + answer |= 0x02000000; +#elif HAVE_ISINF + if (_isinf (regs.fp_result.fp)) answer |= 0x02000000; #endif } @@ -612,18 +615,20 @@ static fptype to_pack (uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) return d; } -// TODO: k-Factor is ignored. +// TODO: Positive k-Factor. static void from_pack (fptype src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3, int kfactor) { - int i; - int t; + int i, t, precision; char *cp; char str[100]; + precision = kfactor <= 0 ? -kfactor : 16; + if (precision > 16) + precision = 16; #if USE_LONG_DOUBLE - sprintf (str, "%.16Le", src); + sprintf (str, "%#.*Le", precision, src); #else - sprintf (str, "%.16e", src); + sprintf (str, "%#.*e", precision, src); #endif cp = str; *wrd1 = *wrd2 = *wrd3 = 0; @@ -646,7 +651,7 @@ static void from_pack (fptype src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd if (*cp >= '0' && *cp <= '9') *wrd3 |= *cp++ - '0'; } - if (*cp == 'e' || *cp == 'E') { + if (*cp == 'e') { cp++; if (*cp == '-') { cp++; @@ -655,9 +660,15 @@ static void from_pack (fptype src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd if (*cp == '+') cp++; t = 0; + while (cp[0] && cp[1]) + cp++; for (i = 0; i < 3; i++) { - if (*cp >= '0' && *cp <= '9') - t = (t << 4) | (*cp++ - '0'); + char c = *cp; + t >>= 4; + if (*cp >= '0' && *cp <= '9') { + t |= (c - '0') << (2 * 4); + cp--; + } } *wrd1 |= t << 16; } @@ -947,9 +958,13 @@ STATIC_INLINE int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, ua case 7: // Packed-Decimal Real with Dynamic k-Factor (P{Dn}) (reg to memory only) { uae_u32 wrd1, wrd2, wrd3; + int kfactor; if (fault_if_4060 (opcode, extra, ad, oldpc, FPU_EXP_UNIMP_DATATYPE)) return -1; - from_pack (value->fp, &wrd1, &wrd2, &wrd3, size == 7 ? m68k_dreg (regs, (extra >> 4) & 7) : extra & 127); + kfactor = size == 7 ? m68k_dreg (regs, (extra >> 4) & 7) : extra; + if (kfactor & 64) + kfactor |= ~63; + from_pack (value->fp, &wrd1, &wrd2, &wrd3, kfactor); x_cp_put_long (ad, wrd1); ad += 4; x_cp_put_long (ad, wrd2); @@ -1132,7 +1147,7 @@ void fpuop_dbcc (uae_u32 opcode, uae_u16 extra) regs.fpu_state = 1; cc = fpp_cond (extra & 0x3f); if (cc == -1) { - fpu_op_illg (opcode, regs.fpiar); + fpu_op_illg (opcode, extra, regs.fpiar); } else if (!cc) { int reg = opcode & 0x7; @@ -1161,7 +1176,7 @@ void fpuop_scc (uae_u32 opcode, uae_u16 extra) regs.fpu_state = 1; cc = fpp_cond (extra & 0x3f); if (cc == -1) { - fpu_op_illg (opcode, regs.fpiar); + fpu_op_illg (opcode, extra, regs.fpiar); } else if ((opcode & 0x38) == 0) { if (fault_if_no_fpu (opcode, extra, 0, pc)) return; @@ -1191,7 +1206,7 @@ void fpuop_trapcc (uae_u32 opcode, uaecptr oldpc, uae_u16 extra) regs.fpu_state = 1; cc = fpp_cond (extra & 0x3f); if (cc == -1) { - fpu_op_illg (opcode, oldpc); + fpu_op_illg (opcode, extra, oldpc); } else if (cc) { Exception (7); } @@ -1213,7 +1228,7 @@ void fpuop_bcc (uae_u32 opcode, uaecptr oldpc, uae_u32 extra) regs.fpu_state = 1; cc = fpp_cond (opcode & 0x3f); if (cc == -1) { - fpu_op_illg (opcode, oldpc - 2); + fpu_op_illg (opcode, extra, oldpc - 2); } else if (cc) { if ((opcode & 0x40) == 0) extra = (uae_s32) (uae_s16) extra; @@ -1239,7 +1254,7 @@ void fpuop_save (uae_u32 opcode) return; if (get_fp_ad (opcode, &ad) == 0) { - fpu_op_illg (opcode, pc); + fpu_op_illg (opcode, 0, pc); return; } @@ -1350,7 +1365,7 @@ void fpuop_restore (uae_u32 opcode) return; if (get_fp_ad (opcode, &ad) == 0) { - fpu_op_illg (opcode, pc); + fpu_op_illg (opcode, 0, pc); return; } @@ -1922,7 +1937,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) break; case 0x01: /* FINT */ /* need to take the current rounding mode into account */ -#if defined(X86_MSVC_ASSEMBLY) +#if defined(X86_MSVC_ASSEMBLY_FPU) { fptype tmp_fp; @@ -1934,24 +1949,23 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) regs.fp[reg].fp = tmp_fp; } #else /* no X86_MSVC */ - switch ((regs.fpcr >> 4) & 3) { - case 0: /* to nearest */ - regs.fp[reg].fp = floor (src + 0.5); - break; - case 1: /* to zero */ - if (src >= 0.0) - regs.fp[reg].fp = floor (src); - else - regs.fp[reg].fp = ceil (src); - break; - case 2: /* down */ - regs.fp[reg].fp = floor (src); - break; - case 3: /* up */ - regs.fp[reg].fp = ceil (src); - break; - default: /* never reached */ - regs.fp[reg].fp = src; + switch (regs.fpcr & 0x30) + { + case FPCR_ROUND_NEAR: + regs.fp[reg].fp = fp_round_to_nearest(src); + break; + case FPCR_ROUND_ZERO: + regs.fp[reg].fp = fp_round_to_zero(src); + break; + case FPCR_ROUND_MINF: + regs.fp[reg].fp = fp_round_to_minus_infinity(src); + break; + case FPCR_ROUND_PINF: + regs.fp[reg].fp = fp_round_to_plus_infinity(src); + break; + default: /* never reached */ + regs.fp[reg].fp = src; + break; } #endif /* X86_MSVC */ break; @@ -2087,6 +2101,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) break; case 0x24: /* FSGLDIV */ regs.fp[reg].fp /= src; + fround (reg); break; case 0x25: /* FREM */ { @@ -2105,6 +2120,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) break; case 0x27: /* FSGLMUL */ regs.fp[reg].fp *= src; + fround (reg); break; case 0x28: /* FSUB */ case 0x68: /* FSSUB */ diff --git a/gencpu.cpp b/gencpu.cpp index 783dfe91..d4b0fdb9 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -96,7 +96,7 @@ static char *prefetch_long, *prefetch_word; static char *srcli, *srcwi, *srcbi, *nextl, *nextw, *nextb; static char *srcld, *dstld; static char *srcwd, *dstwd; -static char *do_cycles, *disp000, *disp020; +static char *do_cycles, *disp000, *disp020, *getpc; #define fetchmode_fea 1 #define fetchmode_cea 2 @@ -652,8 +652,8 @@ static void setpc (const char *format, ...) _vsnprintf (buffer, 1000 - 1, format, parms); va_end (parms); - if (using_mmu) - printf ("\tm68k_setpc_mmu (%s);\n", buffer); + if (using_mmu || using_prefetch || using_prefetch_020) + printf ("\tm68k_setpci (%s);\n", buffer); else printf ("\tm68k_setpc (%s);\n", buffer); } @@ -667,7 +667,7 @@ static void incpc (const char *format, ...) _vsnprintf (buffer, 1000 - 1, format, parms); va_end (parms); - if (using_mmu) + if (using_mmu || using_prefetch || using_prefetch_020) printf ("\tm68k_incpci (%s);\n", buffer); else printf ("\tm68k_incpc (%s);\n", buffer); @@ -713,7 +713,7 @@ static void gen_set_fault_pc (void) if (using_mmu != 68040) return; sync_m68k_pc (); - printf ("\tregs.instruction_pc = m68k_getpci ();\n"); + printf ("\tregs.instruction_pc = %s;\n", getpc); printf ("\tmmu_restart = false;\n"); m68k_pc_offset = 0; clearmmufixup (0); @@ -1295,7 +1295,7 @@ static void genamode2x (amodes mode, char *reg, wordsizes size, char *name, int case PC16: // (d16,PC) printf ("\tuaecptr %sa;\n", name); add_mmu040_movem (movem); - printf ("\t%sa = m68k_getpc () + %d;\n", name, m68k_pc_offset); + printf ("\t%sa = %s + %d;\n", name, getpc, m68k_pc_offset); printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags)); break; case Ad8r: // (d8,An,Xn) @@ -1352,10 +1352,10 @@ static void genamode2x (amodes mode, char *reg, wordsizes size, char *name, int start_brace (); /* This would ordinarily be done in gen_nextiword, which we bypass. */ insn_n_cycles += 4; - printf ("\ttmppc = m68k_getpc ();\n"); + printf ("\ttmppc = %s;\n", getpc); printf ("\t%sa = %s (tmppc, %d);\n", name, disp020, mmudisp020cnt++); } else { - printf ("\ttmppc = m68k_getpc () + %d;\n", m68k_pc_offset); + printf ("\ttmppc = %s + %d;\n", getpc, m68k_pc_offset); if (!(flags & GF_PC8R)) { addcycles000 (2); insn_n_cycles += 2; @@ -2521,9 +2521,11 @@ static void resetvars (void) dstblrmw = NULL; dstwlrmw = NULL; dstllrmw = NULL; + getpc = "m68k_getpc ()"; if (using_indirect) { // tracer + getpc = "m68k_getpci ()"; if (!using_ce020 && !using_prefetch_020) { prefetch_word = "get_word_ce000_prefetch"; srcli = "x_get_ilong"; @@ -2648,6 +2650,7 @@ static void resetvars (void) srcwd = "get_word_mmu030"; dstld = "put_long_mmu030"; dstwd = "put_word_mmu030"; + getpc = "m68k_getpci ()"; } else if (using_mmu == 68040) { // 68040 MMU disp020 = "x_get_disp_ea_020"; @@ -2670,6 +2673,7 @@ static void resetvars (void) dstblrmw = "put_lrmw_byte_mmu040"; dstwlrmw = "put_lrmw_word_mmu040"; dstllrmw = "put_lrmw_long_mmu040"; + getpc = "m68k_getpci ()"; } else if (using_mmu) { // 68060 MMU disp020 = "x_get_disp_ea_020"; @@ -2699,6 +2703,7 @@ static void resetvars (void) dstbrmw = "put_rmw_byte_mmu060"; dstwrmw = "put_rmw_word_mmu060"; dstlrmw = "put_rmw_long_mmu060"; + getpc = "m68k_getpci ()"; } else if (using_ce) { // 68000 ce prefetch_word = "get_word_ce000_prefetch"; @@ -2710,6 +2715,7 @@ static void resetvars (void) srcb = "get_byte_ce000"; dstb = "put_byte_ce000"; do_cycles = "do_cycles_ce000"; + getpc = "m68k_getpci ()"; } else if (using_prefetch) { // 68000 prefetch prefetch_word = "get_word_prefetch"; @@ -2721,6 +2727,7 @@ static void resetvars (void) dstw = "put_word_prefetch"; srcb = "get_byte_prefetch"; dstb = "put_byte_prefetch"; + getpc = "m68k_getpci ()"; } else { // generic prefetch_long = "get_ilong"; @@ -3619,21 +3626,24 @@ static void gen_opcode (unsigned long int opcode) break; case i_RTS: addop_ce020 (curi, 0); - printf ("\tuaecptr pc = m68k_getpc ();\n"); + printf ("\tuaecptr pc = %s;\n", getpc); if (using_ce020 == 1) { add_head_cycs (1); printf ("\tm68k_do_rts_ce020 ();\n"); } else if (using_ce020 == 2) { add_head_cycs (1); printf ("\tm68k_do_rts_ce030 ();\n"); - } else if (using_ce) + } else if (using_ce) { printf ("\tm68k_do_rts_ce ();\n"); - else if (using_mmu) + } else if (using_mmu) { printf ("\tm68k_do_rts_mmu%s ();\n", mmu_postfix); - else + } else if (using_prefetch || using_prefetch_020) { + printf ("\tm68k_do_rtsi ();\n"); + } else { printf ("\tm68k_do_rts ();\n"); - printf ("\tif (m68k_getpc () & 1) {\n"); - printf ("\t\tuaecptr faultpc = m68k_getpc ();\n"); + } + printf ("\tif (%s & 1) {\n", getpc); + printf ("\t\tuaecptr faultpc = %s;\n", getpc); setpc ("pc"); printf ("\t\texception3i (0x%04X, faultpc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); @@ -3653,7 +3663,7 @@ static void gen_opcode (unsigned long int opcode) need_endlabel = 1; break; case i_RTR: - printf ("\tuaecptr oldpc = m68k_getpc ();\n"); + printf ("\tuaecptr oldpc = %s;\n", getpc); printf ("\tMakeSR ();\n"); genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0); genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0); @@ -3661,8 +3671,8 @@ static void gen_opcode (unsigned long int opcode) printf ("\tregs.sr |= sr;\n"); setpc ("pc"); makefromsr (); - printf ("\tif (m68k_getpc () & 1) {\n"); - printf ("\t\tuaecptr faultpc = m68k_getpc ();\n"); + printf ("\tif (%s & 1) {\n", getpc); + printf ("\t\tuaecptr faultpc = %s;\n", getpc); setpc ("oldpc"); printf ("\t\texception3i (0x%04X, faultpc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); @@ -3677,7 +3687,7 @@ static void gen_opcode (unsigned long int opcode) no_prefetch_ce020 = true; genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL); start_brace (); - printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset); + printf ("\tuaecptr oldpc = %s + %d;\n", getpc, m68k_pc_offset); if (using_exception_3) { printf ("\tif (srca & 1) {\n"); printf ("\t\texception3i (opcode, srca);\n"); @@ -3746,22 +3756,24 @@ static void gen_opcode (unsigned long int opcode) printf ("\ts = (uae_s32)src + 2;\n"); if (using_exception_3) { printf ("\tif (src & 1) {\n"); - printf ("\t\texception3b (opcode, m68k_getpc () + s, 0, 1, m68k_getpc () + s);\n"); + printf ("\t\texception3b (opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; } addcycles000 (2); if (using_ce020 == 1) { - printf ("\tm68k_do_bsr_ce020 (m68k_getpc () + %d, s);\n", m68k_pc_offset); + printf ("\tm68k_do_bsr_ce020 (%s + %d, s);\n", getpc, m68k_pc_offset); } else if (using_ce020 == 2) { - printf ("\tm68k_do_bsr_ce030 (m68k_getpc () + %d, s);\n", m68k_pc_offset); + printf ("\tm68k_do_bsr_ce030 (%s + %d, s);\n", getpc, m68k_pc_offset); } else if (using_ce) { - printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset); + printf ("\tm68k_do_bsr_ce (%s + %d, s);\n", getpc, m68k_pc_offset); } else if (using_mmu) { - printf ("\tm68k_do_bsr_mmu%s (m68k_getpc () + %d, s);\n", mmu_postfix, m68k_pc_offset); + printf ("\tm68k_do_bsr_mmu%s (%s + %d, s);\n", mmu_postfix, getpc, m68k_pc_offset); + } else if (using_prefetch || using_prefetch_020) { + printf ("\tm68k_do_bsri (%s + %d, s);\n", getpc, m68k_pc_offset); } else { - printf ("\tm68k_do_bsr (m68k_getpc () + %d, s);\n", m68k_pc_offset); + printf ("\tm68k_do_bsr (%s + %d, s);\n", getpc, m68k_pc_offset); } count_write += 2; m68k_pc_offset = 0; @@ -3773,7 +3785,7 @@ static void gen_opcode (unsigned long int opcode) if (cpu_level < 2) { addcycles000 (2); printf ("\tif (cctrue (%d)) {\n", curi->cc); - printf ("\t\texception3i (opcode, m68k_getpc () + 1);\n"); + printf ("\t\texception3i (opcode, %s + 1);\n", getpc); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); sync_m68k_pc (); @@ -3791,7 +3803,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc); if (using_exception_3) { printf ("\tif (src & 1) {\n"); - printf ("\t\texception3i (opcode, m68k_getpc () + 2 + (uae_s32)src);\n"); + printf ("\t\texception3i (opcode, %s + 2 + (uae_s32)src);\n", getpc); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; @@ -3863,7 +3875,7 @@ static void gen_opcode (unsigned long int opcode) curi->dmode, "dstreg", curi->size, "offs", 1, GF_AA | GF_NOREFILL); //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); //genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); - printf ("\tuaecptr oldpc = m68k_getpc ();\n"); + printf ("\tuaecptr oldpc = %s;\n", getpc); addcycles000 (2); printf ("\tif (!cctrue (%d)) {\n", curi->cc); incpc ("(uae_s32)offs + 2"); @@ -3875,7 +3887,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\tif (src) {\n"); if (using_exception_3) { printf ("\t\t\tif (offs & 1) {\n"); - printf ("\t\t\t\texception3i (opcode, m68k_getpc () + 2 + (uae_s32)offs + 2);\n"); + printf ("\t\t\t\texception3i (opcode, %s + 2 + (uae_s32)offs + 2);\n", getpc); printf ("\t\t\t\tgoto %s;\n", endlabelstr); printf ("\t\t\t}\n"); need_endlabel = 1; @@ -4880,7 +4892,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_FTRAPcc: fpulimit(); - printf ("\tuaecptr oldpc = m68k_getpc ();\n"); + printf ("\tuaecptr oldpc = %s;\n", getpc); printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0)); if (curi->smode != am_unknown && curi->smode != am_illg) genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); @@ -4895,7 +4907,7 @@ static void gen_opcode (unsigned long int opcode) fpulimit(); sync_m68k_pc (); start_brace (); - printf ("\tuaecptr pc = m68k_getpc ();\n"); + printf ("\tuaecptr pc = %s;\n", getpc); genamode (curi, curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0); sync_m68k_pc (); printf ("\tfpuop_bcc (opcode, pc,extra);\n"); @@ -4999,7 +5011,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tmmu_op (opcode, 0);\n"); break; case i_MMUOP030: - printf ("\tuaecptr pc = m68k_getpc ();\n"); + printf ("\tuaecptr pc = %s;\n", getpc); printf ("\tuae_u16 extra = %s (2);\n", prefetch_word); m68k_pc_offset += 2; sync_m68k_pc (); diff --git a/include/cpu_prefetch.h b/include/cpu_prefetch.h index d297e4d3..e7aa34c1 100644 --- a/include/cpu_prefetch.h +++ b/include/cpu_prefetch.h @@ -6,7 +6,7 @@ extern uae_u32 get_word_020_prefetch (int); STATIC_INLINE uae_u32 next_iword_020_prefetch (void) { uae_u32 r = get_word_020_prefetch (0); - m68k_incpc (2); + m68k_incpci (2); return r; } STATIC_INLINE uae_u32 next_ilong_020_prefetch (void) @@ -117,13 +117,13 @@ STATIC_INLINE uae_u32 get_long_ce020_prefetch (int o) STATIC_INLINE uae_u32 next_iword_020ce (void) { uae_u32 r = get_word_ce020_prefetch (0); - m68k_incpc (2); + m68k_incpci (2); return r; } STATIC_INLINE uae_u32 next_ilong_020ce (void) { uae_u32 r = get_long_ce020_prefetch (0); - m68k_incpc (4); + m68k_incpci (4); return r; } @@ -131,11 +131,11 @@ STATIC_INLINE void m68k_do_bsr_ce020 (uaecptr oldpc, uae_s32 offset) { m68k_areg (regs, 7) -= 4; x_put_long (m68k_areg (regs, 7), oldpc); - m68k_incpc (offset); + m68k_incpci (offset); } STATIC_INLINE void m68k_do_rts_ce020 (void) { - m68k_setpc (x_get_long (m68k_areg (regs, 7))); + m68k_setpci (x_get_long (m68k_areg (regs, 7))); m68k_areg (regs, 7) += 4; } @@ -187,13 +187,13 @@ STATIC_INLINE uae_u32 get_long_ce030_prefetch (int o) STATIC_INLINE uae_u32 next_iword_030ce (void) { uae_u32 r = get_word_ce030_prefetch (0); - m68k_incpc (2); + m68k_incpci (2); return r; } STATIC_INLINE uae_u32 next_ilong_030ce (void) { uae_u32 r = get_long_ce030_prefetch (0); - m68k_incpc (4); + m68k_incpci (4); return r; } @@ -201,7 +201,7 @@ STATIC_INLINE void m68k_do_bsr_ce030 (uaecptr oldpc, uae_s32 offset) { m68k_areg (regs, 7) -= 4; put_long_ce030 (m68k_areg (regs, 7), oldpc); - m68k_incpc (offset); + m68k_incpci (offset); } STATIC_INLINE void m68k_do_rts_ce030 (void) { @@ -218,7 +218,7 @@ extern uae_u32 get_word_ce040_prefetch (int); STATIC_INLINE uae_u32 get_word_prefetch (int o) { uae_u32 v = regs.irc; - regs.irc = regs.db = get_wordi (m68k_getpc () + o); + regs.irc = regs.db = get_wordi (m68k_getpci () + o); return v; } STATIC_INLINE uae_u32 get_byte_prefetch (uaecptr addr) @@ -368,7 +368,7 @@ STATIC_INLINE uae_u32 get_word_ce000 (uaecptr addr) } STATIC_INLINE uae_u32 get_wordi_ce000 (int offset) { - return mem_access_delay_wordi_read (m68k_getpc () + offset); + return mem_access_delay_wordi_read (m68k_getpci () + offset); } STATIC_INLINE uae_u32 get_byte_ce000 (uaecptr addr) { @@ -401,7 +401,7 @@ STATIC_INLINE void m68k_do_rts_ce (void) pc = x_get_word (m68k_areg (regs, 7)) << 16; pc |= x_get_word (m68k_areg (regs, 7) + 2); m68k_areg (regs, 7) += 4; - m68k_setpc (pc); + m68k_setpci (pc); } STATIC_INLINE void m68k_do_bsr_ce (uaecptr oldpc, uae_s32 offset) @@ -409,7 +409,7 @@ STATIC_INLINE void m68k_do_bsr_ce (uaecptr oldpc, uae_s32 offset) m68k_areg (regs, 7) -= 4; x_put_word (m68k_areg (regs, 7), oldpc >> 16); x_put_word (m68k_areg (regs, 7) + 2, oldpc); - m68k_incpc (offset); + m68k_incpci (offset); } STATIC_INLINE void m68k_do_jsr_ce (uaecptr oldpc, uaecptr dest) @@ -417,7 +417,7 @@ STATIC_INLINE void m68k_do_jsr_ce (uaecptr oldpc, uaecptr dest) m68k_areg (regs, 7) -= 4; x_put_word (m68k_areg (regs, 7), oldpc >> 16); x_put_word (m68k_areg (regs, 7) + 2, oldpc); - m68k_setpc (dest); + m68k_setpci (dest); } #endif diff --git a/include/cpummu.h b/include/cpummu.h index 2dfe7fdb..ea1aa1b1 100644 --- a/include/cpummu.h +++ b/include/cpummu.h @@ -221,7 +221,7 @@ static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write, return true; } mmu_atc_ways++; - mmu_atc_ways &= (ATC_WAYS - 1); + mmu_atc_ways %= ATC_WAYS; } // we select a random way to void *cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index]; @@ -254,7 +254,7 @@ static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data, return true; } mmu_atc_ways++; - mmu_atc_ways &= (ATC_WAYS - 1); + mmu_atc_ways %= ATC_WAYS; } // we select a random way to void *cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index]; @@ -855,56 +855,56 @@ STATIC_INLINE uae_u32 get_lrmw_long_mmu040 (uaecptr addr) STATIC_INLINE uae_u32 get_ibyte_mmu040 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu040_get_iword (pc); } STATIC_INLINE uae_u32 get_iword_mmu040 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu040_get_iword (pc); } STATIC_INLINE uae_u32 get_ilong_mmu040 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu040_get_ilong (pc); } STATIC_INLINE uae_u32 next_iword_mmu040 (void) { - uae_u32 pc = m68k_getpc (); + uae_u32 pc = m68k_getpci (); m68k_incpci (2); return uae_mmu040_get_iword (pc); } STATIC_INLINE uae_u32 next_ilong_mmu040 (void) { - uae_u32 pc = m68k_getpc (); + uae_u32 pc = m68k_getpci (); m68k_incpci (4); return uae_mmu040_get_ilong (pc); } STATIC_INLINE uae_u32 get_ibyte_mmu060 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu060_get_iword (pc); } STATIC_INLINE uae_u32 get_iword_mmu060 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu060_get_iword (pc); } STATIC_INLINE uae_u32 get_ilong_mmu060 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu060_get_ilong (pc); } STATIC_INLINE uae_u32 next_iword_mmu060 (void) { - uae_u32 pc = m68k_getpc (); + uae_u32 pc = m68k_getpci (); m68k_incpci (2); return uae_mmu060_get_iword (pc); } STATIC_INLINE uae_u32 next_ilong_mmu060 (void) { - uae_u32 pc = m68k_getpc (); + uae_u32 pc = m68k_getpci (); m68k_incpci (4); return uae_mmu060_get_ilong (pc); } diff --git a/include/cpummu030.h b/include/cpummu030.h index 0094e09a..7f3ebb8b 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -355,7 +355,7 @@ STATIC_INLINE uae_u32 get_lrmw_long_mmu030_state (uaecptr addr) STATIC_INLINE uae_u32 get_ibyte_mmu030_state (int o) { uae_u32 v; - uae_u32 addr = m68k_getpc () + o; + uae_u32 addr = m68k_getpci () + o; ACCESS_CHECK_GET v = uae_mmu030_get_iword (addr); ACCESS_EXIT_GET @@ -364,7 +364,7 @@ STATIC_INLINE uae_u32 get_ibyte_mmu030_state (int o) STATIC_INLINE uae_u32 get_iword_mmu030_state (int o) { uae_u32 v; - uae_u32 addr = m68k_getpc () + o; + uae_u32 addr = m68k_getpci () + o; ACCESS_CHECK_GET v = uae_mmu030_get_iword (addr); ACCESS_EXIT_GET @@ -373,7 +373,7 @@ STATIC_INLINE uae_u32 get_iword_mmu030_state (int o) STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o) { uae_u32 v; - uae_u32 addr = m68k_getpc () + o; + uae_u32 addr = m68k_getpci () + o; ACCESS_CHECK_GET v = uae_mmu030_get_ilong (addr); ACCESS_EXIT_GET @@ -382,7 +382,7 @@ STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o) STATIC_INLINE uae_u32 next_iword_mmu030_state (void) { uae_u32 v; - uae_u32 addr = m68k_getpc (); + uae_u32 addr = m68k_getpci (); ACCESS_CHECK_GET_PC(2); v = uae_mmu030_get_iword (addr); m68k_incpci (2); @@ -392,7 +392,7 @@ STATIC_INLINE uae_u32 next_iword_mmu030_state (void) STATIC_INLINE uae_u32 next_ilong_mmu030_state (void) { uae_u32 v; - uae_u32 addr = m68k_getpc (); + uae_u32 addr = m68k_getpci (); ACCESS_CHECK_GET_PC(4); v = uae_mmu030_get_ilong (addr); m68k_incpci (4); @@ -428,23 +428,23 @@ STATIC_INLINE void put_long_mmu030 (uaecptr addr, uae_u32 v) STATIC_INLINE uae_u32 get_ibyte_mmu030 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu030_get_iword (pc); } STATIC_INLINE uae_u32 get_iword_mmu030 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu030_get_iword (pc); } STATIC_INLINE uae_u32 get_ilong_mmu030 (int o) { - uae_u32 pc = m68k_getpc () + o; + uae_u32 pc = m68k_getpci () + o; return uae_mmu030_get_ilong (pc); } STATIC_INLINE uae_u32 next_iword_mmu030 (void) { uae_u32 v; - uae_u32 pc = m68k_getpc (); + uae_u32 pc = m68k_getpci (); v = uae_mmu030_get_iword (pc); m68k_incpci (2); return v; @@ -452,7 +452,7 @@ STATIC_INLINE uae_u32 next_iword_mmu030 (void) STATIC_INLINE uae_u32 next_ilong_mmu030 (void) { uae_u32 v; - uae_u32 pc = m68k_getpc (); + uae_u32 pc = m68k_getpci (); v = uae_mmu030_get_ilong (pc); m68k_incpci (4); return v; diff --git a/include/ethernet.h b/include/ethernet.h index bad2d8e3..14c398ea 100644 --- a/include/ethernet.h +++ b/include/ethernet.h @@ -2,7 +2,8 @@ #define UAENET_NONE 0 #define UAENET_SLIRP 1 -#define UAENET_PCAP 2 +#define UAENET_SLIRP_INBOUND 2 +#define UAENET_PCAP 3 struct netdriverdata { diff --git a/include/inputdevice.h b/include/inputdevice.h index 5e006bd2..2f27a9f6 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -82,6 +82,8 @@ struct inputevent { #define ID_FLAG_INVERTTOGGLE 16 #define ID_FLAG_INVERT 32 #define ID_FLAG_RESERVEDGAMEPORTSCUSTOM 64 +#define ID_FLAG_SET_ONOFF 128 +#define ID_FLAG_SET_ONOFF_VAL 256 #define ID_FLAG_GAMEPORTSCUSTOM_MASK (ID_FLAG_GAMEPORTSCUSTOM1 | ID_FLAG_GAMEPORTSCUSTOM2) #define ID_FLAG_AUTOFIRE_MASK (ID_FLAG_TOGGLE | ID_FLAG_INVERTTOGGLE | ID_FLAG_AUTOFIRE) @@ -104,6 +106,10 @@ struct inputevent { #define ID_FLAG_QUALIFIER_MASK 0xfffffff00000000 #define ID_FLAG_QUALIFIER_MASK_R 0xaaaaaaa00000000 +#define ID_FLAG_SAVE_MASK_CONFIG 0x000001ff +#define ID_FLAG_SAVE_MASK_QUALIFIERS ID_FLAG_QUALIFIER_MASK +#define ID_FLAG_SAVE_MASK_FULL (ID_FLAG_SAVE_MASK_CONFIG | ID_FLAG_SAVE_MASK_QUALIFIERS) + #define IDEV_WIDGET_NONE 0 #define IDEV_WIDGET_BUTTON 1 #define IDEV_WIDGET_AXIS 2 @@ -117,6 +123,9 @@ struct inputevent { #define IDEV_MAPPED_GAMEPORTSCUSTOM1 16 #define IDEV_MAPPED_GAMEPORTSCUSTOM2 32 #define IDEV_MAPPED_INVERT 64 +#define IDEV_MAPPED_SET_ONOFF 128 +#define IDEV_MAPPED_SET_ONOFF_VAL 256 + #define IDEV_MAPPED_QUALIFIER1 0x000000100000000 #define IDEV_MAPPED_QUALIFIER2 0x000000400000000 #define IDEV_MAPPED_QUALIFIER3 0x000001000000000 @@ -132,6 +141,9 @@ struct inputevent { #define IDEV_MAPPED_QUALIFIER_WIN 0x100000000000000 #define IDEV_MAPPED_QUALIFIER_MASK 0xfffffff00000000 +#define SET_ONOFF_ON_VALUE 0x7fffff01 +#define SET_ONOFF_OFF_VALUE 0x7fffff00 + #define ID_BUTTON_OFFSET 0 #define ID_BUTTON_TOTAL 32 #define ID_AXIS_OFFSET 32 @@ -139,6 +151,21 @@ struct inputevent { #define MAX_COMPA_INPUTLIST 30 +/* event masks */ +#define AM_KEY 1 /* keyboard allowed */ +#define AM_JOY_BUT 2 /* joystick buttons allowed */ +#define AM_JOY_AXIS 4 /* joystick axis allowed */ +#define AM_MOUSE_BUT 8 /* mouse buttons allowed */ +#define AM_MOUSE_AXIS 16 /* mouse direction allowed */ +#define AM_AF 32 /* supports autofire */ +#define AM_INFO 64 /* information data for gui */ +#define AM_DUMMY 128 /* placeholder */ +#define AM_CUSTOM 256 /* custom event */ +#define AM_SETTOGGLE 512 /* on/off/toggle */ +#define AM_K (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT|AM_AF) /* generic button/switch */ +#define AM_KK (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT) +#define AM_KT (AM_K|AM_SETTOGGLE) + extern int inputdevice_iterate (int devnum, int num, TCHAR *name, int *af); extern bool inputdevice_set_gameports_mapping (struct uae_prefs *prefs, int devnum, int num, int evtnum, uae_u64 flags, int port, int input_selected_setting); extern int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *custom, uae_u64 flags, int port, int sub); diff --git a/include/keyboard.h b/include/keyboard.h index 6eecff78..ed8a275c 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -140,6 +140,7 @@ enum aks { AKS_ENTERGUI = 0x200, AKS_SCREENSHOT_FILE, AKS_SCREENSHOT_CLIPBOARD, AKS_ENTERDEBUGGER, AKS_IRQ7, AKS_PAUSE, AKS_WARP, AKS_INHIBITSCREEN, AKS_STATEREWIND, AKS_STATECURRENT, AKS_STATECAPTURE, + AKS_VIDEORECORD, AKS_VOLDOWN, AKS_VOLUP, AKS_VOLMUTE, AKS_MVOLDOWN, AKS_MVOLUP, AKS_MVOLMUTE, AKS_QUIT, AKS_HARDRESET, AKS_SOFTRESET, diff --git a/include/newcpu.h b/include/newcpu.h index c7865368..d00b2666 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -266,8 +266,6 @@ STATIC_INLINE void m68k_setpc (uaecptr newpc) regs.instruction_pc = regs.pc = newpc; } -extern void m68k_setpc_normal (uaecptr newpc); - STATIC_INLINE uaecptr m68k_getpc (void) { return (uaecptr)(regs.pc + ((uae_u8*)regs.pc_p - (uae_u8*)regs.pc_oldp)); @@ -284,11 +282,6 @@ STATIC_INLINE void m68k_incpc (int o) regs.pc_p += o; } -STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc) -{ - regs.instruction_pc = regs.pc = newpc; - regs.pc_p = regs.pc_oldp = 0; -} STATIC_INLINE void m68k_setpci (uaecptr newpc) { regs.instruction_pc = regs.pc = newpc; @@ -302,6 +295,22 @@ STATIC_INLINE void m68k_incpci (int o) regs.pc += o; } +STATIC_INLINE void m68k_incpc_normal (int o) +{ + if (currprefs.mmu_model || currprefs.cpu_compatible) + m68k_incpci (o); + else + m68k_incpc (o); +} + +STATIC_INLINE void m68k_setpc_normal (uaecptr pc) +{ + if (currprefs.mmu_model || currprefs.cpu_compatible) + m68k_setpci (pc); + else + m68k_setpc (pc); +} + STATIC_INLINE void m68k_do_rts (void) { uae_u32 newpc = get_long (m68k_areg (regs, 7)); @@ -309,6 +318,13 @@ STATIC_INLINE void m68k_do_rts (void) m68k_areg (regs, 7) += 4; } +STATIC_INLINE void m68k_do_rtsi (void) +{ + uae_u32 newpc = get_long (m68k_areg (regs, 7)); + m68k_setpci (newpc); + m68k_areg (regs, 7) += 4; +} + STATIC_INLINE void m68k_do_bsr (uaecptr oldpc, uae_s32 offset) { m68k_areg (regs, 7) -= 4; @@ -316,6 +332,13 @@ STATIC_INLINE void m68k_do_bsr (uaecptr oldpc, uae_s32 offset) m68k_incpc (offset); } +STATIC_INLINE void m68k_do_bsri (uaecptr oldpc, uae_s32 offset) +{ + m68k_areg (regs, 7) -= 4; + put_long (m68k_areg (regs, 7), oldpc); + m68k_incpci (offset); +} + STATIC_INLINE uae_u32 get_ibyte (int o) { return do_get_mem_byte((uae_u8 *)((regs).pc_p + (o) + 1)); diff --git a/include/options.h b/include/options.h index 9e545a7b..be4ca507 100644 --- a/include/options.h +++ b/include/options.h @@ -89,6 +89,17 @@ struct jport { #define TABLET_MOUSEHACK 1 #define TABLET_REAL 2 +#ifdef WITH_SLIRP +#define MAX_SLIRP_REDIRS 32 +struct slirp_redir +{ + int proto; + int srcport; + int dstport; + unsigned long addr; +}; +#endif + struct cdslot { TCHAR name[MAX_DPATH]; @@ -561,7 +572,9 @@ struct uae_prefs { TCHAR win32_guipage[32]; TCHAR win32_guiactivepage[32]; bool win32_filesystem_mangle_reserved_names; - +#ifdef WITH_SLIRP + struct slirp_redir slirp_redirs[MAX_SLIRP_REDIRS]; +#endif int statecapturerate, statecapturebuffersize; /* input */ diff --git a/inputdevice.cpp b/inputdevice.cpp index 7898202e..27c05e52 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -51,6 +51,9 @@ #endif #include "dongle.h" #include "cdtv.h" +#ifdef AVIOUTPUT +#include "avioutput.h" +#endif // 01 = host events // 02 = joystick @@ -68,10 +71,6 @@ extern int tablet_log; #define ID_FLAG_CUSTOMEVENT_TOGGLED1 0x4000 #define ID_FLAG_CUSTOMEVENT_TOGGLED2 0x8000 -#define ID_FLAG_SAVE_MASK_CONFIG 0x000000ff -#define ID_FLAG_SAVE_MASK_QUALIFIERS ID_FLAG_QUALIFIER_MASK -#define ID_FLAG_SAVE_MASK_FULL (ID_FLAG_SAVE_MASK_CONFIG | ID_FLAG_SAVE_MASK_QUALIFIERS) - #define IE_INVERT 0x80 #define IE_CDTV 0x100 @@ -80,19 +79,6 @@ extern int tablet_log; #define INPUTEVENT_JOY1_CD32_LAST INPUTEVENT_JOY1_CD32_BLUE #define INPUTEVENT_JOY2_CD32_LAST INPUTEVENT_JOY2_CD32_BLUE -/* event masks */ -#define AM_KEY 1 /* keyboard allowed */ -#define AM_JOY_BUT 2 /* joystick buttons allowed */ -#define AM_JOY_AXIS 4 /* joystick axis allowed */ -#define AM_MOUSE_BUT 8 /* mouse buttons allowed */ -#define AM_MOUSE_AXIS 16 /* mouse direction allowed */ -#define AM_AF 32 /* supports autofire */ -#define AM_INFO 64 /* information data for gui */ -#define AM_DUMMY 128 /* placeholder */ -#define AM_CUSTOM 256 /* custom event */ -#define AM_K (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT|AM_AF) /* generic button/switch */ -#define AM_KK (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT) - #define JOYMOUSE_CDTV 8 #define DEFEVENT(A, B, C, D, E, F) {_T(#A), B, C, D, E, F }, @@ -2757,6 +2743,7 @@ static bool inputdevice_handle_inputcode2 (int code, int state) { static int swapperslot; static int tracer_enable; + int newstate; if (code == 0) goto end; @@ -2770,6 +2757,15 @@ static bool inputdevice_handle_inputcode2 (int code, int state) if (vpos != 0) write_log (_T("inputcode=%d but vpos = %d"), code, vpos); + if (state == SET_ONOFF_ON_VALUE) + newstate = 1; + else if (state == SET_ONOFF_OFF_VALUE) + newstate = 0; + else if (state) + newstate = -1; + else + newstate = 0; + #ifdef ARCADIA switch (code) { @@ -2810,6 +2806,11 @@ static bool inputdevice_handle_inputcode2 (int code, int state) case AKS_SCREENSHOT_CLIPBOARD: screenshot (0, 1); break; +#ifdef AVIOUTPUT + case AKS_VIDEORECORD: + AVIOutput_Toggle (newstate, true); + break; +#endif #ifdef ACTION_REPLAY case AKS_FREEZEBUTTON: action_replay_freeze (); @@ -2847,10 +2848,10 @@ static bool inputdevice_handle_inputcode2 (int code, int state) NMI_delayed (); break; case AKS_PAUSE: - pausemode (-1); + pausemode (newstate); break; case AKS_WARP: - warpmode (-1); + warpmode (newstate); break; case AKS_INHIBITSCREEN: toggle_inhibit_frame (IHF_SCROLLLOCK); @@ -2865,19 +2866,19 @@ static bool inputdevice_handle_inputcode2 (int code, int state) savestate_capture (1); break; case AKS_VOLDOWN: - sound_volume (-1); + sound_volume (newstate <= 0 ? -1 : 1); break; case AKS_VOLUP: - sound_volume (1); + sound_volume (newstate <= 0 ? 1 : -1); break; case AKS_VOLMUTE: - sound_mute (-1); + sound_mute (newstate); break; case AKS_MVOLDOWN: - master_sound_volume (-1); + master_sound_volume (newstate <= 0 ? -1 : 1); break; case AKS_MVOLUP: - master_sound_volume (1); + master_sound_volume (newstate <= 0 ? 1 : -1); break; case AKS_MVOLMUTE: master_sound_volume (0); @@ -2931,7 +2932,7 @@ static bool inputdevice_handle_inputcode2 (int code, int state) toggle_mousegrab (); break; case AKS_TOGGLERTG: - toggle_rtg (-1); + toggle_rtg (newstate); break; case AKS_ENTERDEBUGGER: activate_debugger (); @@ -3926,15 +3927,21 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0; int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0; int invert = (flags & ID_FLAG_INVERT) ? 1 : 0; + int setmode = (flags & ID_FLAG_SET_ONOFF) ? 1: 0; + int setval = (flags & ID_FLAG_SET_ONOFF_VAL) ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE; int state; - if (buttonstate < 0) { + if (buttonstate < 0) { state = buttonstate; } else if (invert) { state = buttonstate ? 0 : 1; } else { state = buttonstate; } + if (setmode) { + if (state) + state = setval; + } if (!state) { didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i); @@ -5684,6 +5691,8 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int keyst int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0; int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0; int invert = (flags & ID_FLAG_INVERT) ? 1 : 0; + int setmode = (flags & ID_FLAG_SET_ONOFF) ? 1: 0; + int setval = (flags & ID_FLAG_SET_ONOFF_VAL) ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE; int toggled; int state; @@ -5694,6 +5703,10 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int keyst } else { state = keystate; } + if (setmode) { + if (state) + state = setval; + } setqualifiers (evt, state > 0); @@ -6271,6 +6284,10 @@ int inputdevice_get_mapping (int devnum, int num, uae_u64 *pflags, int *pport, T flags |= IDEV_MAPPED_GAMEPORTSCUSTOM2; if (flag & ID_FLAG_QUALIFIER_MASK) flags |= flag & ID_FLAG_QUALIFIER_MASK; + if (flag & ID_FLAG_SET_ONOFF) + flags |= IDEV_MAPPED_SET_ONOFF; + if (flag & ID_FLAG_SET_ONOFF_VAL) + flags |= IDEV_MAPPED_SET_ONOFF_VAL; if (pflags) *pflags = flags; if (pport) @@ -6327,6 +6344,11 @@ int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *cust flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM1) ? ID_FLAG_GAMEPORTSCUSTOM1 : 0; flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM2) ? ID_FLAG_GAMEPORTSCUSTOM2 : 0; flag |= flags & IDEV_MAPPED_QUALIFIER_MASK; + flag &= ~(IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL); + if (amask & AM_SETTOGGLE) { + flag |= (flags & IDEV_MAPPED_SET_ONOFF) ? ID_FLAG_SET_ONOFF : 0; + flag |= (flags & IDEV_MAPPED_SET_ONOFF_VAL) ? ID_FLAG_SET_ONOFF_VAL : 0; + } if (port >= 0) portp = port; put_event_data (idf, devindex, num, eid, custom, flag, portp, sub); @@ -6840,7 +6862,7 @@ void setjoystickstate (int joy, int axis, int state, int max) v2 = 1; else if (v2 < 0) v2 = -1; - if (v1 && v1 != v2) { + if (v1 && v1 != v2 && (axis == 0 || axis == 1)) { static int prevdir; static struct timeval tv1; struct timeval tv2; diff --git a/inputevents.def b/inputevents.def index bff94a0f..602978a2 100644 --- a/inputevents.def +++ b/inputevents.def @@ -326,6 +326,7 @@ DEFEVENT(SPC_CUSTOM_EVENT,_T(""),AM_K,0,0,0) DEFEVENT(SPC_ENTERGUI,_T("Enter GUI"),AM_K,0,0,AKS_ENTERGUI) DEFEVENT(SPC_SCREENSHOT,_T("Screenshot (file)"),AM_K,0,0,AKS_SCREENSHOT_FILE) DEFEVENT(SPC_SCREENSHOT_CLIPBOARD,_T("Screenshot (clipboard)"),AM_K,0,0,AKS_SCREENSHOT_CLIPBOARD) +DEFEVENT(SPC_VIDEORECORD, _T("Audio/Video recording"),AM_KT,0,0,AKS_VIDEORECORD) DEFEVENT(SPC_FREEZEBUTTON,_T("Activate Cartridge"),AM_K,0,0,AKS_FREEZEBUTTON) DEFEVENT(SPC_FLOPPY0,_T("Change disk in DF0:"),AM_K,0,0,AKS_FLOPPY0) DEFEVENT(SPC_FLOPPY1,_T("Change disk in DF1:"),AM_K,0,0,AKS_FLOPPY1) @@ -335,9 +336,9 @@ DEFEVENT(SPC_EFLOPPY0,_T("Eject disk in DF0:"),AM_K,0,0,AKS_EFLOPPY0) DEFEVENT(SPC_EFLOPPY1,_T("Eject disk in DF1:"),AM_K,0,0,AKS_EFLOPPY1) DEFEVENT(SPC_EFLOPPY2,_T("Eject disk in DF2:"),AM_K,0,0,AKS_EFLOPPY2) DEFEVENT(SPC_EFLOPPY3,_T("Eject disk in DF3:"),AM_K,0,0,AKS_EFLOPPY3) -DEFEVENT(SPC_PAUSE,_T("Pause emulation"),AM_K,0,0,AKS_PAUSE) -DEFEVENT(SPC_WARP,_T("Warp mode"),AM_K,0,0,AKS_WARP) -DEFEVENT(SPC_INHIBITSCREEN,_T("Toggle screen updates"),AM_K,0,0,AKS_INHIBITSCREEN) +DEFEVENT(SPC_PAUSE,_T("Pause emulation"),AM_KT,0,0,AKS_PAUSE) +DEFEVENT(SPC_WARP,_T("Warp mode"),AM_KT,0,0,AKS_WARP) +DEFEVENT(SPC_INHIBITSCREEN,_T("Toggle screen updates"),AM_KT,0,0,AKS_INHIBITSCREEN) DEFEVENT(SPC_IRQ7,_T("Level 7 interrupt"),AM_K,0,0,AKS_IRQ7) DEFEVENT(SPC_STATEREWIND,_T("Load previous state capture checkpoint"),AM_K,0,0,AKS_STATEREWIND) @@ -346,7 +347,7 @@ DEFEVENT(SPC_STATECAPTURE,_T("Save state capture checkpoint"),AM_K,0,0,AKS_STATE DEFEVENT(SPC_VOLUME_DOWN,_T("Decrease volume level"),AM_K,0,0,AKS_VOLDOWN) DEFEVENT(SPC_VOLUME_UP,_T("Increase volume level"),AM_K,0,0,AKS_VOLUP) -DEFEVENT(SPC_VOLUME_MUTE,_T("Mute/unmute volume"),AM_K,0,0,AKS_VOLMUTE) +DEFEVENT(SPC_VOLUME_MUTE,_T("Mute/unmute volume"),AM_KT,0,0,AKS_VOLMUTE) DEFEVENT(SPC_MASTER_VOLUME_DOWN,_T("Decrease master volume level"),AM_K,0,0,AKS_MVOLDOWN) DEFEVENT(SPC_MASTER_VOLUME_UP,_T("Increase master volume level"),AM_K,0,0,AKS_MVOLUP) DEFEVENT(SPC_MASTER_VOLUME_MUTE,_T("Mute/unmute master volume"),AM_K,0,0,AKS_MVOLMUTE) @@ -358,15 +359,15 @@ DEFEVENT(SPC_STATESAVE,_T("Quick save state"),AM_K,0,0,AKS_STATESAVEQUICK) DEFEVENT(SPC_STATERESTORE,_T("Quick restore state"),AM_K,0,0,AKS_STATERESTOREQUICK) DEFEVENT(SPC_STATESAVEDIALOG,_T("Save state"),AM_K,0,0,AKS_STATESAVEDIALOG) DEFEVENT(SPC_STATERESTOREDIALOG,_T("Restore state"),AM_K,0,0,AKS_STATERESTOREDIALOG) -DEFEVENT(SPC_TOGGLEFULLSCREEN,_T("Toggle windowed/fullscreen"),AM_K,0,0,AKS_TOGGLEWINDOWEDFULLSCREEN) -DEFEVENT(SPC_TOGGLEFULLWINDOWFULLSCREEN,_T("Toggle full-window/fullscreen"),AM_K,0,0,AKS_TOGGLEFULLWINDOWFULLSCREEN) -DEFEVENT(SPC_TOGGLEWINDOWFULLWINDOW,_T("Toggle window/full-window"),AM_K,0,0,AKS_TOGGLEWINDOWFULLWINDOW) -DEFEVENT(SPC_TOGGLEDEFAULTSCREEN,_T("Toggle window/default screen"),AM_K,0,0,AKS_TOGGLEDEFAULTSCREEN) -DEFEVENT(SPC_TOGGLEMOUSEGRAB,_T("Toggle between mouse grabbed and un-grabbed"),AM_K,0,0,AKS_TOGGLEMOUSEGRAB) +DEFEVENT(SPC_TOGGLEFULLSCREEN,_T("Toggle windowed/fullscreen"),AM_KT,0,0,AKS_TOGGLEWINDOWEDFULLSCREEN) +DEFEVENT(SPC_TOGGLEFULLWINDOWFULLSCREEN,_T("Toggle full-window/fullscreen"),AM_KT,0,0,AKS_TOGGLEFULLWINDOWFULLSCREEN) +DEFEVENT(SPC_TOGGLEWINDOWFULLWINDOW,_T("Toggle window/full-window"),AM_KT,0,0,AKS_TOGGLEWINDOWFULLWINDOW) +DEFEVENT(SPC_TOGGLEDEFAULTSCREEN,_T("Toggle window/default screen"),AM_KT,0,0,AKS_TOGGLEDEFAULTSCREEN) +DEFEVENT(SPC_TOGGLEMOUSEGRAB,_T("Toggle between mouse grabbed and un-grabbed"),AM_KT,0,0,AKS_TOGGLEMOUSEGRAB) DEFEVENT(SPC_DECREASE_REFRESHRATE,_T("Decrease emulation speed"),AM_K,0,0,AKS_DECREASEREFRESHRATE) DEFEVENT(SPC_INCREASE_REFRESHRATE,_T("Increase emulation speed"),AM_K,0,0,AKS_INCREASEREFRESHRATE) -DEFEVENT(SPC_SWITCHINTERPOL,_T("Switch between audio interpolation methods"),AM_K,0,0,AKS_SWITCHINTERPOL) -DEFEVENT(SPC_TOGGLERTG,_T("Toggle chipset/RTG screen"),AM_K,0,0,AKS_TOGGLERTG) +DEFEVENT(SPC_SWITCHINTERPOL,_T("Switch between audio interpolation methods"),AM_KT,0,0,AKS_SWITCHINTERPOL) +DEFEVENT(SPC_TOGGLERTG,_T("Toggle chipset/RTG screen"),AM_KT,0,0,AKS_TOGGLERTG) DEFEVENT(SPC_DISKSWAPPER_NEXT,_T("Next slot in Disk Swapper"),AM_K,0,0,AKS_DISKSWAPPER_NEXT) DEFEVENT(SPC_DISKSWAPPER_PREV,_T("Previous slot in Disk Swapper"),AM_K,0,0,AKS_DISKSWAPPER_PREV) diff --git a/newcpu.cpp b/newcpu.cpp index fcbe78cb..4831d8ab 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -929,14 +929,6 @@ static void set_x_funcs (void) } -void m68k_setpc_normal (uaecptr pc) -{ - if (currprefs.mmu_model) - m68k_setpc_mmu (pc); - else - m68k_setpc (pc); -} - bool can_cpu_tracer (void) { return (currprefs.cpu_model == 68000 || currprefs.cpu_model == 68020) && currprefs.cpu_cycle_exact; @@ -2129,7 +2121,7 @@ static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32 while (i < 9) { uae_u32 v = 0; m68k_areg (regs, 7) -= 4; - // mmu030_idx is always small enough instruction is FMOVEM. + // mmu030_idx is always small enough if instruction is FMOVEM. if (mmu030_state[1] & MMU030_STATEFLAG1_FMOVEM) { if (i == 7) v = mmu030_fmovem_store[0]; @@ -2253,7 +2245,7 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) exception3 (regs.ir, newpc); return; } - m68k_setpc_mmu (newpc); + m68k_setpci (newpc); fill_prefetch (); exception_trace (nr); } @@ -2313,7 +2305,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) exception3 (regs.ir, newpc); return; } - m68k_setpc_mmu (newpc); + m68k_setpci (newpc); fill_prefetch (); exception_trace (nr); } @@ -2592,6 +2584,8 @@ void NMI (void) static void m68k_reset (bool hardreset) { + uae_u32 v; + regs.spcflags = 0; regs.ipl = regs.ipl_pin = 0; #ifdef SAVESTATE @@ -2615,8 +2609,10 @@ static void m68k_reset (bool hardreset) return; } #endif + v = get_long (4); m68k_areg (regs, 7) = get_long (0); - m68k_setpc_normal (get_long (4)); + m68k_setpc (v); + m68k_setpci (v); regs.s = 1; regs.m = 0; regs.stopped = 0; @@ -2700,7 +2696,7 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) if (cloanto_rom && (opcode & 0xF100) == 0x7100) { m68k_dreg (regs, (opcode >> 9) & 7) = (uae_s8)(opcode & 0xFF); - m68k_incpc (2); + m68k_incpc_normal (2); fill_prefetch (); return 4; } @@ -2721,7 +2717,7 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) if ((opcode & 0xF000) == 0xA000 && inrt) { /* Calltrap. */ - m68k_incpc (2); + m68k_incpc_normal (2); m68k_handle_trap (opcode & 0xFFF); fill_prefetch (); return 4; @@ -3684,7 +3680,7 @@ retry: } } CATCH (prb) { - m68k_setpc_mmu (regs.instruction_pc); + m68k_setpci (regs.instruction_pc); regflags.cznv = f.cznv; regflags.x = f.x; @@ -3746,7 +3742,7 @@ retry: /* restore state if instruction restart */ regflags.cznv = f.cznv; regflags.x = f.x; - m68k_setpc_mmu (regs.instruction_pc); + m68k_setpci (regs.instruction_pc); } if (mmufixup[0].reg >= 0) { @@ -3830,7 +3826,7 @@ insretry: regflags.cznv = f.cznv; regflags.x = f.x; - m68k_setpc_mmu (regs.instruction_pc); + m68k_setpci (regs.instruction_pc); if (mmufixup[0].reg >= 0) { m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value; diff --git a/od-win32/avioutput.cpp b/od-win32/avioutput.cpp index 765e04b5..4ce47346 100644 --- a/od-win32/avioutput.cpp +++ b/od-win32/avioutput.cpp @@ -39,6 +39,7 @@ Copyright(c) 2001 - 2002; #include "xwin.h" #include "avioutput.h" #include "registry.h" +#include "fsdb.h" #include "threaddep/thread.h" #define MAX_AVI_SIZE (0x80000000 - 0x1000000) @@ -67,7 +68,9 @@ int avioutput_fps = VBLANK_HZ_PAL; int avioutput_framelimiter = 0, avioutput_nosoundoutput = 0; int avioutput_nosoundsync = 1, avioutput_originalsize = 0; -TCHAR avioutput_filename[MAX_DPATH]; +TCHAR avioutput_filename_gui[MAX_DPATH]; +TCHAR avioutput_filename_auto[MAX_DPATH]; +TCHAR avioutput_filename_inuse[MAX_DPATH]; static TCHAR avioutput_filename_tmp[MAX_DPATH]; extern struct uae_prefs workprefs; @@ -682,7 +685,7 @@ static void checkAVIsize (int force) if (total_avi_size == 0) return; _tcscpy (fn, avioutput_filename_tmp); - _stprintf (avioutput_filename, _T("%s_%d.avi"), fn, tmp_partcnt); + _stprintf (avioutput_filename_inuse, _T("%s_%d.avi"), fn, tmp_partcnt); write_log (_T("AVI split %d at %d bytes, %d frames\n"), tmp_partcnt, total_avi_size, frame_count); AVIOutput_End (); @@ -1131,11 +1134,11 @@ void AVIOutput_Begin (void) } else { ext1 = _T(".avi"); ext2 = _T(".wav"); } - if (_tcslen (avioutput_filename) >= 4 && !_tcsicmp (avioutput_filename + _tcslen (avioutput_filename) - 4, ext2)) - avioutput_filename[_tcslen (avioutput_filename) - 4] = 0; - if (_tcslen (avioutput_filename) >= 4 && _tcsicmp (avioutput_filename + _tcslen (avioutput_filename) - 4, ext1)) - _tcscat (avioutput_filename, ext1); - _tcscpy (avioutput_filename_tmp, avioutput_filename); + if (_tcslen (avioutput_filename_inuse) >= 4 && !_tcsicmp (avioutput_filename_inuse + _tcslen (avioutput_filename_inuse) - 4, ext2)) + avioutput_filename_inuse[_tcslen (avioutput_filename_inuse) - 4] = 0; + if (_tcslen (avioutput_filename_inuse) >= 4 && _tcsicmp (avioutput_filename_inuse + _tcslen (avioutput_filename_inuse) - 4, ext1)) + _tcscat (avioutput_filename_inuse, ext1); + _tcscpy (avioutput_filename_tmp, avioutput_filename_inuse); i = _tcslen (avioutput_filename_tmp) - 1; while (i > 0 && avioutput_filename_tmp[i] != '.') i--; if (i > 0) @@ -1143,25 +1146,27 @@ void AVIOutput_Begin (void) avioutput_needs_restart = 0; avioutput_enabled = avioutput_audio || avioutput_video; - if (!avioutput_init || !avioutput_enabled) + if (!avioutput_init || !avioutput_enabled) { + write_log (_T("No video or audio enabled\n")); goto error; + } // delete any existing file before writing AVI - SetFileAttributes (avioutput_filename, FILE_ATTRIBUTE_ARCHIVE); - DeleteFile (avioutput_filename); + SetFileAttributes (avioutput_filename_inuse, FILE_ATTRIBUTE_ARCHIVE); + DeleteFile (avioutput_filename_inuse); if (avioutput_audio == AVIAUDIO_WAV) { - wavfile = _tfopen (avioutput_filename, _T("wb")); + wavfile = _tfopen (avioutput_filename_inuse, _T("wb")); if (!wavfile) { gui_message (_T("Failed to open wave-file\n\nThis can happen if the path and or file name was entered incorrectly.\n")); goto error; } writewavheader (0); - write_log (_T("wave-output to '%s' started\n"), avioutput_filename); + write_log (_T("wave-output to '%s' started\n"), avioutput_filename_inuse); return; } - if (((err = AVIFileOpen (&pfile, avioutput_filename, OF_CREATE | OF_WRITE, NULL)) != 0)) { + if (((err = AVIFileOpen (&pfile, avioutput_filename_inuse, OF_CREATE | OF_WRITE, NULL)) != 0)) { gui_message (_T("AVIFileOpen() FAILED (Error %X)\n\nThis can happen if the path and or file name was entered incorrectly.\nRequired *.avi extension.\n"), err); goto error; } @@ -1272,7 +1277,7 @@ void AVIOutput_Begin (void) init_comm_pipe (&queuefull, 20, 1); alive = -1; uae_start_thread (_T("aviworker"), AVIOutput_worker, NULL, NULL); - write_log (_T("AVIOutput enabled: video=%d audio=%d\n"), avioutput_video, avioutput_audio); + write_log (_T("AVIOutput enabled: video=%d audio=%d path='%s'\n"), avioutput_video, avioutput_audio, avioutput_filename_inuse); return; error: @@ -1361,6 +1366,64 @@ static void *AVIOutput_worker (void *arg) return 0; } +void AVIOutput_Toggle (int mode, bool immediate) +{ + if (mode < 0) { + avioutput_requested = !avioutput_requested; + } else { + if (mode == avioutput_requested) + return; + avioutput_requested = mode; + } + + if (!avioutput_requested) + AVIOutput_End (); + + if (immediate && avioutput_requested) { + TCHAR tmp[MAX_DPATH]; + _tcscpy (avioutput_filename_inuse, avioutput_filename_auto); + if (!avioutput_filename_inuse[0]) { + fetch_path (_T("VideoPath"), avioutput_filename_inuse, sizeof (avioutput_filename_inuse) / sizeof (TCHAR)); + _tcscat (avioutput_filename_inuse, _T("output.avi")); + } + + for (;;) { + int num = 0; + TCHAR *ext = NULL; + TCHAR *p = _tcsrchr (avioutput_filename_inuse, '.'); + if (p) + ext = my_strdup (p); + else + p = avioutput_filename_inuse + _tcslen (avioutput_filename_inuse); + p[0] = 0; + if (p > avioutput_filename_inuse && p[-1] >= '0' && p[-1] <= '9') { + p--; + while (p > avioutput_filename_inuse && p[-1] >= '0' && p[-1] <= '9') + p--; + num = _tstol (p); + } else { + *p++ = '_'; + *p = 0; + } + num++; + _stprintf (p, _T("%u"), num); + if (ext) + _tcscat (avioutput_filename_inuse, ext); + xfree (ext); + if (!my_existsfile (avioutput_filename_inuse)) + break; + } + + if (avioutput_audio != AVIAUDIO_WAV) { + avioutput_audio = AVIOutput_GetAudioCodec (tmp, sizeof tmp / sizeof (TCHAR)); + avioutput_video = AVIOutput_GetVideoCodec (tmp, sizeof tmp / sizeof (TCHAR)); + } + AVIOutput_Begin (); + } else if (!immediate && avioutput_requested) { + _tcscpy (avioutput_filename_inuse, avioutput_filename_gui); + } +} + #include diff --git a/od-win32/avioutput.h b/od-win32/avioutput.h index 7b626db1..b4313ad5 100644 --- a/od-win32/avioutput.h +++ b/od-win32/avioutput.h @@ -14,8 +14,11 @@ extern int avioutput_framelimiter, avioutput_nosoundoutput; extern int avioutput_nosoundsync, avioutput_originalsize; extern int screenshot_originalsize; -extern TCHAR avioutput_filename[MAX_DPATH]; +extern TCHAR avioutput_filename_gui[MAX_DPATH]; +extern TCHAR avioutput_filename_auto[MAX_DPATH]; +extern TCHAR avioutput_filename_inuse[MAX_DPATH]; +extern void AVIOutput_Toggle (int mode, bool immediate); extern void AVIOutput_WriteAudio (uae_u8 *sndbuffer, int sndbufsize); extern void AVIOutput_WriteVideo (void); extern int AVIOutput_ChooseAudioCodec (HWND hwnd,TCHAR*,int); diff --git a/od-win32/keyboard_win32.cpp b/od-win32/keyboard_win32.cpp index 67e7b6c8..1c8360b1 100644 --- a/od-win32/keyboard_win32.cpp +++ b/od-win32/keyboard_win32.cpp @@ -399,9 +399,18 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) } #endif #if 0 - if (scancode == DIK_F10) { - extern bool showoverlay; - showoverlay = !showoverlay; + if (scancode == DIK_F1) { + if (newstate) { + extern int paska; + paska++; + } + return; + } + if (scancode == DIK_F2) { + if (newstate) { + extern int paska; + paska--; + } return; } #endif diff --git a/od-win32/md-fpp.h b/od-win32/md-fpp.h index f0b9e18e..7235f5b1 100644 --- a/od-win32/md-fpp.h +++ b/od-win32/md-fpp.h @@ -42,7 +42,7 @@ STATIC_INLINE void from_exten(long double src, uae_u32 * wrd1, uae_u32 * wrd2, u #define HAVE_from_exten #endif /* USE_LONG_DOUBLE */ -#if defined(X86_MSVC_ASSEMBLY) +#if defined(X86_MSVC_ASSEMBLY_FPU) #ifndef HAVE_to_single #define HAVE_to_single STATIC_INLINE double to_single (uae_u32 longvalue) @@ -176,46 +176,62 @@ STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) static double twoto32 = 4294967296.0; #ifndef HAVE_to_exten #define HAVE_to_exten -STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +STATIC_INLINE void to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) { double frac; - if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) - return 0.0; +#ifdef USE_SOFT_LONG_DOUBLE + fpd->fpe = ((uae_u64)wrd2 << 32) | wrd3; + fpd->fpm = wrd1; + fpd->fpx = true; +#endif + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) { + fpd->fp = 0.0; + return; + } frac = ((double)wrd2 + ((double)wrd3 / twoto32)) / 2147483648.0; if (wrd1 & 0x80000000) frac = -frac; - return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383); + fpd->fp = ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383); } #endif #ifndef HAVE_from_exten #define HAVE_from_exten -STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) +STATIC_INLINE void from_exten(fpdata *fpd, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) { int expon; double frac; - if (src == 0.0) { - *wrd1 = 0; - *wrd2 = 0; - *wrd3 = 0; - return; - } - if (src < 0) { - *wrd1 = 0x80000000; - src = -src; - } else { - *wrd1 = 0; - } - frac = frexp (src, &expon); - frac += 0.5 / (twoto32 * twoto32); - if (frac >= 1.0) { - frac /= 2.0; - expon++; - } - *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); - *wrd2 = (uae_u32) (frac * twoto32); - *wrd3 = (uae_u32) ((frac * twoto32 - *wrd2) * twoto32); +#ifdef USE_SOFT_LONG_DOUBLE + if (fpd->fpx) { + *wrd1 = fpd->fpm; + *wrd2 = fpd->fpe >> 32; + *wrd3 = (uae_u32)fpd->fpe; + } else +#endif + { + if (fpd->fp == 0.0) { + *wrd1 = 0; + *wrd2 = 0; + *wrd3 = 0; + return; + } + if (fpd->fp < 0) { + *wrd1 = 0x80000000; + fpd->fp = -fpd->fp; + } else { + *wrd1 = 0; + } + frac = frexp (fpd->fp, &expon); + frac += 0.5 / (twoto32 * twoto32); + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); + *wrd2 = (uae_u32) (frac * twoto32); + *wrd3 = (uae_u32) ((frac * twoto32 - *wrd2) * twoto32); + } } #endif diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 4d62025d..29ef629d 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -2497,7 +2497,8 @@ void picasso_enablescreen (int on) init_picasso_screen (); picasso_refresh (); - checkrtglibrary(); + if (currprefs.rtgmem_type < GFXBOARD_HARDWARE) + checkrtglibrary(); } static void resetpalette(void) diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index fe8b24dd..9765903b 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -270,6 +270,7 @@ #define IDS_INPUTQUALIFIER 272 #define IDS_GENERIC 273 #define IDS_AUTODETECT 274 +#define IDS_OFF 275 #define IDS_NUMSG_NEEDEXT2 300 #define IDS_NUMSG_NOROMKEY 301 #define IDS_NUMSG_KSROMCRCERROR 302 @@ -1210,6 +1211,7 @@ #define ID_ST_CDEJECTALL 40047 #define ID_CDDRIVES_CD 40048 #define ID_ST_CD0 40049 +#define IDC_STATIC -1 // Next default values for new objects // diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 8481d9ba..94437ab7 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -1874,6 +1874,7 @@ BEGIN IDS_INPUTQUALIFIER "Qualifiers" IDS_GENERIC "Generic" IDS_AUTODETECT "Autodetect" + IDS_OFF "off" END STRINGTABLE diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index 1a7514d3..8a955ac0 100644 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -80,6 +80,7 @@ #define WITH_CHD #define WITH_LUA /* lua scripting */ #define WITH_UAENATIVE +#define WITH_SLIRP #else diff --git a/od-win32/win32.h b/od-win32/win32.h index 0ac8f272..9b19acaf 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("9") +#define WINUAEBETA _T("10") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2014, 2, 22) +#define WINUAEDATE MAKEBD(2014, 3, 4) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 9ff84ca3..a0aefa2a 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -3579,6 +3579,18 @@ static void set_lventry_input (HWND list, int index) _tcscpy (invert, _T("-")); if (flags & IDEV_MAPPED_INVERT) WIN32GUI_LoadUIString (IDS_YES, invert, sizeof invert / sizeof (TCHAR)); + if (flags & IDEV_MAPPED_SET_ONOFF) { + _tcscat (name, _T(" (")); + TCHAR val[32]; + if (flags & IDEV_MAPPED_SET_ONOFF_VAL) { + WIN32GUI_LoadUIString (IDS_ON, val, sizeof val / sizeof (TCHAR)); + } else { + WIN32GUI_LoadUIString (IDS_OFF, val, sizeof val / sizeof (TCHAR)); + } + _tcscat (name, val); + _tcscat (name, _T(")")); + } + ListView_SetItemText (list, index, 1, custom[0] ? custom : name); ListView_SetItemText (list, index, 2, af); ListView_SetItemText (list, index, 3, toggle); @@ -13664,6 +13676,34 @@ static void ports_remap (HWND hDlg, int port) } } +static void input_togglesetmode (void) +{ + int evtnum; + uae_u64 flags; + TCHAR name[256]; + TCHAR custom[MAX_DPATH]; + + if (input_selected_device < 0 || input_selected_widget < 0) + return; + evtnum = inputdevice_get_mapping (input_selected_device, input_selected_widget, + &flags, NULL, name, custom, input_selected_sub_num); + if (evtnum) { + struct inputevent *evt = inputdevice_get_eventinfo (evtnum); + if (evt && (evt->allow_mask & AM_SETTOGGLE)) { + if ((flags & (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL)) == (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL)) { + flags &= ~(IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL); + } else if (flags & IDEV_MAPPED_SET_ONOFF) { + flags |= IDEV_MAPPED_SET_ONOFF_VAL; + } else { + flags |= IDEV_MAPPED_SET_ONOFF; + flags &= ~IDEV_MAPPED_SET_ONOFF_VAL; + } + inputdevice_set_mapping (input_selected_device, input_selected_widget, + name, custom, flags, -1, input_selected_sub_num); + } + } +} + static void input_toggleautofire (void) { int evt; @@ -14043,6 +14083,8 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM input_selected_widget = entry; if (column == 0 && entry == oldentry && dblclick) { input_restoredefault (); + } else if (column == 1 && entry == oldentry) { + input_togglesetmode (); } else if (column == 2 && entry == oldentry) { input_toggleautofire (); } else if (column == 3 && entry == oldentry) { @@ -14965,7 +15007,7 @@ static void values_to_avioutputdlg (HWND hDlg) { updatewinfsmode (&workprefs); - SetDlgItemText (hDlg, IDC_AVIOUTPUT_FILETEXT, avioutput_filename); + SetDlgItemText (hDlg, IDC_AVIOUTPUT_FILETEXT, avioutput_filename_gui); CheckDlgButton (hDlg, IDC_AVIOUTPUT_FRAMELIMITER, avioutput_framelimiter ? FALSE : TRUE); CheckDlgButton (hDlg, IDC_AVIOUTPUT_NOSOUNDOUTPUT, avioutput_nosoundoutput ? TRUE : FALSE); CheckDlgButton (hDlg, IDC_AVIOUTPUT_NOSOUNDSYNC, avioutput_nosoundsync ? TRUE : FALSE); @@ -15058,10 +15100,11 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP AVIOutput_GetSettings (); regqueryint (NULL, _T("Screenshot_Original"), &screenshot_originalsize); enable_for_avioutputdlg (hDlg); - if (!avioutput_filename[0]) { - fetch_path (_T("VideoPath"), avioutput_filename, sizeof (avioutput_filename) / sizeof (TCHAR)); - _tcscat (avioutput_filename, _T("output.avi")); + if (!avioutput_filename_gui[0]) { + fetch_path (_T("VideoPath"), avioutput_filename_gui, sizeof (avioutput_filename_gui) / sizeof (TCHAR)); + _tcscat (avioutput_filename_gui, _T("output.avi")); } + _tcscpy (avioutput_filename_auto, avioutput_filename_gui); SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_RESETCONTENT, 0, 0); SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)_T("-")); SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)_T("1")); @@ -15183,9 +15226,7 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP break; case IDC_AVIOUTPUT_ACTIVATED: - avioutput_requested = !avioutput_requested; - if (!avioutput_requested) - AVIOutput_End (); + AVIOutput_Toggle (!avioutput_requested, false); break; case IDC_SCREENSHOT: screenshot(1, 0); @@ -15229,7 +15270,7 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; - ofn.lpstrFile = avioutput_filename; + ofn.lpstrFile = avioutput_filename_gui; ofn.nMaxFile = MAX_DPATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; @@ -15244,8 +15285,9 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP if (ofn.nFilterIndex == 2) { avioutput_audio = AVIAUDIO_WAV; avioutput_video = 0; - if (_tcslen (avioutput_filename) > 4 && !_tcsicmp (avioutput_filename + _tcslen (avioutput_filename) - 4, _T(".avi"))) - _tcscpy (avioutput_filename + _tcslen (avioutput_filename) - 4, _T(".wav")); + if (_tcslen (avioutput_filename_gui) > 4 && !_tcsicmp (avioutput_filename_gui + _tcslen (avioutput_filename_gui) - 4, _T(".avi"))) + _tcscpy (avioutput_filename_gui + _tcslen (avioutput_filename_gui) - 4, _T(".wav")); + _tcscpy (avioutput_filename_auto, avioutput_filename_gui); } break; } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 6440afcd..1cd3737a 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,16 +1,31 @@ -1 -> 0: 0,1FE,1FE,1FE,.. -1 -> 1: 0,1FE,0,1FE,0,.. -1 -> 2: 0,1FE,70,1FE,70,.. (C-) -1 -> 9: 0,1FE,0,74,0,74,.. (DA) -1 -> B: 0,1FE,70,0,74,70,0,74,70,0,74,.. (ACD) -1 -> C: 0,1FE,72,74,70,72,74,70,72,.. (CBA) -1 -> D: 0,1FE,72,74,70,72,74,70,72,.. (CBA) -1 -> E: 0,1FE,70,70,70,70,.. (C) -1 -> F: 0,1FE,70,70,74,70,70,70,74,70,70,70,74,.. (CCCA) +1 -> 0 (-) : 0,1FE,1FE,1FE,.. +1 -> 1 (D) : 0,1FE,0,1FE,0,.. +1 -> 2 (C) : 0,1FE,70,1FE,70,.. (C-) +1 -> 9 (AD) : 0,1FE,0,74,0,74,.. (DA) +1 -> B (ACD) : 0,1FE,70,0,74,70,0,74,70,0,74,.. (ACD) +1 -> C (AB) : 0,1FE,72,74,70,72,74,70,72,.. (CBA) +1 -> D (ABD) : 0,1FE,72,74,70,72,74,70,72,.. (CBA) +1 -> E (ABC) : 0,1FE,70,70,70,70,.. (C) +1 -> F (ABCD): 0,1FE,70,70,74,70,70,70,74,70,70,70,74,.. (CCCA) - restore only single input target to default. +Beta 9: + +- NCR emulation didn't work with SCSI IDs 4-6. +- NCR SCRIPTS MOVE command phase bit test mismatch returned wrong interrupt status. (NetBSD 1.x) +- Added partial hack to NCR emulation that "fixes" NetBSD harmless "Phase mismatch: REQ not asserted!" warnings. +- IDE emulation: use LBA48 calculations only if command is new LBA48 command (read/write ext). + This could have caused unexplained disk error messages if device driver used both lba28 and lba48 commands + and HDF was lba48 enabled (>=128G in size) +- maxmem command line parameter can now also be used to increase natmem limit (if host OS allows it) +- b5 interrupt update had another problem, CE modes lost interrupts in some situations when using UAE HD controller. +- Partition hardfile dostype was set to mostly random value with some CPU configs (b1). +- Disabled "smart centering" (tries to keep old centering parameters if it is "good enough"), it does not seem to + work correctly anymore (probably worked only accidentally) and leaves normal WB screen modes non-centered. Will + be debugged more if something else breaks, as usual.. + Beta 8: - 68000 CE/prefetch mode reads of non-existing memory should return correct data in all situations. diff --git a/slirp/icmp_var.h b/slirp/icmp_var.h index 9af222fb..9fe6d628 100644 --- a/slirp/icmp_var.h +++ b/slirp/icmp_var.h @@ -61,5 +61,7 @@ struct icmpstat { } extern struct icmpstat icmpstat; +extern struct socket icmp; +extern struct socket *icmp_last_so; #endif diff --git a/slirp/ip_icmp.cpp b/slirp/ip_icmp.cpp index d6450bbb..2dfef009 100644 --- a/slirp/ip_icmp.cpp +++ b/slirp/ip_icmp.cpp @@ -34,6 +34,8 @@ #include "ip_icmp.h" struct icmpstat icmpstat; +struct socket icmp; +struct socket *icmp_last_so; /* The message sent when emulating PING */ /* Be nice and tell them it's just a psuedo-ping packet */ @@ -62,6 +64,59 @@ static int icmp_flush[19] = { /* ADDR MASK REPLY (18) */ 0 }; +void icmp_init(void) +{ + icmp.so_next = icmp.so_prev = &icmp; + icmp_last_so = &icmp; +} + +void icmp_cleanup(void) +{ + while (icmp.so_next != &icmp) { + icmp_detach(icmp.so_next); + } +} + +static int icmp_send(struct socket *so, struct mbuf *m, int hlen) +{ + struct ip *ip = mtod(m, struct ip *); + struct sockaddr_in addr; + + so->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); + if (so->s == -1) { + return -1; + } + + so->so_m = m; + so->so_faddr = ip->ip_dst; + so->so_laddr = ip->ip_src; + so->so_iptos = ip->ip_tos; + so->so_type = IPPROTO_ICMP; + so->so_state = SS_ISFCONNECTED; + so->so_expire = curtime + SO_EXPIRE; + + addr.sin_family = AF_INET; + addr.sin_addr = so->so_faddr; + + insque(so, &icmp); + + if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0, + (struct sockaddr *)&addr, sizeof(addr)) == -1) { + DEBUG_MISC(("icmp_input icmp sendto tx errno = %d-%s\n", + errno, strerror(errno))); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); + icmp_detach(so); + } + + return 0; +} + +void icmp_detach(struct socket *so) +{ + closesocket(so->s); + sofree(so); +} + /* * Process a received ICMP message. */ @@ -113,6 +168,8 @@ void icmp_input(struct mbuf *m, int hlen) struct socket *so; struct sockaddr_in addr; if ((so = socreate()) == NULL) goto freeit; + if (icmp_send(so, m, hlen) == 0) + return; if(udp_attach(so) == -1) { DEBUG_MISC(("icmp_input udp_attach errno = %d-%s\n", errno,strerror(errno))); @@ -358,3 +415,39 @@ void icmp_reflect(struct mbuf *m) icmpstat.icps_reflect++; } + +void icmp_receive(struct socket *so) +{ + struct mbuf *m = so->so_m; + struct ip *ip = mtod(m, struct ip *); + int hlen = ip->ip_hl << 2; + u_char error_code; + struct icmp *icp; + int id, len; + + m->m_data += hlen; + m->m_len -= hlen; + icp = mtod(m, struct icmp *); + + id = icp->icmp_id; + len = recv(so->s, (char*)icp, m->m_len, 0); + icp->icmp_id = id; + + m->m_data -= hlen; + m->m_len += hlen; + + if (len == -1 || len == 0) { + if (errno == ENETUNREACH) { + error_code = ICMP_UNREACH_NET; + } else { + error_code = ICMP_UNREACH_HOST; + } + DEBUG_MISC((" udp icmp rx errno = %d-%s\n", errno, + strerror(errno))); + icmp_error(so->so_m, ICMP_UNREACH, error_code, 0, strerror(errno)); + } else { + icmp_reflect(so->so_m); + so->so_m = NULL; /* Don't m_free() it again! */ + } + icmp_detach(so); +} diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h index 08423371..19650abf 100644 --- a/slirp/ip_icmp.h +++ b/slirp/ip_icmp.h @@ -155,8 +155,12 @@ struct icmp { (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) +void icmp_init(void); +void icmp_cleanup(void); void icmp_input _P((struct mbuf *, int)); void icmp_error _P((struct mbuf *, u_char, u_char, int, char *)); void icmp_reflect _P((struct mbuf *)); +void icmp_receive(struct socket *so); +void icmp_detach(struct socket *so); #endif diff --git a/slirp/ip_input.cpp b/slirp/ip_input.cpp index f92c5cd1..efcc98ef 100644 --- a/slirp/ip_input.cpp +++ b/slirp/ip_input.cpp @@ -55,9 +55,17 @@ void ip_init(void) ip_id = tt.tv_sec & 0xffff; udp_init(); tcp_init(); + icmp_init(); ip_defttl = IPDEFTTL; } +void ip_cleanup(void) +{ + udp_cleanup(); + tcp_cleanup(); + icmp_cleanup(); +} + /* * Ip input routine. Checksum and byte swap header. If fragmented * try to reassemble. Process options. Pass to next level. diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 8a1aa31e..669efbfc 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -14,6 +14,7 @@ extern "C" { #endif int slirp_init(void); +void slirp_cleanup(void); int slirp_select_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds); diff --git a/slirp/mbuf.cpp b/slirp/mbuf.cpp index 474bde10..c578eb33 100644 --- a/slirp/mbuf.cpp +++ b/slirp/mbuf.cpp @@ -33,6 +33,27 @@ void m_init(void) msize_init(); } +void m_cleanup(void) +{ + struct mbuf *m, *next; + + m = m_usedlist.m_next; + while (m != &m_usedlist) { + next = m->m_next; + if (m->m_flags & M_EXT) { + free(m->m_ext); + } + free(m); + m = next; + } + m = m_freelist.m_next; + while (m != &m_freelist) { + next = m->m_next; + free(m); + m = next; + } +} + void msize_init(void) { /* diff --git a/slirp/mbuf.h b/slirp/mbuf.h index 183254a0..e1a9bcda 100644 --- a/slirp/mbuf.h +++ b/slirp/mbuf.h @@ -131,6 +131,7 @@ extern struct mbuf m_freelist, m_usedlist; extern int mbuf_max; void m_init _P((void)); +void m_cleanup _P((void)); void msize_init _P((void)); struct mbuf * m_get _P((void)); void m_free _P((struct mbuf *)); diff --git a/slirp/slirp.cpp b/slirp/slirp.cpp index c48a2cc6..aa60899d 100644 --- a/slirp/slirp.cpp +++ b/slirp/slirp.cpp @@ -1,3 +1,4 @@ + #include "slirp.h" /* host address */ @@ -120,22 +121,17 @@ static int get_dns_addr(struct in_addr *pdns_addr) #endif -#ifdef _WIN32 -void __cdecl slirp_cleanup(void) -{ - WSACleanup(); -} -#endif +static int inited; int slirp_init(void) { // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); #ifdef _WIN32 - { + if (!inited) { WSADATA Data; WSAStartup(MAKEWORD(2,0), &Data); - atexit(slirp_cleanup); + inited = 1; } #endif @@ -159,6 +155,13 @@ int slirp_init(void) return 0; } +void slirp_cleanup(void) +{ + ip_cleanup(); + m_cleanup(); + link_up = 0; +} + #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) #define UPD_NFDS(x) if (nfds < (x)) nfds = (x) @@ -299,6 +302,32 @@ int slirp_select_fill(int *pnfds, UPD_NFDS(so->s); } } + + /* + * ICMP sockets + */ + for (so = icmp.so_next; so != &icmp; so = so_next) { + so_next = so->so_next; + + /* + * See if it's timed out + */ + if (so->so_expire) { + if (so->so_expire <= curtime) { + icmp_detach(so); + continue; + } else { + do_slowtimo = 1; /* Let socket expire */ + } + } + + if (so->so_state & SS_ISFCONNECTED) { + FD_SET(so->s, readfds); + UPD_NFDS(so->s); + } + } + + } /* @@ -496,9 +525,21 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) so_next = so->so_next; if (so->s != -1 && FD_ISSET(so->s, readfds)) { - sorecvfrom(so); - } + sorecvfrom(so); + } } + + /* + * Check incoming ICMP relies. + */ + for (so = icmp.so_next; so != &icmp; so = so_next) { + so_next = so->so_next; + + if (so->s != -1 && FD_ISSET(so->s, readfds)) { + icmp_receive(so); + } + } + } /* diff --git a/slirp/slirp.h b/slirp/slirp.h index e3a6a907..43bdcdc1 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -237,6 +237,7 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include "tcp_var.h" #include "tcpip.h" #include "udp.h" +#include "ip_icmp.h" #include "icmp_var.h" #include "mbuf.h" #include "sbuf.h" @@ -319,6 +320,7 @@ void if_output _P((struct socket *, struct mbuf *)); /* ip_input.c */ void ip_init _P((void)); +void ip_cleanup _P((void)); void ip_input _P((struct mbuf *)); struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *)); void ip_freef _P((struct ipq *)); @@ -343,6 +345,7 @@ void tcp_setpersist _P((register struct tcpcb *)); /* tcp_subr.c */ void tcp_init _P((void)); +void tcp_cleanup _P((void)); void tcp_template _P((struct tcpcb *)); void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int)); struct tcpcb * tcp_newtcpcb _P((struct socket *)); diff --git a/slirp/tcp_subr.cpp b/slirp/tcp_subr.cpp index 7f51b034..75c2fdbb 100644 --- a/slirp/tcp_subr.cpp +++ b/slirp/tcp_subr.cpp @@ -56,6 +56,7 @@ void tcp_init(void) { tcp_iss = 1; /* wrong */ tcb.so_next = tcb.so_prev = &tcb; + tcp_last_so = &tcb; /* tcp_rcvspace = our Window we advertise to the remote */ tcp_rcvspace = TCP_RCVSPACE; @@ -66,6 +67,13 @@ void tcp_init(void) tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)); } +void tcp_cleanup(void) +{ + while (tcb.so_next != &tcb) { + tcp_close(sototcpcb(tcb.so_next)); + } +} + /* * Create template to be used to send tcp packets on a connection. * Call after host entry created, fills diff --git a/slirp/udp.cpp b/slirp/udp.cpp index 21257358..fcf931fd 100644 --- a/slirp/udp.cpp +++ b/slirp/udp.cpp @@ -62,6 +62,14 @@ void udp_init(void) { udb.so_next = udb.so_prev = &udb; } + +void udp_cleanup(void) +{ + while (udb.so_next != &udb) { + udp_detach(udb.so_next); + } +} + /* m->m_data points at ip packet header * m->m_len length ip packet * ip->ip_len length data (IPDU) diff --git a/slirp/udp.h b/slirp/udp.h index 5818e39d..b06c8c27 100644 --- a/slirp/udp.h +++ b/slirp/udp.h @@ -95,6 +95,7 @@ extern struct socket udb; struct mbuf; void udp_init _P((void)); +void udp_cleanup _P((void)); void udp_input _P((register struct mbuf *, int)); int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *)); int udp_attach _P((struct socket *));