1
0

pass2.c 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. /*****************************************************************************/
  2. /* */
  3. /* ASM (B322 Assembler) */
  4. /* */
  5. /* Assembler for B322 */
  6. /* Contains all pass 2 functions */
  7. /* */
  8. /*****************************************************************************/
  9. word getNumberForLabel(char* labelName)
  10. {
  11. word bdosOffset = USERBDOS_OFFSET;
  12. word i;
  13. for (i = 0; i < labelListIndex; i++)
  14. {
  15. if (strcmp(labelName, labelListName[i]) == 0)
  16. {
  17. return (labelListLineNumber[i] + bdosOffset);
  18. }
  19. }
  20. BDOS_PrintConsole("Could not find label: ");
  21. BDOS_PrintConsole(labelName);
  22. BDOS_PrintConsole("\n");
  23. exit(1);
  24. return 0;
  25. }
  26. // Convert a 32 bit word into an array of 4 bytes
  27. void instrToByteArray(word instr, char* byteArray)
  28. {
  29. byteArray[0] = (instr >> 24) & 0xFF;
  30. byteArray[1] = (instr >> 16) & 0xFF;
  31. byteArray[2] = (instr >> 8) & 0xFF;
  32. byteArray[3] = instr & 0xFF;
  33. }
  34. void pass2Halt(char* outputAddr, char* outputCursor)
  35. {
  36. char instr[4] = {0xff, 0xff, 0xff, 0xff};
  37. memcpy((outputAddr + *outputCursor), instr, 4);
  38. (*outputCursor) += 4;
  39. }
  40. void pass2Read(char* outputAddr, char* outputCursor)
  41. {
  42. word instr = 0xE0000000;
  43. word arg1num = getNumberAtArg(1);
  44. word negative = 0;
  45. if (arg1num < 0)
  46. {
  47. negative = 1;
  48. arg1num = -arg1num;
  49. }
  50. // arg1 should fit in 16 bits
  51. if ((arg1num >> 16) > 0)
  52. {
  53. BDOS_PrintConsole("READ: arg1 is >16 bits\n");
  54. exit(1);
  55. }
  56. instr += (arg1num << 12);
  57. // arg2
  58. char arg2buf[16];
  59. getArgPos(2, arg2buf);
  60. // arg2 should be a reg
  61. if (arg2buf[0] != 'r')
  62. {
  63. BDOS_PrintConsole("READ: arg2 not a reg\n");
  64. exit(1);
  65. }
  66. word arg2num = strToInt(&arg2buf[1]);
  67. instr += (arg2num << 8);
  68. // arg3
  69. char arg3buf[16];
  70. getArgPos(3, arg3buf);
  71. // arg3 should be a reg
  72. if (arg3buf[0] != 'r')
  73. {
  74. BDOS_PrintConsole("READ: arg3 not a reg\n");
  75. exit(1);
  76. }
  77. word arg3num = strToInt(&arg3buf[1]);
  78. instr += arg3num;
  79. if (negative)
  80. {
  81. instr ^= (1 << 5);
  82. }
  83. // write to mem
  84. char byteInstr[4];
  85. instrToByteArray(instr, byteInstr);
  86. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  87. (*outputCursor) += 4;
  88. }
  89. void pass2Write(char* outputAddr, char* outputCursor)
  90. {
  91. word instr = 0xD0000000;
  92. word arg1num = getNumberAtArg(1);
  93. word negative = 0;
  94. if (arg1num < 0)
  95. {
  96. negative = 1;
  97. arg1num = -arg1num;
  98. }
  99. // arg1 should fit in 16 bits
  100. if ((arg1num >> 16) > 0)
  101. {
  102. BDOS_PrintConsole("WRITE: arg1 is >16 bits\n");
  103. exit(1);
  104. }
  105. instr += (arg1num << 12);
  106. // arg2
  107. char arg2buf[16];
  108. getArgPos(2, arg2buf);
  109. // arg2 should be a reg
  110. if (arg2buf[0] != 'r')
  111. {
  112. BDOS_PrintConsole("WRITE: arg2 not a reg\n");
  113. exit(1);
  114. }
  115. word arg2num = strToInt(&arg2buf[1]);
  116. instr += (arg2num << 8);
  117. // arg3
  118. char arg3buf[16];
  119. getArgPos(3, arg3buf);
  120. // arg3 should be a reg
  121. if (arg3buf[0] != 'r')
  122. {
  123. BDOS_PrintConsole("WRITE: arg3 not a reg\n");
  124. exit(1);
  125. }
  126. word arg3num = strToInt(&arg3buf[1]);
  127. instr += (arg3num << 4);
  128. if (negative)
  129. {
  130. instr ^= 1;
  131. }
  132. // write to mem
  133. char byteInstr[4];
  134. instrToByteArray(instr, byteInstr);
  135. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  136. (*outputCursor) += 4;
  137. }
  138. void pass2Copy(char* outputAddr, char* outputCursor)
  139. {
  140. word instr = 0xC0000000;
  141. word arg1num = getNumberAtArg(1);
  142. word negative = 0;
  143. if (arg1num < 0)
  144. {
  145. negative = 1;
  146. arg1num = -arg1num;
  147. }
  148. // arg1 should fit in 16 bits
  149. if ((arg1num >> 16) > 0)
  150. {
  151. BDOS_PrintConsole("COPY: arg1 is >16 bits\n");
  152. exit(1);
  153. }
  154. instr += (arg1num << 12);
  155. // arg2
  156. char arg2buf[16];
  157. getArgPos(2, arg2buf);
  158. // arg2 should be a reg
  159. if (arg2buf[0] != 'r')
  160. {
  161. BDOS_PrintConsole("COPY: arg2 not a reg\n");
  162. exit(1);
  163. }
  164. word arg2num = strToInt(&arg2buf[1]);
  165. instr += (arg2num << 8);
  166. // arg3
  167. char arg3buf[16];
  168. getArgPos(3, arg3buf);
  169. // arg3 should be a reg
  170. if (arg3buf[0] != 'r')
  171. {
  172. BDOS_PrintConsole("COPY: arg3 not a reg\n");
  173. exit(1);
  174. }
  175. word arg3num = strToInt(&arg3buf[1]);
  176. instr += (arg3num << 4);
  177. if (negative)
  178. {
  179. instr ^= 1;
  180. }
  181. // write to mem
  182. char byteInstr[4];
  183. instrToByteArray(instr, byteInstr);
  184. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  185. (*outputCursor) += 4;
  186. }
  187. void pass2Push(char* outputAddr, char* outputCursor)
  188. {
  189. word instr = 0xB0000000;
  190. // arg1
  191. char arg1buf[16];
  192. getArgPos(1, arg1buf);
  193. // arg1 should be a reg
  194. if (arg1buf[0] != 'r')
  195. {
  196. BDOS_PrintConsole("PUSH: arg1 not a reg\n");
  197. exit(1);
  198. }
  199. word arg1num = strToInt(&arg1buf[1]);
  200. instr += (arg1num << 4);
  201. // write to mem
  202. char byteInstr[4];
  203. instrToByteArray(instr, byteInstr);
  204. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  205. (*outputCursor) += 4;
  206. }
  207. void pass2Pop(char* outputAddr, char* outputCursor)
  208. {
  209. word instr = 0xA0000000;
  210. // arg1
  211. char arg1buf[16];
  212. getArgPos(1, arg1buf);
  213. // arg1 should be a reg
  214. if (arg1buf[0] != 'r')
  215. {
  216. BDOS_PrintConsole("POP: arg1 not a reg\n");
  217. exit(1);
  218. }
  219. word arg1num = strToInt(&arg1buf[1]);
  220. instr += arg1num;
  221. // write to mem
  222. char byteInstr[4];
  223. instrToByteArray(instr, byteInstr);
  224. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  225. (*outputCursor) += 4;
  226. }
  227. void pass2Jump(char* outputAddr, char* outputCursor)
  228. {
  229. word instr = 0x90000000;
  230. // check if jump to label
  231. // if yes, replace label with line number
  232. char arg1buf[LABEL_NAME_SIZE+1];
  233. getArgPos(1, arg1buf);
  234. word arg1bufLen = strlen(arg1buf);
  235. word argIsLabel = 0;
  236. word i;
  237. for (i = 0; i < arg1bufLen; i++)
  238. {
  239. if (arg1buf[i] < '0' || arg1buf[i] > '9')
  240. {
  241. argIsLabel = 1;
  242. break;
  243. }
  244. }
  245. word arg1num = 0;
  246. if (argIsLabel)
  247. {
  248. arg1num = getNumberForLabel(arg1buf);
  249. }
  250. else
  251. {
  252. arg1num = getNumberAtArg(1);
  253. }
  254. // arg1 should fit in 27 bits
  255. if ((arg1num >> 27) > 0)
  256. {
  257. BDOS_PrintConsole("JUMPO: arg1 is >27 bits\n");
  258. exit(1);
  259. }
  260. instr += (arg1num << 1);
  261. // write to mem
  262. char byteInstr[4];
  263. instrToByteArray(instr, byteInstr);
  264. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  265. (*outputCursor) += 4;
  266. }
  267. void pass2Jumpo(char* outputAddr, char* outputCursor)
  268. {
  269. word instr = 0x90000000;
  270. word arg1num = getNumberAtArg(1);
  271. // arg1 should fit in 27 bits
  272. if ((arg1num >> 27) > 0)
  273. {
  274. BDOS_PrintConsole("JUMPO: arg1 is >27 bits\n");
  275. exit(1);
  276. }
  277. instr += (arg1num << 1);
  278. instr ^= 1;
  279. // write to mem
  280. char byteInstr[4];
  281. instrToByteArray(instr, byteInstr);
  282. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  283. (*outputCursor) += 4;
  284. }
  285. void pass2Jumpr(char* outputAddr, char* outputCursor)
  286. {
  287. word instr = 0x80000000;
  288. word arg1num = getNumberAtArg(1);
  289. // arg1 should fit in 16 bits
  290. if ((arg1num >> 16) > 0)
  291. {
  292. BDOS_PrintConsole("JUMPR: arg1 is >16 bits\n");
  293. exit(1);
  294. }
  295. instr += (arg1num << 12);
  296. // arg2
  297. char arg2buf[16];
  298. getArgPos(2, arg2buf);
  299. // arg2 should be a reg
  300. if (arg2buf[0] != 'r')
  301. {
  302. BDOS_PrintConsole("JUMPR: arg2 not a reg\n");
  303. exit(1);
  304. }
  305. word arg2num = strToInt(&arg2buf[1]);
  306. instr += (arg2num << 4);
  307. // write to mem
  308. char byteInstr[4];
  309. instrToByteArray(instr, byteInstr);
  310. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  311. (*outputCursor) += 4;
  312. }
  313. void pass2Load(char* outputAddr, char* outputCursor)
  314. {
  315. word instr = 0x70000000;
  316. word arg1num = getNumberAtArg(1);
  317. // arg1 should fit in 16 bits
  318. if ((arg1num >> 16) > 0)
  319. {
  320. BDOS_PrintConsole("LOAD: arg1 is >16 bits\n");
  321. exit(1);
  322. }
  323. instr += (arg1num << 12);
  324. // arg2
  325. char arg2buf[16];
  326. getArgPos(2, arg2buf);
  327. // arg2 should be a reg
  328. if (arg2buf[0] != 'r')
  329. {
  330. BDOS_PrintConsole("LOAD: arg2 not a reg\n");
  331. exit(1);
  332. }
  333. word arg2num = strToInt(&arg2buf[1]);
  334. instr += arg2num;
  335. // write to mem
  336. char byteInstr[4];
  337. instrToByteArray(instr, byteInstr);
  338. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  339. (*outputCursor) += 4;
  340. }
  341. void pass2Loadhi(char* outputAddr, char* outputCursor)
  342. {
  343. word instr = 0x70000000;
  344. word arg1num = getNumberAtArg(1);
  345. // arg1 should fit in 16 bits
  346. if ((arg1num >> 16) > 0)
  347. {
  348. BDOS_PrintConsole("LOADHI: arg1 is >16 bits\n");
  349. exit(1);
  350. }
  351. instr += (arg1num << 12);
  352. // arg2
  353. char arg2buf[16];
  354. getArgPos(2, arg2buf);
  355. // arg2 should be a reg
  356. if (arg2buf[0] != 'r')
  357. {
  358. BDOS_PrintConsole("LOADHI: arg2 not a reg\n");
  359. exit(1);
  360. }
  361. word arg2num = strToInt(&arg2buf[1]);
  362. instr += arg2num;
  363. instr ^= (1 << 8);
  364. // write to mem
  365. char byteInstr[4];
  366. instrToByteArray(instr, byteInstr);
  367. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  368. (*outputCursor) += 4;
  369. }
  370. void pass2Beq(char* outputAddr, char* outputCursor)
  371. {
  372. word instr = 0x60000000;
  373. // arg1
  374. char arg1buf[16];
  375. getArgPos(1, arg1buf);
  376. // arg1 should be a reg
  377. if (arg1buf[0] != 'r')
  378. {
  379. BDOS_PrintConsole("BEQ: arg1 not a reg\n");
  380. exit(1);
  381. }
  382. word arg1num = strToInt(&arg1buf[1]);
  383. instr += (arg1num << 8);
  384. // arg2
  385. char arg2buf[16];
  386. getArgPos(2, arg2buf);
  387. // arg2 should be a reg
  388. if (arg2buf[0] != 'r')
  389. {
  390. BDOS_PrintConsole("BEQ: arg2 not a reg\n");
  391. exit(1);
  392. }
  393. word arg2num = strToInt(&arg2buf[1]);
  394. instr += (arg2num << 4);
  395. // arg3
  396. word arg3num = getNumberAtArg(3);
  397. // arg3 should fit in 16 bits
  398. if ((arg3num >> 16) > 0)
  399. {
  400. BDOS_PrintConsole("BEQ: arg3 is >16 bits\n");
  401. exit(1);
  402. }
  403. instr += (arg3num << 12);
  404. // write to mem
  405. char byteInstr[4];
  406. instrToByteArray(instr, byteInstr);
  407. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  408. (*outputCursor) += 4;
  409. }
  410. void pass2Bne(char* outputAddr, char* outputCursor)
  411. {
  412. word instr = 0x50000000;
  413. // arg1
  414. char arg1buf[16];
  415. getArgPos(1, arg1buf);
  416. // arg1 should be a reg
  417. if (arg1buf[0] != 'r')
  418. {
  419. BDOS_PrintConsole("BNE: arg1 not a reg\n");
  420. exit(1);
  421. }
  422. word arg1num = strToInt(&arg1buf[1]);
  423. instr += (arg1num << 8);
  424. // arg2
  425. char arg2buf[16];
  426. getArgPos(2, arg2buf);
  427. // arg2 should be a reg
  428. if (arg2buf[0] != 'r')
  429. {
  430. BDOS_PrintConsole("BNE: arg2 not a reg\n");
  431. exit(1);
  432. }
  433. word arg2num = strToInt(&arg2buf[1]);
  434. instr += (arg2num << 4);
  435. // arg3
  436. word arg3num = getNumberAtArg(3);
  437. // arg3 should fit in 16 bits
  438. if ((arg3num >> 16) > 0)
  439. {
  440. BDOS_PrintConsole("BNE: arg3 is >16 bits\n");
  441. exit(1);
  442. }
  443. instr += (arg3num << 12);
  444. // write to mem
  445. char byteInstr[4];
  446. instrToByteArray(instr, byteInstr);
  447. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  448. (*outputCursor) += 4;
  449. }
  450. void pass2Bgt(char* outputAddr, char* outputCursor)
  451. {
  452. word instr = 0x40000000;
  453. // arg1
  454. char arg1buf[16];
  455. getArgPos(1, arg1buf);
  456. // arg1 should be a reg
  457. if (arg1buf[0] != 'r')
  458. {
  459. BDOS_PrintConsole("BGT: arg1 not a reg\n");
  460. exit(1);
  461. }
  462. word arg1num = strToInt(&arg1buf[1]);
  463. instr += (arg1num << 8);
  464. // arg2
  465. char arg2buf[16];
  466. getArgPos(2, arg2buf);
  467. // arg2 should be a reg
  468. if (arg2buf[0] != 'r')
  469. {
  470. BDOS_PrintConsole("BGT: arg2 not a reg\n");
  471. exit(1);
  472. }
  473. word arg2num = strToInt(&arg2buf[1]);
  474. instr += (arg2num << 4);
  475. // arg3
  476. word arg3num = getNumberAtArg(3);
  477. // arg3 should fit in 16 bits
  478. if ((arg3num >> 16) > 0)
  479. {
  480. BDOS_PrintConsole("BGT: arg3 is >16 bits\n");
  481. exit(1);
  482. }
  483. instr += (arg3num << 12);
  484. // write to mem
  485. char byteInstr[4];
  486. instrToByteArray(instr, byteInstr);
  487. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  488. (*outputCursor) += 4;
  489. }
  490. void pass2Bge(char* outputAddr, char* outputCursor)
  491. {
  492. word instr = 0x30000000;
  493. // arg1
  494. char arg1buf[16];
  495. getArgPos(1, arg1buf);
  496. // arg1 should be a reg
  497. if (arg1buf[0] != 'r')
  498. {
  499. BDOS_PrintConsole("BGE: arg1 not a reg\n");
  500. exit(1);
  501. }
  502. word arg1num = strToInt(&arg1buf[1]);
  503. instr += (arg1num << 8);
  504. // arg2
  505. char arg2buf[16];
  506. getArgPos(2, arg2buf);
  507. // arg2 should be a reg
  508. if (arg2buf[0] != 'r')
  509. {
  510. BDOS_PrintConsole("BGE: arg2 not a reg\n");
  511. exit(1);
  512. }
  513. word arg2num = strToInt(&arg2buf[1]);
  514. instr += (arg2num << 4);
  515. // arg3
  516. word arg3num = getNumberAtArg(3);
  517. // arg3 should fit in 16 bits
  518. if ((arg3num >> 16) > 0)
  519. {
  520. BDOS_PrintConsole("BGE: arg3 is >16 bits\n");
  521. exit(1);
  522. }
  523. instr += (arg3num << 12);
  524. // write to mem
  525. char byteInstr[4];
  526. instrToByteArray(instr, byteInstr);
  527. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  528. (*outputCursor) += 4;
  529. }
  530. void pass2Bgts(char* outputAddr, char* outputCursor)
  531. {
  532. word instr = 0x40000000;
  533. // arg1
  534. char arg1buf[16];
  535. getArgPos(1, arg1buf);
  536. // arg1 should be a reg
  537. if (arg1buf[0] != 'r')
  538. {
  539. BDOS_PrintConsole("BGTS: arg1 not a reg\n");
  540. exit(1);
  541. }
  542. word arg1num = strToInt(&arg1buf[1]);
  543. instr += (arg1num << 8);
  544. // arg2
  545. char arg2buf[16];
  546. getArgPos(2, arg2buf);
  547. // arg2 should be a reg
  548. if (arg2buf[0] != 'r')
  549. {
  550. BDOS_PrintConsole("BGTS: arg2 not a reg\n");
  551. exit(1);
  552. }
  553. word arg2num = strToInt(&arg2buf[1]);
  554. instr += (arg2num << 4);
  555. // arg3
  556. word arg3num = getNumberAtArg(3);
  557. // arg3 should fit in 16 bits
  558. if ((arg3num >> 16) > 0)
  559. {
  560. BDOS_PrintConsole("BGTS: arg3 is >16 bits\n");
  561. exit(1);
  562. }
  563. instr += (arg3num << 12);
  564. instr ^= 1;
  565. // write to mem
  566. char byteInstr[4];
  567. instrToByteArray(instr, byteInstr);
  568. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  569. (*outputCursor) += 4;
  570. }
  571. void pass2Bges(char* outputAddr, char* outputCursor)
  572. {
  573. word instr = 0x30000000;
  574. // arg1
  575. char arg1buf[16];
  576. getArgPos(1, arg1buf);
  577. // arg1 should be a reg
  578. if (arg1buf[0] != 'r')
  579. {
  580. BDOS_PrintConsole("BGES: arg1 not a reg\n");
  581. exit(1);
  582. }
  583. word arg1num = strToInt(&arg1buf[1]);
  584. instr += (arg1num << 8);
  585. // arg2
  586. char arg2buf[16];
  587. getArgPos(2, arg2buf);
  588. // arg2 should be a reg
  589. if (arg2buf[0] != 'r')
  590. {
  591. BDOS_PrintConsole("BGES: arg2 not a reg\n");
  592. exit(1);
  593. }
  594. word arg2num = strToInt(&arg2buf[1]);
  595. instr += (arg2num << 4);
  596. // arg3
  597. word arg3num = getNumberAtArg(3);
  598. // arg3 should fit in 16 bits
  599. if ((arg3num >> 16) > 0)
  600. {
  601. BDOS_PrintConsole("BGES: arg3 is >16 bits\n");
  602. exit(1);
  603. }
  604. instr += (arg3num << 12);
  605. instr ^= 1;
  606. // write to mem
  607. char byteInstr[4];
  608. instrToByteArray(instr, byteInstr);
  609. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  610. (*outputCursor) += 4;
  611. }
  612. void pass2Savpc(char* outputAddr, char* outputCursor)
  613. {
  614. word instr = 0x20000000;
  615. // arg1
  616. char arg1buf[16];
  617. getArgPos(1, arg1buf);
  618. // arg1 should be a reg
  619. if (arg1buf[0] != 'r')
  620. {
  621. BDOS_PrintConsole("SAVPC: arg1 not a reg\n");
  622. exit(1);
  623. }
  624. word arg1num = strToInt(&arg1buf[1]);
  625. instr += arg1num;
  626. // write to mem
  627. char byteInstr[4];
  628. instrToByteArray(instr, byteInstr);
  629. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  630. (*outputCursor) += 4;
  631. }
  632. void pass2Reti(char* outputAddr, char* outputCursor)
  633. {
  634. char instr[4] = {0x10, 0x00, 0x00, 0x00};
  635. memcpy((outputAddr + *outputCursor), instr, 4);
  636. (*outputCursor) += 4;
  637. }
  638. void pass2ArithBase(char* outputAddr, char* outputCursor, word arithOpCode)
  639. {
  640. word instr = 0;
  641. instr += (arithOpCode << 23);
  642. // arg1
  643. char arg1buf[16];
  644. getArgPos(1, arg1buf);
  645. // arg1 should be a reg
  646. if (arg1buf[0] != 'r')
  647. {
  648. BDOS_PrintConsole("ARITH: arg1 not a reg\n");
  649. exit(1);
  650. }
  651. word arg1num = strToInt(&arg1buf[1]);
  652. instr += (arg1num << 8);
  653. // arg2
  654. char arg2buf[16];
  655. getArgPos(2, arg2buf);
  656. word arg2num = 0;
  657. // if arg2 is a const
  658. if (arg2buf[0] != 'r')
  659. {
  660. arg2num= getNumberAtArg(2);
  661. // arg1 should fit in 11 bits
  662. if ((arg2num >> 11) > 0)
  663. {
  664. BDOS_PrintConsole("ARITH: const is >11 bits\n");
  665. exit(1);
  666. }
  667. instr += (arg2num << 12);
  668. instr ^= (1 << 27); // set constant bit
  669. }
  670. else // arg2 is a reg
  671. {
  672. arg2num = strToInt(&arg2buf[1]);
  673. instr += (arg2num << 4);
  674. }
  675. // arg3
  676. char arg3buf[16];
  677. getArgPos(3, arg3buf);
  678. // arg3 should be a reg
  679. if (arg3buf[0] != 'r')
  680. {
  681. BDOS_PrintConsole("ARITH: arg3 not a reg\n");
  682. exit(1);
  683. }
  684. word arg3num = strToInt(&arg3buf[1]);
  685. instr += arg3num;
  686. // write to mem
  687. char byteInstr[4];
  688. instrToByteArray(instr, byteInstr);
  689. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  690. (*outputCursor) += 4;
  691. }
  692. void pass2Or(char* outputAddr, char* outputCursor)
  693. {
  694. pass2ArithBase(outputAddr, outputCursor, 0x0);
  695. }
  696. void pass2And(char* outputAddr, char* outputCursor)
  697. {
  698. pass2ArithBase(outputAddr, outputCursor, 0x1);
  699. }
  700. void pass2Xor(char* outputAddr, char* outputCursor)
  701. {
  702. pass2ArithBase(outputAddr, outputCursor, 0x2);
  703. }
  704. void pass2Add(char* outputAddr, char* outputCursor)
  705. {
  706. pass2ArithBase(outputAddr, outputCursor, 0x3);
  707. }
  708. void pass2Sub(char* outputAddr, char* outputCursor)
  709. {
  710. pass2ArithBase(outputAddr, outputCursor, 0x4);
  711. }
  712. void pass2Shiftl(char* outputAddr, char* outputCursor)
  713. {
  714. pass2ArithBase(outputAddr, outputCursor, 0x5);
  715. }
  716. void pass2Shiftr(char* outputAddr, char* outputCursor)
  717. {
  718. pass2ArithBase(outputAddr, outputCursor, 0x6);
  719. }
  720. void pass2Mult(char* outputAddr, char* outputCursor)
  721. {
  722. pass2ArithBase(outputAddr, outputCursor, 0x7);
  723. }
  724. void pass2Not(char* outputAddr, char* outputCursor)
  725. {
  726. pass2ArithBase(outputAddr, outputCursor, 0x8);
  727. }
  728. void pass2LoadLabelLow(char* outputAddr, char* outputCursor)
  729. {
  730. word instr = 0x70000000;
  731. char arg1buf[LABEL_NAME_SIZE+1];
  732. getArgPos(1, arg1buf);
  733. word arg1num = getNumberForLabel(arg1buf);
  734. // only use the lowest 16 bits
  735. arg1num = arg1num << 16;
  736. arg1num = arg1num >> 16;
  737. instr += (arg1num << 12);
  738. // arg2
  739. char arg2buf[16];
  740. getArgPos(2, arg2buf);
  741. // arg2 should be a reg
  742. if (arg2buf[0] != 'r')
  743. {
  744. BDOS_PrintConsole("LOADLABELLOW: arg2 not a reg\n");
  745. exit(1);
  746. }
  747. word arg2num = strToInt(&arg2buf[1]);
  748. instr += arg2num;
  749. // write to mem
  750. char byteInstr[4];
  751. instrToByteArray(instr, byteInstr);
  752. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  753. (*outputCursor) += 4;
  754. }
  755. void pass2LoadLabelHigh(char* outputAddr, char* outputCursor)
  756. {
  757. word instr = 0x70000000;
  758. char arg1buf[LABEL_NAME_SIZE+1];
  759. getArgPos(1, arg1buf);
  760. word arg1num = getNumberForLabel(arg1buf);
  761. // only use the highest 16 bits
  762. arg1num = arg1num >> 16;
  763. instr += (arg1num << 12);
  764. // arg2
  765. char arg2buf[16];
  766. getArgPos(2, arg2buf);
  767. // arg2 should be a reg
  768. if (arg2buf[0] != 'r')
  769. {
  770. BDOS_PrintConsole("LOADLABELHIGH: arg2 not a reg\n");
  771. exit(1);
  772. }
  773. word arg2num = strToInt(&arg2buf[1]);
  774. instr += arg2num;
  775. instr ^= (1 << 8);
  776. // write to mem
  777. char byteInstr[4];
  778. instrToByteArray(instr, byteInstr);
  779. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  780. (*outputCursor) += 4;
  781. }
  782. void pass2Nop(char* outputAddr, char* outputCursor)
  783. {
  784. char instr[4] = {0x00, 0x00, 0x00, 0x00};
  785. memcpy((outputAddr + *outputCursor), instr, 4);
  786. (*outputCursor) += 4;
  787. }
  788. void pass2Dw(char* outputAddr, char* outputCursor)
  789. {
  790. word dwValue = getNumberAtArg(1);
  791. // write to mem
  792. char byteInstr[4];
  793. instrToByteArray(dwValue, byteInstr);
  794. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  795. (*outputCursor) += 4;
  796. }
  797. void pass2Dl(char* outputAddr, char* outputCursor)
  798. {
  799. char arg1buf[LABEL_NAME_SIZE+1];
  800. getArgPos(1, arg1buf);
  801. word dlValue = getNumberForLabel(arg1buf);
  802. // write to mem
  803. char byteInstr[4];
  804. instrToByteArray(dlValue, byteInstr);
  805. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  806. (*outputCursor) += 4;
  807. }
  808. void pass2Readintid(char* outputAddr, char* outputCursor)
  809. {
  810. word instr = 0xE0000000;
  811. // arg1
  812. char arg1buf[16];
  813. getArgPos(1, arg1buf);
  814. // arg1 should be a reg
  815. if (arg1buf[0] != 'r')
  816. {
  817. BDOS_PrintConsole("READINTID: arg1 not a reg\n");
  818. exit(1);
  819. }
  820. word arg1num = strToInt(&arg1buf[1]);
  821. instr += arg1num;
  822. instr ^= (1 << 4);
  823. // write to mem
  824. char byteInstr[4];
  825. instrToByteArray(instr, byteInstr);
  826. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  827. (*outputCursor) += 4;
  828. }