risc8.asm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  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. PUSH r2
  561. CPY3 16
  562. DIV r2,r3; n/=16
  563. CPY0 MEMEND@0
  564. CPY1 MEMEND@1
  565. ADD r0,r2 ; add n to pointer
  566. ADDC r1
  567. CI0 r0
  568. CI1 r1
  569. LWHI r2,NULL
  570. CI0 r0
  571. CI1 r1
  572. LWLO r3,NULL
  573. PUSH r0
  574. PUSH r1
  575. ; check if high or low byte
  576. ; n is saved from MSB to LSB e.g.:
  577. ; data in memory address:
  578. ; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  579. ; n= 0 1 2 3 4 5 6 7 8 9 A B C D E F
  580. ; At this point r3=memLO, r2=memHI
  581. CPY0 1
  582. AH r1; n%16
  583. BGE r1,8,.lo
  584. JUMP .hi
  585. .lo
  586. SUBI r1,8
  587. CI2 r1
  588. SLL r0,0 ; 1 << (n-8)
  589. XOR r3,r0
  590. JUMP .fi
  591. .hi
  592. CI2 r1
  593. SLL r0,0 ; 1 << n
  594. XOR r2,r0
  595. .fi
  596. ; Everything's been flipped, time to upload to ram
  597. POP r1
  598. POP r0
  599. SWHI r2
  600. CI0 r0
  601. CI1 r1
  602. SWLO r3,NULL
  603. POP r2
  604. POP r3
  605. POP r1
  606. POP r0
  607. ; MOVE r0,r2
  608. ; CPY1 16
  609. ; DIV r0,r1; n/=16
  610. ; PUSH r2
  611. ; ; Get array pointer + n/=16
  612. ; CPY1 MEMEND@0
  613. ; CPY2 MEMEND@1
  614. ; ADD r2,r0
  615. ; ADDC r1
  616. RET
  617. mulU16
  618. ; Multiply 2 unsigned 16-bit int
  619. ; {r0 r1} * {r2 r3}
  620. ; A B * X Y
  621. ; Result:
  622. ; r3 = BY0
  623. ; r2 = BY1+BX0+AY0
  624. ; r1 = BX1+AY1+AX0
  625. ; r0 = AX1
  626. ; Carryout must be included to higher bytes
  627. PUSH r3
  628. MUL r3,r1 ; BY0
  629. SWHI r3
  630. AH r3 ; BY1
  631. SWLO r3,mul16buf
  632. POP r3 ; Buffer = [BY0 BY1]
  633. PUSH r2
  634. MUL r2,r1 ; BX0
  635. SWHI r2
  636. AH r2 ; BX1
  637. SWLO r2,mul16buf+1
  638. POP r2 ; Buffer = [BY0 BY1 BX0 BX1]
  639. PUSH r3
  640. MUL r3,r0 ; AY0
  641. SWHI r3
  642. AH r3 ; AY1
  643. SWLO r3,mul16buf+2
  644. POP r3 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1]
  645. PUSH r2
  646. MUL r2,r0 ; AX0
  647. SWHI r2
  648. AH r2 ; AX1
  649. SWLO r2,mul16buf+3
  650. POP r2 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1 AX0 AX1]
  651. ; { 0 } { 1 } { 2 } { 3 }
  652. ; r3 will be used as spare register as it's equal to BY0
  653. LWLO r2,mul16buf ; r2=BY1
  654. LWLO r1,mul16buf+1 ; r1=BX1
  655. LWLO r0,mul16buf+3 ; r0=AX1
  656. LWHI r3,mul16buf+1 ; t=BX0
  657. ADD r2,r3
  658. ADDC r1
  659. ADDC r0
  660. LWHI r3,mul16buf+2 ; t=AY0
  661. ADD r2,r3
  662. ADDC r1
  663. ADDC r0
  664. LWLO r3,mul16buf+2 ; t=AY1
  665. ADD r1,r3
  666. ADDC r0
  667. LWHI r3,mul16buf+3 ; t=AX0
  668. ADD r1,r3
  669. ADDC r0
  670. LWHI r3,mul16buf ; r3=BY0
  671. RET
  672. bin2digit
  673. ; Converts U16 to digit
  674. ; Adopted from http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  675. ; Digit {r0 r1}, Place in 10^n {r2 r3}
  676. PUSH r0
  677. CPY0 0
  678. SWLO r0,generalbuf ; Using general buf to store number
  679. POP r0
  680. .a
  681. CI2 r0
  682. BGT r2,0,.c ; MSB is smaller than digit
  683. CI2 r2
  684. BGT r0,0,.b ; MSB is grater than digit
  685. CI2 r1
  686. BGT r3,0,.c ; LSB is smaller than digit
  687. .b
  688. PUSH r0
  689. LWLO r0,generalbuf
  690. INC r0
  691. SWLO r0,generalbuf
  692. POP r0
  693. SUB r0,r2
  694. SUB r1,r3
  695. SUBC r0
  696. JUMP .a
  697. .c
  698. LWLO r2,generalbuf
  699. RET
  700. printU16
  701. ; print unsigned 16bit int as base-10 digit
  702. ; arguments: digit {r0, r1}
  703. PUSH r0
  704. PUSH r1
  705. PUSH r2
  706. PUSH r3
  707. CPY2 10000@1
  708. CPY3 10000@0
  709. CALL bin2digit
  710. MOVE r3,r0
  711. MOVE r0,r2
  712. ADDI r0,48 ; Convert to ascii digit
  713. CALL print_char
  714. MOVE r0,r3
  715. CPY2 1000@1
  716. CPY3 1000@0
  717. CALL bin2digit
  718. MOVE r3,r0
  719. MOVE r0,r2
  720. ADDI r0,48 ; Convert to ascii digit
  721. CALL print_char
  722. MOVE r0,r3
  723. CPY2 0
  724. CPY3 100
  725. CALL bin2digit
  726. MOVE r0,r2
  727. ADDI r0,48 ; Convert to ascii digit
  728. CALL print_char
  729. MOVE r0,r1
  730. CALL printU8
  731. POP r3
  732. POP r2
  733. POP r1
  734. POP r0
  735. RET
  736. printU8
  737. ; Assuing number is 128
  738. ; a = 128%10 = 8
  739. ; a = 128%100 - a // 10 = 2
  740. ; a = 128%1000 - a // 100 = 1
  741. ; in case of 8bit number quicker is to do 2 if statements for 100s
  742. ; input argument is in r0
  743. PUSH r0
  744. PUSH r1
  745. PUSH r2
  746. PUSH r3
  747. CPY2 10
  748. MOVE r1,r0
  749. DIV r1,r2
  750. AH r1
  751. PUSH r1 ; Stored last digit
  752. BGE r0,10,.ge10
  753. JUMP .p3
  754. .ge10
  755. CPY2 100
  756. MOVE r3,r0
  757. DIV r3,r2
  758. AH r3
  759. SUB r3,r1
  760. CPY2 10
  761. DIV r3,r2
  762. PUSH r3 ; Stored middle digit
  763. BGE r0,100,.ge100
  764. JUMP .p2
  765. .ge100
  766. CPY2 200
  767. CI2 r2
  768. BGE r0,0,.s2
  769. CPY2 100
  770. CI2 r2
  771. BGE r0,0,.s1
  772. JUMP .p2
  773. .s1 CPY0 '1'
  774. JUMP .p0
  775. .s2 CPY0 '2'
  776. .p0 CALL print_char
  777. .p2
  778. POP r0
  779. ADDI r0,48
  780. CALL print_char
  781. .p3
  782. POP r0
  783. ADDI r0,48
  784. CALL print_char
  785. POP r3
  786. POP r2
  787. POP r1
  788. POP r0
  789. RET
  790. arrayClear
  791. ; Clear array at *{r1 r0}
  792. PUSH r2
  793. CI1 r1
  794. CI0 r0
  795. LWHI r2,NULL
  796. SWHI r2
  797. CPY2 0
  798. CI1 r1
  799. CI0 r0
  800. SWLO r2,NULL
  801. POP r2
  802. RET
  803. arrayPush
  804. ; Push to array *{r1 r0} value {r3 r2}
  805. ; If full, changes r1 r0 to 0x0000
  806. PUSH r2
  807. PUSH r3
  808. CI1 r1
  809. CI0 r0
  810. LWLO r2,NULL
  811. CI1 r1
  812. CI0 r0
  813. LWHI r3,NULL ; Stores cap
  814. ; r2=size, r3=cap
  815. CI2 r3
  816. BGE r2,0xFF,.full
  817. INC r2
  818. SWHI r3
  819. CI1 r1
  820. CI0 r0
  821. SWLO r2,NULL
  822. ADD r0,r2
  823. ADDC r1
  824. POP r3
  825. SWHI r3
  826. POP r2
  827. CI1 r1
  828. CI0 r0
  829. SWLO r2,NULL
  830. RET
  831. .full
  832. POP r3
  833. POP r2
  834. CPY0 0
  835. CPY1 0
  836. RET
  837. arrayPop
  838. ; Pop from array *{r1 r0} value {r3 r2}
  839. ; If empty, changes all regs to 0x00
  840. CI1 r1
  841. CI0 r0
  842. LWLO r2,NULL
  843. BEQ r2,0,.empty
  844. DEC r2
  845. CI1 r1
  846. CI0 r0
  847. SWLO r2,NULL
  848. INC r2
  849. ADD r0,r2
  850. ADDC r1
  851. CI1 r1
  852. CI0 r0
  853. LWHI r3,NULL
  854. CI1 r1
  855. CI0 r0
  856. LWLO r2,NULL
  857. RET
  858. .empty
  859. CPY3 0
  860. CPY2 0
  861. CPY1 0
  862. CPY0 0
  863. RET
  864. read_char ; read char to r0
  865. COM r0,COM_UARTR
  866. ANDI r0,0b0000_1000
  867. BZ r0,read_char
  868. COM r0,COM_UARTIN
  869. RET
  870. malloc ; returns memory free memory locaion
  871. ; r0 = size to allocate
  872. ; {r2, r1} memory pointer
  873. LWHI r2,mallocPointer
  874. LWLO r1,mallocPointer
  875. PUSH r2
  876. PUSH r1
  877. ADD r1,r0
  878. ADDC r2
  879. SWHI r2
  880. SWLO r1,mallocPointer
  881. POP r1
  882. POP r2
  883. RET
  884. print_msg ; print value in mem pinter {r2 r1}
  885. PUSH r0
  886. .loop
  887. CI1 r2
  888. CI0 r1
  889. LWHI r0,NULL
  890. BZ r0,.end
  891. CALL print_char
  892. CI1 r2
  893. CI0 r1
  894. LWLO r0,NULL
  895. BZ r0,.end
  896. CALL print_char
  897. INC r1
  898. ADDC r2
  899. JUMP .loop
  900. .end
  901. POP r0
  902. RET
  903. print_char ; print value in r0
  904. PUSH r0
  905. .loop
  906. COM r0,COM_UARTR
  907. ANDI r0,0b0000_0010
  908. XORI r0,0b0000_0010 ; invert
  909. BZ r0,.loop
  910. POP r0
  911. COM r0,COM_UARTW
  912. RET