risc8.asm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  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 NULL 0x000000
  8. %define LF 0x0a
  9. %define CR 0x0d
  10. %define LFCR 0x0a0d
  11. %define COM_UART_TRANS 0b0000_0001
  12. %define COM_UART_RECV 0b0000_0010
  13. %define COM_UART_ECHO 0b0000_0100
  14. %define COM_UART_RR 0b0000_1000 ; Read Ready
  15. section .data 2x3x8192
  16. intro_text DB 0x1B63,0x1B5B324A,0x1B5B34303B33313B316D,"GLaDOS v0.0",0x1B5B303B33323B34306D," starting..",LFCR,0
  17. eq1_text DB LFCR,"1) 0x1194 * 0x2710 = 0x",0
  18. eq2_text DB LFCR,"2) 3*2=",0
  19. eq3_text DB LFCR,"3) 3*2=",0
  20. initial_vt100 DB 0x1B,'c',0x1B,"[2J",0x1B,"[40;32m",0
  21. error_text DB LFCR,"Invalid operation: ",0
  22. error0 DB "Buffer is full",0
  23. error1 DB "Number value overflow",0
  24. mul16buf DBE 8
  25. generalbuf DBE 1
  26. termHiFlag DB 0x0000
  27. termBuff DB 10,0
  28. DBE 10
  29. mallocPointer DB 0
  30. MEMEND DB 0
  31. section .text 1x2x4096
  32. setup
  33. CPY0 65432@1
  34. CPY1 65432@0
  35. CALL printU16
  36. ; Run init
  37. INTRE interrupt
  38. ;CALL read_char
  39. ;CALL print_char
  40. ;.echo
  41. ; JUMP .echo
  42. ; CALL read_char
  43. ; CALL print_char
  44. CPY1 intro_text@0
  45. CPY2 intro_text@1
  46. CALL print_msg
  47. ;CALL read_char
  48. ;CPY1 COM_UART_ECHO
  49. ;COM r1,COM_UARTF
  50. CPY1 eq1_text@0
  51. CPY2 eq1_text@1
  52. CALL print_msg
  53. CPY0 0x11 ; 4500
  54. CPY1 0x94
  55. CPY2 0x27 ; 10000
  56. CPY3 0x10
  57. CALL mulU16
  58. CALL printhex
  59. MOVE r0,r1
  60. CALL printhex
  61. MOVE r0,r2
  62. CALL printhex
  63. MOVE r0,r3
  64. CALL printhex
  65. CALL println
  66. CALL sieveOfAtkin
  67. CALL println
  68. loop
  69. CPY0 0
  70. PUSH r0
  71. CPY0 '>'
  72. CALL print_char
  73. CPY0 0x20 ; space
  74. CALL print_char
  75. ;.loop
  76. ; CALL read_char
  77. ; CALL print_char
  78. ; ;BEQ r2,0x0a,.start
  79. ; BEQ r0,0x0d,.error
  80. ; JUMP .loop
  81. ;.error
  82. ; CPY1 error_text@0
  83. ; CPY2 error_text@1
  84. ; CALL print_msg
  85. ; JUMP .start
  86. .read
  87. CALL read_char
  88. BGT r0,57,.readc0
  89. BGT r0,48,.readadd
  90. .readc0
  91. BEQ r0,0x0d,.done
  92. ;BEQ r0,0x20,.echo
  93. BEQ r0,0x08,.backspace
  94. BEQ r0,0x7F,.backspace
  95. BEQ r0,0x2A,.readadd ; *
  96. BEQ r0,0x2B,.readadd ; +
  97. BEQ r0,0x2D,.readadd ; -
  98. BEQ r0,0x2F,.readadd ; /
  99. JUMP .read
  100. .backspace
  101. ; POP r1
  102. ; BEQ r1,0,.backspaceCheck
  103. ; CPY0 0x1B
  104. ; CALL print_char
  105. ; CPY0 'c'
  106. ; CALL print_char
  107. ; JUMP .read
  108. ;.backspaceCheck
  109. ; PUSH r1
  110. JUMP .read
  111. .readadd
  112. LWLO r3,termHiFlag
  113. BZ r3,.readadd0
  114. JUMP .readstore
  115. .readadd0
  116. CPY3 1
  117. SWHI r0
  118. SWLO r3,termHiFlag
  119. JUMP .echo
  120. .readstore
  121. CPY2 0
  122. LWHI r3,termHiFlag
  123. SWLO r2,termHiFlag
  124. MOVE r2,r0
  125. CPY0 termBuff@0
  126. CPY1 termBuff@1
  127. CALL arrayPush
  128. ; Check if buffer overflow
  129. BZ r0,.readstore0
  130. MOVE r0,r2
  131. JUMP .echo
  132. .readstore0
  133. MOVE r0,r2
  134. BZ r1,.error0
  135. .echo
  136. CALL print_char
  137. JUMP .read
  138. .done
  139. ; if odd number of chars, push r0, 0 to array
  140. LWLO r3,termHiFlag
  141. BZ r3,.doneC
  142. ;LWHI r2,termHiFlag
  143. ;CPY3 0
  144. ;CPY0 termBuff@0
  145. ;CPY1 termBuff@1
  146. ;CALL arrayPush
  147. .doneC
  148. CPY1 termBuff@0
  149. CPY2 termBuff@1
  150. CALL Process
  151. CPY0 termBuff@0
  152. CPY1 termBuff@1
  153. CALL arrayClear
  154. JUMP loop
  155. .done0
  156. POP r0
  157. BEQ r0,0,.done1
  158. CALL print_char
  159. JUMP .done0
  160. .done1
  161. CALL println
  162. JUMP loop
  163. .error0
  164. CALL println
  165. CPY1 error0@0
  166. CPY2 error0@1
  167. CALL print_msg
  168. CALL println
  169. JUMP loop
  170. MOVE r1,r0
  171. SUBI r1,48
  172. CALL print_char
  173. CALL read_char
  174. MOVE r2,r0
  175. CALL print_char
  176. CALL read_char
  177. MOVE r3,r0
  178. SUBI r3,48
  179. CALL print_char
  180. BEQ r2,'+',.add
  181. BEQ r2,'-',.sub
  182. JUMP .invalid
  183. .add
  184. ADD r1,r3
  185. JUMP .result
  186. .sub
  187. SUB r1,r3
  188. JUMP .result
  189. .invalid
  190. CPY1 error_text@0
  191. CPY2 error_text@1
  192. CALL print_msg
  193. JUMP .done
  194. .result
  195. PUSH r1
  196. CPY0 '='
  197. CALL print_char
  198. POP r0
  199. ADDI r0,48
  200. CALL print_char
  201. Process
  202. ; Input array *{r2 r1}
  203. ;CPY1 termBuff@0
  204. ;CPY2 termBuff@1
  205. .readnext
  206. INC r1
  207. ADDC r2
  208. CI1 r2
  209. CI0 r1
  210. SWLO r0,NULL
  211. .isdigit
  212. ;BGT r0,57,.issymbol
  213. ;BGT r0,48,.digit
  214. .issymbol
  215. ;JUMP .error
  216. .digit
  217. ;CI1 r2
  218. ;CI0 r1
  219. ;SWHI r0
  220. .error
  221. CPY1 error_text@0
  222. CPY2 error_text@1
  223. CALL print_msg
  224. CPY1 termBuff@0
  225. CPY2 termBuff@1
  226. INC r1
  227. ADDC r2
  228. CALL print_msg
  229. .end
  230. CALL println
  231. RET
  232. printbin
  233. ; print r0 as binary
  234. PUSH r2
  235. PUSH r1
  236. CPY2 0b1000_0000
  237. MOVE r1,r0
  238. .start
  239. AND r0,r2
  240. BZ r0,.print0
  241. .print1
  242. CPY0 '1'
  243. CALL print_char
  244. JUMP .end
  245. .print0
  246. CPY0 '0'
  247. CALL print_char
  248. .end
  249. SRL r2,1
  250. BZ r2,.done
  251. MOVE r0,r1
  252. JUMP .start
  253. .done
  254. POP r1
  255. POP r2
  256. RET
  257. printhex
  258. ; print r0 as hex
  259. PUSH r0
  260. PUSH r1
  261. MOVE r1,r0
  262. SRL r0,4
  263. BGT r0,9,.p0
  264. ADDI r0,48
  265. JUMP .p1
  266. .p0
  267. ADDI r0,55
  268. .p1
  269. CALL print_char
  270. MOVE r0,r1
  271. POP r1
  272. ANDI r0,0b0000_1111
  273. BGT r0,9,.p2
  274. ADDI r0,48
  275. JUMP .p3
  276. .p2
  277. ADDI r0,55
  278. .p3
  279. CALL print_char
  280. POP r0
  281. RET
  282. ;.done
  283. ;; Equation 1
  284. ;CPY1 eq1_text@0
  285. ;CPY2 eq1_text@1
  286. ;CALL print_msg
  287. ;CPY0 3
  288. ;ADDI r0,2
  289. ;ADDI r0,48 ; Convert to ascii
  290. ;CALL print_char
  291. ;
  292. ;; Equation 2
  293. ;CPY1 eq2_text@0
  294. ;CPY2 eq2_text@1
  295. ;CALL print_msg
  296. ;CPY0 6
  297. ;SUBI r0,2
  298. ;ADDI r0,48 ; Convert to ascii
  299. ;CALL print_char
  300. ;; Equation 3
  301. ;CPY1 eq3_text@0
  302. ;CPY2 eq3_text@1
  303. ;CALL print_msg
  304. ;CPY0 3
  305. ;CPY1 2
  306. ;MUL r0,r1
  307. ;ADDI r0,48 ; Convert to ascii
  308. ;CALL print_char
  309. ;
  310. ;CPY1 eq3x_text@0
  311. ;CPY2 eq3x_text@1
  312. ;CALL print_msg
  313. ;AH r0
  314. ;ADDI r0,48 ; Convert to ascii
  315. ;CALL print_char
  316. ;; Equation 4
  317. ;CPY1 eq4_text@0
  318. ;CPY2 eq4_text@1
  319. ;CALL print_msg
  320. ;CPY0 9
  321. ;CPY1 2
  322. ;DIV r0,r1
  323. ;ADDI r0,48 ; Convert to ascii
  324. ;CALL print_char
  325. ;; Equation 5
  326. ;CPY1 eq5_text@0
  327. ;CPY2 eq5_text@1
  328. ;CALL print_msg
  329. ;AH r0
  330. ;ADDI r0,48 ; Convert to ascii
  331. ;CALL print_char
  332. ;CALL println
  333. ;JUMP .start
  334. ;CPY3 0
  335. start
  336. INC r3
  337. JUMP start
  338. interrupt
  339. PUSH r0
  340. GETIF r0
  341. POP r0
  342. RETI
  343. println
  344. PUSH r0
  345. CPY0 LF
  346. CALL print_char
  347. CPY0 CR
  348. CALL print_char
  349. POP r0
  350. RET
  351. %define SLIMIT 255
  352. sieveOfAtkin
  353. ; Calculate primes up to limit
  354. CPY0 MEMEND@0
  355. CPY1 MEMEND@1
  356. CPY2 0
  357. CPY3 0
  358. ; Initialising memory with 0s
  359. .clearCell
  360. CPY2 0
  361. CI0 r0
  362. CI0 r1
  363. SWLO r2,NULL
  364. INC r3
  365. ADDC r3
  366. INC r1
  367. ADDC r0
  368. BZ r3,.clearCell
  369. .main
  370. CPY0 1 ; x=1
  371. .loopx
  372. ; FOR loop x
  373. PUSH r0
  374. MUL r0,r0 ; x^2
  375. ; check if more than 2 bytes
  376. AH r2
  377. BZ r2,.loopx0
  378. POP r0
  379. JUMP .p2; to part2
  380. .loopx0 ; Loop content
  381. CPY1 1 ; y=1
  382. .loopy
  383. ; FOR loop y
  384. PUSH r1
  385. MUL r1,r1 ; y^2
  386. ; check if more than 2 bytes
  387. AH r2
  388. BZ r2,.loopy0
  389. POP r1
  390. JUMP .loopxe; to loop x end
  391. .loopy0 ; Loop content
  392. ; ======================
  393. ; START OF MAIN FUNCTION
  394. ; ======================
  395. ;At this point r0=x^2; r1=y^2
  396. CPY2 4 ; n=4
  397. MUL r2,r0 ; n=4*x^2
  398. AH r3 ; check for overflow
  399. BZ r3,.c1a
  400. JUMP .c2
  401. .c1a
  402. ADD r2,r1 ; n=4*x^2 + y^2
  403. ADDC r3 ; check for overflow
  404. BZ r3,.c1b
  405. JUMP .c2
  406. .c1b ; check if n%12==1
  407. PUSH r2
  408. CPY3 12
  409. DIV r2,r3
  410. AH r2
  411. CPY3 1
  412. XOR r3,r2
  413. BZ r3,.c1f
  414. ; check if n%12==5
  415. CPY3 5
  416. XOR r3,r2
  417. BZ r3,.c1f
  418. POP r2; return n from stack
  419. ; else cary on C2
  420. JUMP .c2
  421. .c1f
  422. POP r2; return n from stack
  423. CALL sieveOfAtkinInvN
  424. .c2
  425. ; At this point r0=x^2; r1=y^2
  426. CPY2 3 ; n=3
  427. MUL r2,r0 ; n=3*x^2
  428. AH r3 ; check for overflow
  429. BZ r3,.c2a
  430. JUMP .c3
  431. .c2a
  432. ADD r2,r1 ; n=3*x^2 + y^2
  433. ADDC r3 ; check for overflow
  434. BZ r3,.c2b
  435. JUMP .c3
  436. .c2b ; check if n%12==7
  437. PUSH r2
  438. CPY3 12
  439. DIV r2,r3
  440. AH r2
  441. CPY3 7
  442. XOR r3,r2
  443. POP r2
  444. BZ r3,.c2f
  445. JUMP .c3
  446. .c2f
  447. CALL sieveOfAtkinInvN
  448. .c3
  449. ; At this point r0=x^2; r1=y^2
  450. ; n=3*x^2-y^2
  451. CPY2 3
  452. MUL r2,r0
  453. AH r3
  454. SUB r2,r1
  455. SUBC r3
  456. BZ r3,.c3a ; check for limit
  457. JUMP .loopye
  458. .c3a; check if x>y
  459. ; r2=n
  460. POP r1 ; get y
  461. POP r0 ; get x
  462. CI2 r1
  463. BGT r0,0,.c3b
  464. PUSH r0
  465. PUSH r1
  466. JUMP .loopye
  467. .c3b; check if n%12==11
  468. PUSH r0
  469. PUSH r1
  470. PUSH r2
  471. CPY3 12
  472. DIV r2,r3
  473. AH r2 ; n%12
  474. CPY3 11
  475. XOR r3,r2
  476. POP r2
  477. BZ r3,.c3c
  478. JUMP .loopye
  479. .c3c
  480. CALL sieveOfAtkinInvN
  481. ; ====================
  482. ; END OF MAIN FUNCTION
  483. ; ====================
  484. .loopye
  485. POP r1
  486. INC r1
  487. JUMP .loopy
  488. .loopxe
  489. POP r0
  490. INC r0
  491. JUMP .loopx
  492. .p2
  493. ; for (r=5;r^2<limit;r++)
  494. CPY0 5 ; r=5
  495. .loopr
  496. MOVE r1,r0
  497. MUL r1,r0 ; r^2
  498. AH r3
  499. BZ r3,.r0 ; check for overflow
  500. JUMP .end
  501. .r0
  502. CPY2 MEMEND@0
  503. CPY3 MEMEND@1
  504. ADD r2,r0 ; Add r to pointer
  505. ADDC r3
  506. CI0 r2
  507. CI1 r3
  508. LWLO r2,NULL ; if sieve[r]
  509. BZ r2,.loopre
  510. ; for(i = r^2; i<limit;i+=r^2) sieve[r]=0
  511. ; at this point r0 -> r; r1 -> r^2
  512. PUSH r0
  513. MOVE r0,r1 ; set i=r^2
  514. .loopi
  515. ; sieve[r] = 0
  516. CPY2 MEMEND@0
  517. CPY3 MEMEND@1
  518. ADD r2,r0
  519. ADDC r3
  520. CPY0 0
  521. CI0 r2
  522. CI1 r3
  523. LWLO r0,NULL
  524. .loopie
  525. ADD r0,r1
  526. ADDC r2
  527. BZ r2,.loopi ; if carry is zero carry on
  528. POP r0
  529. .loopre
  530. INC r0
  531. JUMP .loopr
  532. .end
  533. ; shall we print here?
  534. CPY0 0
  535. CPY1 MEMEND@0
  536. CPY2 MEMEND@1
  537. .print0
  538. CI0 r1
  539. CI1 r2
  540. LWLO r3,NULL
  541. BZ r3,.print1
  542. CALL printU8
  543. PUSH r0
  544. CPY0 0x20
  545. CALL print_char
  546. POP r0
  547. .print1
  548. INC r2
  549. ADDC r1
  550. INC r0
  551. ADDC r3
  552. BZ r3,.print0 ; if not overflow, carry on
  553. RET
  554. ;sieveOfAtkinCore
  555. sieveOfAtkinInvN
  556. ; sieve[n] ^=1 where n=r2
  557. PUSH r0
  558. PUSH r1
  559. PUSH r3
  560. CPY0 MEMEND@0
  561. CPY1 MEMEND@1
  562. ADD r0,r2
  563. ADDC r1
  564. CI0 r0
  565. CI1 r1
  566. LWLO r3,NULL
  567. XORI r3,1
  568. CI0 r0
  569. CI1 r1
  570. SWLO r3,NULL
  571. MOVE r0,r2
  572. CALL printU8
  573. CPY0 0x20
  574. CALL print_char
  575. POP r3
  576. POP r1
  577. POP r0
  578. ; MOVE r0,r2
  579. ; CPY1 16
  580. ; DIV r0,r1; n/=16
  581. ; PUSH r2
  582. ; ; Get array pointer + n/=16
  583. ; CPY1 MEMEND@0
  584. ; CPY2 MEMEND@1
  585. ; ADD r2,r0
  586. ; ADDC r1
  587. RET
  588. mulU16
  589. ; Multiply 2 unsigned 16-bit int
  590. ; {r0 r1} * {r2 r3}
  591. ; A B * X Y
  592. ; Result:
  593. ; r3 = BY0
  594. ; r2 = BY1+BX0+AY0
  595. ; r1 = BX1+AY1+AX0
  596. ; r0 = AX1
  597. ; Carryout must be included to higher bytes
  598. PUSH r3
  599. MUL r3,r1 ; BY0
  600. SWHI r3
  601. AH r3 ; BY1
  602. SWLO r3,mul16buf
  603. POP r3 ; Buffer = [BY0 BY1]
  604. PUSH r2
  605. MUL r2,r1 ; BX0
  606. SWHI r2
  607. AH r2 ; BX1
  608. SWLO r2,mul16buf+1
  609. POP r2 ; Buffer = [BY0 BY1 BX0 BX1]
  610. PUSH r3
  611. MUL r3,r0 ; AY0
  612. SWHI r3
  613. AH r3 ; AY1
  614. SWLO r3,mul16buf+2
  615. POP r3 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1]
  616. PUSH r2
  617. MUL r2,r0 ; AX0
  618. SWHI r2
  619. AH r2 ; AX1
  620. SWLO r2,mul16buf+3
  621. POP r2 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1 AX0 AX1]
  622. ; { 0 } { 1 } { 2 } { 3 }
  623. ; r3 will be used as spare register as it's equal to BY0
  624. LWLO r2,mul16buf ; r2=BY1
  625. LWLO r1,mul16buf+1 ; r1=BX1
  626. LWLO r0,mul16buf+3 ; r0=AX1
  627. LWHI r3,mul16buf+1 ; t=BX0
  628. ADD r2,r3
  629. ADDC r1
  630. ADDC r0
  631. LWHI r3,mul16buf+2 ; t=AY0
  632. ADD r2,r3
  633. ADDC r1
  634. ADDC r0
  635. LWLO r3,mul16buf+2 ; t=AY1
  636. ADD r1,r3
  637. ADDC r0
  638. LWHI r3,mul16buf+3 ; t=AX0
  639. ADD r1,r3
  640. ADDC r0
  641. LWHI r3,mul16buf ; r3=BY0
  642. RET
  643. bin2digit
  644. ; Converts U16 to digit
  645. ; Adopted from http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  646. ; Digit {r0 r1}, Place in 10^n {r2 r3}
  647. PUSH r0
  648. CPY0 0
  649. SWLO r0,generalbuf ; Using general buf to store number
  650. POP r0
  651. .a
  652. CI2 r0
  653. BGT r2,0,.c ; MSB is smaller than digit
  654. CI2 r2
  655. BGT r0,0,.b ; MSB is grater than digit
  656. CI2 r1
  657. BGT r3,0,.c ; LSB is smaller than digit
  658. .b
  659. PUSH r0
  660. LWLO r0,generalbuf
  661. INC r0
  662. SWLO r0,generalbuf
  663. POP r0
  664. SUB r0,r2
  665. SUB r1,r3
  666. SUBC r0
  667. JUMP .a
  668. .c
  669. LWLO r2,generalbuf
  670. RET
  671. printU16
  672. ; print unsigned 16bit int as base-10 digit
  673. ; arguments: digit {r0, r1}
  674. PUSH r0
  675. PUSH r1
  676. PUSH r2
  677. PUSH r3
  678. CPY2 10000@1
  679. CPY3 10000@0
  680. CALL bin2digit
  681. MOVE r3,r0
  682. MOVE r0,r2
  683. ADDI r0,48 ; Convert to ascii digit
  684. CALL print_char
  685. MOVE r0,r3
  686. CPY2 1000@1
  687. CPY3 1000@0
  688. CALL bin2digit
  689. MOVE r3,r0
  690. MOVE r0,r2
  691. ADDI r0,48 ; Convert to ascii digit
  692. CALL print_char
  693. MOVE r0,r3
  694. CPY2 0
  695. CPY3 100
  696. CALL bin2digit
  697. MOVE r0,r2
  698. ADDI r0,48 ; Convert to ascii digit
  699. CALL print_char
  700. MOVE r0,r1
  701. CALL printU8
  702. POP r3
  703. POP r2
  704. POP r1
  705. POP r0
  706. RET
  707. printU8
  708. ; Assuing number is 128
  709. ; a = 128%10 = 8
  710. ; a = 128%100 - a // 10 = 2
  711. ; a = 128%1000 - a // 100 = 1
  712. ; in case of 8bit number quicker is to do 2 if statements for 100s
  713. ; input argument is in r0
  714. PUSH r0
  715. PUSH r1
  716. PUSH r2
  717. PUSH r3
  718. CPY2 10
  719. MOVE r1,r0
  720. DIV r1,r2
  721. AH r1
  722. PUSH r1 ; Stored last digit
  723. BGE r0,10,.ge10
  724. JUMP .p3
  725. .ge10
  726. CPY2 100
  727. MOVE r3,r0
  728. DIV r3,r2
  729. AH r3
  730. SUB r3,r1
  731. CPY2 10
  732. DIV r3,r2
  733. PUSH r3 ; Stored middle digit
  734. BGE r0,100,.ge100
  735. JUMP .p2
  736. .ge100
  737. CPY2 200
  738. CI2 r2
  739. BGE r0,0,.s2
  740. CPY2 100
  741. CI2 r2
  742. BGE r0,0,.s1
  743. JUMP .p2
  744. .s1 CPY0 '1'
  745. JUMP .p0
  746. .s2 CPY0 '2'
  747. .p0 CALL print_char
  748. .p2
  749. POP r0
  750. ADDI r0,48
  751. CALL print_char
  752. .p3
  753. POP r0
  754. ADDI r0,48
  755. CALL print_char
  756. POP r3
  757. POP r2
  758. POP r1
  759. POP r0
  760. RET
  761. arrayClear
  762. ; Clear array at *{r1 r0}
  763. PUSH r2
  764. CI1 r1
  765. CI0 r0
  766. LWHI r2,NULL
  767. SWHI r2
  768. CPY2 0
  769. CI1 r1
  770. CI0 r0
  771. SWLO r2,NULL
  772. POP r2
  773. RET
  774. arrayPush
  775. ; Push to array *{r1 r0} value {r3 r2}
  776. ; If full, changes r1 r0 to 0x0000
  777. PUSH r2
  778. PUSH r3
  779. CI1 r1
  780. CI0 r0
  781. LWLO r2,NULL
  782. CI1 r1
  783. CI0 r0
  784. LWHI r3,NULL ; Stores cap
  785. ; r2=size, r3=cap
  786. CI2 r3
  787. BGE r2,0xFF,.full
  788. INC r2
  789. SWHI r3
  790. CI1 r1
  791. CI0 r0
  792. SWLO r2,NULL
  793. ADD r0,r2
  794. ADDC r1
  795. POP r3
  796. SWHI r3
  797. POP r2
  798. CI1 r1
  799. CI0 r0
  800. SWLO r2,NULL
  801. RET
  802. .full
  803. POP r3
  804. POP r2
  805. CPY0 0
  806. CPY1 0
  807. RET
  808. arrayPop
  809. ; Pop from array *{r1 r0} value {r3 r2}
  810. ; If empty, changes all regs to 0x00
  811. CI1 r1
  812. CI0 r0
  813. LWLO r2,NULL
  814. BEQ r2,0,.empty
  815. DEC r2
  816. CI1 r1
  817. CI0 r0
  818. SWLO r2,NULL
  819. INC r2
  820. ADD r0,r2
  821. ADDC r1
  822. CI1 r1
  823. CI0 r0
  824. LWHI r3,NULL
  825. CI1 r1
  826. CI0 r0
  827. LWLO r2,NULL
  828. RET
  829. .empty
  830. CPY3 0
  831. CPY2 0
  832. CPY1 0
  833. CPY0 0
  834. RET
  835. read_char ; read char to r0
  836. COM r0,COM_UARTR
  837. ANDI r0,0b0000_1000
  838. BZ r0,read_char
  839. COM r0,COM_UARTIN
  840. RET
  841. malloc ; returns memory free memory locaion
  842. ; r0 = size to allocate
  843. ; {r2, r1} memory pointer
  844. LWHI r2,mallocPointer
  845. LWLO r1,mallocPointer
  846. PUSH r2
  847. PUSH r1
  848. ADD r1,r0
  849. ADDC r2
  850. SWHI r2
  851. SWLO r1,mallocPointer
  852. POP r1
  853. POP r2
  854. RET
  855. print_msg ; print value in mem pinter {r2 r1}
  856. PUSH r0
  857. .loop
  858. CI1 r2
  859. CI0 r1
  860. LWHI r0,NULL
  861. BZ r0,.end
  862. CALL print_char
  863. CI1 r2
  864. CI0 r1
  865. LWLO r0,NULL
  866. BZ r0,.end
  867. CALL print_char
  868. INC r1
  869. ADDC r2
  870. JUMP .loop
  871. .end
  872. POP r0
  873. RET
  874. print_char ; print value in r0
  875. PUSH r0
  876. .loop
  877. COM r0,COM_UARTR
  878. ANDI r0,0b0000_0010
  879. XORI r0,0b0000_0010 ; invert
  880. BZ r0,.loop
  881. POP r0
  882. COM r0,COM_UARTW
  883. RET