logo

ibnjs

Unnamed repository; edit this file 'description' to name the repository.

ibniz.js (24916B)


  1. /* This program is free software. It comes without any warranty, to
  2. * the extent permitted by applicable law. You can redistribute it
  3. * and/or modify it under the terms of the Do What The Fuck You Want
  4. * To Public License, Version 2, as published by Sam Hocevar. See
  5. * http://sam.zoy.org/wtfpl/COPYING for more details. */
  6. Array.prototype.clear = function(){
  7. this.length=0;
  8. }
  9. Array.prototype.exchange = function(){
  10. if(this.length<2) return -1;
  11. var temp = this[this.length-1];
  12. this[this.length-1]=this[this.length-2];
  13. this[this.length-2]=temp;
  14. }
  15. Array.prototype.trirot = function(){
  16. if(this.length<3) return -1;
  17. var temp = this[this.length-1];
  18. this[this.length-1]=this[this.length-3];
  19. this[this.length-3]=this[this.length-2];
  20. this[this.length-2]=temp;
  21. }
  22. Array.prototype.trirot2 = function(){
  23. if(this.length<3) return -1;
  24. var temp = this[this.length-2];
  25. this[this.length-2]=this[this.length-3];
  26. this[this.length-3]=this[this.length-1];
  27. this[this.length-1]=temp;
  28. }
  29. Array.prototype.get = function(addr) {
  30. return this[addr];
  31. }
  32. Array.prototype.gettop = function(addr) {
  33. return this[this.length-1+addr];
  34. }
  35. Array.prototype.put = function(addr,v) {
  36. this[addr]=v|0;
  37. }
  38. Array.prototype.puttop = function(addr,v) {
  39. this[this.length-1+addr]=v|0;
  40. }
  41. Array.prototype.dup = function(){
  42. this.push(this[this.length-1]);
  43. }
  44. Array.prototype.dpush = function(v){
  45. this.push(v|0);
  46. }
  47. function Parser(simpleGetPut,useAudio)
  48. {
  49. this.code = "";
  50. this.parsedCode = new Array();
  51. this.ip = 0;
  52. this.t = 0;
  53. this.x = 0;
  54. this.y = 0;
  55. this.xy = 0;
  56. this.mode = 0;
  57. this.terminate = 0;
  58. this.stackmode = 0;
  59. this.videoout = 0;
  60. this.audioout = 0;
  61. this.stacka = new Array();
  62. this.rstacka = new Array();
  63. this.mem = new Array(1048576);
  64. // 0xC8000-0xCFFFF - return stacks
  65. // 0xD0000-0xFFFFF - stacks
  66. this.shl = function(a,b){
  67. var steps = (a>>16)&63;
  68. return steps<32 ? b<<steps : b>>(steps-32);
  69. }
  70. this.rol = function(a,b){
  71. var steps = (a>>16)&31;
  72. return ((b<<steps)|(b>>>(32-steps)));
  73. }
  74. this.ror = function(a,b){
  75. var steps = (a>>16)&31;
  76. return ((b>>>steps)|(b<<(32-steps)));
  77. }
  78. this.config = function(simpleGetPut,useAudio,recalcAudio)
  79. {
  80. this.useAudio=useAudio;
  81. this.recalcAudio=recalcAudio;
  82. if(simpleGetPut)
  83. {
  84. this.get = function(addr) { return this.mem[addr]; }
  85. this.put = function(addr,val) { this.mem[addr]=val; }
  86. }
  87. else
  88. {
  89. this.get = function(addr,val){
  90. switch(addr>>15)
  91. {
  92. case 0:
  93. case 1:
  94. case 2:
  95. case 3:
  96. case 4:
  97. case 5:
  98. case 6:
  99. case 7:
  100. case 8:
  101. case 9:
  102. case 10:
  103. case 11:
  104. case 12:
  105. case 13:
  106. case 14:
  107. case 15:
  108. case 16:
  109. case 17:
  110. case 18:
  111. case 19:
  112. case 20:
  113. case 21:
  114. case 22:
  115. case 23:
  116. case 24:
  117. return this.mem[addr];
  118. break;
  119. case 25:
  120. return this.rstacka[addr&0x3FFF];
  121. break;
  122. case 26:
  123. case 27:
  124. return this.stacka[addr&0xFFFF];
  125. break;
  126. case 28:
  127. case 29:
  128. case 30:
  129. case 31:
  130. return this.stacka[addr&0x1FFFF];
  131. break;
  132. }
  133. }
  134. this.put = function(addr,val){
  135. switch(addr>>15)
  136. {
  137. case 0:
  138. case 1:
  139. case 2:
  140. case 3:
  141. case 4:
  142. case 5:
  143. case 6:
  144. case 7:
  145. case 8:
  146. case 9:
  147. case 10:
  148. case 11:
  149. case 12:
  150. case 13:
  151. case 14:
  152. case 15:
  153. case 16:
  154. case 17:
  155. case 18:
  156. case 19:
  157. case 20:
  158. case 21:
  159. case 22:
  160. case 23:
  161. case 24:
  162. this.mem[addr] = val;
  163. break;
  164. case 25:
  165. this.rstacka.put(addr&0x3FFF,val);
  166. break;
  167. case 26:
  168. case 27:
  169. this.stacka.put(addr&0xFFFF,val);
  170. break;
  171. case 28:
  172. case 29:
  173. case 30:
  174. case 31:
  175. this.stacka.put(addr&0x1FFFF,val);
  176. break;
  177. }
  178. }
  179. }
  180. }
  181. this.config(simpleGetPut,useAudio);
  182. this.load = function(c)
  183. {
  184. this.code=c;
  185. this.parsedCode = new Array();
  186. this.compile();
  187. this.configureStackmode();
  188. }
  189. this.rol16 = function(b){
  190. return ((b<<16)|(b>>>16));
  191. }
  192. this.compiledpm = function(x,y){}
  193. this.pm0 = function() { this.stacka.push(this.t<<16,0,0); };
  194. this.pushmedia = function(x,y)
  195. {
  196. if(this.mode==0) this.compiledpm(x,y);
  197. else this.stacka.push(this.t<<16 | (y<<8) | x);
  198. }
  199. this.pmaudio = function(x,y)
  200. {
  201. this.stacka.push(this.t*65536 + (y<<8) + x);
  202. }
  203. this.compilepushmedia = function()
  204. {
  205. switch(this.stackmode)
  206. {
  207. case 0:
  208. this.compiledpm = function(x,y) { this.stacka.push(this.t<<16,(y<<9)-65536,(x<<9)-65536); };
  209. break;
  210. case 1:
  211. this.compiledpm = function(x,y) { this.stacka.push(this.t<<16 | (y<<8) | x); };
  212. break;
  213. }
  214. }
  215. this.run = function(x,y)
  216. {
  217. // reset the machine
  218. this.mode = 0;
  219. this.terminate = 0;
  220. this.stacka.length=0;
  221. this.ip = 0;
  222. // push media context
  223. this.compiledpm(x,y);
  224. // loop
  225. this.mediaSwitch=true;
  226. this.exec(x,y);
  227. if(this.mode==0)
  228. {
  229. // run audio, too
  230. this.videoout = this.stacka.pop();
  231. if((this.useFFAudio || this.useChromeAudio) && this.useAudio)
  232. {
  233. if(this.stackmode==1 && !this.recalcAudio)
  234. this.audioout=this.videoout; // same stack data, skip the processing bulk
  235. else if((x%128)==0 && this.recalcAudio)
  236. {
  237. this.mode=1;
  238. this.terminate = 0;
  239. this.stacka.length=0;
  240. this.ip = 0;
  241. this.pmaudio(x,y);
  242. this.exec(x,y);
  243. }
  244. }
  245. }
  246. if((this.useFFAudio || this.useChromeAudio) && this.useAudio && this.mode==1) this.audioout = this.stacka.pop();
  247. }
  248. this.isLimm = function(ci)
  249. {
  250. // is 0-9? A-F? .?
  251. return ((ci>=48 && ci<=57) || (ci>=65 && ci<=70) || (ci==46));
  252. }
  253. this.isImmop = function(ci)
  254. {
  255. return ((ci>=112 && ci<=115)||ci==43||ci==45||ci==42||ci==47||ci==37||ci==38||ci==124||ci==94||ci==108||ci==126||ci==97||ci==100||ci==40||ci==41||ci==74||ci==33||ci==64||ci==86||ci==88||ci==80||ci==123);
  256. }
  257. this.isOpcode = function(ci)
  258. {
  259. return (this.isImmop(ci) || this.isLimm(ci) || ci==77||(ci>=118&&ci<=120)||ci==63||ci==58||ci==59||ci==82||ci==84||ci==105||ci==106||ci==91||ci==93||ci==76||ci==125);
  260. }
  261. this.parse = function()
  262. {
  263. var i = 0;
  264. var j = 0;
  265. while(i<this.code.length)
  266. {
  267. var a = this.code[i].charCodeAt(0);
  268. if(this.isLimm(a))
  269. {
  270. // Loadimm!
  271. var imm1 = 0; // number
  272. var imm2 = 0; // fraction
  273. var imm2_c = 12;
  274. var mode = 0; // number/fraction time?
  275. while(this.isLimm(a) && i<this.code.length)
  276. {
  277. if(a==46) mode=1; // dot, time to switch modes!
  278. else {
  279. if(mode==0)
  280. {
  281. if(a>=48 && a<=57) imm1=(imm1<<4)|(a-48); // number, 0-9
  282. else imm1=(imm1<<4)|(a-55); // fraction, A-F
  283. }
  284. else if(imm2_c>0)
  285. {
  286. if(a>=48 && a<=57) imm2=imm2|((a-48)<<imm2_c); // fraction, 0-9
  287. else imm2=imm2|((a-55)<<imm2_c); // fraction, A-F
  288. imm2_c-=4;
  289. }
  290. }
  291. i++; // increment IP
  292. if(i<this.code.length) a = this.code[i].charCodeAt(0); // char->int (checks for ip overrun)
  293. }
  294. if(i<this.code.length) a = this.code[i].charCodeAt(0);
  295. else a=0;
  296. var out = ((imm1&65535)<<16)|(imm2&65535);
  297. if(this.isImmop(a))
  298. {
  299. switch(a)
  300. {
  301. case 115:
  302. this.parsedCode[j] = new Array(2,Math.sin(out*(Math.PI/32768))*65536);
  303. break;
  304. case 113:
  305. this.parsedCode[j] = new Array(2,0 > out ? 0 : 65536 * Math.sqrt(out / 65536));
  306. break;
  307. case 126:
  308. this.parsedCode[j] = new Array(2,~out);
  309. break;
  310. case 123:
  311. this.parsedCode[j] = new Array(5,this.rol16(out)&1048575,123,0);
  312. break;
  313. case 40:
  314. case 41:
  315. this.parsedCode[j] = new Array(3,0-this.rol16(out),a);
  316. break;
  317. case 74:
  318. case 86:
  319. this.parsedCode[j] = new Array(3,this.rol16(out),a);
  320. break;
  321. case 64:
  322. var addr = this.rol16(out)&1048575;
  323. if(addr<0xC8000) this.parsedCode[j] = new Array(3,addr,128);
  324. else this.parsedCode[j] = new Array(3,addr,a);
  325. break;
  326. case 33:
  327. var addr = this.rol16(out)&1048575;
  328. if(addr<0xC8000) this.parsedCode[j] = new Array(3,addr,129);
  329. else this.parsedCode[j] = new Array(3,addr,a);
  330. break;
  331. default:
  332. this.parsedCode[j] = new Array(3,out,a);
  333. break;
  334. }
  335. i++;
  336. }
  337. else this.parsedCode[j] = new Array(2,out);
  338. j++;
  339. }
  340. else if(this.isOpcode(a))
  341. {
  342. switch(a)
  343. {
  344. case 125:
  345. var t = j;
  346. var chr = 0;
  347. while(chr!=123 && t>=0)
  348. {
  349. t--;
  350. if(this.parsedCode[t] && this.parsedCode[t][0]==1) chr = this.parsedCode[t][1];
  351. else if(this.parsedCode[t] && this.parsedCode[t][0]==5) chr = this.parsedCode[t][2];
  352. }
  353. if(t>=0)
  354. {
  355. if(this.parsedCode[t] && this.parsedCode[t][0]==5)
  356. this.parsedCode[t] = new Array(5,this.parsedCode[t][1],chr,j);
  357. else this.parsedCode[t] = new Array(4,chr,j);
  358. }
  359. this.parsedCode[j] = new Array(1,a);
  360. break;
  361. case 58:
  362. var t = j;
  363. var chr = 0;
  364. while(chr!=63 && t>=0)
  365. {
  366. t--;
  367. if(this.parsedCode[t] && this.parsedCode[t][0]==1) chr = this.parsedCode[t][1];
  368. }
  369. if(t>=0) this.parsedCode[t] = new Array(4,chr,j);
  370. this.parsedCode[j] = new Array(1,a);
  371. break;
  372. case 59:
  373. var t = j;
  374. var chr = 0;
  375. while(chr!=58 && t>=0)
  376. {
  377. t--;
  378. if(this.parsedCode[t] && this.parsedCode[t][0]==1) chr = this.parsedCode[t][1];
  379. }
  380. if(t>=0) this.parsedCode[t] = new Array(4,chr,j);
  381. this.parsedCode[j] = new Array(1,a);
  382. break;
  383. case 118:
  384. this.parsedCode[j] = new Array(1,a);
  385. if(i+1<this.code.length)
  386. {
  387. var b = this.code[i+1].charCodeAt(0);
  388. if(b==118)
  389. {
  390. this.parsedCode[j] = new Array(1,128);
  391. i++;
  392. }
  393. }
  394. break;
  395. default:
  396. this.parsedCode[j] = new Array(1,a);
  397. break;
  398. }
  399. i++;
  400. j++;
  401. }
  402. else i++;
  403. }
  404. }
  405. this.compile = function()
  406. {
  407. // TODO: fix parse ip settings
  408. /*
  409. var i = 0;
  410. var oldCode = this.code;
  411. this.evals = new Array();
  412. this.evals[0] = function(){};
  413. while(i<oldCode.length)
  414. {
  415. this.parse();
  416. this.evaluate();
  417. this.evals[i] = this.evalCode;
  418. this.code = this.code.substr(1);
  419. this.parsedCode = new Array();
  420. i++;
  421. }
  422. */
  423. var i = 0;
  424. var oldCode = this.parsedCode;
  425. this.parse();
  426. this.evals = new Array();
  427. this.evals[0] = function(){};
  428. while(i<oldCode.length)
  429. {
  430. this.evaluate(i);
  431. this.evals[i] = this.evalCode;
  432. //this.parsedCode = this.parsedCode.slice(1);
  433. i++;
  434. }
  435. this.parsedCode = oldCode;
  436. }
  437. this.evalRol16 = function(a)
  438. {
  439. return "((" + a + "<<16)|(" + a + ">>>16))";
  440. }
  441. this.evaluate = function(startIP)
  442. {
  443. var tempCode = "";
  444. var cmd;
  445. var a;
  446. tempCode += "var a; var stacka = me.stacka; var steps;";
  447. for(this.ip=startIP; this.ip<this.parsedCode.length; this.ip++)
  448. {
  449. cmd = this.parsedCode[this.ip];
  450. switch(cmd[0])
  451. {
  452. case 1: // op
  453. switch(cmd[1])
  454. {
  455. // Math!
  456. case 43:
  457. tempCode += "stacka.push((stacka.pop()+stacka.pop())|0);";
  458. break;
  459. case 45:
  460. tempCode += "a = stacka.pop(); stacka.push((stacka.pop()-a)|0);";
  461. break;
  462. case 42:
  463. tempCode += "stacka.push((stacka.pop()*stacka.pop()/65536)|0);";
  464. break;
  465. case 47:
  466. tempCode += "a = stacka.pop(); stacka.push((stacka.pop()*65536/a)|0);";
  467. break;
  468. case 37:
  469. tempCode += "a = stacka.pop(); stacka.push(stacka.pop()%a);";
  470. break;
  471. case 38:
  472. tempCode += "stacka.push(stacka.pop()&stacka.pop());";
  473. break;
  474. case 124:
  475. tempCode += "stacka.push(stacka.pop()|stacka.pop());";
  476. break;
  477. case 94:
  478. tempCode += "stacka.push(stacka.pop()^stacka.pop());";
  479. break;
  480. case 108:
  481. tempCode += "steps = (stacka.pop()>>16)&63; a = stacka.pop(); stacka.push(steps<32 ? a<<steps : a>>(steps-32));";
  482. break;
  483. case 114:
  484. tempCode += "steps = (stacka.pop()>>16)&31; a = stacka.pop(); stacka.push((a>>>steps)|(a<<(32-steps)));";
  485. break;
  486. case 97:
  487. tempCode += "stacka.push((Math.atan2(stacka.pop(),stacka.pop())*"+(65536/(2*Math.PI))+")|0);";
  488. break;
  489. case 115:
  490. tempCode += "stacka.push((Math.sin(stacka.pop()*"+(2*Math.PI/65536)+")*65536)|0);";
  491. break;
  492. case 113:
  493. tempCode += "a = stacka.pop(); stacka.push(0 > a ? 0 : (65536 * Math.sqrt(a / 65536))|0);";
  494. break;
  495. case 60:
  496. tempCode += "a = stacka.pop(); stacka.push(0 > a ? a : 0);";
  497. break;
  498. case 62:
  499. tempCode += "a = stacka.pop(); stacka.push(0 < a ? a : 0);";
  500. break;
  501. case 61:
  502. tempCode += "stacka.push(stacka.pop()==0);";
  503. break;
  504. case 126:
  505. tempCode += "stacka.push(~stacka.pop());";
  506. break;
  507. // Exterior!
  508. case 77: // media context switch
  509. tempCode += "if(!me.mediaSwitch || !me.useAudio) return -15498; ";
  510. tempCode += "else{me.mode=1; me.videoout = stacka.pop(); stacka.length=0;";
  511. tempCode += "me.pmaudio(x,y);}";
  512. break;
  513. case 119: // where am I? well, where are you
  514. tempCode += "me.pushmedia(x,y);";
  515. break;
  516. case 84:
  517. tempCode += "return -15498;";
  518. break;
  519. // Stack!
  520. case 100:
  521. tempCode += "stacka.dup();";
  522. break;
  523. case 120:
  524. tempCode += "stacka.exchange();";
  525. break;
  526. case 118:
  527. tempCode += "stacka.trirot();";
  528. break;
  529. case 112:
  530. tempCode += "stacka.pop();";
  531. break;
  532. case 41:
  533. tempCode += "stacka.push(stacka.gettop(0-me.rol16(stacka.pop())));";
  534. break;
  535. case 40:
  536. tempCode += "a = 0-me.rol16(stacka.pop()); stacka.puttop(a,stacka.pop());";
  537. break;
  538. // Memory!
  539. case 64:
  540. tempCode += "stacka.push(me.get(me.rol16(stacka.pop())&1048575));";
  541. break;
  542. case 33:
  543. tempCode += "a = me.rol16(stacka.pop()); me.put(a&1048575,stacka.pop());";
  544. break;
  545. // Return stack manipulation
  546. case 82:
  547. tempCode += "stacka.push(me.rstacka.pop());";
  548. break;
  549. case 80:
  550. tempCode += "me.rstacka.push(stacka.pop());";
  551. break;
  552. // Loops
  553. case 105:
  554. tempCode += "stacka.push(me.rstacka.gettop(-1));";
  555. break;
  556. case 106:
  557. tempCode += "stacka.push(me.rstacka.gettop(-3));";
  558. break;
  559. case 74:
  560. tempCode += "return me.rol16(stacka.pop())-1;";
  561. break;
  562. case 91:
  563. tempCode += "me.rstacka.push("+this.rol16(this.ip+1)+");";
  564. break;
  565. case 93:
  566. tempCode += "if(stacka.pop()!=0) return me.rol16(me.rstacka.gettop(0))-1; ";
  567. tempCode += "else me.rstacka.pop();";
  568. break;
  569. case 88:
  570. tempCode += "me.rstacka.push(stacka.pop());";
  571. tempCode += "me.rstacka.push("+this.rol16(this.ip+1)+");";
  572. break;
  573. case 76:
  574. tempCode += "a=me.rstacka.gettop(-1)-(1<<16);";
  575. tempCode += "me.rstacka.puttop(-1,a);";
  576. tempCode += "if(a) return me.rol16(me.rstacka.gettop(0))-1;";
  577. tempCode += "else { me.rstacka.pop(); me.rstacka.pop(); }";
  578. break;
  579. // Subroutines
  580. case 125:
  581. tempCode += "return me.rol16(me.rstacka.pop())-1;";
  582. break;
  583. case 86:
  584. tempCode += "me.rstacka.push("+this.rol16(this.ip+1)+");";
  585. tempCode += "return me.rol16(me.get(me.rol16(stacka.pop())&1048575))-1;";
  586. break;
  587. // Special
  588. case 128: // Double trirot
  589. tempCode += "stacka.trirot2();";
  590. break;
  591. default:
  592. break;
  593. }
  594. break;
  595. case 5: // imm+op+nextip
  596. switch(cmd[2])
  597. {
  598. case 123:
  599. tempCode += "me.put(" + cmd[1] + ","+this.rol16(this.ip+1)+");";
  600. this.ip=cmd[3];
  601. break;
  602. }
  603. break;
  604. case 4: // op+nextip
  605. switch(cmd[1])
  606. {
  607. case 123:
  608. tempCode += "me.put(me.rol16(stacka.pop())&1048575,"+this.rol16(this.ip+1)+");";
  609. this.ip=cmd[2];
  610. break;
  611. case 63:
  612. tempCode += "if(stacka.pop()==0) return " + cmd[2] + ";";
  613. break;
  614. case 58:
  615. this.ip=cmd[2];
  616. break;
  617. }
  618. break;
  619. case 3: // imm+op
  620. switch(cmd[2])
  621. {
  622. case 43:
  623. tempCode += "stacka.push(("+cmd[1]+"+stacka.pop())|0);";
  624. break;
  625. case 45:
  626. tempCode += "stacka.push((stacka.pop()-"+cmd[1]+")|0);";
  627. break;
  628. case 42:
  629. tempCode += "stacka.push((("+cmd[1]+"*stacka.pop())/65536)|0);";
  630. break;
  631. case 47:
  632. tempCode += "stacka.push(((stacka.pop()*65536)/"+cmd[1]+")|0);";
  633. break;
  634. case 37:
  635. tempCode += "stacka.push(stacka.pop()%"+cmd[1]+");";
  636. break;
  637. case 38:
  638. tempCode += "stacka.push("+cmd[1]+"&stacka.pop());";
  639. break;
  640. case 124:
  641. tempCode += "stacka.push("+cmd[1]+"|stacka.pop());";
  642. break;
  643. case 94:
  644. tempCode += "stacka.push("+cmd[1]+"^stacka.pop());";
  645. break;
  646. case 108:
  647. tempCode += "stacka.push(me.shl("+cmd[1]+",stacka.pop()));";
  648. break;
  649. case 114:
  650. tempCode += "stacka.push(me.ror("+cmd[1]+",stacka.pop()));";
  651. break;
  652. /*
  653. case 108:
  654. tempCode += "steps = "+((cmd[1]>>16)&63)+"; a = stacka.pop(); stacka.push(steps<32 ? a<<steps : a>>(steps-32));";
  655. break;
  656. case 114:
  657. tempCode += "steps = "+((cmd[1]>>16)&31)+"; a = stacka.pop(); stacka.push((a>>>steps)|(a<<(32-steps)));";
  658. */
  659. break;
  660. case 97:
  661. tempCode += "stacka.push((Math.atan2("+cmd[1]+",stacka.pop())*"+(65536/(2*Math.PI))+")|0);";
  662. break;
  663. case 115:
  664. tempCode += "stacka.push("+((Math.sin(cmd[1]*(Math.PI/32768))*65536)|0)+");";
  665. break;
  666. case 113:
  667. tempCode += "stacka.push("+(0 > cmd[1] ? 0 : (65536 * Math.sqrt(cmd[1] / 65536))|0)+");";
  668. break;
  669. case 126:
  670. tempCode += "stacka.push("+(~cmd[1])+");";
  671. break;
  672. case 100:
  673. tempCode += "stacka.push("+cmd[1]+","+cmd[1]+");";
  674. break;
  675. case 40:
  676. tempCode += "stacka.puttop("+cmd[1]+",stacka.pop());";
  677. break;
  678. case 41:
  679. tempCode += "stacka.push(stacka.gettop("+cmd[1]+"));";
  680. break;
  681. case 74:
  682. tempCode += "return "+cmd[1]+";";
  683. break;
  684. case 64:
  685. tempCode += "stacka.push(me.get("+cmd[1]+"));";
  686. break;
  687. case 33:
  688. tempCode += "me.put("+cmd[1]+",stacka.pop());";
  689. break;
  690. case 86:
  691. tempCode += "me.rstacka.push("+this.rol16(this.ip+1)+");";
  692. tempCode += "return me.rol16(me.get("+cmd[1]+"))-1;";
  693. break;
  694. case 88:
  695. tempCode += "me.rstacka.push("+cmd[1]+");";
  696. tempCode += "me.rstacka.push("+this.rol16(this.ip+1)+");";
  697. break;
  698. case 80:
  699. tempCode += "me.rstacka.push("+cmd[1]+");";
  700. break;
  701. case 112:
  702. break;
  703. // special
  704. case 128: // direct load
  705. tempCode += "stacka.push(me.mem["+cmd[1]+"]);";
  706. break;
  707. case 129: // direct store
  708. tempCode += "me.mem["+cmd[1]+"]=stacka.pop();";
  709. break;
  710. }
  711. break;
  712. case 2: // imm
  713. tempCode += "stacka.push("+cmd[1]+");";
  714. break;
  715. default:
  716. break;
  717. }
  718. }
  719. eval("this.evalCode = function(me,x,y) {" + tempCode + " return -15498;};");
  720. }
  721. this.mediaSwitch=true;
  722. this.configureStackmode = function()
  723. {
  724. // reset the machine
  725. this.mode = 0;
  726. this.stackmode = 0;
  727. this.terminate = 0;
  728. this.stacka.length=0;
  729. this.ip = 0;
  730. // push media context
  731. this.pm0();
  732. // loop
  733. this.mediaSwitch=false;
  734. this.exec(0,0);
  735. if(this.stacka.length>1) this.stackmode = 1;
  736. this.compilepushmedia();
  737. }
  738. this.getOp = function(ip)
  739. {
  740. var cmd = this.parsedCode[this.ip];
  741. if(cmd[0]==1 || cmd[0]==4) return cmd[1];
  742. else if(cmd[0]==3) return cmd[2];
  743. else return 0;
  744. }
  745. this.exec = function(x,y)
  746. {
  747. while(this.ip>=0 && this.ip<this.parsedCode.length)
  748. this.ip = this.evals[this.ip](this,x,y)+1;
  749. }
  750. this.useFFAudio = false;
  751. this.useChromeAudio = false;
  752. this.recalcAudio = false;
  753. this.buffer = new Array(512);
  754. if(typeof Audio !== 'undefined')
  755. {
  756. this.audioOut = new Audio();
  757. if(this.audioOut.mozSetup)
  758. {
  759. this.audioOut.mozSetup(1,512*60);
  760. this.useFFAudio = true;
  761. this.buffer = new Float32Array(512);
  762. }
  763. }
  764. if(typeof AudioContext !== 'undefined')
  765. {
  766. this.audioCtx = new AudioContext();
  767. this.audioSR = this.audioCtx.sampleRate/60;
  768. this.useChromeAudio = true;
  769. this.buffer = new Float32Array(512);
  770. }
  771. this.render = function(c)
  772. {
  773. var idd = c.createImageData(256,256);
  774. var id = idd.data;
  775. var imgpos = 0;
  776. var cy = 0;
  777. var cu = 0;
  778. var cv = 0;
  779. for(var y=0;y<256;y++)
  780. {
  781. for(var x=0;x<256;x++)
  782. {
  783. this.run(x,y);
  784. cy = (p.videoout>>>8)&255;
  785. cu = (((p.videoout>>>16)&255)^0x80)-128;
  786. cv = ((p.videoout>>>24)^0x80)-128;
  787. id[imgpos++] = (298*cy + 409*cv + 128)>>8;
  788. id[imgpos++] = (298*cy - 100*cu - 208*cv + 128)>>8;
  789. id[imgpos++] = (298*cy + 516*cu + 128)>>8;
  790. id[imgpos++] = 255;
  791. this.buffer[(y<<1)] = (((this.audioout&65535)^32768)-32768)/32768;
  792. }
  793. }
  794. c.putImageData(idd,0,0);
  795. this.renderAudio();
  796. }
  797. this.render2 = function(c)
  798. {
  799. var idd = c.createImageData(128,128);
  800. var id = idd.data;
  801. var imgpos = 0;
  802. var cy = 0;
  803. var cu = 0;
  804. var cv = 0;
  805. for(var y=0;y<256;y+=2)
  806. {
  807. for(var x=0;x<256;x+=2)
  808. {
  809. this.run(x,y);
  810. cy = (p.videoout>>>8)&255;
  811. cu = (((p.videoout>>>16)&255)^0x80)-128;
  812. cv = ((p.videoout>>>24)^0x80)-128;
  813. id[imgpos++] = (298*cy + 409*cv + 128)>>8;
  814. id[imgpos++] = (298*cy - 100*cu - 208*cv + 128)>>8;
  815. id[imgpos++] = (298*cy + 516*cu + 128)>>8;
  816. id[imgpos++] = 255;
  817. this.buffer[(y<<1)] = (((this.audioout&65535)^32768)-32768)/32768;
  818. }
  819. }
  820. c.putImageData(idd,0,0);
  821. this.renderAudio();
  822. }
  823. this.renderAudio = function()
  824. {
  825. if(this.useFFAudio) this.audioOut.mozWriteAudio(this.buffer);
  826. else if(this.useChromeAudio)
  827. {
  828. if(this.audioOut.noteOff) this.audioOut.noteOff(0);
  829. this.fixbuffer = new Float32Array(this.audioSR);
  830. for(var i=0;i<this.audioSR;i++)
  831. {
  832. var t1 = i*512/this.audioSR;
  833. var t2 = t1-Math.floor(t1);
  834. this.fixbuffer[i]=this.buffer[Math.floor(t1)]*(1-t2)+this.buffer[Math.ceil(t1)]*t2;
  835. }
  836. this.aBuffer = this.audioCtx.createBuffer(1,this.audioSR,this.audioSR*60);
  837. this.aBuffer.getChannelData(0).set(this.fixbuffer);
  838. this.audioOut = this.audioCtx.createBufferSource();
  839. this.audioOut.buffer=this.aBuffer;
  840. this.audioOut.connect(this.audioCtx.destination);
  841. if(this.audioOut.noteOn) this.audioOut.noteOn(0);
  842. this.audioOut.loop = true;
  843. }
  844. }
  845. this.delayAudio = function(a)
  846. {
  847. if(this.useFFAudio) for(var b=0; b<a; b++) this.audioOut.mozWriteAudio(this.buffer);
  848. }
  849. }
  850. var p = new Parser(false,false);
  851. var oldloop = new Date;
  852. var cc = document.getElementById("ibniz");
  853. var c = cc.getContext("2d");
  854. var runningCode = " ";
  855. p.load(runningCode);
  856. p.t=0;
  857. var codeEdit = document.getElementById("code");
  858. var fpsField = document.getElementById("fps");
  859. var tField = document.getElementById("t");
  860. var pause = document.getElementById("pause");
  861. var simpleGetPut = document.getElementById("simpleGetPut");
  862. var useAudio = document.getElementById("useAudio");
  863. var recalcAudio = document.getElementById("recalcAudio");
  864. var exampleApps = document.getElementById("example_apps");
  865. var exampleAppID = -1;
  866. var halfRes = document.getElementById("halfRes");
  867. var cc2 = document.createElement("canvas");
  868. cc2.width = 256;
  869. cc2.height = 256;
  870. var c2 = cc2.getContext("2d");
  871. function derp()
  872. {
  873. if(!pause.checked)
  874. {
  875. if(halfRes.checked)
  876. {
  877. p.render2(c2);
  878. c.drawImage(cc2,0,0,128,128,0,0,256,256);
  879. }
  880. else p.render(c);
  881. var newloop = new Date;
  882. var fps = 1000 / (newloop - oldloop);
  883. oldloop=newloop;
  884. p.t+=60/fps;
  885. p.delayAudio(Math.round(60/fps));
  886. p.configureStackmode();
  887. p.config(simpleGetPut.checked,useAudio.checked,recalcAudio.checked);
  888. //fpsField.childNodes[1].nodeValue=fps.toFixed(2) + " (about " + (fps*65536*p.parsedCode.length).toFixed(0) + " cycles)";
  889. fpsField.childNodes[1].nodeValue=fps.toFixed(2);
  890. tField.childNodes[1].nodeValue=p.t.toFixed(2);
  891. if(exampleApps.selectedIndex!=exampleAppID)
  892. {
  893. exampleAppID=exampleApps.selectedIndex;
  894. codeEdit.value = exampleApps.options[exampleAppID].value;
  895. }
  896. if(runningCode!=codeEdit.value)
  897. {
  898. p.t=0;
  899. runningCode=codeEdit.value;
  900. p.load(runningCode);
  901. console.log("NEW CODE LOADED");
  902. }
  903. }
  904. setTimeout("derp()",1); // give the browser time to not lag the whole computer
  905. }
  906. function loadFileURL()
  907. {
  908. var url = prompt("Please input an URL","");
  909. var http = createRequestObject();
  910. function createRequestObject() { // http://www.openhosting.co.uk/articles/webdev/5899/
  911. var objAjax;
  912. var browser = navigator.appName;
  913. if(browser == "Microsoft Internet Explorer"){
  914. objAjax = new ActiveXObject("Microsoft.XMLHTTP");
  915. }else{
  916. objAjax = new XMLHttpRequest();
  917. }
  918. return objAjax;
  919. }
  920. function updateFileURL() {
  921. if(http.readyState == 4)
  922. codeEdit.value=http.responseText;
  923. }
  924. http.open('get',url);
  925. http.onreadystatechange = updateFileURL;
  926. http.send(null);
  927. }
  928. derp();