소스 검색

adding microbit v2 implementation

Klaas, Wilfried 3 년 전
부모
커밋
c9ea806ddd
11개의 변경된 파일1223개의 추가작업 그리고 77개의 파일을 삭제
  1. 7 15
      Beispiele/Tone.tps
  2. 2 2
      SPS_EMU.000
  3. 15 2
      SPS_Emu.lpi
  4. 2 1
      SPS_Emu.lpr
  5. BIN
      SPS_Emu.lsu
  6. 4 3
      ugui.lfm
  7. 106 30
      ugui.pas
  8. 386 0
      uimicrobit.lfm
  9. 131 0
      uimicrobit.pas
  10. 404 0
      umicrobit.pas
  11. 166 24
      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,3,""
+0x04,3,3,""
+0x05,F,F,""

+ 2 - 2
SPS_EMU.000

@@ -2,8 +2,8 @@
 LSUTextFile=1
 Copyrigth=MCS Media Computer Software
 [LSUInfo]
-CompileDate=03.05.2021
-CompileTime=14:32:31
+CompileDate=05.05.2021
+CompileTime=21:37:25
 Name=Wilfried Klaas
 LSUBinFile=H:\privat\git-sourcen\SPS_Emulator\SPS_Emu.lsu
 LSUTextFile=H:\privat\git-sourcen\SPS_Emulator\SPS_Emu.

+ 15 - 2
SPS_Emu.lpi

@@ -22,7 +22,7 @@
       <AutoIncrementBuild Value="True"/>
       <MinorVersionNr Value="2"/>
       <RevisionNr Value="1"/>
-      <BuildNr Value="81"/>
+      <BuildNr Value="83"/>
       <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>
@@ -67,7 +67,7 @@
         <PackageName Value="LCL"/>
       </Item3>
     </RequiredPackages>
-    <Units Count="7">
+    <Units Count="9">
       <Unit0>
         <Filename Value="SPS_Emu.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -114,6 +114,19 @@
         <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>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

+ 2 - 1
SPS_Emu.lpr

@@ -7,7 +7,7 @@ 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 +22,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


+ 4 - 3
ugui.lfm

@@ -1,7 +1,7 @@
 object Form1: TForm1
-  Left = 241
+  Left = 243
   Height = 584
-  Top = 118
+  Top = 113
   Width = 959
   AllowDropFiles = True
   Caption = 'SPS Emulator'
@@ -9,6 +9,7 @@ object Form1: TForm1
   ClientWidth = 959
   Constraints.MinHeight = 582
   Constraints.MinWidth = 684
+  OnActivate = FormActivate
   OnCloseQuery = FormCloseQuery
   OnCreate = FormCreate
   OnDropFiles = FormDropFiles
@@ -1151,7 +1152,7 @@ object Form1: TForm1
       end>
     OnSavingProperties = XMLPropStorage1SavingProperties
     OnRestoringProperties = XMLPropStorage1RestoringProperties
-    Left = 496
+    Left = 784
     Top = 496
   end
   object SaveDialog1: TSaveDialog

+ 106 - 30
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,8 +178,7 @@ 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);
@@ -220,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;
@@ -230,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}
 
@@ -615,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;
@@ -797,9 +801,11 @@ begin
   begin
     acNextStep.Enabled := False;
     acStop.Enabled := False;
+    inputMicrobit();
     inputSps();
     sps.nextStep();
     outputSps();
+    outputMicrobit();
     acNextStep.Enabled := True;
     acStop.Enabled := True;
   end;
@@ -884,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;
@@ -1112,8 +1117,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);
@@ -1243,8 +1247,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;
@@ -1259,8 +1262,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;
 
@@ -1316,6 +1318,7 @@ begin
     ADC1.MaxValue := 15;
     ADC2.Value := 0;
     ADC2.MaxValue := 15;
+    enableMicrobit(False);
   end;
   if (cbTPSVersion.ItemIndex = 1) then
   begin
@@ -1342,6 +1345,7 @@ begin
     ADC1.MaxValue := 15;
     ADC2.Value := 0;
     ADC2.MaxValue := 15;
+    enableMicrobit(False);
   end;
   if ((cbTPSVersion.ItemIndex = 2) or (cbTPSVersion.ItemIndex = 3)) then
   begin
@@ -1380,6 +1384,7 @@ begin
     ADC1.MaxValue := 255;
     ADC2.Value := 0;
     ADC2.MaxValue := 255;
+    enableMicrobit(False);
   end;
 
   if (cbTPSVersion.ItemIndex = 4) then
@@ -1407,6 +1412,7 @@ begin
     ADC1.MaxValue := 15;
     ADC2.Value := 0;
     ADC2.MaxValue := 15;
+    enableMicrobit(False);
   end;
 
   if (cbTPSVersion.ItemIndex = 5) then
@@ -1434,12 +1440,18 @@ begin
     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();
@@ -1467,8 +1479,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;
@@ -1513,7 +1524,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);
@@ -1533,6 +1582,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);
@@ -1540,18 +1597,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);
@@ -1592,10 +1654,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
@@ -1634,6 +1703,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;
 
@@ -1691,8 +1768,8 @@ 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;
@@ -1736,8 +1813,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.

+ 166 - 24
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', '', '',
+    '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, MicroBitV2);
+  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, MicroBitV2: 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);
-      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(O_LIST_AT, 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,7 +732,7 @@ 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, MicroBitV2: MCSStrings.copyArray2List(IS_A_LIST_AT, list);
     end;
@@ -701,7 +740,7 @@ begin
   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, MicroBitV2: MCSStrings.copyArray2List(A_IS_LIST_AT, list);
     end;
@@ -709,14 +748,14 @@ begin
   if (cmd = 7) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(A_CALC_LIST_H, 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);
+      Holtek, ATMega8, Microbit: MCSStrings.copyArray2List(PAGE_LIST_H, list);
       ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(PAGE_LIST_AT, list);
     end;
   end;
@@ -729,7 +768,7 @@ 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, MicroBitV2: MCSStrings.copyArray2List(SKIP_LIST_AT, list);
     end;
@@ -739,15 +778,16 @@ begin
   if (cmd = 14) then
   begin
     case version of
-      Holtek, ATMega8, MicroBit: MCSStrings.copyArray2List(RET_LIST_H, 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);
-      ATTiny84, Arduino, MicroBitV2: MCSStrings.copyArray2List(F_LIST_AT, 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
@@ -954,14 +1026,14 @@ begin
         ATTiny84, Arduino, MicroBitV2: a := b - a;
       end;
     14: case version of
-        ATTiny84, Arduino, MicroBitV2: a := a SHR 1;
+        ATTiny84, Arduino, MicroBitV2: a := a shr 1;
       end;
     15: case version of
-        ATTiny84, Arduino, MicroBitV2: 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, MicroBitV2: addr := addr + 1;
+          ATTiny84, Arduino, Microbit, MicroBitV2: addr := addr + 1;
         end;
     1: if (a > b) then
         addr := addr + 1;
@@ -1078,6 +1150,8 @@ begin
     exit;
   end;
   if ((Data = $0f) and ((version = ATTiny84) or (version = Arduino) or (version = MicroBitV2))) then
+
+
   begin
     doReset();
     exit;
@@ -1124,7 +1198,40 @@ begin
       case version of
         ATTiny84, Arduino, MicroBitV2: doTone(Data);
       end;
-    15: begin
+    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;
@@ -1139,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);