Browse Source

Merge branch 'develop'

Wilfried Klaas 3 years ago
parent
commit
b3f01c715a
12 changed files with 1691 additions and 391 deletions
  1. 7 15
      Beispiele/Tone.tps
  2. 4 0
      README.md
  3. 4 4
      SPS_EMU.000
  4. 39 6
      SPS_Emu.lpi
  5. 3 1
      SPS_Emu.lpr
  6. BIN
      SPS_Emu.lsu
  7. 358 294
      ugui.lfm
  8. 169 31
      ugui.pas
  9. 386 0
      uimicrobit.lfm
  10. 131 0
      uimicrobit.pas
  11. 404 0
      umicrobit.pas
  12. 186 40
      usps.pas

+ 7 - 15
Beispiele/Tone.tps

@@ -1,15 +1,7 @@
-#TPS:Willies SPS Arduino
-0x00,4,3,""
-0x01,5,1,""
-0x02,4,0,""
-0x03,7,C,""
-0x04,F,8,""
-0x05,2,9,""
-0x06,4,0,""
-0x07,5,1,""
-0x08,4,0,""
-0x09,7,C,""
-0x0A,F,8,""
-0x0B,2,8,""
-0x0C,3,C,""
-0x0D,0,0,""
+#TPS:BBC micro:bit V2
+0x00,4,0,""
+0x01,0,3,""
+0x02,7,1,""
+0x03,2,6,""
+0x04,3,3,""
+0x05,F,F,""

+ 4 - 0
README.md

@@ -1,4 +1,8 @@
 # **SPS_Emulator Version History**
+**08.04.2021 Version 0.2.1.80**
+
+  * Feature: upload activating for BBC micro:bit V2 via serial connection. 
+
 **01.04.2021 Version 0.2.1.78**
 
   * BUG: fixing upload activating for BBC micro:bit. 

+ 4 - 4
SPS_EMU.000

@@ -2,9 +2,9 @@
 LSUTextFile=1
 Copyrigth=MCS Media Computer Software
 [LSUInfo]
-CompileDate=01.04.2021
-CompileTime=07:50:52
+CompileDate=09.05.2021
+CompileTime=14:46:27
 Name=Wilfried Klaas
-LSUBinFile=H:\privat\git-sourcen\SPS_Emulator\SPS_Emu.lsu
-LSUTextFile=H:\privat\git-sourcen\SPS_Emulator\SPS_Emu.
+LSUBinFile=C:\e-platte\daten\git-sourcen\SPS_Emulator\SPS_Emu.lsu
+LSUTextFile=C:\e-platte\daten\git-sourcen\SPS_Emulator\SPS_Emu.
 RegString=

+ 39 - 6
SPS_Emu.lpi

@@ -22,7 +22,7 @@
       <AutoIncrementBuild Value="True"/>
       <MinorVersionNr Value="2"/>
       <RevisionNr Value="1"/>
-      <BuildNr Value="78"/>
+      <BuildNr Value="86"/>
       <Language Value="0407"/>
       <StringTable CompanyName="MCS" FileDescription="TPS/SPS Emulator" InternalName="SPS_EMU" LegalCopyright="MCS (C) Wilfried Klaas" OriginalFilename="SPS_EMU.exe" ProductName="TPS/SPS Emulator" ProductVersion="0.2"/>
     </VersionInfo>
@@ -56,15 +56,18 @@
         </Mode0>
       </Modes>
     </RunParams>
-    <RequiredPackages Count="2">
+    <RequiredPackages Count="3">
       <Item1>
-        <PackageName Value="SdpoSerialLaz"/>
+        <PackageName Value="laz_synapse"/>
       </Item1>
       <Item2>
-        <PackageName Value="LCL"/>
+        <PackageName Value="SdpoSerialLaz"/>
       </Item2>
+      <Item3>
+        <PackageName Value="LCL"/>
+      </Item3>
     </RequiredPackages>
-    <Units Count="7">
+    <Units Count="10">
       <Unit0>
         <Filename Value="SPS_Emu.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -111,6 +114,25 @@
         <IsPartOfProject Value="True"/>
         <UnitName Value="MCSLSU"/>
       </Unit6>
+      <Unit7>
+        <Filename Value="umicrobit.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="uMicrobit"/>
+      </Unit7>
+      <Unit8>
+        <Filename Value="uimicrobit.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="fMicrobit"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+        <UnitName Value="uiMicrobit"/>
+      </Unit8>
+      <Unit9>
+        <Filename Value="userui.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="Form3"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit9>
     </Units>
   </ProjectOptions>
   <CompilerOptions>
@@ -136,9 +158,14 @@
         </Win32>
       </Options>
     </Linking>
+    <Other>
+      <ExecuteAfter>
+        <Command Value="C:\e-platte\daten\git-sourcen\LCC_Compiler\lcc.exe /B /C /Q &quot;$TargetFile()&quot;"/>
+      </ExecuteAfter>
+    </Other>
   </CompilerOptions>
   <Debugging>
-    <Exceptions Count="5">
+    <Exceptions Count="7">
       <Item1>
         <Name Value="EAbort"/>
       </Item1>
@@ -154,6 +181,12 @@
       <Item5>
         <Name Value="EScannerError"/>
       </Item5>
+      <Item6>
+        <Name Value="RunError(103)"/>
+      </Item6>
+      <Item7>
+        <Name Value="EInOutError"/>
+      </Item7>
     </Exceptions>
   </Debugging>
 </CONFIG>

+ 3 - 1
SPS_Emu.lpr

@@ -7,7 +7,8 @@ uses
   cthreads,
   {$ENDIF}{$ENDIF}
   Interfaces, // this includes the LCL widgetset
-  Forms, sdposeriallaz, uGUI, uSPS, uTextUi, uSelectCom, MCSLSU, MCSAbout;
+  Forms, sdposeriallaz, uGUI, uSPS, uTextUi, uSelectCom, MCSLSU, MCSAbout,
+  uiMicrobit;
 
 {$R *.res}
 
@@ -22,6 +23,7 @@ begin
   Application.CreateForm(TForm1, Form1);
   Application.CreateForm(TForm2, Form2);
   Application.CreateForm(TfrmSelectCom, frmSelectCom);
+  Application.CreateForm(TfMicrobit, fMicrobit);
   Application.Run;
 end.
 

BIN
SPS_Emu.lsu


File diff suppressed because it is too large
+ 358 - 294
ugui.lfm


+ 169 - 31
ugui.pas

@@ -165,6 +165,7 @@ type
     procedure cbCommandChange(Sender: TObject);
     procedure cbDataChange(Sender: TObject);
     procedure cbTPSVersionChange(Sender: TObject);
+    procedure FormActivate(Sender: TObject);
     procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
     procedure FormCreate(Sender: TObject);
     procedure FormDropFiles(Sender: TObject; const FileNames: array of string);
@@ -177,12 +178,13 @@ type
     procedure StringGrid1EditingDone(Sender: TObject);
     procedure StringGrid1Selection(Sender: TObject; aCol, aRow: integer);
     procedure tbPreset1Click(Sender: TObject);
-    procedure tbPreset1ContextPopup(Sender: TObject; MousePos: TPoint;
-      var Handled: boolean);
+    procedure tbPreset1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: boolean);
     procedure tbPrgChange(Sender: TObject);
     procedure tbResetClick(Sender: TObject);
     procedure tbSelChange(Sender: TObject);
     procedure Timer1Timer(Sender: TObject);
+    procedure XMLPropStorage1RestoringProperties(Sender: TObject);
+    procedure XMLPropStorage1SavingProperties(Sender: TObject);
   private
     { private declarations }
     sps: TSPS;
@@ -218,6 +220,9 @@ type
     procedure loadPreset(filename: string);
     procedure savePreset(filename: string);
     procedure activateSps(enable: boolean);
+    procedure enableMicrobit(enable: boolean);
+    procedure outputMicrobit();
+    procedure inputMicrobit();
   public
     { public declarations }
   end;
@@ -228,7 +233,8 @@ var
 implementation
 
 uses MCSAbout, uTextUi, uSelectCom, MCSTools, MCSStrings, synaser,
-  MCSIO, mcsintelhex, MCSLSU, MCSIniFiles, MCSWinHttp, luijsonutils;
+  MCSIO, mcsintelhex, MCSLSU, MCSIniFiles, MCSWinHttp, luijsonutils,
+  uiMicrobit, uMicrobit;
 
 {$R *.lfm}
 
@@ -613,8 +619,8 @@ begin
     begin
       if (StringGrid1.Cells[1, x] <> '') then
       begin
-        line := StringGrid1.Cells[0, x] + ',' + StringGrid1.Cells[1, x] +
-          ',' + StringGrid1.Cells[2, x] + ',"' + StringGrid1.Cells[4, x] + '"';
+        line := StringGrid1.Cells[0, x] + ',' + StringGrid1.Cells[1, x] + ',' +
+          StringGrid1.Cells[2, x] + ',"' + StringGrid1.Cells[4, x] + '"';
         Writeln(f, line);
       end;
     end;
@@ -795,9 +801,11 @@ begin
   begin
     acNextStep.Enabled := False;
     acStop.Enabled := False;
+    inputMicrobit();
     inputSps();
     sps.nextStep();
     outputSps();
+    outputMicrobit();
     acNextStep.Enabled := True;
     acStop.Enabled := True;
   end;
@@ -882,8 +890,7 @@ begin
         tmp := tmp + '0';
       line := line + tmp;
 
-      line := line + '      ' + StringGrid1.Cells[3, x] + '   ,"' +
-        StringGrid1.Cells[4, x] + '"';
+      line := line + '      ' + StringGrid1.Cells[3, x] + '   ,"' + StringGrid1.Cells[4, x] + '"';
       list.add(line);
     end;
   end;
@@ -1016,10 +1023,18 @@ begin
       if (return = mrOk) then
       begin
         hexFile := serialUpload;
+        SdpoSerial1.BaudRate:= br__9600;
+
+        if cbTPSVersion.ItemIndex = 5 then
+        begin
+          // Micro:bit V2 auto programm
+          SdpoSerial1.BaudRate:= br115200;
+        end;
 
         SdpoSerial1.Device := comService;
         SdpoSerial1.Active := True;
 
+        SdpoSerial1.WriteData('p');
         if (not readString(line)) then
         begin
           error := True;
@@ -1109,8 +1124,7 @@ var
 begin
   if (dirty) then
   begin
-    i := MCSLSU.LSUAutoMsgBox('Messages', 'SAVE_CHANGES', MB_ICONQUESTION or
-      MB_YESNOCANCEL);
+    i := MCSLSU.LSUAutoMsgBox('Messages', 'SAVE_CHANGES', MB_ICONQUESTION or MB_YESNOCANCEL);
     if (i = mrYes) then
     begin
       saveFile(activeFile);
@@ -1208,7 +1222,7 @@ var
   tmp: string;
   hexFormat: TIntelHexFormat;
   com, Data: byte;
-  f:file of byte;
+  f: file of byte;
 
 begin
   i := StringGrid1.RowCount;
@@ -1240,8 +1254,7 @@ begin
   end
   else
   begin
-    Caption := MCSLSU.GetLSUText('form1Captions', 'ID_CAPTION', lsuCode) +
-      ':' + ExtractFileName(activeFile);
+    Caption := MCSLSU.GetLSUText('form1Captions', 'ID_CAPTION', lsuCode) + ':' + ExtractFileName(activeFile);
   end;
 
 end;
@@ -1256,8 +1269,7 @@ begin
     StringGrid1.Columns[i].Title.Caption :=
       MCSLSU.GetLSUText('form1Captions', StringGrid1.Columns[i].Title.Caption, lsuCode);
   end;
-  StringGrid1.Cells[0, 0] := MCSLSU.GetLSUText('form1Captions',
-    'ID_GRID_STORAGE', lsuCode);
+  StringGrid1.Cells[0, 0] := MCSLSU.GetLSUText('form1Captions', 'ID_GRID_STORAGE', lsuCode);
   StringGrid1.Repaint;
 end;
 
@@ -1313,6 +1325,7 @@ begin
     ADC1.MaxValue := 15;
     ADC2.Value := 0;
     ADC2.MaxValue := 15;
+    enableMicrobit(False);
   end;
   if (cbTPSVersion.ItemIndex = 1) then
   begin
@@ -1339,6 +1352,7 @@ begin
     ADC1.MaxValue := 15;
     ADC2.Value := 0;
     ADC2.MaxValue := 15;
+    enableMicrobit(False);
   end;
   if ((cbTPSVersion.ItemIndex = 2) or (cbTPSVersion.ItemIndex = 3)) then
   begin
@@ -1377,6 +1391,7 @@ begin
     ADC1.MaxValue := 255;
     ADC2.Value := 0;
     ADC2.MaxValue := 255;
+    enableMicrobit(False);
   end;
 
   if (cbTPSVersion.ItemIndex = 4) then
@@ -1404,12 +1419,46 @@ begin
     ADC1.MaxValue := 15;
     ADC2.Value := 0;
     ADC2.MaxValue := 15;
+    enableMicrobit(False);
+  end;
+
+  if (cbTPSVersion.ItemIndex = 5) then
+  begin
+    // micro:bit v2
+    sps.setTPSVersion(MicroBitV2);
+
+    Label2.Visible := True;
+    ADC2.Visible := True;
+    PWM2.Visible := True;
+    Label16.Visible := True;
+    RC1.Visible := True;
+    Label17.Visible := True;
+    RC2.Visible := True;
+    Servo1.Visible := True;
+    Servo2.Visible := True;
+    Shape1.Visible := True;
+    Shape2.Visible := True;
+    EditE.Visible := True;
+    EditF.Visible := True;
+    acUpload.Enabled := True;
+    Label5.Visible := True;
+    btnTone.Visible := True;
+    ADC1.Value := 0;
+    ADC1.MaxValue := 15;
+    ADC2.Value := 0;
+    ADC2.MaxValue := 15;
+    enableMicrobit(True);
   end;
 
   cbCommand.Items.Clear;
   sps.getCommands(cbCommand.Items);
 end;
 
+procedure TForm1.FormActivate(Sender: TObject);
+begin
+  enableMicrobit(cbTPSVersion.ItemIndex = 5);
+end;
+
 procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
 begin
   canClose := checkDirty();
@@ -1437,8 +1486,7 @@ begin
   begin
     x := StringGrid1.Row;
     StringGrid1.Cells[3, x] :=
-      sps.getCommandText(HexToInt(StringGrid1.Cells[1, x]),
-      HexToInt(StringGrid1.Cells[2, x]));
+      sps.getCommandText(HexToInt(StringGrid1.Cells[1, x]), HexToInt(StringGrid1.Cells[2, x]));
     setDirty(True);
   end;
 end;
@@ -1483,7 +1531,45 @@ begin
   GBControl.Enabled := enable;
   GBInternal.Enabled := enable;
   GBOutput.Enabled := enable;
-  ;
+end;
+
+procedure TForm1.enableMicrobit(enable: boolean);
+begin
+  if fMicrobit <> nil then
+  begin
+    if enable and not fMicrobit.Visible then
+    begin
+      fMicrobit.Show();
+      fMicrobit.Left := Left + Width + 8;
+      fMicrobit.Top := Top;
+    end;
+    if not enable and fMicrobit.Visible then
+      fMicrobit.Hide();
+  end;
+end;
+
+procedure TForm1.inputMicrobit();
+begin
+  if (fMicrobit <> nil) and fMicrobit.Visible then
+  begin
+    sps.setACC(fMicrobit.accx.Value, fMicrobit.accz.Value, fMicrobit.accz.Value);
+    sps.setComp(fMicrobit.compass.Value);
+    sps.setLight(fMicrobit.light.Value);
+    sps.setSnd(fMicrobit.snd.Value);
+    sps.setGesture(fMicrobit.cbGesture.ItemIndex);
+    sps.setLogo(fMicrobit.tbLogo.Checked);
+  end;
+end;
+
+procedure TForm1.outputMicrobit();
+var
+  image: TMBImage;
+begin
+  if (fMicrobit <> nil) and fMicrobit.Visible then
+  begin
+    image := sps.getDisplay();
+    fMicrobit.setImage(image);
+  end;
 end;
 
 procedure TForm1.saveSection(filename: string; key: string);
@@ -1503,6 +1589,14 @@ begin
   WriteIniInteger(key, 'adc2', XMLPropStorage1.ReadInteger(key + '.adc2', 0), filename);
   WriteIniInteger(key, 'rc1', XMLPropStorage1.ReadInteger(key + '.rc1', 0), filename);
   WriteIniInteger(key, 'rc2', XMLPropStorage1.ReadInteger(key + '.rc2', 0), filename);
+  WriteIniBool(key, 'logo', XMLPropStorage1.ReadBoolean(key + '.logo', False), filename);
+  WriteIniInteger(key, 'accx', XMLPropStorage1.ReadInteger(key + '.accx', 0), filename);
+  WriteIniInteger(key, 'accy', XMLPropStorage1.ReadInteger(key + '.accy', 0), filename);
+  WriteIniInteger(key, 'accz', XMLPropStorage1.ReadInteger(key + '.accz', 0), filename);
+  WriteIniInteger(key, 'sound', XMLPropStorage1.ReadInteger(key + '.sound', 0), filename);
+  WriteIniInteger(key, 'light', XMLPropStorage1.ReadInteger(key + '.light', 0), filename);
+  WriteIniInteger(key, 'comp', XMLPropStorage1.ReadInteger(key + '.comp', 0), filename);
+  WriteIniInteger(key, 'gesture', XMLPropStorage1.ReadInteger(key + '.gesture', 0), filename);
 end;
 
 procedure TForm1.loadSection(filename: string; key: string);
@@ -1510,18 +1604,23 @@ begin
   XMLPropStorage1.WriteBoolean(key + '.set', ReadIniBool(key, 'set', False, filename));
   XMLPropStorage1.WriteBoolean(key + '.prg', ReadIniBool(key, 'prg', False, filename));
   XMLPropStorage1.WriteBoolean(key + '.sel', ReadIniBool(key, 'sel', False, filename));
-  XMLPropStorage1.WriteBoolean(key + '.input1', ReadIniBool(key,
-    'input1', False, filename));
-  XMLPropStorage1.WriteBoolean(key + '.input2', ReadIniBool(key,
-    'input2', False, filename));
-  XMLPropStorage1.WriteBoolean(key + '.input3', ReadIniBool(key,
-    'input3', False, filename));
-  XMLPropStorage1.WriteBoolean(key + '.input4', ReadIniBool(key,
-    'input4', False, filename));
+  XMLPropStorage1.WriteBoolean(key + '.input1', ReadIniBool(key, 'input1', False, filename));
+  XMLPropStorage1.WriteBoolean(key + '.input2', ReadIniBool(key, 'input2', False, filename));
+  XMLPropStorage1.WriteBoolean(key + '.input3', ReadIniBool(key, 'input3', False, filename));
+  XMLPropStorage1.WriteBoolean(key + '.input4', ReadIniBool(key, 'input4', False, filename));
   XMLPropStorage1.WriteInteger(key + '.adc1', ReadIniInteger(key, 'adc1', 0, filename));
   XMLPropStorage1.WriteInteger(key + '.adc2', ReadIniInteger(key, 'adc2', 0, filename));
   XMLPropStorage1.WriteInteger(key + '.rc1', ReadIniInteger(key, 'rc1', 0, filename));
   XMLPropStorage1.WriteInteger(key + '.rc2', ReadIniInteger(key, 'rc2', 0, filename));
+
+  XMLPropStorage1.WriteBoolean(key + '.logo', ReadIniBool(key, 'logo', False, filename));
+  XMLPropStorage1.WriteInteger(key + '.accx', ReadIniInteger(key, 'accx', 0, filename));
+  XMLPropStorage1.WriteInteger(key + '.accy', ReadIniInteger(key, 'accy', 0, filename));
+  XMLPropStorage1.WriteInteger(key + '.accz', ReadIniInteger(key, 'accz', 0, filename));
+  XMLPropStorage1.WriteInteger(key + '.sound', ReadIniInteger(key, 'sound', 0, filename));
+  XMLPropStorage1.WriteInteger(key + '.light', ReadIniInteger(key, 'light', 0, filename));
+  XMLPropStorage1.WriteInteger(key + '.comp', ReadIniInteger(key, 'comp', 0, filename));
+  XMLPropStorage1.WriteInteger(key + '.gesture', ReadIniInteger(key, 'gesture', 0, filename));
 end;
 
 procedure TForm1.tbPreset1Click(Sender: TObject);
@@ -1562,10 +1661,17 @@ begin
   ADC2.Value := XMLPropStorage1.ReadInteger(key + '.adc2', ADC2.Value);
   RC1.Value := XMLPropStorage1.ReadInteger(key + '.rc1', RC1.Value);
   RC2.Value := XMLPropStorage1.ReadInteger(key + '.rc2', RC2.Value);
+  fMicrobit.tbLogo.Checked := XMLPropStorage1.ReadBoolean(key + '.logo', fMicrobit.tbLogo.Checked);
+  fMicrobit.accx.Value := XMLPropStorage1.ReadInteger(key + '.accx', fMicrobit.accx.Value);
+  fMicrobit.accy.Value := XMLPropStorage1.ReadInteger(key + '.accy', fMicrobit.accy.Value);
+  fMicrobit.accz.Value := XMLPropStorage1.ReadInteger(key + '.accz', fMicrobit.accz.Value);
+  fMicrobit.snd.Value := XMLPropStorage1.ReadInteger(key + '.sound', fMicrobit.snd.Value);
+  fMicrobit.light.Value := XMLPropStorage1.ReadInteger(key + '.light', fMicrobit.light.Value);
+  fMicrobit.compass.Value := XMLPropStorage1.ReadInteger(key + '.comp', fMicrobit.compass.Value);
+  fMicrobit.cbGesture.ItemIndex := XMLPropStorage1.ReadInteger(key + '.gesture', fMicrobit.cbGesture.ItemIndex);
 end;
 
-procedure TForm1.tbPreset1ContextPopup(Sender: TObject; MousePos: TPoint;
-  var Handled: boolean);
+procedure TForm1.tbPreset1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: boolean);
 var
   key: string;
 begin
@@ -1604,6 +1710,14 @@ begin
   XMLPropStorage1.WriteInteger(key + '.adc2', ADC2.Value);
   XMLPropStorage1.WriteInteger(key + '.rc1', RC1.Value);
   XMLPropStorage1.WriteInteger(key + '.rc2', RC2.Value);
+  XMLPropStorage1.WriteBoolean(key + '.logo', fMicrobit.tbLogo.Checked);
+  XMLPropStorage1.WriteInteger(key + '.accx', fMicrobit.accx.Value);
+  XMLPropStorage1.WriteInteger(key + '.accy', fMicrobit.accy.Value);
+  XMLPropStorage1.WriteInteger(key + '.accz', fMicrobit.accz.Value);
+  XMLPropStorage1.WriteInteger(key + '.sound', fMicrobit.snd.Value);
+  XMLPropStorage1.WriteInteger(key + '.light', fMicrobit.light.Value);
+  XMLPropStorage1.WriteInteger(key + '.comp', fMicrobit.compass.Value);
+  XMLPropStorage1.WriteInteger(key + '.gesture', fMicrobit.cbGesture.ItemIndex);
   checkPresets();
 end;
 
@@ -1661,12 +1775,37 @@ begin
   if (InfoBox.newVersion) then
   begin
     MCSLabel.Font.Color := clred;
-    MCSLabel.Hint := InfoBox.versionHint + chr($0a) + chr($0d) +
-      MCSLSU.GetLSUText('form1Captions', 'ID_CLICK_HERE', lsuCode);
+    MCSLabel.Hint := InfoBox.versionHint + chr($0a) + chr($0d) + MCSLSU.GetLSUText(
+      'form1Captions', 'ID_CLICK_HERE', lsuCode);
   end;
   MCSLabel.Caption := InfoBox.versionText;
 end;
 
+procedure TForm1.XMLPropStorage1RestoringProperties(Sender: TObject);
+var
+  Uid: TGuid;
+  Result: HResult;
+  uuid: string;
+
+begin
+  uuid := XMLPropStorage1.ReadString('AppUUID', '');
+  if uuid = '' then
+  begin
+    Result := CreateGuid(Uid);
+    if Result = S_OK then
+    begin
+      uuid := GuidToString(Uid);
+      XMLPropStorage1.WriteString('AppUUID', uuid);
+    end;
+  end;
+  Infobox.AppUUID := uuid;
+end;
+
+procedure TForm1.XMLPropStorage1SavingProperties(Sender: TObject);
+begin
+
+end;
+
 
 procedure TForm1.renumberGrid;
 var
@@ -1681,8 +1820,7 @@ begin
     if (StringGrid1.Cells[2, x] = '') then
       StringGrid1.Cells[2, x] := '0';
     StringGrid1.Cells[3, x] :=
-      sps.getCommandText(HexToInt(StringGrid1.Cells[1, x]),
-      HexToInt(StringGrid1.Cells[2, x]));
+      sps.getCommandText(HexToInt(StringGrid1.Cells[1, x]), HexToInt(StringGrid1.Cells[2, x]));
   end;
 end;
 

+ 386 - 0
uimicrobit.lfm

@@ -0,0 +1,386 @@
+object fMicrobit: TfMicrobit
+  Left = 1211
+  Height = 259
+  Top = 119
+  Width = 297
+  BorderIcons = []
+  BorderStyle = bsToolWindow
+  Caption = 'micro:bit Input Output'
+  ClientHeight = 259
+  ClientWidth = 297
+  FormStyle = fsStayOnTop
+  OnActivate = FormActivate
+  LCLVersion = '2.0.12.0'
+  object GroupBox1: TGroupBox
+    Left = 8
+    Height = 104
+    Top = 8
+    Width = 104
+    Caption = 'Display'
+    ClientHeight = 84
+    ClientWidth = 100
+    TabOrder = 0
+    object Shape1: TShape
+      Left = 8
+      Height = 15
+      Top = 0
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape2: TShape
+      Left = 24
+      Height = 15
+      Top = 0
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape3: TShape
+      Left = 40
+      Height = 15
+      Top = 0
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape4: TShape
+      Left = 56
+      Height = 15
+      Top = 0
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape5: TShape
+      Left = 72
+      Height = 15
+      Top = 0
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape6: TShape
+      Left = 8
+      Height = 15
+      Top = 16
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape7: TShape
+      Left = 24
+      Height = 15
+      Top = 16
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape8: TShape
+      Left = 40
+      Height = 15
+      Top = 16
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape9: TShape
+      Left = 56
+      Height = 15
+      Top = 16
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape10: TShape
+      Left = 72
+      Height = 15
+      Top = 16
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape11: TShape
+      Left = 8
+      Height = 15
+      Top = 32
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape12: TShape
+      Left = 24
+      Height = 15
+      Top = 32
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape13: TShape
+      Left = 40
+      Height = 15
+      Top = 32
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape14: TShape
+      Left = 56
+      Height = 15
+      Top = 32
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape15: TShape
+      Left = 72
+      Height = 15
+      Top = 32
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape16: TShape
+      Left = 8
+      Height = 15
+      Top = 48
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape17: TShape
+      Left = 24
+      Height = 15
+      Top = 48
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape18: TShape
+      Left = 40
+      Height = 15
+      Top = 48
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape19: TShape
+      Left = 56
+      Height = 15
+      Top = 48
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape20: TShape
+      Left = 72
+      Height = 15
+      Top = 48
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape21: TShape
+      Left = 8
+      Height = 15
+      Top = 64
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape22: TShape
+      Left = 24
+      Height = 15
+      Top = 64
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape23: TShape
+      Left = 40
+      Height = 15
+      Top = 64
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape24: TShape
+      Left = 56
+      Height = 15
+      Top = 64
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+    object Shape25: TShape
+      Left = 72
+      Height = 15
+      Top = 64
+      Width = 17
+      Brush.Color = clRed
+      Shape = stRoundRect
+    end
+  end
+  object GBInput: TGroupBox
+    Left = 120
+    Height = 248
+    Top = 8
+    Width = 172
+    Caption = 'Input'
+    ClientHeight = 228
+    ClientWidth = 168
+    ParentFont = False
+    TabOrder = 1
+    object accx: TSpinEdit
+      Left = 62
+      Height = 23
+      Top = 24
+      Width = 54
+      MaxValue = 255
+      ParentFont = False
+      TabOrder = 0
+    end
+    object accy: TSpinEdit
+      Left = 62
+      Height = 23
+      Top = 52
+      Width = 54
+      MaxValue = 255
+      ParentFont = False
+      TabOrder = 1
+    end
+    object Label1: TLabel
+      Left = 14
+      Height = 15
+      Top = 31
+      Width = 34
+      Caption = 'ACC.X'
+      ParentColor = False
+      ParentFont = False
+    end
+    object Label2: TLabel
+      Left = 14
+      Height = 15
+      Top = 58
+      Width = 34
+      Caption = 'ACC.Y'
+      ParentColor = False
+      ParentFont = False
+    end
+    object accz: TSpinEdit
+      Left = 62
+      Height = 23
+      Top = 81
+      Width = 54
+      MaxValue = 255
+      ParentFont = False
+      TabOrder = 2
+    end
+    object compass: TSpinEdit
+      Left = 62
+      Height = 23
+      Top = 109
+      Width = 54
+      MaxValue = 255
+      ParentFont = False
+      TabOrder = 3
+    end
+    object Label16: TLabel
+      Left = 14
+      Height = 15
+      Top = 87
+      Width = 34
+      Caption = 'ACC.Z'
+      ParentColor = False
+      ParentFont = False
+    end
+    object Label17: TLabel
+      Left = 14
+      Height = 15
+      Top = 115
+      Width = 49
+      Caption = 'Compass'
+      ParentColor = False
+      ParentFont = False
+    end
+    object tbLogo: TToggleBox
+      Left = 14
+      Height = 18
+      Top = 1
+      Width = 50
+      Caption = '&LOGO'
+      ParentFont = False
+      TabOrder = 4
+    end
+    object Label3: TLabel
+      Left = 14
+      Height = 15
+      Top = 143
+      Width = 34
+      Caption = 'Sound'
+      ParentColor = False
+      ParentFont = False
+    end
+    object snd: TSpinEdit
+      Left = 62
+      Height = 23
+      Top = 136
+      Width = 54
+      MaxValue = 255
+      ParentFont = False
+      TabOrder = 5
+    end
+    object Label4: TLabel
+      Left = 14
+      Height = 15
+      Top = 170
+      Width = 27
+      Caption = 'Light'
+      ParentColor = False
+      ParentFont = False
+    end
+    object light: TSpinEdit
+      Left = 62
+      Height = 23
+      Top = 164
+      Width = 54
+      MaxValue = 255
+      ParentFont = False
+      TabOrder = 6
+    end
+    object Label18: TLabel
+      Left = 14
+      Height = 15
+      Top = 199
+      Width = 40
+      Caption = 'Gesture'
+      ParentColor = False
+      ParentFont = False
+    end
+    object cbGesture: TComboBox
+      Left = 64
+      Height = 23
+      Top = 194
+      Width = 68
+      ItemHeight = 15
+      ItemIndex = 0
+      Items.Strings = (
+        'nothing '
+        'up'
+        'down'
+        'left'
+        'right'
+        'face up'
+        'face down'
+        'freefall'
+        '3g'
+        '6g '
+        '8g'
+        'shake'
+      )
+      Style = csDropDownList
+      TabOrder = 7
+      Text = 'nothing '
+    end
+  end
+end

+ 131 - 0
uimicrobit.pas

@@ -0,0 +1,131 @@
+unit uiMicrobit;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
+  Spin, ComCtrls, uMicrobit;
+
+type
+
+  { TfMicrobit }
+
+  TfMicrobit = class(TForm)
+    accx: TSpinEdit;
+    snd: TSpinEdit;
+    accy: TSpinEdit;
+    light: TSpinEdit;
+    cbGesture: TComboBox;
+    GBInput: TGroupBox;
+    GroupBox1: TGroupBox;
+    Label1: TLabel;
+    Label16: TLabel;
+    Label17: TLabel;
+    Label18: TLabel;
+    Label2: TLabel;
+    accz: TSpinEdit;
+    compass: TSpinEdit;
+    Label3: TLabel;
+    Label4: TLabel;
+    Shape1: TShape;
+    Shape10: TShape;
+    Shape11: TShape;
+    Shape12: TShape;
+    Shape13: TShape;
+    Shape14: TShape;
+    Shape15: TShape;
+    Shape16: TShape;
+    Shape17: TShape;
+    Shape18: TShape;
+    Shape19: TShape;
+    Shape2: TShape;
+    Shape20: TShape;
+    Shape21: TShape;
+    Shape22: TShape;
+    Shape23: TShape;
+    Shape24: TShape;
+    Shape25: TShape;
+    Shape3: TShape;
+    Shape4: TShape;
+    Shape5: TShape;
+    Shape6: TShape;
+    Shape7: TShape;
+    Shape8: TShape;
+    Shape9: TShape;
+    tbLogo: TToggleBox;
+    procedure FormActivate(Sender: TObject);
+  private
+
+  public
+    procedure setImage(Display: TMBImage);
+    procedure setPixel(x, y: integer; Value: boolean);
+  end;
+
+var
+  fMicrobit: TfMicrobit;
+
+implementation
+
+{$R *.lfm}
+
+{ TfMicrobit }
+
+procedure TfMicrobit.FormActivate(Sender: TObject);
+var
+  x, y: integer;
+begin
+  for x := 0 to 4 do
+    for y := 0 to 4 do
+      setPixel(x, y, False);
+end;
+
+procedure TfMicrobit.setImage(Display: TMBImage);
+var
+  x, y, pos: integer;
+  Value: boolean;
+begin
+  for x := 0 to 4 do
+    for y := 0 to 4 do
+    begin
+      Value := Display[x, y] > 0;
+      setPixel(x, y, Value);
+    end;
+end;
+
+procedure TfMicrobit.setPixel(x, y: integer; Value: boolean);
+var
+  pos: integer;
+begin
+  pos := (x * 5) + y;
+  case pos of
+    0: Shape1.Visible := Value;
+    1: Shape2.Visible := Value;
+    2: Shape3.Visible := Value;
+    3: Shape4.Visible := Value;
+    4: Shape5.Visible := Value;
+    5: Shape6.Visible := Value;
+    6: Shape7.Visible := Value;
+    7: Shape8.Visible := Value;
+    8: Shape9.Visible := Value;
+    9: Shape10.Visible := Value;
+    10: Shape11.Visible := Value;
+    11: Shape12.Visible := Value;
+    12: Shape13.Visible := Value;
+    13: Shape14.Visible := Value;
+    14: Shape15.Visible := Value;
+    15: Shape16.Visible := Value;
+    16: Shape17.Visible := Value;
+    17: Shape18.Visible := Value;
+    18: Shape19.Visible := Value;
+    19: Shape20.Visible := Value;
+    20: Shape21.Visible := Value;
+    21: Shape22.Visible := Value;
+    22: Shape23.Visible := Value;
+    23: Shape24.Visible := Value;
+    24: Shape25.Visible := Value;
+  end;
+end;
+
+end.

+ 404 - 0
umicrobit.pas

@@ -0,0 +1,404 @@
+unit uMicrobit;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils;
+
+type
+  TMBImage = array[0..4, 0..4] of integer;
+
+const
+  IMAGE_MAP: array[1..63] of TMBImage = (
+    //IMAGE_HEART: TMBImage =
+    ((0, 1, 0, 1, 0),
+    (1, 1, 1, 1, 1),
+    (1, 1, 1, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_HEART_SMALL: TMBImage =
+    ((0, 0, 0, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0)),
+    // smilies
+    //IMAGE_HAPPY: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0),
+    (1, 0, 0, 0, 1),
+    (0, 1, 1, 1, 0)),
+    //IMAGE_SMILE: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (1, 0, 0, 0, 1),
+    (0, 1, 1, 1, 0)),
+    //IMAGE_SAD: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0),
+    (0, 1, 1, 1, 0),
+    (1, 0, 0, 0, 1)),
+    //IMAGE_CONFUSED: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0),
+    (0, 1, 0, 1, 0),
+    (1, 0, 1, 0, 1)),
+    //IMAGE_ANGRY: TMBImage = (
+    ((1, 0, 0, 0, 1),
+    (0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0),
+    (1, 1, 1, 1, 1),
+    (1, 0, 1, 0, 1)),
+    //IMAGE_ASLEEP: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (1, 1, 0, 1, 1),
+    (0, 0, 0, 0, 0),
+    (0, 1, 1, 1, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_SURPRISED: TMBImage = (
+    ((0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_SILLY: TMBImage = (
+    ((1, 0, 0, 0, 1),
+    (0, 0, 0, 0, 0),
+    (1, 1, 1, 1, 1),
+    (0, 0, 1, 0, 1),
+    (0, 0, 1, 1, 1)),
+    //IMAGE_FABULOUS: TMBImage = (
+    ((1, 1, 1, 1, 1),
+    (1, 1, 0, 1, 1),
+    (0, 0, 0, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 1, 1, 1, 0)),
+    //IMAGE_MEH: TMBImage = (
+    ((0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 1, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 0, 0)),
+    // yes/no
+    //IMAGE_YES: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 1),
+    (0, 0, 0, 1, 0),
+    (1, 0, 1, 0, 0),
+    (0, 1, 0, 0, 0)),
+    //IMAGE_NO: TMBImage = (
+    ((1, 0, 0, 0, 1),
+    (0, 1, 0, 1, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 1, 0),
+    (1, 0, 0, 0, 1)),
+    // clock hands
+    //IMAGE_CLOCK12: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK1: TMBImage = (
+    ((0, 0, 0, 1, 0),
+    (0, 0, 0, 1, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK2: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 1, 1),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK3: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 1, 1),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK4: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 1, 1),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK5: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 1, 0),
+    (0, 0, 0, 1, 0)),
+    //IMAGE_CLOCK6: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_CLOCK7: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 0, 0),
+    (0, 1, 0, 0, 0)),
+    //IMAGE_CLOCK8: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (1, 1, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK9: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0),
+    (1, 1, 1, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK10: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (1, 1, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_CLOCK11: TMBImage = (
+    ((0, 1, 0, 0, 0),
+    (0, 1, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0),
+    (0, 0, 0, 0, 0)),
+    // arrows
+    //IMAGE_ARROW_N: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 1, 1, 1, 0),
+    (1, 0, 1, 0, 1),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_ARROW_NE: TMBImage = (
+    ((0, 0, 1, 1, 1),
+    (0, 0, 0, 1, 1),
+    (0, 0, 1, 0, 1),
+    (0, 1, 0, 0, 0),
+    (1, 0, 0, 0, 0)),
+    //IMAGE_ARROW_E: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 0, 0, 1, 0),
+    (1, 1, 1, 1, 1),
+    (0, 0, 0, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_ARROW_SE: TMBImage = (
+    ((1, 0, 0, 0, 0),
+    (0, 1, 0, 0, 0),
+    (0, 0, 1, 0, 1),
+    (0, 0, 0, 1, 1),
+    (0, 0, 1, 1, 1)),
+    //IMAGE_ARROW_S: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (1, 0, 1, 0, 1),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_ARROW_SW: TMBImage = (
+    ((0, 0, 0, 0, 1),
+    (0, 0, 0, 1, 0),
+    (1, 0, 1, 0, 0),
+    (1, 1, 0, 0, 0),
+    (1, 1, 1, 0, 0)),
+    //IMAGE_ARROW_W: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 1, 0, 0, 0),
+    (1, 1, 1, 1, 1),
+    (0, 1, 0, 0, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_ARROW_NW: TMBImage = (
+    ((1, 1, 1, 0, 0),
+    (1, 1, 0, 0, 0),
+    (1, 0, 1, 0, 0),
+    (0, 0, 0, 1, 0),
+    (0, 0, 0, 0, 1)),
+    // geometry
+    //IMAGE_TRIANGLE: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 1, 0),
+    (1, 1, 1, 1, 1),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_TRIANGLE_LEFT: TMBImage = (
+    ((1, 0, 0, 0, 0),
+    (1, 1, 0, 0, 0),
+    (1, 0, 1, 0, 0),
+    (1, 0, 0, 1, 0),
+    (1, 1, 1, 1, 1)),
+    //IMAGE_CHESSBOARD: TMBImage = (
+    ((0, 1, 0, 1, 0),
+    (1, 0, 1, 0, 1),
+    (0, 1, 0, 1, 0),
+    (1, 0, 1, 0, 1),
+    (0, 1, 0, 1, 0)),
+    //IMAGE_DIAMOND: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 1, 0, 1, 0),
+    (1, 0, 0, 0, 1),
+    (0, 1, 0, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_DIAMOND_SMALL: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 1, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_SQUARE: TMBImage = (
+    ((1, 1, 1, 1, 1),
+    (1, 0, 0, 0, 1),
+    (1, 0, 0, 0, 1),
+    (1, 0, 0, 0, 1),
+    (1, 1, 1, 1, 1)),
+    //IMAGE_SQUARE_SMALL: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 1, 1, 1, 0),
+    (0, 1, 0, 1, 0),
+    (0, 1, 1, 1, 0),
+    (0, 0, 0, 0, 0)),
+    // animals
+    //IMAGE_RABBIT: TMBImage = (
+    ((1, 0, 1, 0, 0),
+    (1, 0, 1, 0, 0),
+    (1, 1, 1, 1, 0),
+    (1, 1, 0, 1, 0),
+    (1, 1, 1, 1, 0)),
+    //IMAGE_COW: TMBImage = (
+    ((1, 0, 0, 0, 1),
+    (1, 0, 0, 0, 1),
+    (1, 1, 1, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0)),
+    // musical notes
+    //IMAGE_MUSIC_CROTCHET: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (1, 1, 1, 0, 0),
+    (1, 1, 1, 0, 0)),
+    //IMAGE_MUSIC_QUAVER: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 0, 1, 1, 0),
+    (0, 0, 1, 0, 1),
+    (1, 1, 1, 0, 0),
+    (1, 1, 1, 0, 0)),
+    //IMAGE_MUSIC_QUAVERS: TMBImage = (
+    ((0, 1, 1, 1, 1),
+    (0, 1, 0, 0, 1),
+    (0, 1, 0, 0, 1),
+    (1, 1, 0, 1, 1),
+    (1, 1, 0, 1, 1)),
+    // other icons
+    //IMAGE_PITCHFORK: TMBImage = (
+    ((1, 0, 1, 0, 1),
+    (1, 0, 1, 0, 1),
+    (1, 1, 1, 1, 1),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_XMAS: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 1, 1, 0),
+    (1, 1, 1, 1, 1)),
+    //IMAGE_PACMAN: TMBImage = (
+    ((0, 1, 1, 1, 1),
+    (1, 1, 0, 1, 0),
+    (1, 1, 1, 0, 0),
+    (1, 1, 1, 1, 0),
+    (0, 1, 1, 1, 1)),
+    //IMAGE_TARGET: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 1, 1, 1, 0),
+    (1, 1, 0, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_SHIRT: TMBImage = (
+    ((1, 1, 0, 1, 1),
+    (1, 1, 1, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 1, 1, 1, 0),
+    (0, 1, 1, 1, 0)),
+    //IMAGE_ROLLERSKATE: TMBImage = (
+    ((0, 0, 0, 1, 1),
+    (0, 0, 0, 1, 1),
+    (1, 1, 1, 1, 1),
+    (1, 1, 1, 1, 1),
+    (0, 1, 0, 1, 0)),
+    //IMAGE_DUCK: TMBImage = (
+    ((0, 1, 1, 0, 0),
+    (1, 1, 1, 0, 0),
+    (0, 1, 1, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_HOUSE: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 1, 1, 1, 0),
+    (1, 1, 1, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 1, 0, 1, 0)),
+    //IMAGE_TORTOISE: TMBImage = (
+    ((0, 0, 0, 0, 0),
+    (0, 1, 1, 1, 0),
+    (1, 1, 1, 1, 1),
+    (0, 1, 0, 1, 0),
+    (0, 0, 0, 0, 0)),
+    //IMAGE_BUTTERFLY: TMBImage = (
+    ((1, 1, 0, 1, 1),
+    (1, 1, 1, 1, 1),
+    (0, 0, 1, 0, 0),
+    (1, 1, 1, 1, 1),
+    (1, 1, 0, 1, 1)),
+    //IMAGE_STICKFIGURE: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (1, 1, 1, 1, 1),
+    (0, 0, 1, 0, 0),
+    (0, 1, 0, 1, 0),
+    (1, 0, 0, 0, 1)),
+    //IMAGE_GHOST: TMBImage = (
+    ((1, 1, 1, 1, 1),
+    (1, 0, 1, 0, 1),
+    (1, 1, 1, 1, 1),
+    (1, 1, 1, 1, 1),
+    (1, 0, 1, 0, 1)),
+    //IMAGE_SWORD: TMBImage = (
+    ((0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 0, 1, 0, 0),
+    (0, 1, 1, 1, 0),
+    (0, 0, 1, 0, 0)),
+    //IMAGE_GIRAFFE: TMBImage = (
+    ((1, 1, 0, 0, 0),
+    (0, 1, 0, 0, 0),
+    (0, 1, 0, 0, 0),
+    (0, 1, 1, 1, 0),
+    (0, 1, 0, 1, 0)),
+    //IMAGE_SKULL: TMBImage = (
+    ((0, 1, 1, 1, 0),
+    (1, 0, 1, 0, 1),
+    (1, 1, 1, 1, 1),
+    (0, 1, 1, 1, 0),
+    (0, 1, 1, 1, 0)),
+    //IMAGE_UMBRELLA: TMBImage = (
+    ((0, 1, 1, 1, 0),
+    (1, 1, 1, 1, 1),
+    (0, 0, 1, 0, 0),
+    (1, 0, 1, 0, 0),
+    (0, 1, 1, 0, 0)),
+    //IMAGE_SNAKE: TMBImage = (
+    ((1, 1, 0, 0, 0),
+    (1, 1, 0, 1, 1),
+    (0, 1, 0, 1, 0),
+    (0, 1, 1, 1, 0),
+    (0, 0, 0, 0, 0)));
+
+implementation
+
+end.

+ 186 - 40
usps.pas

@@ -5,7 +5,7 @@ unit uSPS;
 interface
 
 uses
-  Classes, SysUtils, MCSTools;
+  Classes, SysUtils, MCSTools, uMicrobit;
 
 const
 
@@ -30,12 +30,15 @@ const
 
   COMMANDS: array[0..15] of string =
     ('0', 'Dout', 'Delay', 'Jump -', 'A=#', '=A', 'A=',
-    'A=Calculation', 'Page', 'Jump', 'C*', 'D*', 'Skip if', 'Call', 'Ret', 'Byte');
+    'A=Calculation', 'Page', 'Jump', 'C*', 'D*', 'Skip if', 'Call', 'Ret', 'Byte/Board');
 
   O_LIST_H: array[0..15] of string =
     ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
   O_LIST_AT: array[0..15] of string =
     ('NOP', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
+  O_LIST_MB: array[0..15] of string =
+    ('NOP', 'SetPixel(x=A,y=B)', 'ClearPixel(x=A,y=B)', 'Image', '',
+    '', '', '', '', '', '', '', '', '', '', '');
 
   DOUT_LIST: array[0..15] of string = ('Output 0000', 'Output 0001',
     'Output 0010', 'Output 0011', 'Output 0100', 'Output 0101', 'Output 0110',
@@ -131,11 +134,15 @@ const
   F_LIST_AT: array[0..15] of string = ('A=ADC.1', 'A=ADC.2', 'A=RCin.1', 'A=RCin.2',
     'PWM.1=A', 'PWM.2=A', 'Servo.1=A', 'Servo.2=A', 'Tone=A', '', '', '',
     '', 'LED off', 'LED on', 'PrgEnd');
+  F_LIST_MB: array[0..15] of string = ('A=ADC.1', 'A=ADC.2', 'A=RCin.1', 'A=RCin.2',
+    'PWM.1=A', 'PWM.2=A', 'Servo.1=A', 'Servo.2=A', 'Tone=A',
+    'A,E,F=Acc', 'A=Compass', 'A=Sound',
+    'A=Light', 'A=Logo', 'A=Gesture', 'PrgEnd');
 
 type
   {TPSVersion}
 
-  TTPSVersion = (Holtek, ATMega8, ATTiny84, Arduino, MicroBit);
+  TTPSVersion = (Holtek, ATMega8, ATTiny84, Arduino, Microbit, MicroBitV2);
 
   { TServo }
 
@@ -174,7 +181,8 @@ type
 
     saveaddr: array[0..15] of word;
     saveCnt: byte;
-    eeprom: array[0..255] of byte;
+    eeprom: array[0..1024] of byte;
+    e2e: word;
     adrPage: byte;
     addr: word;
     jumpAddr: word;
@@ -190,6 +198,15 @@ type
     delayCallback: TDelayCallback;
     delayActive: boolean;
 
+    // specials for microbit
+    display: TMBImage;
+    sw_logo: boolean;
+    acc_x, acc_y, acc_z: byte;
+    compass: byte;
+    gesture: byte;
+    soundLevel: byte;
+    lightLevel: byte;
+
     procedure doNull(Data: byte);
     procedure doPort(Data: byte);
     procedure doDelay(Data: byte);
@@ -207,7 +224,6 @@ type
     procedure doCallSub(Data: byte);
     procedure doByte(Data: byte);
     procedure doTone(Data: byte);
-
     procedure push(Data: byte);
     function pop(): byte;
   public
@@ -238,6 +254,16 @@ type
     procedure setRC1(Data: byte);
     procedure setRC2(Data: byte);
 
+    // Microbit specials
+    procedure setACC(x, y, z: byte);
+    procedure setComp(Data: byte);
+    procedure setGesture(Data: byte);
+    procedure setLight(Data: byte);
+    procedure setLogo(Data: boolean);
+    procedure setSnd(Data: byte);
+    function getDisplay(): TMBImage;
+    // end
+
     procedure nextStep();
     procedure doReset();
     procedure start();
@@ -277,7 +303,7 @@ type
 implementation
 
 
-uses Math, MCSStrings;
+uses Math, MCSStrings, LCLProc;
 
 { TServo }
 
@@ -412,7 +438,7 @@ begin
 
   doSingleCommand(Value);
 
-  if (addr > SizeOf(eeprom)) then
+  if (addr > e2e) then
   begin
     doReset();
   end;
@@ -447,6 +473,14 @@ begin
   servo2.Write(0);
   servo1.Write(0);
   stop := False;
+  sw_sel := False;
+  acc_x := 0;
+  acc_y := 0;
+  acc_z := 0;
+  compass := 0;
+  gesture := 0;
+  lightLevel := 0;
+  soundLevel := 0;
 end;
 
 procedure TSPS.start();
@@ -455,7 +489,7 @@ var
   x: integer;
 begin
   doReset();
-  for x := 0 to SizeOf(eeprom) do
+  for x := 0 to e2e do
   begin
     Value := eeprom[x];
     cmd := (Value and $F0);
@@ -548,7 +582,7 @@ begin
       case Data of
         0: if (a = 0) then
             case version of
-              ATTiny84, Arduino, MicroBit: skip := True;
+              ATTiny84, Arduino, Microbit, MicroBitV2: skip := True;
             end;
         1: if (a > b) then
             skip := True;
@@ -664,6 +698,10 @@ end;
 procedure TSPS.setTPSVersion(tpsversion: TTPSVersion);
 begin
   version := tpsversion;
+  case version of
+    Holtek, ATMega8, ATTiny84, Microbit: e2e := 256;
+    Arduino, MicroBitV2: e2e := 1024;
+  end;
 end;
 
 procedure TSPS.getCommands(list: TStrings);
@@ -676,8 +714,9 @@ begin
   if (cmd = 0) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(O_LIST_H, list);
+      Holtek, ATMega8, Microbit: MCSStrings.copyArray2List(O_LIST_H, list);
       ATTiny84, Arduino: MCSStrings.copyArray2List(O_LIST_AT, list);
+      MicroBitV2: MCSStrings.copyArray2List(O_LIST_MB, list);
     end;
   end;
   if (cmd = 1) then
@@ -693,31 +732,31 @@ begin
   if (cmd = 5) then
   begin
     case version of
-      Holtek, MicroBit: MCSStrings.copyArray2List(IS_A_LIST_H, list);
+      Holtek, Microbit: MCSStrings.copyArray2List(IS_A_LIST_H, list);
       ATMega8: MCSStrings.copyArray2List(IS_A_LIST_A8, list);
-      ATTiny84, Arduino: MCSStrings.copyArray2List(IS_A_LIST_AT, list);
+      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(IS_A_LIST_AT, list);
     end;
   end;
   if (cmd = 6) then
   begin
     case version of
-      Holtek, MicroBit: MCSStrings.copyArray2List(A_IS_LIST_H, list);
+      Holtek, Microbit: MCSStrings.copyArray2List(A_IS_LIST_H, list);
       ATMega8: MCSStrings.copyArray2List(A_IS_LIST_A8, list);
-      ATTiny84, Arduino: MCSStrings.copyArray2List(A_IS_LIST_AT, list);
+      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(A_IS_LIST_AT, list);
     end;
   end;
   if (cmd = 7) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(A_CALC_LIST_H, list);
-      ATTiny84, Arduino: MCSStrings.copyArray2List(A_CALC_LIST_AT, list);
+      Holtek, ATMega8, Microbit: MCSStrings.copyArray2List(A_CALC_LIST_H, list);
+      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(A_CALC_LIST_AT, list);
     end;
   end;
   if (cmd = 8) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(PAGE_LIST_H, list);
-      ATTiny84, Arduino: MCSStrings.copyArray2List(PAGE_LIST_AT, list);
+      Holtek, ATMega8, Microbit: MCSStrings.copyArray2List(PAGE_LIST_H, list);
+      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(PAGE_LIST_AT, list);
     end;
   end;
   if (cmd = 9) then
@@ -729,9 +768,9 @@ begin
   if (cmd = 12) then
   begin
     case version of
-      Holtek, MicroBit: MCSStrings.copyArray2List(SKIP_LIST_H, list);
+      Holtek, Microbit: MCSStrings.copyArray2List(SKIP_LIST_H, list);
       ATMega8: MCSStrings.copyArray2List(SKIP_LIST_A8, list);
-      ATTiny84, Arduino: MCSStrings.copyArray2List(SKIP_LIST_AT, list);
+      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(SKIP_LIST_AT, list);
     end;
   end;
   if (cmd = 13) then
@@ -739,15 +778,16 @@ begin
   if (cmd = 14) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(RET_LIST_H, list);
-      ATTiny84, Arduino: MCSStrings.copyArray2List(RET_LIST_AT, list);
+      Holtek, ATMega8, Microbit: MCSStrings.copyArray2List(RET_LIST_H, list);
+      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(RET_LIST_AT, list);
     end;
   end;
   if (cmd = 15) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(F_LIST_H, list);
+      Holtek, ATMega8, Microbit: MCSStrings.copyArray2List(F_LIST_H, list);
       ATTiny84, Arduino: MCSStrings.copyArray2List(F_LIST_AT, list);
+      MicroBitV2: MCSStrings.copyArray2List(F_LIST_MB, list);
     end;
   end;
 end;
@@ -774,8 +814,40 @@ begin
 end;
 
 procedure TSPS.doNull(Data: byte);
+var
+  x, y: integer;
+  image: TMBImage;
 begin
   // Do nothing
+  if version = MicroBitV2 then
+  begin
+    case Data of
+      1: display[A, B] := 1;
+      2: display[A, B] := 0;
+      3:
+      begin
+        if A = 0 then
+        begin
+          for x := 0 to 4 do
+            for y := 0 to 4 do
+              display[x, y] := 0;
+        end
+        else
+        begin
+          image := IMAGE_MAP[5];
+          if a <= length(IMAGE_MAP) then
+          begin
+            DebugLn('display an image');
+            image := IMAGE_MAP[a];
+          end;
+          for x := 0 to 4 do
+            for y := 0 to 4 do
+              display[x, y] := image[x, y];
+        end;
+      end;
+    end;
+  end;
+
 end;
 
 // output to port
@@ -888,7 +960,7 @@ var
 begin
   case Data of
     0: case version of
-        ATTiny84, Arduino:
+        ATTiny84, Arduino, MicroBitV2:
         begin
           tmpValue := b;
           b := a;
@@ -945,23 +1017,23 @@ begin
     9: a := a xor b;
     10: a := not a;
     11: case version of
-        ATTiny84, Arduino: a := a mod b;
+        ATTiny84, Arduino, MicroBitV2: a := a mod b;
       end;
     12: case version of
-        ATTiny84, Arduino: a := a + 16 * b;
+        ATTiny84, Arduino, MicroBitV2: a := a + 16 * b;
       end;
     13: case version of
-        ATTiny84, Arduino: a := b - a;
+        ATTiny84, Arduino, MicroBitV2: a := b - a;
       end;
     14: case version of
-        ATTiny84, Arduino: a := a SHR 1;
+        ATTiny84, Arduino, MicroBitV2: a := a shr 1;
       end;
     15: case version of
-        ATTiny84, Arduino: a := a SHL 1;
+        ATTiny84, Arduino, MicroBitV2: a := a shl 1;
       end;
   end;
   case version of
-    Holtek, ATMega8, MicroBit: a := a and 15;
+    Holtek, ATMega8, Microbit: a := a and 15;
   end;
 end;
 
@@ -1005,7 +1077,7 @@ begin
   case (Data) of
     0: if (a = 0) then
         case version of
-          ATTiny84, Arduino, MicroBit: addr := addr + 1;
+          ATTiny84, Arduino, Microbit, MicroBitV2: addr := addr + 1;
         end;
     1: if (a > b) then
         addr := addr + 1;
@@ -1045,7 +1117,7 @@ procedure TSPS.doCall(Data: byte);
 begin
   saveaddr[saveCnt] := addr;
   case version of
-    ATTiny84, Arduino: saveCnt := saveCnt + 1;
+    ATTiny84, Arduino, MicroBitV2: saveCnt := saveCnt + 1;
   end;
   addr := adrpage + Data;
 end;
@@ -1056,7 +1128,7 @@ begin
   if (Data = 0) then
   begin
     case version of
-      ATTiny84, Arduino:
+      ATTiny84, Arduino, MicroBitV2:
       begin
         if (saveCnt = 0) then
         begin
@@ -1069,7 +1141,7 @@ begin
     addr := saveaddr[saveCnt];
     exit;
   end;
-  if ((Data <= 6) and ((version = ATTiny84) or (version = Arduino))) then
+  if ((Data <= 6) and ((version = ATTiny84) or (version = Arduino) or (version = MicroBitV2))) then
   begin
     // call subroutine number
     saveaddr[saveCnt] := addr;
@@ -1077,7 +1149,9 @@ begin
     addr := subs[Data];
     exit;
   end;
-  if ((Data = $0f) and ((version = ATTiny84) or (version = Arduino))) then
+  if ((Data = $0f) and ((version = ATTiny84) or (version = Arduino) or (version = MicroBitV2))) then
+
+
   begin
     doReset();
     exit;
@@ -1091,16 +1165,16 @@ begin
   // Some byte commands
   case (Data) of
     0: case version of
-        ATTiny84, Arduino: a := adc1;
+        ATTiny84, Arduino, MicroBitV2: a := adc1;
       end;
     1: case version of
-        ATTiny84, Arduino: a := adc2;
+        ATTiny84, Arduino, MicroBitV2: a := adc2;
       end;
     2: case version of
-        ATTiny84, Arduino: a := rc1;
+        ATTiny84, Arduino, MicroBitV2: a := rc1;
       end;
     3: case version of
-        ATTiny84, Arduino: a := rc2;
+        ATTiny84, Arduino, MicroBitV2: a := rc2;
       end;
     4: pwm1 := a;
     5: pwm2 := a;
@@ -1122,8 +1196,45 @@ begin
     end;
     8:
       case version of
-        ATTiny84, Arduino: doTone(Data);
+        ATTiny84, Arduino, MicroBitV2: doTone(Data);
+      end;
+    9:
+      case version of
+        MicroBitV2:
+        begin
+          a := acc_x;
+          e := acc_y;
+          f := acc_z;
+        end;
+      end;
+    10:
+      case version of
+        MicroBitV2: a := compass;
+      end;
+    11:
+      case version of
+        MicroBitV2: a := soundLevel;
+      end;
+    12:
+      case version of
+        MicroBitV2: a := lightLevel;
+      end;
+    13:
+      case version of
+        MicroBitV2: if sw_logo then
+            a := 1;
+        else
+          a := 0;
       end;
+    14:
+      case version of
+        MicroBitV2: a := gesture;
+      end;
+    15:
+    begin
+      addr := 0;
+      exit;
+    end;
   end;
 end;
 
@@ -1135,6 +1246,41 @@ begin
     tone := 0;
 end;
 
+procedure TSPS.setACC(x, y, z: byte);
+begin
+
+end;
+
+procedure TSPS.setComp(Data: byte);
+begin
+
+end;
+
+procedure TSPS.setSnd(Data: byte);
+begin
+
+end;
+
+function TSPS.getDisplay(): TMBImage;
+begin
+  Result := display;
+end;
+
+procedure TSPS.setLight(Data: byte);
+begin
+
+end;
+
+procedure TSPS.setGesture(Data: byte);
+begin
+
+end;
+
+procedure TSPS.setLogo(Data: boolean);
+begin
+
+end;
+
 procedure TSPS.push(Data: byte);
 begin
   stack.Push(Data);

Some files were not shown because too many files changed in this diff