oisc8.asm 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. %define COM_UARTF 0x03
  2. %define COM_UARTW 0x05
  3. %define COM_UARTR 0x04
  4. %define COM_LED 0x06
  5. %define COM_DIP 0x08
  6. %define COM_UARTIN 0x09
  7. %define LF 0x0a
  8. %define CR 0x0d
  9. %define LFCR 0x0a0d
  10. %define COM_UART_TRANS 0b0000_0001
  11. %define COM_UART_RECV 0b0000_0010
  12. %define COM_UART_ECHO 0b0000_0100
  13. %define COM_UART_RR 0b0000_1000 ; Read Ready
  14. %macro MEMP 1
  15. MEM1 %1@1
  16. MEM0 %1@0
  17. %endmacro
  18. %macro BRP 1
  19. BR1 %1@1
  20. BR0 %1@0
  21. %endmacro
  22. %macro RET 0
  23. BR0 STACK
  24. BR1 STACK
  25. BRZ NULL
  26. %endmacro
  27. %macro CALL 1
  28. BRP %1
  29. STACK %%return@1
  30. STACK %%return@0
  31. BRZ NULL
  32. %%return:
  33. %endmacro
  34. %macro JUMP 1
  35. BRP %1
  36. BRZ NULL
  37. %endmacro
  38. %macro BRPZ 2
  39. BRP %1
  40. BRZ %2
  41. %endmacro
  42. %macro PRINTMEM 0
  43. REG0 LWHI
  44. CALL print_hex
  45. REG0 LWLO
  46. CALL print_hex
  47. REG0 0x20
  48. CALL print_char
  49. %endmacro
  50. %macro PRINTREG 0
  51. STACK REG0
  52. STACK REG0
  53. REG0 REG1
  54. CALL print_hex
  55. REG0 STACK
  56. CALL print_hex
  57. REG0 0x20
  58. CALL print_char
  59. REG0 LWHI
  60. CALL print_hex
  61. REG0 LWLO
  62. CALL print_hex
  63. CALL println
  64. REG0 STACK
  65. %endmacro
  66. ; ==================
  67. ; Jump on conditions
  68. ; ==================
  69. %macro BGT 1
  70. BRPZ %1,LE
  71. %endmacro
  72. %macro BLT 1
  73. BRPZ %1,GE
  74. %endmacro
  75. %macro BGE 1
  76. BRPZ %1,LT
  77. %endmacro
  78. %macro BLE 1
  79. BRPZ %1,GT
  80. %endmacro
  81. %macro BEQ 1
  82. BRPZ %1,NE
  83. %endmacro
  84. %macro BNE 1
  85. BRPZ %1,EQ
  86. %endmacro
  87. %macro CALC_SIEVE_POINTER 4
  88. ; args: [value of n] [shifted value to store to] [jump label] [debug letter]
  89. ;
  90. ;; start debug
  91. ;STACK REG0
  92. ;REG0 %4
  93. ;CALL print_char
  94. ;REG0 STACK
  95. ;STACK REG0
  96. ;REG0 %1
  97. ;CALL print_u8
  98. ;REG0 0x20
  99. ;CALL print_char
  100. ;REG0 STACK
  101. ;; stop debug
  102. ALU0 %1
  103. STACK ALU0
  104. ALU1 16
  105. ALU0 DIV
  106. ;ALU1 sieve2@0
  107. MEM0 ADD
  108. ;ALU0 sieve2@1
  109. ALU1 0x00
  110. MEM1 ADC ; Memory pointer ready
  111. ALU0 STACK
  112. ALU1 16
  113. ALU1 MOD
  114. ALU0 1
  115. %2 SLL
  116. ALU0 8 ; if n%16 >= 8
  117. BGE %3 ; is high byte memhi
  118. %endmacro
  119. %macro COPY 1 ; copy current pointer to memory %1
  120. STACK MEMLO
  121. STACK MEMHI
  122. MEMP %1
  123. ALU0 STACK ; can't use 2 memory operations at once.
  124. MEMHI ALU0
  125. ALU0 STACK
  126. MEMLO ALU0
  127. %endmacro
  128. section .data 2x3x8192
  129. DBE 1
  130. intro_text: DB 0x1B,"c",0x1B,"[HBooting ",0x1B,"[1m",0x1B,"[36m","OISC",0x1B,"[0m system..",LFCR,0
  131. generalbuf: DBE 1
  132. generalbuf2: DBE 1
  133. sieve_x: DBE 1
  134. sieve_x2: DBE 1
  135. sieve_y: DBE 1
  136. sieve_y2: DBE 1
  137. sieve1: DBE 1
  138. sieve_arr: DBE 16
  139. section .text 2x3x2048
  140. REG0 intro_text@0
  141. REG1 intro_text@1
  142. CALL print_string
  143. ;; test mul_u16
  144. MEMP generalbuf
  145. REG0 60001@0 ; num1 lo
  146. REG1 60001@1 ; num1 hi
  147. MEMLO 344@0 ; num2 lo
  148. MEMHI 344@1 ; num2 hi
  149. MEMLO
  150. CALL mod_u16
  151. CALL print_u16
  152. JUMP forever
  153. ;REG0 MEMLO
  154. ;CALL print_hex
  155. ;REG0 MEMHI
  156. ;CALL print_hex
  157. ;ALU0 0x44
  158. ;ALU1 0x44
  159. ;REG0 NE
  160. ;CALL print_hex
  161. ;ALU0 0x33
  162. ;ALU1 0x00
  163. ;REG0 NE
  164. ;CALL print_hex
  165. ;CALL println
  166. REG0 '@'
  167. CALL print_char
  168. CALL calc_sieve
  169. REG0 '@'
  170. CALL print_char
  171. CALL println
  172. ;JUMP forever
  173. REG0 0
  174. .print_sieve:
  175. CALC_SIEVE_POINTER REG0,REG1,.hi,'x'
  176. ALU0 MEMLO
  177. JUMP .next
  178. .hi:
  179. ALU0 MEMHI
  180. .next:
  181. ALU1 REG1
  182. BRPZ .noprint,AND
  183. STACK REG0
  184. CALL print_u8
  185. REG0 0x20
  186. CALL print_char
  187. REG0 STACK
  188. .noprint:
  189. ALU1 1
  190. ALU0 REG0
  191. REG0 ADD
  192. BRPZ forever,REG0
  193. JUMP .print_sieve
  194. ; REG0 0
  195. ;hex_test:
  196. ; ALU0 REG0
  197. ; ALU1 1
  198. ; REG0 ADD
  199. ; CALL print_hex
  200. ; REG1 REG0
  201. ; REG0 0x20
  202. ; CALL print_char
  203. ; REG0 REG1
  204. ; BRPZ .end,REG0
  205. ; JUMP hex_test
  206. ;.end:
  207. forever:
  208. JUMP forever
  209. mod_u16:
  210. ;; Russian Peasant Multiplication
  211. ;; https://stackoverflow.com/questions/2566010
  212. ;; {reg1,reg0} = {reg1,reg0} % *generalbuf{memhi,memlo}
  213. %def $a0,REG0
  214. %def $a1,REG1
  215. %def $b0,MEMLO
  216. %def $b1,MEMHI
  217. %def $x0,MEMLO
  218. %def $x1,MEMHI
  219. COPY generalbuf2
  220. ; X = B
  221. STACK $a0
  222. STACK $a1
  223. ALU0 $a1 ; \
  224. ALU1 1 ; |
  225. $a1 SRL ; |
  226. ALU0 $a0 ; | A >> 1 (divide by 2)
  227. STACK ROR ; |
  228. ALU0 SRL ; |
  229. ALU1 STACK; |
  230. $a0 OR ; /
  231. ; Do while (X <= A/2)
  232. .while_a_start:
  233. ALU0 $x1
  234. ALU1 $a1
  235. BGT .while_a_end
  236. BLT .while_a_0
  237. ALU0 $x0
  238. ALU1 $a0
  239. BGE .while_a_end
  240. .while_a_0:
  241. ALU0 $x0 ; \
  242. ALU1 1 ; |
  243. $x0 SLL ; |
  244. STACK ROL ; | x <<= 1
  245. ALU0 $x1 ; |
  246. ALU0 SLL ; |
  247. ALU1 STACK ; |
  248. $x1 OR ; /
  249. JUMP .while_a_start
  250. .while_a_end:
  251. ;JUMP forever
  252. $a1 STACK
  253. $a0 STACK ; restore a
  254. .while_b_start:
  255. MEMP generalbuf
  256. ;PRINTREG
  257. ; Do while (A >= B)
  258. ALU0 $a1
  259. ALU1 $b1
  260. BLT .while_b_end
  261. BGT .while_b_0
  262. ALU0 $a0
  263. ALU1 $b0
  264. BLT .while_b_end
  265. .while_b_0:
  266. MEMP generalbuf2
  267. ; Check if A >= X
  268. ALU0 $a1
  269. ALU1 $x1
  270. BLT .next
  271. BGT .a_ge_x
  272. ALU0 $a0
  273. ALU1 $x0
  274. BLT .next
  275. .a_ge_x:
  276. ;PRINTREG
  277. ALU0 $a0
  278. ALU1 $x0
  279. $a0 SUB ; \
  280. ALU0 $a1 ; | A -= X
  281. ALU1 $x1 ; |
  282. $a1 SBC ; /
  283. .next:
  284. ; X >>= 1
  285. ALU0 $x1
  286. ALU1 1
  287. $x1 SRL
  288. STACK ROR
  289. ALU0 $x0
  290. ALU0 SRL
  291. ALU1 STACK
  292. $x0 OR
  293. BRPZ .check_null,$x1
  294. ; Back to while loop
  295. JUMP .while_b_start
  296. .check_null:
  297. BRPZ .while_b_end,$x0
  298. JUMP .while_b_start
  299. .while_b_end:
  300. RET
  301. calc_sieve:
  302. ;; Sieve of Atkin
  303. ; %def $xl,MEMLO
  304. ; %def $xh,MEMHI
  305. ; %def $x2l,REG0
  306. ; %def $x2h,REG1
  307. ; %def $yl,MEMLO
  308. ; %def $yh,MEMHI
  309. ; %def $y2l,REG0
  310. ; %def $y2h,REG1
  311. ;
  312. ; ; loop x setup
  313. ; MEMP sieve_x
  314. ; $xl 1 ;
  315. ; $xh 0 ; x=1
  316. ;.loopx:
  317. ; COPY sieve_x2 ; temp copy x to x2
  318. ; REG0 $xl
  319. ; REG1 $xh
  320. ; CALL mul_u16
  321. ; ALU1 0
  322. ; ALU0 REG1
  323. ; BRP .endp1
  324. ; BRZ EQ ; if x^2 >= 2^16
  325. ; ALU0 REG0
  326. ; BRZ EQ ; if x^2 >= 2^16
  327. ;
  328. ; ; loop y setup
  329. ; MEMP sieve_y
  330. ; $yl 1 ;
  331. ; $yh 0 ; y=1
  332. ;.loopy:
  333. ; COPY sieve_y2 ; temp copy y to y2
  334. ; REG0 $yl
  335. ; REG1 $yh
  336. ; CALL mul_u16
  337. ; ALU1 0
  338. ; ALU0 REG1
  339. ; BRP .loopxe
  340. ; BRZ EQ ; if y^2 >= 2^16
  341. ; ALU0 REG0
  342. ; BRZ EQ ; if y^2 >= 2^16
  343. ;
  344. ; ; ==================
  345. ; ; Start of Main loop
  346. ; ; ==================
  347. ;
  348. ; ;MEMP sieve1
  349. ;
  350. ; %def $nh,MEMHI
  351. ; %def $nl,MEMLO
  352. ; %def $tmp,MEMLO
  353. ;.c1:
  354. ; MEMP sieve_x2
  355. ; COPY sieve1 ; copy x^2 to n
  356. ; REG0 4
  357. ; REG1 0
  358. ; CALL mul_u16 ; x^2 * 0x0004
  359. ; ALU0 REG1 ; \
  360. ; ALU1 0 ; |
  361. ; BRP .c2 ; | checking if 4*x^2 overflow
  362. ; BRZ EQ ; |
  363. ; ALU0 REG0 ; |
  364. ; BRZ EQ ; /
  365. ; ; n += y^2
  366. ; REG0 $nl
  367. ; REG1 $nh
  368. ; MEMP sieve_y2
  369. ; ALU0 REG0 ; $nl
  370. ; ALU1 MEMLO ; $y2l
  371. ; REG0 ADD
  372. ; ALU0 REG1
  373. ; ALU1 MEMHI
  374. ; REG1 ADC
  375. ; ALU0 ADDC ; \
  376. ; ALU1 0 ; | chcek for 4*x^2+y^2 oveflow
  377. ; BNE .c2 ; /
  378. ;
  379. ;
  380. ; %def $n,REG0; to be deleted
  381. ; ALU0 REG0
  382. ; ALU1 4
  383. ; STACK MULLO
  384. ; ALU0 MULHI ; \
  385. ; ALU1 0 ; | Checking if 4x^2 > 255
  386. ; ALU1 EQ ; /
  387. ; ALU0 STACK
  388. ; BRPZ .c2,ALU1 ; if mulhi != 0: goto .c2
  389. ; ALU1 REG1
  390. ; $n ADD ; n = mullo( low{4*x^2} ) + y^2
  391. ; ALU0 ADDC ; \
  392. ; ALU1 0 ; | Checking if 4x^2+y^2 > 255
  393. ; BNE .c2 ; /
  394. ; ALU0 $n ; MEMHI := n
  395. ; ALU1 12
  396. ; $tmp MOD
  397. ; ALU0 $tmp
  398. ; ALU1 1
  399. ; BEQ .c1r ; n%12 == 1
  400. ; ALU0 $tmp
  401. ; ALU1 5
  402. ; BEQ .c1r ; n%12 == 5
  403. ; JUMP .c2
  404. ;.c1r:
  405. ; CALL xorSieveArray
  406. ; MEMP sieve1
  407. ;.c2:
  408. ; ALU0 REG0
  409. ; ALU1 3
  410. ; STACK MULLO
  411. ; ALU0 MULHI ; \
  412. ; ALU1 0 ; | Checking if 3x^2 > 255
  413. ; ALU1 EQ ; /
  414. ; ALU0 STACK
  415. ; BRPZ .c3,ALU1
  416. ; ALU1 REG1
  417. ; STACK ADD
  418. ; ALU0 ADDC ; \
  419. ; ALU1 0 ; | Checking if 3x^2+y^2 > 255
  420. ; ALU1 EQ ; /
  421. ; ALU0 STACK
  422. ; BRPZ .c3,ALU1
  423. ; $n ALU0 ; MEMHI := n
  424. ; ALU1 12
  425. ; ALU0 MOD
  426. ; ALU1 7
  427. ; BNE .c3
  428. ; CALL xorSieveArray
  429. ;.c3:
  430. ; ;MEMP sieve
  431. ; ;ALU1 $y ; y
  432. ; ;ALU0 $x ; x
  433. ; BLE .loopye ; Function needs x>y
  434. ;
  435. ; MEMP sieve1
  436. ; ALU0 REG0
  437. ; ALU1 3
  438. ; $tmp MULHI ; MEMLO := HIGH(3x^2)
  439. ; ALU0 MULLO
  440. ; ALU1 REG1
  441. ; $n SUB ; MEMHI := LOW(3x^2)-y^2
  442. ; ALU0 $tmp
  443. ; ALU1 0x00
  444. ; ALU0 SBC ; ALU0 := HIGH(3x^2)-CARRY(y^2)
  445. ; BNE .c4 ; ALU0 != 0x00: goto .c4
  446. ; ALU0 $n ; \
  447. ; ALU1 12 ; |
  448. ; ALU0 MOD ; | Checking if n%12 != 11
  449. ; ALU1 11 ; |
  450. ; BNE .c4 ; /
  451. ; CALL xorSieveArray
  452. ;.c4:
  453. ; ;MEMP sieve
  454. ; ; ================
  455. ; ; End of main loop
  456. ; ; ================
  457. ;.loopye:
  458. ; MEMP sieve_y
  459. ; ALU0 $yl ; \
  460. ; ALU1 1 ; |
  461. ; $yl ADD ; | y++
  462. ; ALU1 ADDC ; |
  463. ; ALU0 $yh ; |
  464. ; $yh ADD ; /
  465. ; JUMP .loopy
  466. ;.loopxe:
  467. ; MEMP sieve_x
  468. ; ALU0 $xl ; \
  469. ; ALU1 1 ; |
  470. ; $xl ADD ; | x++
  471. ; ALU1 ADDC ; |
  472. ; ALU0 $xh ; |
  473. ; $xh ADD ; /
  474. ; JUMP .loopx
  475. ; ; =============
  476. ; ; End of part 1
  477. ; ; =============
  478. ;.endp1:
  479. ; ; now lets reject squares
  480. ; %def $r,REG0
  481. ; %def $r2,REG1
  482. ; $r 5 ; r:=5
  483. ;.loopr:
  484. ; ALU0 $r
  485. ; ALU1 $r
  486. ; $r2 MULLO ; reg1 := r^2
  487. ; ALU0 MULHI
  488. ; ALU1 0x00
  489. ; BNE .endp2 ; end if r^2 > 255
  490. ; ; accessing mem cell
  491. ; STACK REG0
  492. ; CALC_SIEVE_POINTER REG0,REG0,.hi,'R'
  493. ; ALU1 MEMLO
  494. ; JUMP .x1
  495. ;.hi:
  496. ; ALU1 MEMHI
  497. ;.x1:
  498. ; ALU0 REG0
  499. ; REG0 STACK
  500. ; BRPZ .loopre,AND ; if sieve[r] = 0
  501. ; ; loopi
  502. ; STACK $r; reg0 := r
  503. ; REG0 $r2 ; i := r^2
  504. ;.loopi:
  505. ; STACK REG0
  506. ; CALC_SIEVE_POINTER REG0,REG0,.x2hi,'D'
  507. ; ALU0 REG0
  508. ; ALU1 0xFF
  509. ; ALU0 XOR ; invert REG0
  510. ; ALU1 MEMLO
  511. ; MEMLO AND ; set sieve[i] = 0
  512. ; JUMP .x2
  513. ;.x2hi:
  514. ; ALU0 REG0
  515. ; ALU1 0xFF
  516. ; ALU0 XOR ; invert REG0
  517. ; ALU1 MEMHI
  518. ; MEMHI AND ; set sieve[i] = 0
  519. ;.x2:
  520. ; REG0 STACK
  521. ;.loopie:
  522. ; ALU0 REG0
  523. ; ALU1 REG1
  524. ; REG0 ADD
  525. ; BRPZ .loopi,ADDC ; if not overflow
  526. ; $r STACK ; restoring stack for r
  527. ;
  528. ;.loopre:
  529. ; ALU0 $r
  530. ; ALU1 1
  531. ; $r ADD ; r ++
  532. ; JUMP .loopr
  533. ;.endp2:
  534. RET
  535. xorSieveArray:
  536. ; n := memhi
  537. ; sieve[n;16] ^= 1<<n%16
  538. STACK REG0
  539. REG0 MEMHI
  540. CALL print_u8
  541. REG0 0x20
  542. CALL print_char
  543. ALU0 MEMHI
  544. ALU1 16
  545. REG0 DIV
  546. CALL print_u8
  547. REG0 0x20
  548. CALL print_char
  549. CALC_SIEVE_POINTER MEMHI,REG0,.hi,'A'
  550. ;; debug
  551. STACK REG0
  552. REG0 'L'
  553. CALL print_char
  554. REG0 MEMLO
  555. CALL print_bin
  556. REG0 '^'
  557. CALL print_char
  558. REG0 STACK
  559. CALL print_bin
  560. ;; debug end
  561. ALU0 MEMLO
  562. ALU1 REG0
  563. MEMLO XOR
  564. JUMP .done
  565. .hi:
  566. ;; debug
  567. STACK REG0
  568. REG0 'H'
  569. CALL print_char
  570. REG0 MEMHI
  571. CALL print_bin
  572. REG0 '^'
  573. CALL print_char
  574. REG0 STACK
  575. CALL print_bin
  576. ;; debug end
  577. ALU0 MEMHI
  578. ALU1 REG0
  579. MEMHI XOR
  580. .done:
  581. ;; debug
  582. STACK XOR
  583. REG0 '='
  584. CALL print_char
  585. REG0 STACK
  586. CALL print_bin
  587. CALL println
  588. ;; debug end
  589. REG0 STACK
  590. RET
  591. mul_u16:
  592. ; m1H, m1L, m2H, m2L, MEMHI, MEMLO, REG1, REG0
  593. ; answer = {MEMHI, MEMLO, REG1, REG0}
  594. %def $m1H,REG1
  595. %def $m2H,MEMHI
  596. %def $m1L,REG0
  597. %def $m2L,MEMLO
  598. %def $res3,MEMLO ;REG0
  599. %def $res2,MEMHI ;REG1
  600. %def $res1,REG0 ;MEMLO
  601. %def $res0,REG1 ;MEMHI
  602. ;MEMP generalbuf
  603. ;REG0 -> m1L
  604. ;REG1 -> m2L
  605. ALU0 $m2L
  606. ALU1 $m2H
  607. STACK ALU1 ;m2H
  608. STACK $m1L
  609. STACK ALU0 ;m2L
  610. STACK $m1H ;m1H
  611. STACK ALU0 ;m2L
  612. STACK $m1L
  613. ALU0 $m1H
  614. $res2 MULLO
  615. $res3 MULHI
  616. ALU0 STACK ;m1L
  617. ALU1 STACK ;m2L
  618. $res0 MULLO
  619. $res1 MULHI
  620. ALU0 STACK ;m1H
  621. ALU1 STACK ;m2L
  622. STACK MULHI
  623. ALU0 MULLO
  624. ALU1 $res1
  625. $res1 ADD
  626. ALU0 STACK
  627. ALU1 $res2
  628. $res2 ADC
  629. ALU1 ADDC
  630. ALU0 $res3
  631. $res3 ADD
  632. ALU0 STACK ;m1L
  633. ALU1 STACK ;m2H
  634. STACK MULHI
  635. ALU0 MULLO
  636. ALU1 $res1
  637. $res1 ADD
  638. ALU0 $res2
  639. ALU1 STACK
  640. $res2 ADC
  641. ALU0 ADDC
  642. ALU1 $res3
  643. $res3 ADD
  644. RET
  645. bin2digit:
  646. ; Converts U16 to digit
  647. ; Adopted from http:;www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  648. ; Digit {reg1 reg0} Place in 10^n generalbuf
  649. ; Memory pointer must be set to generalbuf
  650. STACK 0
  651. .a:
  652. ALU0 REG1
  653. ALU1 LWHI
  654. BLT .c
  655. BGT .b
  656. ALU0 REG0
  657. ALU1 LWLO
  658. BLT .c
  659. .b:
  660. ALU0 REG0
  661. ALU1 LWLO
  662. REG0 SUB
  663. ALU0 REG1
  664. ALU1 LWHI
  665. REG1 SBC
  666. ALU0 STACK
  667. ALU1 1
  668. STACK ADD
  669. JUMP .a
  670. .c:
  671. SWLO REG0
  672. REG0 STACK
  673. SWHI REG0
  674. REG0 LWLO
  675. RET
  676. print_u16:
  677. ; Prints U16 in {reg1 reg0}
  678. STACK REG0
  679. STACK REG1
  680. MEMP generalbuf
  681. SWHI 10000@1
  682. SWLO 10000@0 ; 10000 in hex
  683. CALL bin2digit
  684. ALU0 48
  685. ALU1 LWHI
  686. STACK REG0
  687. REG0 ADD
  688. CALL print_char
  689. REG0 STACK
  690. SWHI 1000@1
  691. SWLO 1000@0
  692. CALL bin2digit
  693. ALU0 48
  694. ALU1 LWHI
  695. STACK REG0
  696. REG0 ADD
  697. CALL print_char
  698. REG0 STACK
  699. SWHI 0
  700. SWLO 100
  701. CALL bin2digit
  702. ALU0 48
  703. ALU1 LWHI
  704. STACK REG0
  705. REG0 ADD
  706. CALL print_char
  707. REG0 STACK
  708. ALU0 REG0
  709. ALU1 100
  710. REG1 MOD
  711. ALU1 10
  712. ALU0 REG0
  713. STACK MOD
  714. ALU1 MOD
  715. ALU0 REG1
  716. ALU0 SUB
  717. ALU1 10
  718. ALU0 DIV
  719. ALU1 48
  720. REG0 ADD
  721. CALL print_char
  722. ALU0 STACK
  723. ALU1 48
  724. REG0 ADD
  725. CALL print_char
  726. REG1 STACK
  727. REG0 STACK
  728. RET
  729. print_u8:
  730. ; print u8 in reg0
  731. ; a = 128%10 = 8
  732. ; a = 128%100 - a // 10 = 2
  733. ; a = 128%1000 - a // 100 = 1
  734. STACK REG1
  735. REG1 REG0
  736. ALU1 10
  737. ALU0 REG0
  738. ALU0 MOD ; ALU0 = reg0%10
  739. STACK ALU0
  740. REG0 ALU0
  741. ALU0 REG1
  742. BRPZ .p3,GE
  743. ALU1 100
  744. ALU0 REG1
  745. ALU0 MOD
  746. ALU1 STACK
  747. STACK ALU1
  748. ALU0 SUB
  749. ALU1 10
  750. ALU1 DIV
  751. STACK ALU1
  752. ALU0 REG1
  753. ALU1 100
  754. BRPZ .p2,GE
  755. ALU1 200
  756. BRPZ .p1,GE
  757. REG0 '2'
  758. CALL print_char
  759. JUMP .p2
  760. .p1:
  761. REG0 '1'
  762. CALL print_char
  763. .p2:
  764. ALU0 48
  765. ALU1 STACK
  766. REG0 ADD
  767. CALl print_char
  768. .p3:
  769. ALU0 48
  770. ALU1 STACK
  771. REG0 ADD
  772. CALl print_char
  773. REG0 REG1
  774. REG1 STACK
  775. RET
  776. print_bin:
  777. ; print reg0 as binary
  778. STACK REG0
  779. STACK REG1
  780. REG1 REG0 ; Making copy
  781. ALU0 0b1000_0000
  782. .start:
  783. ALU1 REG1
  784. STACK ALU0
  785. BRPZ .print0,AND
  786. .print1:
  787. REG0 '1'
  788. CALL print_char
  789. JUMP .end
  790. .print0:
  791. REG0 '0'
  792. CALL print_char
  793. .end:
  794. ALU1 1
  795. ALU0 STACK
  796. ALU0 SRL
  797. BRPZ .done,ALU0
  798. REG0 REG1
  799. JUMP .start
  800. .done:
  801. REG1 STACK
  802. REG0 STACK
  803. RET
  804. print_hex:
  805. ; prints reg0 as hex
  806. STACK REG0
  807. STACK REG1
  808. REG1 REG0
  809. ALU1 4
  810. ALU0 REG0
  811. ALU1 SRL
  812. ALU0 10
  813. BRPZ .p0,GT
  814. ALU0 48
  815. JUMP .p1
  816. .p0:
  817. ALU0 55
  818. .p1:
  819. REG0 ADD
  820. CALL print_char
  821. REG0 REG1
  822. ALU0 0b0000_1111
  823. ALU1 REG0
  824. ALU1 AND
  825. ALU0 10
  826. BRPZ .p2,GT
  827. ALU0 48
  828. JUMP .p3
  829. .p2:
  830. ALU0 55
  831. .p3:
  832. REG0 ADD
  833. CALL print_char
  834. REG1 STACK
  835. REG0 STACK
  836. RET
  837. println:
  838. STACK REG0
  839. REG0 LF
  840. CALL print_char
  841. REG0 CR
  842. CALL print_char
  843. REG0 STACK
  844. RET
  845. print_string:
  846. ; prints string in memory location {reg0, reg1}
  847. .st:
  848. MEM0 REG0
  849. MEM1 REG1
  850. BRPZ .end,LWHI
  851. COMA COM_UARTR
  852. BRP .loop0
  853. ALU0 COM_UART_RECV
  854. .loop0:
  855. ALU1 COMD
  856. ALU1 AND
  857. BRZ NE
  858. COMA COM_UARTW
  859. COMD LWHI
  860. BRPZ .end,LWLO
  861. COMA COM_UARTR
  862. BRP .loop1
  863. .loop1:
  864. ALU1 COMD
  865. ALU1 AND
  866. BRZ NE
  867. COMA COM_UARTW
  868. COMD LWLO
  869. ALU0 REG0
  870. ALU1 1
  871. REG0 ADD
  872. ALU1 ADDC
  873. ALU0 REG1
  874. REG1 ADD
  875. JUMP .st
  876. .end:
  877. RET
  878. print_char:
  879. ; prints char in reg0
  880. COMA COM_UARTR
  881. BRP .loop0
  882. ALU0 COM_UART_RECV
  883. .loop0:
  884. ALU1 COMD
  885. ALU1 AND
  886. BRZ NE
  887. COMA COM_UARTW
  888. COMD REG0
  889. RET
  890. read_char:
  891. ; waits for char and stores that in reg0
  892. COMA COM_UARTR
  893. ALU0 0b0000_1000
  894. BRP .loop
  895. .loop:
  896. ALU1 COMD
  897. BRZ AND
  898. COMA COM_UARTIN
  899. REG0 COMD
  900. RET