--- /dev/null
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* Infix->RPN conversion and calculation
+*
+* Copyright 1995-2002 Bernd Schmidt
+* Copyright 1995 Alessandro Bissacco
+* Copyright 2000-2010 Toni Wilen
+*/
+
+
+/*
+
+ Original code from http://en.wikipedia.org/wiki/Shunting_yard_algorithm
+
+*/
+
+#define CALC_DEBUG 0
+
+#if CALC_DEBUG
+#define calc_log(x) do { write_log x; } while(0)
+#else
+#define calc_log(x)
+#endif
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "calc.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#define STACK_SIZE 32
+#define MAX_VALUES 32
+#define IOBUFFERS 256
+
+static double parsedvalues[MAX_VALUES];
+
+// operators
+// precedence operators associativity
+// 1 ! right to left
+// 2 * / % left to right
+// 3 + - left to right
+// 4 = right to left
+static int op_preced(const TCHAR c)
+{
+ switch(c) {
+ case '!':
+ return 4;
+ case '*': case '/': case '\\': case '%':
+ return 3;
+ case '+': case '-':
+ return 2;
+ case '=':
+ return 1;
+ }
+ return 0;
+}
+
+static bool op_left_assoc(const TCHAR c)
+{
+ switch(c) {
+ // left to right
+ case '*': case '/': case '%': case '+': case '-':
+ return true;
+ // right to left
+ case '=': case '!':
+ return false;
+ }
+ return false;
+}
+
+static unsigned int op_arg_count(const TCHAR c)
+{
+ switch(c) {
+ case '*': case '/': case '%': case '+': case '-': case '=':
+ return 2;
+ case '!':
+ return 1;
+ default:
+ return c - 'A';
+ }
+ return 0;
+}
+
+#define is_operator(c) (c == '+' || c == '-' || c == '/' || c == '*' || c == '!' || c == '%' || c == '=')
+#define is_function(c) (c >= 'A' && c <= 'Z')
+#define is_ident(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z'))
+
+static bool shunting_yard(const TCHAR *input, TCHAR *output)
+{
+ const TCHAR *strpos = input, *strend = input + _tcslen(input);
+ TCHAR c, *outpos = output;
+
+ TCHAR stack[STACK_SIZE]; // operator stack
+ unsigned int sl = 0; // stack length
+ TCHAR sc; // used for record stack element
+
+ while(strpos < strend) {
+ if (sl >= STACK_SIZE)
+ return false;
+
+ // read one token from the input stream
+ c = *strpos;
+ if(c != ' ') {
+ // If the token is a number (identifier), then add it to the output queue.
+ if(is_ident(c)) {
+ *outpos = c; ++outpos;
+ }
+ // If the token is a function token, then push it onto the stack.
+ else if(is_function(c)) {
+ stack[sl] = c;
+ ++sl;
+ }
+ // If the token is a function argument separator (e.g., a comma):
+ else if(c == ',') {
+ bool pe = false;
+ while(sl > 0) {
+ sc = stack[sl - 1];
+ if(sc == '(') {
+ pe = true;
+ break;
+ }
+ else {
+ // Until the token at the top of the stack is a left parenthesis,
+ // pop operators off the stack onto the output queue.
+ *outpos = sc;
+ ++outpos;
+ sl--;
+ }
+ }
+ // If no left parentheses are encountered, either the separator was misplaced
+ // or parentheses were mismatched.
+ if(!pe) {
+ calc_log ((L"Error: separator or parentheses mismatched\n"));
+ return false;
+ }
+ }
+ // If the token is an operator, op1, then:
+ else if(is_operator(c)) {
+ while(sl > 0) {
+ sc = stack[sl - 1];
+ // While there is an operator token, o2, at the top of the stack
+ // op1 is left-associative and its precedence is less than or equal to that of op2,
+ // or op1 is right-associative and its precedence is less than that of op2,
+ if(is_operator(sc) &&
+ ((op_left_assoc(c) && (op_preced(c) <= op_preced(sc))) ||
+ (!op_left_assoc(c) && (op_preced(c) < op_preced(sc))))) {
+ // Pop o2 off the stack, onto the output queue;
+ *outpos = sc;
+ ++outpos;
+ sl--;
+ }
+ else {
+ break;
+ }
+ }
+ // push op1 onto the stack.
+ stack[sl] = c;
+ ++sl;
+ }
+ // If the token is a left parenthesis, then push it onto the stack.
+ else if(c == '(') {
+ stack[sl] = c;
+ ++sl;
+ }
+ // If the token is a right parenthesis:
+ else if(c == ')') {
+ bool pe = false;
+ // Until the token at the top of the stack is a left parenthesis,
+ // pop operators off the stack onto the output queue
+ while(sl > 0) {
+ sc = stack[sl - 1];
+ if(sc == '(') {
+ pe = true;
+ break;
+ }
+ else {
+ *outpos = sc;
+ ++outpos;
+ sl--;
+ }
+ }
+ // If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
+ if(!pe) {
+ calc_log ((L"Error: parentheses mismatched\n"));
+ return false;
+ }
+ // Pop the left parenthesis from the stack, but not onto the output queue.
+ sl--;
+ // If the token at the top of the stack is a function token, pop it onto the output queue.
+ if(sl > 0) {
+ sc = stack[sl - 1];
+ if(is_function(sc)) {
+ *outpos = sc;
+ ++outpos;
+ sl--;
+ }
+ }
+ }
+ else {
+ calc_log ((L"Unknown token %c\n", c));
+ return false; // Unknown token
+ }
+ }
+ ++strpos;
+ }
+ // When there are no more tokens to read:
+ // While there are still operator tokens in the stack:
+ while(sl > 0) {
+ sc = stack[sl - 1];
+ if(sc == '(' || sc == ')') {
+ printf("Error: parentheses mismatched\n");
+ return false;
+ }
+ *outpos = sc;
+ ++outpos;
+ --sl;
+ }
+ *outpos = 0; // Null terminator
+ return true;
+}
+
+
+struct calcstack
+{
+ TCHAR *s;
+ double val;
+};
+
+static double docalcx (TCHAR op, double v1, double v2)
+{
+ switch (op)
+ {
+ case '-':
+ return v1 - v2;
+ case '+':
+ return v1 + v2;
+ case '*':
+ return v1 * v2;
+ case '/':
+ return v1 / v2;
+ case '\\':
+ return (int)v1 % (int)v2;
+
+ }
+ return 0;
+}
+
+static double stacktoval(struct calcstack *st)
+{
+ if (st->s) {
+ if (_tcslen(st->s) == 1 && st->s[0] >= 'a' && st->s[0] <= 'z')
+ return parsedvalues[st->s[0] - 'a'];
+ return _tstof (st->s);
+ } else {
+ return st->val;
+ }
+}
+
+static double docalc2 (TCHAR op, struct calcstack *sv1, struct calcstack *sv2)
+{
+ double v1, v2;
+
+ v1 = stacktoval(sv1);
+ v2 = stacktoval(sv2);
+ return docalcx (op, v1, v2);
+}
+static double docalc1 (TCHAR op, struct calcstack *sv1, double v2)
+{
+ double v1;
+
+ v1 = stacktoval(sv1);
+ return docalcx (op, v1, v2);
+}
+
+static TCHAR *stacktostr (struct calcstack *st)
+{
+ static TCHAR out[256];
+ if (st->s)
+ return st->s;
+ _stprintf(out, L"%f", st->val);
+ return out;
+}
+
+static TCHAR *chartostack (TCHAR c)
+{
+ TCHAR *s = xmalloc (TCHAR, 2);
+ s[0] = c;
+ s[1] = 0;
+ return s;
+}
+
+static bool execution_order(const TCHAR *input, double *outval)
+{
+ const TCHAR *strpos = input, *strend = input + _tcslen(input);
+ TCHAR c, res[4];
+ unsigned int sl = 0, rn = 0;
+ struct calcstack stack[STACK_SIZE] = { 0 }, *sc, *sc2;
+ double val = 0;
+ int i;
+ bool ok = false;
+
+ // While there are input tokens left
+ while(strpos < strend) {
+
+ if (sl >= STACK_SIZE)
+ return false;
+
+ // Read the next token from input.
+ c = *strpos;
+ // If the token is a value or identifier
+ if(is_ident(c)) {
+ // Push it onto the stack.
+ stack[sl].s = chartostack (c);
+ ++sl;
+ }
+ // Otherwise, the token is an operator (operator here includes both operators, and functions).
+ else if(is_operator(c) || is_function(c)) {
+ _stprintf(res, L"_%02d", rn);
+ calc_log ((L"%s = ", res));
+ ++rn;
+ // It is known a priori that the operator takes n arguments.
+ unsigned int nargs = op_arg_count(c);
+ // If there are fewer than n values on the stack
+ if(sl < nargs) {
+ // (Error) The user has not input sufficient values in the expression.
+ return false;
+ }
+ // Else, Pop the top n values from the stack.
+ // Evaluate the operator, with the values as arguments.
+ if(is_function(c)) {
+ calc_log ((L"%c(", c));
+ while(nargs > 0){
+ sc = &stack[sl - nargs]; // to remove reverse order of arguments
+ if(nargs > 1) {
+ calc_log ((L"%s, ", sc));
+ }
+ else {
+ calc_log ((L"%s)\n", sc));
+ }
+ --nargs;
+ }
+ sl-=op_arg_count(c);
+ }
+ else {
+ if(nargs == 1) {
+ sc = &stack[sl - 1];
+ sl--;
+ val = docalc1 (c, sc, val);
+ calc_log ((L"%c %s = %f;\n", c, stacktostr(sc), val));
+ }
+ else {
+ sc = &stack[sl - 2];
+ calc_log ((L"%s %c ", stacktostr(sc), c));
+ sc2 = &stack[sl - 1];
+ val = docalc2 (c, sc, sc2);
+ sl--;sl--;
+ calc_log ((L"%s = %f;\n", stacktostr(sc2), val));
+ }
+ }
+ // Push the returned results, if any, back onto the stack.
+ stack[sl].val = val;
+ stack[sl].s = NULL;
+ ++sl;
+ }
+ ++strpos;
+ }
+ // If there is only one value in the stack
+ // That value is the result of the calculation.
+ if(sl == 1) {
+ sc = &stack[sl - 1];
+ sl--;
+ calc_log ((L"result = %f\n", val));
+ if (outval)
+ *outval = val;
+ ok = true;
+ }
+ for (i = 0; i < STACK_SIZE; i++)
+ xfree (stack[i].s);
+
+ // If there are more values in the stack
+ // (Error) The user input has too many values.
+
+ return ok;
+}
+
+static bool parse_values(const TCHAR *ins, TCHAR *out)
+{
+ int ident = 0;
+ TCHAR tmp;
+ TCHAR inbuf[IOBUFFERS];
+ int op;
+
+ _tcscpy (inbuf, ins);
+ TCHAR *in = inbuf;
+ TCHAR *p = out;
+ op = 0;
+ while (*in) {
+ TCHAR *instart = in;
+ if (_istdigit (*in)) {
+ if (ident >= MAX_VALUES)
+ return false;
+ if (op > 1 && (in[-1] == '-' || in[-1] == '+')) {
+ instart--;
+ p--;
+ }
+ *p++ = ident + 'a';
+ while (_istdigit (*in) || *in == '.')
+ in++;
+ tmp = *in;
+ *in = 0;
+ parsedvalues[ident++] = _tstof (instart);
+ *in = tmp;
+ op = 0;
+ } else {
+ if (is_operator(*in))
+ op++;
+ *p++ = *in++;
+ }
+ }
+ *p = 0;
+ return true;
+}
+
+bool calc(const TCHAR *input, double *outval)
+{
+ TCHAR output[IOBUFFERS], output2[IOBUFFERS];
+ calc_log ((L"IN: '%s'\n", input));
+ if (parse_values(input, output2)) {
+ if(shunting_yard(output2, output)) {
+ calc_log ((L"RPN OUT: %s\n", output));
+ if(!execution_order(output, outval)) {
+ calc_log ((L"PARSE ERROR!\n"));
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool iscalcformula (const TCHAR *formula)
+{
+ for (int i = 0; i < _tcslen (formula); i++) {
+ TCHAR c = formula[i];
+ if (is_operator (c))
+ return true;
+ }
+ return false;
+}
+
#include "blkdev.h"
#include "statusline.h"
#include "debug.h"
+#include "calc.h"
static int config_newfilesystem;
static struct strlist *temp_lines;
-static struct zfile *default_file;
+static struct zfile *default_file, *configstore;
static int uaeconfig;
static int unicode_config = 0;
#define UNEXPANDED L"$(FILE_PATH)"
+
static void trimwsa (char *s)
{
/* Delete trailing whitespace. */
return 0;
}
+
+static bool createconfigstore (struct uae_prefs*);
+static int getconfigstoreline (const TCHAR *option, TCHAR *value);
+
+static void calcformula (struct uae_prefs *prefs, TCHAR *in)
+{
+ TCHAR out[MAX_DPATH], configvalue[CONFIG_BLEN];
+ TCHAR *p = out;
+ double val;
+ int cnt1, cnt2;
+ static bool updatestore;
+
+ if (_tcslen (in) < 2 || in[0] != '[' || in[_tcslen (in) - 1] != ']')
+ return;
+ if (!configstore || updatestore)
+ createconfigstore (prefs);
+ updatestore = false;
+ if (!configstore)
+ return;
+ cnt1 = cnt2 = 0;
+ for (int i = 1; i < _tcslen (in) - 1; i++) {
+ TCHAR c = _totupper (in[i]);
+ if (c >= 'A' && c <='Z') {
+ TCHAR *start = &in[i];
+ while (_istalnum (c) || c == '_' || c == '.') {
+ i++;
+ c = in[i];
+ }
+ TCHAR store = in[i];
+ in[i] = 0;
+ //write_log (L"'%s'\n", start);
+ if (!getconfigstoreline (start, configvalue))
+ return;
+ _tcscpy (p, configvalue);
+ p += _tcslen (p);
+ in[i] = store;
+ i--;
+ cnt1++;
+ } else {
+ cnt2++;
+ *p ++= c;
+ }
+ }
+ *p = 0;
+ if (cnt1 == 0 && cnt2 == 0)
+ return;
+ /* single config entry only? */
+ if (cnt1 == 1 && cnt2 == 0) {
+ _tcscpy (in, out);
+ updatestore = true;
+ return;
+ }
+ if (calc (out, &val)) {
+ _stprintf (in, L"%d", (int)val);
+ updatestore = true;
+ return;
+ }
+}
+
int cfgfile_parse_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int type)
{
+ calcformula (p, value);
+
if (!_tcscmp (option, L"debug")) {
write_log (L"CONFIG DEBUG: '%s'\n", value);
return 1;
int i;
line1 = line;
+ line1 += strspn (line1, "\t \r\n");
+ if (*line1 == ';')
+ return 0;
line2 = strchr (line, '=');
if (! line2) {
TCHAR *s = au (line1);
int i;
line1 = line;
+ line1 += _tcsspn (line1, L"\t \r\n");
+ if (*line1 == ';')
+ return 0;
line2 = _tcschr (line, '=');
if (! line2) {
write_log (L"CFGFILE: line was incomplete with only %s\n", line1);
free (str);
}
+static int getconfigstoreline (const TCHAR *option, TCHAR *value)
+{
+ TCHAR tmp[CONFIG_BLEN * 2], tmp2[CONFIG_BLEN * 2];
+ int idx = 0;
+
+ if (!configstore)
+ return 0;
+ zfile_fseek (configstore, 0, SEEK_SET);
+ for (;;) {
+ if (!zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), configstore))
+ return 0;
+ if (!cfgfile_separate_line (tmp, tmp2, value))
+ continue;
+ if (!_tcsicmp (option, tmp2))
+ return 1;
+ }
+}
+
+static bool createconfigstore (struct uae_prefs *p)
+{
+ uae_u8 zero = 0;
+ zfile_fclose (configstore);
+ configstore = zfile_fopen_empty (NULL, L"configstore", 50000);
+ if (!configstore)
+ return false;
+ zfile_fseek (configstore, 0, SEEK_SET);
+ uaeconfig++;
+ cfgfile_save_options (configstore, p, 0);
+ uaeconfig--;
+ cfg_write (&zero, configstore);
+ zfile_fseek (configstore, 0, SEEK_SET);
+ return true;
+}
+
static char *cfg_fgets (char *line, int max, struct zfile *fh)
{
#ifdef SINGLEFILE
temp_lines = u;
}
-static int getconfigstoreline (struct zfile *z, TCHAR *option, TCHAR *value)
-{
- TCHAR tmp[CONFIG_BLEN * 2];
- int idx = 0;
-
- for (;;) {
- TCHAR b = 0;
- if (zfile_fread (&b, 1, sizeof (TCHAR), z) != 1)
- return 0;
- tmp[idx++] = b;
- tmp[idx] = 0;
- if (b == '\n' || b == 0)
- break;
- }
- return cfgfile_separate_line (tmp, option, value);
-}
-
#if 0
static int cfgfile_handle_custom_event (TCHAR *custom, int mode)
{
int argv, i;
uae_u32 err;
TCHAR zero = 0;
- static struct zfile *configstore;
static TCHAR *configsearch;
static int configsearchfound;
argv = cmdlineparser (parms, argc, UAELIB_MAX_PARSE);
if (argv <= 1 && index == 0xffffffff) {
- zfile_fclose (configstore);
+ createconfigstore (&currprefs);
xfree (configsearch);
- configstore = zfile_fopen_empty (NULL, L"configstore", 50000);
configsearch = NULL;
- if (argv > 0 && _tcslen (argc[0]) > 0)
- configsearch = my_strdup (argc[0]);
if (!configstore) {
err = 20;
goto end;
}
- zfile_fseek (configstore, 0, SEEK_SET);
- uaeconfig++;
- cfgfile_save_options (configstore, &currprefs, 0);
- uaeconfig--;
- cfg_write (&zero, configstore);
- zfile_fseek (configstore, 0, SEEK_SET);
+ if (argv > 0 && _tcslen (argc[0]) > 0)
+ configsearch = my_strdup (argc[0]);
err = 0xffffffff;
configsearchfound = 0;
goto end;
p->fpu_model = 0;
p->cpu_model = 68000;
+ p->m68k_speed_throttle = 0;
p->cpu_clock_multiplier = 0;
p->cpu_frequency = 0;
p->mmu_model = 0;
int vpos;
static int vpos_count, vpos_count_prev;
-static int lof_store; // real bit in custom registers
+int lof_store; // real bit in custom registers
static int lof_current; // what display device thinks
static int lol;
static int next_lineno, prev_lineno;
static int vblank_hz_mult, vblank_hz_state;
static struct chipset_refresh *stored_chipset_refresh;
int doublescan;
+bool programmedmode;
frame_time_t syncbase;
static int fmode;
uae_u16 beamcon0, new_beamcon0;
vpos_count = vpos_count_prev = 0;
doublescan = 0;
+ programmedmode = false;
if ((beamcon0 & 0xA0) != (new_beamcon0 & 0xA0))
hzc = 1;
if (beamcon0 != new_beamcon0) {
maxvpos_nom = maxvpos;
equ_vblank_endline = -1;
doublescan = htotal <= 164 ? 1 : 0;
+ programmedmode = true;
dumpsync ();
hzc = 1;
}
if (vs > 0) {
curr_time = read_processor_time ();
+ vsyncmaxtime = curr_time + vsynctimebase;
render_screen ();
show_screen ();
frame_shown = true;
vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
vsync_busywait_start ();
vsyncmintime = curr_time;
- vsyncmaxtime = curr_time + vsynctimebase;
+ vsyncmaxtime = curr_time + vsynctimebase * (100 - currprefs.m68k_speed_throttle) / 100;
} else {
if (currprefs.m68k_speed < 0) {
curr_time = read_processor_time ();
if (curr_time - vsyncmaxtime >= 0 && curr_time - vsyncmaxtime < vsynctimebase) {
- vsyncmaxtime = curr_time + vsynctimebase - (curr_time - vsyncmaxtime);
+ vsyncmaxtime = curr_time + vsynctimebase * (100 - currprefs.m68k_speed_throttle) / 100 - (curr_time - vsyncmaxtime);
} else {
- vsyncmaxtime = curr_time + vsynctimebase;
+ vsyncmaxtime = curr_time + vsynctimebase * (100 - currprefs.m68k_speed_throttle) / 100;
}
vsyncmintime = curr_time;
return;
if (vpos + 1 == maxvpos + lof_store) {
/* really last line, just run the cpu emulation until whole vsync time has been used */
is_syncline = 1;
- vsyncmintime = vsyncmaxtime;
+ if (currprefs.m68k_speed_throttle)
+ vsyncmintime = read_processor_time (); /* end of CPU emulation time */
+ else
+ vsyncmintime = vsyncmaxtime; /* emulate if still time left */
} else {
/* end of scanline, run cpu emulation as long as we still have time */
- vsyncmintime += vsynctimebase / maxvpos_nom;
+ vsyncmintime += (vsynctimebase * (100 - currprefs.m68k_speed_throttle)) / (maxvpos_nom * 100);
if (!vblank_found_chipset && (int)vsyncmaxtime - (int)vsyncmintime > 0) {
is_syncline = -1;
frame_time_t rpt = read_processor_time ();
}
}
-#if 0
-#ifdef JIT
- if (currprefs.cachesize) {
- if (currprefs.m68k_speed < 0) {
- jitcount++;
- if (isvsync () >= 0 && trigger_frh (jitcount)) {
- frh_handler ();
- }
- is_syncline = (trigger_frh (jitcount + 1) && ! rpt_did_reset) ? -1 : 0;
- //write_log (L"%d %d\n", jitcount & (N_LINES - 1), is_syncline);
- } else {
- is_syncline = 0;
- }
- if (vpos + 1 == maxvpos + lof_store)
- is_syncline = 1;
- } else {
-#endif
- is_syncline = (vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed < 0) ? 1 : 0;
-#ifdef JIT
- }
-#endif
-#endif
-
if (!nocustom ()) {
int lineno = vpos;
if (lineno >= MAXVPOS)
extern int diwfirstword_total, diwlastword_total;
extern int ddffirstword_total, ddflastword_total;
extern int firstword_bplcon1;
+extern int lof_store;
#define MIN_DISPLAY_W 256
#define MIN_DISPLAY_H 192
if (gclow > 0 && gcloh > 0)
ret = -1;
- last_planes_vpos = (last_planes_vpos) & ~1;
- plflastline_total = (plflastline_total) & ~1;
+ if (interlace_seen) {
+ // interlace = only use long frames
+ if (!lof_store)
+ return 1;
+ last_planes_vpos++;
+ plflastline_total++;
+ }
+
if (!plflastline_total)
plflastline_total = last_planes_vpos;
- if (doublescan <= 0) {
+ if (doublescan <= 0 && !programmedmode) {
int min = coord_diw_to_window_x (92);
int max = coord_diw_to_window_x (460);
if (diwfirstword_total < min)
if (w == 0 || h == 0)
return 0;
- if (doublescan <= 0) {
+ if (doublescan <= 0 && !programmedmode) {
if ((w >> currprefs.gfx_resolution) < MIN_DISPLAY_W) {
dx += (w - (MIN_DISPLAY_W << currprefs.gfx_resolution)) / 2;
w = MIN_DISPLAY_W << currprefs.gfx_resolution;
if (w <= 0 || h <= 0 || dx <= 0 || dy <= 0)
return ret;
- if (doublescan <= 0) {
+ if (doublescan <= 0 && !programmedmode) {
if (dx > gfxvidinfo.outbuffer->inwidth / 3)
return ret;
if (dy > gfxvidinfo.outbuffer->inheight / 3)
*ph = h;
*pdx = dx;
*pdy = dy;
-
+#if 1
write_log (L"Display Size: %dx%d Offset: %dx%d\n", w, h, dx, dy);
write_log (L"First: %d Last: %d MinV: %d MaxV: %d Min: %d\n",
plffirstline_total, plflastline_total,
first_planes_vpos, last_planes_vpos, minfirstline);
+#endif
return 1;
}
--- /dev/null
+
+extern bool calc(const TCHAR *input, double *outval);
+extern bool iscalcformula (const TCHAR *formula);
extern int minfirstline, vblank_endline, numscrlines;
extern double vblank_hz, fake_vblank_hz;
extern int vblank_skip, doublescan;
+extern bool programmedmode;
extern frame_time_t syncbase;
#define DMA_AUD0 0x0001
struct multipath path_cd;
int m68k_speed;
+ int m68k_speed_throttle;
int cpu_model;
int mmu_model;
int cpu060_revision;
}
if (!uae_int_requested && currprefs.cpu_idle && currprefs.m68k_speed != 0 && ((regs.spcflags & SPCFLAG_STOP)) == SPCFLAG_STOP) {
- /* sleep 1ms if STOP-instruction is executed */
- if (1) {
+ /* sleep 1ms if STOP-instruction is executed
+ * but only if we have free frametime left to prevent slowdown
+ */
+ frame_time_t rpt = read_processor_time ();
+ if ((int)rpt - (int)vsyncmaxtime < 0) {
static int sleepcnt, lvpos, zerocnt;
if (vpos != lvpos) {
sleepcnt--;
typedef BOOL (CALLBACK* SETPROCESSDPIAWARE)(void);
typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD);
+
int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
SETPROCESSDPIAWARE pSetProcessDPIAware;
pSetProcessDPIAware ();
log_open (NULL, 0, 0);
+
__try {
WinMain2 (hInstance, hPrevInstance, lpCmdLine, nCmdShow);
} __except(WIN32_ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
#define LANG_DLL 1
//#define WINUAEBETA L""
-#define WINUAEBETA L"Beta 21"
-#define WINUAEDATE MAKEBD(2012, 3, 10)
-#define WINUAEEXTRA L""
+#define WINUAEBETA L"Beta 22"
+#define WINUAEDATE MAKEBD(2012, 3, 12)
+#define WINUAEEXTRA L"RC1"
//#define WINUAEEXTRA L"AmiKit Preview"
#define WINUAEREV L""
return;
evt = inputdevice_get_mapping (input_selected_device, input_selected_widget,
&flags, NULL, name, custom, input_selected_sub_num);
- if (evt <= 0)
- return;
if ((flags & (IDEV_MAPPED_INVERTTOGGLE | IDEV_MAPPED_AUTOFIRE_SET)) == (IDEV_MAPPED_INVERTTOGGLE | IDEV_MAPPED_AUTOFIRE_SET))
flags &= ~(IDEV_MAPPED_INVERTTOGGLE | IDEV_MAPPED_AUTOFIRE_SET);
else if (flags & IDEV_MAPPED_AUTOFIRE_SET) {
<ClCompile Include="..\..\archivers\wrp\warp.cpp" />
<ClCompile Include="..\..\archivers\zip\unzip.cpp" />
<ClCompile Include="..\..\aros.rom.cpp" />
+ <ClCompile Include="..\..\calc.cpp" />
<ClCompile Include="..\..\cpuemu_21.cpp" />
<ClCompile Include="..\..\events.cpp" />
<ClCompile Include="..\..\hrtmon.rom.cpp" />
<ClCompile Include="..\..\events.cpp">
<Filter>common</Filter>
</ClCompile>
+ <ClCompile Include="..\..\calc.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">
+Beta 22: (RC1)
+
+- CPU Idle limit added, do not sleep if there are no frame time left, no more slowdowns if CPU Idle is set too high.
+- Only use long frames to recalculate interlace autoscale positiong. (Autoscale jitter in some interlace setups)
+- Autoscale didn't always ignore standard mode display limits when displaying programmed display modes.
+
Beta 21: (Fastest possible vsync should be fixed finally, only some testing left to do)
- Direct3D masks and scanlines fixed, forgotten testing code.. (b20)
break;
}
*p = z->data[z->seek++];
- if (*p == '\n') {
+ if (*p == 0 && i == 0)
+ return NULL;
+ if (*p == '\n' || *p == 0) {
p++;
break;
}