]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2400b22
authorToni Wilen <twilen@winuae.net>
Mon, 12 Mar 2012 17:01:39 +0000 (19:01 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 12 Mar 2012 17:01:39 +0000 (19:01 +0200)
15 files changed:
calc.cpp [new file with mode: 0644]
cfgfile.cpp
custom.cpp
drawing.cpp
include/calc.h [new file with mode: 0644]
include/custom.h
include/options.h
newcpu.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gui.cpp
od-win32/winuae_msvc10/winuae_msvc.vcxproj
od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters
od-win32/winuaechangelog.txt
zfile.cpp

diff --git a/calc.cpp b/calc.cpp
new file mode 100644 (file)
index 0000000..4d7e62d
--- /dev/null
+++ b/calc.cpp
@@ -0,0 +1,453 @@
+/*
+* 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;
+}
+
index 114735dd09d6ef39c2193c21f8d16f479bec2493..58216ad24e2746799ed4195e0e225bfea84c71c7 100644 (file)
 #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;
 
@@ -202,6 +203,7 @@ static const TCHAR *obsolete[] = {
 
 #define UNEXPANDED L"$(FILE_PATH)"
 
+
 static void trimwsa (char *s)
 {
        /* Delete trailing whitespace.  */
@@ -2659,8 +2661,69 @@ invalid_fs:
        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;
@@ -2701,6 +2764,9 @@ static int cfgfile_separate_linea (const TCHAR *filename, char *line, TCHAR *lin
        int i;
 
        line1 = line;
+       line1 += strspn (line1, "\t \r\n");
+       if (*line1 == ';')
+               return 0;
        line2 = strchr (line, '=');
        if (! line2) {
                TCHAR *s = au (line1);
@@ -2741,6 +2807,9 @@ static int cfgfile_separate_line (TCHAR *line, TCHAR *line1b, TCHAR *line2b)
        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);
@@ -2861,6 +2930,40 @@ static void subst (TCHAR *p, TCHAR *f, int n)
        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
@@ -3449,23 +3552,6 @@ void cfgfile_addcfgparam (TCHAR *line)
        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)
 {
@@ -3591,7 +3677,6 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u
        int argv, i;
        uae_u32 err;
        TCHAR zero = 0;
-       static struct zfile *configstore;
        static TCHAR *configsearch;
        static int configsearchfound;
 
@@ -3688,22 +3773,15 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u
        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;
@@ -4062,6 +4140,7 @@ void default_prefs (struct uae_prefs *p, int type)
 
        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;
index bc323b8f858f4880ae72f9144d0f4a68b42cfb6e..8b18e11618a3ae701e913c3f0834bfa1816296c9 100644 (file)
@@ -132,7 +132,7 @@ struct ev2 eventtab2[ev2_max];
 
 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;
@@ -189,6 +189,7 @@ double vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored;
 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;
@@ -2964,6 +2965,7 @@ void init_hz (bool fullinit)
                vpos_count = vpos_count_prev = 0;
 
        doublescan = 0;
+       programmedmode = false;
        if ((beamcon0 & 0xA0) != (new_beamcon0 & 0xA0))
                hzc = 1;
        if (beamcon0 != new_beamcon0) {
@@ -3017,6 +3019,7 @@ void init_hz (bool fullinit)
                maxvpos_nom = maxvpos;
                equ_vblank_endline = -1;
                doublescan = htotal <= 164 ? 1 : 0;
+               programmedmode = true;
                dumpsync ();
                hzc = 1;
        }
@@ -5143,6 +5146,7 @@ static void framewait (void)
        if (vs > 0) {
 
                curr_time = read_processor_time ();
+               vsyncmaxtime = curr_time + vsynctimebase;
                render_screen ();
                show_screen ();
                frame_shown = true;
@@ -5163,7 +5167,7 @@ static void framewait (void)
                        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 {
 
@@ -5185,9 +5189,9 @@ static void framewait (void)
        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;
@@ -5793,10 +5797,13 @@ static void hsync_handler_post (bool onvsync)
                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 ();
@@ -5807,29 +5814,6 @@ static void hsync_handler_post (bool onvsync)
                }
        }
 
-#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)
index d3160fc41d2b7d20b5c67cea92906ac1b22a1be3..590d5138ec4f05089a1ea2732eb466b142911748 100644 (file)
@@ -327,6 +327,7 @@ extern int first_planes_vpos, last_planes_vpos;
 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
@@ -377,12 +378,18 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy)
        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)
@@ -443,7 +450,7 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy)
        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;
@@ -467,7 +474,7 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy)
 
        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)
@@ -482,11 +489,12 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy)
        *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;
 }
 
diff --git a/include/calc.h b/include/calc.h
new file mode 100644 (file)
index 0000000..be73234
--- /dev/null
@@ -0,0 +1,3 @@
+
+extern bool calc(const TCHAR *input, double *outval);
+extern bool iscalcformula (const TCHAR *formula);
index 00c8e1af4037d012b140ffc1bed26e651fd4b78d..2ec96b44ab59970107e6e892da9c592e48f38310 100644 (file)
@@ -114,6 +114,7 @@ extern int hsyncstartpos;
 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
index c6647a3773655c1d169788c494c87434b37e4129..8aed9888acf4ab0363a2bc275419d67329897c51 100644 (file)
@@ -380,6 +380,7 @@ struct uae_prefs {
        struct multipath path_cd;
 
        int m68k_speed;
+       int m68k_speed_throttle;
        int cpu_model;
        int mmu_model;
        int cpu060_revision;
index e8a625821c210890d26ece2fbb36ab14587f9eb6..3fa7b501c96d75737a169614f0a4b30d529d00d2 100644 (file)
@@ -3384,8 +3384,11 @@ STATIC_INLINE int do_specialties (int cycles)
                }
 
                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--;
index 97cbd33a40344369978f239b9b303a6859eaafb2..d5949b7f7e1364eb973e8fbdb34e6a74bafaf9de 100644 (file)
@@ -5750,6 +5750,7 @@ void fpux_restore (int *v)
 typedef BOOL (CALLBACK* SETPROCESSDPIAWARE)(void);
 typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD);
 
+
 int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
 {
        SETPROCESSDPIAWARE pSetProcessDPIAware;
@@ -5797,6 +5798,7 @@ int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdL
                pSetProcessDPIAware ();
        log_open (NULL, 0, 0);
 
+       
        __try {
                WinMain2 (hInstance, hPrevInstance, lpCmdLine, nCmdShow);
        } __except(WIN32_ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
index 5272ba6bddc2d64153912852ce41a41873dbfda9..cf827f9ab071d70e8576976f723da7b93c23cfd2 100644 (file)
@@ -19,9 +19,9 @@
 #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""
 
index 2614dcab8f53b183d0598b37b7c36479ca17d7ca..1ddb66f065cd68b6b278701919726555e4166464 100644 (file)
@@ -12170,8 +12170,6 @@ static void input_toggleautofire (void)
                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) {
index 08ad3d6b86a61c85ab6ec49d4b77766dbe483333..07dd59718a51703c658cf5a9add8bf1c1033bd9b 100644 (file)
     <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" />
index 17c918d2a81c4ee56daff192479b2397c44432a2..7e0539467ee3a8685db6a61d9b17f9fba6ba494f 100644 (file)
     <ClCompile Include="..\..\events.cpp">
       <Filter>common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\calc.cpp">
+      <Filter>common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
index af70eabc282a3500ab1d37a2f88ce785f701c1f5..4d6516cbd4b2ee17f76e64fe87f3ae3ad9d47db3 100644 (file)
@@ -1,4 +1,10 @@
 
+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)
index 6c61017a7991ebd676a2116a2bcc2f50f4662e66..fb0985862a91597ecad9f68d3c7ce3d5cb54627c 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -2256,7 +2256,9 @@ TCHAR *zfile_fgets (TCHAR *s, int size, struct zfile *z)
                                break;
                        }
                        *p = z->data[z->seek++];
-                       if (*p == '\n') {
+                       if (*p == 0 && i == 0)
+                               return NULL;
+                       if (*p == '\n' || *p == 0) {
                                p++;
                                break;
                        }