1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327 |
- unit uSPS;
- {$mode objfpc}{$H+}
- interface
- uses
- 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: byte; Data: byte);
- 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;
- implementation
- uses 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
- errorMessage := 'Address out of range after address: 0x' + IntToHex(oldAddr, 2);
- doReset();
- end;
- preFetch();
- 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: byte; Data: byte);
- begin
- eeprom[adr] := Data;
- 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 port
- procedure 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 ms
- procedure 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 back
- procedure TSPS.doJumpBack(Data: byte);
- begin
- addr := addr - Data - 1;
- end;
- // a = data
- procedure 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 * 10) + 10);
- end;
- 12:
- begin
- if (servo2.attached()) then
- servo2.Write((a * 10) + 10);
- end;
- 13: e := a;
- 14: f := a;
- 15: push(a);
- end;
- end;
- // calculations
- procedure 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 page
- procedure TSPS.doPage(Data: byte);
- begin
- adrPage := Data * 16;
- end;
- // jump absolute
- procedure TSPS.doJump(Data: byte);
- begin
- addr := adrPage + Data;
- end;
- // counting with c register
- procedure TSPS.doCCount(Data: byte);
- begin
- if (c > 0) then
- begin
- c := c - 1;
- c := c and $0F;
- doJump(Data);
- end;
- end;
- // counting with d register
- procedure 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 command
- procedure 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 subroutine
- procedure 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 restart
- procedure 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);
- 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);
- 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.
|