summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRr422018-06-25 09:51:09 +0530
committerRr422018-06-25 09:51:09 +0530
commit64c5d19d9febf624c6e5e7f586b781ee66097761 (patch)
tree06fc93609efb6ab2eb84635be2826560a955dfe9
parent27ba12ab2e6014f80b7391a5f765f6cd657f5707 (diff)
downloadLDMicroGtk-64c5d19d9febf624c6e5e7f586b781ee66097761.tar.gz
LDMicroGtk-64c5d19d9febf624c6e5e7f586b781ee66097761.tar.bz2
LDMicroGtk-64c5d19d9febf624c6e5e7f586b781ee66097761.zip
Fixed bug where the status bar did not show all statuses.
-rw-r--r--ldmicro/iolist.cpp6
-rw-r--r--ldmicro/ldmicro.cpp2
-rw-r--r--ldmicro/lib/linuxUI/linuxLD.h2
-rw-r--r--ldmicro/maincontrols.cpp183
-rw-r--r--ldmicro/miscutil.cpp48
-rw-r--r--ldmicro/simulate.cpp1090
6 files changed, 712 insertions, 619 deletions
diff --git a/ldmicro/iolist.cpp b/ldmicro/iolist.cpp
index e2fc032..ca24042 100644
--- a/ldmicro/iolist.cpp
+++ b/ldmicro/iolist.cpp
@@ -413,8 +413,8 @@ void SaveIoListToFile(FILE *f)
// A little toolbar-style window that pops up to allow the user to set the
// simulated value of an ADC pin.
//-----------------------------------------------------------------------------
-// void ShowAnalogSliderPopup(char *name)
-// {
+void ShowAnalogSliderPopup(char *name)
+{
// WNDCLASSEX wc;
// memset(&wc, 0, sizeof(wc));
// wc.cbSize = sizeof(wc);
@@ -513,7 +513,7 @@ void SaveIoListToFile(FILE *f)
// EnableWindow(MainWindow, TRUE);
// DestroyWindow(AnalogSliderMain);
// ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
-// }
+}
//-----------------------------------------------------------------------------
// Window proc for the contacts dialog box
diff --git a/ldmicro/ldmicro.cpp b/ldmicro/ldmicro.cpp
index dd40cd7..e975429 100644
--- a/ldmicro/ldmicro.cpp
+++ b/ldmicro/ldmicro.cpp
@@ -560,7 +560,7 @@ cmp:
break;
case MNU_SIMULATION_MODE:
- // ToggleSimulationMode();
+ ToggleSimulationMode();
break;
case MNU_START_SIMULATION:
diff --git a/ldmicro/lib/linuxUI/linuxLD.h b/ldmicro/lib/linuxUI/linuxLD.h
index 23a8942..50ffabb 100644
--- a/ldmicro/lib/linuxUI/linuxLD.h
+++ b/ldmicro/lib/linuxUI/linuxLD.h
@@ -70,7 +70,7 @@ typedef cairo_t *HCRDC;
typedef GtkWidget *HWID;
typedef GtkWidget *HMENU;
typedef GtkWindow *HWND;
-typedef GtkListStore *HLIST;
+typedef GtkTreeModel *HLIST;
typedef GtkApplication *HAPP;
typedef GtkTreeViewColumn *HTVC;
typedef GdkPixbuf *HICON;
diff --git a/ldmicro/maincontrols.cpp b/ldmicro/maincontrols.cpp
index 93136d5..4f04a17 100644
--- a/ldmicro/maincontrols.cpp
+++ b/ldmicro/maincontrols.cpp
@@ -110,7 +110,7 @@ int ScrollHeight;
BOOL NeedHoriz;
// status bar at the bottom of the screen, to display settings
-static HMENU StatusBar;
+static HMENU StatusBar[3];
// have to get back to the menus to gray/ungray, check/uncheck things
static HMENU FileMenu;
@@ -131,7 +131,6 @@ static int IoListSelectionPoint;
static BOOL IoListOutOfSync;
int IoListHeight;
int IoListTop;
-GtkTreeIter* iter = new GtkTreeIter;
GtkTreeModel **IoListPtr = (GtkTreeModel**)GTK_TREE_MODEL (IoList);
// whether the simulation is running in real time
@@ -347,12 +346,15 @@ HMENU MakeMainWindowMenus(void)
gtk_menu_shell_append (GTK_MENU_SHELL (Settings), MicroControllerMenu);
// Appending the microcontroller names to "Microcontroller" item
+ GSList* mcuList = NULL;
for (i = 0; i < NUM_SUPPORTED_MCUS; i++){
- ProcessorMenuItems[i] = gtk_check_menu_item_new_with_label (SupportedMcus[i].mcuName);
+ ProcessorMenuItems[i] = gtk_radio_menu_item_new_with_label (mcuList, SupportedMcus[i].mcuName);
+ mcuList = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (ProcessorMenuItems[i]));
gtk_menu_shell_append (GTK_MENU_SHELL (ProcessorMenu), ProcessorMenuItems[i]);
}
- ProcessorMenuItems[NUM_SUPPORTED_MCUS] = gtk_check_menu_item_new_with_label ("(no microcontroller)");
+ ProcessorMenuItems[NUM_SUPPORTED_MCUS] = gtk_radio_menu_item_new_with_label (mcuList, "(no microcontroller)");
+ mcuList = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (ProcessorMenuItems[NUM_SUPPORTED_MCUS]));
gtk_menu_shell_append (GTK_MENU_SHELL (ProcessorMenu), ProcessorMenuItems[NUM_SUPPORTED_MCUS]);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(MicroControllerMenu), ProcessorMenu);
@@ -526,7 +528,7 @@ void MakeMainWindowControls(void)
/// Pane to separate Scrolled Window and other widgets
HWID pane = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
- IoList = gtk_list_store_new (5,
+ IoList = (GtkTreeModel*)gtk_list_store_new (5,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
@@ -598,16 +600,45 @@ void MakeMainWindowControls(void)
gtk_paned_pack2 (GTK_PANED(pane), view, FALSE, FALSE);
gtk_paned_set_position (GTK_PANED (pane), 400);
gtk_grid_attach (GTK_GRID (grid), pane, 0, 0, 1, 1);
+
+ gtk_box_pack_start(GTK_BOX(PackBoxMenu), grid, FALSE, TRUE, 0);
- /// Creating Status Bar and attaching to grid
- StatusBar = gtk_statusbar_new();
- gtk_statusbar_push (GTK_STATUSBAR (StatusBar),
- gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar),
+ /// Grid for status bars
+ HWID StatusGrid = gtk_grid_new();
+ /// Creating Status Bar 1 and attaching to grid
+ StatusBar[0] = gtk_statusbar_new();
+
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[0]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[0]),
"Introduction"), "LDMicro Started");
- /// Appneding Status Bar to box which is then added to Main Window
- gtk_box_pack_start(GTK_BOX(PackBoxMenu), grid, FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(PackBoxMenu), StatusBar, FALSE, FALSE, 0);
+ /// Appneding Status Bar 1 to the status grid
+ gtk_grid_attach (GTK_GRID (StatusGrid), StatusBar[0], 0, 0, 1, 1);
+
+ /// Creating Status Bar 2 and attaching to grid
+ StatusBar[1] = gtk_statusbar_new();
+
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[1]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[1]),
+ "Introduction"), "LDMicro Started");
+
+ /// Appneding Status Bar 2 to the status box
+ gtk_grid_attach (GTK_GRID (StatusGrid), StatusBar[1], 1, 0, 1, 1);
+
+ /// Creating Status Bar 3 and attaching to grid
+ StatusBar[2] = gtk_statusbar_new();
+
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[2]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[2]),
+ "Introduction"), "LDMicro Started");
+
+ /// Appneding Status Bar 3 to the status box
+ gtk_grid_attach (GTK_GRID (StatusGrid), StatusBar[2], 2, 0, 1, 1);
+
+ /// Attach status grid to box
+ gtk_box_pack_start(GTK_BOX(PackBoxMenu), StatusGrid, FALSE, FALSE, 0);
+
+ /// Adding box to Main Window
gtk_container_add(GTK_CONTAINER(MainWindow), PackBoxMenu);
}
@@ -914,36 +945,79 @@ void ToggleSimulationMode(void)
//-----------------------------------------------------------------------------
void RefreshControlsToSettings(void)
{
- int i;
- gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), iter);
- gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
- GTK_SELECTION_SINGLE);
+ GtkTreeIter iter;
+ BOOL path_not_empty = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), &iter);
+ g_print("path e = %i\n", path_not_empty);
+
+ int * ip;
+ int i = 0;
+
+
if(!IoListOutOfSync) {
IoListSelectionPoint = -1;
- for(i = 0; i < Prog.io.count; i++) {
- gtk_tree_model_iter_next (GTK_TREE_MODEL(IoList), iter);
- if(gtk_tree_selection_get_selected (gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
- IoListPtr, iter)) {
- IoListSelectionPoint = i;
- break;
- }
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+ if(gtk_tree_selection_get_selected (selection, IoListPtr, &iter))
+ {
+ GtkTreePath *path = gtk_tree_model_get_path ( *IoListPtr , &iter ) ;
+ ip = gtk_tree_path_get_indices ( path ) ;
+ i = ip[0];
+ IoListSelectionPoint = i;
}
}
- gtk_list_store_clear (IoList);
+
+ gtk_list_store_clear (GTK_LIST_STORE(IoList));
+
+ for(i = 0; i < Prog.io.count; i++) {
+ gtk_list_store_append (GTK_LIST_STORE(IoList), &iter);
+
+ }
+
+ if(IoListSelectionPoint >= 0) {
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+ gtk_tree_selection_unselect_all (selection);
+ GtkTreePath *path = gtk_tree_path_new_from_indices ( IoListSelectionPoint, -1);
+ gtk_tree_selection_select_path (selection, path);
+
+ // ListView_EnsureVisible(IoList, IoListSelectionPoint, FALSE);
+ }
+
IoListOutOfSync = FALSE;
if(Prog.mcu) {
- gtk_statusbar_push (GTK_STATUSBAR (StatusBar),
- gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar), "MCU Name"),
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[0]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[0]), "MCU Name"),
(gchar*)Prog.mcu->mcuName);
- // SendMessage(StatusBar, SB_SETTEXT, 0, (LPARAM)Prog.mcu->mcuName);
}
else {
- // SendMessage(StatusBar, SB_SETTEXT, 0, (LPARAM)_("no MCU selected"));
- gtk_statusbar_push (GTK_STATUSBAR (StatusBar),
- gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar), "MCU Name"),
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[0]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[0]), "MCU Name"),
"no MCU selected");
}
+ char buf[256];
+ sprintf(buf, _("cycle time %.2f ms"), (double)Prog.cycleTime/1000.0);
+
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[1]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[1]), "Cycle time"),
+ buf);
+
+ if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC ||
+ Prog.mcu->whichIsa == ISA_INTERPRETED))
+ {
+ strcpy(buf, "");
+ } else {
+ sprintf(buf, _("processor clock %.4f MHz"),
+ (double)Prog.mcuClock/1000000.0);
+ }
+ gtk_statusbar_push (GTK_STATUSBAR (StatusBar[2]),
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[2]), "Processor time"),
+ buf);
+
+
for(i = 0; i < NUM_SUPPORTED_MCUS; i++) {
if(&SupportedMcus[i] == Prog.mcu) {
CheckMenuItem(ProcessorMenu, ProcessorMenuItems[i], MF_CHECKED);
@@ -967,19 +1041,38 @@ void RefreshControlsToSettings(void)
//-----------------------------------------------------------------------------
void GenerateIoListDontLoseSelection(void)
{
- int i;
- gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), iter);
- gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
- GTK_SELECTION_SINGLE);
+ GtkTreeIter iter;
+ BOOL path_not_empty = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), &iter);
+ // g_print("path e = %i\n", path_not_empty);
+
+ int * i ;
IoListSelectionPoint = -1;
- for(i = 0; i < Prog.io.count; i++) {
- gtk_tree_model_iter_next (GTK_TREE_MODEL (IoList), iter);
- if(gtk_tree_selection_get_selected (gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
- IoListPtr, iter)) {
- IoListSelectionPoint = i;
- break;
- }
+
+ // GtkTreeSelection * tsel = gtk_tree_view_get_selection (tv);
+ // GtkTreeModel * tm ;
+ GtkTreePath * path ;
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+ if(gtk_tree_selection_get_selected (selection, IoListPtr, &iter))
+ {
+ path = gtk_tree_model_get_path ( *IoListPtr , &iter ) ;
+ i = gtk_tree_path_get_indices ( path ) ;
+ IoListSelectionPoint = i[0];
}
+
+ // gtk_tree_model_iter_next (GTK_TREE_MODEL(IoList), iter);
+ // BOOL iter_v = gtk_list_store_iter_is_valid(GTK_LIST_STORE(IoList), iter);
+ // g_print("iter = %i\n", iter_v);
+
+
+ // if ( gtk_tree_selection_get_selected ( tsel , &tm , &iter ) )
+ // {
+
+ // return i [ 0 ] ;
+ // }
+
IoListSelectionPoint = GenerateIoList(IoListSelectionPoint);
// can't just update the listview index; if I/O has been added then the
@@ -999,8 +1092,8 @@ void MainWindowResized(void)
GetClientRect(DrawWindow, &main);
RECT status;
- GetWindowRect(StatusBar, &status);
- int statusHeight = status.bottom - status.top;
+ // GetWindowRect(StatusBar, &status);
+ // int statusHeight = status.bottom - status.top;
// MoveWindow(StatusBar, 0, main.bottom - statusHeight, main.right,
// statusHeight, TRUE);
@@ -1014,8 +1107,8 @@ void MainWindowResized(void)
// Make sure that we can't drag the top of the I/O list above the
// bottom of the menu bar, because it then becomes inaccessible.
if(IoListTop < 5) {
- IoListHeight = main.bottom - statusHeight - 5;
- IoListTop = main.bottom - IoListHeight - statusHeight;
+ IoListHeight = main.bottom - 5;//- statusHeight - 5;
+ IoListTop = main.bottom - IoListHeight;// - statusHeight;
}
// MoveWindow(IoList, 0, IoListTop, main.right, IoListHeight, TRUE);
diff --git a/ldmicro/miscutil.cpp b/ldmicro/miscutil.cpp
index fb3275a..882cccd 100644
--- a/ldmicro/miscutil.cpp
+++ b/ldmicro/miscutil.cpp
@@ -53,12 +53,12 @@ HFONT MyFixedFont;
//-----------------------------------------------------------------------------
void dbp(char *str, ...)
{
- va_list f;
- char buf[1024];
- va_start(f, str);
- vsprintf(buf, str, f);
- OutputDebugString(buf);
- OutputDebugString("\n");
+ // va_list f;
+ // char buf[1024];
+ // va_start(f, str);
+ // vsprintf(buf, str, f);
+ // OutputDebugString(buf);
+ // OutputDebugString("\n");
}
//-----------------------------------------------------------------------------
@@ -132,26 +132,26 @@ void CompileSuccessfulMessage(char *str)
//-----------------------------------------------------------------------------
void CheckHeap(char *file, int line)
{
- static unsigned int SkippedCalls;
- static SDWORD LastCallTime;
- SDWORD now = GetTickCount();
-
- // It slows us down too much to do the check every time we are called;
- // but let's still do the check periodically; let's do it every 70
- // calls or every 20 ms, whichever is sooner.
- if(SkippedCalls < 70 && (now - LastCallTime) < 20) {
- SkippedCalls++;
- return;
- }
+ // static unsigned int SkippedCalls;
+ // static SDWORD LastCallTime;
+ // SDWORD now = GetTickCount();
+
+ // // It slows us down too much to do the check every time we are called;
+ // // but let's still do the check periodically; let's do it every 70
+ // // calls or every 20 ms, whichever is sooner.
+ // if(SkippedCalls < 70 && (now - LastCallTime) < 20) {
+ // SkippedCalls++;
+ // return;
+ // }
- SkippedCalls = 0;
- LastCallTime = now;
+ // SkippedCalls = 0;
+ // LastCallTime = now;
- // if(!HeapValidate(MainHeap, 0, NULL)) {
- // dbp("file %s line %d", file, line);
- // Error("Noticed memory corruption at file '%s' line %d.", file, line);
- // oops();
- // }
+ // // if(!HeapValidate(MainHeap, 0, NULL)) {
+ // // dbp("file %s line %d", file, line);
+ // // Error("Noticed memory corruption at file '%s' line %d.", file, line);
+ // // oops();
+ // // }
}
//-----------------------------------------------------------------------------
diff --git a/ldmicro/simulate.cpp b/ldmicro/simulate.cpp
index ecb9b0e..a4a5d1a 100644
--- a/ldmicro/simulate.cpp
+++ b/ldmicro/simulate.cpp
@@ -106,117 +106,117 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// Looks in the SingleBitItems list; if an item is not present then it is
// FALSE by default.
//-----------------------------------------------------------------------------
-// static BOOL SingleBitOn(char *name)
-// {
-// int i;
-// for(i = 0; i < SingleBitItemsCount; i++) {
-// if(strcmp(SingleBitItems[i].name, name)==0) {
-// return SingleBitItems[i].powered;
-// }
-// }
-// return FALSE;
-// }
+static BOOL SingleBitOn(char *name)
+{
+ int i;
+ for(i = 0; i < SingleBitItemsCount; i++) {
+ if(strcmp(SingleBitItems[i].name, name)==0) {
+ return SingleBitItems[i].powered;
+ }
+ }
+ return FALSE;
+}
//-----------------------------------------------------------------------------
// Set the state of a single-bit item. Adds it to the list if it is not there
// already.
//-----------------------------------------------------------------------------
-// static void SetSingleBit(char *name, BOOL state)
-// {
-// int i;
-// for(i = 0; i < SingleBitItemsCount; i++) {
-// if(strcmp(SingleBitItems[i].name, name)==0) {
-// SingleBitItems[i].powered = state;
-// return;
-// }
-// }
-// if(i < MAX_IO) {
-// strcpy(SingleBitItems[i].name, name);
-// SingleBitItems[i].powered = state;
-// SingleBitItemsCount++;
-// }
-// }
+static void SetSingleBit(char *name, BOOL state)
+{
+ int i;
+ for(i = 0; i < SingleBitItemsCount; i++) {
+ if(strcmp(SingleBitItems[i].name, name)==0) {
+ SingleBitItems[i].powered = state;
+ return;
+ }
+ }
+ if(i < MAX_IO) {
+ strcpy(SingleBitItems[i].name, name);
+ SingleBitItems[i].powered = state;
+ SingleBitItemsCount++;
+ }
+}
//-----------------------------------------------------------------------------
// Count a timer up (i.e. increment its associated count by 1). Must already
// exist in the table.
//-----------------------------------------------------------------------------
-// static void IncrementVariable(char *name)
-// {
-// int i;
-// for(i = 0; i < VariablesCount; i++) {
-// if(strcmp(Variables[i].name, name)==0) {
-// (Variables[i].val)++;
-// return;
-// }
-// }
-// oops();
-// }
+static void IncrementVariable(char *name)
+{
+ int i;
+ for(i = 0; i < VariablesCount; i++) {
+ if(strcmp(Variables[i].name, name)==0) {
+ (Variables[i].val)++;
+ return;
+ }
+ }
+ oops();
+}
//-----------------------------------------------------------------------------
// Set a variable to a value.
//-----------------------------------------------------------------------------
-// static void SetSimulationVariable(char *name, SWORD val)
-// {
-// int i;
-// for(i = 0; i < VariablesCount; i++) {
-// if(strcmp(Variables[i].name, name)==0) {
-// Variables[i].val = val;
-// return;
-// }
-// }
-// MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN);
-// SetSimulationVariable(name, val);
-// }
+static void SetSimulationVariable(char *name, SWORD val)
+{
+ int i;
+ for(i = 0; i < VariablesCount; i++) {
+ if(strcmp(Variables[i].name, name)==0) {
+ Variables[i].val = val;
+ return;
+ }
+ }
+ MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN);
+ SetSimulationVariable(name, val);
+}
//-----------------------------------------------------------------------------
// Read a variable's value.
//-----------------------------------------------------------------------------
-// SWORD GetSimulationVariable(char *name)
-// {
-// int i;
-// for(i = 0; i < VariablesCount; i++) {
-// if(strcmp(Variables[i].name, name)==0) {
-// return Variables[i].val;
-// }
-// }
-// MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN);
-// return GetSimulationVariable(name);
-// }
+SWORD GetSimulationVariable(char *name)
+{
+ int i;
+ for(i = 0; i < VariablesCount; i++) {
+ if(strcmp(Variables[i].name, name)==0) {
+ return Variables[i].val;
+ }
+ }
+ MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN);
+ return GetSimulationVariable(name);
+}
//-----------------------------------------------------------------------------
// Set the shadow copy of a variable associated with a READ ADC operation. This
// will get committed to the real copy when the rung-in condition to the
// READ ADC is true.
//-----------------------------------------------------------------------------
-// void SetAdcShadow(char *name, SWORD val)
-// {
-// int i;
-// for(i = 0; i < AdcShadowsCount; i++) {
-// if(strcmp(AdcShadows[i].name, name)==0) {
-// AdcShadows[i].val = val;
-// return;
-// }
-// }
-// strcpy(AdcShadows[i].name, name);
-// AdcShadows[i].val = val;
-// AdcShadowsCount++;
-// }
+void SetAdcShadow(char *name, SWORD val)
+{
+ int i;
+ for(i = 0; i < AdcShadowsCount; i++) {
+ if(strcmp(AdcShadows[i].name, name)==0) {
+ AdcShadows[i].val = val;
+ return;
+ }
+ }
+ strcpy(AdcShadows[i].name, name);
+ AdcShadows[i].val = val;
+ AdcShadowsCount++;
+}
//-----------------------------------------------------------------------------
// Return the shadow value of a variable associated with a READ ADC. This is
// what gets copied into the real variable when an ADC read is simulated.
//-----------------------------------------------------------------------------
-// SWORD GetAdcShadow(char *name)
-// {
-// int i;
-// for(i = 0; i < AdcShadowsCount; i++) {
-// if(strcmp(AdcShadows[i].name, name)==0) {
-// return AdcShadows[i].val;
-// }
-// }
-// return 0;
-// }
+SWORD GetAdcShadow(char *name)
+{
+ int i;
+ for(i = 0; i < AdcShadowsCount; i++) {
+ if(strcmp(AdcShadows[i].name, name)==0) {
+ return AdcShadows[i].val;
+ }
+ }
+ return 0;
+}
//-----------------------------------------------------------------------------
// Mark how a variable is used; a series of flags that we can OR together,
@@ -224,62 +224,62 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// (e.g. just a TON, an RTO with its reset, etc.). Returns NULL for success,
// else an error string.
//-----------------------------------------------------------------------------
-// static char *MarkUsedVariable(char *name, DWORD flag)
-// {
-// int i;
-// for(i = 0; i < VariablesCount; i++) {
-// if(strcmp(Variables[i].name, name)==0) {
-// break;
-// }
-// }
-// if(i >= MAX_IO) return "";
-
-// if(i == VariablesCount) {
-// strcpy(Variables[i].name, name);
-// Variables[i].usedFlags = 0;
-// Variables[i].val = 0;
-// VariablesCount++;
-// }
-
-// switch(flag) {
-// case VAR_FLAG_TOF:
-// if(Variables[i].usedFlags != 0)
-// return _("TOF: variable cannot be used elsewhere");
-// break;
-
-// case VAR_FLAG_TON:
-// if(Variables[i].usedFlags != 0)
-// return _("TON: variable cannot be used elsewhere");
-// break;
+static char *MarkUsedVariable(char *name, DWORD flag)
+{
+ int i;
+ for(i = 0; i < VariablesCount; i++) {
+ if(strcmp(Variables[i].name, name)==0) {
+ break;
+ }
+ }
+ if(i >= MAX_IO) return "";
+
+ if(i == VariablesCount) {
+ strcpy(Variables[i].name, name);
+ Variables[i].usedFlags = 0;
+ Variables[i].val = 0;
+ VariablesCount++;
+ }
+
+ switch(flag) {
+ case VAR_FLAG_TOF:
+ if(Variables[i].usedFlags != 0)
+ return _("TOF: variable cannot be used elsewhere");
+ break;
+
+ case VAR_FLAG_TON:
+ if(Variables[i].usedFlags != 0)
+ return _("TON: variable cannot be used elsewhere");
+ break;
-// case VAR_FLAG_RTO:
-// if(Variables[i].usedFlags & ~VAR_FLAG_RES)
-// return _("RTO: variable can only be used for RES elsewhere");
-// break;
-
-// case VAR_FLAG_CTU:
-// case VAR_FLAG_CTD:
-// case VAR_FLAG_CTC:
-// case VAR_FLAG_RES:
-// case VAR_FLAG_ANY:
-// break;
-
-// case VAR_FLAG_OTHERWISE_FORGOTTEN:
-// if(name[0] != '$') {
-// Error(_("Variable '%s' not assigned to, e.g. with a "
-// "MOV statement, an ADD statement, etc.\r\n\r\n"
-// "This is probably a programming error; now it "
-// "will always be zero."), name);
-// }
-// break;
-
-// default:
-// oops();
-// }
-
-// Variables[i].usedFlags |= flag;
-// return NULL;
-// }
+ case VAR_FLAG_RTO:
+ if(Variables[i].usedFlags & ~VAR_FLAG_RES)
+ return _("RTO: variable can only be used for RES elsewhere");
+ break;
+
+ case VAR_FLAG_CTU:
+ case VAR_FLAG_CTD:
+ case VAR_FLAG_CTC:
+ case VAR_FLAG_RES:
+ case VAR_FLAG_ANY:
+ break;
+
+ case VAR_FLAG_OTHERWISE_FORGOTTEN:
+ if(name[0] != '$') {
+ Error(_("Variable '%s' not assigned to, e.g. with a "
+ "MOV statement, an ADD statement, etc.\r\n\r\n"
+ "This is probably a programming error; now it "
+ "will always be zero."), name);
+ }
+ break;
+
+ default:
+ oops();
+ }
+
+ Variables[i].usedFlags |= flag;
+ return NULL;
+}
//-----------------------------------------------------------------------------
// Check for duplicate uses of a single variable. For example, there should
@@ -287,207 +287,207 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// to have an RTO with the same name as its reset; in fact, verify that
// there must be a reset for each RTO.
//-----------------------------------------------------------------------------
-// static void MarkWithCheck(char *name, int flag)
-// {
-// char *s = MarkUsedVariable(name, flag);
-// if(s) {
-// Error(_("Variable for '%s' incorrectly assigned: %s."), name, s);
-// }
-// }
-
-// static void CheckVariableNamesCircuit(int which, void *elem)
-// {
-// ElemLeaf *l = (ElemLeaf *)elem;
-// char *name = NULL;
-// DWORD flag;
-
-// switch(which) {
-// case ELEM_SERIES_SUBCKT: {
-// int i;
-// ElemSubcktSeries *s = (ElemSubcktSeries *)elem;
-// for(i = 0; i < s->count; i++) {
-// CheckVariableNamesCircuit(s->contents[i].which,
-// s->contents[i].d.any);
-// }
-// break;
-// }
-
-// case ELEM_PARALLEL_SUBCKT: {
-// int i;
-// ElemSubcktParallel *p = (ElemSubcktParallel *)elem;
-// for(i = 0; i < p->count; i++) {
-// CheckVariableNamesCircuit(p->contents[i].which,
-// p->contents[i].d.any);
-// }
-// break;
-// }
+static void MarkWithCheck(char *name, int flag)
+{
+ char *s = MarkUsedVariable(name, flag);
+ if(s) {
+ Error(_("Variable for '%s' incorrectly assigned: %s."), name, s);
+ }
+}
+
+static void CheckVariableNamesCircuit(int which, void *elem)
+{
+ ElemLeaf *l = (ElemLeaf *)elem;
+ char *name = NULL;
+ DWORD flag;
+
+ switch(which) {
+ case ELEM_SERIES_SUBCKT: {
+ int i;
+ ElemSubcktSeries *s = (ElemSubcktSeries *)elem;
+ for(i = 0; i < s->count; i++) {
+ CheckVariableNamesCircuit(s->contents[i].which,
+ s->contents[i].d.any);
+ }
+ break;
+ }
+
+ case ELEM_PARALLEL_SUBCKT: {
+ int i;
+ ElemSubcktParallel *p = (ElemSubcktParallel *)elem;
+ for(i = 0; i < p->count; i++) {
+ CheckVariableNamesCircuit(p->contents[i].which,
+ p->contents[i].d.any);
+ }
+ break;
+ }
-// case ELEM_RTO:
-// case ELEM_TOF:
-// case ELEM_TON:
-// if(which == ELEM_RTO)
-// flag = VAR_FLAG_RTO;
-// else if(which == ELEM_TOF)
-// flag = VAR_FLAG_TOF;
-// else if(which == ELEM_TON)
-// flag = VAR_FLAG_TON;
-// else oops();
-
-// MarkWithCheck(l->d.timer.name, flag);
-
-// break;
-
-// case ELEM_CTU:
-// case ELEM_CTD:
-// case ELEM_CTC:
-// if(which == ELEM_CTU)
-// flag = VAR_FLAG_CTU;
-// else if(which == ELEM_CTD)
-// flag = VAR_FLAG_CTD;
-// else if(which == ELEM_CTC)
-// flag = VAR_FLAG_CTC;
-// else oops();
-
-// MarkWithCheck(l->d.counter.name, flag);
-
-// break;
-
-// case ELEM_RES:
-// MarkWithCheck(l->d.reset.name, VAR_FLAG_RES);
-// break;
-
-// case ELEM_MOVE:
-// MarkWithCheck(l->d.move.dest, VAR_FLAG_ANY);
-// break;
-
-// case ELEM_LOOK_UP_TABLE:
-// MarkWithCheck(l->d.lookUpTable.dest, VAR_FLAG_ANY);
-// break;
-
-// case ELEM_PIECEWISE_LINEAR:
-// MarkWithCheck(l->d.piecewiseLinear.dest, VAR_FLAG_ANY);
-// break;
-
-// case ELEM_READ_ADC:
-// MarkWithCheck(l->d.readAdc.name, VAR_FLAG_ANY);
-// break;
-
-// case ELEM_ADD:
-// case ELEM_SUB:
-// case ELEM_MUL:
-// case ELEM_DIV:
-// MarkWithCheck(l->d.math.dest, VAR_FLAG_ANY);
-// break;
-
-// case ELEM_UART_RECV:
-// MarkWithCheck(l->d.uart.name, VAR_FLAG_ANY);
-// break;
-
-// case ELEM_SHIFT_REGISTER: {
-// int i;
-// for(i = 1; i < l->d.shiftRegister.stages; i++) {
-// char str[MAX_NAME_LEN+10];
-// sprintf(str, "%s%d", l->d.shiftRegister.name, i);
-// MarkWithCheck(str, VAR_FLAG_ANY);
-// }
-// break;
-// }
-
-// case ELEM_PERSIST:
-// case ELEM_FORMATTED_STRING:
-// case ELEM_SET_PWM:
-// case ELEM_MASTER_RELAY:
-// case ELEM_UART_SEND:
-// case ELEM_PLACEHOLDER:
-// case ELEM_COMMENT:
-// case ELEM_OPEN:
-// case ELEM_SHORT:
-// case ELEM_COIL:
-// case ELEM_CONTACTS:
-// case ELEM_ONE_SHOT_RISING:
-// case ELEM_ONE_SHOT_FALLING:
-// case ELEM_EQU:
-// case ELEM_NEQ:
-// case ELEM_GRT:
-// case ELEM_GEQ:
-// case ELEM_LES:
-// case ELEM_LEQ:
-// break;
-
-// default:
-// oops();
-// }
-// }
-
-// static void CheckVariableNames(void)
-// {
-// int i;
-// for(i = 0; i < Prog.numRungs; i++) {
-// CheckVariableNamesCircuit(ELEM_SERIES_SUBCKT, Prog.rungs[i]);
-// }
-// }
+ case ELEM_RTO:
+ case ELEM_TOF:
+ case ELEM_TON:
+ if(which == ELEM_RTO)
+ flag = VAR_FLAG_RTO;
+ else if(which == ELEM_TOF)
+ flag = VAR_FLAG_TOF;
+ else if(which == ELEM_TON)
+ flag = VAR_FLAG_TON;
+ else oops();
+
+ MarkWithCheck(l->d.timer.name, flag);
+
+ break;
+
+ case ELEM_CTU:
+ case ELEM_CTD:
+ case ELEM_CTC:
+ if(which == ELEM_CTU)
+ flag = VAR_FLAG_CTU;
+ else if(which == ELEM_CTD)
+ flag = VAR_FLAG_CTD;
+ else if(which == ELEM_CTC)
+ flag = VAR_FLAG_CTC;
+ else oops();
+
+ MarkWithCheck(l->d.counter.name, flag);
+
+ break;
+
+ case ELEM_RES:
+ MarkWithCheck(l->d.reset.name, VAR_FLAG_RES);
+ break;
+
+ case ELEM_MOVE:
+ MarkWithCheck(l->d.move.dest, VAR_FLAG_ANY);
+ break;
+
+ case ELEM_LOOK_UP_TABLE:
+ MarkWithCheck(l->d.lookUpTable.dest, VAR_FLAG_ANY);
+ break;
+
+ case ELEM_PIECEWISE_LINEAR:
+ MarkWithCheck(l->d.piecewiseLinear.dest, VAR_FLAG_ANY);
+ break;
+
+ case ELEM_READ_ADC:
+ MarkWithCheck(l->d.readAdc.name, VAR_FLAG_ANY);
+ break;
+
+ case ELEM_ADD:
+ case ELEM_SUB:
+ case ELEM_MUL:
+ case ELEM_DIV:
+ MarkWithCheck(l->d.math.dest, VAR_FLAG_ANY);
+ break;
+
+ case ELEM_UART_RECV:
+ MarkWithCheck(l->d.uart.name, VAR_FLAG_ANY);
+ break;
+
+ case ELEM_SHIFT_REGISTER: {
+ int i;
+ for(i = 1; i < l->d.shiftRegister.stages; i++) {
+ char str[MAX_NAME_LEN+10];
+ sprintf(str, "%s%d", l->d.shiftRegister.name, i);
+ MarkWithCheck(str, VAR_FLAG_ANY);
+ }
+ break;
+ }
+
+ case ELEM_PERSIST:
+ case ELEM_FORMATTED_STRING:
+ case ELEM_SET_PWM:
+ case ELEM_MASTER_RELAY:
+ case ELEM_UART_SEND:
+ case ELEM_PLACEHOLDER:
+ case ELEM_COMMENT:
+ case ELEM_OPEN:
+ case ELEM_SHORT:
+ case ELEM_COIL:
+ case ELEM_CONTACTS:
+ case ELEM_ONE_SHOT_RISING:
+ case ELEM_ONE_SHOT_FALLING:
+ case ELEM_EQU:
+ case ELEM_NEQ:
+ case ELEM_GRT:
+ case ELEM_GEQ:
+ case ELEM_LES:
+ case ELEM_LEQ:
+ break;
+
+ default:
+ oops();
+ }
+}
+
+static void CheckVariableNames(void)
+{
+ int i;
+ for(i = 0; i < Prog.numRungs; i++) {
+ CheckVariableNamesCircuit(ELEM_SERIES_SUBCKT, Prog.rungs[i]);
+ }
+}
//-----------------------------------------------------------------------------
// The IF condition is true. Execute the body, up until the ELSE or the
// END IF, and then skip the ELSE if it is present. Called with PC on the
// IF, returns with PC on the END IF.
//-----------------------------------------------------------------------------
-// static void IfConditionTrue(void)
-// {
-// IntPc++;
-// // now PC is on the first statement of the IF body
-// SimulateIntCode();
-// // now PC is on the ELSE or the END IF
-// if(IntCode[IntPc].op == INT_ELSE) {
-// int nesting = 1;
-// for(; ; IntPc++) {
-// if(IntPc >= IntCodeLen) oops();
-
-// if(IntCode[IntPc].op == INT_END_IF) {
-// nesting--;
-// } else if(INT_IF_GROUP(IntCode[IntPc].op)) {
-// nesting++;
-// }
-// if(nesting == 0) break;
-// }
-// } else if(IntCode[IntPc].op == INT_END_IF) {
-// return;
-// } else {
-// oops();
-// }
-// }
+static void IfConditionTrue(void)
+{
+ IntPc++;
+ // now PC is on the first statement of the IF body
+ SimulateIntCode();
+ // now PC is on the ELSE or the END IF
+ if(IntCode[IntPc].op == INT_ELSE) {
+ int nesting = 1;
+ for(; ; IntPc++) {
+ if(IntPc >= IntCodeLen) oops();
+
+ if(IntCode[IntPc].op == INT_END_IF) {
+ nesting--;
+ } else if(INT_IF_GROUP(IntCode[IntPc].op)) {
+ nesting++;
+ }
+ if(nesting == 0) break;
+ }
+ } else if(IntCode[IntPc].op == INT_END_IF) {
+ return;
+ } else {
+ oops();
+ }
+}
//-----------------------------------------------------------------------------
// The IF condition is false. Skip the body, up until the ELSE or the END
// IF, and then execute the ELSE if it is present. Called with PC on the IF,
// returns with PC on the END IF.
//-----------------------------------------------------------------------------
-// static void IfConditionFalse(void)
-// {
-// int nesting = 0;
-// for(; ; IntPc++) {
-// if(IntPc >= IntCodeLen) oops();
-
-// if(IntCode[IntPc].op == INT_END_IF) {
-// nesting--;
-// } else if(INT_IF_GROUP(IntCode[IntPc].op)) {
-// nesting++;
-// } else if(IntCode[IntPc].op == INT_ELSE && nesting == 1) {
-// break;
-// }
-// if(nesting == 0) break;
-// }
-
-// // now PC is on the ELSE or the END IF
-// if(IntCode[IntPc].op == INT_ELSE) {
-// IntPc++;
-// SimulateIntCode();
-// } else if(IntCode[IntPc].op == INT_END_IF) {
-// return;
-// } else {
-// oops();
-// }
-// }
+static void IfConditionFalse(void)
+{
+ int nesting = 0;
+ for(; ; IntPc++) {
+ if(IntPc >= IntCodeLen) oops();
+
+ if(IntCode[IntPc].op == INT_END_IF) {
+ nesting--;
+ } else if(INT_IF_GROUP(IntCode[IntPc].op)) {
+ nesting++;
+ } else if(IntCode[IntPc].op == INT_ELSE && nesting == 1) {
+ break;
+ }
+ if(nesting == 0) break;
+ }
+
+ // now PC is on the ELSE or the END IF
+ if(IntCode[IntPc].op == INT_ELSE) {
+ IntPc++;
+ SimulateIntCode();
+ } else if(IntCode[IntPc].op == INT_END_IF) {
+ return;
+ } else {
+ oops();
+ }
+}
//-----------------------------------------------------------------------------
// Evaluate a circuit, calling ourselves recursively to evaluate if/else
@@ -495,179 +495,179 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// internal tables. Returns when it reaches an end if or an else construct,
// or at the end of the program.
//-----------------------------------------------------------------------------
-// static void SimulateIntCode(void)
-// {
-// for(; IntPc < IntCodeLen; IntPc++) {
-// IntOp *a = &IntCode[IntPc];
-// switch(a->op) {
-// case INT_SIMULATE_NODE_STATE:
-// if(*(a->poweredAfter) != SingleBitOn(a->name1))
-// NeedRedraw = TRUE;
-// *(a->poweredAfter) = SingleBitOn(a->name1);
-// break;
-
-// case INT_SET_BIT:
-// SetSingleBit(a->name1, TRUE);
-// break;
-
-// case INT_CLEAR_BIT:
-// SetSingleBit(a->name1, FALSE);
-// break;
-
-// case INT_COPY_BIT_TO_BIT:
-// SetSingleBit(a->name1, SingleBitOn(a->name2));
-// break;
-
-// case INT_SET_VARIABLE_TO_LITERAL:
-// if(GetSimulationVariable(a->name1) !=
-// a->literal && a->name1[0] != '$')
-// {
-// NeedRedraw = TRUE;
-// }
-// SetSimulationVariable(a->name1, a->literal);
-// break;
-
-// case INT_SET_VARIABLE_TO_VARIABLE:
-// if(GetSimulationVariable(a->name1) !=
-// GetSimulationVariable(a->name2))
-// {
-// NeedRedraw = TRUE;
-// }
-// SetSimulationVariable(a->name1,
-// GetSimulationVariable(a->name2));
-// break;
-
-// case INT_INCREMENT_VARIABLE:
-// IncrementVariable(a->name1);
-// break;
-
-// {
-// SWORD v;
-// case INT_SET_VARIABLE_ADD:
-// v = GetSimulationVariable(a->name2) +
-// GetSimulationVariable(a->name3);
-// goto math;
-// case INT_SET_VARIABLE_SUBTRACT:
-// v = GetSimulationVariable(a->name2) -
-// GetSimulationVariable(a->name3);
-// goto math;
-// case INT_SET_VARIABLE_MULTIPLY:
-// v = GetSimulationVariable(a->name2) *
-// GetSimulationVariable(a->name3);
-// goto math;
-// case INT_SET_VARIABLE_DIVIDE:
-// if(GetSimulationVariable(a->name3) != 0) {
-// v = GetSimulationVariable(a->name2) /
-// GetSimulationVariable(a->name3);
-// } else {
-// v = 0;
-// Error(_("Division by zero; halting simulation"));
-// StopSimulation();
-// }
-// goto math;
-// math:
-// if(GetSimulationVariable(a->name1) != v) {
-// NeedRedraw = TRUE;
-// SetSimulationVariable(a->name1, v);
-// }
-// break;
-// }
-
-// #define IF_BODY \
-// { \
-// IfConditionTrue(); \
-// } else { \
-// IfConditionFalse(); \
-// }
-// case INT_IF_BIT_SET:
-// if(SingleBitOn(a->name1))
-// IF_BODY
-// break;
-
-// case INT_IF_BIT_CLEAR:
-// if(!SingleBitOn(a->name1))
-// IF_BODY
-// break;
-
-// case INT_IF_VARIABLE_LES_LITERAL:
-// if(GetSimulationVariable(a->name1) < a->literal)
-// IF_BODY
-// break;
-
-// case INT_IF_VARIABLE_EQUALS_VARIABLE:
-// if(GetSimulationVariable(a->name1) ==
-// GetSimulationVariable(a->name2))
-// IF_BODY
-// break;
-
-// case INT_IF_VARIABLE_GRT_VARIABLE:
-// if(GetSimulationVariable(a->name1) >
-// GetSimulationVariable(a->name2))
-// IF_BODY
-// break;
-
-// case INT_SET_PWM:
-// // Dummy call will cause a warning if no one ever assigned
-// // to that variable.
-// (void)GetSimulationVariable(a->name1);
-// break;
-
-// // Don't try to simulate the EEPROM stuff: just hold the EEPROM
-// // busy all the time, so that the program never does anything
-// // with it.
-// case INT_EEPROM_BUSY_CHECK:
-// SetSingleBit(a->name1, TRUE);
-// break;
-
-// case INT_EEPROM_READ:
-// case INT_EEPROM_WRITE:
-// oops();
-// break;
-
-// case INT_READ_ADC:
-// // Keep the shadow copies of the ADC variables because in
-// // the real device they will not be updated until an actual
-// // read is performed, which occurs only for a true rung-in
-// // condition there.
-// SetSimulationVariable(a->name1, GetAdcShadow(a->name1));
-// break;
-
-// case INT_UART_SEND:
-// if(SingleBitOn(a->name2) && (SimulateUartTxCountdown == 0)) {
-// SimulateUartTxCountdown = 2;
-// AppendToUartSimulationTextControl(
-// (BYTE)GetSimulationVariable(a->name1));
-// }
-// if(SimulateUartTxCountdown == 0) {
-// SetSingleBit(a->name2, FALSE);
-// } else {
-// SetSingleBit(a->name2, TRUE);
-// }
-// break;
-
-// case INT_UART_RECV:
-// if(QueuedUartCharacter >= 0) {
-// SetSingleBit(a->name2, TRUE);
-// SetSimulationVariable(a->name1, (SWORD)QueuedUartCharacter);
-// QueuedUartCharacter = -1;
-// } else {
-// SetSingleBit(a->name2, FALSE);
-// }
-// break;
-
-// case INT_END_IF:
-// case INT_ELSE:
-// return;
-
-// case INT_COMMENT:
-// break;
+static void SimulateIntCode(void)
+{
+ for(; IntPc < IntCodeLen; IntPc++) {
+ IntOp *a = &IntCode[IntPc];
+ switch(a->op) {
+ case INT_SIMULATE_NODE_STATE:
+ if(*(a->poweredAfter) != SingleBitOn(a->name1))
+ NeedRedraw = TRUE;
+ *(a->poweredAfter) = SingleBitOn(a->name1);
+ break;
+
+ case INT_SET_BIT:
+ SetSingleBit(a->name1, TRUE);
+ break;
+
+ case INT_CLEAR_BIT:
+ SetSingleBit(a->name1, FALSE);
+ break;
+
+ case INT_COPY_BIT_TO_BIT:
+ SetSingleBit(a->name1, SingleBitOn(a->name2));
+ break;
+
+ case INT_SET_VARIABLE_TO_LITERAL:
+ if(GetSimulationVariable(a->name1) !=
+ a->literal && a->name1[0] != '$')
+ {
+ NeedRedraw = TRUE;
+ }
+ SetSimulationVariable(a->name1, a->literal);
+ break;
+
+ case INT_SET_VARIABLE_TO_VARIABLE:
+ if(GetSimulationVariable(a->name1) !=
+ GetSimulationVariable(a->name2))
+ {
+ NeedRedraw = TRUE;
+ }
+ SetSimulationVariable(a->name1,
+ GetSimulationVariable(a->name2));
+ break;
+
+ case INT_INCREMENT_VARIABLE:
+ IncrementVariable(a->name1);
+ break;
+
+ {
+ SWORD v;
+ case INT_SET_VARIABLE_ADD:
+ v = GetSimulationVariable(a->name2) +
+ GetSimulationVariable(a->name3);
+ goto math;
+ case INT_SET_VARIABLE_SUBTRACT:
+ v = GetSimulationVariable(a->name2) -
+ GetSimulationVariable(a->name3);
+ goto math;
+ case INT_SET_VARIABLE_MULTIPLY:
+ v = GetSimulationVariable(a->name2) *
+ GetSimulationVariable(a->name3);
+ goto math;
+ case INT_SET_VARIABLE_DIVIDE:
+ if(GetSimulationVariable(a->name3) != 0) {
+ v = GetSimulationVariable(a->name2) /
+ GetSimulationVariable(a->name3);
+ } else {
+ v = 0;
+ Error(_("Division by zero; halting simulation"));
+ StopSimulation();
+ }
+ goto math;
+math:
+ if(GetSimulationVariable(a->name1) != v) {
+ NeedRedraw = TRUE;
+ SetSimulationVariable(a->name1, v);
+ }
+ break;
+ }
+
+#define IF_BODY \
+ { \
+ IfConditionTrue(); \
+ } else { \
+ IfConditionFalse(); \
+ }
+ case INT_IF_BIT_SET:
+ if(SingleBitOn(a->name1))
+ IF_BODY
+ break;
+
+ case INT_IF_BIT_CLEAR:
+ if(!SingleBitOn(a->name1))
+ IF_BODY
+ break;
+
+ case INT_IF_VARIABLE_LES_LITERAL:
+ if(GetSimulationVariable(a->name1) < a->literal)
+ IF_BODY
+ break;
+
+ case INT_IF_VARIABLE_EQUALS_VARIABLE:
+ if(GetSimulationVariable(a->name1) ==
+ GetSimulationVariable(a->name2))
+ IF_BODY
+ break;
+
+ case INT_IF_VARIABLE_GRT_VARIABLE:
+ if(GetSimulationVariable(a->name1) >
+ GetSimulationVariable(a->name2))
+ IF_BODY
+ break;
+
+ case INT_SET_PWM:
+ // Dummy call will cause a warning if no one ever assigned
+ // to that variable.
+ (void)GetSimulationVariable(a->name1);
+ break;
+
+ // Don't try to simulate the EEPROM stuff: just hold the EEPROM
+ // busy all the time, so that the program never does anything
+ // with it.
+ case INT_EEPROM_BUSY_CHECK:
+ SetSingleBit(a->name1, TRUE);
+ break;
+
+ case INT_EEPROM_READ:
+ case INT_EEPROM_WRITE:
+ oops();
+ break;
+
+ case INT_READ_ADC:
+ // Keep the shadow copies of the ADC variables because in
+ // the real device they will not be updated until an actual
+ // read is performed, which occurs only for a true rung-in
+ // condition there.
+ SetSimulationVariable(a->name1, GetAdcShadow(a->name1));
+ break;
+
+ case INT_UART_SEND:
+ if(SingleBitOn(a->name2) && (SimulateUartTxCountdown == 0)) {
+ SimulateUartTxCountdown = 2;
+ AppendToUartSimulationTextControl(
+ (BYTE)GetSimulationVariable(a->name1));
+ }
+ if(SimulateUartTxCountdown == 0) {
+ SetSingleBit(a->name2, FALSE);
+ } else {
+ SetSingleBit(a->name2, TRUE);
+ }
+ break;
+
+ case INT_UART_RECV:
+ if(QueuedUartCharacter >= 0) {
+ SetSingleBit(a->name2, TRUE);
+ SetSimulationVariable(a->name1, (SWORD)QueuedUartCharacter);
+ QueuedUartCharacter = -1;
+ } else {
+ SetSingleBit(a->name2, FALSE);
+ }
+ break;
+
+ case INT_END_IF:
+ case INT_ELSE:
+ return;
+
+ case INT_COMMENT:
+ break;
-// default:
-// oops();
-// break;
-// }
-// }
-// }
+ default:
+ oops();
+ break;
+ }
+ }
+}
//-----------------------------------------------------------------------------
// Called by the Windows timer that triggers cycles when we are running
@@ -686,38 +686,38 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// any outputs have changed. If so, force a screen refresh. If requested do
// a screen refresh regardless.
//-----------------------------------------------------------------------------
-// void SimulateOneCycle(BOOL forceRefresh)
-// {
-// // When there is an error message up, the modal dialog makes its own
-// // event loop, and there is risk that we would go recursive. So let
-// // us fix that. (Note that there are no concurrency issues; we really
-// // would get called recursively, not just reentrantly.)
-// static BOOL Simulating = FALSE;
+void SimulateOneCycle(BOOL forceRefresh)
+{
+ // When there is an error message up, the modal dialog makes its own
+ // event loop, and there is risk that we would go recursive. So let
+ // us fix that. (Note that there are no concurrency issues; we really
+ // would get called recursively, not just reentrantly.)
+ static BOOL Simulating = FALSE;
-// if(Simulating) return;
-// Simulating = TRUE;
+ if(Simulating) return;
+ Simulating = TRUE;
-// NeedRedraw = FALSE;
+ NeedRedraw = FALSE;
-// if(SimulateUartTxCountdown > 0) {
-// SimulateUartTxCountdown--;
-// } else {
-// SimulateUartTxCountdown = 0;
-// }
+ if(SimulateUartTxCountdown > 0) {
+ SimulateUartTxCountdown--;
+ } else {
+ SimulateUartTxCountdown = 0;
+ }
-// IntPc = 0;
-// SimulateIntCode();
+ IntPc = 0;
+ SimulateIntCode();
-// if(NeedRedraw || SimulateRedrawAfterNextCycle || forceRefresh) {
-// InvalidateRect(MainWindow, NULL, FALSE);
-// ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
-// }
+ if(NeedRedraw || SimulateRedrawAfterNextCycle || forceRefresh) {
+ InvalidateRect(MainWindow, NULL, FALSE);
+ // ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
+ }
-// SimulateRedrawAfterNextCycle = FALSE;
-// if(NeedRedraw) SimulateRedrawAfterNextCycle = TRUE;
+ SimulateRedrawAfterNextCycle = FALSE;
+ if(NeedRedraw) SimulateRedrawAfterNextCycle = TRUE;
-// Simulating = FALSE;
-// }
+ Simulating = FALSE;
+}
//-----------------------------------------------------------------------------
// Start the timer that we use to trigger PLC cycles in approximately real
@@ -740,25 +740,25 @@ static char *MarkUsedVariable(char *name, DWORD flag);
//-----------------------------------------------------------------------------
// Clear out all the parameters relating to the previous simulation.
//-----------------------------------------------------------------------------
-// void ClearSimulationData(void)
-// {
-// VariablesCount = 0;
-// SingleBitItemsCount = 0;
-// AdcShadowsCount = 0;
-// QueuedUartCharacter = -1;
-// SimulateUartTxCountdown = 0;
+void ClearSimulationData(void)
+{
+ VariablesCount = 0;
+ SingleBitItemsCount = 0;
+ AdcShadowsCount = 0;
+ QueuedUartCharacter = -1;
+ SimulateUartTxCountdown = 0;
-// CheckVariableNames();
+ CheckVariableNames();
-// SimulateRedrawAfterNextCycle = TRUE;
+ SimulateRedrawAfterNextCycle = TRUE;
-// if(!GenerateIntermediateCode()) {
-// ToggleSimulationMode();
-// return;
-// }
+ if(!GenerateIntermediateCode()) {
+ ToggleSimulationMode();
+ return;
+ }
-// SimulateOneCycle(TRUE);
-// }
+ SimulateOneCycle(TRUE);
+}
//-----------------------------------------------------------------------------
// Provide a description for an item (Xcontacts, Ycoil, Rrelay, Ttimer,
@@ -795,11 +795,11 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// Toggle the state of a contact input; for simulation purposes, so that we
// can set the input state of the program.
//-----------------------------------------------------------------------------
-// void SimulationToggleContact(char *name)
-// {
-// SetSingleBit(name, !SingleBitOn(name));
-// ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
-// }
+void SimulationToggleContact(char *name)
+{
+ SetSingleBit(name, !SingleBitOn(name));
+ // ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
+}
//-----------------------------------------------------------------------------
// Dialog proc for the popup that lets you interact with the UART stuff.
@@ -944,8 +944,8 @@ static char *MarkUsedVariable(char *name, DWORD flag);
//-----------------------------------------------------------------------------
// Append a received character to the terminal buffer.
//-----------------------------------------------------------------------------
-// static void AppendToUartSimulationTextControl(BYTE b)
-// {
+static void AppendToUartSimulationTextControl(BYTE b)
+{
// char append[5];
// if((isalnum(b) || strchr("[]{};':\",.<>/?`~ !@#$%^&*()-=_+|", b) ||
@@ -971,4 +971,4 @@ static char *MarkUsedVariable(char *name, DWORD flag);
// SendMessage(UartSimulationTextControl, WM_SETTEXT, 0, (LPARAM)buf);
// SendMessage(UartSimulationTextControl, EM_LINESCROLL, 0, (LPARAM)INT_MAX);
-// }
+}