Index: common/core_aux.cc
===================================================================
--- common/core_aux.cc	(nonexistent)
+++ common/core_aux.cc	(working copy)
@@ -0,0 +1,422 @@
+/* 
+
+  Aux util functions for library interface
+
+*/
+
+#include <string.h>
+
+
+#include "core_main.h"
+#include "core_helpers.h"
+#include "core_display.h"
+#include "core_variables.h"
+#include "core_aux.h"
+
+#include "shell.h"
+
+
+int prgmline2buf(char *buf, int len, int4 line, int highlight,
+                        int cmd, arg_struct *arg, bool shift_left = false,
+                        bool highlight_final_end = true);
+
+
+
+
+/*
+ ▄   ▄  ▄   ▄   ▄▄▄    ▄ ▄▄   ▄▄▄  
+ ▀▄ ▄▀  ▀▄ ▄▀  ▀   █   █▀  ▀ █   ▀ 
+  █▄█    █▄█   ▄▀▀▀█   █      ▀▀▀▄ 
+   █      █    ▀▄▄▀█   █     ▀▄▄▄▀ 
+*/
+
+
+typedef struct {
+  const char * name;
+  vartype * var;
+  double val;
+  char namelen;
+  bool rw;
+} vvar_t;
+
+
+#define VV_DevID  0
+#define VV_GrMod  1
+#define VV_RefLCD 2
+#define VV_ResX   3
+#define VV_ResY   4
+#define VV_Vbat   5
+#define VVAR_CNT  6
+
+
+static vvar_t vvars[] = {
+  {"DevID",  0, 0, 5, 0},
+  {"GrMod",  0, 0, 5, 1},
+  {"RefLCD", 0, 7, 6, 1},
+  {"ResX",   0, 0, 4, 0},
+  {"ResY",   0, 0, 4, 0},
+  {"Vbat",   0, 0, 4, 0}
+};
+
+
+int find_vvar(const char *name, int namelength) {
+  int ix = 0;
+  for ( ; ix < VVAR_CNT; ix++) {
+    if ( vvars[ix].namelen != namelength ) continue;
+    if ( !strncmp(vvars[ix].name, name, namelength) )
+      return ix;
+  }
+  return -1;
+}
+
+#include "stdio.h"
+
+void update_vvar(vvar_t *vv, double val) {
+  //printf("Update var '%s' from %i to %i\n", vv->name, (int)(1000*vv->val), (int)(1000*val));
+
+  // No change and we have the var
+  if ( val == vv->val && vv->var != NULL )
+    return;
+
+  free_vartype(vv->var);
+  vv->val = val;
+  vv->var = new_real(val);
+}
+
+
+vartype *recall_vvar(const char *name, int namelength) {
+
+#ifndef ARM
+  return NULL;
+
+#else
+  int ix = find_vvar(name, namelength);
+  if (ix < 0)
+    return NULL;
+
+  vvar_t * vv = vvars+ix;
+  double val;
+  
+  switch(ix) {
+    case VV_DevID:
+      val = shell_dev_id();
+      break;
+    case VV_ResX :
+      val = gr_MAXX();
+      break;
+    case VV_ResY :
+      val = gr_MAXY();
+      break;
+    case VV_Vbat :
+      val = shell_vbat();
+      break;
+    //case VV_GrMod:
+    default:
+      val = vvars[ix].val;
+      break;
+  }
+
+  update_vvar(vv, val);
+
+  return vv->var;
+#endif
+}
+
+
+
+int rval_to_int(vartype *value) {
+  int val = 0;
+
+  if (value->type == TYPE_REAL) {
+    phloat x = ((vartype_real *) value)->x;
+#ifdef BCD_MATH
+    val = to_int4(x);
+#else
+    val = (int)floor(x+0.5);
+#endif
+  }
+  return val;
+}
+
+
+
+// Returns: 1=variable consumed, 0=unknown variable
+int store_vvar(const char *name, int namelength, vartype *value) {
+
+#ifndef ARM
+  return 0;
+
+#else
+  int ix = find_vvar(name, namelength);
+  if (ix < 0)
+    return 0;
+
+  vvar_t * vv = vvars+ix;
+
+  if (vv->rw) {
+    double val = 0;
+
+    switch (ix) {
+      case VV_GrMod:
+        {
+          int gm = rval_to_int(value) & 3;
+          if (gm == 1) gm = 0;
+          val = (double)gm;
+        }
+        break;
+
+      case VV_RefLCD: {
+          int rf = rval_to_int(value);
+          if (rf >= 0) {
+            val = (double)(rf & 7);
+          } else {
+            val = vv->val;
+            shell_force_lcd_refresh((-rf) & 7);
+          }
+        }
+        break;
+
+      default:
+        val = 0;
+        break;
+    }
+
+    free_vartype(value); // We aren't using passed variable
+    update_vvar(vv, val);
+  }
+
+  return 1;
+#endif
+}
+
+
+
+/*
+ ▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄
+ ▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄
+*/
+
+
+
+extern "C" {
+
+
+static const int graph_maxx[] = {131, 131, 200, 400};
+static const int graph_maxy[] = { 16,  16, 120, 240};
+
+
+int gr_MAXX() {
+  int m = graphics_mode();
+  return graph_maxx[m];
+}
+
+int gr_MAXY() {
+  int m = graphics_mode();
+  return graph_maxy[m];
+}
+
+
+/*
+  0 => standard HP mode 131x16
+  1 => for future use (mapped to 0 now)
+  2 => 200x120
+  3 => 400x240
+*/
+
+int graphics_mode() {
+#ifdef ARM
+  return vvars[VV_GrMod].val;
+#else
+  return 0;
+#endif
+}
+
+
+void set_graphics_mode(int gm) {
+#ifdef ARM
+  vvars[VV_GrMod].val = gm;
+#endif
+}
+
+
+
+
+/*
+   ▄▄                          ▀      ▄▀▀                  ▄▀▀               
+   ██   ▄   ▄  ▄   ▄         ▄▄▄    ▄▄█▄▄   ▄▄▄          ▄▄█▄▄  ▄ ▄▄    ▄▄▄  
+  █  █  █   █   █▄█            █      █    █▀  ▀           █    █▀  █  █   ▀ 
+  █▄▄█  █   █   ▄█▄            █      █    █               █    █   █   ▀▀▀▄ 
+ █    █ ▀▄▄▀█  ▄▀ ▀▄         ▄▄█▄▄    █    ▀█▄▄▀           █    █   █  ▀▄▄▄▀ 
+
+*/
+
+
+void core_redisplay() {
+  redisplay();
+}
+
+
+int reg2str(char *buf, int buflen, reg_id_t reg_id) {
+  vartype *reg;
+  int len;
+
+  switch(reg_id) {
+    default: // tame compiler
+    case REG_X:  reg = reg_x; break;
+    case REG_Y:  reg = reg_y; break;
+    case REG_Z:  reg = reg_z; break;
+    case REG_T:  reg = reg_t; break;
+    case REG_LX: reg = reg_lastx; break;
+  }
+
+  if ( reg_id == REG_A ) {
+    len = reg_alpha_length;
+    if ( len > buflen-1 ) {
+      len = buflen-2;
+      buf[len] = 26; // ellipsis
+    }
+    memcpy(buf, reg_alpha, len);
+  } else
+    len = vartype2string(reg, buf, buflen-1);
+  
+  buf[len] = 0;
+  return len;
+}
+
+void clear_no_keystrokes_yet() {
+  no_keystrokes_yet = 0;
+}
+
+
+int is_pgm_mode() {
+  return flags.f.prgm_mode;
+}
+
+int is_number_entry() {
+  return mode_number_entry;
+}
+
+int is_goose() {
+  return program_running() && !flags.f.message;
+}
+
+void get_pgm_info(pgm_info_t * pi) {
+  pi->pgm_line = pc2line(pc);
+  pi->y_row = core_menu() ? 0 : prgm_highlight_row;
+}
+
+
+static arg_struct pgm_arg;
+
+
+void pgm_line_init(pgm_line_t * p, char * buf, int buflen) {
+  memset(p, 0, sizeof(pgm_line_t));
+  p->buf = buf;
+  p->buflen = buflen;
+  p->line = -1;
+}
+
+
+int get_pgm_line(pgm_line_t * p, int line) {
+  int cmd = 0;
+  int len = 0;
+  while (!p->is_end && p->line < line) {
+    if (p->line >= 0) {
+      get_next_command(&p->pc, &cmd, &pgm_arg, 0);
+      p->is_end = cmd == CMD_END;
+    }
+    p->line++;
+    len = prgmline2buf(p->buf, p->buflen, p->line, false, cmd, &pgm_arg, false, true);
+  }
+  return len;
+}
+
+
+
+int is_mode_pause() {
+  return mode_pause;
+}
+
+extern int no_menu_key_this_time;
+
+int core_keydown_ex(int key, int *enqueued, int *repeat, int no_menu_key) {
+  no_menu_key_this_time = no_menu_key;
+  int ret = core_keydown(key,enqueued,repeat);
+  no_menu_key_this_time = 0;
+  return ret;
+}
+
+
+int is_clk24() {
+  return mode_time_clk24;
+}
+
+int is_dmy() {
+  return flags.f.dmy;
+}
+
+void set_clk24(int val) {
+  mode_time_clk24 = val;
+}
+
+void set_dmy(int val) {
+  flags.f.dmy = val;
+}
+
+
+int is_wide_print() {
+  return flags.f.double_wide_print;
+}
+
+
+int get_reflcd_mask() {
+  return vvars[VV_RefLCD].val;
+}
+
+void set_reflcd_mask(int reflcd) {
+#ifdef ARM
+  vvars[VV_RefLCD].val = reflcd;
+#endif
+}
+
+
+extern unsigned int printer_delay;
+
+/* docmd_delay()...
+#ifdef BCD_MATH
+            int4 d = to_int4(x*1000);
+#else
+            int4 d = (int4)floor(x*1000+0.5);
+#endif
+            printer_delay = (unsigned int)d;
+            if ( printer_delay > 1950 ) printer_delay = 1950;
+*/
+
+unsigned int core_printer_delay() {
+  return printer_delay;
+}
+
+void core_set_printer_delay(unsigned int val) {
+  if ( val > 1950 ) val = 1950;
+  printer_delay = val;
+}
+
+// Temporary version hack - Version info isn't available in Free42 interface :(
+#include "../VERSION.rc"
+
+const char * free42_version_str() {
+  return FREE42_VERSION_1;
+}
+
+int get_calc_flag(int flag_nr) {
+  return flags.farray[flag_nr];
+}
+
+void set_calc_flag(int flag_nr, int val) {
+  flags.farray[flag_nr] = val ? 1 : 0;
+}
+
+
+} // extern "C"
+
+
Index: common/core_aux.h
===================================================================
--- common/core_aux.h	(nonexistent)
+++ common/core_aux.h	(working copy)
@@ -0,0 +1,109 @@
+#ifndef __CORE_AUX_H__
+#define __CORE_AUX_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef enum {
+  REG_X = 1,
+  REG_Y,
+  REG_Z,
+  REG_T,
+  REG_LX,
+  REG_A
+} reg_id_t;
+
+
+void set_graphics_mode(int gm);
+int graphics_mode();
+int gr_MAXX();
+int gr_MAXY();
+
+
+// Convert register to string
+int reg2str(char *buf, int buflen, reg_id_t reg_id);
+
+
+// Avoid Free42 functionality disablig auto-started program
+// after ON to turn the calc back to OFF
+void clear_no_keystrokes_yet();
+
+// Returns mode pause state
+int is_mode_pause();
+
+// Returns mode number entry state
+int is_number_entry();
+
+// Returns wide print flag
+int is_wide_print();
+
+// Returns clk24 flag
+int is_clk24();
+
+// Returns dmy flag
+int is_dmy();
+
+// Is program mode
+int is_pgm_mode();
+
+// Set clk24 flag
+void set_clk24(int val);
+
+// Set DMY flag
+void set_dmy(int val);
+
+
+// Is goose displayed
+int is_goose();
+
+// Returns RefLCD mask for LCD update during program RUN
+int get_reflcd_mask();
+void set_reflcd_mask(int reflcd);
+
+typedef struct {
+  int pgm_line;
+  int8_t y_row;
+} pgm_info_t;
+
+void get_pgm_info(pgm_info_t * pi);
+
+typedef struct {
+  int pc;
+  int line;
+  int8_t is_end;
+  char * buf;
+  int buflen;
+} pgm_line_t;
+
+
+void pgm_line_init(pgm_line_t * p, char * buf, int buflen);
+int get_pgm_line(pgm_line_t * p, int line);
+
+
+// Returns free42 version string
+const char * free42_version_str();
+
+// Get/Set calc flag
+int get_calc_flag(int flag_nr);
+void set_calc_flag(int flag_nr, int val);
+
+// Core keydown hack to support separate menu key line
+int core_keydown_ex(int key, int *enqueued, int *repeat, int no_menu_key);
+
+// Returns printer delay set by DELAY command
+unsigned int core_printer_delay();
+void core_set_printer_delay(unsigned int val);
+
+void core_redisplay();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+char* core_display_buffer();
+
+#endif
Index: common/core_commands2.cc
===================================================================
--- common/core_commands2.cc	(revision 3)
+++ common/core_commands2.cc	(working copy)
@@ -26,6 +26,7 @@
 #include "core_math2.h"
 #include "core_sto_rcl.h"
 #include "core_variables.h"
+#include "core_aux.h"
 #include "shell.h"
 
 
@@ -691,6 +692,7 @@
         case ARGTYPE_STK: {
             vartype *v;
             switch (arg->val.stk) {
+                default:
                 case 'X': v = reg_x; break;
                 case 'Y': v = reg_y; break;
                 case 'Z': v = reg_z; break;
@@ -830,25 +832,27 @@
 static void pixel_helper(phloat dx, phloat dy) {
     dx = dx < 0 ? -floor(-dx + 0.5) : floor(dx + 0.5);
     dy = dy < 0 ? -floor(-dy + 0.5) : floor(dy + 0.5);
-    int x = dx < -132 ? -132 : dx > 132 ? 132 : to_int(dx);
-    int y = dy < -132 ? -132 : dy > 132 ? 132 : to_int(dy);
+    int const MAXX = gr_MAXX();
+    int const MAXY = gr_MAXY();
+    int x = dx < -(MAXX+1) ? -(MAXX+1) : dx > (MAXX+1) ? (MAXX+1) : to_int(dx);
+    int y = dy < -(MAXX+1) ? -(MAXX+1) : dy > (MAXX+1) ? (MAXX+1) : to_int(dy);
     int i;
     int dot = 1;
     if (x < 0) {
         x = -x;
-        if (x >= 1 && x <= 131)
-            for (i = 0; i < 16; i++)
+        if (x >= 1 && x <= MAXX)
+            for (i = 0; i < MAXY; i++)
                 draw_pixel(x - 1, i);
         dot = 0;
     }
     if (y < 0) {
         y = -y;
-        if (y >= 1 && y <= 16)
-            for (i = 0; i < 131; i++)
+        if (y >= 1 && y <= MAXY)
+            for (i = 0; i < MAXX; i++)
                 draw_pixel(i, y - 1);
         dot = 0;
     }
-    if (dot && x >= 1 && x <= 131 && y >= 1 && y <= 16)
+    if (dot && x >= 1 && x <= MAXX && y >= 1 && y <= MAXY)
         draw_pixel(x - 1, y - 1);
 }
 
@@ -1524,6 +1528,8 @@
     }
 }
 
+unsigned int printer_delay = 1800; // Default 1800ms
+
 int docmd_delay(arg_struct *arg) {
     if (reg_x->type == TYPE_REAL) {
         phloat x = ((vartype_real *) reg_x)->x;
@@ -1531,9 +1537,16 @@
             x = -x;
         if (x >= 1.95)
             return ERR_INVALID_DATA;
-        else
-            /* We don't actually use the delay value... */
+        else {
+#ifdef BCD_MATH
+            int4 d = to_int4(x*1000);
+#else
+            int4 d = (int4)floor(x*1000+0.5);
+#endif
+            printer_delay = (unsigned int)d;
+            if ( printer_delay > 1950 ) printer_delay = 1950;
             return ERR_NONE;
+        }
     } else if (reg_x->type == TYPE_STRING)
         return ERR_ALPHA_DATA_IS_INVALID;
     else
Index: common/core_commands3.cc
===================================================================
--- common/core_commands3.cc	(revision 3)
+++ common/core_commands3.cc	(working copy)
@@ -306,7 +306,7 @@
         int4 rs = right->rows * right->columns;
         int4 i;
         int inf;
-        phloat xl, yl = 0, zl = 0, xr, yr = 0, zr = 0;
+        phloat xl=0, yl = 0, zl = 0, xr = 0, yr = 0, zr = 0;
         phloat xres, yres, zres;
         vartype_realmatrix *res;
         if (ls > 3 || rs > 3)
Index: common/core_display.cc
===================================================================
--- common/core_display.cc	(revision 3)
+++ common/core_display.cc	(working copy)
@@ -23,11 +23,11 @@
 #include "core_helpers.h"
 #include "core_main.h"
 #include "core_tables.h"
+#include "core_aux.h"
 #include "core_variables.h"
 #include "shell.h"
 #include "shell_spool.h"
 
-
 /********************/
 /* HP-42S font data */
 /********************/
@@ -42,8 +42,11 @@
 #pragma warning(disable: 4309)
 #endif
 
+#include <string.h>
+#include <stdio.h>
 
-static char bigchars[130][5] =
+
+static unsigned char bigchars[130][5] =
     {
         { 0x08, 0x08, 0x2a, 0x08, 0x08 },
         { 0x22, 0x14, 0x08, 0x14, 0x22 },
@@ -522,6 +525,12 @@
 
 static char display[272];
 
+#ifdef ARM
+char* core_display_buffer() {
+  return display;
+}
+#endif
+
 static int is_dirty = 0;
 static int dirty_top, dirty_left, dirty_bottom, dirty_right;
 
@@ -657,6 +666,9 @@
 }
 
 void clear_display() {
+#ifdef ARM
+    thell_clear_display();
+#endif
     int i;
     for (i = 0; i < 272; i++)
         display[i] = 0;
@@ -676,6 +688,11 @@
 }
 
 void draw_pixel(int x, int y) {
+#ifdef ARM
+    thell_draw_pixel(x, y);
+    if ( graphics_mode() )
+        return;
+#endif
     display[y * 17 + (x >> 3)] |= 1 << (x & 7);
     mark_dirty(y, x, y + 1, x + 1);
 }
@@ -682,10 +699,18 @@
 
 void draw_pattern(phloat dx, phloat dy, const char *pattern, int pattern_width){
     int x, y, h, v, hmin, hmax, vmin, vmax;
-    if (dx + pattern_width < 1 || dx > 131 || dy + 8 < 1 || dy > 16)
+    int const MAXX = gr_MAXX();
+    int const MAXY = gr_MAXY();
+
+    if (dx + pattern_width < 1 || dx > MAXX || dy + 8 < 1 || dy > MAXY)
         return;
     x = dx < 0 ? to_int(-floor(-dx + 0.5)) : to_int(floor(dx + 0.5));
     y = dy < 0 ? to_int(-floor(-dy + 0.5)) : to_int(floor(dy + 0.5));
+#ifdef ARM
+    thell_draw_pattern(x-1,y-1, pattern, pattern_width, (flags.f.agraph_control1<<1)|flags.f.agraph_control0);
+    if ( graphics_mode() )
+        return;
+#endif
     hmin = x < 1 ? 1 - x : 0;
     hmax = x + pattern_width > 132 ? 132 - x : pattern_width;
     vmin = y < 1 ? 1 - y : 0;
@@ -822,6 +847,9 @@
 }
 
 void draw_char(int x, int y, char c) {
+#ifdef ARM
+    thell_draw_char(x,y, c);
+#endif
     int X, Y, h, v;
     unsigned char uc = (unsigned char) c;
     if (x < 0 || x >= 22 || y < 0 || y >= 2)
@@ -856,6 +884,7 @@
         bits[i] = bigchars[uc][i];
 }
 
+
 void draw_string(int x, int y, const char *s, int length) {
     while (length != 0 && x < 22) {
         draw_char(x++, y, *s++);
@@ -887,6 +916,10 @@
     if (flags.f.prgm_mode == 1)
         highlight = 0;
 
+#ifdef ARM
+    thell_draw_menu_key(n, highlight, s, length);
+#endif
+
     if (highlight) {
         int f = smallchars_map[fatdot];
         swidth = smallchars_offset[f + 1] - smallchars_offset[f];
@@ -939,10 +972,13 @@
 }
 
 void clear_row(int row) {
+#ifdef ARM
+    thell_clear_row(row);
+#endif
     fill_rect(0, row * 8, 131, 8, 0);
 }
 
-static int prgmline2buf(char *buf, int len, int4 line, int highlight,
+int prgmline2buf(char *buf, int len, int4 line, int highlight,
                         int cmd, arg_struct *arg, bool shift_left = false,
                         bool highlight_final_end = true) {
     int bufptr = 0;
@@ -1843,6 +1879,9 @@
             }
         }
     }
+#ifdef ARM
+    thell_start_show();
+#endif
     flush_display();
 }
 
@@ -1863,13 +1902,23 @@
         flush_display();
         return;
     }
-
+#ifndef ARM
     if (flags.f.two_line_message)
         return;
+#else
+    if (flags.f.two_line_message)
+    {
+        if (!core_menu())
+            return;
+    } else {
+#endif
     if (flags.f.message)
         clear_row(1);
     else
         clear_display();
+#ifdef ARM
+    }
+#endif
 
     if (mode_commandmenu != MENU_NONE)
         menu_id = mode_commandmenu;
@@ -2302,7 +2351,11 @@
     if (cmd >= CMD_ASGN01 && cmd <= CMD_ASGN18)
         string2buf(buf, len, &bufptr, "ASSIGN ", 7);
     else
+#ifdef ARM
+        cmdnam2buf(buf, len, &bufptr, cmdspec->name, cmdspec->name_length);
+#else
         string2buf(buf, len, &bufptr, cmdspec->name, cmdspec->name_length);
+#endif
 
     if (cmd == CMD_XROM) {
         int n = xrom_arg & 0x7FF;
Index: common/core_globals.cc
===================================================================
--- common/core_globals.cc	(revision 3)
+++ common/core_globals.cc	(working copy)
@@ -35,7 +35,7 @@
 #endif
 
 
-error_spec errors[] = {
+const error_spec errors[] = {
     { /* NONE */                   NULL,                       0 },
     { /* ALPHA_DATA_IS_INVALID */  "Alpha Data Is Invalid",   21 },
     { /* INSUFFICIENT_MEMORY */    "Insufficient Memory",     19 },
@@ -72,7 +72,7 @@
 };
 
 
-menu_spec menus[] = {
+const menu_spec menus[] = {
     { /* MENU_ALPHA1 */ MENU_NONE, MENU_ALPHA2, MENU_ALPHA2,
                       { { MENU_ALPHA_ABCDE1, 5, "ABCDE" },
                         { MENU_ALPHA_FGHI,   4, "FGHI"  },
@@ -1339,7 +1339,7 @@
     prgms_capacity = prgms_count;
     for (i = 0; i < prgms_count; i++) {
         prgms[i].capacity = prgms[i].size;
-        prgms[i].text = (unsigned char *) malloc(prgms[i].size);
+        prgms[i].text = (unsigned char *) mallocU(prgms[i].size);
         // TODO - handle memory allocation failure
     }
     for (i = 0; i < prgms_count; i++) {
@@ -1560,7 +1560,7 @@
         prgm_struct *newprgms;
         int i;
         prgms_capacity += 10;
-        newprgms = (prgm_struct *) malloc(prgms_capacity * sizeof(prgm_struct));
+        newprgms = (prgm_struct *) mallocU(prgms_capacity * sizeof(prgm_struct));
         // TODO - handle memory allocation failure
         for (i = 0; i < prgms_count; i++)
             newprgms[i] = prgms[i];
@@ -1755,7 +1755,7 @@
                     int i;
                     labels_capacity += 50;
                     newlabels = (label_struct *)
-                                malloc(labels_capacity * sizeof(label_struct));
+                                mallocU(labels_capacity * sizeof(label_struct));
                     // TODO - handle memory allocation failure
                     for (i = 0; i < labels_count; i++)
                         newlabels[i] = labels[i];
@@ -1837,7 +1837,7 @@
         newsize = prgm->size + nextprgm->size;
         if (newsize > prgm->capacity) {
             int4 newcapacity = (newsize + 511) & ~511;
-            unsigned char *newtext = (unsigned char *) malloc(newcapacity);
+            unsigned char *newtext = (unsigned char *) mallocU(newcapacity);
             // TODO - handle memory allocation failure
             for (pos = 0; pos < prgm->size; pos++)
                 newtext[pos] = prgm->text[pos];
@@ -1921,7 +1921,7 @@
             int i;
             prgms_capacity += 10;
             new_prgms = (prgm_struct *)
-                            malloc(prgms_capacity * sizeof(prgm_struct));
+                            mallocU(prgms_capacity * sizeof(prgm_struct));
             // TODO - handle memory allocation failure
             for (i = 0; i <= current_prgm; i++)
                 new_prgms[i] = prgms[i];
@@ -1938,7 +1938,7 @@
         new_prgm = prgm + 1;
         new_prgm->size = prgm->size - pc;
         new_prgm->capacity = (new_prgm->size + 511) & ~511;
-        new_prgm->text = (unsigned char *) malloc(new_prgm->capacity);
+        new_prgm->text = (unsigned char *) mallocU(new_prgm->capacity);
         // TODO - handle memory allocation failure
         for (i = pc; i < prgm->size; i++)
             new_prgm->text[i - pc] = prgm->text[i];
@@ -2010,7 +2010,7 @@
     if (bufptr + prgm->size > prgm->capacity) {
         unsigned char *newtext;
         prgm->capacity += 512;
-        newtext = (unsigned char *) malloc(prgm->capacity);
+        newtext = (unsigned char *) mallocU(prgm->capacity);
         // TODO - handle memory allocation failure
         for (pos = 0; pos < pc; pos++)
             newtext[pos] = prgm->text[pos];
Index: common/core_globals.h
===================================================================
--- common/core_globals.h	(revision 3)
+++ common/core_globals.h	(working copy)
@@ -67,7 +67,7 @@
     int length;
 } error_spec;
 
-extern error_spec errors[];
+extern const error_spec errors[];
 
 
 /*************/
@@ -198,7 +198,7 @@
     menu_item_spec child[6];
 } menu_spec;
 
-extern menu_spec menus[];
+extern const menu_spec menus[];
 
 
 /***********************/
Index: common/core_helpers.cc
===================================================================
--- common/core_helpers.cc	(revision 3)
+++ common/core_helpers.cc	(working copy)
@@ -25,7 +25,24 @@
 #include "core_variables.h"
 #include "shell.h"
 
+#ifdef ARM
 
+void* unguarded_malloc(size_t size, const char* file, int line) {
+  void * p = malloc(size);
+  if (p == NULL)
+    shell_malloc_fail(size,file,line);
+  return p;
+}
+
+void* unguarded_realloc(void *ptr, size_t size, const char* file, int line) {
+  void * p = realloc(ptr, size);
+  if (p == NULL)
+    shell_malloc_fail(size,file,line);
+  return p;
+}
+
+#endif
+
 int resolve_ind_arg(arg_struct *arg) {
     vartype *v;
     switch (arg->type) {
@@ -505,6 +522,7 @@
         }
     }
 
+#ifndef ARM
     /* Handle text-mode double-width printing by inserting spaces and
      * underscores; do text-mode printing */
     if (flags.f.double_wide_print) {
@@ -515,6 +533,7 @@
         }
         bufptr *= 2;
     }
+#endif
 
     shell_print(buf, bufptr, bitmap, 18, 0, 0, 143, 9);
 }
@@ -1026,6 +1045,15 @@
         buf[buflen - 1] = 26;
 }
 
+void cmdnam2buf(char *buf, int buflen, int *bufptr, const char *s, int slen) {
+    int i;
+    for (i = 0; i < slen; i++)
+        if (*bufptr < buflen)
+            buf[(*bufptr)++] = s[i] & 0x7f;
+        else
+            buf[buflen - 1] = 26;
+}
+
 void string2buf(char *buf, int buflen, int *bufptr, const char *s, int slen) {
     int i;
     for (i = 0; i < slen; i++)
Index: common/core_helpers.h
===================================================================
--- common/core_helpers.h	(revision 3)
+++ common/core_helpers.h	(working copy)
@@ -85,6 +85,7 @@
 
 void char2buf(char *buf, int buflen, int *bufptr, char c);
 void string2buf(char *buf, int buflen, int *bufptr, const char *s, int slen);
+void cmdnam2buf(char *buf, int buflen, int *bufptr, const char *s, int slen);
 int uint2string(uint4 n, char *buf, int buflen);
 int int2string(int4 n, char *buf, int buflen);
 int vartype2string(const vartype *v, char *buf, int buflen, int max_mant_digits = 12);
@@ -92,5 +93,14 @@
 int easy_phloat2string(phloat d, char *buf, int buflen, int base_mode);
 int ip2revstring(phloat d, char *buf, int buflen);
 
+#ifdef ARM
+#define mallocU(x) unguarded_malloc(x,__FILE__,__LINE__)
+#define reallocU(x,y) unguarded_realloc(x,y,__FILE__,__LINE__)
+void* unguarded_malloc(size_t size, const char* file, int line);
+void* unguarded_realloc(void *ptr, size_t size, const char* file, int line);
+#else
+#define mallocU  malloc
+#define reallocU realloc
+#endif
 
 #endif
Index: common/core_keydown.cc
===================================================================
--- common/core_keydown.cc	(revision 3)
+++ common/core_keydown.cc	(working copy)
@@ -28,10 +28,11 @@
 #include "core_variables.h"
 #include "shell.h"
 
+int no_menu_key_this_time = 0;
 
 static int is_number_key(int shift, int key) {
     int *menu = get_front_menu();
-    if (menu != NULL && *menu == MENU_BASE_A_THRU_F
+    if (menu != NULL && *menu == MENU_BASE_A_THRU_F && !no_menu_key_this_time
             && (key == KEY_SIGMA || key == KEY_INV || key == KEY_SQRT
                 || key == KEY_LOG || key == KEY_LN || key == KEY_XEQ))
         return 1;
@@ -92,6 +93,8 @@
 void keydown(int shift, int key) {
     int *menu;
 
+    flags.farray[64] = shift;
+
     pending_command = CMD_NONE;
 
     if (key >= 1024) {
@@ -534,6 +537,9 @@
         char2buf(buf, 100, &bufptr, '?');
     } else
         string2buf(buf, 100, &bufptr, "x\200", 2);
+#ifdef ARM
+    int promptlen = bufptr;
+#endif
     string2buf(buf, 100, &bufptr, cmdline, cmdline_length);
     char2buf(buf, 100, &bufptr, '_');
 
@@ -544,6 +550,9 @@
         draw_char(0, cmdline_row, 26);
         draw_string(1, cmdline_row, buf + bufptr - 21, 21);
     }
+#ifdef ARM
+    thell_edit_number(buf,promptlen, cmdline, cmdline_length);
+#endif
     flush_display();
     return;
 }
@@ -1794,6 +1803,7 @@
         do_interactive(command);
 }
 
+
 void keydown_normal_mode(int shift, int key) {
     int command;
 
@@ -1849,11 +1859,13 @@
         return;
     }
 
-    if ((mode_appmenu != MENU_NONE
+    if ( !no_menu_key_this_time &&
+        (mode_appmenu != MENU_NONE
                 || mode_plainmenu != MENU_NONE
                 || mode_transientmenu != MENU_NONE)
             && mode_alphamenu == MENU_NONE
-            && mode_commandmenu == MENU_NONE) {
+            && mode_commandmenu == MENU_NONE)
+    {
         int menukey = find_menu_key(key);
         int menu, level;
         if (mode_transientmenu != MENU_NONE) {
Index: common/core_main.cc
===================================================================
--- common/core_main.cc	(revision 3)
+++ common/core_main.cc	(working copy)
@@ -80,7 +80,7 @@
                        flags.f.rad || flags.f.grad);
 }
 
-#if defined(IPHONE) || defined(ANDROID)
+#if defined(IPHONE) || defined(ANDROID) || defined(ARM)
 void core_enter_background() {
     if (mode_interruptible != NULL)
         stop_interruptible();
@@ -596,6 +596,63 @@
     return mode_running;
 }
 
+#ifdef ARM
+
+// Use old non-dynamically allocated version
+int core_list_programs(char *buf, int bufsize) {
+    int lastidx = -1;
+    int bufptr = 0;
+    int label;
+    int count = 0;
+    for (label = 0; label < labels_count; label++) {
+        int len = labels[label].length;
+        char name[51];
+        int namelen = 0;
+        int end = 0;
+        int i;
+
+        if (len == 0) {
+            if (labels[label].prgm == lastidx)
+                continue;
+            if (label == labels_count - 1) {
+                string2buf(name, 21, &namelen, ".END.", 5);
+                namelen = 5;
+            } else {
+                string2buf(name, 21, &namelen, "END", 3);
+                namelen = 3;
+            }
+            end = 1;
+        } else {
+            name[namelen++] = '"';
+            namelen += hp2ascii(name + namelen, labels[label].name, len);
+            name[namelen++] = '"';
+            end = labels[label + 1].length == 0;
+        }
+
+        lastidx = labels[label].prgm;
+
+        if (bufptr + namelen + 1 >= bufsize) {
+            if (bufptr > 0 && buf[bufptr - 1] != 0) {
+                buf[bufptr - 1] = 0;
+                count++;
+            }
+            return count;
+        }
+        for (i = 0; i < namelen; i++)
+            buf[bufptr++] = name[i];
+        if (end) {
+            buf[bufptr++] = 0;
+            count++;
+        } else {
+            buf[bufptr++] = ' ';
+        }
+    }
+    return count;
+}
+
+
+#else
+
 char *core_list_programs() {
     int bufsize = 1024;
     char *buf = (char *) malloc(bufsize);
@@ -661,6 +718,8 @@
     return buf;
 }
 
+#endif
+
 static void export_hp42s(int index) {
     int4 pc = 0;
     int cmd;
@@ -1585,7 +1644,7 @@
 
     int pos = 0;
     int byte1, byte2, suffix;
-    int cmd, flag, str_len;
+    int cmd, flag, str_len = 0;
     int done_flag = 0;
     arg_struct arg;
     int assign = 0;
Index: common/core_main.h
===================================================================
--- common/core_main.h	(revision 3)
+++ common/core_main.h	(working copy)
@@ -37,7 +37,7 @@
  */
 void core_init(int read_state, int4 version);
 
-#if defined(IPHONE) || defined(ANDROID)
+#if defined(IPHONE) || defined(ANDROID) || defined(ARM)
 
 /* core_enter_background()
  *
@@ -231,7 +231,13 @@
  * This function will return NULL if it fails to allocate the buffer.
  * The caller should free() the buffer once it is finished using it.
  */
+
+#ifdef ARM
+// Use old non-dynamically allocated version
+int core_list_programs(char *buf, int bufsize);
+#else
 char *core_list_programs();
+#endif
 
 /* core_program_size()
  * This function returns the size of a program, specified by its index.
Index: common/core_phloat.cc
===================================================================
--- common/core_phloat.cc	(revision 3)
+++ common/core_phloat.cc	(working copy)
@@ -959,7 +959,13 @@
 
 #endif // BCD_MATH
 
+#define P2S_BIN_DIGITS     36
+#define P2S_MAX_BIN    (  (1LL<<(P2S_BIN_DIGITS-1))-1 )
+#define P2S_MIN_BIN    ( -(1LL<<(P2S_BIN_DIGITS-1))   )
+//#define P2S_MAX_BIN  34359738367.0
+//#define P2S_MIN_BIN -34359738368.0
 
+
 int phloat2string(phloat pd, char *buf, int buflen, int base_mode, int digits,
                          int dispmode, int thousandssep, int max_mant_digits) {
     if (pd == 0)
@@ -985,10 +991,10 @@
     if (base_mode == 1 && base != 10 || base_mode == 2 && base == 2) {
         int8 n;
         int inexact, shift;
-        char binbuf[36];
+        char binbuf[P2S_BIN_DIGITS];
         int binbufptr = 0;
 
-        if (pd > 34359738367.0 || pd < -34359738368.0) {
+        if (pd > P2S_MAX_BIN || pd < P2S_MIN_BIN) { // (pd > 34359738367.0 || pd < -34359738368.0)
             if (base_mode == 2)
                 goto decimal_after_all;
             else {
@@ -1028,8 +1034,15 @@
     char decstr[50];
 
 #ifndef BCD_MATH
+    //union { double d; unsigned char c[8]; } u;
+    //u.d = to_double(pd);
     double d = to_double(pd);
-    sprintf(decstr, "%.15e", d);
+    //sprintf(decstr, "%.15e", d); // Original code
+    BID_UINT128 dd;
+    binary64_to_bid128(&dd, &d);
+    bid128_to_string(decstr, &dd);
+    //printf("%s\n", decstr);
+    //for(int i=0; i<8; i++) printf("%02x", u.c[i]); printf("\n");
 #else
     bid128_to_string(decstr, &pd.val);
 #endif
Index: common/core_variables.cc
===================================================================
--- common/core_variables.cc	(revision 3)
+++ common/core_variables.cc	(working copy)
@@ -21,6 +21,7 @@
 #include "core_helpers.h"
 #include "core_display.h"
 #include "core_variables.h"
+#include "core_aux.h"
 
 
 // We cache vartype_real, vartype_complex, and vartype_string instances, to
@@ -394,7 +395,7 @@
 vartype *recall_var(const char *name, int namelength) {
     int varindex = lookup_var(name, namelength);
     if (varindex == -1)
-        return NULL;
+        return recall_vvar(name, namelength);
     else
         return vars[varindex].value;
 }
@@ -403,10 +404,12 @@
     int varindex = lookup_var(name, namelength);
     int i;
     if (varindex == -1) {
+        if ( store_vvar(name, namelength, value) )
+            return;
         if (vars_count == vars_capacity) {
             vars_capacity += 25;
             vars = (var_struct *)
-                        realloc(vars, vars_capacity * sizeof(var_struct));
+                        reallocU(vars, vars_capacity * sizeof(var_struct));
             // TODO - handle memory allocation failure
         }
         varindex = vars_count++;
Index: common/core_variables.h
===================================================================
--- common/core_variables.h	(revision 3)
+++ common/core_variables.h	(working copy)
@@ -39,4 +39,8 @@
 int contains_no_strings(const vartype_realmatrix *rm);
 int matrix_copy(vartype *dst, const vartype *src);
 
+// Returns: 1=variable consumed, 0=unknown variable
+int store_vvar(const char *name, int namelength, vartype *value);
+vartype *recall_vvar(const char *name, int namelength);
+
 #endif
Index: common/free42.h
===================================================================
--- common/free42.h	(revision 3)
+++ common/free42.h	(working copy)
@@ -85,7 +85,6 @@
 #endif
 
 
-#define uint unsigned int
 
 /* Magic number and version number for the state file.
  * State file versions correspond to application releases as follows:
Index: common/shell.h
===================================================================
--- common/shell.h	(revision 3)
+++ common/shell.h	(working copy)
@@ -241,4 +241,32 @@
  */
 void shell_log(const char *message);
 
+#if defined(ARM)
+/* shell_malloc_fail()
+ * 
+ * Called when un-guarded malloc fails.
+ */
+void shell_malloc_fail(size_t size, const char * file, int line);
+
+double shell_vbat();
+int shell_dev_id();
+void shell_force_lcd_refresh(int what);
+
+// Text interface functions
+void thell_draw_menu_key(int n, int highlight, const char *s, int length);
+void thell_draw_char(int x, int y, char c);
+
+// Mode: 0=or, 1=set, 2=and_not, 3=xor 
+void thell_draw_pattern(int x, int y, const char * pattern, int pattern_width, int mode);
+void thell_draw_pixel(int x, int y);
+
+void thell_clear_display();
+void thell_clear_row(int row);
+
+void thell_start_show();
+
+void thell_edit_number(const char * prompt, int prompt_len, const char * line, int line_length);
+
 #endif
+
+#endif
Index: common/shell_loadimage.cc
===================================================================
--- common/shell_loadimage.cc	(revision 3)
+++ common/shell_loadimage.cc	(working copy)
@@ -22,6 +22,7 @@
 
 
 #include "shell_skin.h"
+#include "core_helpers.h"
 
 
 typedef struct {
@@ -122,7 +123,7 @@
      * slightly over 4:1 (wide), etc.
      */
 
-    pm->cmap = (SkinColor *) malloc(256 * sizeof(SkinColor));
+    pm->cmap = (SkinColor *) mallocU(256 * sizeof(SkinColor));
     // TODO - handle memory allocation failure
     if (has_global_cmap) {
         for (i = 0; i < ncolors; i++) {
@@ -185,7 +186,7 @@
     }
 
     size = pm->bytesperline * pm->height;
-    pm->pixels = (unsigned char *) malloc(size);
+    pm->pixels = (unsigned char *) mallocU(size);
     // TODO - handle memory allocation failure
     memset(pm->pixels, pm->depth == 1 ? background * 255 : background, size);
 
@@ -251,7 +252,7 @@
                 /* Using local color map */
                 lbpp = (info & 7) + 1;
                 lncolors = 1 << lbpp;
-                lcmap = (SkinColor *) malloc(256 * sizeof(SkinColor));
+                lcmap = (SkinColor *) mallocU(256 * sizeof(SkinColor));
                 // TODO - handle memory allocation failure
                 for (i = 0; i < lncolors; i++) {
                     int r, g, b;
@@ -267,7 +268,7 @@
                     int newbytesperline = pm->width * 4;
                     int v, h;
                     unsigned char *newpixels = (unsigned char *)
-                                malloc(newbytesperline * pm->height);
+                                mallocU(newbytesperline * pm->height);
                     // TODO - handle memory allocation failure
                     for (v = 0; v < pm->height; v++)
                         for (h = 0; h < pm->width; h++) {
Index: console/42s.curs
===================================================================
--- console/42s.curs	(nonexistent)
+++ console/42s.curs	(working copy)
@@ -0,0 +1,31 @@
+
+   +--------+--------+--------+--------+--------+--------+
+ s |  Sum-  |  y^x   |  x^2   |  10^x  |  e^x   |  GTO   |
+   |  Sum+  |  1/x   |  Sqrt  |  Log   |  Ln    |  XEQ   |
+   |  [q]   |  [w]   |  [e]   |  [r]   |  [t]   |  [y]   |
+   +--------+--------+--------+--------+--------+--------+
+ s | Complx |   %    |  Pi    |  ASIN  |  ACOS  |  ATAN  |
+   |  STO   |  RCL   |  R_dwn |   SIN  |   COS  |   TAN  |
+   |  [a]   |  [s]   |  [d]   |   [f]  |   [g]  |   [h]  |
+   +--------+--------+--------+--------+--------+--------+
+ s |     Alpha       | Last x |  MODES |  DISP  |  CLEAR |
+   |     ENTER       |  x<>y  |  +/-   |   E    |   <--  |
+   |       13        |  [c]   |  [v]   |  [b]   |        |
+   +--------+--------+-+------+----+---+-------++--------+
+ s |   BST  | Solver   |  Int f(x) |  Matrix   |  STAT   | 
+   |   Up   |    7     |     8     |     9     |   /     | 
+   |        |          |           |           |         | 
+   +--------+----------+-----------+-----------+---------+
+ s |   SST  |  BASE    |  CONVERT  |  FLAGS    |  PROB   | 
+   |  Down  |    4     |     5     |     6     |    *    | 
+   |        |          |           |           |         | 
+   +--------+----------+-----------+-----------+---------+
+ s |        | ASSIGN   |  CUSTOM   |  PGM.FCN  |  PRINT  | 
+   |  SHIFT |    1     |     2     |     3     |    -    | 
+   |  [tab] |          |           |           |         | 
+   +--------+----------+-----------+-----------+---------+
+ s |  OFF   |  TOP.FCN |   SHOW    |   PRGM    | CATALOG | 
+   |  EXIT  |    0     |     .     |    R/S    |    +    | 
+   |  [o]   |          |           |    [p]    |         | 
+   +--------+----------+-----------+-----------+---------+
+
Index: console/Makefile
===================================================================
--- console/Makefile	(nonexistent)
+++ console/Makefile	(working copy)
@@ -0,0 +1,153 @@
+###############################################################################
+# Free42 -- an HP-42S calculator simulator
+# Copyright (C) 2004-2014  Thomas Okken
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License, version 2,
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see http://www.gnu.org/licenses/.
+###############################################################################
+
+VPATH += ../common
+CXXFLAGS += -I../common
+
+ifdef RELEASE
+CXXFLAGS += -DRELEASE
+endif
+
+CXXFLAGS += -MMD \
+	    -Wall \
+	    -Wno-misleading-indentation \
+	    -Wno-parentheses \
+	    -Wno-write-strings \
+	    -Wno-maybe-uninitialized \
+	    -fno-exceptions \
+	    -fno-rtti \
+	    -DVERSION="\"$(shell cat ../VERSION)\"" \
+	    -DDECIMAL_CALL_BY_REFERENCE=1 \
+	    -DDECIMAL_GLOBAL_ROUNDING=1 \
+	    -DDECIMAL_GLOBAL_ROUNDING_ACCESS_FUNCTIONS=1 \
+	    -DDECIMAL_GLOBAL_EXCEPTION_FLAGS=1 \
+	    -DDECIMAL_GLOBAL_EXCEPTION_FLAGS_ACCESS_FUNCTIONS=1 \
+	    -D_WCHAR_T_DEFINED -O2 -fdata-sections -ffunction-sections -Wl,--gc-sections -ggdb
+
+
+
+FREE42LIB = libfree42.a
+
+FREE42SRCS = keymap.cc \
+	core_main.cc core_commands1.cc core_commands2.cc \
+	core_commands3.cc core_commands4.cc core_commands5.cc \
+	core_commands6.cc core_commands7.cc core_display.cc core_globals.cc \
+	core_helpers.cc core_keydown.cc core_linalg1.cc core_linalg2.cc \
+	core_math1.cc core_math2.cc core_phloat.cc core_sto_rcl.cc \
+	core_tables.cc core_variables.cc core_aux.cc
+
+SRCS = main_con.cc 
+
+
+FREE42OBJS = $(FREE42SRCS:.cc=.o)
+OBJS = $(SRCS:.cc=.o)
+
+
+
+#LIBS := gcc111libbid-$(shell uname -m).a
+
+ifdef ARM_LIB
+CXXFLAGS += -mthumb -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DARM
+#CXXFLAGS += -mthumb -march=armv7e-m -mfloat-abi=softfp -mfpu=fpv4-sp-d16
+#CXXFLAGS += -mthumb -march=armv7e-m
+#CXXFLAGS += -DANDROID
+
+CROSS_COMPILE = arm-none-eabi-
+
+else
+
+LIBS := $(FREE42LIB) gcc111libbid-$(shell uname -m).a
+ifeq "$(shell uname -s)" "Linux"
+LDFLAGS += -Wl,--hash-style=both
+endif
+
+endif
+
+AS = $(CROSS_COMPILE)gcc
+CC = $(CROSS_COMPILE)gcc
+CXX = $(CROSS_COMPILE)g++
+LD = $(CROSS_COMPILE)gcc
+SIZE = $(CROSS_COMPILE)size
+OBJCOPY = $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CROSS_COMPILE)objdump
+RANLIB = $(CROSS_COMPILE)ranlib
+
+HOSTCXX=g++
+
+
+# -ffunction-sections -fdata-sections
+ifdef BCD_MATH
+CXXFLAGS += -DBCD_MATH
+LDFLAGS += -Wl,--gc-sections  -Wl,-Map=abcd.map
+EXE = free42dec
+else
+LDFLAGS += -Wl,--gc-sections  -Wl,-Map=abin.map
+EXE = free42bin
+endif
+
+ifdef USE_CURSES
+CXXFLAGS += -DUSE_CURSES
+LIBS += -lcurses
+endif
+
+ifdef UTF8_DISP
+CXXFLAGS += -DUTF8_DISP
+endif
+
+
+
+$(EXE): $(OBJS) $(FREE42LIB)
+	$(CXX) -o $(EXE) $(LDFLAGS) $(OBJS) $(LIBS)
+
+$(FREE42LIB): $(FREE42OBJS)
+	-rm -f $@
+	$(AR) -r $@ $(FREE42OBJS)
+	$(RANLIB) $@
+
+
+#$(SRCS) keymap2cc.cc : #symlinks
+
+.cc.o:
+	$(CXX) $(CXXFLAGS) -c -o $@ $<
+
+
+keymap2cc: keymap2cc.cc
+	$(HOSTCXX) -O2 -o $@ $<
+
+keymap.cc: keymap2cc keymap.txt
+	./keymap2cc
+
+#symlinks:
+#	for fn in `cd ../common; /bin/ls`; do ln -s ../common/$$fn; done
+#	touch symlinks
+
+clean: FORCE
+	rm -f `find . -type l` \
+		skin2cc skin2cc.exe skins.cc \
+		keymap2cc keymap2cc.exe keymap.cc \
+		*.o *.d *.i *.ii *.s symlinks core.*
+
+cleaner: FORCE
+	rm -f `find . -type l` \
+		free42bin free42bin.exe free42dec free42dec.exe \
+		skin2cc skin2cc.exe skins.cc \
+		keymap2cc keymap2cc.exe keymap.cc \
+		*.o *.d *.i *.ii *.s symlinks core.*
+
+FORCE:
+
+-include $(SRCS:.cc=.d)
Index: console/README.build
===================================================================
--- console/README.build	(nonexistent)
+++ console/README.build	(working copy)
@@ -0,0 +1,44 @@
+
+This directory contains sources and makefile for build of simple 
+testing console frontend of Free42 and for standalone ARM libraries.
+
+
+== Console application build
+
+Use make to build the application. There are some build parameters
+available:
+
+BCD_MATH=1   - (original Free42 make option) activates BCD build
+               Note that you need intel library to link the application
+
+USE_CURSES=1 - Uses curses library for direct key input. Simple
+               line interface which accepts key codes is used otherwise.
+
+UTF8_DISP=1  - Draws the LCD in block graphics instead of ASCII.
+
+
+Note that you should run 
+ make clean
+before build with different make parameters.
+
+E.g.
+make clean
+BCD_MATH=1 USE_CURSES=1 UTF8_DISP=1 make -j30
+
+Builds BCD version of Free42 with curses key read and with UTF8 display support.
+
+
+
+
+== ARM library build
+
+Add ARM toolchain to PATH and run:
+ ./armbuild
+
+Four versions of libraries are built
+
+libfree42_bcd.a      - BCD no optimizations
+libfree42_bcd_rel.a  - BCD optimized for release
+libfree42_bin.a      - BIN no optimizations
+libfree42_bin_rel.a  - BIN optimized for release
+
Index: console/armbuild
===================================================================
--- console/armbuild	(nonexistent)
+++ console/armbuild	(working copy)
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+MAKEOPT=" -j12 "
+
+rm -f libfree42_*.a
+
+type arm-none-eabi-gcc > /dev/null 2>&1
+if [ $? != 0 ]; then
+	echo "Activate ARM toolchain"
+	exit 1
+fi
+
+
+if [ ! -z "$BLD_BIN" ]; then
+	make clean
+	echo "=== ARM_LIB=1"
+	ARM_LIB=1 make $MAKEOPT libfree42.a
+	mv libfree42.a libfree42_bin.a
+
+	make clean
+	echo "=== RELEASE=1 ARM_LIB=1"
+	RELEASE=1 ARM_LIB=1 make $MAKEOPT libfree42.a
+	mv libfree42.a libfree42_bin_rel.a
+fi
+
+
+make clean
+echo "=== ARM_LIB=1 BCD_MATH=1"
+ARM_LIB=1 BCD_MATH=1 make $MAKEOPT libfree42.a
+mv libfree42.a libfree42_bcd.a
+
+make clean
+echo "=== RELEASE=1 ARM_LIB=1 BCD_MATH=1"
+RELEASE=1 ARM_LIB=1 BCD_MATH=1 make $MAKEOPT libfree42.a
+mv libfree42.a libfree42_bcd_rel.a
+

Property changes on: console/armbuild
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: console/con_curses.h
===================================================================
--- console/con_curses.h	(nonexistent)
+++ console/con_curses.h	(working copy)
@@ -0,0 +1,23 @@
+#ifndef __CON_CURSES_H__
+#define __CON_CURSES_H__
+
+#include <locale.h>
+#include <curses.h>
+
+
+
+// Handle macro collisions
+static const int KEY_ENTER_CURS = KEY_ENTER;
+static const int KEY_UP_CURS    = KEY_UP;
+static const int KEY_DOWN_CURS  = KEY_DOWN;
+static const int KEY_EXIT_CURS  = KEY_EXIT;
+
+#undef KEY_ENTER
+#undef KEY_UP
+#undef KEY_DOWN
+#undef KEY_EXIT
+
+#define KEY_TAB 9
+#define KEY_ESC 0x1b
+
+#endif
\ No newline at end of file
Index: console/keymap.txt
===================================================================
--- console/keymap.txt	(nonexistent)
+++ console/keymap.txt	(working copy)
@@ -0,0 +1,123 @@
+# Default key mapping table for Free42 (GTK version)
+#
+# Format: [Ctrl|Alt|Shift]* <KeyName> : <macro>
+# <KeyName> is a string consisting of the name of the symbolic constant as
+# defined in <gdk/gdkkeysyms.h>, with the leading "GDK_" removed; <macro> is a
+# sequence of zero or more HP-42S key codes. The key codes must be between 1
+# and 255; codes 1..37 correspond to actual keys on the calculator's keyboard,
+# while codes 38..255 can be used to refer to extra keys defined by customized
+# skins.
+#
+# Anything from a "#" until the end of the line is a comment, and is ignored.
+# White space (Space, Tab) separates tokens in the key map, but is otherwise
+# ignored.
+#
+# NOTE: Key events that translate to a single character in the printable
+# ASCII range (32..126) are matched without regard of the state of the Shift
+# and Caps Lock keys -- so you don't have to use "Shift A" to match uppercase
+# "A", etc. For other key events, shift *is* relevant (e.g. "Return" is not
+# the same as "Shift Return").
+
+F1              : 1       # menu key 1
+Shift F1        : 28 1    # menu key 1, shifted
+F2              : 2       # menu key 2
+Shift F2        : 28 2    # menu key 2, shifted
+F3              : 3       # menu key 3
+Shift F3        : 28 3    # menu key 3, shifted
+F4              : 4       # menu key 4
+Shift F4        : 28 4    # menu key 4, shifted
+F5              : 5       # menu key 5
+Shift F5        : 28 5    # menu key 5, shifted
+F6              : 6       # menu key 6
+Shift F6        : 28 6    # menu key 6, shifted
+a               : 1       # Sigma+ ("Accumulate")
+A               : 28 1    # Sigma-
+v               : 2       # 1/X ("inVerse")
+V               : 28 2    # Y^X
+q               : 3       # sqrt(X) ("sQuare root")
+Q               : 28 3    # X^2
+o               : 4       # LOG ("lOg, not Ln")
+O               : 28 4    # 10^X
+l               : 5       # LN ("Ln, not lOg")
+L               : 28 5    # E^X
+x               : 6       # XEQ
+X               : 28 6    # GTO
+m               : 7       # STO (m as in memory)
+M               : 28 7    # COMPLEX
+r               : 8       # RCL
+R               : 28 8    # %
+d               : 9       # RDN (d as in down)
+D               : 28 9    # PI
+s               : 10      # SIN
+S               : 28 10   # ASIN
+c               : 11      # COS
+C               : 28 11   # ACOS
+t               : 12      # TAN
+T               : 28 12   # ATAN
+Return          : 13      # ENTER
+KP_Enter        : 13      # ENTER
+Shift Return    : 28 13   # ALPHA
+w               : 14      # X<>Y ("sWap")
+W               : 28 14   # LASTX
+n               : 15      # +/- ("Negative")
+N               : 28 15   # MODES
+e               : 16      # E
+E               : 28 16   # DISP
+BackSpace       : 17      # <-
+Shift BackSpace : 28 17   # CLEAR
+Up              : 18      # up
+Shift Up        : 28 18   # BST
+7               : 19      # 7
+KP_7            : 19      # 7
+ampersand       : 28 19   # SOLVER
+8               : 20      # 8
+KP_8            : 20      # 8
+Alt 8           : 28 20   # Integ f(x) (note: can't use "Shift 8" because that's "*", which we use for "multiply")
+9               : 21      # 9
+KP_9            : 21      # 9
+parenleft       : 28 21   # MATRIX
+slash           : 22      # divide
+KP_Divide       : 22      # divide
+question        : 28 22   # STAT
+Down            : 23      # down
+Shift Down      : 28 23   # SST
+4               : 24      # 4
+KP_4            : 24      # 4
+dollar          : 28 24   # BASE
+5               : 25      # 5
+KP_5            : 25      # 5
+percent         : 28 25   # CONVERT
+6               : 26      # 6
+KP_6            : 26      # 6
+asciicircum     : 28 26   # FLAGS
+asterisk        : 27      # multiply
+KP_Multiply     : 27      # multiply
+Ctrl 8          : 28 27   # PROB ("*" is already shifted so we have to do something odd here)
+1               : 29      # 1
+KP_1            : 29      # 1
+exclam          : 28 29   # ASSIGN
+2               : 30      # 2
+KP_2            : 30      # 2
+at              : 28 30   # CUSTOM
+3               : 31      # 3
+KP_3            : 31      # 3
+numbersign      : 28 31   # PGM.FCN
+minus           : 32      # -
+KP_Subtract     : 32      # -
+underscore      : 28 32   # PRINT
+Escape          : 33      # EXIT
+Shift Escape    : 28 33   # OFF
+0               : 34      # 0
+KP_0            : 34      # 0
+parenright      : 28 34   # TOP.FCN
+period          : 35      # .
+comma           : 35      # .
+KP_Decimal      : 35      # .
+KP_Separator    : 35      # .
+greater         : 28 35   # SHOW
+less            : 28 35   # SHOW
+backslash       : 36      # R/S
+bar             : 28 36   # PRGM
+plus            : 37      # +
+KP_Add          : 37      # +
+equal           : 28 37   # CATALOG ("+" is already shifted so we have to do something odd here)
Index: console/main_con.cc
===================================================================
--- console/main_con.cc	(nonexistent)
+++ console/main_con.cc	(working copy)
@@ -0,0 +1,538 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef USE_CURSES
+#include "con_curses.h"
+#endif
+
+#include "core_main.h"
+#include "core_display.h"
+#include "core_helpers.h"
+
+
+
+static int ann_updown = 0;
+static int ann_shift = 0;
+static int ann_print = 0;
+static int ann_run = 0;
+static int ann_battery = 0;
+static int ann_g = 0;
+static int ann_rad = 0;
+
+
+
+int hp2ascii(char *dst, const char *src, int srclen) {
+    const char *esc;
+    unsigned char c;
+    int s, d = 0;
+    for (s = 0; s < srclen; s++) {
+        c = src[s];
+        if (c >= 130 && c != 138)
+            c &= 127;
+        switch (c) {
+            /* NOTE: this code performs the following 12 translations
+             * that are not ASCII, but seem to be widely accepted --
+             * that is, they looked OK when I tried them in several
+             * fonts in Windows and Linux, and in Memo Pad on the Palm:
+             *
+             *   0: 247 (0367) divide
+             *   1: 215 (0327) multiply
+             *   8: 191 (0277) upside-down question mark
+             *  17: 181 (0265) lowercase mu
+             *  18: 163 (0243) sterling
+             *  19: 176 (0260) degree
+             *  20: 197 (0305) Aring
+             *  21: 209 (0321) Ntilde
+             *  22: 196 (0304) Aumlaut
+             *  25: 198 (0306) AE
+             *  28: 214 (0326) Oumlaut
+             *  29: 220 (0334) Uumlaut
+             *
+             * Two additional candidates are these:
+             *
+             *  26: 133 (0205) ellipsis
+             *  31: 149 (0225) bullet
+             *
+             * I'm not using those last two because support for them is not
+             * as good: they exist in Times New Roman and Adobe Courier
+             * (tested on Windows and Linux, respectively) and on the Palm,
+             * but are missing from Windows Fixedsys (the default Notepad
+             * font, so that is a concern!) and X11 lucidatypewriter and
+             * fixed.
+             * Note that 133 and 149 are both in the 128-159 range, that
+             * is, the Ctrl+Meta range, which is unused in many fonts.
+             * Eventually, I should probably support several translation
+             * modes: raw, pure ASCII (only emit codes 32-126 and 10),
+             * non-pure as below, and more aggressive non-pure (using the
+             * ellipsis and fatdot codes, and maybe others). Then again,
+             * maybe not. :-)
+             */
+            case  0:   esc = "\367"; break;
+            case  1:   esc = "\327"; break;
+            case  2:   esc = "\\sqrt"; break;
+            case  3:   esc = "\\int"; break;
+            case  4:   esc = "\\gray1"; break;
+            case  5:   esc = "\\Sigma"; break;
+            case  6:   esc = ">"; break;
+            case  7:   esc = "\\pi"; break;
+            case  8:   esc = "\277"; break;
+            case  9:   esc = "<="; break;
+            case 11:   esc = ">="; break;
+            case 12:   esc = "!="; break;
+            case 13:   esc = "\\r"; break;
+            case 14:   esc = "v"; break;
+            case 15:   esc = "->"; break;
+            case 16:   esc = "<-"; break;
+            case 17:   esc = "\265"; break;
+            case 18:   esc = "\243"; break;
+            case 19:   esc = "\260"; break;
+            case 20:   esc = "\305"; break;
+            case 21:   esc = "\321"; break;
+            case 22:   esc = "\304"; break;
+            case 23:   esc = "\\angle"; break;
+            case 24:   esc = "E"; break;
+            case 25:   esc = "\306"; break;
+            case 26:   esc = "..."; break;
+            case 27:   esc = "\\esc"; break;
+            case 28:   esc = "\326"; break;
+            case 29:   esc = "\334"; break;
+            case 30:   esc = "\\gray2"; break;
+            case 31:   esc = "\\bullet"; break;
+            case '\\': esc = "\\\\"; break;
+            case 127:  esc = "|-"; break;
+            case 128:  esc = ":"; break;
+            case 129:  esc = "y"; break;
+            case 138:  esc = "\\LF"; break;
+            default:   dst[d++] = c; continue;
+        }
+        while (*esc != 0)
+            dst[d++] = *esc++;
+    }
+    return d;
+}
+
+
+/* === Undefined functions ... just stubs === */
+
+
+
+double shell_random_seed() {
+  return 0.78237947239847;
+}
+
+
+void shell_print(const char *text, int length,
+  const char *bits, int bytesperline,
+  int x, int y, int width, int height)
+{
+  printf("Shell print: %s\n", text);
+}
+
+
+void shell_beeper(int frequency, int duration) {
+}
+
+int shell_wants_cpu() {
+  return 0;
+}
+
+void shell_get_time_date(uint4 *tim, uint4 *date, int *weekday) {
+  *tim = 12345600;
+  *date = 20150825;
+  *weekday = 2;
+}
+
+
+uint4 shell_get_mem() {
+  return 16*1024; // Returns free mem
+}
+
+uint4 shell_milliseconds() {
+  return 1;
+}
+
+void shell_request_timeout3(int delay) {
+}
+
+void shell_delay(int duration) {
+  // usleep(duration * 1000);
+}
+
+void shell_powerdown() {
+}
+
+int4 shell_read_saved_state(void *buf, int4 bufsize) {
+  return -1;
+}
+
+
+
+
+/* ======================= */
+/* === LOCAL FUNCTIONS === */
+/* ======================= */
+
+#ifdef USE_CURSES
+void curses_init() {
+  setlocale(LC_ALL, "");
+  initscr();  noecho();  halfdelay(1);
+  nonl();
+  intrflush(stdscr, FALSE);
+  keypad(stdscr, TRUE);
+}
+void curses_end() {
+  echo(); nocbreak();
+  endwin();
+}
+int curses_map_key(int key) {
+  int calc_key = -1;
+  switch(key) {
+    case 'q': calc_key =  1; break;
+    case 'w': calc_key =  2; break;
+    case 'e': calc_key =  3; break;
+    case 'r': calc_key =  4; break;
+    case 't': calc_key =  5; break;
+    case 'y': calc_key =  6; break;
+    case 'a': calc_key =  7; break;
+    case 's': calc_key =  8; break;
+    case 'd': calc_key =  9; break;
+    case 'f': calc_key = 10; break;
+    case 'g': calc_key = 11; break;
+    case 'h': calc_key = 12; break;
+    case KEY_ENTER:
+    case 'z': calc_key = 13; break;
+    case 'x': calc_key = 13; break;
+    case 'c': calc_key = 14; break;
+    case 'v': calc_key = 15; break;
+    case 'E':
+    case 'b': calc_key = 16; break;
+    case KEY_BACKSPACE:
+    case 'n': calc_key = 17; break;
+    case KEY_UP_CURS:
+              calc_key = 18; break;
+    case KEY_DOWN_CURS:
+              calc_key = 23; break;
+    case KEY_TAB:
+              calc_key = 28; break;
+    case 'o': calc_key = 33; break;
+
+    case '0': calc_key = 34; break;
+    case '1': calc_key = 29; break;
+    case '2': calc_key = 30; break;
+    case '3': calc_key = 31; break;
+    case '4': calc_key = 24; break;
+    case '5': calc_key = 25; break;
+    case '6': calc_key = 26; break;
+    case '7': calc_key = 19; break;
+    case '8': calc_key = 20; break;
+    case '9': calc_key = 21; break;
+
+    case '/': calc_key = 22; break;
+    case '*': calc_key = 27; break;
+    case '-': calc_key = 32; break;
+    case '+': calc_key = 37; break;
+    case '.': calc_key = 35; break;
+    
+    case 'p': calc_key = 36; break;
+    default:
+      break;
+  }
+  return calc_key;
+}
+#endif
+
+
+
+
+#define LCDW 131
+#define LCDH  16
+
+char disp[LCDH][LCDW+1];
+
+
+void disp_clear() {
+  int i;
+  memset(disp, ' ', (LCDW+1)*LCDH);
+  for(i=0; i<LCDH; i++)
+    disp[i][LCDW]=0;
+}
+
+
+#if USE_CURSES
+#define NL "\r\n"
+#else
+#define NL "\n"
+#endif
+
+
+#ifdef UTF8_DISP
+
+char const* disp_char(int i) {
+  switch (i) {
+    case  0: return " ";
+    case  1: return "\xe2\x96\x80"; // 2580 - top 
+    case  2: return "\xe2\x96\x84"; // 2584 - down
+    case  3: return "\xe2\x96\x88"; // 2588 - both
+    
+    case  4: return "\xe2\x95\x90"; // 2550 - ==
+    case  5: return "\xe2\x95\x92"; // 2552 - ,=
+    case  6: return "\xe2\x95\x95"; // 2555 - =,
+    case  7: return "\xe2\x95\x98"; // 2558 - '=
+    case  8: return "\xe2\x95\x9b"; // 255b - ='
+    case  9: return "\xe2\x94\x82"; // 2502 - |
+
+    case 11: return "\xe2\x96\xbc"; // 25bc - triangle down
+    case 12: return "\xe2\x96\xb2"; // 25b2 - triangle up
+    default: break;
+  }
+  return " ";
+}
+void disp_char_print(int i) {
+  printf("%s", disp_char(i));
+}
+
+#define P  disp_char_print
+#define PC disp_char_print_cnt
+
+#endif
+
+int disp_annun() {
+  if (ann_updown) {
+#ifdef UTF8_DISP
+    P(11); P(12);
+#else
+    printf("v^");
+#endif  
+  } else
+    printf("  ");
+
+  printf("  ");
+  printf("%s", ann_shift?"SHIFT":"     ");
+  printf("  ");
+  return 11; // number of chars displayed
+}
+
+#ifdef UTF8_DISP
+
+void disp_char_print_cnt(int i, int cnt) {
+  const char * s = disp_char(i);
+  int a;
+  for(a=0; a<cnt; a++)
+    printf("%s", s);
+}
+
+
+void disp_print() {
+  int i,j;
+  P(5); PC(4,LCDW+2);  P(6); printf(NL);
+  P(9); printf(" "); i=disp_annun(); PC(0,LCDW+1-i); P(9); printf(NL);
+  P(9); PC(0,LCDW+2); P(9); printf(NL);
+  for(i=0; i<LCDH; i+=2) {
+    P(9); printf(" ");
+    for(j=0; j<LCDW; j++) {
+      int k = 0;
+      if (disp[i][j]   != ' ') k+=1;
+      if (disp[i+1][j] != ' ') k+=2;
+      P(k);
+    }
+    printf(" "); P(9); printf(NL);
+  }
+  P(7); PC(4,LCDW+2); P(8); printf(NL);
+}
+
+#else
+
+void disp_print() {
+  printf("-------------------------" NL);
+  disp_annun();
+  printf(NL);
+  int i;
+  for(i=0; i<LCDH; i++)
+    printf("%s" NL, disp[i]);
+}
+
+#endif
+
+
+
+/* --------------------------- */
+/* --- LOCAL FUNCTIONS END --- */
+/* --------------------------- */
+
+
+
+
+/* ===================== */
+/* === Ifc functions === */
+/* ===================== */
+
+
+void skin_repaint_annunciator(int which, bool state) {
+}
+
+void shell_blitter(const char *bits, int bytesperline, int x, int y, int width, int height) {
+  printf("Shell blitter" NL);
+
+  for (int v = y; v < y + height; v++) {
+    for (int h = x; h < x + width; h++) {
+      int b = bits[v * bytesperline + (h >> 3)] & (1 << (h & 7));
+      disp[v][h] = b ? '#' : ' ';
+    }
+  }
+
+  disp_print();
+}
+
+void shell_annunciators(int updn, int shf, int prt, int run, int g, int rad) {
+  printf("Shell annunciators" NL);
+    if (updn != -1 && ann_updown != updn) {
+        ann_updown = updn;
+        skin_repaint_annunciator(1, ann_updown);
+    }
+    if (shf != -1 && ann_shift != shf) {
+        ann_shift = shf;
+        skin_repaint_annunciator(2, ann_shift);
+    }
+    if (prt != -1 && ann_print != prt) {
+        ann_print = prt;
+        skin_repaint_annunciator(3, ann_print);
+    }
+    if (run != -1 && ann_run != run) {
+        ann_run = run;
+        skin_repaint_annunciator(4, ann_run);
+    }
+    if (g != -1 && ann_g != g) {
+        ann_g = g;
+        skin_repaint_annunciator(6, ann_g);
+    }
+    if (rad != -1 && ann_rad != rad) {
+        ann_rad = rad;
+        skin_repaint_annunciator(7, ann_rad);
+    }
+  disp_print();
+}
+
+int shell_low_battery() {
+  int lowbat = 0;
+  if (lowbat != ann_battery) {
+    ann_battery = lowbat;
+    skin_repaint_annunciator(5, ann_battery);
+  }
+  return lowbat;
+}
+
+int decimal_point = 1;
+
+int shell_decimal_point() {
+  return decimal_point ? 1 : 0;
+}
+
+
+
+/* ------------------------- */
+/* --- Ifc functions END --- */
+/* ------------------------- */
+
+
+void empty_keydown() {
+  int dummy1, dummy2, keep_running;
+  do {
+    printf("empty keydown:" NL);
+    keep_running = core_keydown(0, &dummy1, &dummy2);
+    printf("end of empty keydown: keep_running=%i" NL, keep_running);
+  } while (keep_running);
+}
+
+static int enqueued;
+
+
+#ifdef USE_CURSES
+
+
+
+void main_loop_curses() {
+  curses_init();
+  (void)getch(); // Just make it print :)
+  printf("%x %x" NL, KEY_UP_CURS, KEY_DOWN_CURS);
+
+  core_init(0,0);
+
+  for(;;) {
+    int e, key;
+    empty_keydown();
+
+    do {
+      e = getch();
+      if ( e == ERR ) {
+        // timeout - do some timout stuf
+        //printf("."); fflush(stdout);
+      }
+    } while ( e == ERR );
+
+    if ( e == KEY_ESC ) break;
+
+    printf("curs_key=%08x" NL,e); fflush(stdout);
+    key = curses_map_key(e);
+    if ( key > 0 ) {
+      // Key pressed
+      printf("key press %i" NL,key);
+      int repeat, keep_running;
+      keep_running = core_keydown(key, &enqueued, &repeat);
+      printf("end of keydown: keep_running=%i  enqueued=%i  repeat=%i" NL, keep_running, enqueued, repeat);
+      printf("keyup" NL);
+      keep_running = core_keyup();
+      printf("end of keyup: keep_running=%i" NL, keep_running);
+    }
+  }
+
+  curses_end();
+}
+
+#else
+
+
+#define LINELEN 256
+
+void main_loop() {
+  core_init(0,0);
+  for(;;) {
+    char s[LINELEN];
+
+    // Run until end
+    empty_keydown();
+
+    printf("> ");
+    if ( !fgets(s, LINELEN, stdin) )
+      break;
+
+    int key = atoi(s);
+    if ( key > 0 && key <= 37 ) {
+      // Press key
+      printf("key press %i\n",key);
+      int repeat, keep_running;
+      keep_running = core_keydown(key, &enqueued, &repeat);
+      printf("end of keydown: keep_running=%i  enqueued=%i  repeat=%i\n", keep_running, enqueued, repeat);
+      printf("keyup\n");
+      keep_running = core_keyup();
+      printf("end of keyup: keep_running=%i\n", keep_running);
+    }
+  }
+}
+
+
+#endif
+
+
+int main(int argc, char *argv[]) {
+  printf("Free42 console emulator\n");
+
+#ifdef USE_CURSES
+  main_loop_curses();
+#else
+  main_loop();
+#endif  
+
+  return 0;
+}
Index: gtk/Makefile
===================================================================
--- gtk/Makefile	(revision 3)
+++ gtk/Makefile	(working copy)
@@ -35,7 +35,7 @@
 	 -D_WCHAR_T_DEFINED
 
 LDFLAGS = -L/usr/X11R6/lib
-LIBS = gcc111libbid.a -lXmu $(shell pkg-config --libs gtk+-2.0)
+LIBS = gcc111libbid.a -lXmu -lX11 $(shell pkg-config --libs gtk+-2.0)
 
 ifeq "$(shell uname -s)" "Linux"
 LDFLAGS += -Wl,--hash-style=both
@@ -57,6 +57,9 @@
 	core_math1.o core_math2.o core_phloat.o core_sto_rcl.o \
 	core_tables.o core_variables.o
 
+SRCS += core_aux.cc
+OBJS += core_aux.o
+
 ifdef BCD_MATH
 CXXFLAGS += -DBCD_MATH
 EXE = free42dec
Index: gtk/Makefile.back
===================================================================
--- gtk/Makefile.back	(nonexistent)
+++ gtk/Makefile.back	(working copy)
@@ -0,0 +1,135 @@
+###############################################################################
+# Free42 -- an HP-42S calculator simulator
+# Copyright (C) 2004-2017  Thomas Okken
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License, version 2,
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see http://www.gnu.org/licenses/.
+###############################################################################
+
+CFLAGS = -MMD \
+	 -Wall \
+	 -Wno-parentheses \
+	 -Wno-write-strings \
+	 -g \
+	 -I/usr/X11R6/include \
+	 $(shell pkg-config --cflags gtk+-2.0) \
+	 -DVERSION="\"$(shell cat ../VERSION)\"" \
+	 -DDECIMAL_CALL_BY_REFERENCE=1 \
+	 -DDECIMAL_GLOBAL_ROUNDING=1 \
+	 -DDECIMAL_GLOBAL_ROUNDING_ACCESS_FUNCTIONS=1 \
+	 -DDECIMAL_GLOBAL_EXCEPTION_FLAGS=1 \
+	 -DDECIMAL_GLOBAL_EXCEPTION_FLAGS_ACCESS_FUNCTIONS=1
+
+CXXFLAGS = $(CFLAGS) \
+	 -fno-exceptions \
+	 -fno-rtti \
+	 -D_WCHAR_T_DEFINED
+
+LDFLAGS = -L/usr/X11R6/lib
+LIBS = gcc111libbid.a -lXmu -lX11 $(shell pkg-config --libs gtk+-2.0)
+
+ifeq "$(shell uname -s)" "Linux"
+LDFLAGS += -Wl,--hash-style=both
+LIBS += -lpthread
+endif
+
+SRCS = shell_main.cc shell_skin.cc skins.cc keymap.cc shell_loadimage.cc \
+	shell_spool.cc core_main.cc core_commands1.cc core_commands2.cc \
+	core_commands3.cc core_commands4.cc core_commands5.cc \
+	core_commands6.cc core_commands7.cc core_display.cc core_globals.cc \
+	core_helpers.cc core_keydown.cc core_linalg1.cc core_linalg2.cc \
+	core_math1.cc core_math2.cc core_phloat.cc core_sto_rcl.cc \
+	core_tables.cc core_variables.cc
+OBJS = shell_main.o shell_skin.o skins.o keymap.o shell_loadimage.o \
+	shell_spool.o core_main.o core_commands1.o core_commands2.o \
+	core_commands3.o core_commands4.o core_commands5.o \
+	core_commands6.o core_commands7.o core_display.o core_globals.o \
+	core_helpers.o core_keydown.o core_linalg1.o core_linalg2.o \
+	core_math1.o core_math2.o core_phloat.o core_sto_rcl.o \
+	core_tables.o core_variables.o
+
+ifdef BCD_MATH
+CXXFLAGS += -DBCD_MATH
+EXE = free42dec
+else
+EXE = free42bin
+endif
+
+ifdef FREE42_FPTEST
+CFLAGS += -DFREE42_FPTEST
+SRCS += readtest.c readtest_lines.cc
+OBJS += readtest.o readtest_lines.o
+endif
+
+ifdef AUDIO_ALSA
+# Note: the name of the libasound shared library that is usually compiled into
+# the executable is defined in the corresponding *.la file, in the 'dlname'
+# property. I suppose it would be better to grab it from there at build time,
+# rather than hard-coding it into the Makefile like this, but as long as the
+# build environment doesn't change (still Fedora 6 at the time of writing),
+# this is fine.
+CXXFLAGS += -DAUDIO_ALSA -DALSALIB="\"libasound.so.2\""
+SRCS += audio_alsa.cc
+OBJS += audio_alsa.o
+endif
+
+$(EXE): $(OBJS)
+	$(CXX) -o $(EXE) $(LDFLAGS) $(OBJS) $(LIBS)
+
+$(SRCS) skin2cc.cc keymap2cc.cc skin2cc.conf: symlinks
+
+.cc.o:
+	$(CXX) $(CXXFLAGS) -c -o $@ $<
+
+readtest.o: readtest.c
+	$(CC) $(CFLAGS) -I IntelRDFPMathLib20U1/TESTS -D__intptr_t_defined -DLINUX -c -o $@ $<
+
+skin2cc: skin2cc.cc
+	$(CXX) -o skin2cc skin2cc.cc
+
+skins.cc: skin2cc skin2cc.conf
+	./skin2cc
+
+keymap2cc: keymap2cc.cc
+	$(CXX) -o keymap2cc keymap2cc.cc
+
+keymap.cc: keymap2cc keymap.txt
+	./keymap2cc
+
+symlinks:
+	for fn in `cd ../common; /bin/ls`; do ln -s ../common/$$fn; done
+	sh ./build-intel-lib.sh
+	ln -s IntelRDFPMathLib20U1/TESTS/readtest.c
+	touch symlinks
+
+clean: FORCE
+	rm -f `find . -type l` \
+		skin2cc skin2cc.exe skins.cc \
+		keymap2cc keymap2cc.exe keymap.cc \
+	        readtest_lines.cc \
+	        gcc111libbid.a \
+		*.o *.d *.i *.ii *.s symlinks core.*
+	rm -rf IntelRDFPMathLib20U1
+
+cleaner: FORCE
+	rm -f `find . -type l` \
+		free42bin free42bin.exe free42dec free42dec.exe \
+		skin2cc skin2cc.exe skins.cc \
+		keymap2cc keymap2cc.exe keymap.cc \
+	        readtest_lines.cc \
+	        gcc111libbid.a \
+		*.o *.d *.i *.ii *.s symlinks core.*
+	rm -rf IntelRDFPMathLib20U1
+
+FORCE:
+
+-include $(SRCS:.cc=.d)
Index: gtk/makefile.patch
===================================================================
--- gtk/makefile.patch	(nonexistent)
+++ gtk/makefile.patch	(working copy)
@@ -0,0 +1,23 @@
+Index: Makefile
+===================================================================
+--- Makefile	(revision 56)
++++ Makefile	(working copy)
+@@ -35,7 +35,7 @@
+ 	 -D_WCHAR_T_DEFINED
+ 
+ LDFLAGS = -L/usr/X11R6/lib
+-LIBS = gcc111libbid.a -lXmu $(shell pkg-config --libs gtk+-2.0)
++LIBS = gcc111libbid.a -lXmu -lX11 $(shell pkg-config --libs gtk+-2.0)
+ 
+ ifeq "$(shell uname -s)" "Linux"
+ LDFLAGS += -Wl,--hash-style=both
+@@ -57,6 +57,9 @@
+ 	core_math1.o core_math2.o core_phloat.o core_sto_rcl.o \
+ 	core_tables.o core_variables.o
+ 
++SRCS += core_aux.cc
++OBJS += core_aux.o
++
+ ifdef BCD_MATH
+ CXXFLAGS += -DBCD_MATH
+ EXE = free42dec
Index: gtk/mk_all
===================================================================
--- gtk/mk_all	(nonexistent)
+++ gtk/mk_all	(working copy)
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+make clean
+make -j16
+
+make clean
+BCD_MATH=1 make -j16
+
+make clean
+

Property changes on: gtk/mk_all
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
