usps.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  1. unit uSPS;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, MCSTools;
  6. const
  7. CMD_NULL = $00;
  8. PORT = $10;
  9. DELAY = $20;
  10. JUMP_BACK = $30;
  11. SET_A = $40;
  12. IS_A = $50;
  13. A_IS = $60;
  14. CALC = $70;
  15. PAGE = $80;
  16. JUMP = $90;
  17. C_COUNT = $A0;
  18. D_COUNT = $B0;
  19. SKIP_IF = $C0;
  20. CALL = $D0;
  21. CALL_SUB = $E0;
  22. CMD_BYTE = $F0;
  23. const
  24. COMMANDS: array[0..15] of string =
  25. ('0', 'Dout', 'Delay', 'Jump -', 'A=#', '=A', 'A=',
  26. 'A=Calculation', 'Page', 'Jump', 'C*', 'D*', 'Skip if', 'Call', 'Ret', 'Byte');
  27. O_LIST_H: array[0..15] of string =
  28. ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
  29. O_LIST_AT: array[0..15] of string =
  30. ('NOP', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
  31. DOUT_LIST: array[0..15] of string = ('Output 0000', 'Output 0001',
  32. 'Output 0010', 'Output 0011', 'Output 0100', 'Output 0101', 'Output 0110',
  33. 'Output 0111', 'Output 1000', 'Output 1001', 'Output 1010', 'Output 1011',
  34. 'Output 1100', 'Output 1101', 'Output 1110', 'Output 1111');
  35. DELAY_LIST: array[0..15] of string = ('Delay 1ms', 'Delay 2ms',
  36. 'Delay 5ms', 'Delay 10ms', 'Delay 20ms', 'Delay 50ms', 'Delay 100ms',
  37. 'Delay 200ms', 'Delay 500ms', 'Delay 1s', 'Delay 2s', 'Delay 5s',
  38. 'Delay 10s', 'Delay 20s', 'Delay 30s', 'Delay 60s');
  39. JUMP_B_LIST: array[0..15] of string = ('jump -0', 'jump -1',
  40. 'jump -2', 'jump -3', 'jump -4', 'jump -5', 'jump -6',
  41. 'jump -7', 'jump -8', 'jump -9', 'jump -10', 'jump -11',
  42. 'jump -12', 'jump -13', 'jump -14', 'jump -15');
  43. A_LIST: array[0..15] of string = ('A=0', 'A=1',
  44. 'A=2', 'A=3', 'A=4', 'A=5', 'A=6',
  45. 'A=7', 'A=8', 'A=9', 'A=10', 'A=11',
  46. 'A=12', 'A=13', 'A=14', 'A=15');
  47. IS_A_LIST_H: array[0..15] of string = ('', 'B=A',
  48. 'C=A', 'D=A', 'Dout=A', 'Dout.1=A.0', 'Dout.2=A.0',
  49. 'Dout.3=A.0', 'Dout.4=A.0', 'PWM.1=A', '', '',
  50. '', '', '', '');
  51. IS_A_LIST_A8: array[0..15] of string = ('', 'B=A',
  52. 'C=A', 'D=A', 'Dout=A', 'Dout.1=A.0', 'Dout.2=A.0',
  53. 'Dout.3=A.0', 'Dout.4=A.0', 'PWM.1=A', 'PWM.2=A', '',
  54. '', '', '', '');
  55. IS_A_LIST_AT: array[0..15] of string = ('A<->B', 'B=A',
  56. 'C=A', 'D=A', 'Dout=A', 'Dout.1=A.0', 'Dout.2=A.0',
  57. 'Dout.3=A.0', 'Dout.4=A.0', 'PWM.1=A', 'PWM.2=A', 'Servo.1=A',
  58. 'Servo.2=A', 'E=A', 'F=A', 'Push A');
  59. A_IS_LIST_H: array[0..15] of string = ('', 'A=B',
  60. 'A=C', 'A=D', 'A=Din', 'A=Din.1', 'A=Din.2',
  61. 'A=Din.3', 'A=Din.4', 'A=ADC.1', 'A=ADC.2', '',
  62. '', '', '', '');
  63. A_IS_LIST_A8: array[0..15] of string = ('', 'A=B',
  64. 'A=C', 'A=D', 'A=Din', 'A=Din.1', 'A=Din.2',
  65. 'A=Din.3', 'A=Din.4', 'A=ADC.1', 'A=ADC.2', '',
  66. '', '', '', '');
  67. A_IS_LIST_AT: array[0..15] of string = ('', 'A=B',
  68. 'A=C', 'A=D', 'A=Din', 'A=Din.1', 'A=Din.2',
  69. 'A=Din.3', 'A=Din.4', 'A=ADC.1', 'A=ADC.2', 'A=RC.1',
  70. 'A=RC.2', 'A=E', 'A=F', 'Pop A');
  71. A_CALC_LIST_H: array[0..15] of string = ('', 'A=A+1',
  72. 'A=A-1', 'A=A+B', 'A=A-B', 'A=A*B', 'A=A/B',
  73. 'A=A And B', 'A=A Or B', 'A=A Xor B', 'A=Not A', '',
  74. '', '', '', '');
  75. A_CALC_LIST_AT: array[0..15] of string = ('', 'A=A+1',
  76. 'A=A-1', 'A=A+B', 'A=A-B', 'A=A*B', 'A=A/B',
  77. 'A=A And B', 'A=A Or B', 'A=A Xor B', 'A=Not A', 'A=A % B',
  78. 'A=A+16*B', 'A = B - A', '', '');
  79. PAGE_LIST_H: array[0..15] of string = ('Page 0', 'Page 1',
  80. 'Page 2', 'Page 3', 'Page 4', 'Page 5', 'Page 6',
  81. 'Page 7', '', '', '', '', '', '', '', '');
  82. PAGE_LIST_AT: array[0..15] of string = ('Page 0', 'Page 1',
  83. 'Page 2', 'Page 3', 'Page 4', 'Page 5', 'Page 6',
  84. 'Page 7', 'Page 8', 'Page 9', 'Page A', 'Page B',
  85. 'Page C', 'Page D', 'Page E', 'Page F');
  86. JUMP_LIST: array[0..15] of string = ('Jump 0', 'Jump 1',
  87. 'Jump 2', 'Jump 3', 'Jump 4', 'Jump 5', 'Jump 6',
  88. 'Jump 7', 'Jump 8', 'Jump 9', 'Jump A', 'Jump B',
  89. 'Jump C', 'Jump D', 'Jump E', 'Jump F');
  90. C_LIST: array[0..15] of string = ('C 0', 'C 1',
  91. 'C 2', 'C 3', 'C 4', 'C 5', 'C 6',
  92. 'C 7', 'C 8', 'C 9', 'C A', 'C B',
  93. 'C C', 'C D', 'C E', 'C F');
  94. D_LIST: array[0..15] of string = ('D 0', 'D 1',
  95. 'D 2', 'D 3', 'D 4', 'D 5', 'D 6',
  96. 'D 7', 'D 8', 'D 9', 'D A', 'D B',
  97. 'D C', 'D D', 'D E', 'D F');
  98. SKIP_LIST_H: array[0..15] of string = ('', 'A>B',
  99. 'A<B', 'A=B', 'Din.1=1', 'Din.2=1', 'Din.3=1',
  100. 'Din.4=1', 'Din.1=0', 'Din.2=0', 'Din.3=0', 'Din.4=0',
  101. 'S_SEL=0', 'S_PRG=0', 'S_SEL=1', 'S_PRG=1');
  102. SKIP_LIST_A8: array[0..15] of string = ('', 'A>B',
  103. 'A<B', 'A=B', 'Din.1=1', 'Din.2=1', 'Din.3=1',
  104. 'Din.4=1', 'Din.1=0', 'Din.2=0', 'Din.3=0', 'Din.4=0',
  105. 'S_SEL=0', 'S_PRG=0', 'S_SEL=1', 'S_PRG=1');
  106. SKIP_LIST_AT: array[0..15] of string = ('A=0', 'A>B',
  107. 'A<B', 'A=B', 'Din.1=1', 'Din.2=1', 'Din.3=1',
  108. 'Din.4=1', 'Din.1=0', 'Din.2=0', 'Din.3=0', 'Din.4=0',
  109. 'S_SEL=0', 'S_PRG=0', 'S_SEL=1', 'S_PRG=1');
  110. CALL_LIST: array[0..15] of string = ('Jump 0', 'Jump 1',
  111. 'Jump 2', 'Jump 3', 'Jump 4', 'Jump 5', 'Jump 6',
  112. 'Jump 7', 'Jump 8', 'Jump 9', 'Jump A', 'Jump B',
  113. 'Jump C', 'Jump D', 'Jump E', 'Jump F');
  114. RET_LIST_H: array[0..15] of string = ('Return', '',
  115. '', '', '', '', '', '', '', '', '', '', '', '', '', '');
  116. RET_LIST_AT: array[0..15] of string = ('Return', 'Call 1',
  117. 'Call 2', 'Call 3', 'Call 4', 'Call 5', 'Call 6',
  118. '', 'Def 1', 'Def 2', 'Def 3', 'Def 4', 'Def 5',
  119. 'Def 6', '', 'Restart');
  120. F_LIST_H: array[0..15] of string =
  121. ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
  122. F_LIST_AT: array[0..15] of string = ('A=ADC.1', 'A=ADC.2', 'A=RCin.1', 'A=RCin.2',
  123. 'PWM.1=A', 'PWM.2=A', 'Servo.1=A', 'Servo.2=A', 'Tone=A', '', '', '',
  124. '', '', '', 'PrgEnd');
  125. type
  126. {TPSVersion}
  127. TTPSVersion = (Holtek, ATMega8, ATTiny84, Arduino);
  128. { TServo }
  129. TServo = class(TObject)
  130. private
  131. pinno: integer;
  132. myValue: byte;
  133. public
  134. constructor Create();
  135. procedure attach(pin: byte);
  136. function attached: boolean;
  137. function getValue: byte;
  138. procedure Write(Value: byte);
  139. end;
  140. { TDelayCallback }
  141. TDelayCallback = procedure(Value: integer);
  142. { TSPS }
  143. TSPS = class(TObject)
  144. private
  145. { private declarations }
  146. version: TTPSVersion;
  147. dout1, dout2, dout3, dout4: boolean;
  148. din1, din2, din3, din4: boolean;
  149. sw_prg, sw_sel: boolean;
  150. adc1, adc2: byte;
  151. pwm1, pwm2: byte;
  152. rc1, rc2: byte;
  153. subs: array[1..6] of word;
  154. saveaddr: array[0..15] of word;
  155. saveCnt: byte;
  156. eeprom: array[0..255] of byte;
  157. adrPage: byte;
  158. addr: word;
  159. a, b, c, d, e, f: byte;
  160. servo1, servo2: TServo;
  161. tone: integer;
  162. active: boolean;
  163. stop: boolean;
  164. stack: TByteStack;
  165. delayCallback: TDelayCallback;
  166. delayActive: boolean;
  167. procedure doNull(Data: byte);
  168. procedure doPort(Data: byte);
  169. procedure doDelay(Data: byte);
  170. procedure doJumpBack(Data: byte);
  171. procedure doSetA(Data: byte);
  172. procedure doAIs(Data: byte);
  173. procedure doIsA(Data: byte);
  174. procedure doCalc(Data: byte);
  175. procedure doPage(Data: byte);
  176. procedure doJump(Data: byte);
  177. procedure doCCount(Data: byte);
  178. procedure doDCount(Data: byte);
  179. procedure doSkipIf(Data: byte);
  180. procedure doCall(Data: byte);
  181. procedure doCallSub(Data: byte);
  182. procedure doByte(Data: byte);
  183. procedure doTone(Data: byte);
  184. procedure push(Data: byte);
  185. function pop(): byte;
  186. public
  187. { public declarations }
  188. constructor Create;
  189. destructor Destroy; override;
  190. procedure setDelayCallback(callback: TDelayCallback);
  191. function isDout1(): boolean;
  192. function isDout2(): boolean;
  193. function isDout3(): boolean;
  194. function isDout4(): boolean;
  195. function getPWM1(): byte;
  196. function getPWM2(): byte;
  197. function getServo1(): byte;
  198. function getServo2(): byte;
  199. function getTone(): integer;
  200. procedure setDin1(Data: boolean);
  201. procedure setDin2(Data: boolean);
  202. procedure setDin3(Data: boolean);
  203. procedure setDin4(Data: boolean);
  204. procedure setSPrg(Data: boolean);
  205. procedure setSSel(Data: boolean);
  206. procedure setADC1(Data: byte);
  207. procedure setADC2(Data: byte);
  208. procedure setRC1(Data: byte);
  209. procedure setRC2(Data: byte);
  210. procedure nextStep();
  211. procedure doReset();
  212. procedure start();
  213. procedure break();
  214. procedure doSingleCommand(command: byte);
  215. procedure writeEEProm(adr: byte; Data: byte);
  216. function isActive(): boolean;
  217. function isDelayActive(): boolean;
  218. function getAddress(): word;
  219. function getPage(): word;
  220. function getRAdr(): word;
  221. procedure getStack(List: TStrings);
  222. function getARegister(): byte;
  223. function getBRegister(): byte;
  224. function getCRegister(): byte;
  225. function getDRegister(): byte;
  226. function getERegister(): byte;
  227. function getFRegister(): byte;
  228. procedure setTPSVersion(tpsversion: TTPSVersion);
  229. procedure getCommands(list: TStrings);
  230. procedure getDatas(cmd: byte; list: TStrings);
  231. function getCommandText(cmd, Data: byte): string;
  232. end;
  233. implementation
  234. uses Math, MCSStrings;
  235. { TServo }
  236. constructor TServo.Create;
  237. begin
  238. pinno := -1;
  239. end;
  240. procedure TServo.attach(pin: byte);
  241. begin
  242. pinno := pin;
  243. end;
  244. function TServo.attached: boolean;
  245. begin
  246. Result := pinno > -1;
  247. end;
  248. function TServo.getValue: byte;
  249. begin
  250. Result := myValue;
  251. end;
  252. procedure TServo.Write(Value: byte);
  253. begin
  254. myValue := Value;
  255. end;
  256. { TSPS }
  257. function TSPS.isDout1(): boolean;
  258. begin
  259. Result := dout1;
  260. end;
  261. function TSPS.isDout2(): boolean;
  262. begin
  263. Result := dout2;
  264. end;
  265. function TSPS.isDout3(): boolean;
  266. begin
  267. Result := dout3;
  268. end;
  269. function TSPS.isDout4(): boolean;
  270. begin
  271. Result := dout4;
  272. end;
  273. function TSPS.getPWM1(): byte;
  274. begin
  275. Result := pwm1;
  276. end;
  277. function TSPS.getPWM2(): byte;
  278. begin
  279. Result := pwm2;
  280. end;
  281. function TSPS.getServo1(): byte;
  282. begin
  283. Result := servo1.getValue;
  284. end;
  285. function TSPS.getServo2(): byte;
  286. begin
  287. Result := servo2.getValue;
  288. end;
  289. function TSPS.getTone(): integer;
  290. begin
  291. Result := tone;
  292. end;
  293. procedure TSPS.setDin1(Data: boolean);
  294. begin
  295. din1 := Data;
  296. end;
  297. procedure TSPS.setDin2(Data: boolean);
  298. begin
  299. din2 := Data;
  300. end;
  301. procedure TSPS.setDin3(Data: boolean);
  302. begin
  303. din3 := Data;
  304. end;
  305. procedure TSPS.setDin4(Data: boolean);
  306. begin
  307. din4 := Data;
  308. end;
  309. procedure TSPS.setSPrg(Data: boolean);
  310. begin
  311. sw_prg := Data;
  312. end;
  313. procedure TSPS.setSSel(Data: boolean);
  314. begin
  315. sw_sel := Data;
  316. end;
  317. procedure TSPS.setADC1(Data: byte);
  318. begin
  319. adc1 := Data;
  320. end;
  321. procedure TSPS.setADC2(Data: byte);
  322. begin
  323. adc2 := Data;
  324. end;
  325. procedure TSPS.setRC1(Data: byte);
  326. begin
  327. rc1 := Data;
  328. end;
  329. procedure TSPS.setRC2(Data: byte);
  330. begin
  331. rc2 := Data;
  332. end;
  333. procedure TSPS.nextStep();
  334. var
  335. Value: byte;
  336. begin
  337. Value := eeprom[addr];
  338. addr := addr + 1;
  339. doSingleCommand(Value);
  340. if (addr > SizeOf(eeprom)) then
  341. begin
  342. doReset();
  343. end;
  344. end;
  345. procedure TSPS.doReset();
  346. begin
  347. a := 0;
  348. b := 0;
  349. c := 0;
  350. d := 0;
  351. e := 0;
  352. f := 0;
  353. stack.Reset();
  354. active := False;
  355. din1 := False;
  356. din2 := False;
  357. din3 := False;
  358. din4 := False;
  359. dout1 := False;
  360. dout2 := False;
  361. dout3 := False;
  362. dout4 := False;
  363. addr := 0;
  364. adrPage := 0;
  365. pwm2 := 0;
  366. pwm1 := 0;
  367. adc1 := 0;
  368. adc2 := 0;
  369. saveCnt := 0;
  370. servo2.Write(0);
  371. servo1.Write(0);
  372. stop := False;
  373. end;
  374. procedure TSPS.start();
  375. var
  376. Value, cmd, Data: byte;
  377. x: integer;
  378. begin
  379. doReset();
  380. for x := 0 to SizeOf(eeprom) do
  381. begin
  382. Value := eeprom[x];
  383. cmd := (Value and $F0);
  384. Data := (Value and $0F);
  385. if (cmd = CALL_SUB) then
  386. begin
  387. if (Data >= 8) then
  388. begin
  389. Data := Data - 7;
  390. subs[Data] := x + 1;
  391. end;
  392. end;
  393. if ((cmd = IS_A) and (Data = $0B)) then
  394. begin
  395. servo1.attach(0);
  396. end;
  397. if ((cmd = IS_A) and (Data = $0C)) then
  398. begin
  399. servo2.attach(1);
  400. end;
  401. if ((cmd = CMD_BYTE) and (Data = $06)) then
  402. begin
  403. servo1.attach(0);
  404. end;
  405. if ((cmd = CMD_BYTE) and (Data = $07)) then
  406. begin
  407. servo2.attach(1);
  408. end;
  409. end;
  410. active := True;
  411. end;
  412. procedure TSPS.break();
  413. begin
  414. stop := True;
  415. end;
  416. procedure TSPS.doSingleCommand(command: byte);
  417. var
  418. cmd, Data: byte;
  419. begin
  420. cmd := (command and $F0);
  421. Data := (command and $0F);
  422. case cmd of
  423. CMD_NULL: doNull(Data);
  424. PORT: doPort(Data);
  425. DELAY: doDelay(Data);
  426. JUMP_BACK: doJumpBack(Data);
  427. SET_A: doSetA(Data);
  428. A_IS: doAIs(Data);
  429. IS_A: doIsA(Data);
  430. CALC: doCalc(Data);
  431. PAGE: doPage(Data);
  432. JUMP: doJump(Data);
  433. C_COUNT: doCCount(Data);
  434. D_COUNT: doDCount(Data);
  435. SKIP_IF: doSkipIf(Data);
  436. CALL: doCall(Data);
  437. CALL_SUB: doCallSub(Data);
  438. CMD_BYTE: doByte(Data);
  439. end;
  440. end;
  441. procedure TSPS.writeEEProm(adr: byte; Data: byte);
  442. begin
  443. eeprom[adr] := Data;
  444. end;
  445. function TSPS.isActive(): boolean;
  446. begin
  447. Result := active;
  448. end;
  449. function TSPS.isDelayActive(): boolean;
  450. begin
  451. Result := delayActive;
  452. end;
  453. function TSPS.getAddress(): word;
  454. begin
  455. Result := addr;
  456. end;
  457. function TSPS.getPage(): word;
  458. begin
  459. Result := adrPage div 16;
  460. end;
  461. function TSPS.getRAdr(): word;
  462. begin
  463. if (saveCnt = 0) then
  464. begin
  465. Result := 0;
  466. end;
  467. Result := saveaddr[saveCnt - 1];
  468. end;
  469. procedure TSPS.getStack(List: TStrings);
  470. var
  471. i: integer;
  472. begin
  473. for i := 0 to stack.Count - 1 do
  474. begin
  475. List.Add(IntToHex(stack.peek(i), 2));
  476. end;
  477. end;
  478. function TSPS.getARegister(): byte;
  479. begin
  480. Result := a;
  481. end;
  482. function TSPS.getBRegister(): byte;
  483. begin
  484. Result := b;
  485. end;
  486. function TSPS.getCRegister(): byte;
  487. begin
  488. Result := c;
  489. end;
  490. function TSPS.getDRegister(): byte;
  491. begin
  492. Result := d;
  493. end;
  494. function TSPS.getERegister(): byte;
  495. begin
  496. Result := e;
  497. end;
  498. function TSPS.getFRegister(): byte;
  499. begin
  500. Result := f;
  501. end;
  502. procedure TSPS.setTPSVersion(tpsversion: TTPSVersion);
  503. begin
  504. version := tpsversion;
  505. end;
  506. procedure TSPS.getCommands(list: TStrings);
  507. begin
  508. MCSStrings.copyArray2List(COMMANDS, list);
  509. end;
  510. procedure TSPS.getDatas(cmd: byte; list: TStrings);
  511. begin
  512. if (cmd = 0) then
  513. begin
  514. case version of
  515. Holtek, ATMega8: MCSStrings.copyArray2List(O_LIST_H, list);
  516. ATTiny84, Arduino: MCSStrings.copyArray2List(O_LIST_AT, list);
  517. end;
  518. end;
  519. if (cmd = 1) then
  520. begin
  521. MCSStrings.copyArray2List(DOUT_LIST, list);
  522. end;
  523. if (cmd = 2) then
  524. MCSStrings.copyArray2List(DELAY_LIST, list);
  525. if (cmd = 3) then
  526. MCSStrings.copyArray2List(JUMP_B_LIST, list);
  527. if (cmd = 4) then
  528. MCSStrings.copyArray2List(A_LIST, list);
  529. if (cmd = 5) then
  530. begin
  531. case version of
  532. Holtek: MCSStrings.copyArray2List(IS_A_LIST_H, list);
  533. ATMega8: MCSStrings.copyArray2List(IS_A_LIST_A8, list);
  534. ATTiny84, Arduino: MCSStrings.copyArray2List(IS_A_LIST_AT, list);
  535. end;
  536. end;
  537. if (cmd = 6) then
  538. begin
  539. case version of
  540. Holtek: MCSStrings.copyArray2List(A_IS_LIST_H, list);
  541. ATMega8: MCSStrings.copyArray2List(A_IS_LIST_A8, list);
  542. ATTiny84, Arduino: MCSStrings.copyArray2List(A_IS_LIST_AT, list);
  543. end;
  544. end;
  545. if (cmd = 7) then
  546. begin
  547. case version of
  548. Holtek, ATMega8: MCSStrings.copyArray2List(A_CALC_LIST_H, list);
  549. ATTiny84, Arduino: MCSStrings.copyArray2List(A_CALC_LIST_AT, list);
  550. end;
  551. end;
  552. if (cmd = 8) then
  553. begin
  554. case version of
  555. Holtek, ATMega8: MCSStrings.copyArray2List(PAGE_LIST_H, list);
  556. ATTiny84, Arduino: MCSStrings.copyArray2List(PAGE_LIST_AT, list);
  557. end;
  558. end;
  559. if (cmd = 9) then
  560. MCSStrings.copyArray2List(JUMP_LIST, list);
  561. if (cmd = 10) then
  562. MCSStrings.copyArray2List(C_LIST, list);
  563. if (cmd = 11) then
  564. MCSStrings.copyArray2List(D_LIST, list);
  565. if (cmd = 12) then
  566. begin
  567. case version of
  568. Holtek: MCSStrings.copyArray2List(SKIP_LIST_H, list);
  569. ATMega8: MCSStrings.copyArray2List(SKIP_LIST_A8, list);
  570. ATTiny84, Arduino: MCSStrings.copyArray2List(SKIP_LIST_AT, list);
  571. end;
  572. end;
  573. if (cmd = 13) then
  574. MCSStrings.copyArray2List(CALL_LIST, list);
  575. if (cmd = 14) then
  576. begin
  577. case version of
  578. Holtek, ATMega8: MCSStrings.copyArray2List(RET_LIST_H, list);
  579. ATTiny84, Arduino: MCSStrings.copyArray2List(RET_LIST_AT, list);
  580. end;
  581. end;
  582. if (cmd = 15) then
  583. begin
  584. case version of
  585. Holtek, ATMega8: MCSStrings.copyArray2List(F_LIST_H, list);
  586. ATTiny84, Arduino: MCSStrings.copyArray2List(F_LIST_AT, list);
  587. end;
  588. end;
  589. end;
  590. function TSPS.getCommandText(cmd, Data: byte): string;
  591. var
  592. list: TStrings;
  593. line: string;
  594. begin
  595. if ((cmd >= 0) and (cmd < 16)) then
  596. begin
  597. list := TStringList.Create;
  598. getDatas(cmd, list);
  599. if ((Data >= 0) and (Data < 16)) then
  600. line := COMMANDS[cmd] + ':' + list[Data];
  601. list.Free;
  602. end;
  603. Result := line;
  604. end;
  605. procedure TSPS.doNull(Data: byte);
  606. begin
  607. // Do nothing
  608. end;
  609. // output to port
  610. procedure TSPS.doPort(Data: byte);
  611. begin
  612. dout1 := (Data and $01) > 0;
  613. dout2 := (Data and $02) > 0;
  614. dout3 := (Data and $04) > 0;
  615. dout4 := (Data and $08) > 0;
  616. end;
  617. // delay in ms
  618. procedure TSPS.doDelay(Data: byte);
  619. var
  620. delayValue: integer;
  621. x: integer;
  622. begin
  623. case Data of
  624. 0: delayValue := 1;
  625. 1: delayValue := 2;
  626. 2: delayValue := 5;
  627. 3: delayValue := 10;
  628. 4: delayValue := 20;
  629. 5: delayValue := 50;
  630. 6: delayValue := 100;
  631. 7: delayValue := 200;
  632. 8: delayValue := 500;
  633. 9: delayValue := 1000;
  634. 10: delayValue := 2000;
  635. 11: delayValue := 5000;
  636. 12: delayValue := 10000;
  637. 13: delayValue := 20000;
  638. 14: delayValue := 30000;
  639. 15: delayValue := 60000;
  640. end;
  641. delayActive := True;
  642. repeat
  643. if (delayValue >= 100) then
  644. begin
  645. Dec(delayValue, 100);
  646. Sleep(100);
  647. delayCallback(delayValue);
  648. end;
  649. until ((delayValue <= 100) or stop);
  650. delayCallback(0);
  651. delayActive := False;
  652. end;
  653. // jump relative back
  654. procedure TSPS.doJumpBack(Data: byte);
  655. begin
  656. addr := addr - Data - 1;
  657. end;
  658. // a = data
  659. procedure TSPS.doSetA(Data: byte);
  660. begin
  661. a := Data;
  662. end;
  663. // a = somthing;
  664. procedure TSPS.doAIs(Data: byte);
  665. begin
  666. case Data of
  667. 1: a := b;
  668. 2: a := c;
  669. 3: a := d;
  670. 4:
  671. begin
  672. a := 0;
  673. if (din1) then
  674. a := a + 1;
  675. if (din2) then
  676. a := a + 2;
  677. if (din3) then
  678. a := a + 4;
  679. if (din4) then
  680. a := a + 8;
  681. end;
  682. 5: if (din1) then
  683. a := 1
  684. else
  685. a := 0;
  686. 6: if (din2) then
  687. a := 1
  688. else
  689. a := 0;
  690. 7: if (din3) then
  691. a := 1
  692. else
  693. a := 0;
  694. 8: if (din4) then
  695. a := 1
  696. else
  697. a := 0;
  698. 9: a := adc1 and $0f; //(Umrechnen auf 4 bit)
  699. 10: a := adc2 and $0f; //(Umrechnen auf 4 bit)
  700. 11: a := rc1 and $0f; //(Umrechnen auf 4 bit)
  701. 12: a := rc2 and $0f; //(Umrechnen auf 4 bit)
  702. 13: a := e;
  703. 14: a := f;
  704. 15: a := pop();
  705. end;
  706. end;
  707. // somthing = a;
  708. procedure TSPS.doIsA(Data: byte);
  709. var
  710. tmpValue: byte;
  711. begin
  712. case Data of
  713. 0: case version of
  714. ATTiny84, Arduino:
  715. begin
  716. tmpValue := b;
  717. b := a;
  718. a := tmpValue;
  719. end;
  720. end;
  721. 1: b := a;
  722. 2: c := a;
  723. 3: d := a;
  724. 4: doPort(a);
  725. 5: dout1 := (a and $01) > 0;
  726. 6: dout2 := (a and $01) > 0;
  727. 7: dout3 := (a and $01) > 0;
  728. 8: dout4 := (a and $01) > 0;
  729. 9: pwm1 := a * 16;
  730. 10: pwm2 := a * 16;
  731. 11:
  732. begin
  733. if (servo1.attached()) then
  734. servo1.Write((a * 10) + 10);
  735. end;
  736. 12:
  737. begin
  738. if (servo2.attached()) then
  739. servo2.Write((a * 10) + 10);
  740. end;
  741. 13: e := a;
  742. 14: f := a;
  743. 15: push(a);
  744. end;
  745. end;
  746. // calculations
  747. procedure TSPS.doCalc(Data: byte);
  748. begin
  749. case Data of
  750. 1: a := a + 1;
  751. 2: a := a - 1;
  752. 3: a := a + b;
  753. 4: a := a - b;
  754. 5: a := a * b;
  755. 6: a := a div b;
  756. 7: a := a and b;
  757. 8: a := a or b;
  758. 9: a := a xor b;
  759. 10: a := not a;
  760. 11: case version of
  761. ATTiny84, Arduino: a := a mod b;
  762. end;
  763. 12: case version of
  764. ATTiny84, Arduino: a := a + 16 * b;
  765. end;
  766. 13: case version of
  767. ATTiny84, Arduino: a := b - a;
  768. end;
  769. end;
  770. case version of
  771. Holtek, ATMega8: a := a and 15;
  772. end;
  773. end;
  774. // setting page
  775. procedure TSPS.doPage(Data: byte);
  776. begin
  777. adrPage := Data * 16;
  778. end;
  779. // jump absolute
  780. procedure TSPS.doJump(Data: byte);
  781. begin
  782. addr := adrPage + Data;
  783. end;
  784. // counting with c register
  785. procedure TSPS.doCCount(Data: byte);
  786. begin
  787. if (c > 0) then
  788. begin
  789. c := c - 1;
  790. c := c and $0F;
  791. doJump(Data);
  792. end;
  793. end;
  794. // counting with d register
  795. procedure TSPS.doDCount(Data: byte);
  796. begin
  797. if (d > 0) then
  798. begin
  799. d := d - 1;
  800. d := d and $0F;
  801. doJump(Data);
  802. end;
  803. end;
  804. // simple comdition = true skip next command
  805. procedure TSPS.doSkipIf(Data: byte);
  806. begin
  807. case (Data) of
  808. 0: if (a = 0) then
  809. case version of
  810. ATTiny84, Arduino: addr := addr + 1;
  811. end;
  812. 1: if (a > b) then
  813. addr := addr + 1;
  814. 2: if (a < b) then
  815. addr := addr + 1;
  816. 3: if (a = b) then
  817. addr := addr + 1;
  818. 4: if (din1) then
  819. addr := addr + 1;
  820. 5: if (din2) then
  821. addr := addr + 1;
  822. 6: if (din3) then
  823. addr := addr + 1;
  824. 7: if (din4) then
  825. addr := addr + 1;
  826. 8: if (not din1) then
  827. addr := addr + 1;
  828. 9: if (not din2) then
  829. addr := addr + 1;
  830. 10: if (not din3) then
  831. addr := addr + 1;
  832. 11: if (not din4) then
  833. addr := addr + 1;
  834. 12: if (sw_sel) then
  835. addr := addr + 1;
  836. 13: if (sw_prg) then
  837. addr := addr + 1;
  838. 14: if (not sw_sel) then
  839. addr := addr + 1;
  840. 15: if (not sw_prg) then
  841. addr := addr + 1;
  842. end;
  843. end;
  844. // calling a subroutine
  845. procedure TSPS.doCall(Data: byte);
  846. begin
  847. saveaddr[saveCnt] := addr;
  848. case version of
  849. ATTiny84, Arduino: saveCnt := saveCnt + 1;
  850. end;
  851. addr := adrpage + Data;
  852. end;
  853. // calling a subroutine, calling return and restart
  854. procedure TSPS.doCallSub(Data: byte);
  855. begin
  856. if (Data = 0) then
  857. begin
  858. case version of
  859. ATTiny84, Arduino:
  860. begin
  861. if (saveCnt = 0) then
  862. begin
  863. doReset();
  864. exit;
  865. end;
  866. saveCnt := saveCnt - 1;
  867. end;
  868. end;
  869. addr := saveaddr[saveCnt];
  870. exit;
  871. end;
  872. if ((Data <= 6) and ((version = ATTiny84) or (version = Arduino))) then
  873. begin
  874. // call subroutine number
  875. saveaddr[saveCnt] := addr;
  876. saveCnt := saveCnt + 1;
  877. addr := subs[Data];
  878. exit;
  879. end;
  880. if ((Data = $0f) and ((version = ATTiny84) or (version = Arduino))) then
  881. begin
  882. doReset();
  883. exit;
  884. end;
  885. end;
  886. procedure TSPS.doByte(Data: byte);
  887. var
  888. Value: integer;
  889. begin
  890. // Some byte commands
  891. case (Data) of
  892. 0: case version of
  893. ATTiny84, Arduino: a := adc1;
  894. end;
  895. 1: case version of
  896. ATTiny84, Arduino: a := adc2;
  897. end;
  898. 2: case version of
  899. ATTiny84, Arduino: a := rc1;
  900. end;
  901. 3: case version of
  902. ATTiny84, Arduino: a := rc2;
  903. end;
  904. 4: pwm1 := a;
  905. 5: pwm2 := a;
  906. 6:
  907. begin
  908. if (servo1.attached()) then
  909. begin
  910. Value := (180 * a) div 255;
  911. servo1.Write(Value);
  912. end;
  913. end;
  914. 7:
  915. begin
  916. if (servo2.attached()) then
  917. begin
  918. Value := (180 * a) div 255;
  919. servo2.Write(Value);
  920. end;
  921. end;
  922. 8:
  923. case version of
  924. ATTiny84, Arduino: doTone(Data);
  925. end;
  926. end;
  927. end;
  928. procedure TSPS.doTone(Data: byte);
  929. begin
  930. if (a in [36..109]) then
  931. tone := round(440 * power(2.0, ((a - 69) / 12)))
  932. else
  933. tone := 0;
  934. end;
  935. procedure TSPS.push(Data: byte);
  936. begin
  937. stack.Push(Data);
  938. end;
  939. function TSPS.pop(): byte;
  940. begin
  941. Result := stack.pop;
  942. end;
  943. constructor TSPS.Create;
  944. begin
  945. servo1 := TServo.Create();
  946. servo2 := TServo.Create();
  947. stack := TByteStack.Create;
  948. stop := False;
  949. delayActive := False;
  950. end;
  951. destructor TSPS.Destroy;
  952. begin
  953. inherited Destroy;
  954. servo1.Free;
  955. servo2.Free;
  956. stack.Free;
  957. end;
  958. procedure TSPS.setDelayCallback(callback: TDelayCallback);
  959. begin
  960. delayCallback := callback;
  961. end;
  962. end.