aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/Source
diff options
context:
space:
mode:
authorNicolas Schodet2011-07-04 01:23:24 +0200
committerNicolas Schodet2011-07-04 01:27:42 +0200
commitc331530002825a86f12151266a9772167a3a49ce (patch)
tree9a4bb16c6a87e30629da039e82cbf026dc361009 /AT91SAM7S256/Source
parent0cb650f1cf6f446bbb0186300a198b5936f49bb4 (diff)
parentb0472321014e8fcb110f4cecad734bb6a7e27ae0 (diff)
Merge branch 'jch-import' into jch-merge
Conflicts: AT91SAM7S256/Source/BtTest.inc AT91SAM7S256/Source/Functions.inl AT91SAM7S256/Source/Ui.txt AT91SAM7S256/Source/c_cmd.c AT91SAM7S256/Source/c_input.c AT91SAM7S256/Source/c_output.c AT91SAM7S256/Source/c_ui.c AT91SAM7S256/Source/c_ui.h AT91SAM7S256/Source/d_loader.h AT91SAM7S256/Source/d_lowspeed.r AT91SAM7S256/Source/d_output.c AT91SAM7S256/Source/d_output.h
Diffstat (limited to 'AT91SAM7S256/Source')
-rw-r--r--AT91SAM7S256/Source/BtTest.inc16
-rw-r--r--AT91SAM7S256/Source/Functions.inl72
-rw-r--r--AT91SAM7S256/Source/Ui.txt17
-rw-r--r--AT91SAM7S256/Source/cCmdWriteIOMapOffsetsFile.txt125
-rw-r--r--AT91SAM7S256/Source/c_cmd.c2437
-rw-r--r--AT91SAM7S256/Source/c_cmd.h72
-rw-r--r--AT91SAM7S256/Source/c_cmd.iom61
-rw-r--r--AT91SAM7S256/Source/c_cmd_alternate.c108
-rw-r--r--AT91SAM7S256/Source/c_cmd_bytecodes.h79
-rw-r--r--AT91SAM7S256/Source/c_cmd_drawing.inc1724
-rw-r--r--AT91SAM7S256/Source/c_comm.c187
-rw-r--r--AT91SAM7S256/Source/c_comm.iom79
-rw-r--r--AT91SAM7S256/Source/c_display.c235
-rw-r--r--AT91SAM7S256/Source/c_display.iom72
-rw-r--r--AT91SAM7S256/Source/c_input.c56
-rw-r--r--AT91SAM7S256/Source/c_loader.c245
-rw-r--r--AT91SAM7S256/Source/c_loader.h3
-rw-r--r--AT91SAM7S256/Source/c_loader.iom25
-rw-r--r--AT91SAM7S256/Source/c_lowspeed.c2
-rw-r--r--AT91SAM7S256/Source/c_lowspeed.iom15
-rw-r--r--AT91SAM7S256/Source/c_output.c2
-rw-r--r--AT91SAM7S256/Source/c_output.iom3
-rw-r--r--AT91SAM7S256/Source/c_ui.c69
-rw-r--r--AT91SAM7S256/Source/c_ui.h12
-rw-r--r--AT91SAM7S256/Source/c_ui.iom6
-rw-r--r--AT91SAM7S256/Source/d_bt.c8
-rw-r--r--AT91SAM7S256/Source/d_bt.h4
-rw-r--r--AT91SAM7S256/Source/d_bt.r26
-rw-r--r--AT91SAM7S256/Source/d_button.r31
-rw-r--r--AT91SAM7S256/Source/d_display.c4
-rw-r--r--AT91SAM7S256/Source/d_display.h2
-rw-r--r--AT91SAM7S256/Source/d_display.r4
-rw-r--r--AT91SAM7S256/Source/d_display2.r388
-rw-r--r--AT91SAM7S256/Source/d_hispeed.c24
-rw-r--r--AT91SAM7S256/Source/d_hispeed.h2
-rw-r--r--AT91SAM7S256/Source/d_hispeed.r13
-rw-r--r--AT91SAM7S256/Source/d_loader.c109
-rw-r--r--AT91SAM7S256/Source/d_loader.h16
-rw-r--r--AT91SAM7S256/Source/d_lowspeed.c4
-rw-r--r--AT91SAM7S256/Source/d_lowspeed.h2
-rw-r--r--AT91SAM7S256/Source/d_lowspeed.r23
-rw-r--r--AT91SAM7S256/Source/d_output.c156
-rw-r--r--AT91SAM7S256/Source/d_output.h3
-rw-r--r--AT91SAM7S256/Source/modules.h3
44 files changed, 5524 insertions, 1020 deletions
diff --git a/AT91SAM7S256/Source/BtTest.inc b/AT91SAM7S256/Source/BtTest.inc
index f879e20..fe2a7ae 100644
--- a/AT91SAM7S256/Source/BtTest.inc
+++ b/AT91SAM7S256/Source/BtTest.inc
@@ -22,16 +22,11 @@ void GetProtocolVersion(UBYTE *String)
if (Tmp < 100)
{
-#ifdef CUSTOM_FIRMWAREVERSION
- int pad = (sizeof (CUSTOM_FIRMWAREVERSION) - 1) > 7 ? 1 : 1 + 7 - (sizeof (CUSTOM_FIRMWAREVERSION) - 1);
- sprintf((char*)String,"FW %*u.%02ui-%.7s", pad, (FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF, CUSTOM_FIRMWAREVERSION);
-#else
- sprintf((char*)String,"FW %3u.%02u",(FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF);
-#endif
+ sprintf((char*)String,"FW NBC/NXC %2u.%02u",(FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF);
}
else
{
- sprintf((char*)String,"FW Hex %2X.%02X",(FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF);
+ sprintf((char*)String,"FW NBC/NXC %2X.%02X",(FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF);
}
}
@@ -104,6 +99,7 @@ enum TSTPRG
{
SYSTEM_INIT = 1,
SYSTEM_UNLOCK_INIT,
+#ifdef TESTPRG
SYSTEM_UNLOCK,
SYSTEM_PAGE,
TIMER_INIT,
@@ -151,9 +147,9 @@ enum TSTPRG
TSTPRG_MOTOR_INIT,
TSTPRG_MOTOR,
TSTPRG_SKIP_MOTOR,
-
- TSTPRG_SKIP,
- TSTPRG_WAIT
+#endif
+ TSTPRG_SKIP//,
+// TSTPRG_WAIT
};
const UBYTE TXT_EMPTY[] = " ";
diff --git a/AT91SAM7S256/Source/Functions.inl b/AT91SAM7S256/Source/Functions.inl
index 1424721..a547619 100644
--- a/AT91SAM7S256/Source/Functions.inl
+++ b/AT91SAM7S256/Source/Functions.inl
@@ -19,11 +19,15 @@
//******* cUiBtTest **********************************************************
const UBYTE NONVOLATILE_NAME[] = UI_NONVOLATILE; // Non volatile filename without extention
+#ifndef STRIPPED
const UBYTE DEFAULT_PROGRAM_NAME[] = UI_PROGRAM_DEFAULT; // On brick programming filename without extention
const UBYTE TEMP_PROGRAM_FILENAME[] = UI_PROGRAM_TEMP; // On brick programming tmp filename without extention
const UBYTE VM_PROGRAM_READER[] = UI_PROGRAM_READER; // On brick programming script reader filename without extention
+#endif
+#ifndef STRIPPED
const UBYTE TEMP_DATALOG_FILENAME[] = UI_DATALOG_TEMP; // On brick datalog tmp filename without extention
const UBYTE DEFAULT_DATALOG_NAME[] = UI_DATALOG_DEFAULT; // On brick datalog filename without extention
+#endif
const UBYTE DEFAULT_PIN_CODE[] = UI_PINCODE_DEFAULT; // Default blue tooth pin code
const UBYTE TXT_INVALID_SENSOR[] = "??????????????"; // Display invalid sensor data
@@ -226,6 +230,8 @@ UBYTE cUiReadLowspeed(UBYTE Port,UBYTE RxBytes,UWORD *Value)
void cUiUpdateSensor(SWORD Time)
{
+#ifndef STRIPPED
+
UBYTE Port;
UBYTE Sensor;
UBYTE Result;
@@ -368,6 +374,7 @@ void cUiUpdateSensor(SWORD Time)
VarsUi.SensorReset = FALSE;
}
+#endif
}
@@ -422,6 +429,7 @@ const UBYTE COLORNAME[COLORNAMES][10] =
void cUiPrintSensorInDisplayBuffer(UBYTE Port)
{
+#ifndef STRIPPED
UBYTE Sensor;
float Value;
SWORD Size;
@@ -451,6 +459,7 @@ void cUiPrintSensorInDisplayBuffer(UBYTE Port)
}
}
}
+#endif
}
@@ -1127,12 +1136,14 @@ UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT
{
VarsUi.Counter = VarsUi.NVData.VolumeStep + 1;
+#ifndef STRIPPED
VarsUi.pTmp = (UBYTE*)Cursor;
for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++)
{
VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp;
VarsUi.pTmp++;
}
+#endif
Action = MENU_DRAW;
}
break;
@@ -1175,9 +1186,11 @@ UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT
sprintf((char*)VarsUi.DisplayBuffer,"%u",(UWORD)VarsUi.Counter - 1);
pMapDisplay->pTextLines[TEXTLINE_3] = VarsUi.DisplayBuffer;
+#ifndef STRIPPED
pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp;
VarsUi.CursorTmp[4] = 46;
VarsUi.CursorTmp[5] = 24;
+#endif
pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4));
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | BITMAP_BIT(BITMAP_1));
@@ -1319,7 +1332,7 @@ UBYTE cUiGetUserString(UBYTE Type) // 0=Pincode, 1=filename
Tmp2 = 0;
}
}
- pMapDisplay->pFunc(DISPLAY_HORISONTAL_LINE,TRUE,42,47,57,0);
+ pMapDisplay->pFunc(DISPLAY_HORIZONTAL_LINE,TRUE,42,47,57,0);
pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE,TRUE,42,47,0,63);
pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE,TRUE,57,47,0,63);
@@ -1475,6 +1488,7 @@ void cUiDrawPortNo(UBYTE *Bitmap,UBYTE MenuIconNo,UBYTE PortNo)
UBYTE cUiDataLogging(UBYTE Action)
{
+#ifndef STRIPPED
SBYTE TmpBuffer[DATALOGBUFFERSIZE + 1];
switch (Action)
@@ -1482,7 +1496,7 @@ UBYTE cUiDataLogging(UBYTE Action)
case MENU_INIT : // Initialize all ports to empty
{
// Show select
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL);
@@ -1498,7 +1512,7 @@ UBYTE cUiDataLogging(UBYTE Action)
case MENU_EXIT : // Initialize all ports to empty
{
// Show select
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL);
@@ -1891,7 +1905,7 @@ UBYTE cUiDataLogging(UBYTE Action)
case 2 : // Display saved text
{
- if (!cUiFeedback((BMPMAP*)Info,TXT_FB_DL_FILE_SAVED_INFO,0xFF,DISPLAY_SHOW_FILENAME_TIME))
+ if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FILE_SAVED_INFO,0xFF,DISPLAY_SHOW_FILENAME_TIME))
{
VarsUi.State++;
}
@@ -1953,7 +1967,7 @@ UBYTE cUiDataLogging(UBYTE Action)
case MENU_SELECT : // Save sensor
{
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
@@ -2006,7 +2020,7 @@ UBYTE cUiDataLogging(UBYTE Action)
break;
}
-
+#endif
return (VarsUi.State);
}
@@ -2067,6 +2081,7 @@ void cUiRunning(UBYTE Action)
UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming
{
+#ifndef STRIPPED
switch (Action)
{
case MENU_INIT : // Show motor / sensor text
@@ -2268,7 +2283,7 @@ UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming
case 2 :
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_OBP_FILE_EXIST_FAIL,TXT_FB_OBP_OVERWRITE_FAIL,0))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_FILE_EXIST_FAIL,TXT_FB_OVERWRITE_FAIL,0))
{
VarsUi.State = 0;
}
@@ -2287,7 +2302,7 @@ UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming
case 4 : // Display saved text
{
- if (!cUiFeedback((BMPMAP*)Info,TXT_FB_OBP_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME))
+ if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME))
{
VarsUi.State++;
}
@@ -2330,7 +2345,7 @@ UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming
default : // Display saved text
{
- if (!cUiFeedback((BMPMAP*)Info,TXT_FB_OBP_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME))
+ if (!cUiFeedback((BMPMAP*)Info,TXT_FB_FILE_SAVED_INFO,0,DISPLAY_SHOW_TIME))
{
VarsUi.State = 0;
}
@@ -2454,6 +2469,7 @@ UBYTE cUiOnBrickProgramming(UBYTE Action) // On brick programming
pMapDisplay->UpdateMask |= (SPECIAL_BIT(STEPLINE) | SPECIAL_BIT(TOPLINE));
}
+#endif
return (VarsUi.State);
}
@@ -2667,7 +2683,8 @@ UBYTE cUiFileRun(UBYTE Action) // Run selected file
default :
{
- pMapDisplay->pTextLines[FILERUN_TEXTLINE] = cUiGetString(TXT_FILERUN_FILE_ERROR);
+ sprintf((char*)VarsUi.DisplayText,(char*)cUiGetString(TXT_FILERUN_FILE_ERROR), pMapCmd->ProgStatus);
+ pMapDisplay->pTextLines[FILERUN_TEXTLINE] = VarsUi.DisplayText;
VarsUi.State = 99;
}
break;
@@ -2675,7 +2692,7 @@ UBYTE cUiFileRun(UBYTE Action) // Run selected file
}
}
break;
-
+#ifndef STRIPPED
case (FILETYPE_NXT * 10 + 0) :// Start Program file (*.prg)
{
VarsUi.TmpHandle = pMapLoader->pFunc(OPENREAD,VarsUi.SelectedFilename,NULL,&VarsUi.TmpLength);
@@ -2739,7 +2756,7 @@ UBYTE cUiFileRun(UBYTE Action) // Run selected file
}
}
break;
-
+#endif
case 99 : // Wait for display show time or user action
{
pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_LARGE);
@@ -2840,15 +2857,17 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT
{
case MENU_INIT : // Init
{
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL);
+#ifndef STRIPPED
// Init ports
for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++)
{
VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY;
}
+#endif
}
break;
@@ -2861,8 +2880,9 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT
if ((Action >= MENU_PORT_1) && (Action <= MENU_PORT_C))
{
VarsUi.SelectedPort = Action;
-
+#ifndef STRIPPED
VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor;
+#endif
IOMapUi.Flags |= UI_BUSY;
pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE);
@@ -2897,7 +2917,7 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT
VarsUi.Tmp = cUiReadButtons();
if (VarsUi.Tmp == BUTTON_EXIT)
{
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask &= ~TEXTLINE_BIT(TEXTLINE_4);
@@ -2980,7 +3000,7 @@ UBYTE cUiBtOn(UBYTE Action)
default : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_TURNING_ON_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
Action = MENU_EXIT;
}
@@ -3038,7 +3058,7 @@ UBYTE cUiBtOn(UBYTE Action)
default : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_TURNING_OFF_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
Action = MENU_EXIT;
}
@@ -3277,7 +3297,7 @@ UBYTE cUiBtSearch(UBYTE Action) // Search for devices
default : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SEARCHING_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
VarsUi.State = 0;
IOMapUi.State = EXIT_PRESSED;
@@ -3306,7 +3326,7 @@ UBYTE cUiBtDeviceList(UBYTE Action) // Show devices
cUiBTCommand(UI_BT_GET_DEVICES,VarsUi.DevicesKnown,&VarsUi.Devices,NULL);
if (VarsUi.Devices)
{
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_BTDEVICELIST_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
VarsUi.MenuIconTextSave = pMapDisplay->pMenuText;
@@ -3328,7 +3348,7 @@ UBYTE cUiBtDeviceList(UBYTE Action) // Show devices
cUiBTCommand(UI_BT_GET_DEVICES,VarsUi.DevicesKnown,&VarsUi.Devices,NULL);
if (VarsUi.Devices)
{
- pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_BTDEVICELIST_SELECT);
+ pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_GENERIC_SELECT);
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3);
VarsUi.MenuIconTextSave = pMapDisplay->pMenuText;
@@ -3420,7 +3440,7 @@ UBYTE cUiBtDeviceList(UBYTE Action) // Show devices
default : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_REMOVE_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
Action = MENU_EXIT;
}
@@ -3562,7 +3582,7 @@ UBYTE cUiBtConnectList(UBYTE Action) // Show connections and maybe disconnec
default : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_DISCONNECT_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
Action = MENU_EXIT;
}
@@ -3793,7 +3813,7 @@ UBYTE cUiBtConnect(UBYTE Action) // Select connection no and insert device
default : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_CONNECTING_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
Action = MENU_EXIT;
}
@@ -3870,7 +3890,7 @@ UBYTE cUiBtConnect(UBYTE Action) // Select connection no and insert device
case 4 : // Display fail text
{
- if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_BT_SENDING_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
+ if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_GENERIC_FAIL,0,DISPLAY_SHOW_ERROR_TIME))
{
Action = MENU_EXIT;
}
@@ -3965,12 +3985,14 @@ UBYTE cUiPowerOffTime(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_E
{
VarsUi.Counter = VarsUi.NVData.PowerdownCode + 1;
+#ifndef STRIPPED
VarsUi.pTmp = (UBYTE*)Cursor;
for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)SIZEOF_DATA(Cursor));VarsUi.Tmp++)
{
VarsUi.CursorTmp[VarsUi.Tmp] = *VarsUi.pTmp;
VarsUi.pTmp++;
}
+#endif
Action = MENU_DRAW;
}
break;
@@ -4012,9 +4034,11 @@ UBYTE cUiPowerOffTime(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_E
}
pMapDisplay->pTextLines[TEXTLINE_3] = VarsUi.DisplayBuffer;
+#ifndef STRIPPED
pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)VarsUi.CursorTmp;
VarsUi.CursorTmp[4] = 46;
VarsUi.CursorTmp[5] = 24;
+#endif
pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4));
pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3);
pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | BITMAP_BIT(BITMAP_1));
diff --git a/AT91SAM7S256/Source/Ui.txt b/AT91SAM7S256/Source/Ui.txt
index 2cf47aa..5746a55 100644
--- a/AT91SAM7S256/Source/Ui.txt
+++ b/AT91SAM7S256/Source/Ui.txt
@@ -3,39 +3,30 @@ DEFINE_DATA(TXT, Ui) =
0x05,0x00, // Text Format
0x04,0x0D, // Text DataSize
0x01, // ItemsX
- 0x3D, // ItemsY
+ 0x32, // ItemsY
0x11, // ItemCharsX
0x01, // ItemCharsY
BEGIN_DATA
+ 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'C','o','n','n','e','c','t','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'L','i','n','e',' ','i','s',' ','b','u','s','y', 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'C','o','n','n','e','c','t','i','o','n','?', 0 , 0 , 0 , 0 , 0 , 0 ,
'S','e','n','d','i','n','g',' ','f','i','l','e', 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'T','u','r','n','i','n','g',' ','o','n', 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'T','u','r','n','i','n','g',' ','o','f','f', 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'S','e','a','r','c','h','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'A','b','o','r','t','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','a','i','l','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'M','e','m','o','r','y',' ','f','u','l','l','!', 0 , 0 , 0 , 0 , 0 ,
'F','i','l','e',' ','s','a','v','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'F','i','l','e',' ','e','x','i','s','t','s', 0 , 0 , 0 , 0 , 0 , 0 ,
'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'S','a','v','e','d',' ','a','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','i','l','e',' ','e','x','i','s','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'F','i','l','e',' ','d','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 ,
'F','i','l','e','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'd','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'R','u','n','n','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'A','b','o','r','t','e','d','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'D','o','n','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'F','i','l','e',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 ,
+ 'F','i','l','e',' ','e','r','r','o','r','!',' ','%','d', 0 , 0 , 0 ,
'D','e','l','e','t','i','n','g',' ','a','l','l', 0 , 0 , 0 , 0 , 0 ,
'%','s',' ','f','i','l','e','s','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'P','r','e','s','s',' ','C','l','e','a','r',' ','t','o', 0 , 0 , 0 ,
@@ -57,8 +48,6 @@ BEGIN_DATA
'4',' ','-',' ','U','l','t','r','a','s','o','n','i','c',' ',' ', 0 ,
'B','/','C',' ','-',' ','L','/','R',' ','m','o','t','o','r','s', 0 ,
'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 'S','e','l','e','c','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'B','T',' ','s','a','v','e',' ','d','a','t','a', 0 , 0 , 0 , 0 , 0 ,
'e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
'B','T',' ','s','t','o','r','e',' ','i','s', 0 , 0 , 0 , 0 , 0 , 0 ,
diff --git a/AT91SAM7S256/Source/cCmdWriteIOMapOffsetsFile.txt b/AT91SAM7S256/Source/cCmdWriteIOMapOffsetsFile.txt
new file mode 100644
index 0000000..a317c79
--- /dev/null
+++ b/AT91SAM7S256/Source/cCmdWriteIOMapOffsetsFile.txt
@@ -0,0 +1,125 @@
+#if WRITE_IOMAP_OFFSETS
+void cCmdWriteIOMapOffsetsFile()
+{
+ LOADER_STATUS LStatus;
+ UBYTE Handle;
+ ULONG BenchFileSize;
+ ULONG Length;
+ UBYTE Buffer[256];
+
+ //Remove old benchmark file, create a new one
+ strcpy((char *)Buffer, "offsets.txt");
+ pMapLoader->pFunc(DELETE, Buffer, NULL, NULL);
+ BenchFileSize = 2048;
+ LStatus = pMapLoader->pFunc(OPENWRITEDATA, Buffer, NULL, &BenchFileSize);
+
+ if (!LOADER_ERR(LStatus))
+ {
+ //Write Benchmark file
+ Handle = LOADER_HANDLE(LStatus);
+
+ //Header
+ sprintf((char *)Buffer, "%s Offsets\r\n", "Comm Module");
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "pFunc: %d\r\n", (ULONG)pMapComm->pFunc - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "pFunc2: %d\r\n", (ULONG)pMapComm->pFunc2 - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtDeviceTable: %d\r\n", (ULONG)pMapComm->BtDeviceTable - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtConnectTable: %d\r\n", (ULONG)pMapComm->BtConnectTable - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BrickData: %d\r\n", (ULONG)pMapComm->BrickData.Name - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtInBuf: %d\r\n", (ULONG)pMapComm->BtInBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtOutBuf: %d\r\n", (ULONG)pMapComm->BtOutBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsInBuf: %d\r\n", (ULONG)pMapComm->HsInBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsOutBuf: %d\r\n", (ULONG)pMapComm->HsOutBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "UsbInBuf: %d\r\n", (ULONG)pMapComm->UsbInBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "UsbOutBuf: %d\r\n", (ULONG)pMapComm->UsbOutBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "UsbPollBuf: %d\r\n", (ULONG)pMapComm->UsbPollBuf.Buf - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtDeviceCnt: %d\r\n", (ULONG)&(pMapComm->BtDeviceCnt) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtDeviceNameCnt: %d\r\n", (ULONG)&(pMapComm->BtDeviceNameCnt) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsFlags: %d\r\n", (ULONG)&(pMapComm->HsFlags) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsSpeed: %d\r\n", (ULONG)&(pMapComm->HsSpeed) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsState: %d\r\n", (ULONG)&(pMapComm->HsState) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "UsbState: %d\r\n", (ULONG)&(pMapComm->UsbState) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsMode: %d\r\n", (ULONG)&(pMapComm->HsMode) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtDataMode: %d\r\n", (ULONG)&(pMapComm->BtDataMode) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsDataMode: %d\r\n", (ULONG)&(pMapComm->HsDataMode) - (ULONG)pMapComm);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "HsDataMode = %d\r\n", pMapComm->HsDataMode);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+
+ sprintf((char *)Buffer, "BtDataMode = %d\r\n", pMapComm->BtDataMode);
+ Length = strlen((char *)Buffer);
+ LStatus = pMapLoader->pFunc(WRITE, &Handle, Buffer, &Length);
+/*
+
+ UBYTE Spare1;
+*/
+ //close file
+ LStatus = pMapLoader->pFunc(CLOSE, &Handle, NULL, NULL);
+ }
+}
+#endif
diff --git a/AT91SAM7S256/Source/c_cmd.c b/AT91SAM7S256/Source/c_cmd.c
index 87b3e24..e834625 100644
--- a/AT91SAM7S256/Source/c_cmd.c
+++ b/AT91SAM7S256/Source/c_cmd.c
@@ -1,11 +1,11 @@
//
// Date init 14.12.2004
//
-// Revision date $Date: 24-06-09 8:53 $
+// Revision date $Date: 26-02-10 11:38 $
//
// Filename $Workfile:: c_cmd.c $
//
-// Version $Revision: 14 $
+// Version $Revision: 15 $
//
// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $
//
@@ -43,13 +43,14 @@
#include <string.h>
#include <stdlib.h>
#include <math.h> // for sqrt, abs, and trig stuff
+#include <limits.h>
+#include <float.h>
#define VMProfilingCode 0
static IOMAPCMD IOMapCmd;
static VARSCMD VarsCmd;
static HEADER **pHeaders;
-static ULONG gInstrsToExecute;
static SLONG gPCDelta;
#define NUM_INTERP_FUNCS 16
#define NUM_SHORT_INTERP_FUNCS 8
@@ -192,7 +193,7 @@ static pSysCall SysCallFuncs[SYSCALL_COUNT] =
cCmdWrapKeepAlive,
cCmdWrapIOMapRead,
cCmdWrapIOMapWrite,
- cCmdWrapColorSensorRead,
+ cCmdWrapColorSensorRead, // new in 2.0
cCmdWrapCommBTOnOff, // 35
cCmdWrapCommBTConnection,
cCmdWrapCommHSWrite,
@@ -205,8 +206,61 @@ static pSysCall SysCallFuncs[SYSCALL_COUNT] =
cCmdWrapDatalogWrite,
cCmdWrapDatalogGetTimes, //45
cCmdWrapSetSleepTimeout,
- cCmdWrapListFiles //47
-
+ cCmdWrapListFiles, //47
+ cCmdWrapUndefinedSysCall, // leave a gap so that I don't have to keep renumbering system calls
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall, // 50
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall, // 55
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall, // 60
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall, // 65
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall, // 70
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall, // 75
+ cCmdWrapUndefinedSysCall,
+ cCmdWrapUndefinedSysCall,
+// enhanced NBC/NXC
+ cCmdWrapIOMapReadByID, // 78
+ cCmdWrapIOMapWriteByID,
+ cCmdWrapDisplayExecuteFunction, // 80
+ cCmdWrapCommExecuteFunction,
+ cCmdWrapLoaderExecuteFunction,
+ cCmdWrapFileFindFirst,
+ cCmdWrapFileFindNext,
+ cCmdWrapFileOpenWriteLinear, // 85
+ cCmdWrapFileOpenWriteNonLinear,
+ cCmdWrapFileOpenReadLinear,
+ cCmdWrapCommHSControl,
+ cCmdWrapCommLSWriteEx,
+ cCmdWrapFileSeek, // 90
+ cCmdWrapFileResize,
+ cCmdWrapDrawPictureArray,
+ cCmdWrapDrawPolygon,
+ cCmdWrapDrawEllipse,
+ cCmdWrapDrawFont, // 95
+ cCmdWrapMemoryManager,
+ cCmdWrapReadLastResponse,
+ cCmdWrapFileTell,
+ cCmdWrapRandomEx // 100 system call slots
+
// don't forget to update SYSCALL_COUNT in c_cmd.h
};
@@ -362,6 +416,107 @@ UBYTE cCmdBTGetDeviceType(UBYTE *pCOD)
return (Result);
}
+void cCmdSetVMState(VM_STATE newState)
+{
+ VarsCmd.VMState = newState;
+}
+
+UBYTE CMD_RESPONSE_LENGTH[256] =
+{
+ 3, // DCStartProgram (x00)
+ 3, // DCStopProgram (x01)
+ 3, // DCPlaySoundFile (x02)
+ 3, // DCPlayTone (x03)
+ 3, // DCSetOutputState (x04)
+ 3, // DCSetInputMode (x05)
+ 25, // DCGetOutputState (x06)
+ 16, // DCGetInputValues (x07)
+ 3, // DCResetInputScaledValue (x08)
+ 3, // DCMessageWrite (x09)
+ 3, // DCResetMotorPosition (x0a)
+ 5, // DCGetBatteryLevel (x0b)
+ 3, // DCStopSoundPlayback (x0c)
+ 7, // DCKeepAlive (x0d)
+ 4, // DCLSGetStatus (x0e)
+ 3, // DCLSWrite (x0f)
+ 20, // DCLSRead (x10)
+ 23, // DCGetCurrentProgramName (x11)
+ 0, // DCGetButtonState (not implemented) (x12)
+ 64, // DCMessageRead (x13)
+ 0, // DCRESERVED1 (x14)
+ 0, // DCRESERVED2 (x15)
+ 0, // DCRESERVED3 (x16)
+ 0, // DCRESERVED4 (x17)
+ 0, // DCRESERVED5 (x18)
+ 64, // DCDatalogRead (1.28+) (x19)
+ 3, // DCDatalogSetTimes (1.28+) (x1a)
+ 4, // DCBTGetContactCount (1.28+) (x1b)
+ 21, // DCBTGetContactName (1.28+) (x1c)
+ 4, // DCBTGetConnCount (1.28+) (x1d)
+ 21, // DCBTGetConnName (1.28+) (x1e)
+ 3, // DCSetProperty(1.28+) (x1f)
+ 7, // DCGetProperty (1.28+) (x20)
+ 3, // DCUpdateResetCount (1.28+) (x21)
+ 7, // RC_SET_VM_STATE (enhanced only) (x22)
+ 7, // RC_GET_VM_STATE (enhanced only) (x23)
+ 15, // RC_SET_BREAKPOINTS (enhanced only) (x24)
+ 15, // RC_GET_BREAKPOINTS (enhanced only) (x25)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (x26-x2f)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (x30-x3f)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (x40-x4f)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (x50-x5f)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (x60-x6f)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (x70-x7f)
+ 8, // OPENREAD = 0x80,
+ 4, // OPENWRITE = 0x81,
+ 64, // READ = 0x82, (actually is a variable length response)
+ 6, // WRITE = 0x83,
+ 4, // CLOSE = 0x84,
+ 23, // DELETE = 0x85,
+ 28, // FINDFIRST = 0x86,
+ 28, // FINDNEXT = 0x87,
+ 7, // VERSIONS = 0x88,
+ 4, // OPENWRITELINEAR = 0x89,
+ 7, // OPENREADLINEAR = 0x8A, (not actually implemented)
+ 4, // OPENWRITEDATA = 0x8B,
+ 8, // OPENAPPENDDATA = 0x8C,
+ 4, // CROPDATAFILE = 0x8D, /* New cmd for datalogging */
+ 0, // XXXXXXXXXXXXXX = 0x8E,
+ 0, // XXXXXXXXXXXXXX = 0x8F,
+ 34, // FINDFIRSTMODULE = 0x90,
+ 34, // FINDNEXTMODULE = 0x91,
+ 4, // CLOSEMODHANDLE = 0x92,
+ 0, // XXXXXXXXXXXXXX = 0x93,
+ 64, // IOMAPREAD = 0x94, (actually is a variable length response)
+ 9, // IOMAPWRITE = 0x95,
+ 0, // XXXXXXXXXXXXXX = 0x96,
+ 7, // BOOTCMD = 0x97, (can only be executed via USB)
+ 3, // SETBRICKNAME = 0x98,
+ 0, // XXXXXXXXXXXXXX = 0x99,
+ 10, // BTGETADR = 0x9A,
+ 33, // DEVICEINFO = 0x9B,
+ 0, // XXXXXXXXXXXXXX = 0x9C,
+ 0, // XXXXXXXXXXXXXX = 0x9D,
+ 0, // XXXXXXXXXXXXXX = 0x9E,
+ 0, // XXXXXXXXXXXXXX = 0x9F,
+ 3, // DELETEUSERFLASH = 0xA0,
+ 5, // POLLCMDLEN = 0xA1,
+ 64, // POLLCMD = 0xA2,
+ 44, // RENAMEFILE = 0xA3,
+ 3, // BTFACTORYRESET = 0xA4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (xA5-xAF)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (xB0-xBf)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (xC0-xCf)
+ 0, // RESIZEDATAFILE = 0xD0,
+ 0, // SEEKFROMSTART = 0xD1,
+ 0, // SEEKFROMCURRENT = 0xD2,
+ 0, // SEEKFROMEND = 0xD3
+ 0, // FILEPOSITION = 0xD4
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (xD5-xDF)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // (xE0-xEF)
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // (xF0-xFF)
+};
+
//cCmdHandleRemoteCommands is the registered handler for "direct" command protocol packets
//It is only intended to be called via c_comm's main protocol handler
UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
@@ -472,23 +627,52 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
{
UBYTE Port = pInBuf[1];
//Don't do anything if illegal port specification is made
- if (Port >= NO_OF_OUTPUTS && Port != 0xFF)
+ // supported ports are 0, 1, 2 == A, B, C
+ // 3 == AB, 4 == AC, 5 == BC, 6 == ABC
+ if (Port > RC_OUT_ABC && Port < RC_PORTS_AB)
{
RCStatus = ERR_RC_ILLEGAL_VAL;
break;
}
//0xFF is protocol defined to mean "all ports".
- if (Port == 0xFF)
- {
- FirstPort = 0;
- LastPort = NO_OF_OUTPUTS - 1;
+ switch(Port) {
+ case RC_PORTS_ALL:
+ case RC_OUT_ABC:
+ case RC_PORTS_AC:
+ case RC_OUT_AC:
+ {
+ FirstPort = 0;
+ LastPort = NO_OF_OUTPUTS - 1;
+ }
+ break;
+ case RC_PORTS_BC:
+ case RC_OUT_BC:
+ {
+ // B&C
+ FirstPort = 1;
+ LastPort = NO_OF_OUTPUTS - 1;
+ }
+ break;
+ case RC_PORTS_AB:
+ case RC_OUT_AB:
+ {
+ // A&B
+ FirstPort = 0;
+ LastPort = 1;
+ }
+ break;
+ default:
+ {
+ FirstPort = LastPort = Port;
+ }
+ break;
}
- else
- FirstPort = LastPort = Port;
for (i = FirstPort; i <= LastPort; i++)
{
+ if (((Port == RC_PORTS_AC) || (Port == RC_OUT_AC)) && (i > FirstPort) && (i < LastPort))
+ continue;
OUTPUT * pOut = &(pMapOutPut->Outputs[i]);
pOut->Speed = pInBuf[2];
pOut->Mode = pInBuf[3];
@@ -603,7 +787,7 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
//Echo port
pOutBuf[ResponseLen] = i;
ResponseLen++;
-
+
INPUTSTRUCT * pIn = &(pMapInput->Inputs[i]);
//Set "Valid?" boolean
@@ -768,7 +952,7 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
break;
}
- RCStatus = cCmdLSWrite(i, Count, &(pInBuf[4]), pInBuf[3]);
+ RCStatus = cCmdLSWrite(i, Count, &(pInBuf[4]), pInBuf[3], 0);
}
break;
@@ -866,6 +1050,7 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
// pInBuf[1] = Remove? (bool)
case RC_DATALOG_READ:
{
+#ifndef STRIPPED
if (SendResponse == TRUE)
{
RCStatus = cCmdDatalogGetSize(&Count);
@@ -888,13 +1073,16 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
memset(&(pOutBuf[ResponseLen]), 0, Count);
ResponseLen += Count;
}
+#endif
}
break;
case RC_DATALOG_SET_TIMES:
{
+#ifndef STRIPPED
//SyncTime SLONG
memcpy((PSZ)&IOMapCmd.SyncTime, (PSZ)&(pInBuf[1]), 4);
IOMapCmd.SyncTick= dTimerReadNoPoll();
+#endif
}
break;
@@ -967,6 +1155,14 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
pMapUi->SleepTimeout= value / 60000;
}
break;
+ case RC_PROP_DEBUGGING: { // ulong debug info
+ ULONG value;
+ memcpy((PSZ)&value, (PSZ)&(pInBuf[2]), 4);
+ VarsCmd.Debugging = (UBYTE)((value>>24)&0xFF);
+ VarsCmd.PauseClump = (UBYTE)((value>>16)&0xFF);
+ VarsCmd.PausePC = (CODE_INDEX)(value&0xFFFF);
+ }
+ break;
default:
//Unknown property -- still inform client to not expect any response bytes
NXT_BREAK;
@@ -988,7 +1184,14 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
}
break;
case RC_PROP_SLEEP_TIMEOUT: {
- ULONG value= (pMapUi->SleepTimeout * 60 * 1000);
+ ULONG value= (pMapUi->SleepTimeout * 60000);
+ memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&value, 4);
+ ResponseLen += 4;
+ }
+ break;
+ case RC_PROP_DEBUGGING: { // ulong debug info
+ ULONG value;
+ value = ((VarsCmd.Debugging<<24)|(VarsCmd.PauseClump<<16)|VarsCmd.PausePC);
memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&value, 4);
ResponseLen += 4;
}
@@ -1015,6 +1218,87 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
pMapOutPut->Outputs[i].Flags |= UPDATE_RESET_COUNT;
}
break;
+ case RC_SET_VM_STATE:
+ {
+ // don't change the VM state if the state is currently idle or resetting
+ if (VarsCmd.VMState > VM_IDLE && VarsCmd.VMState < VM_RESET1)
+ {
+ cCmdSetVMState((VM_STATE)pInBuf[1]);
+ // setting the VM state turns on debugging
+ VarsCmd.Debugging = TRUE;
+ if (VarsCmd.VMState == VM_RESET1)
+ IOMapCmd.ProgStatus = PROG_ABORT;
+ }
+ // fall through to RC_GET_VM_STATE
+ }
+ case RC_GET_VM_STATE:
+ {
+ if (SendResponse == TRUE)
+ {
+ // output the vm state, current clump and its relative program counter (4 bytes)
+ pOutBuf[ResponseLen] = VarsCmd.VMState;
+ ResponseLen++;
+ pOutBuf[ResponseLen] = VarsCmd.RunQ.Head;
+ ResponseLen++;
+ CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[VarsCmd.RunQ.Head]);
+ CODE_INDEX pc = (CODE_INDEX)(pClumpRec->PC-pClumpRec->CodeStart);
+ memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&(pc), 2);
+ ResponseLen += 2;
+ }
+ }
+ break;
+
+ case RC_SET_BREAKPOINTS:
+ {
+ CLUMP_ID Clump = (CLUMP_ID)pInBuf[1];
+ //Don't do anything if illegal clump specification is made
+ if (Clump >= VarsCmd.AllClumpsCount)
+ {
+ RCStatus = ERR_RC_ILLEGAL_VAL;
+ break;
+ }
+ // setting breakpoint information turns on debugging mode
+ VarsCmd.Debugging = TRUE;
+ CLUMP_BREAK_REC* pBreakpoints = VarsCmd.pAllClumps[Clump].Breakpoints;
+ // length varies from 6 bytes min to 18 bytes max
+ // clump byte, bpidx, bplocation (2 bytes), bp enabled, [...] terminal byte 0xFF
+ UBYTE idx = 2;
+ UBYTE bDone = FALSE;
+ while (!bDone) {
+ UBYTE bpIdx = (UBYTE)pInBuf[idx];
+ idx++;
+ memcpy((PSZ)(&(pBreakpoints[bpIdx].Location)), (PSZ)(&pInBuf[idx]), 2);
+ idx += 2;
+ pBreakpoints[bpIdx].Enabled = (UBYTE)pInBuf[idx];
+ idx++;
+ bDone = (((UBYTE)pInBuf[idx] == 0xFF) || (idx >= 18));
+ }
+ // fall through to RC_GET_BREAKPOINTS
+ }
+
+ case RC_GET_BREAKPOINTS:
+ {
+ if (SendResponse == TRUE)
+ {
+ // output the list of breakpoints for the specified clump ID
+ CLUMP_ID Clump = (CLUMP_ID)pInBuf[1];
+ //Don't do anything if illegal clump specification is made
+ if (Clump >= VarsCmd.AllClumpsCount)
+ {
+ RCStatus = ERR_RC_ILLEGAL_VAL;
+ break;
+ }
+ CLUMP_BREAK_REC* pBreakpoints = VarsCmd.pAllClumps[Clump].Breakpoints;
+ for(int j = 0; j < MAX_BREAKPOINTS; j++)
+ {
+ memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&(pBreakpoints[j].Location), 2);
+ ResponseLen += 2;
+ pOutBuf[ResponseLen] = pBreakpoints[j].Enabled;
+ ResponseLen++;
+ }
+ }
+ }
+ break;
default:
{
//Unknown remote command -- still inform client to not expect any response bytes
@@ -1055,12 +1339,20 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen)
//If telegram doesn't check out, do nothing. No errors are ever returned for reply telegrams.
}
- break;
+ // fall through to the default case
+// break;
default:
{
//Unhandled reply telegram. Do nothing.
//!!! Could/should stash unhandled/all replies somewhere so a syscall could read them
+ VarsCmd.LastResponseLength = CMD_RESPONSE_LENGTH[pInBuf[0]];
+ memset((PSZ)VarsCmd.LastResponseBuffer, 0, 64);
+ UBYTE len = VarsCmd.LastResponseLength - 1;
+ if (*pLen < len)
+ len = *pLen;
+ if (VarsCmd.LastResponseLength > 1)
+ memcpy((PSZ)VarsCmd.LastResponseBuffer, (PSZ)(&pInBuf[0]), len);
}
break;
};
@@ -1147,7 +1439,7 @@ void cCmdInit(void* pHeader)
VarsCmd.DirtyComm = FALSE;
VarsCmd.DirtyDisplay = FALSE;
- VarsCmd.VMState = VM_IDLE;
+ cCmdSetVMState(VM_IDLE);
#if defined (ARM_NXT)
//Make sure Pool is long-aligned
@@ -1204,15 +1496,17 @@ void cCmdCtrl(void)
VarsCmd.CmdCtrlCount++;
#endif
//Abort current program if cancel button is pressed
- if (IOMapCmd.DeactivateFlag == TRUE || pMapButton->State[BTN1] & PRESSED_EV)
+ if (IOMapCmd.DeactivateFlag == TRUE ||
+ ((pMapButton->State[BTN1] & pMapUi->AbortFlag) &&
+ ((pMapButton->State[BTN4] & PRESSED_EV) != PRESSED_EV))) // JCH 2010-01-13 Make sure enter button is not also pressed
{
IOMapCmd.DeactivateFlag = FALSE;
//Clear pressed event so it doesn't get double-counted by UI
- pMapButton->State[BTN1] &= ~PRESSED_EV;
+ pMapButton->State[BTN1] &= ~(pMapUi->AbortFlag);
//Go to VM_RESET1 state and report abort
- VarsCmd.VMState = VM_RESET1;
+ cCmdSetVMState(VM_RESET1);
IOMapCmd.ProgStatus = PROG_ABORT;
break;
}
@@ -1235,12 +1529,15 @@ void cCmdCtrl(void)
#if VMProfilingCode
CmdCtrlClumpTime[clump] += dTimerReadHiRes() - ClumpEnterTime;
#endif
+ // automatically switch from RUN_SINGLE to RUN_PAUSE after a single step
+ if (VarsCmd.VMState == VM_RUN_SINGLE)
+ cCmdSetVMState(VM_RUN_PAUSE);
//If RunQ and RestQ are empty, program is done, or wacko
if (!cCmdIsClumpIDSane(VarsCmd.RunQ.Head)) {
Continue = FALSE;
if(!cCmdIsClumpIDSane(VarsCmd.RestQ.Head)) {
- VarsCmd.VMState = VM_RESET1;
+ cCmdSetVMState(VM_RESET1);
IOMapCmd.ProgStatus = PROG_OK;
}
}
@@ -1258,20 +1555,20 @@ void cCmdCtrl(void)
else if (IS_ERR(Status)) // mem error is handled in InterpFromClump if possible
{
Continue = FALSE;
- VarsCmd.VMState = VM_RESET1;
- IOMapCmd.ProgStatus = PROG_ERROR;
+ cCmdSetVMState(VM_RESET1);
+ IOMapCmd.ProgStatus = Status;
}
else if (Status == STOP_REQ)
{
Continue = FALSE;
- VarsCmd.VMState = VM_RESET1;
+ cCmdSetVMState(VM_RESET1);
IOMapCmd.ProgStatus = PROG_OK;
}
else if (Status == BREAKOUT_REQ)
{
Continue = FALSE;
}
- } while (Continue == TRUE);
+ } while (Continue == TRUE && VarsCmd.VMState == VM_RUN_FREE);
#if VMProfilingCode
FinishTime= dTimerReadHiRes();
if(NotFirstCall)
@@ -1300,19 +1597,15 @@ void cCmdCtrl(void)
//2. Proceed to VM_RESET1 (some unneeded work, yes, but preserves contract with UI
if (IS_ERR(Status))
{
- IOMapCmd.ProgStatus = PROG_ERROR;
- VarsCmd.VMState = VM_RESET1;
+ IOMapCmd.ProgStatus = Status;
+ cCmdSetVMState(VM_RESET1);
}
//Else start running program
else
{
- VarsCmd.VMState = VM_RUN_FREE;
+ cCmdSetVMState(VM_RUN_FREE);
IOMapCmd.ProgStatus = PROG_RUNNING;
VarsCmd.StartTick = IOMapCmd.Tick;
- if(VarsCmd.VMState == VM_RUN_FREE)
- gInstrsToExecute = 20;
- else
- gInstrsToExecute= 1;
#if VM_BENCHMARK
//Re-init benchmark
@@ -1375,7 +1668,7 @@ void cCmdCtrl(void)
//Artificially set CommStatReset to BTBUSY to force at least one SETCMDMODE call (see VM_RESET2 case)
VarsCmd.CommStatReset = (SWORD)BTBUSY;
- VarsCmd.VMState = VM_RESET2;
+ cCmdSetVMState(VM_RESET2);
while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time
}
break;
@@ -1401,12 +1694,18 @@ void cCmdCtrl(void)
VarsCmd.DirtyComm = FALSE;
//Go to VM_IDLE state
- VarsCmd.VMState = VM_IDLE;
+ cCmdSetVMState(VM_IDLE);
IOMapCmd.ProgStatus = PROG_IDLE;
}
while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time
}
break;
+
+ case VM_RUN_PAUSE:
+ {
+ while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time
+ }
+ break;
}//END state machine switch
//Set tick to new value for next time 'round
@@ -1510,7 +1809,7 @@ NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize,
//Must have at least one clump and count can't exceed the NOT_A_CLUMP sentinel
if (FileClumpCount == 0 || FileClumpCount >= NOT_A_CLUMP)
- return (ERR_FILE);
+ return (ERR_CLUMP_COUNT);
else
VarsCmd.AllClumpsCount = (CLUMP_ID)FileClumpCount;
@@ -1519,7 +1818,7 @@ NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize,
//Can't have a valid program with no code
if (VarsCmd.CodespaceCount == 0)
- return (ERR_FILE);
+ return (ERR_NO_CODE);
//
// Now, calculate offsets for each data segment in the file
@@ -1560,7 +1859,7 @@ NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize,
if (CurrOffset != (DataSize - VarsCmd.CodespaceCount * 2))
{
NXT_BREAK;
- return (ERR_FILE);
+ return (ERR_INSANE_OFFSET);
}
//
@@ -1597,7 +1896,7 @@ NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize,
if (VarsCmd.PoolSize > POOL_MAX_SIZE)
{
NXT_BREAK;
- return (ERR_FILE);
+ return (ERR_BAD_POOL_SIZE);
}
return (NO_ERR);
@@ -1695,7 +1994,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
//If Loader returned error or bad file pointer, bail out
if (LOADER_ERR(LStatus) != SUCCESS || pData == NULL || DataSize == 0)
- return (ERR_FILE);
+ return (ERR_LOADER_ERR);
//Deactivate current program and re-initialize memory pool
cCmdDeactivateProgram();
@@ -1726,7 +2025,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
|| (VarsCmd.DataspaceSize == 0) )
{
NXT_BREAK;
- return ERR_FILE;
+ return ERR_SPOTCHECK_FAIL;
}
//Initialize CLUMP_RECs as contiguous list in RAM
@@ -1741,6 +2040,15 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
//Initialize remaining CLUMP_REC fields
clumpPtr->PC = clumpPtr->CodeStart;
clumpPtr->Link = NOT_A_CLUMP;
+ clumpPtr->Priority = INSTR_MAX_COUNT;
+ clumpPtr->CalledClump = NOT_A_CLUMP;
+
+ CLUMP_BREAK_REC* pBreakpoints = clumpPtr->Breakpoints;
+ for (j = 0; j < MAX_BREAKPOINTS; j++)
+ {
+ pBreakpoints[j].Location = 0;
+ pBreakpoints[j].Enabled = FALSE;
+ }
//Activate any clumps with CurrFireCount of 0
clumpPtr->CurrFireCount = clumpPtr->InitFireCount;
@@ -1828,7 +2136,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
}
//Programs with no active clumps constitutes an activation error
if (VarsCmd.RunQ.Head == NOT_A_CLUMP)
- return (ERR_FILE);
+ return (ERR_NO_ACTIVE_CLUMP);
else
{
// now that we know which clumps are scalar and poly, refresh dispatch table to match head
@@ -1852,7 +2160,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
|| (DefaultsOffset + FileOffsets.DynamicDefaultsSize != FileOffsets.DSDefaultsSize))
{
NXT_BREAK;
- return (ERR_FILE);
+ return (ERR_DEFAULT_OFFSETS);
}
//Copy Dynamic defaults from file
@@ -1869,7 +2177,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
if ((UBYTE *)VarsCmd.MemMgr.pDopeVectorArray != VarsCmd.pDataspace + DV_ARRAY[0].Offset)
{
NXT_BREAK;
- return (ERR_FILE);
+ return (ERR_MEMMGR_FAIL);
}
//Initialize message queues
@@ -1884,6 +2192,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
}
}
+#ifndef STRIPPED
//Initialize datalog queue
VarsCmd.DatalogBuffer.ReadIndex = 0;
VarsCmd.DatalogBuffer.WriteIndex = 0;
@@ -1891,6 +2200,7 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
{
VarsCmd.DatalogBuffer.Datalogs[j] = NOT_A_DS_ID;
}
+#endif
// now that we've loaded program, prime memmgr dopevectors based upon number of handles in ds.
ULONG numHandles= DV_ARRAY[0].Count/2;
@@ -1905,6 +2215,14 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName)
gRequestSemData= 0;
// preload all calibration coefficients into mem
cCmdLoadCalibrationFiles();
+ // initialize the graphic globals
+ gpPassedImgVars = NULL;
+ memset(gpImgData,0,sizeof(gpImgData));
+ gPassedVarsCount = 0;
+ // configure debugging flags in VarsCmd
+ VarsCmd.Debugging = FALSE;
+ VarsCmd.PauseClump = NOT_A_CLUMP;
+ VarsCmd.PausePC = 0xFFFF;
return (Status);
}
@@ -1913,6 +2231,10 @@ void cCmdDeactivateProgram()
{
UBYTE i, tmp;
+ // reset the DS and DVA Offsets
+ IOMapCmd.OffsetDVA = 0xFFFF;
+ IOMapCmd.OffsetDS = 0xFFFF;
+
//Wipe away all references into the pool and clear all run-time data
VarsCmd.pCodespace = NULL;
VarsCmd.CodespaceCount = 0;
@@ -1951,12 +2273,18 @@ void cCmdDeactivateProgram()
tmp = i;
//Close file
if (*(VarsCmd.FileHandleTable[i]) != 0)
- pMapLoader->pFunc(CROPDATAFILE, &tmp, NULL, NULL);
+ pMapLoader->pFunc(CROPDATAFILE, &tmp, NULL, NULL); /*CLOSE*/
}
//Clear FileHandleTable
memset(VarsCmd.FileHandleTable, 0, sizeof(VarsCmd.FileHandleTable));
-
+
+ // reset AbortFlag to default value
+ pMapUi->AbortFlag = PRESSED_EV;
+
+ // reset Contrast to default value
+ pMapDisplay->Contrast = DISPLAY_CONTRAST_DEFAULT;
+
return;
}
@@ -2227,6 +2555,49 @@ NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex)
return (Status);
}
+UBYTE cCmdIsClumpOnAMutexWaitQ(CLUMP_ID Clump)
+{
+ //Make sure Clump's ID is valid
+ NXT_ASSERT(cCmdIsClumpIDSane(Clump));
+ DATA_ARG Arg1;
+ MUTEX_Q * Mutex;
+ for (Arg1=0; Arg1 < VarsCmd.DataspaceCount; Arg1++)
+ {
+ if (VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX)
+ {
+ Mutex = cCmdDSPtr(Arg1, 0);
+ if (cCmdIsClumpOnQ(&(Mutex->WaitQ), Clump))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+NXT_STATUS cCmdReleaseAllMutexes(CLUMP_ID Clump)
+{
+ //Make sure Clump's ID is valid
+ NXT_ASSERT(cCmdIsClumpIDSane(Clump));
+ DATA_ARG Arg1;
+ MUTEX_Q * Mutex;
+ UBYTE bFoundWaitingMutex = FALSE;
+ for (Arg1=0; Arg1 < VarsCmd.DataspaceCount; Arg1++)
+ {
+ if (VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX)
+ {
+ Mutex = cCmdDSPtr(Arg1, 0);
+ // if this clump owns the Mutex then release it
+ if (Mutex->Owner == Clump)
+ cCmdReleaseMutex(Mutex);
+ // also make sure that this Clump is not waiting in this mutex's wait queue
+ if (!bFoundWaitingMutex && cCmdIsClumpOnQ(&(Mutex->WaitQ), Clump)) {
+ bFoundWaitingMutex = TRUE;
+ cCmdDeQClump(&(Mutex->WaitQ), Clump);
+ cCmdEnQClump(&(VarsCmd.RunQ), Clump);
+ }
+ }
+ }
+ return (NO_ERR);
+}
NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex)
{
@@ -2253,6 +2624,39 @@ NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex)
return (NO_ERR);
}
+NXT_STATUS cCmdStopClump(CLUMP_ID Clump)
+{
+ // first check whether this clump has called another clump
+ CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[Clump]);
+ if (pClumpRec->CalledClump != NOT_A_CLUMP) {
+ // in this situation we know that this clump
+ // is not on any queues of any kind (run, rest, or wait)
+ // so instead of trying to stop THIS clump we will
+ // try to stop the clump it called instead
+ cCmdStopClump(pClumpRec->CalledClump);
+ }
+ else
+ {
+ // release any mutexes owned by this clump
+ // and remove it from any wait queues that it might be on
+ cCmdReleaseAllMutexes(Clump);
+ if (cCmdIsClumpOnQ(&(VarsCmd.RunQ), Clump)) {
+ // remove the specified clump from the run queue if it is on it
+ cCmdDeQClump(&(VarsCmd.RunQ), Clump);
+ }
+ else if (cCmdIsClumpOnQ(&(VarsCmd.RestQ), Clump)) {
+ // if the specified clump happened to be sleeping then
+ // remove it from the rest queue
+ cCmdDeQClump(&(VarsCmd.RestQ), Clump);
+ }
+ // since we have stopped that clump we should reset its clump rec values.
+ pClumpRec->PC = pClumpRec->CodeStart;
+ pClumpRec->CurrFireCount = pClumpRec->InitFireCount;
+ pClumpRec->awakenTime = 0;
+ }
+ return (NO_ERR);
+}
+
// No instruction to do this yet, but put current clump to sleep until awakeTime occurs
NXT_STATUS cCmdSleepClump(ULONG time)
{
@@ -3133,6 +3537,7 @@ NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length)
{
NXT_STATUS Status = NO_ERR;
+#ifndef STRIPPED
if (pData == NULL)
return ERR_ARG;
@@ -3175,11 +3580,13 @@ NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length)
//Advance write index
VarsCmd.DatalogBuffer.WriteIndex = (VarsCmd.DatalogBuffer.WriteIndex + 1) % DATALOG_QUEUE_DEPTH;
+#endif
return Status;
}
NXT_STATUS cCmdDatalogGetSize(UWORD * Size)
{
+#ifndef STRIPPED
DV_INDEX ReadDVIndex;
if (Size == NULL)
@@ -3203,11 +3610,16 @@ NXT_STATUS cCmdDatalogGetSize(UWORD * Size)
*Size = 0;
return (STAT_MSG_EMPTY_MAILBOX);
}
+#else
+ *Size = 0;
+ return (NO_ERR);
+#endif
}
NXT_STATUS cCmdDatalogRead(UBYTE * pBuffer, UWORD Length, UBYTE Remove)
{
NXT_STATUS Status = NO_ERR;
+#ifndef STRIPPED
DV_INDEX ReadDVIndex;
if (pBuffer == NULL)
@@ -3248,7 +3660,7 @@ NXT_STATUS cCmdDatalogRead(UBYTE * pBuffer, UWORD Length, UBYTE Remove)
return (STAT_MSG_EMPTY_MAILBOX);
}
-
+#endif
return Status;
}
@@ -3391,13 +3803,14 @@ void cCmdSetByte(void * pVal, ULONG NewVal);
void cCmdSetWord(void * pVal, ULONG NewVal);
void cCmdSetLong(void * pVal, ULONG NewVal);
void cCmdSetError(void * pVal, ULONG NewVal);
+void cCmdSetFloat(void * pVal, ULONG NewVal);
typedef ULONG (*pGetOperand)(void *);
static pGetOperand GetProcArray[11]= {cCmdGetUByte, cCmdGetUByte, cCmdGetSByte, cCmdGetUWord, cCmdGetSWord, cCmdGetULong, cCmdGetSLong, cCmdGetError, cCmdGetError, cCmdGetError, cCmdGetFloat}; // dup UByte to line up
typedef void (*pSetOperand)(void *, ULONG);
-static pSetOperand SetProcArray[9]= {cCmdSetByte, cCmdSetByte, cCmdSetByte, cCmdSetWord, cCmdSetWord, cCmdSetLong, cCmdSetLong, cCmdSetError, cCmdSetError}; // dup UByte to line up
+static pSetOperand SetProcArray[11]= {cCmdSetByte, cCmdSetByte, cCmdSetByte, cCmdSetWord, cCmdSetWord, cCmdSetLong, cCmdSetLong, cCmdSetError, cCmdSetError, cCmdSetError, cCmdSetFloat}; // dup UByte to line up
void cCmdSetError(void * pVal, ULONG NewVal) {
NXT_BREAK;
@@ -3415,6 +3828,10 @@ void cCmdSetByte(void * pVal, ULONG NewVal) {
*(UBYTE*)pVal = (UBYTE)NewVal;
}
+void cCmdSetFloat(void * pVal, ULONG NewVal) {
+ *(float*)pVal = (float)NewVal;
+}
+
// only works on simple types, equivalent to resolve and get, but faster
ULONG cCmdGetScalarValFromDataArg(DATA_ARG DataArg, UWORD Offset)
{
@@ -3422,6 +3839,11 @@ ULONG cCmdGetScalarValFromDataArg(DATA_ARG DataArg, UWORD Offset)
return GetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset + Offset);
}
+float cCmdGetFloatValFromDataArg(DATA_ARG DataArg, UWORD Offset)
+{
+ DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg];
+ return (float)(*(float*)(VarsCmd.pDataspace + dsTOCPtr->DSOffset + Offset));
+}
ULONG cCmdGetError(void * pVal) {
NXT_BREAK;
@@ -3850,6 +4272,17 @@ UWORD cCmdGetDVIndex(DS_ELEMENT_ID DSElementID, UWORD Offset)
return DVIndex;
}
+UWORD cCmdArrayDimensions(DS_ELEMENT_ID DSElementID)
+{
+ NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID));
+ UWORD result = 0;
+ while (cCmdDSType(DSElementID) == TC_ARRAY)
+ {
+ result++;
+ DSElementID = INC_ID(DSElementID);
+ }
+ return result;
+}
UWORD cCmdArrayCount(DS_ELEMENT_ID DSElementID, UWORD Offset)
{
@@ -4165,10 +4598,39 @@ NXT_STATUS cCmdInterpFromClump()
pInstr = pClumpRec->PC; // abs
lastClumpInstr= pClumpRec->CodeEnd; // abs
- i= gInstrsToExecute;
+ if(VarsCmd.VMState == VM_RUN_FREE)
+ i = pClumpRec->Priority;
+ else
+ i = 1;
nextMSTick= dTimerGetNextMSTickCnt();
do
{
+ // are we debugging and are free running and reach a breakpoint/autopause?
+ if (VarsCmd.Debugging && (VarsCmd.VMState == VM_RUN_FREE))
+ {
+ CLUMP_BREAK_REC* pBreakpoints = pClumpRec->Breakpoints;
+ for(int j = 0; j < MAX_BREAKPOINTS; j++)
+ {
+ if (pBreakpoints[j].Enabled &&
+ (pBreakpoints[j].Location == (CODE_INDEX)(pClumpRec->PC-pClumpRec->CodeStart)))
+ {
+ cCmdSetVMState(VM_RUN_PAUSE);
+ return BREAKOUT_REQ;
+ }
+ }
+ // auto pause at clump == pauseClump and relative PC = pausePC
+ if ((Clump == VarsCmd.PauseClump) &&
+ ((CODE_INDEX)(pClumpRec->PC-pClumpRec->CodeStart) == VarsCmd.PausePC))
+ {
+ // pause the VM
+ cCmdSetVMState(VM_RUN_PAUSE);
+ // and turn off the auto pause flags
+ VarsCmd.PauseClump = NOT_A_CLUMP;
+ VarsCmd.PausePC = 0xFFFF;
+ return BREAKOUT_REQ;
+ }
+ }
+
#if VMProfilingCode
ULONG instrStartTime;
instrStartTime= dTimerReadHiRes();
@@ -4299,12 +4761,16 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode)
case OP_SUBRET:
{
NXT_ASSERT(cCmdIsDSElementIDSane(Arg1));
-
+ CLUMP_ID clump = *((CLUMP_ID *)cCmdDSScalarPtr(Arg1, 0));
+
//Take Subroutine off RunQ
//Add Subroutine's caller to RunQ
cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head);
- cCmdEnQClump(&(VarsCmd.RunQ), *((CLUMP_ID *)cCmdDSScalarPtr(Arg1, 0)));
+ cCmdEnQClump(&(VarsCmd.RunQ), clump);
+ CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[clump]);
+ pClumpRec->CalledClump = NOT_A_CLUMP;
+
Status = CLUMP_DONE;
}
break;
@@ -4319,6 +4785,22 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode)
}
break;
+ case OP_WAITI:
+ case OP_WAITV:
+ {
+ ULONG wait= 0;
+ if (opCode == OP_WAITV) {
+ wait = cCmdGetScalarValFromDataArg(Arg1, 0);
+ }
+ else
+ wait = Arg1;
+ if(wait == 0)
+ Status= ROTATE_QUEUE;
+ else
+ Status = cCmdSleepClump(wait + IOMapCmd.Tick); // put to sleep, to wake up wait ms in future
+ }
+ break;
+
case OP_GETTICK:
{
cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll());
@@ -4335,6 +4817,29 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode)
}
break;
+ case OP_STOPCLUMPIMMED:
+ {
+ // Release any mutexes that the clump we are stopping owns
+ CLUMP_ID Clump = (CLUMP_ID)Arg1;
+ cCmdStopClump(Clump);
+ }
+ break;
+
+ case OP_STARTCLUMPIMMED:
+ {
+ CLUMP_ID Clump = (CLUMP_ID)Arg1;
+ // only enqueue the clump if it is not already on one of the queues
+ // otherwise this is a no-op
+ if (!cCmdIsClumpOnQ(&(VarsCmd.RunQ), Clump) &&
+ !cCmdIsClumpOnQ(&(VarsCmd.RestQ), Clump) &&
+ !cCmdIsClumpOnAMutexWaitQ(Clump))
+ {
+ cCmdEnQClump(&(VarsCmd.RunQ), Clump); //Enqueue the specified clump
+ Status = CLUMP_SUSPEND;
+ }
+ }
+ break;
+
default:
{
//Fatal error: Unrecognized instruction
@@ -4436,13 +4941,10 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
polyUn2Dispatch ++;
UWORD Count;
UWORD Offset;
- SLONG TmpSLong;
- ULONG TmpULong;
+// SLONG TmpSLong;
+// ULONG TmpULong;
ULONG ArgVal2;
float FltArgVal2;
- char Buffer[30];
- char FormatString[5];
- UBYTE CheckTrailingZeros = 0;
NXT_ASSERT(pCode != NULL);
@@ -4451,7 +4953,10 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
Arg1 = pCode[1];
Arg2 = pCode[2];
- if (opCode == OP_NEG || opCode == OP_NOT || opCode == OP_TST || opCode == OP_SQRT || opCode == OP_ABS)
+ if (opCode == OP_NEG || opCode == OP_NOT || opCode == OP_TST ||
+ opCode == OP_CMNT || opCode == OP_SQRT || opCode == OP_ABS || opCode == OP_SIGN ||
+ (opCode >= OP_ACOS && opCode <= OP_FRAC) ||
+ (opCode >= OP_ACOSD && opCode <= OP_SINHD))
{
return cCmdInterpPolyUnop2(*pCode, Arg1, 0, Arg2, 0);
}
@@ -4468,7 +4973,13 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
{
//!!! Should throw error if TypeCode1 is non-scalar
// Accepting non-scalar destinations could have unpredictable results!
- cCmdSetScalarValFromDataArg(Arg1, Arg2);
+ pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1);
+ if (TypeCode1 == TC_SLONG)
+ *(ULONG*)pArg1 = (SWORD)Arg2;
+ else if (TypeCode1 == TC_ULONG)
+ *(ULONG*)pArg1 = (UWORD)Arg2;
+ else if (TypeCode1 < TC_ULONG)
+ cCmdSetScalarValFromDataArg(Arg1, Arg2);
}
break;
@@ -4510,16 +5021,33 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
}
break;
+ case OP_PRIORITY:
+ {
+ // set the priority of the specified clump
+ CLUMP_ID clump;
+ if (Arg2 != NOT_A_DS_ID)
+ clump = (CLUMP_ID)Arg1;
+ else
+ clump = VarsCmd.RunQ.Head;
+ CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[clump]);
+ pClumpRec->Priority = (UBYTE)Arg2;
+ }
+ break;
+
case OP_SUBCALL:
{
NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1));
NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1));
NXT_ASSERT(cCmdIsDSElementIDSane(Arg2));
+
+ CLUMP_ID clump = VarsCmd.RunQ.Head;
+ CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[clump]);
+ pClumpRec->CalledClump = (CLUMP_ID)Arg1;
- *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head;
+ *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = clump;
- cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ
+ cCmdDeQClump(&(VarsCmd.RunQ), clump); //Take caller off RunQ
cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ
Status = CLUMP_SUSPEND;
@@ -4618,6 +5146,7 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
case OP_NUMTOSTRING:
{
+ char Buffer[36];
//Assert that the destination is a string (array of bytes)
NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY);
NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE);
@@ -4628,65 +5157,40 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
if (TypeCode2 == TC_FLOAT)
{
- pArg2 = cCmdResolveDataArg(Arg2, 0, NULL);
- FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2);
- // is number too big for display? then format differently and don't bother with trailing zeros
- if ((FltArgVal2 > 9999999999999.99f)||(FltArgVal2 < -999999999999.99f)){ // these are the widest %.2f numbers that will fit on display
- strcpy (FormatString, "%.6g");
- }
- else{
- strcpy (FormatString, "%.2f");
- CheckTrailingZeros = 1;
+ FltArgVal2 = cCmdGetFloatValFromDataArg(Arg2, 0);
+ if ((FltArgVal2 > 99999999999.9999f)||(FltArgVal2 < -9999999999.9999f)){ // these are the widest %.4f numbers that will fit on display
+ Count = sprintf(Buffer, "%.6g", FltArgVal2);
}
- Count = sprintf(Buffer, FormatString, FltArgVal2);
+ else
+ Count = sprintf(Buffer, "%.4f", FltArgVal2);
Count++; //add room for null terminator
-
- if (CheckTrailingZeros){
- // Determine if the trailing digits are zeros. If so, drop them
- if (Buffer[Count-2] == 0x30) { // NOTE: 0x30 is ASCII 0
- if (Buffer[Count-3] == 0x30){
- strcpy (FormatString, "%.0f"); // the last two digits = 0, copy as integer
- Count = Count - 3; // don't need memory for decimal and 2 ascii characters
- }
- else {
- strcpy (FormatString, "%.1f"); // only the 2nd digit = 0 so drop it, but keep the tenths place
- Count = Count - 1; // don't need memory for 2nd ascii character
- }
- }
+ // remove trailing zeros
+ while (Buffer[Count-2] == 0x30) {
+ Buffer[Count-2] = 0x00;
+ Count--;
+ }
+ // if last character is now a period then delete it too
+ if (Buffer[Count-2] == '.') {
+ Buffer[Count-2] = 0x00;
+ Count--;
}
}
else
{
- ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0);
- //Calculate size of array
- if (ArgVal2 == 0)
- Count = 1;
- else {
- Count = 0;
- SLONG digits= 0;
- ULONG Tmp= 1;
- if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE)
+ ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0);
+
+ // Calculate size of array
+ if (IS_SIGNED_TYPE(TypeCode2))
{
- TmpSLong = (SLONG)ArgVal2;
- //Add room for negative sign
- if (TmpSLong < 0) {
- Count++;
- TmpULong= -TmpSLong;
- }
- else
- TmpULong= ArgVal2;
+ Count = sprintf(Buffer, "%d", (SLONG)ArgVal2);
}
else
- TmpULong= ArgVal2;
-
- while (Tmp <= TmpULong && digits < 10) { // maxint is ten digits, max
- Tmp *= 10;
- digits++;
+ {
+ Count = sprintf(Buffer, "%u", ArgVal2);
}
- Count += digits;
- }
- //add room for NULL terminator
- Count++;
+
+ //add room for NULL terminator
+ Count++;
}
//Allocate array
@@ -4697,18 +5201,7 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1);
//Populate array
- if (TypeCode2 == TC_FLOAT)
- {
- sprintf(pArg1, FormatString, FltArgVal2);
- }
- else if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE)
- {
- sprintf(pArg1, "%d", (SLONG)ArgVal2);
- }
- else
- {
- sprintf(pArg1, "%u", ArgVal2);
- }
+ memcpy(pArg1, Buffer, Count);
}
break;
@@ -4800,6 +5293,8 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset
TypeCode1 = cCmdDSType(Arg1);
TypeCode2 = cCmdDSType(Arg2);
+ UBYTE opCode = OP_CODE(&Code);
+
//Simple case, scalar. Solve and return.
if (!IS_AGGREGATE_TYPE(TypeCode2))
{
@@ -4817,7 +5312,7 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset
else
{
ArgVal2= cCmdGetScalarValFromDataArg(Arg2, Offset2);
- if(OP_CODE(&Code) == OP_MOV)
+ if(opCode == OP_MOV)
ArgVal1= ArgVal2;
else
ArgVal1 = cCmdUnop2(Code, ArgVal2, TypeCode2);
@@ -4828,11 +5323,11 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset
//At least one of the args is an aggregate type
- if(TypeCode1 == TC_ARRAY && TypeCode2 == TC_ARRAY) {
+ if(TypeCode1 == TC_ARRAY && TypeCode2 == TC_ARRAY && opCode == OP_MOV) {
TYPE_CODE tc1, tc2;
tc1= cCmdDSType(INC_ID(Arg1));
tc2= cCmdDSType(INC_ID(Arg2));
- if(tc1 <= TC_LAST_INT_SCALAR && tc1 == tc2) {
+ if((tc1 <= TC_LAST_INT_SCALAR || tc1 == TC_FLOAT) && tc1 == tc2) {
void *pArg1, *pArg2;
ULONG Count = cCmdArrayCount(Arg2, Offset2);
Status = cCmdDSArrayAlloc(Arg1, Offset1, Count);
@@ -4943,6 +5438,10 @@ ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode)
return cCmdCompare(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode);
else if(opCode == OP_ABS)
return abs(Operand);
+ else if (opCode == OP_CMNT)
+ return (~Operand);
+ else if (opCode == OP_SIGN)
+ return (((SLONG)Operand) < 0) ? -1 : ((Operand == 0) ? 0 : 1);
else
{
//Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller)
@@ -4951,9 +5450,13 @@ ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode)
}
}
+#define DEG2RAD 0.017453F
+#define RAD2DEG 57.29578F
+
float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode)
{
UBYTE opCode;
+ float ip, fp;
opCode = OP_CODE((&Code));
if(opCode == OP_MOV)
@@ -4968,9 +5471,10 @@ float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode)
return cCmdCompareFlt(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode);
else if(opCode == OP_ABS)
return fabsf(Operand);
+ else if (opCode == OP_SIGN)
+ return (Operand < 0) ? -1 : ((Operand == 0) ? 0 : 1);
else if(opCode == OP_SQRT)
return sqrtf(Operand);
-#if 0
else if(opCode == OP_SIN)
return sinf(Operand);
else if(opCode == OP_COS)
@@ -4983,7 +5487,50 @@ float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode)
return acosf(Operand);
else if(opCode == OP_ATAN)
return atanf(Operand);
-#endif
+ else if(opCode == OP_CEIL)
+ return ceilf(Operand);
+ else if(opCode == OP_EXP)
+ return expf(Operand);
+ else if(opCode == OP_FLOOR)
+ return floorf(Operand);
+ else if(opCode == OP_LOG)
+ return logf(Operand);
+ else if(opCode == OP_LOG10)
+ return log10f(Operand);
+ else if (opCode == OP_TRUNC)
+ {
+ modff(Operand, &ip);
+ return ip;
+ }
+ else if (opCode == OP_FRAC)
+ {
+ fp = modff(Operand, &ip);
+ return fp;
+ }
+ else if(opCode == OP_SIND)
+ return sinf((float)Operand*DEG2RAD);
+ else if(opCode == OP_COSD)
+ return cosf((float)Operand*DEG2RAD);
+ else if(opCode == OP_TAND)
+ return tanf((float)Operand*DEG2RAD);
+ else if(opCode == OP_ASIND)
+ return (float)(asinf(Operand)*RAD2DEG);
+ else if(opCode == OP_ACOSD)
+ return (float)(acosf(Operand)*RAD2DEG);
+ else if(opCode == OP_ATAND)
+ return (float)(atanf(Operand)*RAD2DEG);
+ else if(opCode == OP_TANH)
+ return tanhf(Operand);
+ else if(opCode == OP_COSH)
+ return coshf(Operand);
+ else if(opCode == OP_SINH)
+ return sinhf(Operand);
+ else if(opCode == OP_TANHD)
+ return tanhf((float)Operand*DEG2RAD);
+ else if(opCode == OP_COSHD)
+ return coshf((float)Operand*DEG2RAD);
+ else if(opCode == OP_SINHD)
+ return sinhf((float)Operand*DEG2RAD);
else
{
//Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller)
@@ -5027,7 +5574,7 @@ NXT_STATUS cCmdIOGetSet(ULONG opCode, DATA_ARG Arg1, DATA_ARG Arg2, DATA_ARG Arg
pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2);
TypeCode1= cCmdDSType(Arg1);
pArg1= cCmdDSScalarPtr(Arg1, 0);
- if(TypeCode1 <= TC_SBYTE && TypeCode1 <= TC_SBYTE) // seems really common
+ if(TypeCode1 <= TC_SBYTE && TypeCode2 <= TC_SBYTE) // seems really common
*(UBYTE*)pArg1= *(UBYTE*)pArg2;
else
cCmdSetVal(pArg1, TypeCode1, cCmdGetVal(pArg2, TypeCode2));
@@ -5126,6 +5673,9 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode)
UBYTE CmpBool;
DV_INDEX DVIndex1, DVIndex2;
UWORD i;
+ void *pArg1 = NULL, *pArg2 = NULL;
+ UWORD Count;
+ TYPE_CODE TypeCode1;
polyBinopDispatch ++;
gPCDelta= 4;
@@ -5136,7 +5686,9 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode)
Arg2 = pCode[2];
Arg3 = pCode[3];
- if (opCode <= OP_XOR) // && ! OP_NEG, can't happen since it is unop
+ if ((opCode <= OP_XOR) ||
+ (opCode >= OP_LSL && opCode <= OP_ROTR) ||
+ (opCode == OP_ATAN2) || (opCode == OP_POW) || (opCode == OP_ATAN2D)) // && ! OP_NEG, can't happen since it is unop
Status= cCmdInterpPolyBinop(opCode, Arg1, 0, Arg2, 0, Arg3, 0);
else if(opCode >= OP_SETIN && opCode <= OP_GETOUT)
Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3);
@@ -5205,16 +5757,19 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode)
NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY);
+ // determine the type of the array destination arg
+ TYPE_CODE TypeCode = cCmdDSType(INC_ID(Arg1));
+
+ // How many elements do we want?
ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0;
Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)ArgVal3);
if (!IS_ERR(Status))
{
DVIndex1 = cCmdGetDVIndex(Arg1, 0);
- if(cCmdDSType(Arg2) <= TC_LAST_INT_SCALAR)
+ if(cCmdDSType(Arg2) <= TC_LAST_INT_SCALAR && TypeCode <= TC_LAST_INT_SCALAR)
{
ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0);
- TYPE_CODE TypeCode= cCmdDSType(INC_ID(Arg1));
for (i = 0; i < ArgVal3; i++) // could init ptr and incr by offset GM???
{
//copy Arg2 into each element of Arg1
@@ -5228,6 +5783,79 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode)
}
break;
+ case OP_FMTNUM:
+ {
+ //Check that the destination is a string (array of bytes)
+ if (cCmdDSType(Arg1) != TC_ARRAY || cCmdDSType(INC_ID(Arg1)) != TC_UBYTE) {
+ Status = ERR_INSTR;
+ return (Status);
+ }
+
+ //Check that the format is a string (array of bytes)
+ if (cCmdDSType(Arg2) != TC_ARRAY || cCmdDSType(INC_ID(Arg2)) != TC_UBYTE) {
+ Status = ERR_INSTR;
+ return (Status);
+ }
+
+ pArg2 = cCmdResolveDataArg(Arg2, 0, NULL);
+ TYPE_CODE TypeCode3 = cCmdDSType(Arg3);
+
+ //Make sure we're trying to convert a scalar/float to a string
+ if (TypeCode3 == TC_VOID || (TypeCode3 > TC_LAST_INT_SCALAR && TypeCode3 != TC_FLOAT)) {
+ Status = ERR_INSTR;
+ return (Status);
+ }
+
+ char fmtBuf[256]; // arbitrary limit!!!
+ // handle floats separately from scalar types
+ if (TypeCode3 == TC_FLOAT) {
+ float FltArgVal3 = cCmdGetFloatValFromDataArg(Arg3, 0);
+ Count = sprintf(fmtBuf, pArg2, FltArgVal3);
+ }
+ else
+ {
+ ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0);
+ // Calculate size of array
+ if (IS_SIGNED_TYPE(TypeCode3))
+ {
+ Count = sprintf(fmtBuf, pArg2, (SLONG)ArgVal3);
+ }
+ else
+ {
+ Count = sprintf(fmtBuf, pArg2, ArgVal3);
+ }
+ }
+
+ //add room for NULL terminator
+ Count++;
+
+ //Allocate array
+ Status = cCmdDSArrayAlloc(Arg1, 0, Count);
+ if (IS_ERR(Status))
+ return Status;
+
+ pArg1 = cCmdResolveDataArg(Arg1, 0, NULL);
+
+ //Populate array
+ memcpy(pArg1, fmtBuf, Count);
+ }
+ break;
+
+ case OP_ADDROF:
+ {
+ pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1);
+ if (TypeCode1 == TC_ULONG) {
+ pArg2 = cCmdResolveDataArg(Arg2, 0, NULL);
+ if ((UBYTE)Arg3) // relative address requested
+ *(ULONG*)pArg1 = (ULONG)pArg2 - (ULONG)(IOMapCmd.MemoryPool);
+ else
+ *(ULONG*)pArg1 = (ULONG)pArg2;
+ }
+ else
+ Status = ERR_INSTR; // output argument MUST be an unsigned long type
+ }
+ break;
+
default:
{
//Fatal error: Unrecognized instruction
@@ -5470,6 +6098,70 @@ ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE Lef
return cCmdCompare(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType);
}
+ case OP_LSL:
+ {
+ if (((SLONG)RightOp) <= 0)
+ return LeftOp; // negative shifts == shifting by zero
+ else
+ return LeftOp << RightOp;
+ }
+
+ case OP_LSR:
+ {
+ if (((SLONG)RightOp) <= 0)
+ return LeftOp; // negative shifts == shifting by zero
+ else
+ return LeftOp >> RightOp;
+ }
+
+ case OP_ASL:
+ {
+ if (((SLONG)RightOp) <= 0)
+ return LeftOp; // negative shifts == shifting by zero
+ else if (!IS_SIGNED_TYPE(LeftType))
+ return LeftOp << RightOp;
+ else
+ return LeftOp * (1 << RightOp);
+ }
+
+ case OP_ASR:
+ {
+ if (((SLONG)RightOp) <= 0)
+ return LeftOp; // negative shifts == shifting by zero
+ else if (!IS_SIGNED_TYPE(LeftType))
+ return LeftOp >> RightOp;
+ else
+ return ((SLONG)LeftOp) / (1 << RightOp);
+ }
+
+ case OP_ROTL:
+ {
+ if (((SLONG)RightOp) <= 0)
+ return LeftOp; // negative rotates == rotating by zero
+ else {
+ if (LeftType == TC_ULONG || LeftType == TC_SLONG)
+ return (LeftOp << RightOp) | (LeftOp >> (32 - RightOp));
+ else if (LeftType == TC_UWORD || LeftType == TC_SWORD)
+ return (((UWORD)LeftOp) << RightOp) | (((UWORD)LeftOp) >> (16 - RightOp));
+ else if (LeftType == TC_UBYTE || LeftType == TC_SBYTE)
+ return (((UBYTE)LeftOp) << RightOp) | (((UBYTE)LeftOp) >> (8 - RightOp));
+ }
+ }
+
+ case OP_ROTR:
+ {
+ if (((SLONG)RightOp) <= 0)
+ return LeftOp; // negative rotates == rotating by zero
+ else {
+ if (LeftType == TC_ULONG || LeftType == TC_SLONG)
+ return (LeftOp >> RightOp) | (LeftOp << (32 - RightOp));
+ else if (LeftType == TC_UWORD || LeftType == TC_SWORD)
+ return (((UWORD)LeftOp) >> RightOp) | (((UWORD)LeftOp) << (16 - RightOp));
+ else if (LeftType == TC_UBYTE || LeftType == TC_SBYTE)
+ return (((UBYTE)LeftOp) >> RightOp) | (((UBYTE)LeftOp) << (8 - RightOp));
+ }
+ }
+
default:
{
//Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller)
@@ -5519,7 +6211,7 @@ float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE
if (RightOp == 0)
return (LeftOp);
- return (SLONG)LeftOp % (SLONG)RightOp;
+ return fmodf(LeftOp, RightOp);
}
case OP_AND:
@@ -5542,6 +6234,26 @@ float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE
return cCmdCompareFlt(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType);
}
+ case OP_ATAN2:
+ {
+ return atan2f(LeftOp, RightOp);
+ }
+
+ case OP_POW:
+ {
+ float intpart, fracpart;
+ fracpart = modff(RightOp, &intpart);
+ if (LeftOp < 0 && fracpart != 0)
+ return 0; // make the result zero if you try to raise a negative number to a fractional exponent
+ else
+ return powf(LeftOp, RightOp);
+ }
+
+ case OP_ATAN2D:
+ {
+ return (float)(atan2f(LeftOp, RightOp)*RAD2DEG);
+ }
+
default:
{
//Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller)
@@ -5588,13 +6300,15 @@ NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode)
return Status;
}
-ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveArrInt= 0, moveOther= 0;
+ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveIntFloat= 0, moveFloatInt= 0, moveArrInt= 0, moveOther= 0;
NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2)
{
NXT_STATUS Status;
DS_TOC_ENTRY *TOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1],
*TOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2];
TYPE_CODE tc1= TOC1Ptr->TypeCode, tc2= TOC2Ptr->TypeCode;
+ UBYTE ElemSize1 = cCmdSizeOf((TOC1Ptr+1)->TypeCode),
+ ElemSize2 = cCmdSizeOf((TOC2Ptr+1)->TypeCode);
void *pArg1, *pArg2;
if(tc1 <= TC_LAST_INT_SCALAR && tc2 <= TC_LAST_INT_SCALAR)
@@ -5628,10 +6342,46 @@ NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2)
*(float*)pArg1= *(float*)pArg2;
Status= NO_ERR;
}
- //!!! Optimized move for arrays of ints.
- else if ((tc1 == TC_ARRAY) && (tc2 == TC_ARRAY)
- && ((TOC1Ptr+1)->TypeCode <= TC_LAST_INT_SCALAR)
- && ((TOC1Ptr+1)->TypeCode == (TOC2Ptr+1)->TypeCode))
+ else if(tc1 == TC_FLOAT && tc2 <= TC_LAST_INT_SCALAR) { // int to float
+ moveIntFloat++;
+ pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset;
+ pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset;
+ if (tc2 == TC_SLONG)
+ *(float*)pArg1 = *(SLONG*)pArg2;
+ else if (tc2 == TC_ULONG)
+ *(float*)pArg1 = *(ULONG*)pArg2;
+ else if (tc2 == TC_SBYTE)
+ *(float*)pArg1 = *(SBYTE*)pArg2;
+ else if (tc2 == TC_UBYTE)
+ *(float*)pArg1 = *(UBYTE*)pArg2;
+ else if (tc2 == TC_UWORD)
+ *(float*)pArg1 = *(UWORD*)pArg2;
+ else
+ *(float*)pArg1= *(SWORD*)pArg2;
+ Status= NO_ERR;
+ }
+ else if(tc2 == TC_FLOAT && tc1 <= TC_LAST_INT_SCALAR) { // float to int
+ moveFloatInt++;
+ pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset;
+ pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset;
+ if (tc1 == TC_SLONG)
+ *(SLONG*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_ULONG)
+ *(ULONG*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_SBYTE)
+ *(SBYTE*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_UBYTE)
+ *(UBYTE*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_UWORD)
+ *(UWORD*)pArg1 = *(float*)pArg2;
+ else
+ *(SWORD*)pArg1 = *(float*)pArg2;
+ Status= NO_ERR;
+ }
+ //!!! Optimized move for arrays of ints and floats.
+ else if ((tc1 == TC_ARRAY) && (tc2 == TC_ARRAY) &&
+ (((TOC1Ptr+1)->TypeCode <= TC_LAST_INT_SCALAR && ElemSize1 == ElemSize2) ||
+ ((TOC1Ptr+1)->TypeCode == TC_FLOAT && (TOC2Ptr+1)->TypeCode == TC_FLOAT)))
{
ULONG Count;
moveArrInt++;
@@ -5697,6 +6447,23 @@ NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode)
}
+ULONG cCmdGetPortFromValue(ULONG val, ULONG i)
+{
+ ULONG result = NO_OF_OUTPUTS; // invalid NO-OP output
+ if (val < NO_OF_OUTPUTS)
+ result = val;
+ else
+ {
+ if (val <= RC_OUT_ABC)
+ {
+ result = i;
+ if ((val == RC_OUT_BC) || (val == RC_OUT_AC && i))
+ result++;
+ }
+ }
+ return result;
+}
+
//OP_SETOUT gets it's own interpreter function because it is relatively complex
// (called from cCmdInterpOther())
//This also serves as a convenient breakpoint stop for investigating output module behavior
@@ -5708,7 +6475,7 @@ NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode)
*pPort = NULL;
DS_ELEMENT_ID PortArg;
UWORD PortCount, InstrSize;
- ULONG Port, FieldTableIndex, i, j;
+ ULONG Port, FieldTableIndex, i, j, val = 0;
DV_INDEX DVIndex;
//Arg1 = InstrSize
@@ -5730,7 +6497,17 @@ NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode)
PortCount = cCmdArrayCount(PortArg, 0);
}
else
- PortCount = 1;
+ {
+ // arg may refer to multiple ports
+ // (0, 1, 2 are single ports;
+ val = cCmdGetScalarValFromDataArg(PortArg, 0);
+ if (val < NO_OF_OUTPUTS)
+ PortCount = 1;
+ else if (val < RC_OUT_ABC)
+ PortCount = 2;
+ else
+ PortCount = 3;
+ }
//For each port, process all the tuples
for (i = 0; i < PortCount; i++)
@@ -5742,7 +6519,7 @@ NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode)
}
else
{
- Port = cCmdGetScalarValFromDataArg(PortArg, 0);
+ Port = cCmdGetPortFromValue(val, i);
}
//If user specified a valid port, process the tuples. Else, this port is a no-op
@@ -5771,6 +6548,174 @@ NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode)
}
+void shell_sort_u1(UBYTE* A, UWORD size)
+{
+ UWORD i, j, increment;
+ UBYTE temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
+void shell_sort_s1(SBYTE* A, UWORD size)
+{
+ UWORD i, j, increment;
+ SBYTE temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
+void shell_sort_u2(UWORD* A, UWORD size)
+{
+ UWORD i, j, increment;
+ UWORD temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
+void shell_sort_s2(SWORD* A, UWORD size)
+{
+ UWORD i, j, increment;
+ SWORD temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
+void shell_sort_u4(ULONG* A, UWORD size)
+{
+ UWORD i, j, increment;
+ ULONG temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
+void shell_sort_s4(SLONG* A, UWORD size)
+{
+ UWORD i, j, increment;
+ SLONG temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
+void shell_sort_flt(float* A, UWORD size)
+{
+ UWORD i, j, increment;
+ float temp;
+ increment = size / 2;
+
+ while (increment > 0) {
+ for (i = increment; i < size; i++) {
+ j = i;
+ temp = A[i];
+ while ((j >= increment) && (A[j-increment] > temp)) {
+ A[j] = A[j - increment];
+ j = j - increment;
+ }
+ A[j] = temp;
+ }
+
+ if (increment == 2)
+ increment = 1;
+ else
+ increment = (UWORD)((float)increment / (float)2.2);
+ }
+}
+
NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
{
NXT_STATUS Status = NO_ERR;
@@ -5811,6 +6756,7 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
//Arg2 - Src
//Arg3 - Index
//Arg4 - New val / array of vals
+ UWORD SrcDims, NewValDims;
Arg1 = pCode[1];
Arg2 = pCode[2];
@@ -5824,7 +6770,8 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
//!!! Could avoid full data copy if we knew which portion to overwrite
if (Arg1 != Arg2)
{
- Status= cCmdMove(Arg1, Arg2);
+// Status= cCmdMove(Arg1, Arg2);
+ Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg2, 0);
if (IS_ERR(Status))
return Status;
}
@@ -5848,13 +6795,17 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
if (ArgVal3 >= ArrayCount1)
return (NO_ERR);
- if (cCmdDSType(Arg4) != TC_ARRAY)
+ SrcDims = cCmdArrayDimensions(Arg2);
+ NewValDims = cCmdArrayDimensions(Arg4);
+ // if the new value argument has an array dimension that is 1 less than
+ // the array dimension of the source array then use MOV to copy data
+ if (NewValDims == (SrcDims-1))
{
Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, ArgVal3), Arg4, 0);
if (IS_ERR(Status))
return Status;
}
- else
+ else if (NewValDims == SrcDims)
{
DVIndex4 = cCmdGetDVIndex(Arg4, 0);
@@ -5871,6 +6822,12 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
return Status;
}
}
+ else
+ {
+ // any other situation is unsupported
+ NXT_BREAK;
+ return 0;
+ }
}
break;
@@ -6233,8 +7190,10 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
case OP_STRINGTONUM:
{
+ ULONG ArgVal1;
float ArgValF;
SLONG decimals= 0;
+ UBYTE exponent=FALSE;
UBYTE cont= TRUE;
// Arg1 - Dst number (output)
// Arg2 - Offset past match (output)
@@ -6242,10 +7201,6 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
// Arg4 - Offset
// Arg5 - Default (type/value)
- //!!! Currently, both outputs must have valid destinations.
- // It would be trivial to handle NOT_A_DS_ID to avoid dummy
- // allocations when outputs are unused.
-
Arg1 = pCode[1];
Arg2 = pCode[2];
Arg3 = pCode[3];
@@ -6271,39 +7226,402 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode)
}
//Read number from string
- if (sscanf(((PSZ)pArg3 + ArgVal4), "%f", &ArgValF) == 1)
+ // scan either to integer or float, depending on TypeCode1
+ int scanResult;
+ if (TypeCode1 == TC_FLOAT)
+ scanResult = sscanf(((PSZ)pArg3 + ArgVal4), "%f", &ArgValF);
+ else
+ scanResult = sscanf(((PSZ)pArg3 + ArgVal4), "%d", &ArgVal1);
+ // check the result
+ if (scanResult == 1)
{
- i = (UWORD)ArgVal4;
- //Scan until we see the number, consumes negative sign too
- while ((((UBYTE *)pArg3)[i] < '0') || (((UBYTE *)pArg3)[i] > '9'))
- i++;
-
- //Scan until we get past the number and no more than one decimal
- while (cont) {
- if ((((UBYTE *)pArg3)[i] >= '0') && (((UBYTE *)pArg3)[i] <= '9'))
- i++;
- else if(((UBYTE *)pArg3)[i] == '.' && !decimals) {
+ if (Arg2 != NOT_A_DS_ID)
+ {
+ i = (UWORD)ArgVal4;
+ //Scan until we see the number, consumes negative sign too
+ while ((((UBYTE *)pArg3)[i] < '0') || (((UBYTE *)pArg3)[i] > '9'))
i++;
- decimals++;
+
+ if (TypeCode1 == TC_FLOAT)
+ {
+ //Scan until we get past the number and no more than one decimal
+ // optionally there can also be a single "e" or "E" followed by
+ // one or more digits (but the decimal cannot come after this)
+ while (cont) {
+ UBYTE ch = ((UBYTE *)pArg3)[i];
+ if ((ch >= '0') && (ch <= '9'))
+ i++;
+ else if(ch == '.' && !decimals && !exponent) {
+ i++;
+ decimals++;
+ }
+ else if (((ch == 'E') || (ch == 'e')) && !exponent) {
+ i++;
+ exponent = TRUE;
+ }
+ else
+ cont= FALSE;
}
- else
- cont= FALSE;
+ }
+ else {
+ //Scan until we get past the number
+ while ((((UBYTE *)pArg3)[i] >= '0') && (((UBYTE *)pArg3)[i] <= '9'))
+ i++;
+ }
+ ArgVal2 = i;
}
- ArgVal2 = i;
}
else
{
//Number wasn't found in string, use defaults
ArgValF = ArgVal5;
+ ArgVal1 = ArgVal5;
ArgVal2 = 0;
}
//Set outputs
- cCmdSetValFlt(pArg1, TypeCode1, ArgValF);
- cCmdSetScalarValFromDataArg(Arg2, ArgVal2);
+ if (TypeCode1 == TC_FLOAT)
+ cCmdSetValFlt(pArg1, TypeCode1, ArgValF);
+ else
+ cCmdSetVal(pArg1, TypeCode1, ArgVal1);
+ if (Arg2 != NOT_A_DS_ID)
+ cCmdSetScalarValFromDataArg(Arg2, ArgVal2);
+ }
+ break;
+
+ case OP_ARROP:
+ {
+ //Arg1 - Command (immediate constant)
+ //Arg2 - Dst (scalar|array)
+ //Arg3 - Src (scalar array)
+ //Arg4 - Index
+ //Arg5 - Length
+
+ Arg1 = pCode[1];
+ Arg2 = pCode[2];
+ Arg3 = pCode[3];
+ Arg4 = pCode[4];
+ Arg5 = pCode[5];
+
+ // array operation
+ if (Arg1 == OPARR_SORT) {
+ // source must be an array of non-aggregate type
+ NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY);
+ TypeCode2 = cCmdDSType(INC_ID(Arg2));
+ NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode2));
+ }
+ else {
+ // destination must be a non-aggregate type
+ NXT_ASSERT(!IS_AGGREGATE_TYPE(cCmdDSType(Arg2)));
+ }
+ // source must be an array of non-aggregate type
+ NXT_ASSERT(cCmdDSType(Arg3) == TC_ARRAY);
+ TypeCode3 = cCmdDSType(INC_ID(Arg3));
+ NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode3));
+
+ ArrayCount3 = cCmdArrayCount(Arg3, 0);
+
+ if (Arg4 != NOT_A_DS_ID)
+ ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0);
+ else //Index input unwired
+ ArgVal4 = 0;
+
+ if (Arg5 != NOT_A_DS_ID)
+ ArgVal5 = cCmdGetScalarValFromDataArg(Arg5, 0);
+ else //Length input unwired, set to "rest"
+ ArgVal5 = 0xFFFF;
+
+ //Bounds check
+ if (ArgVal4 > ArrayCount3)
+ {
+ if (Arg1 == OPARR_SORT) {
+ //Illegal range - return empty subset
+ Status = cCmdDSArrayAlloc(Arg2, 0, 0);
+ return Status;
+ }
+ else {
+ //Illegal range - return zero
+ pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2);
+ cCmdSetVal(pArg2, TypeCode2, 0);
+ return NO_ERR;
+ }
+ }
+
+ //Set MinCount to "rest"
+ MinCount = (UWORD)(ArrayCount3 - ArgVal4);
+
+ // Copy "Length" if it is less than "rest"
+ if (ArgVal5 < (ULONG)MinCount)
+ MinCount = (UWORD)ArgVal5;
+
+ DV_INDEX DVIndex3 = cCmdGetDVIndex(Arg3, 0);
+
+ SLONG sval, svaltmp;
+ ULONG uval, uvaltmp;
+ float fval, fvaltmp;
+ float numElements = (float)MinCount;
+ //sum elements from src subset to dst
+ if ((Arg1 == OPARR_SUM) || (Arg1 == OPARR_MEAN) ||
+ (Arg1 == OPARR_SUMSQR) || (Arg1 == OPARR_STD))
+ {
+ pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2);
+ if (TypeCode3 == TC_FLOAT)
+ {
+ fval = 0;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ fvaltmp = cCmdGetValFlt(pArg3, TypeCode3);
+ if (Arg1 == OPARR_SUMSQR)
+ fvaltmp *= fvaltmp;
+ fval += fvaltmp;
+ }
+ if (Arg1 == OPARR_MEAN)
+ cCmdSetValFlt(pArg2, TypeCode2, fval/numElements);
+ else if (Arg1 != OPARR_STD)
+ cCmdSetValFlt(pArg2, TypeCode2, fval);
+ }
+ else if (IS_SIGNED_TYPE(TypeCode3) && (Arg1 != OPARR_SUMSQR))
+ {
+ sval = 0;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ svaltmp = (SLONG)cCmdGetVal(pArg3, TypeCode3);
+ sval += svaltmp;
+ }
+ if (Arg1 == OPARR_MEAN)
+ cCmdSetVal(pArg2, TypeCode2, (SLONG)(float)sval/numElements);
+ else if (Arg1 != OPARR_STD)
+ cCmdSetVal(pArg2, TypeCode2, sval);
+ }
+ else
+ {
+ uval = 0;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ if (IS_SIGNED_TYPE(TypeCode3))
+ {
+ // this can only be the SUMSQR operation (given the IF statement above)
+ svaltmp = cCmdGetVal(pArg3, TypeCode3);
+ uvaltmp = (ULONG)abs(svaltmp) * (ULONG)abs(svaltmp);
+ uval += uvaltmp;
+ }
+ else {
+ uvaltmp = cCmdGetVal(pArg3, TypeCode3);
+ if (Arg1 == OPARR_SUMSQR)
+ uvaltmp *= uvaltmp;
+ uval += uvaltmp;
+ }
+ }
+ if (Arg1 == OPARR_MEAN)
+ cCmdSetVal(pArg2, TypeCode2, (ULONG)(float)uval/numElements);
+ else if (Arg1 != OPARR_STD)
+ cCmdSetVal(pArg2, TypeCode2, uval);
+ }
+ // calculate standard deviation
+ if (Arg1 == OPARR_STD)
+ {
+ float avg, delta, sumSqr;
+ if (TypeCode3 == TC_FLOAT)
+ avg = fval/numElements;
+ else if (IS_SIGNED_TYPE(TypeCode3))
+ avg = (float)sval/numElements;
+ else
+ avg = (float)uval/numElements;
+ sumSqr = 0;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ if (TypeCode3 == TC_FLOAT)
+ delta = cCmdGetValFlt(pArg3, TypeCode3) - avg;
+ if (IS_SIGNED_TYPE(TypeCode3))
+ delta = (float)(SLONG)cCmdGetVal(pArg3, TypeCode3) - avg;
+ else // unsigned types
+ delta = (float)cCmdGetVal(pArg3, TypeCode3) - avg;
+ sumSqr += (delta*delta);
+ }
+ delta = sqrtf(sumSqr / (numElements - (float)1.0));
+ if (TypeCode3 == TC_FLOAT)
+ cCmdSetValFlt(pArg2, TypeCode2, delta);
+ else if (IS_SIGNED_TYPE(TypeCode3))
+ cCmdSetVal(pArg2, TypeCode2, (SLONG)delta);
+ else
+ cCmdSetVal(pArg2, TypeCode2, (ULONG)delta);
+ }
+ }
+ else if ((Arg1 == OPARR_MIN) || (Arg1 == OPARR_MAX))
+ {
+ pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2);
+ if (TypeCode3 == TC_FLOAT)
+ {
+ if (Arg1 == OPARR_MIN)
+ fval = FLT_MAX;
+ else
+ fval = -FLT_MAX;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ fvaltmp = cCmdGetValFlt(pArg3, TypeCode3);
+ if (((Arg1 == OPARR_MIN) && (fvaltmp < fval)) ||
+ ((Arg1 == OPARR_MAX) && (fvaltmp > fval)))
+ fval = fvaltmp;
+ }
+ cCmdSetValFlt(pArg2, TypeCode2, fval);
+ }
+ else if (IS_SIGNED_TYPE(TypeCode3))
+ {
+ if (Arg1 == OPARR_MIN)
+ sval = LONG_MAX;
+ else
+ sval = LONG_MIN;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ svaltmp = (SLONG)cCmdGetVal(pArg3, TypeCode3);
+ if (((Arg1 == OPARR_MIN) && (svaltmp < sval)) ||
+ ((Arg1 == OPARR_MAX) && (svaltmp > sval)))
+ sval = svaltmp;
+ }
+ cCmdSetVal(pArg2, TypeCode2, sval);
+ }
+ else
+ {
+ if (Arg1 == OPARR_MIN)
+ uval = ULONG_MAX;
+ else
+ uval = 0;
+ for (i = 0; i < MinCount; i++)
+ {
+ pArg3 = cCmdResolveDataArg(INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i), NULL);
+ uvaltmp = cCmdGetVal(pArg3, TypeCode3);
+ if (((Arg1 == OPARR_MIN) && (uvaltmp < uval)) ||
+ ((Arg1 == OPARR_MAX) && (uvaltmp > uval)))
+ uval = uvaltmp;
+ }
+ cCmdSetVal(pArg2, TypeCode2, uval);
+ }
+ }
+ else if (Arg1 == OPARR_SORT)
+ {
+ //Allocate Dst array
+ Status = cCmdDSArrayAlloc(Arg2, 0, MinCount);
+ if (IS_ERR(Status))
+ return Status;
+
+ DVIndex2 = cCmdGetDVIndex(Arg2, 0);
+
+ //Move src subset to dst
+ for (i = 0; i < MinCount; i++)
+ {
+ Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, i), INC_ID(Arg3), ARRAY_ELEM_OFFSET(DVIndex3, ArgVal4 + i));
+ if (IS_ERR(Status))
+ return Status;
+ }
+ // now dst is ready to be sorted
+ pArg2 = cCmdResolveDataArg(Arg2, 0, NULL);
+ Size = cCmdSizeOf(TypeCode2);
+ if (TypeCode2 == TC_SBYTE)
+ shell_sort_s1(pArg2, MinCount);
+ else if (TypeCode2 == TC_SWORD)
+ shell_sort_s2(pArg2, MinCount);
+ else if (TypeCode2 == TC_SLONG)
+ shell_sort_s4(pArg2, MinCount);
+ else if (TypeCode2 == TC_UBYTE)
+ shell_sort_u1(pArg2, MinCount);
+ else if (TypeCode2 == TC_UWORD)
+ shell_sort_u2(pArg2, MinCount);
+ else if (TypeCode2 == TC_ULONG)
+ shell_sort_u4(pArg2, MinCount);
+ else if (TypeCode2 == TC_FLOAT)
+ shell_sort_flt(pArg2, MinCount);
+ }
+ else
+ {
+ //Fatal error: Unrecognized instruction
+ NXT_BREAK;
+ Status = ERR_INSTR;
+ }
}
break;
+ case OP_MULDIV:
+ {
+ //Arg1 - Dst (scalar)
+ //Arg2 - SrcA (scalar)
+ //Arg3 - SrcB (scalar)
+ //Arg4 - SrcC (scalar)
+
+ Arg1 = pCode[1];
+ Arg2 = pCode[2];
+ Arg3 = pCode[3];
+ Arg4 = pCode[4];
+ ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0);
+ ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0);
+ ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0);
+ ArgVal3 = (ULONG)(((long long)ArgVal2*(long long)ArgVal3)/(long long)ArgVal4);
+ pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1);
+ cCmdSetVal(pArg1, TypeCode1, ArgVal3);
+ }
+ break;
+
+/*
+ case OP_PRINTF:
+ {
+ // Arg1 - Instruction Size in bytes
+ // Arg2 - Dst
+ // Arg3 - Fmtstr
+ // Arg4-N - Srcs (max args = 8)
+ void *srcPtrs[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+ void *pArg2 = NULL, *pArg3 = NULL;
+
+ Arg2 = pCode[2];
+ Arg3 = pCode[3];
+
+ //Make sure Dst arg is a string
+ NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY);
+ NXT_ASSERT(cCmdDSType(INC_ID(Arg2)) == TC_UBYTE);
+
+ //Make sure Fmtstr arg is a string
+ NXT_ASSERT(cCmdDSType(Arg3) == TC_ARRAY);
+ NXT_ASSERT(cCmdDSType(INC_ID(Arg3)) == TC_UBYTE);
+
+ //Number of Srcs = total code words - 4 (account for opcode word, size, Dst, and Fmtstr)
+ //!!! Argument access like this is potentially unsafe.
+ //A function/macro which checks proper encoding would be better
+ SrcCount = (pCode[1] / 2) - 4;
+ if (SrcCount > 8) {
+ Status = ERR_INSTR;
+ return (Status);
+ }
+
+ // get pointers to Dst and FmtSt
+ pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2);
+ pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3);
+
+ // resolve src pointers for all our sources
+ for (i = 0; i < SrcCount; i++)
+ {
+ TmpDSID = pCode[4 + i];
+ TYPE_CODE tc = cCmdDSType(TmpDSID);
+ if ((tc == TC_ARRAY && cCmdDSType(INC_ID(TmpDSID)) != TC_UBYTE) ||
+ (tc == TC_VOID) || (tc > TC_LAST_INT_SCALAR && tc != TC_FLOAT))
+ {
+ // invalid source (only scalars, floats, and strings are supported)
+ Status = ERR_INSTR;
+ return (Status);
+ }
+ srcPtrs[i] = cCmdResolveDataArg(TmpDSID, 0, &TypeCode1);
+ }
+
+ //Calculate Dst array count
+ ArrayCount2 = sprintf(NULL, pArg3, srcPtrs[0], srcPtrs[1], srcPtrs[2],
+ srcPtrs[3], srcPtrs[4], srcPtrs[5],
+ srcPtrs[6], srcPtrs[7], srcPtrs[8]);
+ }
+ break;
+*/
default:
{
//Fatal error: Unrecognized instruction
@@ -6375,13 +7693,17 @@ UBYTE cCmdLSCalcBytesReady(UBYTE Port)
//If InPtr is actually behind OutPtr, circular buffer has wrapped. Account for wrappage...
if (Tmp < 0)
Tmp = (pInBuf->InPtr + (SIZE_OF_LSBUF - pInBuf->OutPtr));
+ else if ((Tmp == 0) &&
+ (pInBuf->BytesToRx == SIZE_OF_LSBUF) &&
+ (pMapLowSpeed->ChannelState[Port] == LOWSPEED_IDLE))
+ Tmp = SIZE_OF_LSBUF;
return (UBYTE)(Tmp);
}
//cCmdLSWrite
//Write BufLength bytes into specified port's lowspeed buffer and kick off comm process to device
-NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength)
+NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength, UBYTE NoRestartOnRead)
{
if (Port >= NO_OF_LOWSPEED_COM_CHANNEL)
{
@@ -6412,6 +7734,10 @@ NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseL
*pChState = LOWSPEED_INIT;
pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port);
+ if (NoRestartOnRead)
+ pMapLowSpeed->NoRestartOnRead |= (0x01 << Port);
+ else
+ pMapLowSpeed->NoRestartOnRead &= ~(0x01 << Port);
return (NO_ERR);
}
@@ -6459,9 +7785,10 @@ NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf)
pBuf += BytesToRead;
BytesToRead = BufLength - BytesToRead;
}
-
- memcpy(pBuf, pInBuf->Buf + pInBuf->OutPtr, BytesToRead);
- pInBuf->OutPtr += BytesToRead;
+ if (BytesToRead > 0) {
+ memcpy(pBuf, pInBuf->Buf + pInBuf->OutPtr, BytesToRead);
+ pInBuf->OutPtr += BytesToRead;
+ }
return (NO_ERR);
}
@@ -6471,13 +7798,7 @@ NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf)
//Wrappers for OP_SYSCALL
//
-//
-//cCmdWrapFileOpenRead
-//ArgV[0]: (Function return) Loader status, U16 return
-//ArgV[1]: File Handle, U8 return
-//ArgV[2]: Filename, CStr
-//ArgV[3]: Length, U32 return
-NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[])
+NXT_STATUS cCmdWrapFileOpenReadHelper(UBYTE Cmd, UBYTE * ArgV[])
{
LOADER_STATUS LStatus;
DV_INDEX DVIndex;
@@ -6486,7 +7807,7 @@ NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[])
DVIndex = *(DV_INDEX *)(ArgV[2]);
ArgV[2] = cCmdDVPtr(DVIndex);
- LStatus = pMapLoader->pFunc(OPENREAD, ArgV[2], NULL, (ULONG *)ArgV[3]);
+ LStatus = pMapLoader->pFunc(Cmd, ArgV[2], NULL, (ULONG *)ArgV[3]);
//Add entry into FileHandleTable
if (LOADER_ERR(LStatus) == SUCCESS)
@@ -6503,12 +7824,7 @@ NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[])
return NO_ERR;
}
-//cCmdWrapFileOpenWrite
-//ArgV[0]: (Function return) Loader status, U16 return
-//ArgV[1]: File Handle, U8 return
-//ArgV[2]: Filename, CStr
-//ArgV[3]: Length, U32 return
-NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[])
+NXT_STATUS cCmdWrapFileOpenWriteHelper(UBYTE Cmd, UBYTE * ArgV[])
{
LOADER_STATUS LStatus;
DV_INDEX DVIndex;
@@ -6517,7 +7833,7 @@ NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[])
DVIndex = *(DV_INDEX *)(ArgV[2]);
ArgV[2] = cCmdDVPtr(DVIndex);
- LStatus = pMapLoader->pFunc(OPENWRITEDATA, ArgV[2], NULL, (ULONG *)ArgV[3]);
+ LStatus = pMapLoader->pFunc(Cmd, ArgV[2], NULL, (ULONG *)ArgV[3]);
//Add entry into FileHandleTable
if (LOADER_ERR(LStatus) == SUCCESS)
@@ -6534,6 +7850,27 @@ NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[])
return NO_ERR;
}
+//
+//cCmdWrapFileOpenRead
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 return
+//ArgV[2]: Filename, CStr
+//ArgV[3]: Length, U32 return
+NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[])
+{
+ return cCmdWrapFileOpenReadHelper(OPENREAD, ArgV);
+}
+
+//cCmdWrapFileOpenWrite
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 return
+//ArgV[2]: Filename, CStr
+//ArgV[3]: Length, U32 return
+NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[])
+{
+ return cCmdWrapFileOpenWriteHelper(OPENWRITEDATA, ArgV);
+}
+
//cCmdWrapFileOpenAppend
//ArgV[0]: (Function return) Loader status, U16 return
//ArgV[1]: File Handle, U8 return
@@ -6541,28 +7878,7 @@ NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[])
//ArgV[3]: Length Remaining, U32 return
NXT_STATUS cCmdWrapFileOpenAppend(UBYTE * ArgV[])
{
- LOADER_STATUS LStatus;
- DV_INDEX DVIndex;
-
- //Resolve array argument
- DVIndex = *(DV_INDEX *)(ArgV[2]);
- ArgV[2] = cCmdDVPtr(DVIndex);
-
- LStatus = pMapLoader->pFunc(OPENAPPENDDATA, ArgV[2], NULL, (ULONG *)ArgV[3]);
-
- //Add entry into FileHandleTable
- if (LOADER_ERR(LStatus) == SUCCESS)
- {
- VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)][0] = 'w';
- strcpy((PSZ)(VarsCmd.FileHandleTable[LOADER_HANDLE(LStatus)] + 1), (PSZ)(ArgV[2]));
- }
-
- //Status code in high byte of LStatus
- *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
- //File handle in low byte of LStatus
- *(ArgV[1]) = LOADER_HANDLE(LStatus);
-
- return NO_ERR;
+ return cCmdWrapFileOpenWriteHelper(OPENAPPENDDATA, ArgV);
}
//cCmdWrapFileRead
@@ -6898,7 +8214,7 @@ NXT_STATUS cCmdWrapCommLSWrite(UBYTE * ArgV[])
pBuf = cCmdDVPtr(DVIndex);
BufLength = DV_ARRAY[DVIndex].Count;
- *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength);
+ *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength, 0);
return (NO_ERR);
}
@@ -7304,7 +8620,7 @@ NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[])
-#define MAX_IOM_BUFFER_SIZE 64
+#define MAX_IOM_BUFFER_SIZE 800
//
//cCmdWrapIOMapRead
//ArgV[0]: (return) Status byte, SBYTE
@@ -7527,6 +8843,7 @@ void cCmdWriteBenchmarkFile()
//
NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[])
{
+#ifndef STRIPPED
NXT_STATUS Status = NO_ERR;
DV_INDEX DVIndex;
@@ -7542,6 +8859,9 @@ NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[])
return Status;
else
return (NO_ERR);
+#else
+ return (NO_ERR);
+#endif
}
//
@@ -7551,8 +8871,10 @@ NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[])
//
NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[])
{
+#ifndef STRIPPED
*((ULONG *)ArgV[1]) = IOMapCmd.SyncTime;
*((ULONG *)ArgV[2]) = IOMapCmd.SyncTick;
+#endif
return (NO_ERR);
}
@@ -7579,104 +8901,16 @@ NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[])
return (NO_ERR);
}
-// currently copied from LS, not finished.
-//
-//cCmdWrapCommHSWrite
-//ArgV[0]: (return) Status code, SBYTE
-//ArgV[1]: Port specifier, UBYTE
-//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used
-//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device
-//
-NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[])
-{
- SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
- UBYTE Port = *(ArgV[1]);
- UBYTE * pBuf;
- UWORD BufLength;
- UBYTE ResponseLength = *(ArgV[3]);
- DV_INDEX DVIndex;
-
- //Resolve array arguments
- DVIndex = *(DV_INDEX *)(ArgV[2]);
- pBuf = cCmdDVPtr(DVIndex);
- BufLength = DV_ARRAY[DVIndex].Count;
-
- *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength);
-
- return (NO_ERR);
-}
-
-//
-//cCmdWrapCommHSCheckStatus
-//ArgV[0]: (return) Status code, SBYTE
-//ArgV[1]: Port specifier, UBYTE
-//ArgV[2]: BytesReady, UBYTE
-//
-NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[])
-{
- UBYTE Port = *(ArgV[1]);
-
- *((SBYTE*)(ArgV[0])) = cCmdLSCheckStatus(Port);
- *((UBYTE*)(ArgV[2])) = cCmdLSCalcBytesReady(Port);
-
- return (NO_ERR);
-}
-
-//
-//cCmdWrapCommHSRead
-//ArgV[0]: (return) Status code, SBYTE
-//ArgV[1]: Port specifier, UBYTE
-//ArgV[2]: Buffer for data, UBYTE array, max SIZE_OF_LSBUF bytes will be written
-//ArgV[3]: BufferLength, UBYTE, specifies size of buffer requested
-//
-NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[])
-{
- SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
- UBYTE Port = *(ArgV[1]);
- UBYTE * pBuf;
- UBYTE BufLength = *(ArgV[3]);
- UBYTE BytesToRead;
- DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[2]);
- NXT_STATUS AllocStatus;
-
- *pReturnVal = cCmdLSCheckStatus(Port);
- BytesToRead = cCmdLSCalcBytesReady(Port);
-
- //If channel is OK and has data ready for us, put the data into outgoing buffer
- if (!IS_ERR(*pReturnVal) && BytesToRead > 0)
- {
- //Limit buffer to available data
- if (BufLength > BytesToRead)
- BufLength = BytesToRead;
-
- AllocStatus = cCmdDVArrayAlloc(DVIndex, BufLength);
- if (IS_ERR(AllocStatus))
- return (AllocStatus);
-
- pBuf = cCmdDVPtr(DVIndex);
- *pReturnVal = cCmdLSRead(Port, BufLength, pBuf);
- }
- //Else, the channel has an error and/or there's no data to read; clear the output array
- else
- {
- AllocStatus = cCmdDVArrayAlloc(DVIndex, 0);
- if (IS_ERR(AllocStatus))
- return (AllocStatus);
- }
-
- return (NO_ERR);
-}
-
//
//cCmdWrapCommBTOnOff
-//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[0]: (return) Status byte, SBYTE // JCH - this should be UWORD
//ArgV[1]: Power State, 0-1
//
NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[])
{
UWORD retVal;
- NXT_STATUS status;
- SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UWORD status;
+ UWORD * pReturnVal = (UWORD*)(ArgV[0]);
UBYTE powerState = *(ArgV[1]);
if(powerState)
@@ -7690,7 +8924,7 @@ NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[])
//
//cCmdWrapCommBTConnection
-//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[0]: (return) Status byte, SBYTE // JCH - this should be UWORD
//ArgV[1]: Action, UBYTE
//ArgV[2]: name, UBYTE array CStr
//ArgV[3]: connection slot, UBYTE
@@ -7698,8 +8932,8 @@ NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[])
NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[])
{
UWORD retVal;
- NXT_STATUS status;
- SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UWORD status;
+ UWORD * pReturnVal = (UWORD*)(ArgV[0]);
UBYTE *nmPtr;
UBYTE action = *(ArgV[1]);
@@ -7961,6 +9195,609 @@ NXT_STATUS cCmdWrapListFiles (UBYTE * ArgV[])
return Status;
}
+//
+//cCmdWrapCommExecuteFunction
+//ArgV[0]: (return) Result word, UWORD
+//ArgV[1]: UBYTE Cmd
+//ArgV[2]: UBYTE Param1
+//ArgV[3]: UBYTE Param2
+//ArgV[4]: UBYTE Param3
+//ArgV[5]: Name, UBYTE array
+//ArgV[6]: UWORD RetVal
+//
+NXT_STATUS cCmdWrapCommExecuteFunction(UBYTE * ArgV[])
+{
+ // resolve Name
+ ArgV[5] = cCmdDVPtr(*(DV_INDEX *)(ArgV[5]));
+
+ *(UWORD*)(ArgV[0]) =
+ pMapComm->pFunc(*(UBYTE*)(ArgV[1]),
+ *(UBYTE*)(ArgV[2]),
+ *(UBYTE*)(ArgV[3]),
+ *(UBYTE*)(ArgV[4]),
+ (UBYTE*)(ArgV[5]),
+ (UWORD*)(ArgV[6]));
+ return (NO_ERR);
+}
+
+//
+//cCmdWrapLoaderExecuteFunction
+//ArgV[0]: (return) Result word, UWORD
+//ArgV[1]: UBYTE Cmd
+//ArgV[2]: FileName, UBYTE array
+//ArgV[3]: Buffer, UBYTE array
+//ArgV[4]: ULONG pLength
+//
+NXT_STATUS cCmdWrapLoaderExecuteFunction(UBYTE * ArgV[])
+{
+ // resolve FileName
+ ArgV[2] = cCmdDVPtr(*(DV_INDEX *)(ArgV[2]));
+ // resolve Buffer
+ ArgV[3] = cCmdDVPtr(*(DV_INDEX *)(ArgV[3]));
+
+ *(UWORD*)(ArgV[0]) =
+ pMapLoader->pFunc(*(UBYTE*)(ArgV[1]),
+ (UBYTE*)(ArgV[2]),
+ (UBYTE*)(ArgV[3]),
+ (ULONG*)(ArgV[4]));
+ return (NO_ERR);
+}
+
+//
+//cCmdWrapIOMapReadByID
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: ModuleID, ULONG
+//ArgV[2]: Offset, UWORD
+//ArgV[3]: Count, UWORD
+//ArgV[4]: Buffer, UBYTE array
+//
+NXT_STATUS cCmdWrapIOMapReadByID(UBYTE * ArgV[])
+{
+ UWORD LStatus;
+ NXT_STATUS Status;
+
+ SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UWORD Offset = *(UWORD*)(ArgV[2]);
+ //Our copy of 'Count' must be a ULONG to match the loader interface
+ ULONG Count = *(UWORD*)(ArgV[3]);
+ ULONG ModuleID = *(ULONG*)ArgV[1];
+
+ DV_INDEX DVIndex;
+
+ //Buffer to store data and offset in for IOMAPREAD call
+ //!!! Constant size means only limited reads and writes
+ UBYTE DataBuffer[MAX_IOM_BUFFER_SIZE + 2];
+
+ if (Count > MAX_IOM_BUFFER_SIZE)
+ {
+ //Request to read too much data at once; clear buffer, return error.
+ DVIndex = *(DV_INDEX *)(ArgV[4]);
+ *pReturnVal = cCmdDVArrayAlloc(DVIndex, 0);
+ if (IS_ERR(*pReturnVal))
+ return (*pReturnVal);
+
+ *pReturnVal = ERR_INVALID_SIZE;
+ return (NO_ERR);
+ }
+
+ //Module was found, transfer Offset into first two bytes of DataBuffer and attempt to read
+ *(UWORD*)(DataBuffer) = Offset;
+ LStatus = pMapLoader->pFunc(IOMAPREAD, (UBYTE *)&ModuleID, DataBuffer, &Count);
+
+ if (LOADER_ERR(LStatus) == SUCCESS)
+ {
+ //No error from IOMAPREAD, so copy the data into VM's dataspace
+ //Size destination array
+ DVIndex = *(DV_INDEX *)(ArgV[4]);
+ Status = cCmdDVArrayAlloc(DVIndex, (UWORD)Count);
+ if (IS_ERR(Status))
+ {
+ //Alloc failed, so return
+ return (Status);
+ }
+
+ //Alloc succeeded, so resolve and copy away
+ ArgV[4] = cCmdDVPtr(DVIndex);
+ memcpy(ArgV[4], &(DataBuffer[2]), Count);
+ }
+
+ *pReturnVal = LOADER_ERR_BYTE(LStatus);
+
+ return (NO_ERR);
+}
+
+//
+//cCmdWrapIOMapWriteByID
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: ModuleID, ULONG
+//ArgV[2]: Offset, UWORD
+//ArgV[3]: Buffer, UBYTE array
+//
+NXT_STATUS cCmdWrapIOMapWriteByID(UBYTE * ArgV[])
+{
+ UWORD LStatus;
+
+ SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UWORD Offset = *(UWORD*)(ArgV[2]);
+ ULONG ModuleID = *(ULONG*)ArgV[1];
+
+ //Our copy of 'Count' must be a ULONG to match the loader interface
+ ULONG Count;
+ DV_INDEX DVIndex;
+
+ //Buffer to store data and offset in for IOMAPREAD call
+ //!!! Constant size means only limited reads and writes
+ UBYTE DataBuffer[MAX_IOM_BUFFER_SIZE + 2];
+
+ //Resolve buffer
+ DVIndex = *(DV_INDEX *)(ArgV[3]);
+ ArgV[3] = cCmdDVPtr(DVIndex);
+ Count = DV_ARRAY[DVIndex].Count;
+
+ if (Count > MAX_IOM_BUFFER_SIZE)
+ {
+ //Request to read too much data at once; return error and give up
+ *pReturnVal = ERR_INVALID_SIZE;
+ return (NO_ERR);
+ }
+
+ //Module was found, transfer Offset into first two bytes of DataBuffer, copy data into rest of buffer, then write
+ *(UWORD*)(DataBuffer) = Offset;
+ memcpy(&(DataBuffer[2]), ArgV[3], Count);
+ LStatus = pMapLoader->pFunc(IOMAPWRITE, (UBYTE *)&ModuleID, DataBuffer, &Count);
+
+ *pReturnVal = LOADER_ERR_BYTE(LStatus);
+
+ return (NO_ERR);
+}
+
+/*
+NXT_STATUS cCmdWrapFileFindHelper(UBYTE First, UBYTE * ArgV[])
+{
+ LOADER_STATUS LStatus;
+ NXT_STATUS Status;
+ DV_INDEX DVIndex;
+ UBYTE LoaderCmd = FINDNEXT;
+
+ UBYTE FileMask[FILENAME_LENGTH+1];
+
+ //Resolve array arguments
+ // input mask/output filename
+ DVIndex = *(DV_INDEX *)(ArgV[2]);
+ if (First) {
+ LoaderCmd = FINDFIRST;
+ ArgV[1] = FileMask;
+ memcpy(FileMask, cCmdDVPtr(DVIndex), DV_ARRAY[DVIndex].Count);
+ }
+ //Size Buffer to Length
+ //Add room for null terminator to length
+ Status = cCmdDVArrayAlloc(DVIndex, (UWORD)(FILENAME_LENGTH + 1));
+ if (IS_ERR(Status))
+ return Status;
+ ArgV[2] = cCmdDVPtr(DVIndex);
+
+ LStatus = pMapLoader->pFunc(LoaderCmd, ArgV[1], ArgV[2], (ULONG *)ArgV[3]);
+
+ //Status code in high byte of LStatus
+ *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
+
+ //File handle in low byte of LStatus
+ *(ArgV[1]) = LOADER_HANDLE(LStatus);
+
+ return (NO_ERR);
+}
+*/
+//cCmdWrapFileFindFirst
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 out
+//ArgV[2]: Filename, CStr in/out
+//ArgV[3]: Length, U32 out
+NXT_STATUS cCmdWrapFileFindFirst(UBYTE * ArgV[])
+{
+// return cCmdWrapFileFindHelper(TRUE, ArgV);
+ LOADER_STATUS LStatus;
+ NXT_STATUS Status;
+ DV_INDEX DVIndex;
+
+ UBYTE FileMask[FILENAME_LENGTH+1];
+
+ //Resolve array arguments
+ // input mask/output filename
+ DVIndex = *(DV_INDEX *)(ArgV[2]);
+ memcpy(FileMask, cCmdDVPtr(DVIndex), DV_ARRAY[DVIndex].Count);
+ //Size Buffer to Length
+ //Add room for null terminator to length
+ Status = cCmdDVArrayAlloc(DVIndex, (UWORD)(FILENAME_LENGTH + 1));
+ if (IS_ERR(Status))
+ return Status;
+ ArgV[2] = cCmdDVPtr(DVIndex);
+
+ LStatus = pMapLoader->pFunc(FINDFIRST, FileMask, ArgV[2], (ULONG *)ArgV[3]);
+
+ //Status code in high byte of LStatus
+ *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
+
+ //File handle in low byte of LStatus
+ *(ArgV[1]) = LOADER_HANDLE(LStatus);
+
+ return (NO_ERR);
+}
+
+//cCmdWrapFileFindNext
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 in/out
+//ArgV[2]: Filename, CStr out
+//ArgV[3]: Length, U32 out
+NXT_STATUS cCmdWrapFileFindNext(UBYTE * ArgV[])
+{
+// return cCmdWrapFileFindHelper(FALSE, ArgV);
+ LOADER_STATUS LStatus;
+ NXT_STATUS Status;
+ DV_INDEX DVIndex;
+
+ //Resolve array arguments
+ // output filename
+ DVIndex = *(DV_INDEX *)(ArgV[2]);
+ //Size Buffer to Length
+ //Add room for null terminator to length
+ Status = cCmdDVArrayAlloc(DVIndex, (UWORD)(FILENAME_LENGTH + 1));
+ if (IS_ERR(Status))
+ return Status;
+ ArgV[2] = cCmdDVPtr(DVIndex);
+
+ LStatus = pMapLoader->pFunc(FINDNEXT, ArgV[1], ArgV[2], (ULONG *)ArgV[3]);
+
+ //Status code in high byte of LStatus
+ *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
+
+ //File handle in low byte of LStatus
+ *(ArgV[1]) = LOADER_HANDLE(LStatus);
+
+ return (NO_ERR);
+}
+
+//cCmdWrapFileOpenReadLinear
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 return
+//ArgV[2]: Filename, CStr
+//ArgV[3]: Length, U32 return
+NXT_STATUS cCmdWrapFileOpenReadLinear(UBYTE * ArgV[])
+{
+ return cCmdWrapFileOpenReadHelper(OPENREADLINEAR, ArgV);
+}
+
+//cCmdWrapFileOpenWriteLinear
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 return
+//ArgV[2]: Filename, CStr
+//ArgV[3]: Length, U32 return
+NXT_STATUS cCmdWrapFileOpenWriteLinear(UBYTE * ArgV[])
+{
+ return cCmdWrapFileOpenWriteHelper(OPENWRITELINEAR, ArgV);
+}
+
+//cCmdWrapFileOpenWriteNonLinear
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 return
+//ArgV[2]: Filename, CStr
+//ArgV[3]: Length, U32 return
+NXT_STATUS cCmdWrapFileOpenWriteNonLinear(UBYTE * ArgV[])
+{
+ return cCmdWrapFileOpenWriteHelper(OPENWRITE, ArgV);
+}
+
+//
+//cCmdWrapCommHSControl
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: Command, UBYTE (init, uart, or exit)
+//ArgV[2]: BaudRate, UBYTE
+//ArgV[3]: Mode, UWORD
+NXT_STATUS cCmdWrapCommHSControl(UBYTE * ArgV[])
+{
+ pMapComm->HsInBuf.InPtr = 0;
+ pMapComm->HsInBuf.OutPtr = 0;
+ pMapComm->HsOutBuf.InPtr = 0;
+ pMapComm->HsOutBuf.OutPtr = 0;
+ switch (*(ArgV[1]))
+ {
+ case HS_CTRL_INIT:
+ {
+ // hi-speed enable/init
+ pMapComm->HsState = HS_ENABLE;
+ pMapComm->HsFlags = HS_UPDATE;
+ }
+ break;
+
+ case HS_CTRL_UART:
+ {
+ // hi-speed setup uart
+ pMapComm->HsSpeed = *(ArgV[2]);
+ pMapComm->HsMode = *(UWORD*)(ArgV[3]);
+ pMapComm->HsState = HS_INITIALISE;
+ pMapComm->HsFlags = HS_UPDATE;
+ }
+ break;
+
+ case HS_CTRL_EXIT:
+ {
+ // hi-speed exit
+ pMapComm->HsState = HS_DISABLE;
+ pMapComm->HsFlags = HS_UPDATE;
+ }
+ break;
+ }
+
+ *(ArgV[0]) = pMapComm->HsState;
+
+ return (NO_ERR);
+}
+
+//cCmdWrapCommHSCheckStatus
+//ArgV[0]: SendingData, UBYTE out
+//ArgV[1]: DataAvailable, UBYTE out
+NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[])
+{
+ *(ArgV[0]) = (pMapComm->HsOutBuf.InPtr != pMapComm->HsOutBuf.OutPtr) || (pMapComm->HsState == HS_SEND_DATA);
+ *(ArgV[1]) = (pMapComm->HsInBuf.InPtr != pMapComm->HsInBuf.OutPtr);
+ return (NO_ERR);
+}
+
+//cCmdWrapCommHSWrite
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: Buffer
+NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UBYTE * pBuf;
+ UWORD BufLength;
+ DV_INDEX DVIndex;
+
+ //Resolve array arguments
+ DVIndex = *(DV_INDEX *)(ArgV[1]);
+ pBuf = cCmdDVPtr(DVIndex);
+ BufLength = DV_ARRAY[DVIndex].Count;
+
+ if (BufLength > SIZE_OF_HSBUF)
+ {
+ *pReturnVal = ERR_INVALID_SIZE;
+ return (NO_ERR);
+ }
+
+ // set inptr & outptr
+ pMapComm->HsOutBuf.OutPtr = 0;
+ pMapComm->HsOutBuf.InPtr = BufLength;
+ memcpy(pMapComm->HsOutBuf.Buf, pBuf, BufLength);
+
+ // send the data
+ pMapComm->HsState = HS_SEND_DATA;
+ pMapComm->HsFlags = HS_UPDATE;
+
+ *pReturnVal = pMapComm->HsState;
+
+ return (NO_ERR);
+}
+
+//cCmdWrapCommHSRead
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: Buffer, out
+NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[])
+{
+ //Normally, bytes available is a simple difference.
+ SLONG Tmp = pMapComm->HsInBuf.InPtr - pMapComm->HsInBuf.OutPtr;
+
+ //If InPtr is actually behind OutPtr, circular buffer has wrapped. Account for wrappage...
+ if (Tmp < 0)
+ Tmp = (pMapComm->HsInBuf.InPtr + (SIZE_OF_HSBUF - pMapComm->HsInBuf.OutPtr));
+
+ //Resolve array arguments
+ // output buffer
+ DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[1]);
+ //Size Buffer to Length
+ NXT_STATUS Status = cCmdDVArrayAlloc(DVIndex, (UWORD)Tmp);
+ if (IS_ERR(Status))
+ return Status;
+ UBYTE* pBuf = cCmdDVPtr(DVIndex);
+ ArgV[1] = pBuf;
+
+ //If the bytes we want to read wrap around the end, we must first read the end, then reset back to the beginning
+ UBYTE BytesToRead = (UBYTE)Tmp;
+ if (pMapComm->HsInBuf.OutPtr + BytesToRead >= SIZE_OF_HSBUF)
+ {
+ BytesToRead = SIZE_OF_HSBUF - pMapComm->HsInBuf.OutPtr;
+ memcpy(pBuf, pMapComm->HsInBuf.Buf + pMapComm->HsInBuf.OutPtr, BytesToRead);
+ pMapComm->HsInBuf.OutPtr = 0;
+ pBuf += BytesToRead;
+ BytesToRead = Tmp - BytesToRead;
+ }
+
+ memcpy(pBuf, pMapComm->HsInBuf.Buf + pMapComm->HsInBuf.OutPtr, BytesToRead);
+ pMapComm->HsInBuf.OutPtr += BytesToRead;
+
+ return (NO_ERR);
+}
+
+//cCmdWrapCommLSWriteEx
+//ArgV[0]: (return) Status code, SBYTE
+//ArgV[1]: Port specifier, UBYTE
+//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used
+//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device
+//ArgV[4]: NoRestartOnRead, UBYTE, specifies whether or not to restart before the read
+//
+NXT_STATUS cCmdWrapCommLSWriteEx(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UBYTE Port = *(ArgV[1]);
+ UBYTE * pBuf;
+ UWORD BufLength;
+ UBYTE ResponseLength = *(ArgV[3]);
+ UBYTE NoRestartOnRead = *(ArgV[4]);
+ DV_INDEX DVIndex;
+
+ //Resolve array arguments
+ DVIndex = *(DV_INDEX *)(ArgV[2]);
+ pBuf = cCmdDVPtr(DVIndex);
+ BufLength = DV_ARRAY[DVIndex].Count;
+
+ *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength, NoRestartOnRead);
+
+ return (NO_ERR);
+}
+
+//cCmdWrapFileSeek
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 in/out
+//ArgV[2]: Origin, U8 in
+//ArgV[3]: Length, S32 in
+NXT_STATUS cCmdWrapFileSeek(UBYTE * ArgV[])
+{
+ UBYTE Origin = *((UBYTE *)ArgV[2]);
+ LOADER_STATUS LStatus = pMapLoader->pFunc(Origin+SEEKFROMSTART, ArgV[1], NULL, (ULONG *)ArgV[3]);
+ //Status code in high byte of LStatus
+ *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
+ //File handle in low byte of LStatus
+ *(ArgV[1]) = LOADER_HANDLE(LStatus);
+ return (NO_ERR);
+}
+
+//cCmdWrapFileResize
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 in/out
+//ArgV[2]: NewSize, U16 in
+NXT_STATUS cCmdWrapFileResize(UBYTE * ArgV[])
+{
+ LOADER_STATUS LStatus = pMapLoader->pFunc(RESIZEDATAFILE, ArgV[1], NULL, (ULONG *)ArgV[2]);
+ //Status code in high byte of LStatus
+ *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
+ //File handle in low byte of LStatus
+ *(ArgV[1]) = LOADER_HANDLE(LStatus);
+ return (NO_ERR);
+}
+
+//cCmdWrapMemoryManager
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: Compact?, UBYTE (true or false)
+//ArgV[2]: PoolSize, UWORD
+//ArgV[3]: DataspaceSize, UWORD
+NXT_STATUS cCmdWrapMemoryManager(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ *pReturnVal = NO_ERR;
+ if (*(ArgV[1])) {
+ *pReturnVal = cCmdDSCompact();
+ }
+ *(UWORD*)(ArgV[2]) = (UWORD)VarsCmd.PoolSize;
+ *(UWORD*)(ArgV[3]) = VarsCmd.DataspaceSize;
+
+ return (NO_ERR);
+}
+
+//cCmdWrapReadLastResponse
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: Clear?, UBYTE (true or false)
+//ArgV[2]: Length, UBYTE out
+//ArgV[3]: Command, UBYTE out
+//ArgV[4]: Buffer, out
+NXT_STATUS cCmdWrapReadLastResponse(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
+ UWORD bufLen = 0;
+ if (VarsCmd.LastResponseLength > 0)
+ bufLen = VarsCmd.LastResponseLength-2;
+
+ //Resolve array arguments
+ // output buffer
+ DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[4]);
+ //Size Buffer to Length
+ NXT_STATUS Status = cCmdDVArrayAlloc(DVIndex, bufLen);
+ if (IS_ERR(Status))
+ return Status;
+ UBYTE* pBuf = cCmdDVPtr(DVIndex);
+ ArgV[4] = pBuf;
+ *(ArgV[2]) = bufLen; // Length
+ *pReturnVal = NO_ERR;
+
+ if (bufLen > 0)
+ {
+ memset(pBuf, 0, bufLen);
+ memcpy(pBuf, (PSZ)&(VarsCmd.LastResponseBuffer[2]), bufLen-1);
+ *pReturnVal = VarsCmd.LastResponseBuffer[1];
+ *(ArgV[3]) = VarsCmd.LastResponseBuffer[0];
+ }
+ // clear?
+ if (*(ArgV[1])) {
+ VarsCmd.LastResponseLength = 0;
+ memset(VarsCmd.LastResponseBuffer, 0, 64);
+ }
+
+ return (NO_ERR);
+}
+
+//cCmdWrapFileTell
+//ArgV[0]: (Function return) Loader status, U16 return
+//ArgV[1]: File Handle, U8 in/out
+//ArgV[2]: File Position, U32 out
+NXT_STATUS cCmdWrapFileTell(UBYTE * ArgV[])
+{
+ LOADER_STATUS LStatus = pMapLoader->pFunc(FILEPOSITION, ArgV[1], NULL, (ULONG *)ArgV[2]);
+ //Status code in high byte of LStatus
+ *((UWORD *)ArgV[0]) = LOADER_ERR(LStatus);
+ //File handle in low byte of LStatus
+ *(ArgV[1]) = LOADER_HANDLE(LStatus);
+ return (NO_ERR);
+}
+
+//
+//cCmdWrapRandomEx
+//ArgV[0]: Seed, SLONG (in/out)
+//ArgV[1]: Reseed?, UBYTE (true or false) (in)
+static SLONG __random_seed = 1;
+static SLONG __old_random_seed = 1;
+
+NXT_STATUS cCmdWrapRandomEx(UBYTE * ArgV[])
+{
+ SLONG * pSeed = (SLONG*)(ArgV[0]);
+ if (*(ArgV[1]))
+ {
+ // reseed
+ if (*pSeed == 0) {
+ *pSeed = (SLONG)dTimerRead();
+ if (*pSeed < 0)
+ *pSeed = 1;
+ }
+ else if (*pSeed < 0)
+ *pSeed = __old_random_seed;
+ __random_seed = *pSeed;
+ __old_random_seed = __random_seed;
+ }
+ else
+ {
+ /*
+ MINSTD
+ a = 16807 (with q = 127773 and r = 2836) or
+ better randomness
+ a = 48271 (with q = 44488 and r = 3399) or
+ a = 69621 (with q = 30845 and r = 23902)
+ */
+#define a 48271
+#define m 2147483647
+#define q (m / a)
+#define r (m % a)
+ SLONG test = a * (__random_seed % q) - r * (__random_seed / q);
+ if (test > 0)
+ __random_seed = test;
+ else
+ __random_seed = test + m;
+ }
+ *pSeed = __random_seed;
+
+ return NO_ERR;
+}
+
+NXT_STATUS cCmdWrapUndefinedSysCall(UBYTE * ArgV[])
+{
+ return (NO_ERR);
+}
+
#ifdef SIM_NXT
// Accessors for simulator library code
SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index)
diff --git a/AT91SAM7S256/Source/c_cmd.h b/AT91SAM7S256/Source/c_cmd.h
index c6e5267..5a3a13e 100644
--- a/AT91SAM7S256/Source/c_cmd.h
+++ b/AT91SAM7S256/Source/c_cmd.h
@@ -27,7 +27,7 @@
#endif
#include "c_cmd_bytecodes.h"
-#define SYSCALL_COUNT 48
+#define SYSCALL_COUNT 100
extern const HEADER cCmd;
@@ -55,6 +55,17 @@ void cCmdExit(void);
//
#define ENABLE_VM 1
#undef ARM_DEBUG
+
+
+//
+//WRITE_IOMAP_OFFSETS enables saving a file containing accurate iomap offsets.
+//
+#define WRITE_IOMAP_OFFSETS 0
+
+#if WRITE_IOMAP_OFFSETS
+void cCmdWriteIOMapOffsetsFile();
+#endif
+
//
//VM_BENCHMARK enables extra instrumentation code to measure VM performance.
//When enabled, a file named "benchmark.txt" is produced every time a program completes.
@@ -323,6 +334,7 @@ typedef struct
#define SET_WRITE_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].WriteIndex] = (DVIndex))
#define SET_READ_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].ReadIndex] = (DVIndex))
+#ifndef STRIPPED
//
// Datalog Queuing
//
@@ -353,6 +365,7 @@ typedef struct
#define SET_WRITE_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex] = (DVIndex))
#define SET_READ_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex] = (DVIndex))
+#endif
//
//Definitions related to dataflow scheduling
@@ -388,6 +401,17 @@ typedef struct
CLUMP_Q WaitQ;
} MUTEX_Q;
+
+// Clump Breakpoints
+//
+typedef struct
+{
+ CODE_INDEX Location;
+ UBYTE Enabled;
+} CLUMP_BREAK_REC;
+
+#define MAX_BREAKPOINTS 4
+
//
// Clump Record, run-time book-keeping for each clump
//
@@ -398,6 +422,7 @@ typedef struct
// CurrFireCount: Run-time count of unsatisfied dependencies
// Link: ID of next clump in the queue. NOT_A_CLUMP denotes end or bad link.
//
+// Priority: number of instructions to run per pass on this clump
// clumpScalarDispatchHints: this clump only uses scalar data args, can be interpretted with faster dispatch tables
//
// pDependents: pointer to list of downstream dependents' ClumpIDs
@@ -413,11 +438,14 @@ typedef struct
UBYTE CurrFireCount; //AKA ShortCount
CLUMP_ID Link;
+ UBYTE Priority; // deleted in 1.28
UBYTE clumpScalarDispatchHints;
CLUMP_ID* pDependents;
ULONG awakenTime;
UBYTE DependentCount;
+ CLUMP_ID CalledClump;
+ CLUMP_BREAK_REC Breakpoints[MAX_BREAKPOINTS];
} CLUMP_REC;
//
@@ -536,8 +564,18 @@ typedef struct
ULONG StartTick;
+#ifndef STRIPPED
DATALOG_QUEUE DatalogBuffer;
+#endif
+ UBYTE Debugging;
+ UBYTE PauseClump;
+ CODE_INDEX PausePC;
+
+ // add a buffer for storing the last response raw content (64 bytes)
+ UBYTE LastResponseBuffer[64];
+ UBYTE LastResponseLength;
+
#if VM_BENCHMARK
ULONG InstrCount;
ULONG Average;
@@ -789,7 +827,7 @@ float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode);
NXT_STATUS cCmdLSCheckStatus(UBYTE Port);
UBYTE cCmdLSCalcBytesReady(UBYTE Port);
-NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength);
+NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength, UBYTE NoRestartOnRead);
NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf);
//
@@ -847,9 +885,6 @@ NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapListFiles(UBYTE * ArgV[]);
// Handlers for dynamically added syscalls
-NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]);
-NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]);
-NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]);
@@ -857,6 +892,33 @@ NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapComputeCalibValue(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapIOMapReadByID(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapIOMapWriteByID(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapDisplayExecuteFunction(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapCommExecuteFunction(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapLoaderExecuteFunction(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileFindFirst(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileFindNext(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileOpenWriteLinear(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileOpenWriteNonLinear(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileOpenReadLinear(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapCommHSControl(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapCommLSWriteEx(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileSeek(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileResize(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapDrawPictureArray(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapDrawPolygon(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapDrawEllipse(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapDrawFont(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapMemoryManager(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapReadLastResponse(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapFileTell(UBYTE * ArgV[]);
+NXT_STATUS cCmdWrapRandomEx(UBYTE * ArgV[]);
+
+NXT_STATUS cCmdWrapUndefinedSysCall(UBYTE * ArgV[]);
//Handler for remote control protocol packets -- called from comm module via IO map function pointer
UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen);
diff --git a/AT91SAM7S256/Source/c_cmd.iom b/AT91SAM7S256/Source/c_cmd.iom
index 7c5906c..820f01d 100644
--- a/AT91SAM7S256/Source/c_cmd.iom
+++ b/AT91SAM7S256/Source/c_cmd.iom
@@ -41,12 +41,24 @@
#define NO_ERR 0
//Fatal errors
-#define ERR_ARG -1 //0xFF Bad arguments
-#define ERR_INSTR -2 //0xFE Illegal bytecode instruction
-#define ERR_FILE -3 //0xFD Mal-formed file contents
-#define ERR_VER -4 //0xFC Version mismatch between firmware and compiler
-#define ERR_MEM -5 //0xFB Insufficient memory available
-#define ERR_BAD_PTR -6 //0xFA Someone passed us a bad pointer!
+#define ERR_ARG -1 // 0xFF Bad arguments
+#define ERR_INSTR -2 // 0xFE Illegal bytecode instruction
+#define ERR_FILE -3 // 0xFD cCmdVerifyMemMgr() != TRUE
+#define ERR_VER -4 // 0xFC Version mismatch between firmware and compiler
+#define ERR_MEM -5 // 0xFB Insufficient memory available
+#define ERR_BAD_PTR -6 // 0xFA Someone passed us a bad pointer!
+
+#define ERR_CLUMP_COUNT -7 // 0xF9 (FileClumpCount == 0 || FileClumpCount >= NOT_A_CLUMP)
+#define ERR_NO_CODE -8 // 0xF8 VarsCmd.CodespaceCount == 0
+#define ERR_INSANE_OFFSET -9 // 0xF7 CurrOffset != (DataSize - VarsCmd.CodespaceCount * 2)
+#define ERR_BAD_POOL_SIZE -10 // 0xF6 VarsCmd.PoolSize > POOL_MAX_SIZE
+#define ERR_LOADER_ERR -11 // 0xF5 LOADER_ERR(LStatus) != SUCCESS || pData == NULL || DataSize == 0
+#define ERR_SPOTCHECK_FAIL -12 // 0xF4 ((UBYTE*)(VarsCmd.pCodespace) < pData) (c_cmd.c 1893)
+#define ERR_NO_ACTIVE_CLUMP -13 // 0xF3 VarsCmd.RunQ.Head == NOT_A_CLUMP
+#define ERR_DEFAULT_OFFSETS -14 // 0xF2 (DefaultsOffset != FileOffsets.DynamicDefaults) || (DefaultsOffset + FileOffsets.DynamicDefaultsSize != FileOffsets.DSDefaultsSize)
+#define ERR_MEMMGR_FAIL -15 // 0xF1 (UBYTE *)VarsCmd.MemMgr.pDopeVectorArray != VarsCmd.pDataspace + DV_ARRAY[0].Offset
+
+#define ERR_NON_FATAL -16 //0xF0 or greater
//General errors
#define ERR_INVALID_PORT -16 //0xF0 Bad input or output port specified
@@ -73,7 +85,7 @@
#define IS_ERR(Status) ((Status) < NO_ERR)
//Errors are considered fatal if they are something we'd consider halting the VM for.
-#define IS_FATAL(Status) ((Status) < NO_ERR && (Status) >= ERR_BAD_PTR)
+#define IS_FATAL(Status) ((Status) < NO_ERR && (Status) > ERR_NON_FATAL)
//Direct command protocol opcodes
//!!! These MUST be mutually exclusive with c_comm's protocol opcodes.
@@ -114,7 +126,10 @@ enum
RC_SET_PROPERTY,
RC_GET_PROPERTY,
RC_UPDATE_RESET_COUNT,
-
+ RC_SET_VM_STATE,
+ RC_GET_VM_STATE,
+ RC_SET_BREAKPOINTS,
+ RC_GET_BREAKPOINTS,
NUM_RC_OPCODES
};
@@ -122,9 +137,20 @@ enum
enum {
RC_PROP_BTONOFF,
RC_PROP_SOUND_LEVEL,
-RC_PROP_SLEEP_TIMEOUT
+RC_PROP_SLEEP_TIMEOUT,
+RC_PROP_DEBUGGING = 0xF
};
+#define RC_PORTS_AB 0xFC
+#define RC_PORTS_AC 0xFD
+#define RC_PORTS_BC 0xFE
+#define RC_PORTS_ALL 0xFF
+
+#define RC_OUT_AB 0x03
+#define RC_OUT_AC 0x04
+#define RC_OUT_BC 0x05
+#define RC_OUT_ABC 0x06
+
//
//Published status of last program to be activated
//This value is published so outside parties (like the UI) can check if a program is running,
@@ -134,15 +160,14 @@ RC_PROP_SLEEP_TIMEOUT
//PROG_ERROR: Last program ended because of an error
//PROG_ABORT: Last program ended because of (user) abort
//
-typedef enum
-{
- PROG_IDLE,
- PROG_OK,
- PROG_RUNNING,
- PROG_ERROR,
- PROG_ABORT,
- PROG_RESET
-} PROGRAM_STATUS;
+
+typedef SBYTE PROGRAM_STATUS;
+#define PROG_IDLE 0x00
+#define PROG_OK 0x01
+#define PROG_RUNNING 0x02
+#define PROG_ERROR 0x03
+#define PROG_ABORT 0x04
+#define PROG_RESET 0x05
//Maximum size of memory pool, in bytes
//!!! Code assumes this value is evenly divisible by 4!
diff --git a/AT91SAM7S256/Source/c_cmd_alternate.c b/AT91SAM7S256/Source/c_cmd_alternate.c
new file mode 100644
index 0000000..c892c9d
--- /dev/null
+++ b/AT91SAM7S256/Source/c_cmd_alternate.c
@@ -0,0 +1,108 @@
+//
+// File Description:
+// This file contains an alternate implementation of c_cmd for testing purposes.
+// It implements the minimal standard interface for the module, and serves as
+// an example of output module control via C code.
+//
+
+void cCmdInit(void* pHeader)
+{
+ pHeaders = pHeader;
+
+ IOMapCmd.Awake = TRUE;
+
+ dTimerInit();
+ IOMapCmd.Tick = dTimerRead();
+
+ return;
+}
+
+//Test: Start at speed 100 when enter is pressed; then progressively ramp down every half second until -100.
+void cCmdCtrl(void)
+{
+ static UBYTE State = 0;
+ static ULONG MyTick = 0;
+
+ if (pMapButton->State[BTN1] & PRESSED_EV)
+ {
+ pMapButton->State[BTN1] &= ~PRESSED_EV;
+
+ State = 1;
+ }
+
+ switch(State)
+ {
+ case 0:
+ {
+ //Initialize
+ pMapInput->Inputs[0].SensorType = LOWSPEED;
+ }
+ break;
+
+ case 1:
+ {
+ if (pMapLowSpeed->ChannelState[0] == LOWSPEED_IDLE)
+ {
+ pMapLowSpeed->OutBuf[0].InPtr = 0;
+ pMapLowSpeed->OutBuf[0].OutPtr = 0;
+
+ pMapLowSpeed->OutBuf[0].Buf[pMapLowSpeed->OutBuf[0].InPtr] = 0x88; // I2C adress = 1000100X
+ pMapLowSpeed->OutBuf[0].InPtr++;
+ pMapLowSpeed->OutBuf[0].Buf[pMapLowSpeed->OutBuf[0].InPtr] = 0x00; // Selecting register to write into
+ pMapLowSpeed->OutBuf[0].InPtr++;
+ pMapLowSpeed->OutBuf[0].Buf[pMapLowSpeed->OutBuf[0].InPtr] = 0x88; // Data to set into register => Setting Control register
+ pMapLowSpeed->OutBuf[0].InPtr++;
+
+ pMapLowSpeed->InBuf[0].BytesToRx = 0;
+ pMapLowSpeed->ChannelState[0] = LOWSPEED_INIT;
+ pMapLowSpeed->State = COM_CHANNEL_ONE_ACTIVE;
+
+ State = 2;
+ }
+ }
+ break;
+
+ case 2:
+ {
+ if (pMapLowSpeed->ChannelState[0] == LOWSPEED_IDLE)
+ {
+ pMapLowSpeed->OutBuf[0].InPtr = 0;
+ pMapLowSpeed->OutBuf[0].OutPtr = 0;
+
+ pMapLowSpeed->OutBuf[0].Buf[pMapLowSpeed->OutBuf[0].InPtr] = 0x88; // I2C adress = 1000100X
+ pMapLowSpeed->OutBuf[0].InPtr++;
+ pMapLowSpeed->OutBuf[0].Buf[pMapLowSpeed->OutBuf[0].InPtr] = 0x04; // Start register to read from
+ pMapLowSpeed->OutBuf[0].InPtr++;
+
+ pMapLowSpeed->InBuf[0].BytesToRx = 2; // Read 2 bytes from I2C unit
+ pMapLowSpeed->ChannelState[0] = LOWSPEED_INIT;
+ pMapLowSpeed->State = COM_CHANNEL_ONE_ACTIVE;
+
+ State = 3;
+ }
+ }
+ break;
+
+ case 3:
+ {
+
+ }
+ break;
+
+ default:
+ break;
+ };
+
+ //Busy loop to ensure return on 1ms boundary
+ while (IOMapCmd.Tick == dTimerRead());
+
+ IOMapCmd.Tick = dTimerRead();
+ MyTick++;
+
+ return;
+}
+
+void cCmdExit(void)
+{
+ return;
+}
diff --git a/AT91SAM7S256/Source/c_cmd_bytecodes.h b/AT91SAM7S256/Source/c_cmd_bytecodes.h
index 5cd9dfd..5c24472 100644
--- a/AT91SAM7S256/Source/c_cmd_bytecodes.h
+++ b/AT91SAM7S256/Source/c_cmd_bytecodes.h
@@ -4,7 +4,7 @@
// opcode definitions
// symbol, bits, arg format
//
-#define OPCODE_COUNT 0x38
+#define OPCODE_COUNT 0x51
//Family: Math
#define OP_ADD 0x00 // dest, src1, src2
@@ -21,13 +21,13 @@
#define OP_NOT 0x09 // dest, src
//Family: Bit manipulation
-#define OP_CMNT 0x0A // dest, src
-#define OP_LSL 0x0B // dest, src
-#define OP_LSR 0x0C // dest, src
-#define OP_ASL 0x0D // dest, src
-#define OP_ASR 0x0E // dest, src
-#define OP_ROTL 0x0F // dest, src
-#define OP_ROTR 0x10 // dest, src
+#define OP_CMNT 0x0A // dest, src
+#define OP_LSL 0x0B // dest, src, bits
+#define OP_LSR 0x0C // dest, src, bits
+#define OP_ASL 0x0D // dest, src, bits
+#define OP_ASR 0x0E // dest, src, bits
+#define OP_ROTL 0x0F // dest, src, bits
+#define OP_ROTR 0x10 // dest, src, bits
//Family: Comparison
#define OP_CMP 0x11 // dest, src1, src2
@@ -86,6 +86,69 @@
#define OP_SQRT 0x36 // dest, src
#define OP_ABS 0x37 // dest, src
+// JCH ADDS
+#define OP_WAITI 0x64 // immed
+#define OP_WAITV 0x65 // var
+#define OP_SIGN 0x66 // dest, src
+#define OP_STOPCLUMPIMMED 0x67 // clumpID
+#define OP_STARTCLUMPIMMED 0x68 // clumpID
+#define OP_PRIORITY 0x69 // clumpID, pri
+#define OP_FMTNUM 0x6a // dest, fmt, src1
+#define OP_ARROP 0x6b // cmd, dest, src, idx, len
+
+// math ops (float)
+#define OP_ACOS 0x6c // dest, src
+#define OP_ASIN 0x6d // dest, src
+#define OP_ATAN 0x6e // dest, src
+#define OP_CEIL 0x6f // dest, src
+#define OP_EXP 0x70 // dest, src
+#define OP_FLOOR 0x71 // dest, src
+#define OP_TAN 0x72 // dest, src
+#define OP_COS 0x74 // dest, src
+#define OP_LOG 0x76 // dest, src
+#define OP_LOG10 0x77 // dest, src
+#define OP_SIN 0x78 // dest, src
+#define OP_TRUNC 0x7a // dest, src
+#define OP_FRAC 0x7b // dest, src
+
+#define OP_ATAN2 0x7c // dest, src1, src2
+#define OP_POW 0x7d // dest, src1, src2
+
+#define OP_MULDIV 0x7e // dest, src1, src2, src3
+
+// transcendental opcodes that use degrees instead of radians
+#define OP_ACOSD 0x7f // dest, src
+#define OP_ASIND 0x80 // dest, src
+#define OP_ATAND 0x81 // dest, src
+#define OP_TAND 0x82 // dest, src
+#define OP_COSD 0x84 // dest, src
+#define OP_SIND 0x86 // dest, src
+#define OP_ATAN2D 0x88 // dest, src1, src2
+
+
+// hyperbolic transcendental functions
+#define OP_TANH 0x73 // dest, src
+#define OP_COSH 0x75 // dest, src
+#define OP_SINH 0x79 // dest, src
+#define OP_TANHD 0x83 // dest, src
+#define OP_COSHD 0x85 // dest, src
+#define OP_SINHD 0x87 // dest, src
+
+// misc other JCH additions
+#define OP_ADDROF 0x89 // dest, src, rel
+
+// additional string opcodes
+
+
+// array operation definitions
+#define OPARR_SUM 0x00
+#define OPARR_MEAN 0x01
+#define OPARR_SUMSQR 0x02
+#define OPARR_STD 0x03
+#define OPARR_MIN 0x04
+#define OPARR_MAX 0x05
+#define OPARR_SORT 0x06
+
// condition code definitions
#define OPCC1_LT 0x00
#define OPCC1_GT 0x01
diff --git a/AT91SAM7S256/Source/c_cmd_drawing.inc b/AT91SAM7S256/Source/c_cmd_drawing.inc
index 0132d44..5592180 100644
--- a/AT91SAM7S256/Source/c_cmd_drawing.inc
+++ b/AT91SAM7S256/Source/c_cmd_drawing.inc
@@ -12,12 +12,17 @@
// Platform C
//
+#define MAX_CORNERS 128
+
//absolute value of a
#define ABS(a) (((a)<0) ? -(a) : (a))
//take binary sign of a, either -1, or 1 if >= 0
#define SGN(a) (((a)<0) ? -1 : 1)
+#define MAX(a,b) (((a>b) ? (a) : (b)))
+#define MIN(a,b) (((a<b) ? (a) : (b)))
+
#define DISP_BUFFER_P ((UBYTE*)&(pMapDisplay->Normal))
//------------------------------------------------------------------
@@ -30,7 +35,7 @@ void cCmdRestoreDefaultScreen(void);
//------------------------------------------------------------------
// cCmdDrawString - Draw string to display buffer
-void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y);
+void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y, UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode);
// OP codes supported by RIC files
enum {
@@ -42,17 +47,73 @@ enum {
IMG_LINE_ID = 5,
IMG_RECTANGLE_ID = 6,
IMG_CIRCLE_ID = 7,
- IMG_NUMBOX_ID = 8
+ IMG_NUMBOX_ID = 8,
+ IMG_ELLIPSE_ID = 9,
+ IMG_POLYGON_ID = 10
};
#define IMG_SYMB_USEARGS(_v) (_v & (SWORD)0xF000)
#define IMG_SYMB_MAP(_v) ((_v & 0x0F00) >> 8)
-#define IMG_SYMB_ARG(_v) (_v & 0x000F)
+#define IMG_SYMB_ARG(_v) (_v & 0x00FF)
+
+//JJR
+//#define DRAW_OPT_CLEAR_PIXELS (0x0004)
+//#define SET_PIXELS(_v) (((_v) & DRAW_OPT_CLEAR_PIXELS) ? FALSE : TRUE)
// DrawingOptions
-#define DRAW_OPT_CLEAR_WHOLE_SCREEN (0x0001)
-#define DRAW_OPT_CLEAR_EXCEPT_STATUS_SCREEN (0x0002)
-#define DRAW_OPT_CLEAR_MODE(_v) ((_v) & 0x0003)
+// (and CopyOptions)
+// - parameter used within byte code drawing operations
+// - now unified with 'CopyOptions' parameter in RIC files
+// Bits 0 & 1 (values 0,1,2,3) control screen clearing behaviour (Not within RIC files).
+// Bit 2 (value 4) controls the NOT operation, i.e. draw in white or invert text/graphics.
+// Bits 3 & 4 (values 0,8,16,24) control pixel logical combinations (COPY/AND/OR/XOR).
+// Bit 5 (value 32) controls shape filling, or overrides text/graphic bitmaps with set pixels.
+// These may be ORed together for the full instruction.
+// These operations are resolved into the separate, common parameters
+// defined in 'c_display.iom' before any drawing function is called.
+// Note that when drawing a RIC file, the initial 'DrawingOptions' parameter
+// supplied in the drawing instruction controls screen clearing, but nothing else.
+// The 'CopyOptions' parameter from each instruction in the RIC file then controls
+// graphic operations, but the screen-clearing bits are ignored.
+
+#define DRAW_OPT_NORMAL (0x0000)
+#define DRAW_OPT_LOGICAL_COPY (0x0000)
+
+#define DRAW_OPT_CLEAR_WHOLE_SCREEN (0x0001)
+#define DRAW_OPT_CLEAR_EXCEPT_STATUS_SCREEN (0x0002)
+#define DRAW_OPT_INVERT (0x0004)
+#define DRAW_OPT_LOGICAL_AND (0x0008)
+#define DRAW_OPT_LOGICAL_OR (0x0010)
+#define DRAW_OPT_LOGICAL_XOR (0x0018)
+#define DRAW_OPT_FILL_SHAPE (0x0020)
+
+// Combined parameter masks:
+#define DRAW_OPT_CLEAR_SCREEN_MODES (0x0003)
+#define DRAW_OPT_LOGICAL_OPERATIONS (0x0018)
+#define DRAW_OPT_FONT_DIRECTIONS (0x01C0)
+
+#define DRAW_OPT_FONT_WRAP (0x0200)
+
+#define DRAW_OPT_FONT_DIR_L2RB (0x0000) // Font left to right bottom align
+#define DRAW_OPT_FONT_DIR_L2RT (0x0040) // Font left to right top align
+#define DRAW_OPT_FONT_DIR_R2LB (0x0080) // Font right to left bottom align
+#define DRAW_OPT_FONT_DIR_R2LT (0x00C0) // Font right to left top align
+#define DRAW_OPT_FONT_DIR_B2TL (0x0100) // Font bottom to top left align
+#define DRAW_OPT_FONT_DIR_B2TR (0x0140) // Font bottom to top right align
+#define DRAW_OPT_FONT_DIR_T2BL (0x0180) // Font top to bottom left align
+#define DRAW_OPT_FONT_DIR_T2BR (0x01C0) // Font top to bottom right align
+
+// new constant for polyline vs polygon
+#define DRAW_OPT_POLYGON_POLYLINE (0x0400)
+
+#define DESC_FONTOUT 0x8001 // ID for new font out function
+
+// CopyOptions, as originally defined for RIC files, now equate to:
+// COPY = 0 = 0x00 = DRAW_OPT_NORMAL = Copy all bits, solid and clear
+// COPY_NOT = 4 = 0x04 = DRAW_OPT_INVERT = Copy all bits, but invert bitmap images first
+// OR = 16 = 0x10 = DRAW_OPT_LOGICAL_OR = Copy solid bits, ignore clear bits
+// BIT_CLEAR = 12 = 0x0C = DRAW_OPT_INVERT + DRAW_OPT_LOGICAL_AND = Erase screen for solid bits, ignore clear bits
+//JJR
// Clear Before Drawing Modes for Draw functions
@@ -63,7 +124,8 @@ enum {
// Screen Modes for SetScreenMode function
enum {
- RESTORE_NXT_SCREEN = 0
+ RESTORE_NXT_SCREEN = 0,
+ CLEAR_NXT_SCREEN = 1
};
#define IMG_COMMON_FIELDS UWORD OpSize; UWORD OpCode;
@@ -118,7 +180,7 @@ typedef struct
typedef struct
{
IMG_COMMON_FIELDS
- UWORD CopyOptions; // Copy, CopyNot, Or, BitClear;
+ UWORD CopyOptions; // Copy, CopyNot, Or, BitClear; //JJR ,Xor;
UWORD DataAddr; // Address of an already defined sprite
IMG_RECT Src; // Source rectangle
IMG_PT Dst; // Destination left top
@@ -164,6 +226,23 @@ typedef struct
UWORD Value; // typically mapped to an argument
} IMG_OP_NUMBOX;
+typedef struct
+{
+ IMG_COMMON_FIELDS
+ UWORD CopyOptions;
+ IMG_PT Pt;
+ UWORD Radius1;
+ UWORD Radius2;
+} IMG_OP_ELLIPSE;
+
+typedef struct
+{
+ IMG_COMMON_FIELDS
+ UWORD CopyOptions;
+ UWORD Count; //The actual size of the following array.
+ IMG_PT Points[3]; //Minimum of 3 for polygon
+} IMG_OP_POLYGON;
+
typedef union
{ IMG_OP_CORE Core;
IMG_OP_DESCRIPTION Desc;
@@ -175,22 +254,47 @@ typedef union
IMG_OP_RECT Rect;
IMG_OP_CIRCLE Circle;
IMG_OP_NUMBOX NumBox;
+ IMG_OP_ELLIPSE Ellipse;
+ IMG_OP_POLYGON Polygon;
} IMG_OP_UNION;
// Variables for DrawImage
#define IMG_MAX_DATA 11
IMG_OP_UNION * gpImgData[IMG_MAX_DATA];
-SLONG * gpPassedImgVars;
-SWORD gPassedVarsCount;
+SLONG * gpPassedImgVars = NULL;
+SWORD gPassedVarsCount = 0;
// Private Prototypes
-void cCmdDrawLine(SLONG x1, SLONG y1, SLONG x2, SLONG y2);
-void cCmdDrawRect(SLONG left, SLONG bottom, SLONG width, SLONG hieght);
+void cCmdDrawLine(SLONG x1, SLONG y1, SLONG x2, SLONG y2, UBYTE PixelMode);
+void cCmdDrawRect(SLONG left, SLONG bottom, SLONG width, SLONG height, UBYTE PixelMode, UBYTE FillMode);
+void cCmdDrawCircle(SLONG cx, SLONG cy, SLONG radius, UBYTE PixelMode, UBYTE FillMode);
+void cCmdDrawPolygon(IMG_PT* points, UWORD polyCorners, UBYTE PixelMode, UBYTE FillMode, UBYTE bLine);
+void cCmdDrawEllipse(SWORD cx, SWORD cy, SWORD a, SWORD b, UBYTE PixelMode, UBYTE FillMode);
void cCmdCopyBitMapBits(SLONG dst_x, SLONG dst_y,
SLONG src_x, SLONG src_y, SLONG src_width, SLONG src_height,
- IMG_OP_SPRITE * pSprite);
+ IMG_OP_SPRITE * pSprite,
+ UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode);
SLONG cCmdResolveValue(SWORD Value);
-void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val);
+void cCmdSetPixel(SLONG X, SLONG Y, ULONG PixelMode);
+
+UBYTE cCmdResolveDrawingMode(UWORD DrawingOptions, UBYTE* pPixelMode, UBYTE* pFillMode);
+void cCmdResolveBitmapMode(UWORD DrawingOptions, UBYTE* pInvertMode, UBYTE* pLogicalMode, UBYTE* pFillMode);
+UBYTE cCmdResolveClearScreenMode(UWORD DrawingOptions);
+
+void cCmdResolveFontOptions(UWORD DrawingOptions, UBYTE* pFontDir, UBYTE* pFontWrap);
+void cCmdDrawFont(IMG_OP_SPRITE *pSprite, SLONG sW, SLONG sH, SLONG startx, SLONG starty,
+ UBYTE fontDir, UBYTE fontWrap, UBYTE invertMode, UBYTE logicalMode, UBYTE fillMode);
+
+
+void cCmdDrawTextHelper(ULONG DrawOptions, UBYTE *pString, IMG_PT * pPt)
+{
+ UBYTE invertMode, logicalMode, fillMode;
+ cCmdClearScreenIfNeeded(DrawOptions);
+ // Display the String
+ cCmdResolveBitmapMode(DrawOptions, &invertMode, &logicalMode, &fillMode);
+ cCmdDrawString(pString, (UBYTE)pPt->X, (UBYTE)pPt->Y, invertMode, logicalMode, fillMode);
+ pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
+}
//-----------------------------------------------------------------
//cCmdWrapDrawText
@@ -204,13 +308,7 @@ NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[])
IMG_PT * pPt = (IMG_PT*) ArgV[1];
ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); //Resolve array argument
-
- cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);
-
- // Display the String
- cCmdDrawString(ArgV[2], (UBYTE)pPt->X, (UBYTE)(pPt->Y));
- pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
-
+ cCmdDrawTextHelper(*(ULONG*)ArgV[3], ArgV[2], pPt);
// Set return value
*((SBYTE*)(ArgV[0])) = NO_ERR;
@@ -225,11 +323,14 @@ NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[])
NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[])
{
IMG_PT * pPt = (IMG_PT*) ArgV[1];
+ ULONG DrawOptions = *(ULONG*)ArgV[2];
+ UBYTE pixelMode, fillMode;
- cCmdClearScreenIfNeeded(*(ULONG*)ArgV[2]);
+ cCmdClearScreenIfNeeded(DrawOptions);
- // Display the String
- cCmdSetPixel(pPt->X, pPt->Y, TRUE);
+ // Display the Pixel
+ if (cCmdResolveDrawingMode(DrawOptions, &pixelMode, &fillMode))
+ cCmdSetPixel(pPt->X, pPt->Y, pixelMode);
pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
@@ -249,10 +350,13 @@ NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[])
{
IMG_PT * pPt1 = (IMG_PT*) ArgV[1];
IMG_PT * pPt2 = (IMG_PT*) ArgV[2];
+ ULONG DrawOptions = *(ULONG*)ArgV[3];
+ UBYTE pixelMode, fillMode;
- cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);
+ cCmdClearScreenIfNeeded(DrawOptions);
- cCmdDrawLine(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y);
+ if (cCmdResolveDrawingMode(DrawOptions, &pixelMode, &fillMode))
+ cCmdDrawLine(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y, pixelMode);
pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
@@ -270,61 +374,15 @@ NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[])
//ArgV[3]: Options (ULONG)
NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[])
{
- SLONG x, x1, y1, y, dp, delta;
IMG_PT * pPt = (IMG_PT*) ArgV[1];
SLONG radius = *(UBYTE*)ArgV[2];
-
- cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);
-
- x1 = pPt->X;
- y1 = pPt->Y;
- x = 0;
- y = radius;
- dp=2*(1-radius);
- while(y >= 0)
- {
- cCmdSetPixel((x+x1), (y+y1), TRUE);
- cCmdSetPixel((-x+x1),(-y+y1), TRUE);
- cCmdSetPixel((x+x1), (-y+y1), TRUE);
- cCmdSetPixel((-x+x1),(y+y1), TRUE);
- if(dp<0)
- {
- delta = 2*dp + 2*y - 1;
- if (delta > 0)
- {
- x++;
- y--;
- dp += 2*x - 2*y + 2;
- }
- else
- {
- x++;
- dp += 2*x + 1;
- }
- }
- else if (dp > 0)
- {
- delta = 2*dp - 2*x - 1;
- if (delta > 0)
- {
- y--;
- dp += 1 - 2*y;
- }
- else
- {
- x++;
- y--;
- dp += 2*x - 2*y + 2;
- }
- }
- else
- {
- x++;
- y--;
- dp += 2*x - 2*y +2;
- }
- }
-
+ ULONG DrawOptions = *(ULONG*)ArgV[3];
+ UBYTE pixelMode, fillMode;
+
+ cCmdClearScreenIfNeeded(DrawOptions);
+ if (cCmdResolveDrawingMode(DrawOptions, &pixelMode, &fillMode))
+ cCmdDrawCircle(pPt->X, pPt->Y, radius, pixelMode, fillMode);
+
pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
// Set return value
@@ -343,10 +401,13 @@ NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[])
{
IMG_PT * pPt1 = (IMG_PT*) ArgV[1];
IMG_PT * pPt2 = (IMG_PT*) ArgV[2]; // Second point is actually (width, height)
+ ULONG DrawOptions = *(ULONG*)ArgV[3];
+ UBYTE pixelMode, fillMode;
- cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);
+ cCmdClearScreenIfNeeded(DrawOptions);
- cCmdDrawRect(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y);
+ if (cCmdResolveDrawingMode(DrawOptions, &pixelMode, &fillMode))
+ cCmdDrawRect(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y, pixelMode, fillMode);
pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
@@ -357,6 +418,65 @@ NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[])
}
//-----------------------------------------------------------------
+//cCmdWrapDrawPolygon
+//ArgV[0]: (Function return) Status byte, SBYTE
+//ArgV[1]: Points IMG_PT[]
+//ArgV[2]: Options (ULONG)
+NXT_STATUS cCmdWrapDrawPolygon(UBYTE * ArgV[])
+{
+ ULONG DrawOptions = *(ULONG*)ArgV[2];
+ UBYTE pixelMode, fillMode, bLine;
+
+ //Resolve array argument
+ IMG_PT * Points = (IMG_PT*)cCmdDVPtr(*(DV_INDEX *)(ArgV[1]));
+ UWORD polyCorners = DV_ARRAY[*(DV_INDEX *)(ArgV[1])].Count;
+
+ cCmdClearScreenIfNeeded(DrawOptions);
+ bLine = (DrawOptions & DRAW_OPT_POLYGON_POLYLINE) ? 1 : 0;
+ if (cCmdResolveDrawingMode(DrawOptions, &pixelMode, &fillMode)) {
+ if (fillMode == DRAW_SHAPE_FILLED && polyCorners > MAX_CORNERS) {
+ // Set return value
+ *((SBYTE*)(ArgV[0])) = ERR_INSTR;
+ return ERR_INSTR;
+ }
+ else
+ cCmdDrawPolygon(Points, polyCorners, pixelMode, fillMode, bLine);
+ }
+
+ pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
+
+ // Set return value
+ *((SBYTE*)(ArgV[0])) = NO_ERR;
+
+ return NO_ERR;
+}
+
+//-----------------------------------------------------------------
+//cCmdWrapDrawEllipse
+//ArgV[0]: (Function return) Status byte, SBYTE
+//ArgV[1]: Start Location (IMG_PT *)
+//ArgV[2]: Radius1 (U8)
+//ArgV[3]: Radius2 (U8)
+//ArgV[4]: Options (ULONG)
+NXT_STATUS cCmdWrapDrawEllipse(UBYTE * ArgV[])
+{
+ IMG_PT * pPt = (IMG_PT*) ArgV[1];
+ SWORD radius1 = *(UBYTE*)ArgV[2];
+ SWORD radius2 = *(UBYTE*)ArgV[3];
+ ULONG DrawOptions = *(ULONG*)ArgV[4];
+ UBYTE pixelMode, fillMode;
+
+ cCmdClearScreenIfNeeded(DrawOptions);
+ if (cCmdResolveDrawingMode(DrawOptions, &pixelMode, &fillMode))
+ cCmdDrawEllipse(pPt->X, pPt->Y, radius1, radius2, pixelMode, fillMode);
+
+ pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
+ // Set return value
+ *((SBYTE*)(ArgV[0])) = NO_ERR;
+ return NO_ERR;
+}
+
+//-----------------------------------------------------------------
IMG_OP_UNION * cCmdGetIMGData(ULONG DataAddr)
{
if (DataAddr >= IMG_MAX_DATA)
@@ -375,12 +495,17 @@ void cCmdSetIMGData(ULONG DataAddr, IMG_OP_UNION * pSprite)
//-----------------------------------------------------------------
SLONG cCmdResolveValue(SWORD Value)
{
- if (!IMG_SYMB_USEARGS(Value))
+ if (!IMG_SYMB_USEARGS(Value) || !gpPassedImgVars || (gPassedVarsCount == 0))
{
return Value;
}
else
{
+ // if we try to access a variable beyond the end of the array we provided
+ // then just return the original value
+ if (IMG_SYMB_ARG(Value) >= gPassedVarsCount)
+ return Value;
+
IMG_OP_VARMAP * pVarMap;
SLONG Arg;
@@ -428,252 +553,843 @@ SLONG cCmdResolveValue(SWORD Value)
}
-//-----------------------------------------------------------------
-//cCmdWrapDrawGraphic
-//ArgV[0]: (Function return) Status Byte, SBYTE
-//ArgV[1]: Left Top (IMG_PT *)
-//ArgV[2]: Filename, CStr
-//ArgV[3]: Variables, array of I32
-//ArgV[4]: Options (ULONG)
-NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[])
+NXT_STATUS cCmdDrawPictureHelper(IMG_OP_UNION** ppImage, IMG_PT* pPoint, SLONG* pVars, ULONG DataSize, ULONG Options)
{
- SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
- LOADER_STATUS LStatus;
- NXT_STATUS DStatus = NO_ERR;
- ULONG DataSize;
- SLONG OpSize;
- IMG_PT Pt; // Where to draw the picture at (up and to the right)
- UBYTE ImageHandle;
- IMG_OP_UNION * pImage;
-
- //Resolve array argument
- ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2]));
- ArgV[3] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[3]));
-
- cCmdClearScreenIfNeeded(*(ULONG*)ArgV[4]);
-
- //Open the file in memory map mode. return if failure.
- LStatus = pMapLoader->pFunc(OPENREADLINEAR, ArgV[2], (UBYTE*)(&pImage), &DataSize);
- ImageHandle = LOADER_HANDLE(LStatus);
-
- //If error opening file, give up and write loader status back to user.
- if (LOADER_ERR(LStatus) != SUCCESS || pImage == NULL)
+ SLONG OpSize;
+ UBYTE gFillMode, gInvertMode, gLogicalMode, gFontDir, gFontWrap;
+ UBYTE pixelMode, fillMode;
+ UBYTE invertMode, logicalMode;
+ IMG_PT Pt; // Where to draw the picture at (up and to the right)
+ NXT_STATUS DStatus = NO_ERR;
+ IMG_OP_UNION* pImage = *ppImage;
+ // Read the params, Clear the data table.
+ Pt = *pPoint;
+ gpPassedImgVars = pVars;
+ memset(gpImgData,0,sizeof(gpImgData));
+
+ cCmdClearScreenIfNeeded(Options);
+
+ cCmdResolveBitmapMode(Options, &gInvertMode, &gLogicalMode, &gFillMode);
+ cCmdResolveFontOptions(Options, &gFontDir, &gFontWrap);
+
+ // Run through the op codes.
+ while(!IS_ERR(DStatus))
{
- *pReturnVal = (SBYTE)(LOADER_ERR_BYTE(LStatus));
- return (NO_ERR);
- }
- //Else, start interpretting the file
- else
- {
- // Read the ArgV params, Clear the data table.
- Pt = *(IMG_PT*)ArgV[1];
- //!!! Unsafe assumption that array is non-empty. Should check and avoid using pointer if empty.
- gpPassedImgVars = (SLONG*)ArgV[3];
- memset(gpImgData,0,sizeof(gpImgData));
-
- // Run through the op codes.
- while(!IS_ERR(DStatus))
+ // Setup to look at an opcode, make sure it looke reasonable.
+ if (DataSize < sizeof(IMG_OP_CORE))
+ {
+ DStatus = ERR_FILE;
+ break; // Too small to look at, somethings wrong.
+ }
+ OpSize = pImage->Core.OpSize + sizeof(UWORD);
+ if (OpSize & 0x01)
+ {
+ DStatus = ERR_FILE;
+ break; // Odd sizes not allowed.
+ }
+
+ switch(pImage->Core.OpCode)
{
- // Setup to look at an opcode, make sure it looke reasonable.
- if (DataSize < sizeof(IMG_OP_CORE))
+ case IMG_SPRITE_ID:
{
- DStatus = ERR_FILE;
- break; // Too small to look at, somethings wrong.
+ if (OpSize >= sizeof(IMG_OP_SPRITE))
+ cCmdSetIMGData(pImage->Sprite.DataAddr, pImage);
}
- OpSize = pImage->Core.OpSize + sizeof(UWORD);
- if (OpSize & 0x01)
+ break;
+
+ case IMG_VARMAP_ID:
{
- DStatus = ERR_FILE;
- break; // Odd sizes not allowed.
+ if (OpSize >= sizeof(IMG_OP_VARMAP))
+ cCmdSetIMGData(pImage->VarMap.DataAddr, pImage);
}
+ break;
- switch(pImage->Core.OpCode)
+ case IMG_COPYBITS_ID:
{
- case IMG_SPRITE_ID:
+ if (OpSize >= sizeof(IMG_OP_COPYBITS))
{
- if (OpSize >= sizeof(IMG_OP_SPRITE))
- cCmdSetIMGData(pImage->Sprite.DataAddr, pImage);
+ IMG_OP_COPYBITS * pCB = &(pImage->CopyBits);
+ cCmdResolveBitmapMode(pCB->CopyOptions, &invertMode, &logicalMode, &fillMode);
+ cCmdCopyBitMapBits(
+ (cCmdResolveValue(pCB->Dst.X) + Pt.X),
+ (cCmdResolveValue(pCB->Dst.Y) + Pt.Y),
+ cCmdResolveValue((pCB->Src.Pt.X)),
+ cCmdResolveValue((pCB->Src.Pt.Y)),
+ cCmdResolveValue((pCB->Src.Width)),
+ cCmdResolveValue((pCB->Src.Height)),
+ (IMG_OP_SPRITE*)cCmdGetIMGData(cCmdResolveValue(pCB->DataAddr)),
+ invertMode, logicalMode, fillMode);
}
- break;
+ }
+ break;
- case IMG_VARMAP_ID:
+ case IMG_LINE_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_LINE))
{
- if (OpSize >= sizeof(IMG_OP_VARMAP))
- cCmdSetIMGData(pImage->VarMap.DataAddr, pImage);
+ IMG_OP_LINE * pL = &(pImage->Line);
+ cCmdResolveDrawingMode(pL->CopyOptions, &pixelMode, &fillMode); //JJR
+ cCmdDrawLine(
+ (cCmdResolveValue(pL->Pt1.X)+Pt.X),
+ (cCmdResolveValue(pL->Pt1.Y)+Pt.Y),
+ (cCmdResolveValue(pL->Pt2.X)+Pt.X),
+ (cCmdResolveValue(pL->Pt2.Y)+Pt.Y),
+ pixelMode //JJR
+ );
}
- break;
+ }
+ break;
- case IMG_COPYBITS_ID:
+ case IMG_RECTANGLE_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_RECT))
{
- if (OpSize >= sizeof(IMG_OP_COPYBITS))
- {
- IMG_OP_COPYBITS * pCB = &(pImage->CopyBits);
- cCmdCopyBitMapBits(
- (cCmdResolveValue(pCB->Dst.X) + Pt.X),
- (cCmdResolveValue(pCB->Dst.Y) + Pt.Y),
- cCmdResolveValue((pCB->Src.Pt.X)),
- cCmdResolveValue((pCB->Src.Pt.Y)),
- cCmdResolveValue((pCB->Src.Width)),
- cCmdResolveValue((pCB->Src.Height)),
- (IMG_OP_SPRITE*)cCmdGetIMGData(cCmdResolveValue(pCB->DataAddr)));
- }
+ IMG_OP_RECT * pR = &(pImage->Rect);
+ cCmdResolveDrawingMode(pR->CopyOptions, &pixelMode, &fillMode); //JJR
+ cCmdDrawRect(
+ (SWORD)(cCmdResolveValue(pR->Pt.X)+Pt.X),
+ (SWORD)(cCmdResolveValue(pR->Pt.Y)+Pt.Y),
+ (SWORD)(cCmdResolveValue(pR->Width)),
+ (SWORD)(cCmdResolveValue(pR->Height)),
+ pixelMode, fillMode //JJR
+ );
}
- break;
+ }
+ break;
- case IMG_LINE_ID:
+ case IMG_CIRCLE_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_CIRCLE))
{
- if (OpSize >= sizeof(IMG_OP_LINE))
- {
- IMG_OP_LINE * pL = &(pImage->Line);
- cCmdDrawLine(
- (cCmdResolveValue(pL->Pt1.X)+Pt.X),
- (cCmdResolveValue(pL->Pt1.Y)+Pt.Y),
- (cCmdResolveValue(pL->Pt2.X)+Pt.X),
- (cCmdResolveValue(pL->Pt2.Y)+Pt.Y)
- );
- }
+ IMG_OP_CIRCLE * pC = &(pImage->Circle);
+ cCmdResolveDrawingMode(pC->CopyOptions, &pixelMode, &fillMode); //JJR
+ cCmdDrawCircle(
+ (SWORD)(cCmdResolveValue(pC->Pt.X)+Pt.X),
+ (SWORD)(cCmdResolveValue(pC->Pt.Y)+Pt.Y),
+ (SWORD)(cCmdResolveValue(pC->Radius)),
+ pixelMode, fillMode //JJR
+ );
}
- break;
+ }
+ break;
- case IMG_RECTANGLE_ID:
+ case IMG_PIXEL_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_PIXEL))
{
- if (OpSize >= sizeof(IMG_OP_LINE))
- {
- IMG_OP_RECT * pL = &(pImage->Rect);
- cCmdDrawRect(
- (SWORD)(cCmdResolveValue(pL->Pt.X)+Pt.X),
- (SWORD)(cCmdResolveValue(pL->Pt.Y)+Pt.Y),
- (SWORD)(cCmdResolveValue(pL->Width)),
- (SWORD)(cCmdResolveValue(pL->Height))
+ cCmdResolveDrawingMode(pImage->Pixel.CopyOptions, &pixelMode, &fillMode); //JJR
+ cCmdSetPixel(
+ (cCmdResolveValue(pImage->Pixel.Pt.X) + Pt.X),
+ (cCmdResolveValue(pImage->Pixel.Pt.Y) + Pt.Y),
+ pixelMode //JJR
);
- }
}
- break;
+ }
+ break;
- case IMG_PIXEL_ID:
+ case IMG_NUMBOX_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_NUMBOX))
{
- if (OpSize >= sizeof(IMG_OP_PIXEL))
- {
- cCmdSetPixel(
- (cCmdResolveValue(pImage->Pixel.Pt.X) + Pt.X),
- (cCmdResolveValue(pImage->Pixel.Pt.Y) + Pt.Y),
- TRUE);
- }
+ UBYTE NumStr[20];
+ IMG_OP_NUMBOX * pNB = &(pImage->NumBox);
+ sprintf((PSZ)NumStr, "%d", cCmdResolveValue(pNB->Value));
+ cCmdResolveBitmapMode(pNB->CopyOptions, &invertMode, &logicalMode, &fillMode);
+ cCmdDrawString(
+ NumStr,
+ (UBYTE) (cCmdResolveValue(pNB->Pt.X) + Pt.X),
+ (UBYTE) (cCmdResolveValue(pNB->Pt.Y) + Pt.Y),
+ invertMode, logicalMode, fillMode //JJR
+ );
}
- break;
+ }
+ break;
- case IMG_NUMBOX_ID:
+ case IMG_ELLIPSE_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_ELLIPSE))
{
- if (OpSize >= sizeof(IMG_OP_NUMBOX))
- {
- UBYTE NumStr[20];
- IMG_OP_NUMBOX * pNB = &(pImage->NumBox);
- sprintf((PSZ)NumStr, "%d", cCmdResolveValue(pNB->Value));
- cCmdDrawString(
- NumStr,
- (UBYTE) (cCmdResolveValue(pNB->Pt.X) + Pt.X),
- (UBYTE) (cCmdResolveValue(pNB->Pt.Y) + Pt.Y));
- }
+ IMG_OP_ELLIPSE * pE = &(pImage->Ellipse);
+ cCmdResolveDrawingMode(pE->CopyOptions, &pixelMode, &fillMode); //JJR
+ cCmdDrawEllipse(
+ (SWORD)(cCmdResolveValue(pE->Pt.X)+Pt.X),
+ (SWORD)(cCmdResolveValue(pE->Pt.Y)+Pt.Y),
+ (SWORD)(cCmdResolveValue(pE->Radius1)),
+ (SWORD)(cCmdResolveValue(pE->Radius2)),
+ pixelMode, fillMode //JJR
+ );
}
- break;
+ }
+ break;
- case IMG_DESCRIPTION_ID:
+ case IMG_POLYGON_ID:
+ {
+ if (OpSize >= sizeof(IMG_OP_POLYGON))
{
- //No-op
+ IMG_OP_POLYGON * pP = &(pImage->Polygon);
+ UBYTE bLine = (pP->CopyOptions & DRAW_OPT_POLYGON_POLYLINE) ? 1 : 0;
+ cCmdResolveDrawingMode(pP->CopyOptions, &pixelMode, &fillMode); //JJR
+ // resolve all the values in the struct
+ if (fillMode != DRAW_SHAPE_FILLED || pP->Count <= MAX_CORNERS)
+ {
+ for(int i=0;i<pP->Count; i++) {
+ pP->Points[i].X = (SWORD)(cCmdResolveValue(pP->Points[i].X)+Pt.X);
+ pP->Points[i].Y = (SWORD)(cCmdResolveValue(pP->Points[i].Y)+Pt.Y);
+ }
+ cCmdDrawPolygon(pP->Points, pP->Count, pixelMode, fillMode, bLine);
+ }
}
- break;
+ }
+ break;
- default:
+ case IMG_DESCRIPTION_ID:
+ {
+ switch( pImage->Desc.Options )
{
- //Unrecognized opcode, pass an error back to the user.
- DStatus = ERR_FILE;
+ case DESC_FONTOUT :
+ cCmdDrawFont((IMG_OP_SPRITE*)cCmdGetIMGData(1), pImage->Desc.Width,
+ pImage->Desc.Height, Pt.X, Pt.Y, gFontDir, gFontWrap, gInvertMode,
+ gLogicalMode, gFillMode);
+ break;
}
- break;
}
+ break;
- DataSize -= OpSize;
- pImage = (IMG_OP_UNION*) ((UBYTE*)pImage + OpSize);
+ default:
+ {
+ //Unrecognized opcode, pass an error back to the user.
+ DStatus = ERR_FILE;
+ }
+ break;
}
- pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
+ DataSize -= OpSize;
+ pImage = (IMG_OP_UNION*) ((UBYTE*)pImage + OpSize);
}
+ gpPassedImgVars = NULL;
+ memset(gpImgData,0,sizeof(gpImgData));
+ pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);
+ return DStatus;
+}
- // Set return value, close file and return
- *pReturnVal = DStatus;
+void cCmdDrawPictureFromFile(UBYTE *pFilename, IMG_PT* pPoint, SLONG* pVars, ULONG Options, SBYTE * pReturnVal)
+{
+ LOADER_STATUS LStatus;
+ ULONG DataSize;
+ UBYTE ImageHandle;
+ IMG_OP_UNION * pImage;
+
+ //Open the file in memory map mode. return if failure.
+ LStatus = pMapLoader->pFunc(OPENREADLINEAR, pFilename, (UBYTE*)(&pImage), &DataSize);
+ ImageHandle = LOADER_HANDLE(LStatus);
+
+ //If error opening file, give up and write loader status back to user.
+ if (LOADER_ERR(LStatus) != SUCCESS || pImage == NULL)
+ {
+ *pReturnVal = (SBYTE)(LOADER_ERR_BYTE(LStatus));
+ return;
+ }
+ //Else, start interpretting the file
+ else
+ {
+ *pReturnVal = cCmdDrawPictureHelper(&pImage, pPoint, pVars, DataSize, Options);
+ }
pMapLoader->pFunc(CLOSE, &ImageHandle, NULL, NULL);
+}
+
+//-----------------------------------------------------------------
+//cCmdWrapDrawPicture
+//ArgV[0]: (Function return) Status Byte, SBYTE
+//ArgV[1]: Left Top (IMG_PT *)
+//ArgV[2]: Filename, CStr
+//ArgV[3]: Variables, array of I32
+//ArgV[4]: Options (ULONG)
+NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE *)ArgV[0];
+ IMG_PT* pPt = (IMG_PT*)ArgV[1];
+ ULONG Options = *(ULONG *)ArgV[4];
+
+ // count the variables
+ gPassedVarsCount = DV_ARRAY[*(DV_INDEX *)(ArgV[3])].Count;
+
+ //Resolve array argument
+ ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2]));
+ ArgV[3] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[3]));
+
+ cCmdDrawPictureFromFile((UBYTE *)ArgV[2], pPt, (SLONG *)ArgV[3], Options, pReturnVal);
+
+ return (NO_ERR);
+}
+
+//-----------------------------------------------------------------
+//cCmdWrapDrawPictureArray
+//ArgV[0]: (Function return) Status Byte, SBYTE
+//ArgV[1]: Left Top (IMG_PT *)
+//ArgV[2]: Data, array of U8
+//ArgV[3]: Variables, array of I32
+//ArgV[4]: Options (ULONG)
+NXT_STATUS cCmdWrapDrawPictureArray(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE *)ArgV[0];
+ IMG_PT* pPt = (IMG_PT *)ArgV[1];
+ DV_INDEX DVIndex = *(DV_INDEX*)ArgV[2];
+ ULONG Options = *(ULONG *)ArgV[4];
+ ULONG DataSize = DV_ARRAY[DVIndex].Count;
+ IMG_OP_UNION* pImage;
+
+ // count the variables
+ gPassedVarsCount = DV_ARRAY[*(DV_INDEX *)(ArgV[3])].Count;
+
+ //Resolve array argument
+ pImage = (IMG_OP_UNION*)cCmdDVPtr(DVIndex);
+ ArgV[3] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[3])); // pVar
+
+ *pReturnVal = cCmdDrawPictureHelper((IMG_OP_UNION**)&pImage, pPt, (SLONG*)ArgV[3], DataSize, Options);
return (NO_ERR);
}
//-----------------------------------------------------------------
-// cCmdDrawLine - draw a line. All clipping is done by the set pixel function.
+//cCmdWrapDrawFont
+//ArgV[0]: (Function return) Status Byte, SBYTE
+//ArgV[1]: Left Top (IMG_PT *)
+//ArgV[2]: FontFilename, CStr
+//ArgV[3]: Text, CStr
+//ArgV[4]: Options (ULONG)
+NXT_STATUS cCmdWrapDrawFont(UBYTE * ArgV[])
+{
+ SBYTE * pReturnVal = (SBYTE *)ArgV[0];
+ IMG_PT * pPt = (IMG_PT*)ArgV[1];
+ ULONG Options = *(ULONG *)ArgV[4];
+
+ // count the number of characters
+ gPassedVarsCount = DV_ARRAY[*(DV_INDEX *)(ArgV[3])].Count;
+
+ //Resolve array arguments
+ ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2]));
+ ArgV[3] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[3]));
+
+ if (strlen((PSZ)ArgV[2]) == 0) {
+ // if font filename is empty then use draw text instead
+ cCmdDrawTextHelper(Options, ArgV[3], pPt);
+ // Set return value
+ *pReturnVal = NO_ERR;
+ return NO_ERR;
+ }
+ else
+ {
+ // count the variables
+ gPassedVarsCount = MIN(strlen((PSZ)ArgV[3]), 256);
+ // copy data from input string into SLONG* array
+ SLONG Vars[256];
+ for(int i=0; i<256;i++) {
+ if (i < gPassedVarsCount)
+ Vars[i] = ArgV[3][i];
+ else
+ Vars[i] = 0;
+ }
+ cCmdDrawPictureFromFile((UBYTE *)ArgV[2], pPt, (SLONG*)Vars, Options, pReturnVal);
+ return (NO_ERR);
+ }
+}
+
+//-----------------------------------------------------------------
+// cCmdDrawLine - draw a line. Line is clipped to screen boundaries.
void cCmdDrawLine(
SLONG x1,
SLONG y1,
SLONG x2,
- SLONG y2)
-{
- SLONG d,x,y,ax,ay,sx,sy,dx,dy;
-
- // Initialize variables
- dx = x2-x1; ax = ABS(dx)<<1; sx = SGN(dx);
- dy = y2-y1; ay = ABS(dy)<<1; sy = SGN(dy);
- x = x1;
- y = y1;
- if (ax>ay)
- { /* x dominant */
- d = ay-(ax>>1);
- for (;;)
+ SLONG y2,
+ UBYTE PixelMode) //JJR
+{
+ SLONG tx, ty; //JJR
+ SLONG dx, dy; //JJR
+
+ dx = x2-x1; //JJR
+ dy = y2-y1; //JJR
+
+ //Clip line ends vertically - easier if y1<y2:
+ if (y1 > y2) {tx=x1; x1=x2; x2=tx;
+ ty=y1; y1=y2; y2=ty;}
+
+ //Is line completely off screen?
+ if (y2<0 || y1>=DISPLAY_HEIGHT) return;
+
+ //Trim y1 end:
+ if (y1 < 0)
+ {
+ if (dx && dy)
+ x1 = x1 + (((0-y1)*dx)/dy);
+ y1 = 0;
+ }
+ //Trim y2 end:
+ if (y2 > DISPLAY_HEIGHT-1)
+ {
+ if (dx && dy)
+ x2 = x2 - (((y2-(DISPLAY_HEIGHT-1))*dx)/dy);
+ y2 = DISPLAY_HEIGHT-1;
+ }
+
+ //Clip horizontally - easier if x1<x2
+ if (x1 > x2) {tx=x1; x1=x2; x2=tx;
+ ty=y1; y1=y2; y2=ty;}
+
+ //Is line completely off screen?
+ if (x2<0 || x1>=DISPLAY_WIDTH) return;
+
+ //Trim x1 end:
+ if (x1 < 0)
{
- cCmdSetPixel(x, y, TRUE);
- if (x==x2)
- return;
- if (d>=0)
- {
- y += sy;
- d -= ax;
- }
- x += sx;
- d += ay;
+ if (dx && dy)
+ y1 = y1 + (((0-x1)*dy)/dx);
+ x1 = 0;
}
- }
- else
- { /* y dominant */
- d = ax-(ay>>1);
- for (;;)
+ //Trim x2 end:
+ if (x2 > DISPLAY_WIDTH-1)
{
- cCmdSetPixel(x, y, TRUE);
- if (y==y2)
- return;
- if (d>=0)
+ if (dx && dy)
+ y2 = y2 - (((x2-(DISPLAY_WIDTH-1))*dy)/dx);
+ x2 = DISPLAY_WIDTH-1;
+ }
+
+ if (x1 == x2) {
+ // vertical line or a single point
+ if (y1 == y2)
+ //cCmdSetPixel(x1, y1, Set); //JJR
+ pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)PixelMode, (UBYTE)x1, (UBYTE)TRANSLATE_Y(y1), 0, 0); //JJR
+ else
+ {
+ //pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE, Set, x1, TRANSLATE_Y(y1), 0, TRANSLATE_Y(y2)); //JJR
+ pMapDisplay->pFunc(DISPLAY_VERTICAL_LINE, PixelMode, x1, TRANSLATE_Y(y1), 0, TRANSLATE_Y(y2)); //JJR
+ }
+ }
+ else if (y1 == y2) {
+
+ // horizontal line (single point already dealt with)
+ pMapDisplay->pFunc(DISPLAY_HORIZONTAL_LINE, PixelMode, x1, TRANSLATE_Y(y1), x2, 0); //JJR
+ }
+ else {
+ SLONG d,x,y,ax,ay,sx,sy,dx,dy;
+ // Initialize variables
+ dx = x2-x1; ax = ABS(dx)<<1; sx = SGN(dx);
+ dy = y2-y1; ay = ABS(dy)<<1; sy = SGN(dy);
+ x = x1;
+ y = y1;
+ if (ax>ay)
+ { // x dominant
+ d = ay-(ax>>1);
+ for (;;)
{
+ //cCmdSetPixel(x, y, Set); //JJR
+ pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)PixelMode, (UBYTE)x, (UBYTE)TRANSLATE_Y(y), 0, 0); //JJR
+ if (x==x2)
+ return;
+ if (d>=0)
+ {
+ y += sy;
+ d -= ax;
+ }
x += sx;
- d -= ay;
+ d += ay;
+ }
+ }
+ else
+ { // y dominant
+ d = ax-(ay>>1);
+ for (;;)
+ {
+ //cCmdSetPixel(x, y, Set); //JJR
+ pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)PixelMode, (UBYTE)x, (UBYTE)TRANSLATE_Y(y), 0, 0); //JJR
+ if (y==y2)
+ return;
+ if (d>=0)
+ {
+ x += sx;
+ d -= ay;
+ }
+ y += sy;
+ d += ax;
}
- y += sy;
- d += ax;
}
}
}
//-----------------------------------------------------------------
-// cCmdDrawRect - draw a rectangle. All clipping is done by the set pixel function.
+// cCmdDrawRect - draw a rectangle.
void cCmdDrawRect(
SLONG left,
SLONG bottom,
SLONG width,
- SLONG height)
+ SLONG height,
+ UBYTE PixelMode, //JJR
+ UBYTE FillMode) //JJR
+{
+ SLONG x1, y1;
+ SLONG x2, y2;
+ SLONG t;
+
+ x1 = left;
+ x2 = left + width;
+/*
+ if (width > 0)
+ x2 = left + width - 1;
+ else if (width < 0)
+ x2 = left + width + 1;
+ else
+ x2 = x1;
+*/
+ y1 = bottom;
+ y2 = bottom + height;
+/*
+ if (height > 0)
+ y2 = bottom + height - 1;
+ else if (height < 0)
+ y2 = bottom + height + 1;
+ else
+ y2 = y1;
+*/
+
+ if (x1>x2) {t = x1; x1 = x2; x2 = t;}
+ if (y1>y2) {t = y1; y1 = y2; y2 = t;}
+
+ if (y2 == y1 || x2 == x1) {
+ // height == 0 so draw a single pixel horizontal line OR
+ // width == 0 so draw a single pixel vertical line
+ cCmdDrawLine(x1, y1, x2, y2, PixelMode);
+ return;
+ }
+ // rectangle has abs(width) or abs(height) >= 1
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ if (x2<0 || y2<0 || x1>DISPLAY_WIDTH-1 || y1>DISPLAY_HEIGHT-1) return;
+ if (x1<0) x1=0;
+ if (y1<0) y1=0;
+ if (x2>DISPLAY_WIDTH-1) x2=DISPLAY_WIDTH-1;
+ if (y2>DISPLAY_HEIGHT-1) y2=DISPLAY_HEIGHT-1;
+ pMapDisplay->pFunc(DISPLAY_FILL_REGION, PixelMode, x1, TRANSLATE_Y(y2), x2-x1+1, y2-y1+1);
+ }
+ else
+ {
+ //Use the full line drawing functions rather than horizontal/vertical
+ //functions so these get clipped properly. These will fall straight
+ //through to the faster functions anyway.
+ //Also don't re-draw parts of slim rectangles since XOR might be on.
+
+ cCmdDrawLine(x1, y1, x2, y1, PixelMode);
+ if (y2>y1)
+ {
+ cCmdDrawLine(x1, y2, x2, y2, PixelMode);
+ if (y2 > y1+1)
+ {
+ cCmdDrawLine(x2, y1+1, x2, y2-1, PixelMode);
+ if (x2>x1)
+ cCmdDrawLine(x1, y1+1, x1, y2-1, PixelMode);
+ }
+ }
+ }
+
+}
+
+void cCmdDrawPolygon(IMG_PT* points, UWORD polyCorners, UBYTE PixelMode, UBYTE FillMode, UBYTE bLine)
{
- SLONG right = left + width;
- SLONG top = bottom + height;
+ // the fill mode overrides the polyline vs polygon setting
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ int nodes;
+ int nodeX[MAX_CORNERS];
+ int pixelY;
+ int i, j;
+ int swap;
+ int IMAGE_TOP = -1;
+ int IMAGE_BOTTOM = 1024;
+ int IMAGE_RIGHT = -1;
+ int IMAGE_LEFT = 1024;
+ // calculate maximum and minimum X and Y coordinate values
+ for(i=0;i<polyCorners;i++) {
+ int tmpY = points[i].Y;
+ int tmpX = points[i].X;
+ if (tmpY>IMAGE_TOP) IMAGE_TOP = tmpY;
+ if (tmpY<IMAGE_BOTTOM) IMAGE_BOTTOM = tmpY;
+ if (tmpX>IMAGE_RIGHT) IMAGE_RIGHT = tmpX;
+ if (tmpX<IMAGE_LEFT) IMAGE_LEFT = tmpX;
+ }
+
+ // Loop through the rows of the image.
+ for (pixelY=IMAGE_BOTTOM; pixelY<IMAGE_TOP; pixelY++) {
+ // Build a list of nodes.
+ nodes=0; j=polyCorners-1;
+ for (i=0; i<polyCorners; i++) {
+ IMG_PT pI, pJ;
+ pI = points[i];
+ pJ = points[j];
+ if ((pI.Y<pixelY && pJ.Y>=pixelY) ||
+ (pJ.Y<pixelY && pI.Y>=pixelY)) {
+ nodeX[nodes++]=(pI.X+(pixelY-pI.Y)*(pJ.X-pI.X)/(pJ.Y-pI.Y));
+ }
+ j=i;
+ }
+
+ // Sort the nodes, via a simple “Bubble” sort.
+ i=0;
+ while (i<nodes-1) {
+ if (nodeX[i]>nodeX[i+1]) {
+ swap=nodeX[i];
+ nodeX[i]=nodeX[i+1];
+ nodeX[i+1]=swap;
+ if (i) i--;
+ }
+ else
+ i++;
+ }
- // Draw the four line segments
- cCmdDrawLine(left, top, right, top);
- cCmdDrawLine(right, top, right, bottom);
- cCmdDrawLine(right, bottom, left, bottom);
- cCmdDrawLine(left, bottom, left, top);
+ // Fill the pixels between node pairs.
+ for (i=0; i<nodes; i+=2) {
+ if (nodeX[i ]>=IMAGE_RIGHT) break;
+ if (nodeX[i+1]> IMAGE_LEFT) {
+ if (nodeX[i ]< IMAGE_LEFT) nodeX[i ]=IMAGE_LEFT;
+ if (nodeX[i+1]> IMAGE_RIGHT) nodeX[i+1]=IMAGE_RIGHT;
+ cCmdDrawLine(nodeX[i], pixelY, nodeX[i+1], pixelY, PixelMode);
+ }
+ }
+ }
+ }
+ else
+ {
+// for(int i = 0, j = polyCorners-1; i<polyCorners; j=i++) {
+ IMG_PT pI, pJ;
+ int i = 1, j = 0;
+ while (i < polyCorners) {
+ pI = points[i];
+ pJ = points[j];
+ cCmdDrawLine(pI.X, pI.Y, pJ.X, pJ.Y, PixelMode);
+ j=i++;
+ }
+ if (!bLine) {
+ i = 0;
+ pI = points[i];
+ pJ = points[j];
+ cCmdDrawLine(pI.X, pI.Y, pJ.X, pJ.Y, PixelMode);
+ }
+ }
}
+//-----------------------------------------------------------------
+// cCmdDrawEllipse - draw an ellipse. All clipping is done by the set pixel function.
+void cCmdDrawEllipse(SWORD xc, SWORD yc, SWORD a, SWORD b, UBYTE PixelMode, UBYTE FillMode) //JCH
+{ /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
+ SWORD x = 0, y = b;
+ SWORD rx = x, ry = y;
+ UWORD width = 1;
+ UWORD height = 1;
+ SLONG a2 = (SLONG)a*a;
+ SLONG b2 = (SLONG)b*b;
+ SLONG crit1 = -(a2/4 + a%2 + b2);
+ SLONG crit2 = -(b2/4 + b%2 + a2);
+ SLONG crit3 = -(b2/4 + b%2);
+ SLONG t = -a2*y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */
+ SLONG dxt = 2*b2*x, dyt = -2*a2*y;
+ SLONG d2xt = 2*b2, d2yt = 2*a2;
+
+ if (b == 0) {
+ cCmdDrawRect(xc-a, yc, 2*a, 0, PixelMode, FillMode);
+ return;
+ }
+ if (a == 0) {
+ cCmdDrawRect(xc, yc-b, 0, 2*b, PixelMode, FillMode);
+ return;
+ }
+
+ while (y>=0 && x<=a)
+ {
+ if (FillMode != DRAW_SHAPE_FILLED)
+ {
+ cCmdSetPixel(xc+x, yc+y, PixelMode);
+ if (x!=0 || y!=0)
+ cCmdSetPixel(xc-x, yc-y, PixelMode);
+ if (x!=0 && y!=0)
+ {
+ cCmdSetPixel(xc+x, yc-y, PixelMode);
+ cCmdSetPixel(xc-x, yc+y, PixelMode);
+ }
+ }
+ if (t + b2*x <= crit1 || /* e(x+1,y-1/2) <= 0 */
+ t + a2*y <= crit3) /* e(x+1/2,y) <= 0 */
+ {
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ if (height == 1)
+ ; /* draw nothing */
+ else if (ry*2+1 > (height-1)*2)
+ {
+ cCmdDrawRect(xc-rx, yc-ry, width-1, height-1, PixelMode, FillMode);
+ cCmdDrawRect(xc-rx, yc+ry, width-1, -(height-1), PixelMode, FillMode);
+ ry -= height-1;
+ height = 1;
+ }
+ else
+ {
+ cCmdDrawRect(xc-rx, yc-ry, width-1, ry*2, PixelMode, FillMode);
+ ry -= ry;
+ height = 1;
+ }
+ rx++;
+ width += 2;
+ }
+ x++;
+ dxt += d2xt;
+ t += dxt;
+ }
+ else if (t - a2*y > crit2) /* e(x+1/2,y-1) > 0 */
+ {
+ y--;
+ dyt += d2yt;
+ t += dyt;
+ if (FillMode == DRAW_SHAPE_FILLED)
+ height++;
+ }
+ else
+ {
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ if (ry*2+1 > height*2)
+ {
+ cCmdDrawRect(xc-rx, yc-ry, width-1, height-1, PixelMode, FillMode);
+ cCmdDrawRect(xc-rx, yc+ry, width-1, -(height-1), PixelMode, FillMode);
+ }
+ else
+ {
+ cCmdDrawRect(xc-rx, yc-ry, width-1, ry*2, PixelMode, FillMode);
+ }
+ width += 2;
+ ry -= height;
+ height = 1;
+ rx++;
+ }
+ x++;
+ dxt += d2xt;
+ t += dxt;
+ y--;
+ dyt += d2yt;
+ t += dyt;
+ }
+ }
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ if (ry > height) {
+ cCmdDrawRect(xc-rx, yc-ry, width-1, height-1, PixelMode, FillMode);
+ cCmdDrawRect(xc-rx, yc+ry, width-1, -(height-1), PixelMode, FillMode);
+ }
+ else {
+ cCmdDrawRect(xc-rx, yc-ry, width-1, ry*2, PixelMode, FillMode);
+ }
+ }
+}
+
+//-----------------------------------------------------------------
+// cCmdDrawCircle - draw a circle. All clipping is done by the set pixel function.
+//void cCmdDrawCircle(SLONG cx, SLONG cy, SLONG radius, UBYTE Set) //JJR
+void cCmdDrawCircle(SLONG cx, SLONG cy, SLONG radius, UBYTE PixelMode, UBYTE FillMode) //JJR
+{
+ cCmdDrawEllipse(cx, cy, radius, radius, PixelMode, FillMode);
+}
+/*
+//-----------------------------------------------------------------
+// cCmdDrawCircle - draw a circle. All clipping is done by the set pixel function.
+//void cCmdDrawCircle(SLONG cx, SLONG cy, SLONG radius, UBYTE Set) //JJR
+void cCmdDrawCircle(SLONG cx, SLONG cy, SLONG radius, UBYTE PixelMode, UBYTE FillMode) //JJR
+{
+ SLONG f, ddF_x, ddF_y, x, y;
+ SLONG ox, oy; //JJR
+
+ f = 1 - radius;
+ ddF_x = 0;
+ ddF_y = -2 * radius;
+ x = 0;
+ y = abs(radius); //JJR
+
+//JJR
+ if (y==0)
+ {
+ cCmdSetPixel(cx, cy + radius, PixelMode);
+ return;
+ }
+
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ cCmdDrawLine(cx-radius, cy, cx+radius, cy, PixelMode);
+ }
+ else
+ {
+ cCmdSetPixel(cx + radius, cy, PixelMode);
+ cCmdSetPixel(cx - radius, cy, PixelMode);
+ }
+
+ if (FillMode != DRAW_SHAPE_FILLED || y==1)
+ {
+ cCmdSetPixel(cx, cy + radius, PixelMode);
+ cCmdSetPixel(cx, cy - radius, PixelMode);
+ }
+
+ if (y==1) return;
+
+
+ while (x < y)
+ {
+ ox = x; //JJR
+ oy = y; //JJR
+ if(f >= 0)
+ {
+ y--;
+ ddF_y += 2;
+ f += ddF_y;
+ }
+ x++;
+ ddF_x += 2;
+ f += ddF_x + 1;
+
+//JJR
+ //Need to avoid duplicating pixels if drawing with XOR:
+
+ if (FillMode == DRAW_SHAPE_FILLED)
+ {
+ //Fill by drawing successive horizontal lines above and below
+ //a horizontal centre line.
+ if (x <= y)
+ {
+ cCmdDrawLine(cx-y, cy+x, cx+y, cy+x, PixelMode);
+ cCmdDrawLine(cx-y, cy-x, cx+y, cy-x, PixelMode);
+ }
+ //Only draw horizontal lines from the top and bottom if:
+ //i. The line doesn't overlap with the one just drawn, and the top
+ // curve has just stepped down a pixel or:
+ //ii. A line wasn't just drawn and the loop is about to exit.
+ if ((x<oy && y!=oy) || (x>y && ox<oy))
+ {
+ cCmdDrawLine(cx-ox, cy+oy, cx+ox, cy+oy, PixelMode);
+ cCmdDrawLine(cx-ox, cy-oy, cx+ox, cy-oy, PixelMode);
+ }
+ }
+ else
+ {
+ if (x <= y)
+ {
+ cCmdSetPixel(cx + x, cy + y, PixelMode);
+ cCmdSetPixel(cx - x, cy + y, PixelMode);
+ cCmdSetPixel(cx + x, cy - y, PixelMode);
+ cCmdSetPixel(cx - x, cy - y, PixelMode);
+ }
+ if (x < y)
+ {
+ cCmdSetPixel(cx + y, cy + x, PixelMode);
+ cCmdSetPixel(cx - y, cy + x, PixelMode);
+ cCmdSetPixel(cx + y, cy - x, PixelMode);
+ cCmdSetPixel(cx - y, cy - x, PixelMode);
+ }
+ }
+ }
+}
+*/
#ifndef DISPLAY_REALWIDTH
#define DISPLAY_REALWIDTH DISPLAY_WIDTH
@@ -687,20 +1403,21 @@ void cCmdCopyBitMapBits(
SLONG src_y, // starting pixel y coordinate from source map
SLONG src_width, // width in pixels to the right (negative implies to the left)
SLONG src_height, // height in pixels down (negative implies down)
- IMG_OP_SPRITE * pSprite)
+ IMG_OP_SPRITE * pSprite, UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode)
{
SLONG dy; // Location in the destination pixmap , the screen that is
SLONG sx;
SLONG sy; // Location in the source pixmap.
SLONG trim, last_x, last_y, rowbytes;
UBYTE *pSrcByte;
+ UBYTE srcByte; //JJR
UBYTE *pDstBytes;
UBYTE *pDstByte, *pFirstDstByte;
UBYTE *pLastDstByte;
- UBYTE bit_y, not_bit_y;
+ UBYTE bit_y; //JJR
UBYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
- // Data in the image file is row major 8 pixels per byte.top row first.
+ // Data in the image file is row major 8 pixels per byte. top row first.
// src and dst coordinates treat the bottom left most pixel as (0,0)
if (!pSprite || pSprite->OpCode!=IMG_SPRITE_ID)
@@ -750,17 +1467,56 @@ void cCmdCopyBitMapBits(
for (dy = dst_y; dy > last_y; dy--)
{
sx = src_x;
- bit_y = masks[7 - (dy & 0x07)];
- not_bit_y = ~ bit_y;
+ bit_y = masks[7 - (dy & 0x07)];
+ // not_bit_y = ~ bit_y; //JJR
pDstByte = pFirstDstByte;
pLastDstByte = pDstByte + (last_x - dst_x);
for (; pDstByte < pLastDstByte; pDstByte++)
{
- if ( *(pSrcByte + (sx >> 3)) & masks[sx & 0x07] ){
- *pDstByte |= bit_y;
- } else {
- *pDstByte &= not_bit_y;
+ //Read source byte:
+ //If fill mode is on, pretend the source bitmap is solid:
+ if (FillMode==DRAW_SHAPE_FILLED)
+ srcByte = 0xff;
+ else
+ srcByte = *(pSrcByte + (sx >> 3)); //JJR
+
+ //If invert mode is on, invert the source byte:
+ if (InvertMode==DRAW_BITMAP_INVERT) srcByte = ~srcByte; //JJR
+
+ //Test the pixel in the source byte:
+ if ( srcByte & masks[sx & 0x07] ) //JJR
+ {
+ //If pixel is set in source image:
+ switch (LogicalMode)
+ {
+ case DRAW_LOGICAL_AND:
+ break;
+ case DRAW_LOGICAL_XOR:
+ *pDstByte ^= bit_y;
+ break;
+ case DRAW_LOGICAL_OR:
+ case DRAW_LOGICAL_COPY:
+ default:
+ *pDstByte |= bit_y;
+ break;
+ }
}
+ else
+ {
+ //If pixel is clear in source image:
+ switch (LogicalMode)
+ {
+ case DRAW_LOGICAL_OR:
+ case DRAW_LOGICAL_XOR:
+ break;
+ case DRAW_LOGICAL_AND:
+ case DRAW_LOGICAL_COPY:
+ default:
+ *pDstByte &= ~bit_y;
+ break;
+ }
+ }
+//JJR
sx ++;
}
pSrcByte -= rowbytes;
@@ -772,12 +1528,13 @@ void cCmdCopyBitMapBits(
}
//-----------------------------------------------------------------
-// cCmdSetPixel - Set or clear a pixel based on Val
-void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val)
+// cCmdSetPixel - Set, clear or invert a pixel based on PixelMode
+void cCmdSetPixel(SLONG X, SLONG Y, ULONG PixelMode)
{
Y = TRANSLATE_Y(Y);
- pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)Val, (UBYTE)X, (UBYTE)Y, 0, 0);
+ if (X>=0 && X<DISPLAY_WIDTH && Y>=0 && Y<DISPLAY_HEIGHT)
+ pMapDisplay->pFunc(DISPLAY_PIXEL, (UBYTE)PixelMode, (UBYTE)X, (UBYTE)Y, 0, 0);
}
@@ -791,27 +1548,68 @@ NXT_STATUS cCmdWrapSetScreenMode(UBYTE * ArgV[])
if (ScreenMode == RESTORE_NXT_SCREEN) {
cCmdRestoreDefaultScreen();
}
+ else if (ScreenMode == CLEAR_NXT_SCREEN) {
+ pMapDisplay->pFunc(DISPLAY_ERASE_ALL, 0, 0, 0, 0, 0);
+ }
// Set return value
*(SBYTE*)(ArgV[0]) = NO_ERR;
return NO_ERR;
}
-//------------------------------------------------------------------
-// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required.
-void cCmdClearScreenIfNeeded(ULONG DrawOptions)
+void cDirtyDisplay(ULONG* DrawOptions)
{
- //If we are the first drawing command, clear the screen and record that we've done so
+ //If we are the first drawing command mark the display as dirty
if (VarsCmd.DirtyDisplay == FALSE)
{
VarsCmd.DirtyDisplay = TRUE;
pMapUi->Flags &= ~UI_ENABLE_STATUS_UPDATE;
-
- //Override DrawOptions because we have to clear anyway
- DrawOptions = DRAW_OPT_CLEAR_WHOLE_SCREEN;
+
+ if (DrawOptions) {
+ //Override DrawOptions because we have to clear anyway
+ *DrawOptions = DRAW_OPT_CLEAR_WHOLE_SCREEN;
+ }
}
+}
+
+//
+//cCmdWrapDisplayExecuteFunction
+//ArgV[0]: (return) Status byte, SBYTE
+//ArgV[1]: UBYTE Cmd
+//ArgV[2]: UBYTE On
+//ArgV[3]: UBYTE X1
+//ArgV[4]: UBYTE Y1
+//ArgV[5]: UBYTE X2
+//ArgV[6]: UBYTE Y2
+//
+NXT_STATUS cCmdWrapDisplayExecuteFunction(UBYTE * ArgV[])
+{
+ cDirtyDisplay(NULL);
+ UBYTE Cmd = *(UBYTE*)(ArgV[1]);
+ UBYTE Y1 = *(UBYTE*)(ArgV[4]);
+ UBYTE Y2 = *(UBYTE*)(ArgV[6]);
+ if (Cmd != DISPLAY_CHAR)
+ Y1 = TRANSLATE_Y(Y1);
+ if (Cmd == DISPLAY_VERTICAL_LINE)
+ Y2 = TRANSLATE_Y(Y2);
+ pMapDisplay->pFunc(Cmd,
+ *(UBYTE*)(ArgV[2]),
+ *(UBYTE*)(ArgV[3]),
+ Y1,
+ *(UBYTE*)(ArgV[5]),
+ Y2);
+ *(SBYTE*)(ArgV[0]) = NO_ERR;
+ return (NO_ERR);
+}
+
+
+//------------------------------------------------------------------
+// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required.
+void cCmdClearScreenIfNeeded(ULONG DrawOptions)
+{
+ cDirtyDisplay(&DrawOptions);
- if (DRAW_OPT_CLEAR_MODE(DrawOptions))
+ if (cCmdResolveClearScreenMode(DrawOptions))
{
pMapDisplay->pFunc(DISPLAY_ERASE_ALL, 0, 0, 0, 0, 0);
@@ -827,10 +1625,12 @@ void cCmdClearScreenIfNeeded(ULONG DrawOptions)
// Properly uses 'Normal' display buffer to avoid conflicts with popup buffer
// Clips text at bottom and right hand edges of the screen buffer
//!!! Function copied and modified from cDisplayString
-void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y)
+//void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y) //JJR
+void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y, UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode) //JJR
{
UBYTE *pSource;
UBYTE *pDestination;
+ UBYTE a;
FONT *pFont;
ULONG FontWidth;
ULONG Items;
@@ -858,7 +1658,7 @@ void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y)
//Calculate X coordinate of the right edge of this character.
//If it will extend past the right edge, clip the string.
X += FontWidth;
- if (X >= DISPLAY_WIDTH)
+ if (X > DISPLAY_WIDTH) // JCH: was >= This clipped text that ended at pixel 99
break;
//If Item is defined by the font, display it. Else, ignore it.
@@ -868,7 +1668,37 @@ void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y)
pSource = (UBYTE*)&(pFont->Data[Item * FontWidth]);
while (FontWidth--)
{
- *pDestination = *pSource;
+//JJR
+// *pDestination = *pSource;
+
+ //Fetch a byte from the source bitmap:
+ //If fill mode is on, pretend the source bitmap is solid:
+ if (FillMode==DRAW_SHAPE_FILLED)
+ a = 0xff;
+ else
+ a = *pSource;
+
+ //Implement bitmap invert mode:
+ if (InvertMode==DRAW_BITMAP_INVERT) a = ~a;
+
+ //Implement bitmap logical mode when writing on screen:
+ switch (LogicalMode)
+ {
+ case DRAW_LOGICAL_OR:
+ *pDestination |= a;
+ break;
+ case DRAW_LOGICAL_AND:
+ *pDestination &= a;
+ break;
+ case DRAW_LOGICAL_XOR:
+ *pDestination ^= a;
+ break;
+ case DRAW_LOGICAL_COPY:
+ default:
+ *pDestination = a;
+ break;
+ }
+//JJR
pDestination++;
pSource++;
}
@@ -891,4 +1721,338 @@ void cCmdRestoreDefaultScreen(void)
pMapUi->Flags |= UI_ENABLE_STATUS_UPDATE | UI_REDRAW_STATUS;
}
+ // restore default display state
+ pMapDisplay->Display = (UBYTE*)pMapDisplay->Normal;
+ pMapDisplay->Flags = DISPLAY_REFRESH | DISPLAY_ON;
}
+
+//------------------------------------------------------------------
+// cCmdResolveDrawingMode - extract the parameters that affect pixel, line and shape
+// drawing from the 'DrawingOptions' or 'CopyOptions' parameter.
+// Return FALSE for combinations that do nothing.
+
+UBYTE cCmdResolveDrawingMode(UWORD DrawingOptions, UBYTE* pPixelMode, UBYTE* pFillMode)
+{
+ DrawingOptions = cCmdResolveValue(DrawingOptions);
+ // Extract shape fill option:
+ if (DrawingOptions & DRAW_OPT_FILL_SHAPE)
+ *pFillMode = DRAW_SHAPE_FILLED;
+ else
+ *pFillMode = DRAW_SHAPE_HOLLOW;
+
+ // Extract pixel drawing options:
+ if (DrawingOptions & DRAW_OPT_INVERT)
+ {
+ //Drawing with white pixels:
+ switch (DrawingOptions & DRAW_OPT_LOGICAL_OPERATIONS)
+ {
+ //Only these cases do anything:
+ case DRAW_OPT_LOGICAL_COPY:
+ case DRAW_OPT_LOGICAL_AND:
+ *pPixelMode = DRAW_PIXELS_CLEAR;
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ //Drawing with black pixels:
+ switch (DrawingOptions & DRAW_OPT_LOGICAL_OPERATIONS)
+ {
+ //Only these cases do anything:
+ case DRAW_OPT_LOGICAL_COPY:
+ case DRAW_OPT_LOGICAL_OR:
+ *pPixelMode = DRAW_PIXELS_SET;
+ return TRUE;
+ case DRAW_OPT_LOGICAL_XOR:
+ *pPixelMode = DRAW_PIXELS_INVERT;
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ // If no operation is required, set defaults and return FALSE.
+ // e.g. 'AND' on its own is meaningless for line drawing,
+ // 'INVERT + OR' and 'INVERT + XOR' do nothing either.
+
+ *pPixelMode = DRAW_PIXELS_SET;
+ *pFillMode = DRAW_SHAPE_HOLLOW;
+ return FALSE;
+}
+
+//------------------------------------------------------------------
+// cCmdResolveBitmapMode - extract the parameters that affect bitmap and text
+// drawing from the 'DrawingOptions' or 'CopyOptions' parameter.
+void cCmdResolveBitmapMode(UWORD DrawingOptions, UBYTE* pInvertMode, UBYTE* pLogicalMode, UBYTE* pFillMode)
+{
+ DrawingOptions = cCmdResolveValue(DrawingOptions);
+ //Extract bitmap inversion mode:
+ if (DrawingOptions & DRAW_OPT_INVERT)
+ *pInvertMode = DRAW_BITMAP_INVERT;
+ else
+ *pInvertMode = DRAW_BITMAP_PLAIN;
+
+ //Extract bitmap logical operation:
+ switch (DrawingOptions & DRAW_OPT_LOGICAL_OPERATIONS)
+ {
+ case DRAW_OPT_LOGICAL_OR:
+ *pLogicalMode = DRAW_LOGICAL_OR;
+ break;
+ case DRAW_OPT_LOGICAL_AND:
+ *pLogicalMode = DRAW_LOGICAL_AND;
+ break;
+ case DRAW_OPT_LOGICAL_XOR:
+ *pLogicalMode = DRAW_LOGICAL_XOR;
+ break;
+ case DRAW_OPT_LOGICAL_COPY:
+ default:
+ *pLogicalMode = DRAW_LOGICAL_COPY;
+ break;
+ }
+
+ // Extract shape fill option (overrides source bitmap with all pixels set):
+ if (DrawingOptions & DRAW_OPT_FILL_SHAPE)
+ *pFillMode = DRAW_SHAPE_FILLED;
+ else
+ *pFillMode = DRAW_SHAPE_HOLLOW;
+
+}
+
+//------------------------------------------------------------------
+// cCmdResolveFontOptions - extract the parameters that affect custom RIC font drawing
+// drawing from the 'DrawingOptions' parameter.
+void cCmdResolveFontOptions(UWORD DrawingOptions, UBYTE* pFontDir, UBYTE* pFontWrap)
+{
+ //Extract bitmap inversion mode:
+ if (DrawingOptions & DRAW_OPT_FONT_WRAP)
+ *pFontWrap = DRAW_FONT_WRAP_ON;
+ else
+ *pFontWrap = DRAW_FONT_WRAP_OFF;
+
+ //Extract bitmap logical operation:
+ switch (DrawingOptions & DRAW_OPT_FONT_DIRECTIONS)
+ {
+ case DRAW_OPT_FONT_DIR_L2RB:
+ *pFontDir = DRAW_FONT_DIR_L2RB;
+ break;
+ case DRAW_OPT_FONT_DIR_L2RT:
+ *pFontDir = DRAW_FONT_DIR_L2RT;
+ break;
+ case DRAW_OPT_FONT_DIR_R2LB:
+ *pFontDir = DRAW_FONT_DIR_R2LB;
+ break;
+ case DRAW_OPT_FONT_DIR_R2LT:
+ *pFontDir = DRAW_FONT_DIR_R2LT;
+ break;
+ case DRAW_OPT_FONT_DIR_B2TL:
+ *pFontDir = DRAW_FONT_DIR_B2TL;
+ break;
+ case DRAW_OPT_FONT_DIR_B2TR:
+ *pFontDir = DRAW_FONT_DIR_B2TR;
+ break;
+ case DRAW_OPT_FONT_DIR_T2BL:
+ *pFontDir = DRAW_FONT_DIR_T2BL;
+ break;
+ case DRAW_OPT_FONT_DIR_T2BR:
+ *pFontDir = DRAW_FONT_DIR_T2BR;
+ break;
+ default:
+ *pFontDir = DRAW_FONT_DIR_L2RB;
+ break;
+ }
+}
+
+//------------------------------------------------------------------
+// cCmdResolveClearScreenMode - extract the parameters that affect screen clearing
+// from the 'DrawingOptions' parameter.
+UBYTE cCmdResolveClearScreenMode(UWORD DrawingOptions)
+{
+ if (DrawingOptions & DRAW_OPT_CLEAR_SCREEN_MODES)
+ return TRUE;
+ else
+ return FALSE;
+}
+//JJR
+
+void cCmdDrawFont(IMG_OP_SPRITE *pSprite, SLONG sW, SLONG sH, SLONG startx, SLONG starty,
+ UBYTE fontDir, UBYTE fontWrap, UBYTE invertMode, UBYTE logicalMode, UBYTE fillMode)
+{
+ SWORD index; // index on id for output
+ SWORD xpos; // x-position for next output
+ SWORD ypos; // y-position for next output
+ SLONG sourcex; // X-Pos of pattern inside bitmap
+ SLONG sourcey; // Y-Pos of pattern inside bitmap
+ SLONG sourcew; // Width of pattern inside bitmap
+ SLONG sourceh; // Height of pattern inside bitmap
+ int destx; // X-Destination position on screen
+ int desty; // Y-Destination position on screen
+ SWORD stdw; // Standard font width
+ SWORD stdh; // Standard font height
+
+ if (!gpPassedImgVars) // exit early if we do not have parameters
+ return;
+
+ stdw = MIN( sW, DISPLAY_WIDTH ); // calculate the standard width
+ stdh = MIN( sH, DISPLAY_HEIGHT ); // calculate the standard height
+
+ index=0; // Reset the start position
+ xpos=startx; // Initial start position X
+ ypos=starty; // Initial start position Y
+
+ while( index < gPassedVarsCount )
+ {
+ // terminate the loop at our first null
+ if (gpPassedImgVars[index] == 0)
+ break;
+ sourcex=cCmdResolveValue(0xF200|index); // Get dynamic xpos of pattern
+ sourcey=cCmdResolveValue(0xF300|index); // Get dynamic ypos of pattern
+ sourcew=cCmdResolveValue(0xF400|index); // Get dynamic width of pattern
+ sourceh=cCmdResolveValue(0xF500|index); // Get dynamic height of pattern
+
+ //--Calculate the rectangle for source (inside the sprite) and destination
+ //--on the screen (related to the fontdirection) for performing the
+ //--BitCopy function
+
+ switch( fontDir )
+ {
+ case DRAW_FONT_DIR_L2RB : // Left to right with bottom align----------------
+
+ if( fontWrap )
+ {
+ if( ( xpos + sourcew ) > DISPLAY_WIDTH )
+ {
+ xpos = startx;
+ ypos -= stdh;
+ }
+ }
+
+ destx = xpos;
+ desty = ypos;
+ xpos = xpos + sourcew;
+
+ break;
+
+ case DRAW_FONT_DIR_L2RT : // Left to right with align to top----------------
+
+ if( fontWrap )
+ {
+ if( ( xpos + sourcew ) > DISPLAY_WIDTH )
+ {
+ xpos = startx;
+ ypos += stdh;
+ }
+ }
+
+ destx = xpos;
+ desty = ypos - sourceh + 1;
+ xpos = xpos + sourcew;
+ break;
+
+ case DRAW_FONT_DIR_R2LB : // Right to left with align to bottom-------------
+
+ if( fontWrap )
+ {
+ if( ( xpos - sourcew ) < 0 )
+ {
+ xpos = startx;
+ ypos -= stdh;
+ }
+ }
+
+ destx = xpos - sourcew + 1;
+ desty = ypos;
+ xpos = xpos - sourcew;
+ break;
+
+ case DRAW_FONT_DIR_R2LT : // Right to left with align to top----------------
+
+ if( fontWrap )
+ {
+ if( ( xpos - sourcew ) < 0 )
+ {
+ xpos = startx;
+ ypos += stdh;
+ }
+ }
+
+ destx = xpos - sourcew + 1;
+ desty = ypos - sourceh + 1;
+ xpos = xpos - sourcew;
+ break;
+
+ case DRAW_FONT_DIR_B2TL : // Bottom to top with allign to left--------------
+
+ if( fontWrap )
+ {
+ if( ( ypos + sourceh ) > DISPLAY_HEIGHT )
+ {
+ xpos += stdw;
+ ypos = starty;
+ }
+ }
+
+ destx = xpos;
+ desty = ypos;
+ ypos = ypos + sourceh;
+ break;
+
+ case DRAW_FONT_DIR_B2TR : // Bottom to top with allign to right-------------
+
+ if( fontWrap )
+ {
+ if( ( ypos + sourceh ) > DISPLAY_HEIGHT )
+ {
+ xpos -= stdw;
+ ypos = starty;
+ }
+ }
+
+ destx = xpos - sourcew + 1;
+ desty = ypos;
+ ypos = ypos + sourceh;
+ break;
+
+ case DRAW_FONT_DIR_T2BL : // Top to bottom with allign to right-------------
+
+ if( fontWrap )
+ {
+ if( ( ypos - sourceh ) < 0 )
+ {
+ xpos += stdw;
+ ypos = starty;
+ }
+ }
+
+ destx = xpos;
+ desty = ypos - sourceh + 1;
+ ypos = ypos - sourceh;
+ break;
+
+ case DRAW_FONT_DIR_T2BR : // Top to bottom with allign to right-------------
+
+ if( fontWrap )
+ {
+ if( ( ypos - sourceh ) < 0 )
+ {
+ xpos -= stdw;
+ ypos = starty;
+ }
+ }
+
+ destx = xpos - sourcew + 1;
+ desty = ypos - sourceh + 1;
+ ypos = ypos - sourceh;
+ break;
+ }
+
+ //--Output of the calculated pattern to the screen------------------------
+ cCmdCopyBitMapBits(destx, desty, sourcex, sourcey, sourcew, sourceh,
+ pSprite, invertMode, logicalMode, fillMode);
+
+ // move on to next character
+ index++;
+ }
+}
+
diff --git a/AT91SAM7S256/Source/c_comm.c b/AT91SAM7S256/Source/c_comm.c
index ee0c6ae..c760b84 100644
--- a/AT91SAM7S256/Source/c_comm.c
+++ b/AT91SAM7S256/Source/c_comm.c
@@ -60,13 +60,13 @@ enum
IOMapComm.BtInBuf.InPtr = 0;\
CLEARExtMode;\
dBtClearArm7CmdSignal();\
- dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE);
+ dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE, FALSE);
#define SETBtDataState IOMapComm.BtInBuf.InPtr = 0;\
VarsComm.BtState = BT_ARM_DATA_MODE;\
dBtClearTimeOut(); /* stop cmd timeout because in datamode */\
dBtSetArm7CmdSignal();\
- dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)STREAM_MODE)
+ dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)STREAM_MODE, IOMapComm.BtDataMode != DATA_MODE_NXT);
#define SETBtOff VarsComm.BtState = BT_ARM_OFF;\
dBtSetBcResetPinLow()
@@ -160,10 +160,15 @@ void cCommInit(void* pHeader)
}
IOMapComm.BtDeviceCnt = 0;
IOMapComm.BrickData.BtStateStatus = 0;
-
+ IOMapComm.HsSpeed = HS_BAUD_921600;
+ IOMapComm.HsAddress = HS_ADDRESS_ALL;
+ IOMapComm.HsMode = HS_MODE_8N1;
+ IOMapComm.BtDataMode = DATA_MODE_NXT;
+ IOMapComm.HsDataMode = DATA_MODE_RAW;
+
cCommClrConnTable();
- dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE);
+ dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)CMD_MODE, FALSE);
dBtStartADConverter();
dHiSpeedInit();
@@ -177,7 +182,18 @@ void cCommInit(void* pHeader)
void cCommCtrl(void)
{
-
+ // remove the update flag from the hi-speed data mode field
+ IOMapComm.HsDataMode &= ~DATA_MODE_UPDATE;
+
+ if (IOMapComm.BtDataMode & DATA_MODE_UPDATE)
+ {
+ // remove the update flag from the data mode field
+ IOMapComm.BtDataMode &= ~DATA_MODE_UPDATE;
+ // re-initialize the receiver (only changing the NoLengthBytes param)
+
+ dBtInitReceive(VarsComm.BtModuleInBuf.Buf, (UBYTE)((VarsComm.BtState == BT_ARM_CMD_MODE) ? CMD_MODE : STREAM_MODE), IOMapComm.BtDataMode != DATA_MODE_NXT);
+ }
+
if (FALSE == cCommReceivedBtData())
{
@@ -227,7 +243,9 @@ void cCommCtrl(void)
break;
}
}
- IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0;
+ // don't overwrite this byte when we are in DATA GPS or RAW mode
+ if ((VarsComm.BtState == BT_ARM_CMD_MODE) || (IOMapComm.BtDataMode == DATA_MODE_NXT))
+ IOMapComm.BtInBuf.Buf[BT_CMD_BYTE] = 0;
/* Here comes the the HIGHSPEED_PORT implementation */
@@ -238,7 +256,7 @@ void cCommCtrl(void)
{
case HS_INITIALISE:
{
- dHiSpeedSetupUart();
+ dHiSpeedSetupUart(IOMapComm.HsSpeed, IOMapComm.HsMode);
IOMapComm.HsState = HS_INIT_RECEIVER;
IOMapComm.HsFlags |= HS_UPDATE;
}
@@ -254,6 +272,7 @@ void cCommCtrl(void)
case HS_SEND_DATA:
{
cCommSendHiSpeedData();
+ IOMapComm.HsState = HS_DEFAULT; // do not leave this in HS_SEND_DATA state
}
break;
@@ -263,6 +282,13 @@ void cCommCtrl(void)
dHiSpeedExit();
}
break;
+
+ case HS_ENABLE:
+ {
+ if (VarsComm.HsState == 0)
+ dHiSpeedInit();
+ }
+ break;
}
}
@@ -413,8 +439,11 @@ UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE C
case REPLY_CMD:
{
- /* If this is a reply to a direct command opcode, pRCHandler will handle it */
- if (pInBuf[1] < NUM_RC_OPCODES)
+ // in the enhanced firmware all replies (system or direct) go to the RC Handler function
+ // since it stores the last response in VarsCmd.LastResponseBuffer field
+
+// /* If this is a reply to a direct command opcode, pRCHandler will handle it */
+// if (pInBuf[1] < NUM_RC_OPCODES)
pMapCmd->pRCHandler(&(pInBuf[0]), NULL, pLength);
/* No Reply ever required on REPLY_CMD messages */
@@ -464,6 +493,9 @@ UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE C
break;
case REPLY_CMD:
{
+ // in the enhanced firmware all replies (system or direct) go to the RC Handler function
+ // since it stores the last response in VarsCmd.LastResponseBuffer field
+ pMapCmd->pRCHandler(&(pInBuf[0]), NULL, pLength);
}
break;
default:
@@ -657,13 +689,19 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL
Length = FileLength;
/* Here test for channel - USB can only handle a 64 byte return (- wrapping )*/
- if (CmdBit & USB_CMD_READY)
+ if ((CmdBit & BT_CMD_READY) != BT_CMD_READY)
{
- if (FileLength > (SIZE_OF_USBBUF - 6))
+ // USB or HS
+ UBYTE bufSize;
+ if (CmdBit & USB_CMD_READY)
+ bufSize = SIZE_OF_USBBUF;
+ else
+ bufSize = SIZE_OF_HSBUF;
+ if (FileLength > (bufSize - 6))
{
/* Buffer cannot hold the requested data adjust to buffer size */
- FileLength = (SIZE_OF_USBBUF - 6);
+ FileLength = (bufSize - 6);
}
*pLength = FileLength + 4;
Status = pMapLoader->pFunc(READ, &pInBuf[1], &pOutBuf[4], &FileLength);
@@ -876,13 +914,18 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL
FileLength <<= 8;
FileLength |= pInBuf[7];
- if (CmdBit & USB_CMD_READY)
+ if (!(CmdBit & BT_CMD_READY))
{
+ UBYTE bufSize;
+ if (CmdBit & USB_CMD_READY)
+ bufSize = SIZE_OF_USBBUF;
+ else
+ bufSize = SIZE_OF_HSBUF;
- /* test for USB buffer overrun */
- if (FileLength > (SIZE_OF_USBBUF - 9))
+ /* test for USB or HS buffer overrun */
+ if (FileLength > (bufSize - 9))
{
- FileLength = SIZE_OF_USBBUF - 9;
+ FileLength = bufSize - 9;
}
}
else
@@ -1083,10 +1126,14 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL
{
MaxBufData = (SIZE_OF_USBDATA - 5); /* Substract wrapping */
}
- else
+ else if (CmdBit & BT_CMD_READY)
{
MaxBufData = (SIZE_OF_BTBUF - 7); /* Substract wrapping + length bytes for BT*/
}
+ else // HS_CMD_READY
+ {
+ MaxBufData = (SIZE_OF_HSBUF - 5); /* Substract wrapping */
+ }
if (0x00 == pInBuf[1])
{
@@ -1123,7 +1170,7 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL
for (Tmp = 0; ((Tmp < (*pLength)) && (IOMapComm.HsInBuf.InPtr != IOMapComm.HsInBuf.OutPtr)); Tmp++)
{
pOutBuf[3 + Tmp] = IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.OutPtr];
- IOMapComm.HsInBuf.OutPtr = ((IOMapComm.HsInBuf.OutPtr) + 1) % SIZE_OF_USBBUF;
+ IOMapComm.HsInBuf.OutPtr = ((IOMapComm.HsInBuf.OutPtr) + 1) % SIZE_OF_HSBUF;
}
pOutBuf[2] = Tmp;
@@ -1143,12 +1190,23 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL
(*pLength) += 3; /* Add 3 bytes for the status byte, length byte and Buf no */
}
break;
+
+ case RENAMEFILE:
+ {
+ Status = pMapLoader->pFunc(RENAMEFILE, &pInBuf[1], &pInBuf[21], &FileLength);
+ pOutBuf[0] = LOADER_ERR_BYTE(Status);
+ pOutBuf[1] = LOADER_HANDLE(Status);
+ cCommCopyFileName(&pOutBuf[2], &pInBuf[1]);
+ cCommCopyFileName(&pOutBuf[22], &pInBuf[21]);
+ *pLength = 42;
+ }
+ break;
case BTFACTORYRESET:
{
UWORD RtnVal;
- if (CmdBit & USB_CMD_READY)
+ if ((CmdBit & USB_CMD_READY) || (CmdBit & HS_CMD_READY))
{
if (SUCCESS == cCommReq(FACTORYRESET, 0, 0, 0, NULL, &RtnVal))
{
@@ -1188,7 +1246,7 @@ UWORD cCommReceivedBtData(void)
UWORD BytesToGo;
UWORD RtnVal;
- RtnVal = dBtReceivedData(&NumberOfBytes, &BytesToGo);
+ RtnVal = dBtReceivedData(&NumberOfBytes, &BytesToGo, IOMapComm.BtDataMode != DATA_MODE_NXT);
if (TRUE == RtnVal)
{
@@ -1214,21 +1272,35 @@ UWORD cCommReceivedBtData(void)
/* VarsComm.CmdSwitchCnt != 0 if a transition to Cmd mode is in process */
if ((VarsComm.BtState == BT_ARM_DATA_MODE) && (0 == VarsComm.CmdSwitchCnt))
{
+ if (IOMapComm.BtDataMode == DATA_MODE_NXT)
+ {
- /* Move the inptr ahead */
- IOMapComm.BtInBuf.InPtr = NumberOfBytes;
+ /* Move the inptr ahead */
+ IOMapComm.BtInBuf.InPtr = NumberOfBytes;
- /* using the outbuf inptr in order to get the number of bytes in the return answer at the right place*/
- IOMapComm.BtOutBuf.InPtr = NumberOfBytes;
+ /* using the outbuf inptr in order to get the number of bytes in the return answer at the right place*/
+ IOMapComm.BtOutBuf.InPtr = NumberOfBytes;
- /* call the data stream interpreter */
- cCommInterprete(IOMapComm.BtInBuf.Buf, IOMapComm.BtOutBuf.Buf, &(IOMapComm.BtOutBuf.InPtr), (UBYTE) BT_CMD_READY, BytesToGo);
+ /* call the data stream interpreter */
+ cCommInterprete(IOMapComm.BtInBuf.Buf, IOMapComm.BtOutBuf.Buf, &(IOMapComm.BtOutBuf.InPtr), (UBYTE) BT_CMD_READY, BytesToGo);
/* if there is a reply to be send then send it */
- if (IOMapComm.BtOutBuf.InPtr)
+ if (IOMapComm.BtOutBuf.InPtr)
+ {
+ dBtSendMsg(IOMapComm.BtOutBuf.Buf, IOMapComm.BtOutBuf.InPtr, IOMapComm.BtOutBuf.InPtr);
+ IOMapComm.BtOutBuf.InPtr = 0;
+ }
+ }
+ else if (IOMapComm.BtDataMode == DATA_MODE_GPS)
+ {
+ /* Move the inptr ahead */
+ IOMapComm.BtInBuf.InPtr = NumberOfBytes;
+ // interpret GPS sentence?
+ }
+ else if (IOMapComm.BtDataMode == DATA_MODE_RAW)
{
- dBtSendMsg(IOMapComm.BtOutBuf.Buf, IOMapComm.BtOutBuf.InPtr, IOMapComm.BtOutBuf.InPtr);
- IOMapComm.BtOutBuf.InPtr = 0;
+ /* Move the inptr ahead */
+ IOMapComm.BtInBuf.InPtr = NumberOfBytes;
}
}
}
@@ -1437,23 +1509,64 @@ void cCommReceivedHiSpeedData(void)
{
UWORD NumberOfBytes;
UWORD Tmp;
-
+ UBYTE Address;
+
dHiSpeedReceivedData(&NumberOfBytes);
if (NumberOfBytes != 0)
{
- for (Tmp = 0; Tmp < NumberOfBytes; Tmp++)
+ if (IOMapComm.HsDataMode != DATA_MODE_NXT)
{
- IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.InPtr] = VarsComm.HsModuleInBuf.Buf[Tmp];
- IOMapComm.HsInBuf.InPtr++;
- if (IOMapComm.HsInBuf.InPtr > (SIZE_OF_HSBUF - 1))
+ // this is the normal way to handle incoming hi-speed data
+ for (Tmp = 0; Tmp < NumberOfBytes; Tmp++)
{
- IOMapComm.HsInBuf.InPtr = 0;
+ IOMapComm.HsInBuf.Buf[IOMapComm.HsInBuf.InPtr] = VarsComm.HsModuleInBuf.Buf[Tmp];
+ IOMapComm.HsInBuf.InPtr++;
+ if (IOMapComm.HsInBuf.InPtr > (SIZE_OF_HSBUF - 1))
+ {
+ IOMapComm.HsInBuf.InPtr = 0;
+ }
+ VarsComm.HsModuleInBuf.Buf[Tmp] = 0;
}
- VarsComm.HsModuleInBuf.Buf[Tmp] = 0;
- }
/* Now new data is available from the HIGH SPEED port ! */
+ }
+ else
+ {
+ // receiving hi-speed data in NXT mode
+ if (NumberOfBytes > SIZE_OF_HSBUF)
+ NumberOfBytes = SIZE_OF_HSBUF;
+ Address = VarsComm.HsModuleInBuf.Buf[0];
+ NumberOfBytes--;
+ if ((IOMapComm.HsAddress == Address) ||
+ (HS_ADDRESS_ALL == Address) ||
+ (HS_ADDRESS_ALL == IOMapComm.HsAddress))
+ {
+ /* Copy the bytes into the IOMapBuffer */
+ memcpy((PSZ)IOMapComm.HsInBuf.Buf, (PSZ)(VarsComm.HsModuleInBuf.Buf+1), NumberOfBytes);
+ memset((PSZ)VarsComm.HsModuleInBuf.Buf, 0, 256);
+
+ /* Move the inptr ahead */
+ IOMapComm.HsInBuf.InPtr = NumberOfBytes;
+ IOMapComm.HsInBuf.OutPtr = 0;
+
+ /* using the outbuf inptr in order to get the number of bytes in the return answer at the right place*/
+ IOMapComm.HsOutBuf.InPtr = NumberOfBytes;
+
+ /* call the data stream interpreter */
+ cCommInterprete(IOMapComm.HsInBuf.Buf, (UBYTE *)(IOMapComm.HsOutBuf.Buf+1), &(IOMapComm.HsOutBuf.InPtr), (UBYTE) HS_CMD_READY, NumberOfBytes);
+
+ /* if there is a reply to be sent then send it */
+ if (IOMapComm.HsOutBuf.InPtr)
+ {
+ IOMapComm.HsOutBuf.Buf[0] = HS_ADDRESS_ALL; // reply is sent to "all"
+ IOMapComm.HsOutBuf.InPtr++;
+ cCommSendHiSpeedData();
+ IOMapComm.HsOutBuf.InPtr = 0;
+ IOMapComm.HsOutBuf.OutPtr = 0;
+ }
+ }
+ }
}
}
diff --git a/AT91SAM7S256/Source/c_comm.iom b/AT91SAM7S256/Source/c_comm.iom
index 2dfe994..7f11837 100644
--- a/AT91SAM7S256/Source/c_comm.iom
+++ b/AT91SAM7S256/Source/c_comm.iom
@@ -40,6 +40,13 @@ enum
BT_ARM_DATA_MODE,
};
+// Constants refering to BtDataMode and HsDataMode
+#define DATA_MODE_NXT 0x00
+#define DATA_MODE_GPS 0x01
+#define DATA_MODE_RAW 0x02
+#define DATA_MODE_MASK 0x07
+#define DATA_MODE_UPDATE 0x08
+
//Constant reffering to BtStateStatus
#define BT_BRICK_VISIBILITY 0x01
#define BT_BRICK_PORT_OPEN 0x02
@@ -64,9 +71,73 @@ enum
HS_INITIALISE = 1,
HS_INIT_RECEIVER,
HS_SEND_DATA,
- HS_DISABLE
+ HS_DISABLE,
+ HS_ENABLE,
+ HS_DEFAULT
+};
+
+// Constants reffering to hi-speed control syscall function
+enum
+{
+ HS_CTRL_INIT,
+ HS_CTRL_UART,
+ HS_CTRL_EXIT
};
+// Constants refering to HsSpeed
+enum
+{
+ HS_BAUD_1200,
+ HS_BAUD_2400,
+ HS_BAUD_3600,
+ HS_BAUD_4800,
+ HS_BAUD_7200,
+ HS_BAUD_9600,
+ HS_BAUD_14400,
+ HS_BAUD_19200,
+ HS_BAUD_28800,
+ HS_BAUD_38400,
+ HS_BAUD_57600,
+ HS_BAUD_76800,
+ HS_BAUD_115200,
+ HS_BAUD_230400,
+ HS_BAUD_460800,
+ HS_BAUD_921600
+};
+
+// constants referring to HsMode (number of bits)
+#define HS_MODE_5_DATA 0x0000
+#define HS_MODE_6_DATA 0x0040
+#define HS_MODE_7_DATA 0x0080
+#define HS_MODE_8_DATA 0x00C0
+
+// constants referring to HsMode (number of stop bits)
+#define HS_MODE_10_STOP 0x0000
+#define HS_MODE_15_STOP 0x1000
+#define HS_MODE_20_STOP 0x2000
+
+// constants referring to HsMode (parity)
+#define HS_MODE_E_PARITY 0x0000
+#define HS_MODE_O_PARITY 0x0200
+#define HS_MODE_S_PARITY 0x0400
+#define HS_MODE_M_PARITY 0x0600
+#define HS_MODE_N_PARITY 0x0800
+
+// constants referring to HsMode (D|P|S)
+#define HS_MODE_8N1 (HS_MODE_8_DATA|HS_MODE_N_PARITY|HS_MODE_10_STOP)
+#define HS_MODE_7E1 (HS_MODE_7_DATA|HS_MODE_E_PARITY|HS_MODE_10_STOP)
+
+// constants referring to HsAddress
+#define HS_ADDRESS_ALL 0
+#define HS_ADDRESS_1 1
+#define HS_ADDRESS_2 2
+#define HS_ADDRESS_3 3
+#define HS_ADDRESS_4 4
+#define HS_ADDRESS_5 5
+#define HS_ADDRESS_6 6
+#define HS_ADDRESS_7 7
+#define HS_ADDRESS_8 8
+
//Constants refering to DeviceStatus within DeviceTable
enum
{
@@ -213,6 +284,12 @@ typedef struct
UBYTE HsState;
UBYTE UsbState;
+ UBYTE HsAddress; // make RS485 addressible for up to 8 bricks
+
+ UWORD HsMode;
+
+ UBYTE BtDataMode; // nxt, gps, raw
+ UBYTE HsDataMode; // nxt, gps, raw
}IOMAPCOMM;
diff --git a/AT91SAM7S256/Source/c_display.c b/AT91SAM7S256/Source/c_display.c
index 6b15495..1732667 100644
--- a/AT91SAM7S256/Source/c_display.c
+++ b/AT91SAM7S256/Source/c_display.c
@@ -98,6 +98,14 @@ void cDisplayClrPixel(UBYTE X,UBYTE Y)
}
}
+void cDisplayXorPixel(UBYTE X,UBYTE Y)
+{
+ if ((X < DISPLAY_WIDTH) && (Y < DISPLAY_HEIGHT))
+ {
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] ^= (1 << (Y % 8));
+ }
+}
+
void cDisplayChar(FONT *pFont,UBYTE On,UBYTE X,UBYTE Y,UBYTE Char)
{
@@ -316,34 +324,84 @@ void cDisplayUpdateIcon(ICON *pIcons,UBYTE Index,SCREEN_CORDINATE *pCord)
}
-void cDisplayLineX(UBYTE X1,UBYTE X2,UBYTE Y)
+void cDisplayLineX(UBYTE X1, UBYTE X2, UBYTE Y, UBYTE PixelMode)
{
UBYTE X;
UBYTE M;
+ UBYTE t;
+ if (Y > DISPLAY_HEIGHT) return;
+ if (X1 > X2) {t = X1; X1 = X2; X2 = t;}
+ if (X2 > (DISPLAY_WIDTH-1)) X2 = (DISPLAY_WIDTH-1);
+
M = 1 << (Y % 8);
Y >>= 3;
- for (X = X1;X < X2;X++)
+ for (X = X1;X <= X2;X++)
{
- IOMapDisplay.Display[Y * DISPLAY_WIDTH + X] |= M;
+ switch (PixelMode)
+ {
+ case DRAW_PIXELS_INVERT:
+ IOMapDisplay.Display[Y * DISPLAY_WIDTH + X] ^= M;
+ break;
+ case DRAW_PIXELS_CLEAR:
+ IOMapDisplay.Display[Y * DISPLAY_WIDTH + X] &= ~M;
+ break;
+ case DRAW_PIXELS_SET:
+ default:
+ IOMapDisplay.Display[Y * DISPLAY_WIDTH + X] |= M;
+ break;
+ }
}
}
-void cDisplayLineY(UBYTE X,UBYTE Y1,UBYTE Y2)
+static UBYTE Masks[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
+void cDisplayLineY(UBYTE X,UBYTE Y1,UBYTE Y2,UBYTE PixelMode)
{
UBYTE Y;
-
- for (Y = Y1;Y < Y2;Y++)
+ UBYTE M;
+ UBYTE t;
+
+ if (X > DISPLAY_WIDTH) return;
+ if (Y1 > Y2) {t = Y1; Y1 = Y2; Y2 = t;}
+ if (Y2 > (DISPLAY_HEIGHT-1)) Y2 = (DISPLAY_HEIGHT-1);
+
+ // starting point of Y is the byte containing Y1
+ Y = (Y1 / 8) * 8;
+
+ while (Y <= Y2)
{
- IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= (1 << (Y % 8));
+ M = 0xff;
+ if (Y < Y1)
+ M &= ~Masks[Y1 % 8];
+ if ((Y2-Y) < 8)
+ M &= Masks[(Y2 % 8) + 1];
+ switch (PixelMode)
+ {
+ case DRAW_PIXELS_INVERT:
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] ^= M;
+ break;
+ case DRAW_PIXELS_CLEAR:
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] &= ~M;
+ break;
+ case DRAW_PIXELS_SET:
+ default:
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= M;
+ break;
+ }
+ Y += 8;
}
+
}
-void cDisplayFrame(SCREEN_CORDINATE *pCord)
+void cDisplayFrame(SCREEN_CORDINATE *pCord, UBYTE PixelMode)
{
- cDisplayLineX(pCord->StartX,pCord->StartX + pCord->PixelsX - 1,pCord->StartY);
- cDisplayLineY(pCord->StartX,pCord->StartY,pCord->StartY + pCord->PixelsY - 1);
- cDisplayLineY(pCord->StartX + pCord->PixelsX - 1,pCord->StartY,pCord->StartY + pCord->PixelsY - 1);
+ cDisplayLineX(pCord->StartX, pCord->StartX + pCord->PixelsX-1, pCord->StartY, PixelMode);
+ if (pCord->PixelsY > 1)
+ {
+ cDisplayLineY(pCord->StartX, pCord->StartY + 1, pCord->StartY + pCord->PixelsY - 1, PixelMode);
+ cDisplayLineY(pCord->StartX + pCord->PixelsX - 1, pCord->StartY + 1, pCord->StartY + pCord->PixelsY - 1, PixelMode);
+ }
}
@@ -358,30 +416,55 @@ void cDisplayErase(void)
memset(&IOMapDisplay.Display[0], 0x00, DISPLAY_WIDTH*DISPLAY_HEIGHT/8);
}
-
-void cDisplayEraseScreen(SCREEN_CORDINATE *pCord)
+void cDisplayFillScreen(SCREEN_CORDINATE *pCord, UBYTE PixelMode)
{
- UBYTE *pDestination;
- UBYTE Line;
- UBYTE Lines;
-
- if (((pCord->StartY & 0x07) == 0) && ((pCord->PixelsY & 0x07) == 0))
+ UBYTE X1, Y1;
+ UBYTE X2, Y2;
+ UBYTE X, Y;
+ UBYTE M;
+
+ X1 = pCord->StartX;
+ Y1 = pCord->StartY;
+ X2 = pCord->StartX + pCord->PixelsX - 1;
+ Y2 = pCord->StartY + pCord->PixelsY - 1;
+
+ if (X2 > (DISPLAY_WIDTH-1)) X2 = (DISPLAY_WIDTH-1);
+ if (Y2 > (DISPLAY_HEIGHT-1)) Y2 = (DISPLAY_HEIGHT-1);
+
+ Y = (Y1 / 8) * 8;
+
+ while (Y <= Y2)
{
- Line = pCord->StartY / 8;
- Lines = Line + pCord->PixelsY / 8;
-
- while (Line < Lines)
+ M = 0xff;
+ if (Y < Y1)
+ M &= ~Masks[Y1 % 8];
+ if ((Y2-Y) < 8)
+ M &= Masks[(Y2 % 8) + 1];
+ switch (PixelMode)
{
- pDestination = &IOMapDisplay.Display[Line * DISPLAY_WIDTH + pCord->StartX];
- memset(pDestination,0,(size_t)pCord->PixelsX);
- Line++;
+ case DRAW_PIXELS_INVERT:
+ for (X=X1; X<=X2; X++)
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] ^= M;
+ break;
+ case DRAW_PIXELS_CLEAR:
+ for (X=X1; X<=X2; X++)
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] &= ~M;
+ break;
+ case DRAW_PIXELS_SET:
+ default:
+ for (X=X1; X<=X2; X++)
+ IOMapDisplay.Display[(Y / 8) * DISPLAY_WIDTH + X] |= M;
+ break;
}
+ Y += 8;
}
}
-void cDisplayDraw(UBYTE Cmd,UBYTE On,UBYTE X1,UBYTE Y1,UBYTE X2,UBYTE Y2)
+void cDisplayDraw(UBYTE Cmd,UBYTE PixelMode,UBYTE X1,UBYTE Y1,UBYTE X2,UBYTE Y2)
{
+ SCREEN_CORDINATE Coord;
+
switch (Cmd)
{
case DISPLAY_ERASE_ALL :
@@ -392,52 +475,63 @@ void cDisplayDraw(UBYTE Cmd,UBYTE On,UBYTE X1,UBYTE Y1,UBYTE X2,UBYTE Y2)
case DISPLAY_PIXEL :
{
- if (On == TRUE)
+ switch (PixelMode)
{
- cDisplaySetPixel(X1,Y1);
- }
- else
- {
- cDisplayClrPixel(X1,Y1);
+ case DRAW_PIXELS_INVERT:
+ cDisplayXorPixel(X1,Y1);
+ break;
+ case DRAW_PIXELS_CLEAR:
+ cDisplayClrPixel(X1,Y1);
+ break;
+ case DRAW_PIXELS_SET:
+ default:
+ cDisplaySetPixel(X1,Y1);
+ break;
}
}
break;
- case DISPLAY_HORISONTAL_LINE :
+ case DISPLAY_HORIZONTAL_LINE :
{
- if (On == TRUE)
- {
- if (X1 > X2)
- {
- cDisplayLineX(X2,X1,Y1);
- }
- else
- {
- cDisplayLineX(X1,X2,Y1);
- }
- }
+ cDisplayLineX(X1,X2,Y1,PixelMode);
}
break;
case DISPLAY_VERTICAL_LINE :
{
- if (On == TRUE)
- {
- if (Y1 > Y2)
- {
- cDisplayLineY(X1,Y2,Y1);
- }
- else
- {
- cDisplayLineY(X1,Y1,Y2);
- }
- }
+ cDisplayLineY(X1,Y1,Y2,PixelMode);
}
break;
case DISPLAY_CHAR :
{
- cDisplayChar(IOMapDisplay.pFont,On,X1,Y1,X2);
+ cDisplayChar(IOMapDisplay.pFont,PixelMode,X1,Y1,X2);
+ }
+ break;
+
+ case DISPLAY_ERASE_LINE :
+ {
+ cDisplayEraseLine(X1);
+ }
+ break;
+
+ case DISPLAY_FILL_REGION :
+ {
+ Coord.StartX = X1;
+ Coord.StartY = Y1;
+ Coord.PixelsX = X2;
+ Coord.PixelsY = Y2;
+ cDisplayFillScreen(&Coord, PixelMode);
+ }
+ break;
+
+ case DISPLAY_FRAME :
+ {
+ Coord.StartX = X1;
+ Coord.StartY = Y1;
+ Coord.PixelsX = X2;
+ Coord.PixelsY = Y2;
+ cDisplayFrame(&Coord, PixelMode);
}
break;
@@ -454,6 +548,7 @@ void cDisplayInit(void* pHeader)
IOMapDisplay.UpdateMask = 0;
IOMapDisplay.TextLinesCenterFlags = 0;
IOMapDisplay.Flags = DISPLAY_REFRESH | DISPLAY_ON;
+ IOMapDisplay.Contrast = 0x5A; // 90
VarsDisplay.ErasePointer = 0;
VarsDisplay.UpdatePointer = 0;
}
@@ -514,7 +609,7 @@ void cDisplayCtrl(void)
}
if (Tmp < MENUICONS)
{
- cDisplayEraseScreen((SCREEN_CORDINATE*)&MENUICON_CORDINATES[Tmp]);
+ cDisplayFillScreen((SCREEN_CORDINATE*)&MENUICON_CORDINATES[Tmp], DRAW_PIXELS_CLEAR);
}
}
else
@@ -528,7 +623,7 @@ void cDisplayCtrl(void)
}
if (Tmp < STATUSICONS)
{
- cDisplayEraseScreen((SCREEN_CORDINATE*)&STATUSICON_CORDINATES[Tmp]);
+ cDisplayFillScreen((SCREEN_CORDINATE*)&STATUSICON_CORDINATES[Tmp], DRAW_PIXELS_CLEAR);
}
}
else
@@ -542,13 +637,13 @@ void cDisplayCtrl(void)
}
if (Tmp < SCREENS)
{
- cDisplayEraseScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[Tmp]);
+ cDisplayFillScreen((SCREEN_CORDINATE*)&SCREEN_CORDINATES[Tmp], DRAW_PIXELS_CLEAR);
}
if ((TmpMask & SCREEN_BIT(SCREEN_LARGE)))
{
if ((IOMapDisplay.UpdateMask & SPECIAL_BIT(TOPLINE)))
{
- cDisplayLineX(0,DISPLAY_WIDTH - 1,9);
+ cDisplayLineX(0,DISPLAY_WIDTH - 1, 9, DRAW_PIXELS_SET);
IOMapDisplay.UpdateMask &= ~SPECIAL_BIT(TOPLINE);
}
}
@@ -568,7 +663,7 @@ void cDisplayCtrl(void)
Cordinate.StartY = VarsDisplay.pOldBitmaps[Tmp]->StartY;
Cordinate.PixelsX = VarsDisplay.pOldBitmaps[Tmp]->PixelsX;
Cordinate.PixelsY = VarsDisplay.pOldBitmaps[Tmp]->PixelsY;
- cDisplayEraseScreen(&Cordinate);
+ cDisplayFillScreen(&Cordinate, DRAW_PIXELS_CLEAR);
}
}
else
@@ -622,7 +717,7 @@ void cDisplayCtrl(void)
}
if (Tmp < STEPICONS)
{
- cDisplayEraseScreen((SCREEN_CORDINATE*)&STEPICON_CORDINATES[Tmp]);
+ cDisplayFillScreen((SCREEN_CORDINATE*)&STEPICON_CORDINATES[Tmp], DRAW_PIXELS_CLEAR);
}
}
}
@@ -740,7 +835,7 @@ void cDisplayCtrl(void)
{
case FRAME_SELECT :
{
- cDisplayFrame((SCREEN_CORDINATE*)&SELECT_FRAME_CORDINATES);
+ cDisplayFrame((SCREEN_CORDINATE*)&SELECT_FRAME_CORDINATES,DRAW_PIXELS_SET);
}
break;
@@ -758,16 +853,16 @@ void cDisplayCtrl(void)
case STEPLINE :
{
- cDisplayLineX(22,28,20);
- cDisplayLineX(39,45,20);
- cDisplayLineX(56,62,20);
- cDisplayLineX(73,79,20);
+ cDisplayLineX(22,28,20,DRAW_PIXELS_SET);
+ cDisplayLineX(39,45,20,DRAW_PIXELS_SET);
+ cDisplayLineX(56,62,20,DRAW_PIXELS_SET);
+ cDisplayLineX(73,79,20,DRAW_PIXELS_SET);
}
break;
case TOPLINE :
{
- cDisplayLineX(0,DISPLAY_WIDTH - 1,9);
+ cDisplayLineX(0,DISPLAY_WIDTH - 1,9,DRAW_PIXELS_SET);
}
break;
@@ -808,11 +903,11 @@ void cDisplayCtrl(void)
{
if ((IOMapDisplay.Flags & DISPLAY_ON))
{
- dDisplayOn(TRUE);
+ dDisplayOn(TRUE, IOMapDisplay.Contrast);
}
else
{
- dDisplayOn(FALSE);
+ dDisplayOn(FALSE, IOMapDisplay.Contrast);
}
if (!(dDisplayUpdate(DISPLAY_HEIGHT,DISPLAY_WIDTH,(UBYTE*)IOMapDisplay.Normal)))
{
diff --git a/AT91SAM7S256/Source/c_display.iom b/AT91SAM7S256/Source/c_display.iom
index 2e1ab74..0b3cb46 100644
--- a/AT91SAM7S256/Source/c_display.iom
+++ b/AT91SAM7S256/Source/c_display.iom
@@ -24,11 +24,63 @@
// Constants related to simple draw entry (x = dont care)
enum
{
- DISPLAY_ERASE_ALL = 0x00, // W - erase entire screen (CMD,x,x,x,x,x)
- DISPLAY_PIXEL = 0x01, // W - set pixel (on/off) (CMD,TRUE/FALSE,X,Y,x,x)
- DISPLAY_HORISONTAL_LINE = 0x02, // W - draw horisontal line (CMD,TRUE,X1,Y1,X2,x)
- DISPLAY_VERTICAL_LINE = 0x03, // W - draw vertical line (CMD,TRUE,X1,Y1,x,Y2)
- DISPLAY_CHAR = 0x04 // W - draw char (actual font) (CMD,TRUE,X1,Y1,Char,x)
+ DISPLAY_ERASE_ALL = 0x00, // W - erase entire screen (CMD,x,x,x,x,x)
+ DISPLAY_PIXEL = 0x01, // W - set pixel (on/off) (CMD,TRUE/FALSE,X,Y,x,x)
+ DISPLAY_HORIZONTAL_LINE = 0x02, // W - draw horisontal line (on/off) (CMD,TRUE/FALSE,X1,Y1,X2,x)
+ DISPLAY_VERTICAL_LINE = 0x03, // W - draw vertical line (on/off) (CMD,TRUE/FALSE,X1,Y1,x,Y2)
+ DISPLAY_CHAR = 0x04, // W - draw char (actual font) (CMD,TRUE/FALSE,X1,Y1,Char,x)
+ DISPLAY_ERASE_LINE = 0x05, // W - erase a single line (CMD,x,LINE,x,x,x)
+ DISPLAY_FILL_REGION = 0x06, // W - fill screen region (CMD,TRUE/FALSE,X1,Y1,X2,Y2)
+ DISPLAY_FRAME = 0x07 // W - draw a frame (on/off) (CMD,TRUE/FALSE,X1,Y1,X2,Y2)
+};
+
+//JJR
+// Constants related to drawing operations.
+
+enum
+{
+ DRAW_PIXELS_SET = 0x00, //Basic options for pixel, line and shape drawing.
+ DRAW_PIXELS_CLEAR = 0x01,
+ DRAW_PIXELS_INVERT = 0x02
+};
+
+enum
+{
+ DRAW_SHAPE_HOLLOW = 0x00, //Extra options for shape drawing.
+ DRAW_SHAPE_FILLED = 0x01
+};
+
+enum
+{
+ DRAW_BITMAP_PLAIN = 0x00,
+ DRAW_BITMAP_INVERT = 0x01
+};
+
+enum
+{
+ DRAW_LOGICAL_COPY = 0x00,
+ DRAW_LOGICAL_AND = 0x01,
+ DRAW_LOGICAL_OR = 0x02,
+ DRAW_LOGICAL_XOR = 0x03
+};
+//JJR
+
+enum
+{
+ DRAW_FONT_WRAP_OFF = 0x00,
+ DRAW_FONT_WRAP_ON = 0x01
+};
+
+enum
+{
+ DRAW_FONT_DIR_L2RB = 0x00,
+ DRAW_FONT_DIR_L2RT = 0x01,
+ DRAW_FONT_DIR_R2LB = 0x02,
+ DRAW_FONT_DIR_R2LT = 0x03,
+ DRAW_FONT_DIR_B2TL = 0x04,
+ DRAW_FONT_DIR_B2TR = 0x05,
+ DRAW_FONT_DIR_T2BL = 0x06,
+ DRAW_FONT_DIR_T2BR = 0x07
};
// Constants related to Flags
@@ -44,6 +96,7 @@ enum
#define DISPLAY_HEIGHT 64 // Y pixels
#define DISPLAY_WIDTH 100 // X pixels
+#define DISPLAY_BUFF_WIDTH 100 // width of buffer
#define DISPLAY_MENUICONS_Y 40
#define DISPLAY_MENUICONS_X_OFFS 7
@@ -51,6 +104,9 @@ enum
#define DISPLAY_IDLE ((pMapDisplay->EraseMask == 0) && (pMapDisplay->UpdateMask == 0))
+#define DISPLAY_CONTRAST_DEFAULT 0x5A
+#define DISPLAY_CONTRAST_MAX 0x7F
+
enum TEXTLINE_NO // Used in macro "TEXTLINE_BIT"
{
TEXTLINE_1, // Upper most line
@@ -166,8 +222,10 @@ typedef struct
UBYTE TextLinesCenterFlags; // Mask to center TextLines
- UBYTE Normal[DISPLAY_HEIGHT / 8][DISPLAY_WIDTH]; // Raw display memory for normal screen
- UBYTE Popup[DISPLAY_HEIGHT / 8][DISPLAY_WIDTH]; // Raw display memory for popup screen
+ UBYTE Normal[DISPLAY_HEIGHT / 8][DISPLAY_BUFF_WIDTH]; // Raw display memory for normal screen
+ UBYTE Popup[DISPLAY_HEIGHT / 8][DISPLAY_BUFF_WIDTH]; // Raw display memory for popup screen
+
+ UBYTE Contrast; // Display contrast
}
IOMAPDISPLAY;
diff --git a/AT91SAM7S256/Source/c_input.c b/AT91SAM7S256/Source/c_input.c
index 2cb9be1..18a14c6 100644
--- a/AT91SAM7S256/Source/c_input.c
+++ b/AT91SAM7S256/Source/c_input.c
@@ -2,11 +2,11 @@
//
// Date init 14.12.2004
//
-// Revision date $Date:: 3/21/09 10:31a $
+// Revision date $Date:: 19-03-10 12:36 $
//
// Filename $Workfile:: c_input.c $
//
-// Version $Revision:: 39 $
+// Version $Revision:: 40 $
//
// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $
//
@@ -88,7 +88,7 @@ void cInputCalcSensorValue(UWORD NewSensorRaw, UWORD *pOldSensorRaw, SWORD
UBYTE *pBoolean, UBYTE *pDebounce, UBYTE *pSampleCnt,
UBYTE *LastAngle, UBYTE *pEdgeCnt, UBYTE Slope,
UBYTE Mode);
-void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType);
+void cInputSetupType(UBYTE Port, UBYTE newType, UBYTE OldType);
void cInputSetupCustomSensor(UBYTE Port);
void cInputCalcSensorValues(UBYTE No);
UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus);
@@ -185,6 +185,17 @@ void cInputCtrl(void)
VarsInput.ColorStatus &= ~(0x01<<Tmp);
memset(&(VarsInput.VarsColor[Tmp]),0 ,sizeof(VarsInput.VarsColor[Tmp]));
+ VarsInput.InvalidTimer[Tmp] = INVALID_RELOAD_NORMAL;
+ /* If old type is color sensor in color lamp mode then turn off leds */
+ if ((sType == NO_SENSOR) &&
+ (oldType == COLORRED || oldType == COLORGREEN ||
+ oldType == COLORBLUE || oldType == COLORFULL ||
+ oldType == COLOREXIT))
+ {
+ VarsInput.InvalidTimer[Tmp] = INVALID_RELOAD_COLOR;
+ IOMapInput.Inputs[Tmp].SensorType = COLOREXIT;
+ sType = COLOREXIT;
+ }
/* Setup the pins for the new sensortype */
cInputSetupType(Tmp, pType, oldType);
sType = *pType;
@@ -317,11 +328,6 @@ void cInputCalcSensorValues(UBYTE No)
{
case SENSOROFF:
{
-
- /* Make sure that sensor data are invalid while unplugged*/
- VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR;
- IOMapInput.Inputs[No].InvalidData = INVALID_DATA;
-
/* Check if sensor has been attached */
if (dInputCheckColorStatus(No))
{
@@ -384,11 +390,6 @@ void cInputCalcSensorValues(UBYTE No)
{
case SENSOROFF:
{
-
- /* Make sure that sensor data are invalid while unplugged */
- VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR;
- IOMapInput.Inputs[No].InvalidData = INVALID_DATA;
-
/* Check if sensor has been attached */
if (dInputCheckColorStatus(No))
{
@@ -944,29 +945,10 @@ void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFu
}
-void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType)
+void cInputSetupType(UBYTE Port, UBYTE newType, UBYTE OldType)
{
- VarsInput.InvalidTimer[Port] = INVALID_RELOAD_NORMAL;
-
- /* If old type is color sensor in color lamp mode then turn off leds */
- switch (OldType)
- {
- case COLORRED:
- case COLORGREEN:
- case COLORBLUE:
- case COLORFULL:
- case COLOREXIT:
- {
- if (NO_SENSOR == *pType)
- {
- VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR;
- *pType = COLOREXIT;
- }
- }
- break;
- }
- switch(*pType)
+ switch(newType)
{
case NO_SENSOR:
case SWITCH:
@@ -1063,6 +1045,8 @@ void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType)
dInputSetDirInDigi1(Port);
IOMapInput.Colors[Port].CalibrationState = SENSORCAL;
VarsInput.VarsColor[Port].ColorInitState = 0;
+
+ IOMapInput.Inputs[Port].SensorValue = BLACKCOLOR;
}
break;
@@ -1086,6 +1070,10 @@ void cInputSetupCustomSensor(UBYTE Port)
dInputClearDigi0(Port);
}
}
+ else
+ {
+ dInputSetDirInDigi0(Port);
+ }
if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x02)
{
if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x02)
diff --git a/AT91SAM7S256/Source/c_loader.c b/AT91SAM7S256/Source/c_loader.c
index 995c920..b6e6436 100644
--- a/AT91SAM7S256/Source/c_loader.c
+++ b/AT91SAM7S256/Source/c_loader.c
@@ -18,6 +18,7 @@
#include "c_ioctrl.iom"
#include "d_loader.h"
#include "c_loader.h"
+#include <string.h>
static IOMAPLOADER IOMapLoader;
static VARSLOADER VarsLoader;
@@ -41,12 +42,18 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen
UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize);
UWORD cLoaderFindModule(UBYTE *pBuffer);
void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule);
+UWORD cLoaderCreateFile(UBYTE *pFileName, ULONG *pLength, UBYTE bLinear, UBYTE fType);
+UWORD cLoaderRenameFile(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength);
+UWORD cLoaderOpenRead(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength, UBYTE bLinear);
+UWORD cLoaderDeleteFile(UBYTE *pFileName);
+UWORD cLoaderResizeFile(UBYTE *pFileName, ULONG pLength);
void cLoaderInit(void* pHeader)
{
IOMapLoader.pFunc = &cLoaderFileRq;
VarsLoader.IoMapHandle = FALSE;
+ VarsLoader.Resizing = FALSE;
pHeaders = pHeader;
dLoaderInit();
IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
@@ -54,9 +61,154 @@ void cLoaderInit(void* pHeader)
void cLoaderCtrl(void)
{
+ if (VarsLoader.Resizing)
+ {
+ // keep resizing the file currently in the file resize operation
+ // copy 1024 bytes from old file handle to new file handle
+ // if no more bytes to copy then set Resizing to FALSE,
+ // close both files, and delete the old file.
+ }
}
+UWORD cLoaderCreateFile(UBYTE *pFileName, ULONG *pLength, UBYTE bLinear, UBYTE fType)
+{
+ UWORD ReturnState;
+ /* This is to create a new file */
+ ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, bLinear, fType);
+ if (0x8000 <= ReturnState)
+ {
+ dLoaderCloseHandle(ReturnState);
+ }
+ else
+ {
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ }
+ return ReturnState;
+}
+UWORD cLoaderRenameFile(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength)
+{
+ UWORD ReturnState;
+ UBYTE FoundName[FILENAME_LENGTH + 1];
+
+ /* Check for file exists*/
+ ReturnState = dLoaderFind(pBuffer, FoundName, pLength, pLength, (UBYTE) SEARCHING);
+ dLoaderCloseHandle(LOADER_HANDLE(ReturnState));
+ if (FILENOTFOUND == LOADER_ERR(ReturnState))
+ {
+ ReturnState = dLoaderFind(pFileName, FoundName, pLength, pLength, (UBYTE) SEARCHING);
+ if (ReturnState < 0x8000)
+ {
+ ReturnState = dLoaderCheckFiles((UBYTE) ReturnState);
+ if (ReturnState < 0x8000)
+ {
+ dLoaderRenameFile((UBYTE) ReturnState, pBuffer);
+ }
+ }
+ dLoaderCloseHandle(LOADER_HANDLE(ReturnState));
+ }
+ else
+ {
+ if (SUCCESS == LOADER_ERR(ReturnState))
+ {
+ ReturnState |= FILEEXISTS;
+ }
+ }
+ return ReturnState;
+}
+
+UWORD cLoaderOpenRead(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength, UBYTE bLinear)
+{
+ UWORD ReturnState;
+ if (bLinear)
+ ReturnState = dLoaderGetFilePtr(pFileName, pBuffer, pLength);
+ else
+ ReturnState = dLoaderOpenRead(pFileName, pLength);
+ if (0x8000 <= ReturnState)
+ {
+ dLoaderCloseHandle(ReturnState);
+ }
+ return ReturnState;
+}
+
+UWORD cLoaderDeleteFile(UBYTE *pFileName)
+{
+ UWORD ReturnState;
+ ReturnState = dLoaderDelete(pFileName);
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ return ReturnState;
+}
+
+UWORD cLoaderResizeFile(UBYTE *pFileName, ULONG pLength)
+{
+ UWORD ReturnState = SUCCESS;
+ /*
+ All that this method can do is start the process of
+ resizing a file. To do that we will
+ a) rename the file
+ b) open old file for reading
+ c) create new file for writing
+ d) store both handles in VarsLoader & set resizing flag
+ e) if any errors occur in a, b, or c then restore original file
+ f) return LOADER_BUSY (maybe?)
+ */
+/*
+ // rename file to _tmpoldname
+ strcat __frsFRArgs.NewFilename, '_tmp', __frsOldName
+ mov __frsFRArgs.OldFilename, __frsOldName
+ syscall FileRename, __frsFRArgs
+ mov __frsResult, __frsFRArgs.Result
+ brtst NEQ, __frsEnd, __frsResult
+ // old file has been renamed successfully
+ mov __frsFOReadArgs.Filename, __frsFRArgs.NewFilename
+ syscall FileOpenRead, __frsFOReadArgs
+ mov __frsResult, __frsFOReadArgs.Result
+ brtst NEQ, __frsOpenReadFailed, __frsResult
+ // renamed file is open for reading
+ mov __frsFOWriteArgs.Filename, __frsOldName
+ mov __frsFOWriteArgs.Length, __frsNewSize
+ syscall FileOpenWrite, __frsFOWriteArgs
+ mov __frsResult, __frsFOWriteArgs.Result
+ brtst NEQ, __frsOpenWriteFailed, __frsResult
+ // both files are open
+ mov __frsFReadArgs.FileHandle, __frsFOReadArgs.FileHandle
+ mov __frsFWriteArgs.FileHandle, __frsFOWriteArgs.FileHandle
+__frsCopyLoop:
+ set __frsFReadArgs.Length, 1024
+ syscall FileRead, __frsFReadArgs
+ brtst NEQ, __frsEndLoop, __frsFReadArgs.Result
+ brtst LTEQ, __frsEndLoop, __frsFReadArgs.Length
+ mov __frsFWriteArgs.Buffer, __frsFReadArgs.Buffer
+ mov __frsFWriteArgs.Length, __frsFReadArgs.Length
+ syscall FileWrite, __frsFWriteArgs
+ brtst NEQ, __frsEndLoop, __frsFWriteArgs.Result
+ jmp __frsCopyLoop
+__frsEndLoop:
+ // close read file
+ mov __frsFCArgs.FileHandle, __frsFOReadArgs.FileHandle
+ syscall FileClose, __frsFCArgs
+ // close write file
+ mov __frsFCArgs.FileHandle, __frsFOWriteArgs.FileHandle
+ syscall FileClose, __frsFCArgs
+ // delete read file
+ mov __frsFDArgs.Filename, __frsFOReadArgs.Filename
+ syscall FileDelete, __frsFDArgs
+ jmp __frsEnd
+__frsOpenWriteFailed:
+ // close read file
+ mov __frsFCArgs.FileHandle, __frsFOReadArgs.FileHandle
+ syscall FileClose, __frsFCArgs
+// jmp __frsEnd
+__frsOpenReadFailed:
+ // if the open read failed rename tmp back to original and exit
+ mov __frsFRArgs.OldFilename, __frsFRArgs.NewFilename
+ mov __frsFRArgs.NewFilename, __frsOldName
+ syscall FileRename, __frsFRArgs
+__frsEnd:
+ return
+*/
+ return ReturnState;
+}
UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength)
{
@@ -68,63 +220,29 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen
{
case OPENREAD:
{
- ReturnState = dLoaderOpenRead(pFileName, pLength);
- if (0x8000 <= ReturnState)
- {
- dLoaderCloseHandle(ReturnState);
- }
+ ReturnState = cLoaderOpenRead(pFileName, pBuffer, pLength, FALSE);
}
break;
case OPENREADLINEAR:
{
- ReturnState = dLoaderGetFilePtr(pFileName, pBuffer, pLength);
- if (0x8000 <= ReturnState)
- {
- dLoaderCloseHandle(ReturnState);
- }
-
+ ReturnState = cLoaderOpenRead(pFileName, pBuffer, pLength, TRUE);
}
break;
case OPENWRITE:
{
/* This is to create a new file */
- ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, SYSTEMFILE);
- if (0x8000 <= ReturnState)
- {
- dLoaderCloseHandle(ReturnState);
- }
- else
- {
- IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
- }
+ ReturnState = cLoaderCreateFile(pFileName, pLength, (UBYTE) NONLINEAR, SYSTEMFILE);
}
break;
case OPENWRITELINEAR:
{
- ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) LINEAR, SYSTEMFILE);
- if (0x8000 <= ReturnState)
- {
- dLoaderCloseHandle(ReturnState);
- }
- else
- {
- IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
- }
+ ReturnState = cLoaderCreateFile(pFileName, pLength, (UBYTE) LINEAR, SYSTEMFILE);
}
break;
case OPENWRITEDATA:
{
-
- ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, DATAFILE);
- if (0x8000 <= ReturnState)
- {
- dLoaderCloseHandle(ReturnState);
- }
- else
- {
- IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
- }
+ ReturnState = cLoaderCreateFile(pFileName, pLength, (UBYTE) NONLINEAR, DATAFILE);
}
break;
case OPENAPPENDDATA:
@@ -147,6 +265,26 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen
IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
}
break;
+ case RESIZEDATAFILE:
+ {
+ ReturnState = cLoaderResizeFile(pFileName, *pLength);
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ }
+ break;
+ case SEEKFROMSTART:
+ case SEEKFROMCURRENT:
+ case SEEKFROMEND:
+ {
+ // *pFileName is the handle, *pLength is the offset, Cmd-SEEKFROMSTART is the origin
+ ReturnState = dLoaderSeek(*pFileName, *(SLONG*)pLength, Cmd-SEEKFROMSTART);
+ }
+ break;
+ case FILEPOSITION:
+ {
+ // *pFileName is the handle, pLength is the returned file position
+ ReturnState = dLoaderTell(*pFileName, pLength);
+ }
+ break;
case READ:
{
ReturnState = dLoaderRead(*pFileName, pBuffer, pLength);
@@ -179,8 +317,7 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen
break;
case DELETE:
{
- ReturnState = dLoaderDelete(pFileName);
- IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ ReturnState = cLoaderDeleteFile(pFileName);
}
break;
@@ -320,31 +457,7 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen
case RENAMEFILE:
{
- UBYTE FoundName[FILENAME_LENGTH + 1];
-
- /* Check for file exists*/
- ReturnState = dLoaderFind(pBuffer, FoundName, pLength, pLength, (UBYTE) SEARCHING);
- dLoaderCloseHandle(LOADER_HANDLE(ReturnState));
- if (FILENOTFOUND == LOADER_ERR(ReturnState))
- {
- ReturnState = dLoaderFind(pFileName, FoundName, pLength, pLength, (UBYTE) SEARCHING);
- if (ReturnState < 0x8000)
- {
- ReturnState = dLoaderCheckFiles((UBYTE) ReturnState);
- if (ReturnState < 0x8000)
- {
- dLoaderRenameFile((UBYTE) ReturnState, pBuffer);
- }
- }
- dLoaderCloseHandle(LOADER_HANDLE(ReturnState));
- }
- else
- {
- if (SUCCESS == LOADER_ERR(ReturnState))
- {
- ReturnState |= FILEEXISTS;
- }
- }
+ ReturnState = cLoaderRenameFile(pFileName, pBuffer, pLength);
}
break;
diff --git a/AT91SAM7S256/Source/c_loader.h b/AT91SAM7S256/Source/c_loader.h
index 03f8062..2305dd9 100644
--- a/AT91SAM7S256/Source/c_loader.h
+++ b/AT91SAM7S256/Source/c_loader.h
@@ -30,6 +30,9 @@ typedef struct
UBYTE ModSearchType;
UBYTE UsbStatus;
UBYTE IoMapHandle;
+ UBYTE Resizing;
+ UBYTE ResizeOldHandle;
+ UBYTE ResizeNewHandle;
}VARSLOADER;
void cLoaderInit(void* pHeader);
diff --git a/AT91SAM7S256/Source/c_loader.iom b/AT91SAM7S256/Source/c_loader.iom
index dde8b6a..afc6523 100644
--- a/AT91SAM7S256/Source/c_loader.iom
+++ b/AT91SAM7S256/Source/c_loader.iom
@@ -1,11 +1,11 @@
//
// Date init 14.12.2004
//
-// Revision date $Date:: 24-06-09 8:53 $
+// Revision date $Date:: 19-03-10 12:36 $
//
// Filename $Workfile:: c_loader.iom $
//
-// Version $Revision:: 15 $
+// Version $Revision:: 17 $
//
// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $
//
@@ -21,7 +21,7 @@
//For example, version 1.5 would be 0x0105
//If these switch to little-endian, be sure to update
//definition and usages of VM_OLDEST_COMPATIBLE_VERSION, too!
-#define FIRMWAREVERSION 0x011D //1.28
+#define FIRMWAREVERSION 0x011F //1.31
#define PROTOCOLVERSION 0x017C //1.124
enum
@@ -40,21 +40,36 @@ enum
OPENWRITEDATA = 0x8B,
OPENAPPENDDATA = 0x8C,
CROPDATAFILE = 0x8D, /* New cmd for datalogging */
+// XXXXXXXXXXXXXX = 0x8E,
+// XXXXXXXXXXXXXX = 0x8F,
FINDFIRSTMODULE = 0x90,
FINDNEXTMODULE = 0x91,
CLOSEMODHANDLE = 0x92,
+// XXXXXXXXXXXXXX = 0x93,
IOMAPREAD = 0x94,
IOMAPWRITE = 0x95,
+// XXXXXXXXXXXXXX = 0x96,
BOOTCMD = 0x97, /* external command only */
SETBRICKNAME = 0x98,
+// XXXXXXXXXXXXXX = 0x99,
BTGETADR = 0x9A,
DEVICEINFO = 0x9B,
+// XXXXXXXXXXXXXX = 0x9C,
+// XXXXXXXXXXXXXX = 0x9D,
+// XXXXXXXXXXXXXX = 0x9E,
+// XXXXXXXXXXXXXX = 0x9F,
DELETEUSERFLASH = 0xA0,
POLLCMDLEN = 0xA1,
POLLCMD = 0xA2,
RENAMEFILE = 0xA3,
- BTFACTORYRESET = 0xA4
-
+ BTFACTORYRESET = 0xA4,
+
+ // enhanced firmware additions
+ RESIZEDATAFILE = 0xD0,
+ SEEKFROMSTART = 0xD1,
+ SEEKFROMCURRENT = 0xD2,
+ SEEKFROMEND = 0xD3,
+ FILEPOSITION = 0xD4
};
typedef UWORD LOADER_STATUS;
diff --git a/AT91SAM7S256/Source/c_lowspeed.c b/AT91SAM7S256/Source/c_lowspeed.c
index 26851db..f8baa92 100644
--- a/AT91SAM7S256/Source/c_lowspeed.c
+++ b/AT91SAM7S256/Source/c_lowspeed.c
@@ -101,7 +101,7 @@ void cLowSpeedCtrl(void)
{
if (IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx != 0)
{
- dLowSpeedReceiveData(ChannelNumber, &VarsLowSpeed.InputBuf[ChannelNumber].Buf[0], IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx);
+ dLowSpeedReceiveData(ChannelNumber, &VarsLowSpeed.InputBuf[ChannelNumber].Buf[0], IOMapLowSpeed.InBuf[ChannelNumber].BytesToRx, IOMapLowSpeed.NoRestartOnRead);
VarsLowSpeed.RxTimeCnt[ChannelNumber] = 0;
}
IOMapLowSpeed.ChannelState[ChannelNumber] = LOWSPEED_COMMUNICATING;
diff --git a/AT91SAM7S256/Source/c_lowspeed.iom b/AT91SAM7S256/Source/c_lowspeed.iom
index 290ed35..15e0a8e 100644
--- a/AT91SAM7S256/Source/c_lowspeed.iom
+++ b/AT91SAM7S256/Source/c_lowspeed.iom
@@ -67,6 +67,19 @@ enum
LOWSPEED_RX_ERROR
};
+// Constants referring to NoRestartOnRead
+enum
+{
+ COM_CHANNEL_RESTART_ALL = 0x00,
+ COM_CHANNEL_NO_RESTART_1 = 0x01,
+ COM_CHANNEL_NO_RESTART_2 = 0x02,
+ COM_CHANNEL_NO_RESTART_3 = 0x04,
+ COM_CHANNEL_NO_RESTART_4 = 0x08,
+ COM_CHANNEL_RESTART_NONE = 0x0F,
+ COM_CHANNEL_NO_RESTART_MASK = 0x10
+};
+
+
typedef struct
{
@@ -85,7 +98,7 @@ typedef struct
UBYTE ErrorType[NO_OF_LSBUF];
UBYTE State;
UBYTE Speed;
- UBYTE Spare1;
+ UBYTE NoRestartOnRead;
}IOMAPLOWSPEED;
diff --git a/AT91SAM7S256/Source/c_output.c b/AT91SAM7S256/Source/c_output.c
index e0645e0..30058b4 100644
--- a/AT91SAM7S256/Source/c_output.c
+++ b/AT91SAM7S256/Source/c_output.c
@@ -130,7 +130,7 @@ void cOutputCtrl(void)
if (pOut->Flags & UPDATE_TACHO_LIMIT)
{
pOut->Flags &= ~UPDATE_TACHO_LIMIT;
- dOutputSetTachoLimit(Tmp, pOut->TachoLimit);
+ dOutputSetTachoLimit(Tmp, pOut->TachoLimit, pOut->Options);
}
if (pOut->Flags & UPDATE_PID_VALUES)
{
diff --git a/AT91SAM7S256/Source/c_output.iom b/AT91SAM7S256/Source/c_output.iom
index 276bcba..989a0c4 100644
--- a/AT91SAM7S256/Source/c_output.iom
+++ b/AT91SAM7S256/Source/c_output.iom
@@ -27,6 +27,9 @@ enum
REG_METHOD = 0xF0 /* Regulation methods - to be designed! */
};
+#define OPTION_HOLDATLIMIT 0x10
+#define OPTION_RAMPDOWNTOLIMIT 0x20
+
// Constants related to Flags
enum
{
diff --git a/AT91SAM7S256/Source/c_ui.c b/AT91SAM7S256/Source/c_ui.c
index 7e39d6f..a9986f1 100644
--- a/AT91SAM7S256/Source/c_ui.c
+++ b/AT91SAM7S256/Source/c_ui.c
@@ -59,7 +59,9 @@ const HEADER cUi =
#include "Display.txt" // Bitmap for frame used in view and datalog
#include "LowBattery.txt" // Bitmap showed when low battery occures
#include "Font.txt" // Font used for all text
+#ifndef STRIPPED
#include "Step.txt" // Bitmap used in On Brick Programming
+#endif
#include "Cursor.txt" // Bitmap for cursor
#include "Running.txt" // Icon collection used for "running" symbol
#include "Port.txt" // Font used for naming sensor ports in datalog/bluetooth
@@ -69,6 +71,7 @@ const HEADER cUi =
#include "Info.txt" // Bitmap for feedback
#include "Icons.txt" // Icon collection used for menues
+#ifndef STRIPPED
// ****** INTRO ANIMATION RESOURCES ******************************************
#include "RCXintro_1.txt" // Bitmap for picture 1 in the intro animation
@@ -107,6 +110,7 @@ const BMPMAP *Intro[NO_OF_INTROBITMAPS] = // Picture sequence for the intro
(BMPMAP*) POINTER_TO_DATA (RCXintro_15),
(BMPMAP*) POINTER_TO_DATA (RCXintro_16)
};
+#endif
// ****** STATUS LINE GRAPHIC RESOURCES **************************************
@@ -168,43 +172,29 @@ enum STATUS_NO // Index in status icon collection file
enum // String index in text string file
{
TXT_GENERAL_EMPTY,
+ TXT_FB_GENERIC_FAIL, // "Failed!"
+
// BlueTooth connect
TXT_FB_BT_CONNECTING_WAIT, // "Connecting"
TXT_FB_BT_CONNECT_BUSY_FAIL, // "Line is busy"
- TXT_FB_BT_CONNECTING_FAIL, // "Failed!"
// BlueTooth send file
TXT_FB_BT_SENDING_NO_CONN_FAIL, // "Connection?"
TXT_FB_BT_SENDING_WAIT, // "Sending file"
- TXT_FB_BT_SENDING_FAIL, // "Failed!"
// BlueTooth on/off
TXT_FB_BT_TURNING_ON_WAIT, // "Turning on"
- TXT_FB_BT_TURNING_ON_FAIL, // "Failed!"
TXT_FB_BT_TURNING_OFF_WAIT, // "Turning off"
- TXT_FB_BT_TURNING_OFF_FAIL, // "Failed!"
// BlueTooth seach
TXT_FB_BT_SEARCHING_WAIT, // "Searching"
TXT_FB_BT_SEARCH_ABORTED_INFO, // "Aborted!"
- TXT_FB_BT_SEARCHING_FAIL, // "Failed!"
-
- // BlueTooth device list
- TXT_FB_BT_REMOVE_FAIL, // "Failed!"
-
- // BlueTooth connection list
- TXT_FB_BT_DISCONNECT_FAIL, // "Failed!"
// On Brick Programming
TXT_FB_OBP_MEMORY_FULL_FAIL, // "Memory full!"
- TXT_FB_OBP_FILE_SAVED_INFO, // "File saved"
- TXT_FB_OBP_FILE_EXIST_FAIL, // "File exist"
- TXT_FB_OBP_OVERWRITE_FAIL, // "overwrite!"
-
- // Datalogging
- TXT_FB_DL_FILE_SAVED_INFO, // "File saved"
- TXT_FB_DL_FILE_EXIST_FAIL, // "File exist"
- TXT_FB_DL_OVERWRITE_FAIL, // "overwrite!"
+ TXT_FB_FILE_SAVED_INFO, // "File saved"
+ TXT_FB_FILE_EXIST_FAIL, // "File exist"
+ TXT_FB_OVERWRITE_FAIL, // "overwrite!"
// File delete
TXT_FB_FD_FILE_DELETED_INFO, // "File deleted"
@@ -217,7 +207,7 @@ enum // String index in text string file
TXT_FILERUN_RUNNING, // "Running"
TXT_FILERUN_ABORTED, // "Aborted!"
TXT_FILERUN_ENDED, // "Ended"
- TXT_FILERUN_FILE_ERROR, // "File error!"
+ TXT_FILERUN_FILE_ERROR, // "File error! %d"
// Files delete
TXT_FILESDELETE_DELETING_ALL, // "Deleting all"
@@ -250,13 +240,7 @@ enum // String index in text string file
TXT_ONBRICKPROGRAMMING_BC_LR_MOTORS, // "B/C - L/R motors"
// View
- TXT_VIEW_SELECT, // "Select"
-
- // BlueTooth device list
- TXT_BTDEVICELIST_SELECT, // "Select"
-
- // BlueTooth connection list
- TXT_BTCONNECTLIST_SELECT, // "Select"
+ TXT_GENERIC_SELECT, // "Select"
// Bluetooth list errors
TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_1, // BT save data error!
@@ -1286,10 +1270,24 @@ void cUiCtrl(void)
*/
//
+ if ((!(IOMapUi.Flags & UI_EXECUTE_LMS_FILE)) && (IOMapUi.State == INIT_INTRO)/* && ((pMapButton->State[BTN1] & PRESSED_STATE)!=PRESSED_STATE)*/)
+ {
+ UWORD LStatus;
+ if (LOADER_ERR(LStatus = pMapLoader->pFunc(FINDFIRST, UI_STARTUP_PROGRAM, NULL, NULL)) == SUCCESS)
+ {
+ //Close file handle returned by FINDFIRST
+ pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(LStatus), NULL, NULL);
+ strcpy((char*)IOMapUi.LMSfilename, UI_STARTUP_PROGRAM);
+ IOMapUi.Flags |= UI_EXECUTE_LMS_FILE;
+ IOMapUi.State = INIT_MENU;
+ }
+ }
VarsUi.CRPasskey++;
VarsUi.ButtonTimer++;
+#ifndef STRIPPED
VarsUi.OBPTimer++;
+#endif
switch (IOMapUi.State)
{
case INIT_DISPLAY : // Load font and icons
@@ -1309,7 +1307,9 @@ void cUiCtrl(void)
pMapDisplay->pFont = (FONT*)Font;
pMapDisplay->pStatusIcons = (ICON*)Status;
pMapDisplay->pStatusText = (UBYTE*)VarsUi.StatusText;
+#ifndef STRIPPED
pMapDisplay->pStepIcons = (ICON*)Step;
+#endif
VarsUi.State = 0;
VarsUi.Pointer = 0;
@@ -1328,7 +1328,9 @@ void cUiCtrl(void)
IOMapUi.State = CONFIG_INTRO ? INIT_INTRO : INIT_WAIT;
pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND);
- pMapDisplay->pBitmaps[BITMAP_1] = CONFIG_INTRO ? (BMPMAP*)Intro[VarsUi.Pointer] : RCXintro_16;
+#ifndef STRIPPED
+ pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer];
+#endif
pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1);
pMapDisplay->Flags |= DISPLAY_ON;
@@ -1345,7 +1347,9 @@ void cUiCtrl(void)
{
VarsUi.LowBattHasOccured = 2;
pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND);
+#ifndef STRIPPED
pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer];
+#endif
pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1);
IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE;
VarsUi.State = 0;
@@ -1377,6 +1381,7 @@ void cUiCtrl(void)
VarsUi.LowBattHasOccured = 1;
}
}
+#ifndef STRIPPED
if (++VarsUi.Timer >= (INTRO_SHIFT_TIME))
{
switch (VarsUi.State)
@@ -1429,11 +1434,15 @@ void cUiCtrl(void)
}
}
+#else
+ pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_BACKGROUND);
+ IOMapUi.State = INIT_MENU;
+#endif
}
}
break;
#endif /* CONFIG_INTRO */
-
+#ifndef STRIPPED
case INIT_WAIT :
{
if (++VarsUi.Timer >= INTRO_STOP_TIME)
@@ -1443,7 +1452,7 @@ void cUiCtrl(void)
}
}
break;
-
+#endif
case INIT_MENU :
{
// Restart menu system
diff --git a/AT91SAM7S256/Source/c_ui.h b/AT91SAM7S256/Source/c_ui.h
index e0f8f4a..71d0e18 100644
--- a/AT91SAM7S256/Source/c_ui.h
+++ b/AT91SAM7S256/Source/c_ui.h
@@ -19,7 +19,11 @@
#ifndef C_UI
#define C_UI
+#ifndef STRIPPED
#define DATALOGENABLED 1 // 1 == Datalog enable
+#else
+#define DATALOGENABLED 0 // 0 == Datalog disabled
+#endif
#define NO_OF_FEEDBACK_CHARS 12 // Chars left when bitmap also showed
#define SIZE_OF_CURSOR 16 // Bitmap size of cursor (header + 8x8 pixels)
@@ -283,6 +287,7 @@ typedef struct
UBYTE FileRight; // File right
UBYTE NoOfFiles; // No of files
+#ifndef STRIPPED
// On brick programming menu
UBYTE ProgramSteps[ON_BRICK_PROGRAMSTEPS]; // On brick programming steps
UBYTE ProgramStepPointer; // On brick programming step pointer
@@ -290,7 +295,8 @@ typedef struct
UBYTE FileHeader[FILEHEADER_LENGTH]; // File header for programs
UBYTE *FeedBackText; // Program end text
UWORD OBPTimer; // Graphic update timer
-
+#endif
+
// BT search menu
UBYTE NoOfDevices; // BT search no of devices found
UBYTE NoOfNames; // BT search no of names found
@@ -337,6 +343,7 @@ typedef struct
SLONG ViewSampleValue; // Latch for sensor values
UBYTE ViewSampleValid; // Latch for sensor valid
+#ifndef STRIPPED
// Datalog
ULONG DatalogOldTick;
ULONG DatalogRTC; // Real time in mS
@@ -348,7 +355,8 @@ typedef struct
UWORD DatalogError; // Error code
UBYTE DatalogPort[DATALOGPORTS]; // Logging sensor
UBYTE Update; // Update icons flag
-
+#endif
+
// NV storage
ULONG NVTmpLength; // Non volatile filelength
SWORD NVTmpHandle; // Non volatile filehandle
diff --git a/AT91SAM7S256/Source/c_ui.iom b/AT91SAM7S256/Source/c_ui.iom
index 770b682..9cfe925 100644
--- a/AT91SAM7S256/Source/c_ui.iom
+++ b/AT91SAM7S256/Source/c_ui.iom
@@ -31,15 +31,20 @@ enum
// Various filenames without extension
#define UI_NONVOLATILE "NVConfig" // Ui non volatile config filename
+#ifndef STRIPPED
#define UI_PROGRAM_DEFAULT "Untitled" // On brick programming default filename
#define UI_PROGRAM_TEMP "Program" // On brick programming tmp filename
#define UI_PROGRAM_READER "RPGReader" // On brick programming script reader filename
+#endif
+#ifndef STRIPPED
#define UI_DATALOG_FILENAME "OBD_" // On brick datalog filename
#define UI_DATALOG_DEFAULT "Untitled" // On brick datalog default name
#define UI_DATALOG_TEMP "Tmp" // On brick datalog tmp filename
+#endif
#define UI_STARTUP_SOUND "! Startup" // Sound file activated when the menu system starts up
#define UI_KEYCLICK_SOUND "! Click" // Sound file activated when key pressed in the menu system
#define UI_ATTENTION_SOUND "! Attention" // Sound file activated when incomming BT requests attention
+#define UI_STARTUP_PROGRAM "! Startup.rxe" // Program file activated when the NXT boots
// Various text strings
#define UI_NAME_DEFAULT "NXT" // Default blue tooth name
@@ -122,6 +127,7 @@ typedef struct
UBYTE Error; // W - Error code
UBYTE OBPPointer; // W - Actual OBP step (0 - 4)
UBYTE ForceOff; // W - Force off (> 0 = off)
+ UBYTE AbortFlag; // RW - Abort on this button state
}IOMAPUI;
#endif
diff --git a/AT91SAM7S256/Source/d_bt.c b/AT91SAM7S256/Source/d_bt.c
index 6e3e47d..cac6e76 100644
--- a/AT91SAM7S256/Source/d_bt.c
+++ b/AT91SAM7S256/Source/d_bt.c
@@ -56,9 +56,9 @@ void dBtStartADConverter(void)
BTStartADConverter;
}
-void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode)
+void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode, UBYTE NoLengthBytes)
{
- BTInitReceiver(InputBuffer, Mode);
+ BTInitReceiver(InputBuffer, Mode, NoLengthBytes);
}
void dBtSetArm7CmdSignal(void)
@@ -124,12 +124,12 @@ void dBtSend(UBYTE *OutputBuffer, UBYTE BytesToSend)
BTSend(OutputBuffer, BytesToSend);
}
-UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo)
+UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo, UBYTE NoLengthBytes)
{
UWORD RtnVal;
RtnVal = TRUE;
- BTReceivedData(pLength, pBytesToGo);
+ BTReceivedData(pLength, pBytesToGo, NoLengthBytes);
if (*pLength)
{
SETTimeout(0);
diff --git a/AT91SAM7S256/Source/d_bt.h b/AT91SAM7S256/Source/d_bt.h
index baf3ab6..5a5fd97 100644
--- a/AT91SAM7S256/Source/d_bt.h
+++ b/AT91SAM7S256/Source/d_bt.h
@@ -23,7 +23,7 @@ void dBtExit(void);
void dBtStartADConverter(void);
void dBtSetArm7CmdSignal(void);
void dBtClearArm7CmdSignal(void);
-void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode);
+void dBtInitReceive(UBYTE *InputBuffer, UBYTE Mode, UBYTE NoLengthBytes);
void dBtSetBcResetPinLow(void);
void dBtSetBcResetPinHigh(void);
void dBtSendBtCmd(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE *pBdAddr, UBYTE *pName, UBYTE *pCod, UBYTE *pPin);
@@ -33,7 +33,7 @@ void dBtResetTimeOut(void);
void dBtClearTimeOut(void);
UBYTE dBtGetBc4CmdSignal(void);
UWORD dBtTxEnd(void);
-UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo);
+UWORD dBtReceivedData(UWORD *pLength, UWORD *pBytesToGo, UBYTE NoLengthBytes);
UWORD dBtCheckForTxBuf(void);
#endif
diff --git a/AT91SAM7S256/Source/d_bt.r b/AT91SAM7S256/Source/d_bt.r
index 8c9558f..76c079b 100644
--- a/AT91SAM7S256/Source/d_bt.r
+++ b/AT91SAM7S256/Source/d_bt.r
@@ -138,18 +138,25 @@ static UWORD RemainingLength;
*AT91C_PIOA_CODR = BT_RST_PIN; /* PA11 set output low */\
}
-#define BTInitReceiver(InputBuffer, Mode)\
+#define BTInitReceiver(InputBuffer, Mode, noLenBytes)\
{\
pBuffer = InputBuffer;\
MsgIn = 0;\
FullRxLength = 0;\
- if (STREAM_MODE == Mode)\
+ if (noLenBytes)\
{\
- LengthSize = 2;\
+ LengthSize = 0;\
}\
else\
{\
- LengthSize = 1;\
+ if (STREAM_MODE == Mode)\
+ {\
+ LengthSize = 2;\
+ }\
+ else\
+ {\
+ LengthSize = 1;\
+ }\
}\
}
@@ -200,7 +207,7 @@ static UWORD RemainingLength;
OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\
OutDma[DmaBufPtr][1] = (UBYTE)(MsgSize>>8);\
}\
- else\
+ else if (1 == LengthSize)\
{\
OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\
}\
@@ -212,7 +219,7 @@ static UWORD RemainingLength;
}
-#define BTReceivedData(pByteCnt, pToGo)\
+#define BTReceivedData(pByteCnt, pToGo, noLenBytes)\
{\
UWORD InCnt, Cnt;\
*pByteCnt = 0;\
@@ -222,6 +229,11 @@ static UWORD RemainingLength;
{\
InCnt = SIZE_OF_INBUF;\
}\
+ if (noLenBytes)\
+ {\
+ FullRxLength = InCnt;\
+ RemainingLength = InCnt;\
+ }\
InCnt -= InBufOutCnt; /* Remove already read bytes */\
if (InCnt)\
{\
@@ -244,7 +256,7 @@ static UWORD RemainingLength;
/* Remove Length when in strean mode */\
MsgIn = 0;\
}\
- else\
+ else if (1 == LengthSize)\
{\
FullRxLength = pBuffer[0];\
}\
diff --git a/AT91SAM7S256/Source/d_button.r b/AT91SAM7S256/Source/d_button.r
index c478394..1e24b36 100644
--- a/AT91SAM7S256/Source/d_button.r
+++ b/AT91SAM7S256/Source/d_button.r
@@ -40,10 +40,7 @@ static UBYTE RisingTime;
/* And because it's an AD value returned from the AVR */
/* then a peak detector is needed */
#define BUTTONRead(pB) {\
- UBYTE Tmp, BtnPtr;\
- UWORD TmpBtn;\
*pB = OldState;\
- BtnPtr = 0x01;\
if (OldVal < IoFromAvr.Buttons)\
{\
OldVal = IoFromAvr.Buttons;\
@@ -60,27 +57,31 @@ static UBYTE RisingTime;
{\
if (RisingTime > RISING_THRESHOLD)\
{\
- TmpBtn = IoFromAvr.Buttons;\
- if (0x40 > TmpBtn)\
- {\
- TmpBtn = 0x00;\
+ UBYTE Tmp, BtnPtr, TmpBtn;\
+ UWORD buttonsVal;\
+ buttonsVal = IoFromAvr.Buttons;\
+ TmpBtn = 0;\
+ if (buttonsVal > 0x5FF) {\
+ TmpBtn = 0x08;\
+ buttonsVal -= 0x7ff;\
}\
- else if (0x100 > TmpBtn)\
+ if (0x40 > buttonsVal)\
{\
- TmpBtn = 0x04;\
+ TmpBtn |= 0x00;\
}\
- else if (0x1FF > TmpBtn)\
+ else if (0x100 > buttonsVal)\
{\
- TmpBtn = 0x02;\
+ TmpBtn |= 0x04;\
}\
- else if (0x5FF > TmpBtn)\
+ else if (0x1FF > buttonsVal)\
{\
- TmpBtn = 0x01;\
+ TmpBtn |= 0x02;\
}\
- else\
+ else if (0x5FF > buttonsVal)\
{\
- TmpBtn = 0x08;\
+ TmpBtn |= 0x01;\
}\
+ BtnPtr = 0x01;\
for (Tmp = 0; Tmp < NOS_OF_AVR_BTNS; Tmp++)\
{\
if ((TmpBtn) & BtnPtr)\
diff --git a/AT91SAM7S256/Source/d_display.c b/AT91SAM7S256/Source/d_display.c
index 99f16c6..89d22fd 100644
--- a/AT91SAM7S256/Source/d_display.c
+++ b/AT91SAM7S256/Source/d_display.c
@@ -28,11 +28,11 @@ void dDisplayInit(void)
}
-void dDisplayOn(UBYTE On)
+void dDisplayOn(UBYTE On, UBYTE Contrast)
{
if (On)
{
- DISPLAYOn;
+ DISPLAYOn(Contrast);
}
else
{
diff --git a/AT91SAM7S256/Source/d_display.h b/AT91SAM7S256/Source/d_display.h
index a894685..fa04dd3 100644
--- a/AT91SAM7S256/Source/d_display.h
+++ b/AT91SAM7S256/Source/d_display.h
@@ -20,7 +20,7 @@
#define D_DISPLAY
void dDisplayInit(void);
-void dDisplayOn(UBYTE On);
+void dDisplayOn(UBYTE On, UBYTE Contrast);
UBYTE dDisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage);
void dDisplayExit(void);
diff --git a/AT91SAM7S256/Source/d_display.r b/AT91SAM7S256/Source/d_display.r
index e38bb45..81e7078 100644
--- a/AT91SAM7S256/Source/d_display.r
+++ b/AT91SAM7S256/Source/d_display.r
@@ -353,8 +353,8 @@ UBYTE DisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage)
#endif
-#define DISPLAYOn {\
- DisplayInitString[6] = 0x5A;\
+#define DISPLAYOn(c) {\
+ DisplayInitString[6] = (c)&0x7F;\
DisplayInitString[13] = 0xAF;\
}
diff --git a/AT91SAM7S256/Source/d_display2.r b/AT91SAM7S256/Source/d_display2.r
new file mode 100644
index 0000000..71243be
--- /dev/null
+++ b/AT91SAM7S256/Source/d_display2.r
@@ -0,0 +1,388 @@
+//
+// Programmer
+//
+// Date init 14.12.2004
+//
+// Reviser $Author:: Dktochpe $
+//
+// Revision date $Date:: 20-12-05 12:28 $
+//
+// Filename $Workfile:: d_display.r $
+//
+// Version $Revision:: 18 $
+//
+// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_display. $
+//
+// Platform C
+//
+
+#ifdef SAM7S256
+
+// Display 128 x 64
+// 1/65 duty, 1/9 bias
+// VLCD 12.0V
+
+// SPI interface
+//
+// PCB LCD ARM PIO
+// ------ ----- ---- -----
+// CS_DIS -CS1 PA10 NPCS2 (PB)
+// DIS_A0 A0 PA12 PA12
+// DIS_SCL SCL PA14 SPCK (PA)
+// DIS_SDA SI PA13 MOSI (PA)
+
+
+// CPOL = 0, NCPHA=0,
+
+#define BT_RESET_OUT AT91C_PIO_PA11
+#define BT_RESET_IN AT91C_PIO_PA29
+#define BT_MOSI_OUT AT91C_PIO_PA13
+#define BT_MOSI_IN AT91C_PIO_PA20
+#define BT_CLK_OUT AT91C_PIO_PA14
+#define BT_CLK_IN AT91C_PIO_PA28
+#define BT_CE_OUT AT91C_PIO_PA31
+#define BT_CE_IN AT91C_PIO_PA19
+#define BT_REA_OUT AT91C_PIO_PA7
+#define BT_MISO_OUT AT91C_PIO_PA6
+#define BT_MISO_IN AT91C_PIO_PA12
+
+#pragma optimize=s 9
+
+__ramfunc void SpiBtIo(void)
+{
+ register ULONG Port;
+
+ *AT91C_AIC_IDCR = 0xFFFFFFFF; /* Disable all interrupts */
+
+ *AT91C_PIOA_PER = BT_RESET_OUT; /* Enable pin RESET out */
+ *AT91C_PIOA_OER = BT_RESET_OUT; /* Set output */
+ *AT91C_PIOA_SODR = BT_RESET_OUT; /* Set high */
+
+ *AT91C_PIOA_PER = BT_MOSI_OUT; /* Enable pin MOSI out */
+ *AT91C_PIOA_OER = BT_MOSI_OUT; /* Set output */
+
+ *AT91C_PIOA_PER = BT_CLK_OUT; /* Enable pin CLK out */
+ *AT91C_PIOA_OER = BT_CLK_OUT; /* Set output */
+
+ *AT91C_PIOA_PER = BT_CE_OUT; /* Enable pin CE out */
+ *AT91C_PIOA_OER = BT_CE_OUT; /* Set output */
+
+ *AT91C_PIOA_PER = BT_REA_OUT; /* Enable pin REA out */
+ *AT91C_PIOA_OER = BT_REA_OUT; /* Set output */
+ *AT91C_PIOA_SODR = BT_REA_OUT; /* Set high */
+
+ *AT91C_PIOA_PER = BT_MISO_OUT; /* Enable pin MISO out */
+ *AT91C_PIOA_OER = BT_MISO_OUT; /* Set output */
+
+ *AT91C_PIOA_PER = BT_RESET_IN; /* Enable pin RESET in */
+ *AT91C_PIOA_ODR = BT_RESET_IN; /* Set input */
+ *AT91C_PIOA_IFDR = BT_RESET_IN; /* Disable filter */
+ *AT91C_PIOA_IDR = BT_RESET_IN; /* Disable interrupt */
+ *AT91C_PIOA_MDDR = BT_RESET_IN; /* Disable multidriver */
+ *AT91C_PIOA_PPUDR = BT_RESET_IN; /* Disable pullup */
+
+ *AT91C_PIOA_PER = BT_MOSI_IN; /* Enable pin MOSI in */
+ *AT91C_PIOA_ODR = BT_MOSI_IN; /* Set input */
+ *AT91C_PIOA_IFDR = BT_MOSI_IN; /* Disable filter */
+ *AT91C_PIOA_IDR = BT_MOSI_IN; /* Disable interrupt */
+ *AT91C_PIOA_MDDR = BT_MOSI_IN; /* Disable multidriver */
+ *AT91C_PIOA_PPUDR = BT_MOSI_IN; /* Disable pullup */
+
+ *AT91C_PIOA_PER = BT_CLK_IN; /* Enable pin CLK in */
+ *AT91C_PIOA_ODR = BT_CLK_IN; /* Set input */
+ *AT91C_PIOA_IFDR = BT_CLK_IN; /* Disable filter */
+ *AT91C_PIOA_IDR = BT_CLK_IN; /* Disable interrupt */
+ *AT91C_PIOA_MDDR = BT_CLK_IN; /* Disable multidriver */
+ *AT91C_PIOA_PPUDR = BT_CLK_IN; /* Disable pullup */
+
+ *AT91C_PIOA_PER = BT_CE_IN; /* Enable pin CE in */
+ *AT91C_PIOA_ODR = BT_CE_IN; /* Set input */
+ *AT91C_PIOA_IFDR = BT_CE_IN; /* Disable filter */
+ *AT91C_PIOA_IDR = BT_CE_IN; /* Disable interrupt */
+ *AT91C_PIOA_MDDR = BT_CE_IN; /* Disable multidriver */
+ *AT91C_PIOA_PPUDR = BT_CE_IN; /* Disable pullup */
+
+ *AT91C_PIOA_PER = BT_MISO_IN; /* Enable pin MISO in */
+ *AT91C_PIOA_ODR = BT_MISO_IN; /* Set input */
+ *AT91C_PIOA_IFDR = BT_MISO_IN; /* Disable filter */
+ *AT91C_PIOA_IDR = BT_MISO_IN; /* Disable interrupt */
+ *AT91C_PIOA_MDDR = BT_MISO_IN; /* Disable multidriver */
+ *AT91C_PIOA_PPUDR = BT_MISO_IN; /* Disable pullup */
+
+ while (1)
+ {
+ Port = *AT91C_PIOA_PDSR;
+ if ((Port & BT_MISO_IN))
+ {
+ *AT91C_PIOA_SODR = BT_MISO_OUT;
+ }
+ else
+ {
+ *AT91C_PIOA_CODR = BT_MISO_OUT;
+ }
+ if ((Port & BT_MOSI_IN))
+ {
+ *AT91C_PIOA_SODR = BT_MOSI_OUT;
+ }
+ else
+ {
+ *AT91C_PIOA_CODR = BT_MOSI_OUT;
+ }
+ if ((Port & BT_CLK_IN))
+ {
+ *AT91C_PIOA_SODR = BT_CLK_OUT;
+ }
+ else
+ {
+ *AT91C_PIOA_CODR = BT_CLK_OUT;
+ }
+ if ((Port & BT_CE_IN))
+ {
+ *AT91C_PIOA_SODR = BT_CE_OUT;
+ }
+ else
+ {
+ *AT91C_PIOA_CODR = BT_CE_OUT;
+ }
+ }
+
+}
+
+
+void BtIo(void)
+{
+ SpiBtIo();
+}
+
+
+
+#define SPI_BITRATE 2000000
+
+#define SPIA0High {\
+ *AT91C_PIOA_SODR = AT91C_PIO_PA12;\
+ }
+
+
+#define SPIA0Low {\
+ *AT91C_PIOA_CODR = AT91C_PIO_PA12;\
+ }
+
+
+#define SPIInit {\
+ *AT91C_PMC_PCER = (1L << AT91C_ID_SPI); /* Enable MCK clock */\
+ *AT91C_PIOA_PER = AT91C_PIO_PA12; /* Enable A0 on PA12 */\
+ *AT91C_PIOA_OER = AT91C_PIO_PA12;\
+ *AT91C_PIOA_CODR = AT91C_PIO_PA12;\
+ *AT91C_PIOA_PDR = AT91C_PA14_SPCK; /* Enable SPCK on PA14 */\
+ *AT91C_PIOA_ASR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_ODR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_OWER = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_MDDR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_PPUDR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_IFDR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_CODR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_IDR = AT91C_PA14_SPCK;\
+ *AT91C_PIOA_PDR = AT91C_PA13_MOSI; /* Enable mosi on PA13 */\
+ *AT91C_PIOA_ASR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_ODR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_OWER = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_MDDR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_PPUDR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_IFDR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_CODR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_IDR = AT91C_PA13_MOSI;\
+ *AT91C_PIOA_PDR = AT91C_PA10_NPCS2; /* Enable npcs0 on PA11 */\
+ *AT91C_PIOA_BSR = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_ODR = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_OWER = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_MDDR = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_PPUDR = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_IFDR = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_CODR = AT91C_PA10_NPCS2;\
+ *AT91C_PIOA_IDR = AT91C_PA10_NPCS2;\
+ *AT91C_SPI_CR = AT91C_SPI_SWRST; /* Soft reset */\
+ *AT91C_SPI_CR = AT91C_SPI_SPIEN; /* Enable spi */\
+ *AT91C_SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (0xB << 16);\
+ AT91C_SPI_CSR[2] = ((OSC / SPI_BITRATE) << 8) | AT91C_SPI_CPOL;\
+ }
+
+
+#define SPIWrite(pString,Length) {\
+ *AT91C_SPI_TPR = (unsigned int)pString;\
+ *AT91C_SPI_TCR = (unsigned int)Length;\
+ *AT91C_SPI_PTCR = AT91C_PDC_TXTEN;\
+ }
+
+
+
+#define CMD 0
+#define DAT 1
+#define DISP_LINES 8
+
+#if defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4)
+
+#define ACTUAL_WIDTH 100
+
+UBYTE DisplayInitString[] =
+{
+ 0xEB, // LCD bias setting = 1/9 0xEB
+ 0x2F, // Power control = internal 0x2F
+ 0xA4, // All points not on 0xA4
+ 0xA6, // Not inverse 0xA6
+ 0x40, // Start line = 0 0x40
+ 0x81, // Electronic volume 0x81
+ 0x5A, // -"- 0x5F
+ 0xC4, // LCD mapping 0xC4
+ 0x27, // Set temp comp. 0x27-
+ 0x29, // Panel loading 0x28 0-1
+ 0xA0, // Framerate 0xA0-
+ 0x88, // CA++ 0x88-
+ 0x23, // Multiplex 1:65 0x23
+ 0xAF // Display on 0xAF
+};
+
+#else
+
+#define ACTUAL_WIDTH 128
+
+UBYTE DisplayInitString[] =
+{
+ 0xA2, // LCD bias setting = 1/9
+ 0x2F, // Power control = internal
+ 0xA4, // All points not on
+ 0xA6, // Not inverse
+ 0x40, // Start line = 0
+ 0x81, // Electronic volume
+ 0x3F, // -"-
+ 0xA0, // LCD mapping
+ 0x27, // Resistor ratio
+ 0xC8, // Common output state selection
+ 0xF8, // Booster ratio
+ 0x00, // -"-
+ 0xE3, // nop
+ 0xAF // Display on
+};
+
+#endif
+
+UBYTE DisplayLineString[DISP_LINES][3] =
+{
+ { 0xB0,0x10,0x00 },
+ { 0xB1,0x10,0x00 },
+ { 0xB2,0x10,0x00 },
+ { 0xB3,0x10,0x00 },
+ { 0xB4,0x10,0x00 },
+ { 0xB5,0x10,0x00 },
+ { 0xB6,0x10,0x00 },
+ { 0xB7,0x10,0x00 }
+};
+
+UBYTE DisplayWrite(UBYTE Type,UBYTE *pData,UWORD Length)
+{
+ UBYTE Result = FALSE;
+
+ if ((*AT91C_SPI_SR & AT91C_SPI_TXEMPTY))
+ {
+ if (Type)
+ {
+ SPIA0High;
+ }
+ else
+ {
+ SPIA0Low;
+ }
+ SPIWrite(pData,Length);
+ Result = TRUE;
+ }
+
+ return (Result);
+}
+
+UBYTE DisplayUpdate(UWORD Height,UWORD Width,UBYTE *pImage)
+{
+ static UWORD State = 0;
+ static UWORD Line;
+
+ if (State == 0)
+ {
+ if (DisplayWrite(CMD,(UBYTE*)DisplayInitString,sizeof(DisplayInitString)) == TRUE)
+ {
+ Line = 0;
+ State++;
+ }
+ }
+ else
+ {
+ if ((State & 1))
+ {
+ // always write all lines so only use address 0
+ if (DisplayWrite(CMD, (UBYTE*)DisplayLineString[0], 3) == TRUE)
+ State++;
+// if (DisplayWrite(CMD,(UBYTE*)DisplayLineString[Line],3) == TRUE)
+// State++;
+ }
+ else
+ {
+ // write 1056 bytes once rather than 100 bytes 8 times
+ static UBYTE buffer[132*8];
+ UBYTE *pBuf = buffer;
+ while (Line < (Height / 8))
+ {
+ memcpy(pBuf,(UBYTE*)&pImage[Line * Width],ACTUAL_WIDTH);
+ pBuf += 132;
+ Line++;
+ }
+ if (DisplayWrite(DAT,pBuf,132*8) == TRUE)
+ State = 0;
+/*
+ if (DisplayWrite(DAT,(UBYTE*)&pImage[Line * Width],ACTUAL_WIDTH) == TRUE)
+ {
+ State++;
+ if (++Line >= (Height / 8))
+ {
+ State = 0;
+ }
+ }
+*/
+ }
+ }
+
+ return (State);
+}
+
+
+#if defined (PROTOTYPE_PCB_3)
+
+#define DISPLAYInit {\
+ TSTInit;\
+ TSTOn;\
+ SPIInit;\
+ }
+
+#else
+
+#define DISPLAYInit {\
+ SPIInit;\
+ }
+
+#endif
+
+#define DISPLAYOn {\
+ DisplayInitString[6] = 0x5A;\
+ DisplayInitString[13] = 0xAF;\
+ }
+
+#define DISPLAYOff {\
+ DisplayInitString[6] = 0x00;\
+ DisplayInitString[13] = 0xAE;\
+ }
+
+#define DISPLAYUpdate(H,W,I) DisplayUpdate(H,W,I)
+
+#define DISPLAYExit
+
+#endif
+
+#ifdef PCWIN
+
+#endif
diff --git a/AT91SAM7S256/Source/d_hispeed.c b/AT91SAM7S256/Source/d_hispeed.c
index 01f2d07..a764492 100644
--- a/AT91SAM7S256/Source/d_hispeed.c
+++ b/AT91SAM7S256/Source/d_hispeed.c
@@ -17,6 +17,25 @@
#include "d_hispeed.h"
#include "d_hispeed.r"
+const ULONG SPEED_TO_BAUD[16] = {
+ 1200L,
+ 2400L,
+ 3600L,
+ 4800L,
+ 7200L,
+ 9600L,
+ 14400L,
+ 19200L,
+ 28800L,
+ 38400L,
+ 57600L,
+ 76800L,
+ 115200L,
+ 230400L,
+ 460800L,
+ BAUD_RATE
+};
+
void dHiSpeedInit(void)
{
HIGHSPEEDInit;
@@ -27,9 +46,10 @@ void dHiSpeedSendData(UBYTE *OutputBuffer, UBYTE BytesToSend)
HIGHSPEEDSendDmaData(OutputBuffer,BytesToSend);
}
-void dHiSpeedSetupUart(void)
+void dHiSpeedSetupUart(UBYTE speed, UWORD mode)
{
- HIGHSPEEDSetupUart;
+ ULONG baud = SPEED_TO_BAUD[speed];
+ HIGHSPEEDSetupUart(baud, ((unsigned int)mode));
}
void dHiSpeedInitReceive(UBYTE *InputBuffer)
diff --git a/AT91SAM7S256/Source/d_hispeed.h b/AT91SAM7S256/Source/d_hispeed.h
index 669a5d1..b9d8a30 100644
--- a/AT91SAM7S256/Source/d_hispeed.h
+++ b/AT91SAM7S256/Source/d_hispeed.h
@@ -17,7 +17,7 @@
void dHiSpeedInit(void);
void dHiSpeedSendData(UBYTE *OutputBuffer, UBYTE BytesToSend);
-void dHiSpeedSetupUart(void);
+void dHiSpeedSetupUart(UBYTE speed, UWORD mode);
void dHiSpeedInitReceive(UBYTE *InputBuffer);
void dHiSpeedReceivedData(UWORD *ByteCnt);
void dHiSpeedExit(void);
diff --git a/AT91SAM7S256/Source/d_hispeed.r b/AT91SAM7S256/Source/d_hispeed.r
index 52d5e14..949f0f5 100644
--- a/AT91SAM7S256/Source/d_hispeed.r
+++ b/AT91SAM7S256/Source/d_hispeed.r
@@ -52,8 +52,7 @@ static UBYTE InBufOutCnt;
*AT91C_PIOA_CODR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN; /* Set output low */\
}
-
-#define HIGHSPEEDSetupUart {\
+#define HIGHSPEEDSetupUart(_baud, _mode) {\
UBYTE Tmp;\
InBufInPtr = 0;\
for(Tmp = 0; Tmp < NO_OF_INBUFFERS; Tmp++)\
@@ -66,18 +65,16 @@ static UBYTE InBufOutCnt;
*AT91C_PIOA_ASR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN;; /* Enable Per. A on PA5, PA6 & PA7 */\
*AT91C_US0_CR = AT91C_US_RSTSTA; /* Resets pins on UART0 */\
*AT91C_US0_CR = AT91C_US_STTTO; /* Start timeout functionality after 1 byte */\
- *AT91C_US0_RTOR = 2400; /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\
+ *AT91C_US0_RTOR = ((_baud)/400); /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\
*AT91C_US0_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\
*AT91C_AIC_IDCR = UART0_INQ; /* Disable UART0 interrupt */\
*AT91C_AIC_ICCR = UART0_INQ; /* Clear interrupt register */\
*AT91C_US0_MR = AT91C_US_USMODE_RS485; /* Set UART to RUN RS485 Mode*/\
*AT91C_US0_MR &= ~AT91C_US_SYNC; /* Set UART in asynchronous mode */\
*AT91C_US0_MR |= AT91C_US_CLKS_CLOCK; /* Clock setup MCK*/\
- *AT91C_US0_MR |= AT91C_US_CHRL_8_BITS; /* UART using 8-bit */\
- *AT91C_US0_MR |= AT91C_US_PAR_NONE; /* UART using none parity bit */\
- *AT91C_US0_MR |= AT91C_US_NBSTOP_1_BIT; /* UART using 1 stop bit */\
- *AT91C_US0_MR |= AT91C_US_OVER; /* UART is using 8-bit sampling */\
- *AT91C_US0_BRGR = ((OSC/8/BAUD_RATE) | (((OSC/8) - ((OSC/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);\
+ *AT91C_US0_MR |= AT91C_US_OVER; /* UART is using over sampling mode */\
+ *AT91C_US0_MR |= (_mode); /* default is 8n1 */\
+ *AT91C_US0_BRGR = ((OSC/8/(_baud)) | (((OSC/8) - ((OSC/8/(_baud)) * (_baud))) / (((_baud) + 4)/8)) << 16);\
*AT91C_US0_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\
*AT91C_US0_RCR = 0; /* Receive Counter Register */\
*AT91C_US0_TCR = 0; /* Transmit Counter Register */\
diff --git a/AT91SAM7S256/Source/d_loader.c b/AT91SAM7S256/Source/d_loader.c
index a5ceb7d..ae3c54d 100644
--- a/AT91SAM7S256/Source/d_loader.c
+++ b/AT91SAM7S256/Source/d_loader.c
@@ -20,7 +20,7 @@
#include <string.h>
#include <ctype.h>
-#define FILEVERSION (0x0000010DL)
+#define FILEVERSION (0x0000010DL) //(0x0000010CL)
#define MAX_FILES ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/
#define FILEVERSIONINDEX ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/
@@ -72,6 +72,7 @@ UWORD dLoaderAllocateWriteBuffer(UWORD Handle);
UWORD dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData);
UWORD dLoaderGetSectorNumber(ULONG Adr);
void dLoaderCheckVersion(void);
+UWORD dLoaderCheckHandleForReadWrite(UWORD Handle);
UWORD dLoaderCheckHandle(UWORD Handle, UBYTE Operation);
ULONG dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors);
UWORD dLoaderCheckDownload(UBYTE *pName);
@@ -377,6 +378,7 @@ UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearStat
{
Header.DataSize = FileSize;
}
+ HandleTable[Handle].ReadLength = 0;
HandleTable[Handle].FileType = FileType | LinearState; /* if it is a datafile it can be stopped */
Header.FileType = FileType | LinearState; /* FileType included for future appending */
@@ -630,7 +632,7 @@ UWORD dLoaderCloseHandle(UWORD Handle)
UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength)
{
UWORD Handle;
- UBYTE Name[16];
+ UBYTE Name[FILENAME_SIZE];
const FILEHEADER *TmpHeader;
ULONG FileLength;
ULONG DataLength;
@@ -642,7 +644,7 @@ UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength)
{
TmpHeader = (FILEHEADER const *)(FILEPTRTABLE[HandleTable[Handle].FileIndex]);
HandleTable[Handle].pFlash = (const UBYTE *)TmpHeader->FileStartAdr;
- HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable;
+ HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable;
HandleTable[Handle].DataLength = TmpHeader->DataSize;
HandleTable[Handle].ReadLength = 0;
*pLength = TmpHeader->DataSize;
@@ -655,6 +657,82 @@ UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength)
return(Handle);
}
+UWORD dLoaderSeek(UBYTE Handle, SLONG offset, UBYTE from)
+{
+ // move the ReadLength file pointer for this handle to the new offset
+ // and update pFlash appropriately
+ UWORD Status;
+ SLONG distFromStart;
+ const FILEHEADER *TmpHeader;
+
+ Status = dLoaderCheckHandleForReadWrite(Handle);
+ if (0x8000 > Status)
+ {
+ Status = Handle;
+ // calculate distance from start regardless of "from"
+ // and start from there going forward unless distance > current
+ // in which case start from current going forward
+ switch (from) {
+ case SEEK_FROMSTART:
+ distFromStart = offset;
+ break;
+ case SEEK_FROMCURRENT:
+ distFromStart = (SLONG)HandleTable[Handle].ReadLength + offset;
+ break;
+ case SEEK_FROMEND:
+ distFromStart = (SLONG)HandleTable[Handle].DataLength + offset;
+ break;
+ }
+ if (distFromStart != HandleTable[Handle].ReadLength) {
+ if ((distFromStart < 0) || (distFromStart > HandleTable[Handle].DataLength))
+ return (Status | INVALIDSEEK);
+ if (distFromStart < HandleTable[Handle].ReadLength) {
+ // start from the beginning in this case
+ TmpHeader = (FILEHEADER const *)(FILEPTRTABLE[HandleTable[Handle].FileIndex]);
+ HandleTable[Handle].pFlash = (const UBYTE *)TmpHeader->FileStartAdr;
+ HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable;
+ HandleTable[Handle].ReadLength = 0;
+ }
+ else
+ distFromStart -= HandleTable[Handle].ReadLength; // dist from current
+ // now move forward from the current location
+ while (distFromStart > 0) {
+ distFromStart--;
+ // move to next byte in the flash
+ HandleTable[Handle].pFlash++;
+ // update our file pointer
+ HandleTable[Handle].ReadLength++;
+ // if we reach a flash sector boundary then find the next sector pointer
+ if (!((ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE-1)))
+ {
+ HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle);
+ }
+ }
+ // if we are open for writing then we need to do a little more work
+ if (HandleTable[Handle].Status == DOWNLOADING)
+ {
+ // open for writing
+ WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = (ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE - 1);
+ memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (const UBYTE *)((ULONG)(HandleTable[Handle].pFlash) & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex );
+ }
+ }
+ }
+ return(Status);
+}
+
+UWORD dLoaderTell(UBYTE Handle, ULONG* filePos)
+{
+ UWORD Status;
+
+ Status = dLoaderCheckHandleForReadWrite(Handle);
+ if (0x8000 > Status)
+ {
+ Status = Handle;
+ *filePos = HandleTable[Handle].ReadLength;
+ }
+ return(Status);
+}
+
UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuffer, ULONG *pLength)
{
UWORD ByteCnt, Status;
@@ -668,16 +746,21 @@ UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuffer, ULONG *pLength)
{
if (HandleTable[Handle].DataLength <= HandleTable[Handle].ReadLength)
{
+ // if the file pointer (ReadLength) is >= file size then return EOF
*pLength = ByteCnt;
Status |= ENDOFFILE;
}
else
{
+ // copy a byte at a time from pFlash to pBuffer
*pBuffer = *(HandleTable[Handle].pFlash);
pBuffer++;
ByteCnt++;
+ // move to next byte in the flash
HandleTable[Handle].pFlash++;
+ // update our file pointer
HandleTable[Handle].ReadLength++;
+ // if we reach a flash sector boundary then find the next sector pointer
if (!((ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE-1)))
{
HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle);
@@ -693,7 +776,7 @@ UWORD dLoaderDelete(UBYTE *pFile)
UWORD LStatus;
ULONG FileLength;
ULONG DataLength;
- UBYTE Name[FILENAME_LENGTH + 1];
+ UBYTE Name[FILENAME_SIZE];
LStatus = dLoaderFind(pFile, Name, &FileLength, &DataLength, (UBYTE)BUSY);
@@ -1206,6 +1289,7 @@ UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize)
HandleTable[Handle].Status = (UBYTE)DOWNLOADING;
*pAvailSize = FileSize - DataSize;
HandleTable[Handle].DataLength = *pAvailSize;
+ HandleTable[Handle].ReadLength = DataSize;
HandleTable[Handle].FileType = pHeader->FileType;
}
}
@@ -1378,6 +1462,23 @@ void dLoaderInsertSearchStr(UBYTE *pDst, UBYTE *pSrc, UBYTE *pSearchType)
}
}
+UWORD dLoaderCheckHandleForReadWrite(UWORD Handle)
+{
+ if (MAX_HANDLES > Handle)
+ {
+ if ((DOWNLOADING != HandleTable[(UBYTE)Handle].Status) &&
+ (BUSY != HandleTable[(UBYTE)Handle].Status))
+ {
+ Handle |= ILLEGALHANDLE;
+ }
+ }
+ else
+ {
+ Handle |= ILLEGALHANDLE;
+ }
+ return(Handle);
+}
+
UWORD dLoaderCheckHandle(UWORD Handle, UBYTE Operation)
{
diff --git a/AT91SAM7S256/Source/d_loader.h b/AT91SAM7S256/Source/d_loader.h
index 902c7f7..d550fa8 100644
--- a/AT91SAM7S256/Source/d_loader.h
+++ b/AT91SAM7S256/Source/d_loader.h
@@ -19,7 +19,11 @@
#define STARTOFFILETABLE (0x140000L - (FILETABLE_SIZE*4))
#define FILEPTRTABLE ((const ULONG*)(0x140000L - (FILETABLE_SIZE*4)))
#ifndef STARTOFUSERFLASH_FROM_LINKER
-#define STARTOFUSERFLASH (0x122100L)
+#ifndef STRIPPED
+#define STARTOFUSERFLASH (0x125800L)//(0x124600L) 1.31 == (0x122100L)
+#else
+#define STARTOFUSERFLASH (0x122400L)//(0x124600L) 1.31 == (0x122100L)
+#endif
#define SIZEOFUSERFLASH_MAX SIZEOFUSERFLASH
#else
extern char __STARTOFUSERFLASH_FROM_LINKER;
@@ -66,6 +70,14 @@ enum
NONLINEAR = 0x08
};
+/* Enum related to seek operation */
+enum
+{
+ SEEK_FROMSTART,
+ SEEK_FROMCURRENT,
+ SEEK_FROMEND
+};
+
typedef struct
{
UBYTE FileName[FILENAME_SIZE];
@@ -84,6 +96,8 @@ UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearStat
UWORD dLoaderWriteData(UWORD Handle, UBYTE *pBuf, UWORD *pLen);
UWORD dLoaderCloseHandle(UWORD Handle);
UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength);
+UWORD dLoaderSeek(UBYTE Handle, SLONG offset, UBYTE from);
+UWORD dLoaderTell(UBYTE Handle, ULONG* filePos);
UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuf, ULONG *pLength);
UWORD dLoaderDelete(UBYTE *pFile);
UWORD dLoaderFind(UBYTE *pFind, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength, UBYTE Session);
diff --git a/AT91SAM7S256/Source/d_lowspeed.c b/AT91SAM7S256/Source/d_lowspeed.c
index 91c1341..bb4f699 100644
--- a/AT91SAM7S256/Source/d_lowspeed.c
+++ b/AT91SAM7S256/Source/d_lowspeed.c
@@ -48,9 +48,9 @@ UBYTE dLowSpeedSendData(UBYTE ChannelNumber, UBYTE *DataOutBuffer, UBYTE NumberO
return(Status);
}
-void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx)
+void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx, UBYTE NoRestart)
{
- RxData(ChannelNumber, DataInBuffer, ByteToRx);
+ RxData(ChannelNumber, DataInBuffer, ByteToRx, NoRestart);
}
UBYTE dLowSpeedComTxStatus(UBYTE ChannelNumber)
diff --git a/AT91SAM7S256/Source/d_lowspeed.h b/AT91SAM7S256/Source/d_lowspeed.h
index 6ec62fd..3c916c3 100644
--- a/AT91SAM7S256/Source/d_lowspeed.h
+++ b/AT91SAM7S256/Source/d_lowspeed.h
@@ -20,7 +20,7 @@ void dLowSpeedStartTimer(void);
void dLowSpeedStopTimer(void);
void dLowSpeedInitPins(UBYTE ChannelNumber);
UBYTE dLowSpeedSendData(UBYTE ChannelNumber, UBYTE *DataOutBuffer, UBYTE NumberOfTxByte);
-void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx);
+void dLowSpeedReceiveData(UBYTE ChannelNumber, UBYTE *DataInBuffer, UBYTE ByteToRx, UBYTE NoRestart);
UBYTE dLowSpeedComTxStatus(UBYTE ChannelNumber);
UBYTE dLowSpeedComRxStatus(UBYTE ChannelNumber);
void dLowSpeedExit(void);
diff --git a/AT91SAM7S256/Source/d_lowspeed.r b/AT91SAM7S256/Source/d_lowspeed.r
index 279c10e..9741f0c 100644
--- a/AT91SAM7S256/Source/d_lowspeed.r
+++ b/AT91SAM7S256/Source/d_lowspeed.r
@@ -173,12 +173,12 @@ ULONG CLK_PINS[4] = {CHANNEL_ONE_CLK, CHANNEL_TWO_CLK, CHANNEL_THREE_CLK, CHANNE
#define GetClkPinLevel(ChannelNr) (*AT91C_PIOA_PDSR & CLK_PINS[ChannelNr])
#define GetDataPinLevel(ChannelNr) (*AT91C_PIOA_PDSR & DATA_PINS[ChannelNr])
-#define ENABLEPWMTimerForLowCom {\
- *AT91C_PWMC_ENA = AT91C_PWMC_CHID0; /* Enable PWM output channel 0 */\
+#define ENABLEPWMTimerForLowCom {\
+ *AT91C_PWMC_ENA = AT91C_PWMC_CHID0; /* Enable PWM output channel 0 */\
}
-#define DISABLEPWMTimerForLowCom {\
- *AT91C_PWMC_DIS = AT91C_PWMC_CHID0; /* Disable PWM output channel 0 */\
+#define DISABLEPWMTimerForLowCom {\
+ *AT91C_PWMC_DIS = AT91C_PWMC_CHID0; /* Disable PWM output channel 0 */\
}
#define OLD_DISABLEPWMTimerForLowCom {\
@@ -231,6 +231,7 @@ __ramfunc void LowSpeedPwmIrqHandler(void)
case TX_DATA_CLK_HIGH:
{
SETClkLow(ChannelNr);
+ for (int a=0; a<60; a++); // let the line settle
if (LowSpeedData[ChannelNr].MaskBit == 0) //Is Byte Done, then we need a ack from receiver
{
SETDataToInput(ChannelNr); //Set datapin to input
@@ -530,13 +531,13 @@ __ramfunc void LowSpeedPwmIrqHandler(void)
}\
}
-#define RxData(ChannelNumber, DataInBuffer, RxBytes) {\
- LowSpeedData[ChannelNumber].pComInBuffer = DataInBuffer;\
- LowSpeedData[ChannelNumber].RxBitCnt = 0;\
- LowSpeedData[ChannelNumber].RxByteCnt = RxBytes;\
- LowSpeedData[ChannelNumber].RxState = RX_DATA_CLK_LOW;\
- LowSpeedData[ChannelNumber].ReStartBit = 1;\
- LowSpeedData[ChannelNumber].RxWaitCnt = 0;\
+#define RxData(ChannelNumber, DataInBuffer, RxBytes, NoRestart) {\
+ LowSpeedData[ChannelNumber].pComInBuffer = DataInBuffer;\
+ LowSpeedData[ChannelNumber].RxBitCnt = 0;\
+ LowSpeedData[ChannelNumber].RxByteCnt = RxBytes;\
+ LowSpeedData[ChannelNumber].RxState = RX_DATA_CLK_LOW;\
+ LowSpeedData[ChannelNumber].ReStartBit = (1 - (NoRestart & (1<<ChannelNumber)));\
+ LowSpeedData[ChannelNumber].RxWaitCnt = 0;\
}
diff --git a/AT91SAM7S256/Source/d_output.c b/AT91SAM7S256/Source/d_output.c
index 326f6f8..8e5c904 100644
--- a/AT91SAM7S256/Source/d_output.c
+++ b/AT91SAM7S256/Source/d_output.c
@@ -45,6 +45,9 @@ void dOutputSpeedFilter(UBYTE MotorNr, SLONG PositionDiff);
#define ABS(a) (((a) < 0) ? -(a) : (a))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define OPTION_HOLDATLIMIT 0x10
+#define OPTION_RAMPDOWNTOLIMIT 0x20
+
typedef struct
{
SBYTE MotorSetSpeed; // Motor setpoint in speed
@@ -77,6 +80,10 @@ typedef struct
SWORD SpeedFracError; // Fractionnal speed error of last speed update
SBYTE MotorMaxSpeed; // For absolute regulation, maximum motor speed
SBYTE MotorMaxAcceleration; // For absolute regulation, maximum motor acceleration
+ UBYTE RunStateAtLimit; // what run state to switch to when tacho limit is reached
+ UBYTE RampDownToLimit;
+ UBYTE Spare2;
+ UBYTE Spare3;
}MOTORDATA;
typedef struct
@@ -92,6 +99,25 @@ static SYNCMOTORDATA SyncData;
static UBYTE RegulationTime;
static UBYTE RegulationOptions;
+UBYTE dOutputRunStateAtLimit(MOTORDATA * pMD)
+{
+// return MOTOR_RUN_STATE_IDLE;
+ return pMD->RunStateAtLimit;
+}
+
+UBYTE dOutputRampDownToLimit(MOTORDATA * pMD)
+{
+// return 0;
+ return pMD->RampDownToLimit;
+}
+
+UBYTE dOutputRegModeAtLimit(MOTORDATA * pMD)
+{
+ if (dOutputRunStateAtLimit(pMD)==MOTOR_RUN_STATE_HOLD)
+ return REGSTATE_REGULATED;
+ return REGSTATE_IDLE;
+}
+
void dOutputInit(void)
{
UBYTE Temp;
@@ -100,6 +126,8 @@ void dOutputInit(void)
ENABLECaptureMotorA;
ENABLECaptureMotorB;
ENABLECaptureMotorC;
+
+ RegulationTime = REGULATION_TIME;
for (Temp = 0; Temp < 3; Temp++)
{
@@ -122,12 +150,14 @@ void dOutputInit(void)
pMD->MotorMaxAcceleration = DEFAULT_MAX_ACCELERATION;
pMD->RegulationMode = 0;
pMD->MotorOverloaded = 0;
+ pMD->RunStateAtLimit = MOTOR_RUN_STATE_IDLE;
+ pMD->RampDownToLimit = 0;
INSERTMode(Temp, COAST_MOTOR_MODE);
INSERTSpeed(Temp, pMD->MotorSetSpeed);
}
}
-/* This function is called every 1 mS and will go through all the motors and there dependencies */
+/* This function is called every 1 mS and will go through all the motors and their dependencies */
/* Actual motor speed is only passed (updated) to the AVR controller form this function */
/* DeltacaptureCount used to count number of Tachocount within last 100 mS. Used with position control regulation */
/* CurrentCaptureCount used to tell total current position. Used to tell when movement has been obtained */
@@ -316,7 +346,7 @@ void dOutputSetRegulationOptions(UBYTE NewRegulationOptions)
/* Called to set TachoCountToRun which is used for position control for the model */
/* Must be called before motor start */
/* TachoCountToRun is calculated as a signed value */
-void dOutputSetTachoLimit(UBYTE MotorNr, ULONG BlockTachoCntToTravel)
+void dOutputSetTachoLimit(UBYTE MotorNr, ULONG BlockTachoCntToTravel, UBYTE Options)
{
MOTORDATA * pMD = &(MotorData[MotorNr]);
if (pMD->RegulationMode & REGSTATE_POSITION)
@@ -327,10 +357,14 @@ void dOutputSetTachoLimit(UBYTE MotorNr, ULONG BlockTachoCntToTravel)
else if (BlockTachoCntToTravel == 0)
{
pMD->MotorRunForever = 1;
+ pMD->RunStateAtLimit = MOTOR_RUN_STATE_IDLE;
+ pMD->RampDownToLimit = 0;
}
else
{
pMD->MotorRunForever = 0;
+ pMD->RunStateAtLimit = (Options & OPTION_HOLDATLIMIT) ? MOTOR_RUN_STATE_HOLD : MOTOR_RUN_STATE_IDLE;
+ pMD->RampDownToLimit = Options & OPTION_RAMPDOWNTOLIMIT;
if (pMD->MotorSetSpeed == 0)
{
@@ -562,7 +596,7 @@ void dOutputRampUpFunction(UBYTE MotorNr)
if ((pMD->CurrentCaptureCount - pMD->MotorRampTachoCountStart) >= (pMD->MotorTachoCountToRun - pMD->MotorRampTachoCountStart))
{
pMD->MotorTargetSpeed = pMD->MotorSetSpeed;
- pMD->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pMD->MotorRunState = dOutputRunStateAtLimit(pMD);
}
}
else
@@ -570,7 +604,7 @@ void dOutputRampUpFunction(UBYTE MotorNr)
if ((pMD->CurrentCaptureCount + pMD->MotorRampTachoCountStart) <= (pMD->MotorTachoCountToRun + pMD->MotorRampTachoCountStart))
{
pMD->MotorTargetSpeed = pMD->MotorSetSpeed;
- pMD->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pMD->MotorRunState = dOutputRunStateAtLimit(pMD);
}
}
if (pMD->MotorSetSpeed > 0)
@@ -679,7 +713,7 @@ void dOutputRampDownFunction(UBYTE MotorNr)
if ((pMD->RegulationMode & REGSTATE_SYNCHRONE) && (pMD->TurnParameter != 0))
{
dOutputSyncTachoLimitControl(MotorNr);
- if (pMD->MotorRunState == MOTOR_RUN_STATE_IDLE)
+ if (pMD->MotorRunState == dOutputRunStateAtLimit(pMD))
{
dOutputMotorReachedTachoLimit(MotorNr);
}
@@ -724,22 +758,47 @@ void dOutputTachoLimitControl(UBYTE MotorNr)
}
else
{
- if (pMD->MotorSetSpeed > 0)
+ if (dOutputRampDownToLimit(pMD) == 0)
{
- if ((pMD->CurrentCaptureCount >= pMD->MotorTachoCountToRun))
+ if (pMD->MotorSetSpeed > 0)
+ {
+ if ((pMD->CurrentCaptureCount >= pMD->MotorTachoCountToRun))
+ {
+ pMD->MotorRunState = dOutputRunStateAtLimit(pMD);
+ pMD->RegulationMode = dOutputRegModeAtLimit(pMD);
+ }
+ }
+ else
{
- pMD->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pMD->RegulationMode = REGSTATE_IDLE;
+ if (pMD->MotorSetSpeed < 0)
+ {
+ if (pMD->CurrentCaptureCount <= pMD->MotorTachoCountToRun)
+ {
+ pMD->MotorRunState = dOutputRunStateAtLimit(pMD);
+ pMD->RegulationMode = dOutputRegModeAtLimit(pMD);
+ }
+ }
}
}
else
{
- if (pMD->MotorSetSpeed < 0)
+ if (pMD->MotorSetSpeed > 0)
+ {
+ if ((pMD->CurrentCaptureCount >= (SLONG)((float)pMD->MotorTachoCountToRun * (float)0.80)))
+ {
+ pMD->MotorRunState = MOTOR_RUN_STATE_RAMPDOWN;
+ pMD->MotorSetSpeed = 0;
+ }
+ }
+ else
{
- if (pMD->CurrentCaptureCount <= pMD->MotorTachoCountToRun)
+ if (pMD->MotorSetSpeed < 0)
{
- pMD->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pMD->RegulationMode = REGSTATE_IDLE;
+ if (pMD->CurrentCaptureCount <= (SLONG)((float)pMD->MotorTachoCountToRun * (float)0.80))
+ {
+ pMD->MotorRunState = MOTOR_RUN_STATE_RAMPDOWN;
+ pMD->MotorSetSpeed = 0;
+ }
}
}
}
@@ -1134,15 +1193,15 @@ void dOutputMotorReachedTachoLimit(UBYTE MotorNr)
pOne->MotorSetSpeed = 0;
pOne->MotorTargetSpeed = 0;
pOne->MotorActualSpeed = 0;
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pOne->RegulationMode = REGSTATE_IDLE;
+ pOne->MotorRunState = dOutputRunStateAtLimit(pOne);
+ pOne->RegulationMode = dOutputRegModeAtLimit(pOne);
if (MotorTwo != 0xFF) {
MOTORDATA * pTwo = &(MotorData[MotorTwo]);
pTwo->MotorSetSpeed = 0;
pTwo->MotorTargetSpeed = 0;
pTwo->MotorActualSpeed = 0;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->RegulationMode = REGSTATE_IDLE;
+ pTwo->MotorRunState = dOutputRunStateAtLimit(pTwo);
+ pTwo->RegulationMode = dOutputRegModeAtLimit(pTwo);
}
}
else
@@ -1152,8 +1211,8 @@ void dOutputMotorReachedTachoLimit(UBYTE MotorNr)
pOne->MotorTargetSpeed = 0;
pOne->MotorActualSpeed = 0;
}
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pOne->RegulationMode = REGSTATE_IDLE;
+ pOne->MotorRunState = dOutputRunStateAtLimit(pOne);
+ pOne->RegulationMode = dOutputRegModeAtLimit(pOne);
}
}
@@ -1183,30 +1242,44 @@ void dOutputSyncTachoLimitControl(UBYTE MotorNr)
{
MOTORDATA * pOne = &(MotorData[MotorOne]);
MOTORDATA * pTwo = &(MotorData[MotorTwo]);
+ SLONG l1 = pOne->MotorTachoCountToRun;
+ SLONG l2 = pTwo->MotorTachoCountToRun;
+ UBYTE NewRunState1 = dOutputRunStateAtLimit(pOne);
+ UBYTE NewRunState2 = dOutputRunStateAtLimit(pTwo);
+ if (dOutputRampDownToLimit(pOne) == OPTION_RAMPDOWNTOLIMIT)
+ {
+ NewRunState1 = MOTOR_RUN_STATE_RAMPDOWN;
+ l1 = (SLONG)((float)l1 * 0.80f);
+ }
+ if (dOutputRampDownToLimit(pTwo) == OPTION_RAMPDOWNTOLIMIT)
+ {
+ NewRunState2 = MOTOR_RUN_STATE_RAMPDOWN;
+ l2 = (SLONG)((float)l2 * 0.80f);
+ }
if (pOne->TurnParameter != 0)
{
if (pOne->TurnParameter > 0)
{
if (pTwo->MotorTargetSpeed >= 0)
{
- if ((SLONG)(pTwo->CurrentCaptureCount >= pTwo->MotorTachoCountToRun))
+ if ((SLONG)(pTwo->CurrentCaptureCount >= l2))
{
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pOne->MotorRunState = NewRunState1;
+ pTwo->MotorRunState = NewRunState2;
pOne->CurrentCaptureCount = pTwo->CurrentCaptureCount;
- pOne->MotorTachoCountToRun = pTwo->MotorTachoCountToRun;
+ pOne->MotorTachoCountToRun = l2;
}
}
else
{
- if ((SLONG)(pOne->CurrentCaptureCount <= pOne->MotorTachoCountToRun))
+ if ((SLONG)(pOne->CurrentCaptureCount <= l1))
{
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pOne->MotorRunState = NewRunState1;
+ pTwo->MotorRunState = NewRunState2;
pTwo->CurrentCaptureCount = pOne->CurrentCaptureCount;
- pTwo->MotorTachoCountToRun = pOne->MotorTachoCountToRun;
+ pTwo->MotorTachoCountToRun = l1;
}
}
}
@@ -1214,46 +1287,47 @@ void dOutputSyncTachoLimitControl(UBYTE MotorNr)
{
if (pOne->MotorTargetSpeed >= 0)
{
- if ((SLONG)(pOne->CurrentCaptureCount >= pOne->MotorTachoCountToRun))
+ if ((SLONG)(pOne->CurrentCaptureCount >= l1))
{
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pOne->MotorRunState = NewRunState1;
+ pTwo->MotorRunState = NewRunState2;
pTwo->CurrentCaptureCount = pOne->CurrentCaptureCount;
- pTwo->MotorTachoCountToRun = pOne->MotorTachoCountToRun;
+ pTwo->MotorTachoCountToRun = l1;
}
}
else
{
- if ((SLONG)(pTwo->CurrentCaptureCount <= pTwo->MotorTachoCountToRun))
+ if ((SLONG)(pTwo->CurrentCaptureCount <= l2))
{
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pOne->MotorRunState = NewRunState1;
+ pTwo->MotorRunState = NewRunState2;
pOne->CurrentCaptureCount = pTwo->CurrentCaptureCount;
- pOne->MotorTachoCountToRun = pTwo->MotorTachoCountToRun;
+ pOne->MotorTachoCountToRun = l2;
}
}
}
}
else
{
+ // no turning
if (pOne->MotorSetSpeed > 0)
{
- if ((pOne->CurrentCaptureCount >= pOne->MotorTachoCountToRun) || (pTwo->CurrentCaptureCount >= pTwo->MotorTachoCountToRun))
+ if ((pOne->CurrentCaptureCount >= l1) || (pTwo->CurrentCaptureCount >= l2))
{
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pOne->MotorRunState = NewRunState1;
+ pTwo->MotorRunState = NewRunState2;
}
}
else
{
if (pOne->MotorSetSpeed < 0)
{
- if ((pOne->CurrentCaptureCount <= pOne->MotorTachoCountToRun) || (pTwo->CurrentCaptureCount <= pTwo->MotorTachoCountToRun))
+ if ((pOne->CurrentCaptureCount <= l1) || (pTwo->CurrentCaptureCount <= l2))
{
- pOne->MotorRunState = MOTOR_RUN_STATE_IDLE;
- pTwo->MotorRunState = MOTOR_RUN_STATE_IDLE;
+ pOne->MotorRunState = NewRunState1;
+ pTwo->MotorRunState = NewRunState2;
}
}
}
diff --git a/AT91SAM7S256/Source/d_output.h b/AT91SAM7S256/Source/d_output.h
index 4d5189b..d06b1b5 100644
--- a/AT91SAM7S256/Source/d_output.h
+++ b/AT91SAM7S256/Source/d_output.h
@@ -77,7 +77,7 @@ void dOutputSetMode(UBYTE MotorNr, UBYTE Mode);
void dOutputSetSpeed (UBYTE MotorNr, UBYTE NewMotorRunState, SBYTE Speed, SBYTE TurnParameter);
void dOutputEnableRegulation(UBYTE MotorNr, UBYTE RegulationMode);
void dOutputDisableRegulation(UBYTE MotorNr);
-void dOutputSetTachoLimit(UBYTE MotorNr, ULONG TachoCntToTravel);
+void dOutputSetTachoLimit(UBYTE MotorNr, ULONG TachoCntToTravel, UBYTE Options);
void dOutputResetTachoLimit(UBYTE MotorNr);
void dOutputResetBlockTachoLimit(UBYTE MotorNr);
void dOutputResetRotationCaptureCount(UBYTE MotorNr);
@@ -99,5 +99,6 @@ void dOutputMotorIdleControl(UBYTE MotorNr);
void dOutputSyncTachoLimitControl(UBYTE MotorNr);
void dOutputMotorSyncStatus(UBYTE MotorNr, UBYTE *SyncMotorOne, UBYTE *SyncMotorTwo);
void dOutputResetSyncMotors(UBYTE MotorNr);
+void dOutputUpdateRegulationTime(UBYTE rt);
#endif
diff --git a/AT91SAM7S256/Source/modules.h b/AT91SAM7S256/Source/modules.h
index a5f3bb1..14a1780 100644
--- a/AT91SAM7S256/Source/modules.h
+++ b/AT91SAM7S256/Source/modules.h
@@ -66,7 +66,8 @@ enum
FILETX_DSTEXISTS = 0x9800,
FILETX_SRCMISSING = 0x9900,
FILETX_STREAMERROR = 0x9A00,
- FILETX_CLOSEERROR = 0x9B00
+ FILETX_CLOSEERROR = 0x9B00,
+ INVALIDSEEK = 0x9C00
};