| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337 | unit uSPS;{$mode objfpc}{$H+}interfaceuses  Classes, SysUtils, MCSTools, uMicrobit;const  CMD_NULL = $00;  PORT = $10;  DELAY = $20;  JUMP_BACK = $30;  SET_A = $40;  IS_A = $50;  A_IS = $60;  CALC = $70;  PAGE = $80;  JUMP = $90;  C_COUNT = $A0;  D_COUNT = $B0;  SKIP_IF = $C0;  CALL = $D0;  CALL_SUB = $E0;  CMD_BYTE = $F0;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/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',    'Output 0111', 'Output 1000', 'Output 1001', 'Output 1010', 'Output 1011',    'Output 1100', 'Output 1101', 'Output 1110', 'Output 1111');  DELAY_LIST: array[0..15] of string = ('Delay 1ms', 'Delay 2ms',    'Delay 5ms', 'Delay 10ms', 'Delay 20ms', 'Delay 50ms', 'Delay 100ms',    'Delay 200ms', 'Delay 500ms', 'Delay 1s', 'Delay 2s', 'Delay 5s',    'Delay 10s', 'Delay 20s', 'Delay 30s', 'Delay 60s');  JUMP_B_LIST: array[0..15] of string = ('jump -0', 'jump -1',    'jump -2', 'jump -3', 'jump -4', 'jump -5', 'jump -6',    'jump -7', 'jump -8', 'jump -9', 'jump -10', 'jump -11',    'jump -12', 'jump -13', 'jump -14', 'jump -15');  A_LIST: array[0..15] of string = ('A=0', 'A=1',    'A=2', 'A=3', 'A=4', 'A=5', 'A=6',    'A=7', 'A=8', 'A=9', 'A=10', 'A=11',    'A=12', 'A=13', 'A=14', 'A=15');  IS_A_LIST_H: array[0..15] of string = ('', 'B=A',    'C=A', 'D=A', 'Dout=A', 'Dout.1=A.0', 'Dout.2=A.0',    'Dout.3=A.0', 'Dout.4=A.0', 'PWM.1=A', '', '',    '', '', '', '');  IS_A_LIST_A8: array[0..15] of string = ('', 'B=A',    'C=A', 'D=A', 'Dout=A', 'Dout.1=A.0', 'Dout.2=A.0',    'Dout.3=A.0', 'Dout.4=A.0', 'PWM.1=A', 'PWM.2=A', '',    '', '', '', '');  IS_A_LIST_AT: array[0..15] of string = ('A<->B', 'B=A',    'C=A', 'D=A', 'Dout=A', 'Dout.1=A.0', 'Dout.2=A.0',    'Dout.3=A.0', 'Dout.4=A.0', 'PWM.1=A', 'PWM.2=A', 'Servo.1=A',    'Servo.2=A', 'E=A', 'F=A', 'Push A');  A_IS_LIST_H: array[0..15] of string = ('', 'A=B',    'A=C', 'A=D', 'A=Din', 'A=Din.1', 'A=Din.2',    'A=Din.3', 'A=Din.4', 'A=ADC.1', 'A=ADC.2', '',    '', '', '', '');  A_IS_LIST_A8: array[0..15] of string = ('', 'A=B',    'A=C', 'A=D', 'A=Din', 'A=Din.1', 'A=Din.2',    'A=Din.3', 'A=Din.4', 'A=ADC.1', 'A=ADC.2', '',    '', '', '', '');  A_IS_LIST_AT: array[0..15] of string = ('', 'A=B',    'A=C', 'A=D', 'A=Din', 'A=Din.1', 'A=Din.2',    'A=Din.3', 'A=Din.4', 'A=ADC.1', 'A=ADC.2', 'A=RC.1',    'A=RC.2', 'A=E', 'A=F', 'Pop A');  A_CALC_LIST_H: array[0..15] of string = ('', 'A=A+1',    'A=A-1', 'A=A+B', 'A=A-B', 'A=A*B', 'A=A/B',    'A=A And B', 'A=A Or B', 'A=A Xor B', 'A=Not A', '',    '', '', '', '');  A_CALC_LIST_AT: array[0..15] of string = ('', 'A=A+1',    'A=A-1', 'A=A+B', 'A=A-B', 'A=A*B', 'A=A/B',    'A=A And B', 'A=A Or B', 'A=A Xor B', 'A=Not A', 'A=A % B',    'A=A+16*B', 'A = B - A', 'A=A SHR 1', 'A=A SHL 1');  PAGE_LIST_H: array[0..15] of string = ('Page 0', 'Page 1',    'Page 2', 'Page 3', 'Page 4', 'Page 5', 'Page 6',    'Page 7', '', '', '', '', '', '', '', '');  PAGE_LIST_AT: array[0..15] of string = ('Page 0', 'Page 1',    'Page 2', 'Page 3', 'Page 4', 'Page 5', 'Page 6',    'Page 7', 'Page 8', 'Page 9', 'Page A', 'Page B',    'Page C', 'Page D', 'Page E', 'Page F');  JUMP_LIST: array[0..15] of string = ('Jump 0', 'Jump 1',    'Jump 2', 'Jump 3', 'Jump 4', 'Jump 5', 'Jump 6',    'Jump 7', 'Jump 8', 'Jump 9', 'Jump A', 'Jump B',    'Jump C', 'Jump D', 'Jump E', 'Jump F');  C_LIST: array[0..15] of string = ('C 0', 'C 1',    'C 2', 'C 3', 'C 4', 'C 5', 'C 6',    'C 7', 'C 8', 'C 9', 'C A', 'C B',    'C C', 'C D', 'C E', 'C F');  D_LIST: array[0..15] of string = ('D 0', 'D 1',    'D 2', 'D 3', 'D 4', 'D 5', 'D 6',    'D 7', 'D 8', 'D 9', 'D A', 'D B',    'D C', 'D D', 'D E', 'D F');  SKIP_LIST_H: array[0..15] of string = ('', 'A>B',    'A<B', 'A=B', 'Din.1=1', 'Din.2=1', 'Din.3=1',    'Din.4=1', 'Din.1=0', 'Din.2=0', 'Din.3=0', 'Din.4=0',    'S_SEL=0', 'S_PRG=0', 'S_SEL=1', 'S_PRG=1');  SKIP_LIST_A8: array[0..15] of string = ('', 'A>B',    'A<B', 'A=B', 'Din.1=1', 'Din.2=1', 'Din.3=1',    'Din.4=1', 'Din.1=0', 'Din.2=0', 'Din.3=0', 'Din.4=0',    'S_SEL=0', 'S_PRG=0', 'S_SEL=1', 'S_PRG=1');  SKIP_LIST_AT: array[0..15] of string = ('A=0', 'A>B',    'A<B', 'A=B', 'Din.1=1', 'Din.2=1', 'Din.3=1',    'Din.4=1', 'Din.1=0', 'Din.2=0', 'Din.3=0', 'Din.4=0',    'S_SEL=0', 'S_PRG=0', 'S_SEL=1', 'S_PRG=1');  CALL_LIST: array[0..15] of string = ('Jump 0', 'Jump 1',    'Jump 2', 'Jump 3', 'Jump 4', 'Jump 5', 'Jump 6',    'Jump 7', 'Jump 8', 'Jump 9', 'Jump A', 'Jump B',    'Jump C', 'Jump D', 'Jump E', 'Jump F');  RET_LIST_H: array[0..15] of string = ('Return', '',    '', '', '', '', '', '', '', '', '', '', '', '', '', '');  RET_LIST_AT: array[0..15] of string = ('Return', 'Call 1',    'Call 2', 'Call 3', 'Call 4', 'Call 5', 'Call 6',    '', 'Def 1', 'Def 2', 'Def 3', 'Def 4', 'Def 5',    'Def 6', '', 'Restart');  F_LIST_H: array[0..15] of string =    ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');  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, MicroBitV2);  { TServo }  TServo = class(TObject)  private    pinno: integer;    myValue: byte;  public    constructor Create();    procedure attach(pin: byte);    function attached: boolean;    function getValue: byte;    procedure Write(Value: byte);  end;  { TDelayCallback }  TDelayCallback = procedure(Value: integer);  { TSPS }  TSPS = class(TObject)  private    { private declarations }    version: TTPSVersion;    dout1, dout2, dout3, dout4: boolean;    din1, din2, din3, din4: boolean;    sw_prg, sw_sel: boolean;    adc1, adc2: byte;    pwm1, pwm2: byte;    rc1, rc2: byte;    subs: array[1..6] of word;    saveaddr: array[0..15] of word;    saveCnt: byte;    eeprom: array[0..1024] of byte;    e2e: word;    adrPage: byte;    addr: word;    jumpAddr: word;    a, b, c, d, e, f: byte;    servo1, servo2: TServo;    tone: integer;    active: boolean;    stop: boolean;    stack: TByteStack;    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;    errorMessage: string;    procedure doNull(Data: byte);    procedure doPort(Data: byte);    procedure doDelay(Data: byte);    procedure doJumpBack(Data: byte);    procedure doSetA(Data: byte);    procedure doAIs(Data: byte);    procedure doIsA(Data: byte);    procedure doCalc(Data: byte);    procedure doPage(Data: byte);    procedure doJump(Data: byte);    procedure doCCount(Data: byte);    procedure doDCount(Data: byte);    procedure doSkipIf(Data: byte);    procedure doCall(Data: byte);    procedure doCallSub(Data: byte);    procedure doByte(Data: byte);    procedure doTone(Data: byte);    procedure push(Data: byte);    function pop(): byte;  public    { public declarations }    constructor Create;    destructor Destroy; override;    procedure setDelayCallback(callback: TDelayCallback);    function isDout1(): boolean;    function isDout2(): boolean;    function isDout3(): boolean;    function isDout4(): boolean;    function getPWM1(): byte;    function getPWM2(): byte;    function getServo1(): byte;    function getServo2(): byte;    function getTone(): integer;    procedure setDin1(Data: boolean);    procedure setDin2(Data: boolean);    procedure setDin3(Data: boolean);    procedure setDin4(Data: boolean);    procedure setSPrg(Data: boolean);    procedure setSSel(Data: boolean);    procedure setADC1(Data: byte);    procedure setADC2(Data: byte);    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();    procedure break();    procedure doSingleCommand(command: byte);    procedure preFetch();    function getLastError():string;    procedure writeEEProm(adr: word; Data: byte);    function getE2E():word;    function isActive(): boolean;    function isDelayActive(): boolean;    function getAddress(): word;    function getPage(): word;    function getRAdr(): word;    procedure getStack(List: TStrings);    function getARegister(): byte;    function getBRegister(): byte;    function getCRegister(): byte;    function getDRegister(): byte;    function getERegister(): byte;    function getFRegister(): byte;    procedure setTPSVersion(tpsversion: TTPSVersion);    procedure getCommands(list: TStrings);    procedure getDatas(cmd: byte; list: TStrings);    function getCommandText(cmd, Data: byte): string;    function getJump(): byte;  end;implementationuses Math, MCSStrings, LCLProc;{ TServo }constructor TServo.Create;begin  pinno := -1;end;procedure TServo.attach(pin: byte);begin  pinno := pin;end;function TServo.attached: boolean;begin  Result := pinno > -1;end;function TServo.getValue: byte;begin  Result := myValue;end;procedure TServo.Write(Value: byte);begin  myValue := Value;end;{ TSPS }function TSPS.isDout1(): boolean;begin  Result := dout1;end;function TSPS.isDout2(): boolean;begin  Result := dout2;end;function TSPS.isDout3(): boolean;begin  Result := dout3;end;function TSPS.isDout4(): boolean;begin  Result := dout4;end;function TSPS.getPWM1(): byte;begin  Result := pwm1;end;function TSPS.getPWM2(): byte;begin  Result := pwm2;end;function TSPS.getServo1(): byte;begin  Result := servo1.getValue;end;function TSPS.getServo2(): byte;begin  Result := servo2.getValue;end;function TSPS.getTone(): integer;begin  Result := tone;end;procedure TSPS.setDin1(Data: boolean);begin  din1 := Data;end;procedure TSPS.setDin2(Data: boolean);begin  din2 := Data;end;procedure TSPS.setDin3(Data: boolean);begin  din3 := Data;end;procedure TSPS.setDin4(Data: boolean);begin  din4 := Data;end;procedure TSPS.setSPrg(Data: boolean);begin  sw_prg := Data;end;procedure TSPS.setSSel(Data: boolean);begin  sw_sel := Data;end;procedure TSPS.setADC1(Data: byte);begin  adc1 := Data;end;procedure TSPS.setADC2(Data: byte);begin  adc2 := Data;end;procedure TSPS.setRC1(Data: byte);begin  rc1 := Data;end;procedure TSPS.setRC2(Data: byte);begin  rc2 := Data;end;procedure TSPS.nextStep();var  Value: byte;  oldAddr : word;begin  errorMessage := '';  Value := eeprom[addr];  oldAddr := addr;  addr := addr + 1;  doSingleCommand(Value);  if (addr > e2e) then  begin    addr := 0;    // errorMessage := 'Address out of range after address: 0x' + IntToHex(oldAddr, 2);    // doReset();  end  else begin    preFetch();  end;end;procedure TSPS.doReset();begin  a := 0;  b := 0;  c := 0;  d := 0;  e := 0;  f := 0;  stack.Reset();  active := False;  din1 := False;  din2 := False;  din3 := False;  din4 := False;  dout1 := False;  dout2 := False;  dout3 := False;  dout4 := False;  addr := 0;  adrPage := 0;  pwm2 := 0;  pwm1 := 0;  adc1 := 0;  adc2 := 0;  saveCnt := 0;  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();var  Value, cmd, Data: byte;  x: integer;begin  doReset();  for x := 0 to e2e do  begin    Value := eeprom[x];    cmd := (Value and $F0);    Data := (Value and $0F);    if (cmd = CALL_SUB) then    begin      if (Data >= 8) then      begin        Data := Data - 7;        subs[Data] := x + 1;      end;    end;    if ((cmd = IS_A) and (Data = $0B)) then    begin      servo1.attach(0);    end;    if ((cmd = IS_A) and (Data = $0C)) then    begin      servo2.attach(1);    end;    if ((cmd = CMD_BYTE) and (Data = $06)) then    begin      servo1.attach(0);    end;    if ((cmd = CMD_BYTE) and (Data = $07)) then    begin      servo2.attach(1);    end;  end;  active := True;end;procedure TSPS.break();begin  stop := True;end;procedure TSPS.doSingleCommand(command: byte);var  cmd, Data: byte;begin  cmd := (command and $F0);  Data := (command and $0F);  case cmd of    CMD_NULL: doNull(Data);    PORT: doPort(Data);    DELAY: doDelay(Data);    JUMP_BACK: doJumpBack(Data);    SET_A: doSetA(Data);    A_IS: doAIs(Data);    IS_A: doIsA(Data);    CALC: doCalc(Data);    PAGE: doPage(Data);    JUMP: doJump(Data);    C_COUNT: doCCount(Data);    D_COUNT: doDCount(Data);    SKIP_IF: doSkipIf(Data);    CALL: doCall(Data);    CALL_SUB: doCallSub(Data);    CMD_BYTE: doByte(Data);  end;end;procedure TSPS.preFetch();var  cmd, Data: byte;  skip: boolean;begin  jumpAddr := 0;  skip := False;  cmd := eeprom[addr];  Data := (cmd and $0F);  cmd := (cmd and $F0);  case cmd of    C_COUNT:    begin      if (c > 0) then        jumpAddr := Data + 16 * Page;    end;    D_COUNT:    begin      if (d > 0) then        jumpAddr := Data + 16 * Page;    end;    JUMP_BACK: jumpAddr := addr - Data;    JUMP: jumpAddr := Data + 16 * Page;    SKIP_IF:    begin      case Data of        0: if (a = 0) then            case version of              ATTiny84, Arduino, Microbit, MicroBitV2: skip := True;            end;        1: if (a > b) then            skip := True;        2: if (a < b) then            skip := True;        3: if (a = b) then            skip := True;        4: if (din1) then            skip := True;        5: if (din2) then            skip := True;        6: if (din3) then            skip := True;        7: if (din4) then            skip := True;        8: if (not din1) then            skip := True;        9: if (not din2) then            skip := True;        10: if (not din3) then            skip := True;        11: if (not din4) then            skip := True;        12: if (sw_sel) then            skip := True;        13: if (sw_prg) then            skip := True;        14: if (not sw_sel) then            skip := True;        15: if (not sw_prg) then            skip := True;      end;      if (skip = True) then        jumpAddr := addr + 2;    end;  end;end;function TSPS.getLastError(): string;begin  result := errorMessage;end;procedure TSPS.writeEEProm(adr: word; Data: byte);begin  if adr < e2e then  eeprom[adr] := Data;end;function TSPS.getE2E(): word;begin   Result := e2e;end;function TSPS.isActive(): boolean;begin  Result := active;end;function TSPS.isDelayActive(): boolean;begin  Result := delayActive;end;function TSPS.getAddress(): word;begin  Result := addr;end;function TSPS.getPage(): word;begin  Result := adrPage div 16;end;function TSPS.getRAdr(): word;begin  if (saveCnt = 0) then  begin    Result := 0;  end;  Result := saveaddr[saveCnt - 1];end;procedure TSPS.getStack(List: TStrings);var  i: integer;begin  for i := 0 to stack.Count - 1 do  begin    List.Add(IntToHex(stack.peek(i), 2));  end;end;function TSPS.getARegister(): byte;begin  Result := a;end;function TSPS.getBRegister(): byte;begin  Result := b;end;function TSPS.getCRegister(): byte;begin  Result := c;end;function TSPS.getDRegister(): byte;begin  Result := d;end;function TSPS.getERegister(): byte;begin  Result := e;end;function TSPS.getFRegister(): byte;begin  Result := f;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);begin  MCSStrings.copyArray2List(COMMANDS, list);end;procedure TSPS.getDatas(cmd: byte; list: TStrings);begin  if (cmd = 0) then  begin    case version of      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  begin    MCSStrings.copyArray2List(DOUT_LIST, list);  end;  if (cmd = 2) then    MCSStrings.copyArray2List(DELAY_LIST, list);  if (cmd = 3) then    MCSStrings.copyArray2List(JUMP_B_LIST, list);  if (cmd = 4) then    MCSStrings.copyArray2List(A_LIST, list);  if (cmd = 5) then  begin    case version of      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;  end;  if (cmd = 6) then  begin    case version of      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;  end;  if (cmd = 7) then  begin    case version of      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, MicroBitV2: MCSStrings.copyArray2List(PAGE_LIST_AT, list);    end;  end;  if (cmd = 9) then    MCSStrings.copyArray2List(JUMP_LIST, list);  if (cmd = 10) then    MCSStrings.copyArray2List(C_LIST, list);  if (cmd = 11) then    MCSStrings.copyArray2List(D_LIST, list);  if (cmd = 12) then  begin    case version of      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;  end;  if (cmd = 13) then    MCSStrings.copyArray2List(CALL_LIST, list);  if (cmd = 14) then  begin    case version of      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: MCSStrings.copyArray2List(F_LIST_AT, list);      MicroBitV2: MCSStrings.copyArray2List(F_LIST_MB, list);    end;  end;end;function TSPS.getCommandText(cmd, Data: byte): string;var  list: TStrings;  line: string;begin  if ((cmd >= 0) and (cmd < 16)) then  begin    list := TStringList.Create;    getDatas(cmd, list);    if ((Data >= 0) and (Data < 16)) then      line := COMMANDS[cmd] + ':' + list[Data];    list.Free;  end;  Result := line;end;function TSPS.getJump(): byte;begin  Result := jumpAddr;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[4];          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 portprocedure TSPS.doPort(Data: byte);begin  dout1 := (Data and $01) > 0;  dout2 := (Data and $02) > 0;  dout3 := (Data and $04) > 0;  dout4 := (Data and $08) > 0;end;// delay in msprocedure TSPS.doDelay(Data: byte);var  delayValue: integer;  x: integer;begin  case Data of    0: delayValue := 1;    1: delayValue := 2;    2: delayValue := 5;    3: delayValue := 10;    4: delayValue := 20;    5: delayValue := 50;    6: delayValue := 100;    7: delayValue := 200;    8: delayValue := 500;    9: delayValue := 1000;    10: delayValue := 2000;    11: delayValue := 5000;    12: delayValue := 10000;    13: delayValue := 20000;    14: delayValue := 30000;    15: delayValue := 60000;  end;  delayActive := True;  repeat    if (delayValue >= 100) then    begin      Dec(delayValue, 100);      Sleep(100);      delayCallback(delayValue);    end;  until ((delayValue <= 100) or stop);  delayCallback(0);  delayActive := False;end;// jump relative backprocedure TSPS.doJumpBack(Data: byte);begin  addr := addr - Data - 1;end;// a = dataprocedure TSPS.doSetA(Data: byte);begin  a := Data;end;// a = somthing;procedure TSPS.doAIs(Data: byte);begin  case Data of    1: a := b;    2: a := c;    3: a := d;    4:    begin      a := 0;      if (din1) then        a := a + 1;      if (din2) then        a := a + 2;      if (din3) then        a := a + 4;      if (din4) then        a := a + 8;    end;    5: if (din1) then        a := 1      else        a := 0;    6: if (din2) then        a := 1      else        a := 0;    7: if (din3) then        a := 1      else        a := 0;    8: if (din4) then        a := 1      else        a := 0;    9: a := adc1 and $0f; //(Umrechnen auf 4 bit)    10: a := adc2 and $0f; //(Umrechnen auf 4 bit)    11: a := rc1 and $0f; //(Umrechnen auf 4 bit)    12: a := rc2 and $0f; //(Umrechnen auf 4 bit)    13: a := e;    14: a := f;    15: a := pop();  end;end;// somthing = a;procedure TSPS.doIsA(Data: byte);var  tmpValue: byte;begin  case Data of    0: case version of        ATTiny84, Arduino, MicroBitV2:        begin          tmpValue := b;          b := a;          a := tmpValue;        end;      end;    1: b := a;    2: c := a;    3: d := a;    4: doPort(a);    5: dout1 := (a and $01) > 0;    6: dout2 := (a and $01) > 0;    7: dout3 := (a and $01) > 0;    8: dout4 := (a and $01) > 0;    9:    begin      pwm1 := a * 16;      case version of        Holtek:        begin          pwm1 := a;        end;      end;    end;    10: pwm2 := a * 16;    11:    begin      if (servo1.attached()) then        servo1.Write(((a and 15)  * 10) + 10);    end;    12:    begin      if (servo2.attached()) then        servo2.Write(((a and 15) * 10) + 10);    end;    13: e := a;    14: f := a;    15: push(a);  end;end;// calculationsprocedure TSPS.doCalc(Data: byte);begin  case Data of    1: a := a + 1;    2: a := a - 1;    3: a := a + b;    4: a := a - b;    5: a := a * b;    6: a := a div b;    7: a := a and b;    8: a := a or b;    9: a := a xor b;    10: a := not a;    11: case version of        ATTiny84, Arduino, MicroBitV2: a := a mod b;      end;    12: case version of        ATTiny84, Arduino, MicroBitV2: a := a + 16 * b;      end;    13: case version of        ATTiny84, Arduino, MicroBitV2: a := b - a;      end;    14: case version of        ATTiny84, Arduino, MicroBitV2: a := a shr 1;      end;    15: case version of        ATTiny84, Arduino, MicroBitV2: a := a shl 1;      end;  end;  case version of    Holtek, ATMega8, Microbit: a := a and 15;  end;end;// setting pageprocedure TSPS.doPage(Data: byte);begin  adrPage := Data * 16;end;// jump absoluteprocedure TSPS.doJump(Data: byte);begin  addr := adrPage + Data;end;// counting with c registerprocedure TSPS.doCCount(Data: byte);begin  if (c > 0) then  begin    c := c - 1;    c := c and $0F;    doJump(Data);  end;end;// counting with d registerprocedure TSPS.doDCount(Data: byte);begin  if (d > 0) then  begin    d := d - 1;    d := d and $0F;    doJump(Data);  end;end;// simple comdition = true skip next commandprocedure TSPS.doSkipIf(Data: byte);begin  case (Data) of    0: if (a = 0) then        case version of          ATTiny84, Arduino, Microbit, MicroBitV2: addr := addr + 1;        end;    1: if (a > b) then        addr := addr + 1;    2: if (a < b) then        addr := addr + 1;    3: if (a = b) then        addr := addr + 1;    4: if (din1) then        addr := addr + 1;    5: if (din2) then        addr := addr + 1;    6: if (din3) then        addr := addr + 1;    7: if (din4) then        addr := addr + 1;    8: if (not din1) then        addr := addr + 1;    9: if (not din2) then        addr := addr + 1;    10: if (not din3) then        addr := addr + 1;    11: if (not din4) then        addr := addr + 1;    12: if (sw_sel) then        addr := addr + 1;    13: if (sw_prg) then        addr := addr + 1;    14: if (not sw_sel) then        addr := addr + 1;    15: if (not sw_prg) then        addr := addr + 1;  end;end;// calling a subroutineprocedure TSPS.doCall(Data: byte);begin  saveaddr[saveCnt] := addr;  case version of    ATTiny84, Arduino, MicroBitV2: saveCnt := saveCnt + 1;  end;  addr := adrpage + Data;end;// calling a subroutine, calling return and restartprocedure TSPS.doCallSub(Data: byte);begin  if (Data = 0) then  begin    case version of      ATTiny84, Arduino, MicroBitV2:      begin        if (saveCnt = 0) then        begin          doReset();          exit;        end;        saveCnt := saveCnt - 1;      end;    end;    addr := saveaddr[saveCnt];    exit;  end;  if ((Data <= 6) and ((version = ATTiny84) or (version = Arduino) or (version = MicroBitV2))) then  begin    // call subroutine number    saveaddr[saveCnt] := addr;    saveCnt := saveCnt + 1;    addr := subs[Data];    exit;  end;  if ((Data = $0f) and ((version = ATTiny84) or (version = Arduino) or (version = MicroBitV2))) then  begin    doReset();    exit;  end;end;procedure TSPS.doByte(Data: byte);var  Value: integer;begin  // Some byte commands  case (Data) of    0: case version of        ATTiny84, Arduino, MicroBitV2: a := adc1;      end;    1: case version of        ATTiny84, Arduino, MicroBitV2: a := adc2;      end;    2: case version of        ATTiny84, Arduino, MicroBitV2: a := rc1;      end;    3: case version of        ATTiny84, Arduino, MicroBitV2: a := rc2;      end;    4: pwm1 := a;    5: pwm2 := a;    6:    begin      if (servo1.attached()) then      begin        Value := (180 * a) div 255;        servo1.Write(Value);      end;    end;    7:    begin      if (servo2.attached()) then      begin        Value := (180 * a) div 255;        servo2.Write(Value);      end;    end;    8:      case version of        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;procedure TSPS.doTone(Data: byte);begin  if (a in [36..109]) then    tone := a  else    tone := 0;end;procedure TSPS.setACC(x, y, z: byte);beginend;procedure TSPS.setComp(Data: byte);beginend;procedure TSPS.setSnd(Data: byte);beginend;function TSPS.getDisplay(): TMBImage;begin  Result := display;end;procedure TSPS.setLight(Data: byte);beginend;procedure TSPS.setGesture(Data: byte);beginend;procedure TSPS.setLogo(Data: boolean);beginend;procedure TSPS.push(Data: byte);begin  stack.Push(Data);end;function TSPS.pop(): byte;begin  Result := stack.pop;end;constructor TSPS.Create;begin  servo1 := TServo.Create();  servo2 := TServo.Create();  stack := TByteStack.Create;  stop := False;  delayActive := False;end;destructor TSPS.Destroy;begin  inherited Destroy;  servo1.Free;  servo2.Free;  stack.Free;end;procedure TSPS.setDelayCallback(callback: TDelayCallback);begin  delayCallback := callback;end;end.
 |