1
0

pass2.c 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  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] = ((unsigned)instr >> 24) & 0xFF;
  30. byteArray[1] = ((unsigned)instr >> 16) & 0xFF;
  31. byteArray[2] = ((unsigned)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 (((unsigned)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 (((unsigned)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 pass2Readintid(char* outputAddr, char* outputCursor)
  139. {
  140. word instr = 0xC0000000;
  141. // arg1
  142. char arg1buf[16];
  143. getArgPos(1, arg1buf);
  144. // arg1 should be a reg
  145. if (arg1buf[0] != 'r')
  146. {
  147. BDOS_PrintConsole("READINTID: arg1 not a reg\n");
  148. exit(1);
  149. }
  150. word arg1num = strToInt(&arg1buf[1]);
  151. instr += arg1num;
  152. // write to mem
  153. char byteInstr[4];
  154. instrToByteArray(instr, byteInstr);
  155. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  156. (*outputCursor) += 4;
  157. }
  158. void pass2Push(char* outputAddr, char* outputCursor)
  159. {
  160. word instr = 0xB0000000;
  161. // arg1
  162. char arg1buf[16];
  163. getArgPos(1, arg1buf);
  164. // arg1 should be a reg
  165. if (arg1buf[0] != 'r')
  166. {
  167. BDOS_PrintConsole("PUSH: arg1 not a reg\n");
  168. exit(1);
  169. }
  170. word arg1num = strToInt(&arg1buf[1]);
  171. instr += (arg1num << 4);
  172. // write to mem
  173. char byteInstr[4];
  174. instrToByteArray(instr, byteInstr);
  175. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  176. (*outputCursor) += 4;
  177. }
  178. void pass2Pop(char* outputAddr, char* outputCursor)
  179. {
  180. word instr = 0xA0000000;
  181. // arg1
  182. char arg1buf[16];
  183. getArgPos(1, arg1buf);
  184. // arg1 should be a reg
  185. if (arg1buf[0] != 'r')
  186. {
  187. BDOS_PrintConsole("POP: arg1 not a reg\n");
  188. exit(1);
  189. }
  190. word arg1num = strToInt(&arg1buf[1]);
  191. instr += arg1num;
  192. // write to mem
  193. char byteInstr[4];
  194. instrToByteArray(instr, byteInstr);
  195. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  196. (*outputCursor) += 4;
  197. }
  198. void pass2Jump(char* outputAddr, char* outputCursor)
  199. {
  200. word instr = 0x90000000;
  201. // check if jump to label
  202. // if yes, replace label with line number
  203. char arg1buf[LABEL_NAME_SIZE+1];
  204. getArgPos(1, arg1buf);
  205. word arg1bufLen = strlen(arg1buf);
  206. word argIsLabel = 0;
  207. word i;
  208. for (i = 0; i < arg1bufLen; i++)
  209. {
  210. if (arg1buf[i] < '0' || arg1buf[i] > '9')
  211. {
  212. argIsLabel = 1;
  213. break;
  214. }
  215. }
  216. word arg1num = 0;
  217. if (argIsLabel)
  218. {
  219. arg1num = getNumberForLabel(arg1buf);
  220. }
  221. else
  222. {
  223. arg1num = getNumberAtArg(1);
  224. }
  225. // arg1 should fit in 27 bits
  226. if (((unsigned)arg1num >> 27) > 0)
  227. {
  228. BDOS_PrintConsole("JUMPO: arg1 is >27 bits\n");
  229. exit(1);
  230. }
  231. instr += (arg1num << 1);
  232. // write to mem
  233. char byteInstr[4];
  234. instrToByteArray(instr, byteInstr);
  235. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  236. (*outputCursor) += 4;
  237. }
  238. void pass2Jumpo(char* outputAddr, char* outputCursor)
  239. {
  240. word instr = 0x90000000;
  241. word arg1num = getNumberAtArg(1);
  242. // arg1 should fit in 27 bits
  243. if (((unsigned)arg1num >> 27) > 0)
  244. {
  245. BDOS_PrintConsole("JUMPO: arg1 is >27 bits\n");
  246. exit(1);
  247. }
  248. instr += (arg1num << 1);
  249. instr ^= 1;
  250. // write to mem
  251. char byteInstr[4];
  252. instrToByteArray(instr, byteInstr);
  253. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  254. (*outputCursor) += 4;
  255. }
  256. void pass2Jumpr(char* outputAddr, char* outputCursor)
  257. {
  258. word instr = 0x80000000;
  259. word arg1num = getNumberAtArg(1);
  260. // arg1 should fit in 16 bits
  261. if (((unsigned)arg1num >> 16) > 0)
  262. {
  263. BDOS_PrintConsole("JUMPR: arg1 is >16 bits\n");
  264. exit(1);
  265. }
  266. instr += (arg1num << 12);
  267. // arg2
  268. char arg2buf[16];
  269. getArgPos(2, arg2buf);
  270. // arg2 should be a reg
  271. if (arg2buf[0] != 'r')
  272. {
  273. BDOS_PrintConsole("JUMPR: arg2 not a reg\n");
  274. exit(1);
  275. }
  276. word arg2num = strToInt(&arg2buf[1]);
  277. instr += (arg2num << 4);
  278. // write to mem
  279. char byteInstr[4];
  280. instrToByteArray(instr, byteInstr);
  281. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  282. (*outputCursor) += 4;
  283. }
  284. void pass2Jumpro(char* outputAddr, char* outputCursor)
  285. {
  286. return;
  287. }
  288. void pass2Beq(char* outputAddr, char* outputCursor)
  289. {
  290. word instr = 0x60000000;
  291. // arg1
  292. char arg1buf[16];
  293. getArgPos(1, arg1buf);
  294. // arg1 should be a reg
  295. if (arg1buf[0] != 'r')
  296. {
  297. BDOS_PrintConsole("BEQ: arg1 not a reg\n");
  298. exit(1);
  299. }
  300. word arg1num = strToInt(&arg1buf[1]);
  301. instr += (arg1num << 8);
  302. // arg2
  303. char arg2buf[16];
  304. getArgPos(2, arg2buf);
  305. // arg2 should be a reg
  306. if (arg2buf[0] != 'r')
  307. {
  308. BDOS_PrintConsole("BEQ: arg2 not a reg\n");
  309. exit(1);
  310. }
  311. word arg2num = strToInt(&arg2buf[1]);
  312. instr += (arg2num << 4);
  313. // arg3
  314. word arg3num = getNumberAtArg(3);
  315. // arg3 should fit in 16 bits
  316. if (((unsigned)arg3num >> 16) > 0)
  317. {
  318. BDOS_PrintConsole("BEQ: arg3 is >16 bits\n");
  319. exit(1);
  320. }
  321. instr += (arg3num << 12);
  322. // write to mem
  323. char byteInstr[4];
  324. instrToByteArray(instr, byteInstr);
  325. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  326. (*outputCursor) += 4;
  327. }
  328. void pass2Bgt(char* outputAddr, char* outputCursor)
  329. {
  330. word instr = 0x40000000;
  331. // arg1
  332. char arg1buf[16];
  333. getArgPos(1, arg1buf);
  334. // arg1 should be a reg
  335. if (arg1buf[0] != 'r')
  336. {
  337. BDOS_PrintConsole("BGT: arg1 not a reg\n");
  338. exit(1);
  339. }
  340. word arg1num = strToInt(&arg1buf[1]);
  341. instr += (arg1num << 8);
  342. // arg2
  343. char arg2buf[16];
  344. getArgPos(2, arg2buf);
  345. // arg2 should be a reg
  346. if (arg2buf[0] != 'r')
  347. {
  348. BDOS_PrintConsole("BGT: arg2 not a reg\n");
  349. exit(1);
  350. }
  351. word arg2num = strToInt(&arg2buf[1]);
  352. instr += (arg2num << 4);
  353. // arg3
  354. word arg3num = getNumberAtArg(3);
  355. // arg3 should fit in 16 bits
  356. if (((unsigned)arg3num >> 16) > 0)
  357. {
  358. BDOS_PrintConsole("BGT: arg3 is >16 bits\n");
  359. exit(1);
  360. }
  361. instr += (arg3num << 12);
  362. // write to mem
  363. char byteInstr[4];
  364. instrToByteArray(instr, byteInstr);
  365. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  366. (*outputCursor) += 4;
  367. }
  368. void pass2Bgts(char* outputAddr, char* outputCursor)
  369. {
  370. word instr = 0x40000000;
  371. // arg1
  372. char arg1buf[16];
  373. getArgPos(1, arg1buf);
  374. // arg1 should be a reg
  375. if (arg1buf[0] != 'r')
  376. {
  377. BDOS_PrintConsole("BGTS: arg1 not a reg\n");
  378. exit(1);
  379. }
  380. word arg1num = strToInt(&arg1buf[1]);
  381. instr += (arg1num << 8);
  382. // arg2
  383. char arg2buf[16];
  384. getArgPos(2, arg2buf);
  385. // arg2 should be a reg
  386. if (arg2buf[0] != 'r')
  387. {
  388. BDOS_PrintConsole("BGTS: arg2 not a reg\n");
  389. exit(1);
  390. }
  391. word arg2num = strToInt(&arg2buf[1]);
  392. instr += (arg2num << 4);
  393. // arg3
  394. word arg3num = getNumberAtArg(3);
  395. // arg3 should fit in 16 bits
  396. if (((unsigned)arg3num >> 16) > 0)
  397. {
  398. BDOS_PrintConsole("BGTS: arg3 is >16 bits\n");
  399. exit(1);
  400. }
  401. instr += (arg3num << 12);
  402. instr ^= 1;
  403. // write to mem
  404. char byteInstr[4];
  405. instrToByteArray(instr, byteInstr);
  406. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  407. (*outputCursor) += 4;
  408. }
  409. void pass2Bge(char* outputAddr, char* outputCursor)
  410. {
  411. word instr = 0x30000000;
  412. // arg1
  413. char arg1buf[16];
  414. getArgPos(1, arg1buf);
  415. // arg1 should be a reg
  416. if (arg1buf[0] != 'r')
  417. {
  418. BDOS_PrintConsole("BGE: arg1 not a reg\n");
  419. exit(1);
  420. }
  421. word arg1num = strToInt(&arg1buf[1]);
  422. instr += (arg1num << 8);
  423. // arg2
  424. char arg2buf[16];
  425. getArgPos(2, arg2buf);
  426. // arg2 should be a reg
  427. if (arg2buf[0] != 'r')
  428. {
  429. BDOS_PrintConsole("BGE: arg2 not a reg\n");
  430. exit(1);
  431. }
  432. word arg2num = strToInt(&arg2buf[1]);
  433. instr += (arg2num << 4);
  434. // arg3
  435. word arg3num = getNumberAtArg(3);
  436. // arg3 should fit in 16 bits
  437. if (((unsigned)arg3num >> 16) > 0)
  438. {
  439. BDOS_PrintConsole("BGE: arg3 is >16 bits\n");
  440. exit(1);
  441. }
  442. instr += (arg3num << 12);
  443. // write to mem
  444. char byteInstr[4];
  445. instrToByteArray(instr, byteInstr);
  446. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  447. (*outputCursor) += 4;
  448. }
  449. void pass2Bges(char* outputAddr, char* outputCursor)
  450. {
  451. word instr = 0x30000000;
  452. // arg1
  453. char arg1buf[16];
  454. getArgPos(1, arg1buf);
  455. // arg1 should be a reg
  456. if (arg1buf[0] != 'r')
  457. {
  458. BDOS_PrintConsole("BGES: arg1 not a reg\n");
  459. exit(1);
  460. }
  461. word arg1num = strToInt(&arg1buf[1]);
  462. instr += (arg1num << 8);
  463. // arg2
  464. char arg2buf[16];
  465. getArgPos(2, arg2buf);
  466. // arg2 should be a reg
  467. if (arg2buf[0] != 'r')
  468. {
  469. BDOS_PrintConsole("BGES: arg2 not a reg\n");
  470. exit(1);
  471. }
  472. word arg2num = strToInt(&arg2buf[1]);
  473. instr += (arg2num << 4);
  474. // arg3
  475. word arg3num = getNumberAtArg(3);
  476. // arg3 should fit in 16 bits
  477. if (((unsigned)arg3num >> 16) > 0)
  478. {
  479. BDOS_PrintConsole("BGES: arg3 is >16 bits\n");
  480. exit(1);
  481. }
  482. instr += (arg3num << 12);
  483. instr ^= 1;
  484. // write to mem
  485. char byteInstr[4];
  486. instrToByteArray(instr, byteInstr);
  487. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  488. (*outputCursor) += 4;
  489. }
  490. void pass2Bne(char* outputAddr, char* outputCursor)
  491. {
  492. word instr = 0x50000000;
  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("BNE: 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("BNE: 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 (((unsigned)arg3num >> 16) > 0)
  519. {
  520. BDOS_PrintConsole("BNE: 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 pass2Blt(char* outputAddr, char* outputCursor)
  531. {
  532. return;
  533. }
  534. void pass2Blts(char* outputAddr, char* outputCursor)
  535. {
  536. return;
  537. }
  538. void pass2Ble(char* outputAddr, char* outputCursor)
  539. {
  540. return;
  541. }
  542. void pass2Bles(char* outputAddr, char* outputCursor)
  543. {
  544. return;
  545. }
  546. void pass2Savpc(char* outputAddr, char* outputCursor)
  547. {
  548. word instr = 0x20000000;
  549. // arg1
  550. char arg1buf[16];
  551. getArgPos(1, arg1buf);
  552. // arg1 should be a reg
  553. if (arg1buf[0] != 'r')
  554. {
  555. BDOS_PrintConsole("SAVPC: arg1 not a reg\n");
  556. exit(1);
  557. }
  558. word arg1num = strToInt(&arg1buf[1]);
  559. instr += arg1num;
  560. // write to mem
  561. char byteInstr[4];
  562. instrToByteArray(instr, byteInstr);
  563. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  564. (*outputCursor) += 4;
  565. }
  566. void pass2Reti(char* outputAddr, char* outputCursor)
  567. {
  568. char instr[4] = {0x10, 0x00, 0x00, 0x00};
  569. memcpy((outputAddr + *outputCursor), instr, 4);
  570. (*outputCursor) += 4;
  571. }
  572. void pass2ArithBase(char* outputAddr, char* outputCursor, word arithOpCode)
  573. {
  574. word instr = 0;
  575. instr += (arithOpCode << 23);
  576. // arg1
  577. char arg1buf[16];
  578. getArgPos(1, arg1buf);
  579. // arg1 should be a reg
  580. if (arg1buf[0] != 'r')
  581. {
  582. BDOS_PrintConsole("ARITH: arg1 not a reg\n");
  583. exit(1);
  584. }
  585. word arg1num = strToInt(&arg1buf[1]);
  586. instr += (arg1num << 8);
  587. // arg2
  588. char arg2buf[16];
  589. getArgPos(2, arg2buf);
  590. word arg2num = 0;
  591. // if arg2 is a const
  592. if (arg2buf[0] != 'r')
  593. {
  594. arg2num= getNumberAtArg(2);
  595. // arg1 should fit in 11 bits
  596. if (((unsigned)arg2num >> 11) > 0)
  597. {
  598. BDOS_PrintConsole("ARITH: const is >11 bits\n");
  599. exit(1);
  600. }
  601. instr += (arg2num << 12);
  602. instr ^= (1 << 27); // set constant bit
  603. }
  604. else // arg2 is a reg
  605. {
  606. arg2num = strToInt(&arg2buf[1]);
  607. instr += (arg2num << 4);
  608. }
  609. // arg3
  610. char arg3buf[16];
  611. getArgPos(3, arg3buf);
  612. // arg3 should be a reg
  613. if (arg3buf[0] != 'r')
  614. {
  615. BDOS_PrintConsole("ARITH: arg3 not a reg\n");
  616. exit(1);
  617. }
  618. word arg3num = strToInt(&arg3buf[1]);
  619. instr += arg3num;
  620. // write to mem
  621. char byteInstr[4];
  622. instrToByteArray(instr, byteInstr);
  623. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  624. (*outputCursor) += 4;
  625. }
  626. void pass2Or(char* outputAddr, char* outputCursor)
  627. {
  628. pass2ArithBase(outputAddr, outputCursor, 0x0);
  629. }
  630. void pass2And(char* outputAddr, char* outputCursor)
  631. {
  632. pass2ArithBase(outputAddr, outputCursor, 0x1);
  633. }
  634. void pass2Xor(char* outputAddr, char* outputCursor)
  635. {
  636. pass2ArithBase(outputAddr, outputCursor, 0x2);
  637. }
  638. void pass2Add(char* outputAddr, char* outputCursor)
  639. {
  640. pass2ArithBase(outputAddr, outputCursor, 0x3);
  641. }
  642. void pass2Sub(char* outputAddr, char* outputCursor)
  643. {
  644. pass2ArithBase(outputAddr, outputCursor, 0x4);
  645. }
  646. void pass2Shiftl(char* outputAddr, char* outputCursor)
  647. {
  648. pass2ArithBase(outputAddr, outputCursor, 0x5);
  649. }
  650. void pass2Shiftr(char* outputAddr, char* outputCursor)
  651. {
  652. pass2ArithBase(outputAddr, outputCursor, 0x6);
  653. }
  654. void pass2Shiftrs(char* outputAddr, char* outputCursor)
  655. {
  656. pass2ArithBase(outputAddr, outputCursor, 0x0);
  657. }
  658. void pass2Mults(char* outputAddr, char* outputCursor)
  659. {
  660. pass2ArithBase(outputAddr, outputCursor, 0x7);
  661. }
  662. void pass2Multu(char* outputAddr, char* outputCursor)
  663. {
  664. pass2ArithBase(outputAddr, outputCursor, 0x7);
  665. }
  666. void pass2Slt(char* outputAddr, char* outputCursor)
  667. {
  668. pass2ArithBase(outputAddr, outputCursor, 0x7);
  669. }
  670. void pass2Sltu(char* outputAddr, char* outputCursor)
  671. {
  672. pass2ArithBase(outputAddr, outputCursor, 0x7);
  673. }
  674. void pass2Not(char* outputAddr, char* outputCursor)
  675. {
  676. pass2ArithBase(outputAddr, outputCursor, 0x8);
  677. }
  678. void pass2Load(char* outputAddr, char* outputCursor)
  679. {
  680. word instr = 0x70000000;
  681. word arg1num = getNumberAtArg(1);
  682. // arg1 should fit in 16 bits
  683. if (((unsigned)arg1num >> 16) > 0)
  684. {
  685. BDOS_PrintConsole("LOAD: arg1 is >16 bits\n");
  686. exit(1);
  687. }
  688. instr += (arg1num << 12);
  689. // arg2
  690. char arg2buf[16];
  691. getArgPos(2, arg2buf);
  692. // arg2 should be a reg
  693. if (arg2buf[0] != 'r')
  694. {
  695. BDOS_PrintConsole("LOAD: arg2 not a reg\n");
  696. exit(1);
  697. }
  698. word arg2num = strToInt(&arg2buf[1]);
  699. instr += arg2num;
  700. // write to mem
  701. char byteInstr[4];
  702. instrToByteArray(instr, byteInstr);
  703. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  704. (*outputCursor) += 4;
  705. }
  706. void pass2Loadhi(char* outputAddr, char* outputCursor)
  707. {
  708. word instr = 0x70000000;
  709. word arg1num = getNumberAtArg(1);
  710. // arg1 should fit in 16 bits
  711. if (((unsigned)arg1num >> 16) > 0)
  712. {
  713. BDOS_PrintConsole("LOADHI: arg1 is >16 bits\n");
  714. exit(1);
  715. }
  716. instr += (arg1num << 12);
  717. // arg2
  718. char arg2buf[16];
  719. getArgPos(2, arg2buf);
  720. // arg2 should be a reg
  721. if (arg2buf[0] != 'r')
  722. {
  723. BDOS_PrintConsole("LOADHI: arg2 not a reg\n");
  724. exit(1);
  725. }
  726. word arg2num = strToInt(&arg2buf[1]);
  727. instr += arg2num;
  728. instr ^= (1 << 8);
  729. // write to mem
  730. char byteInstr[4];
  731. instrToByteArray(instr, byteInstr);
  732. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  733. (*outputCursor) += 4;
  734. }
  735. void pass2LoadLabelLow(char* outputAddr, char* outputCursor)
  736. {
  737. word instr = 0x70000000;
  738. char arg1buf[LABEL_NAME_SIZE+1];
  739. getArgPos(1, arg1buf);
  740. word arg1num = getNumberForLabel(arg1buf);
  741. // only use the lowest 16 bits
  742. arg1num = arg1num << 16;
  743. arg1num = (unsigned)arg1num >> 16;
  744. instr += (arg1num << 12);
  745. // arg2
  746. char arg2buf[16];
  747. getArgPos(2, arg2buf);
  748. // arg2 should be a reg
  749. if (arg2buf[0] != 'r')
  750. {
  751. BDOS_PrintConsole("LOADLABELLOW: arg2 not a reg\n");
  752. exit(1);
  753. }
  754. word arg2num = strToInt(&arg2buf[1]);
  755. instr += arg2num;
  756. // write to mem
  757. char byteInstr[4];
  758. instrToByteArray(instr, byteInstr);
  759. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  760. (*outputCursor) += 4;
  761. }
  762. void pass2LoadLabelHigh(char* outputAddr, char* outputCursor)
  763. {
  764. word instr = 0x70000000;
  765. char arg1buf[LABEL_NAME_SIZE+1];
  766. getArgPos(1, arg1buf);
  767. word arg1num = getNumberForLabel(arg1buf);
  768. // only use the highest 16 bits
  769. arg1num = (unsigned)arg1num >> 16;
  770. instr += (arg1num << 12);
  771. // arg2
  772. char arg2buf[16];
  773. getArgPos(2, arg2buf);
  774. // arg2 should be a reg
  775. if (arg2buf[0] != 'r')
  776. {
  777. BDOS_PrintConsole("LOADLABELHIGH: arg2 not a reg\n");
  778. exit(1);
  779. }
  780. word arg2num = strToInt(&arg2buf[1]);
  781. instr += arg2num;
  782. instr ^= (1 << 8);
  783. // write to mem
  784. char byteInstr[4];
  785. instrToByteArray(instr, byteInstr);
  786. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  787. (*outputCursor) += 4;
  788. }
  789. void pass2Nop(char* outputAddr, char* outputCursor)
  790. {
  791. char instr[4] = {0x00, 0x00, 0x00, 0x00};
  792. memcpy((outputAddr + *outputCursor), instr, 4);
  793. (*outputCursor) += 4;
  794. }
  795. void pass2Dw(char* outputAddr, char* outputCursor)
  796. {
  797. word dwValue = getNumberAtArg(1);
  798. // write to mem
  799. char byteInstr[4];
  800. instrToByteArray(dwValue, byteInstr);
  801. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  802. (*outputCursor) += 4;
  803. }
  804. void pass2Dl(char* outputAddr, char* outputCursor)
  805. {
  806. char arg1buf[LABEL_NAME_SIZE+1];
  807. getArgPos(1, arg1buf);
  808. word dlValue = getNumberForLabel(arg1buf);
  809. // write to mem
  810. char byteInstr[4];
  811. instrToByteArray(dlValue, byteInstr);
  812. memcpy((outputAddr + *outputCursor), byteInstr, 4);
  813. (*outputCursor) += 4;
  814. }