12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337 |
- 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: 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;
- 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
- 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 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.
|