risc8.asm 18 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361
  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. %macro PRINTREGS 0
  16. PUSH r0
  17. CALL print_hex
  18. MOVE r0,r1
  19. CALL print_hex
  20. MOVE r0,r2
  21. CALL print_hex
  22. MOVE r0,r3
  23. CALL print_hex
  24. CALL println
  25. POP r0
  26. %endmacro
  27. %macro PRINTREG 1
  28. PUSH r0
  29. MOVE r0,%1
  30. CALL print_hex
  31. POP r0
  32. %endmacro
  33. %macro SLL16 4
  34. ; 1 2 3 4
  35. ; shift by, low byte, high byte, temp reg
  36. SLL %2,%1
  37. PUSH %4
  38. GETAH %4
  39. SLL %3,%1
  40. OR %3,%4
  41. POP %4
  42. %endmacro
  43. %macro LOAD 3
  44. LWLO %3,%1
  45. LWHI %2,%1
  46. %endmacro
  47. %macro SAVE 3
  48. SWHI %2
  49. SWLO %3,%1
  50. %endmacro
  51. %macro PRINTMEM 1
  52. PUSH r0
  53. LWHI r0,%1
  54. CALL print_hex
  55. LWLO r0,%1
  56. CALL print_hex
  57. POP r0
  58. %endmacro
  59. %macro CH 1
  60. PUSH r0
  61. CPY0 %1
  62. CALL print_char
  63. POP r0
  64. %endmacro
  65. %macro BGE16 5
  66. ; 1 2 3 4 5
  67. ; Brach to if, A{H,L} >= B{H,L}
  68. CI2 %4
  69. BGT %2,0,%1
  70. CI2 %2
  71. BGT %4,0,%%continue
  72. CI2 %5
  73. BGE %3,0,%1
  74. %%continue:
  75. %endmacro
  76. section .data depth=4096,width=2
  77. intro_text: DB "\x1Bc\x1B[2J\x1B[HBooting \x1B[1m\x1B[33mRISC\x1B[0m system\r\n",0
  78. eq1_text: DB LFCR,"1) 0x1194 * 0x2710 = 0x",0
  79. eq2_text: DB LFCR,"2) 3*2=",0
  80. eq3_text: DB LFCR,"3) 3*2=",0
  81. initial_vt100: DB 0x1B,'c',0x1B,"[2J",0x1B,"[40;32m",0
  82. error_text: DB LFCR,"Invalid operation: ",0
  83. error0: DB "Buffer is full",0
  84. error1: DB "Number value overflow",0
  85. mul16buf: DBE 8
  86. generalbuf: DBE 1
  87. generalbuf2: DBE 1
  88. generalbuf3: DBE 1
  89. termHiFlag: DB 0x0000
  90. termBuff: DB 10,0
  91. DBE 10
  92. mallocPointer: DB 0
  93. MEMEND: DB 0
  94. section .text depth=4096,width=1,length=2
  95. setup:
  96. CPY1 intro_text@0
  97. CPY2 intro_text@1
  98. CALL print_msg
  99. ;JUMP forever
  100. CPY0 0x00
  101. CPY1 0x02
  102. SAVE generalbuf,r0,r1
  103. PRINTMEM generalbuf
  104. CALL println
  105. CALL println
  106. CPY0 50000@1
  107. CPY1 50000@0
  108. CALL div_u16
  109. CALL println
  110. PRINTMEM generalbuf2
  111. CH 0x20
  112. PRINTREGS
  113. CALL println
  114. JUMP forever
  115. ;CALL printU16
  116. ;PRINTREG
  117. ;CALL printU16
  118. ;CALL println
  119. JUMP forever
  120. SRL r0,1
  121. GETAH r1
  122. CALL println
  123. CALL print_bin
  124. CALL println
  125. MOVE r0,r1
  126. CALL print_bin
  127. CALL println
  128. forever:
  129. CALL read_char
  130. CALL print_char
  131. JUMP forever
  132. ; Run init
  133. ;INTRE interrupt
  134. ;CALL read_char
  135. ;CALL print_char
  136. ;.echo
  137. ; JUMP .echo
  138. ; CALL read_char
  139. ; CALL print_char
  140. ;CPY0 65432@1
  141. ;CPY1 65432@0
  142. ;CALL printU16
  143. ;CALL read_char
  144. ;CPY1 COM_UART_ECHO
  145. ;COM r1,COM_UARTF
  146. ;CPY1 eq1_text@0
  147. ;CPY2 eq1_text@1
  148. ;CALL print_msg
  149. CPY0 0x0A ;
  150. CPY1 0x0B ; a = 0
  151. CPY2 0x03 ;
  152. CPY3 0x00 ; b = 0
  153. loopyloop:
  154. PUSH r0
  155. PUSH r1
  156. PUSH r2
  157. PUSH r3
  158. CALL mulU16
  159. ;CALL print_hex
  160. ;MOVE r0,r1
  161. ;CALL print_hex
  162. ;MOVE r0,r2
  163. ;CALL print_hex
  164. ;MOVE r0,r3
  165. ;CALL print_hex
  166. ;CALL println
  167. POP r3
  168. POP r2
  169. POP r1
  170. POP r0
  171. INC r3
  172. ADDC r2
  173. BZ r3,.ztest0
  174. JUMP loopyloop
  175. .ztest0:
  176. BZ r2,.ztest1
  177. JUMP loopyloop
  178. .ztest1:
  179. INC r1
  180. ADDC r0
  181. ;PUSH r0
  182. ;CALL print_hex
  183. ;MOVE r0,r1
  184. ;CALL print_hex
  185. ;CPY0 '*'
  186. ;CALL print_char
  187. ;MOVE r0,r2
  188. ;CALL print_hex
  189. ;MOVE r0,r3
  190. ;CALL print_hex
  191. ;POP r0
  192. JUMP loopyloop
  193. CALL sieveOfAtkin
  194. CALL println
  195. div_u16:
  196. %def $Rh,r2
  197. %def $Rl,r3
  198. CPY2 0 ; set R = 0
  199. CPY3 0
  200. ; Keep r1 <= Nl
  201. PUSH r1 ; keep Nl for second loop
  202. CALL print_hex
  203. PRINTREG r1
  204. CALL println
  205. MOVE r1,r0
  206. ; for i=0;i<15;i++
  207. CPY0 0b1000_0000
  208. .for_start0:
  209. CALL println
  210. ;CALL print_bin
  211. ;CALL println
  212. SLL16 1,$Rl,$Rh,r0
  213. CH 'N'
  214. PRINTREG r1
  215. ;; Finding N(i)
  216. PUSH r1 ;; copy Nh
  217. AND r1,r0 ; AND i,N
  218. BEQ r1,0,.z0 ; if N&i == 0, do nothing
  219. PUSH r0
  220. CPY0 0x01
  221. OR $Rl,r0 ; R[0] = 1
  222. POP r0
  223. .z0:
  224. CH 0x20
  225. CH 'R'
  226. PRINTREG $Rh
  227. PRINTREG $Rl
  228. ; check if R >= D
  229. PUSH r0
  230. %def $Dl,r1
  231. %def $Dh,r0
  232. LOAD generalbuf,$Dh,$Dl
  233. CH 0x20
  234. CH 'D'
  235. CALL print_hex
  236. PRINTREG r1
  237. CH 0x20
  238. BGE16 .sub0,$Rh,$Rl,$Dh,$Dl
  239. POP r0
  240. JUMP .fin0
  241. .sub0:
  242. ; R -= D
  243. SUB $Rl,$Dl
  244. SUB $Rh,$Dh
  245. SUBC $Rh
  246. CH 'R'
  247. PRINTREG $Rh
  248. PRINTREG $Rl
  249. CH 0x20
  250. ; Q[i] = 1
  251. POP r0
  252. LWHI r1,generalbuf2
  253. OR r1,r0
  254. PRINTREG r1
  255. SWHI r1
  256. LWLO r1,generalbuf2
  257. SWLO r1,generalbuf2
  258. .fin0:
  259. POP r1 ;; restore Nh
  260. .for_end0:
  261. SRL r0,1
  262. BEQ r0,0,.done0
  263. JUMP .for_start0
  264. .done0:
  265. POP r1 ; restore Nh
  266. CPY0 0b1000_0000
  267. .for_start1:
  268. ;CALL print_bin
  269. ;CALL println
  270. CALL println
  271. SLL16 1,$Rl,$Rh,r0
  272. CH 'N'
  273. PRINTREG r1
  274. ;; Finding N(i)
  275. PUSH r1 ;; copy Nl
  276. AND r1,r0 ; AND i,N
  277. BEQ r1,0,.z1 ; if N&i == 0, do nothing
  278. PUSH r0
  279. CPY0 0x01
  280. OR $Rl,r0 ; R[0] = 1
  281. POP r0
  282. .z1:
  283. CH 0x20
  284. CH 'R'
  285. PRINTREG $Rh
  286. PRINTREG $Rl
  287. ; check if R >= D
  288. PUSH r0
  289. %def $Dl,r1
  290. %def $Dh,r0
  291. LOAD generalbuf,$Dh,$Dl
  292. CH 0x20
  293. CH 'D'
  294. CALL print_hex
  295. PRINTREG r1
  296. CH 0x20
  297. BGE16 .sub1,$Rh,$Rl,$Dh,$Dl
  298. POP r0
  299. JUMP .fin1
  300. .sub1:
  301. ; R -= D
  302. SUB $Rl,$Dl
  303. SUB $Rh,$Dh
  304. SUBC $Rh
  305. ; Q[i] = 1
  306. POP r0
  307. LWHI r1,generalbuf2 ; \ keep high byte
  308. SWHI r1 ; /
  309. LWLO r1,generalbuf2
  310. OR r1,r0
  311. PRINTREG r1
  312. SWLO r1,generalbuf2
  313. .fin1:
  314. POP r1 ;; restore Nl
  315. .for_end1:
  316. SRL r0,1
  317. BEQ r0,0,.done1
  318. JUMP .for_start1
  319. .done1:
  320. RET
  321. mod_u16:
  322. ; {Ah, Al} = {Ah, Al} % {Bh, Bl}
  323. %def $Al,r1
  324. %def $Ah,r0
  325. %def $Bl,r3
  326. %def $Bh,r2
  327. %def $Xl,r3
  328. %def $Xh,r2
  329. PUSH $Bl
  330. PUSH $Bh
  331. PUSH $Al
  332. PUSH $Ah
  333. ; Assume X = B
  334. ; Change A /= 2
  335. PUSH r2
  336. SRL $Ah,1
  337. GETAH r2
  338. SRL $Al,1
  339. OR $Al,r2
  340. POP r2
  341. ; While x <= A/2
  342. .part1:
  343. CI2 $Ah
  344. BGT $Xh,0,.part2
  345. CI2 $Xh
  346. BGT $Ah,0,.xsl
  347. CI2 $Al
  348. BGT $Xl,0,.part2
  349. .xsl:
  350. PUSH r0
  351. SLL $Xl,1
  352. GETAH r0
  353. SLL $Xh,1
  354. OR $Xh,r0
  355. POP r0
  356. JUMP .part1
  357. .part2:
  358. ; Saving X
  359. SWHI $Xh
  360. SWLO $Xl,generalbuf
  361. ; Returning A
  362. POP $Ah
  363. POP $Al
  364. ; Returning B
  365. POP $Bh
  366. POP $Bl
  367. .p2check:
  368. ; Check A>=B
  369. ;PRINTREG
  370. CI2 $Ah
  371. BGT $Bh,0,.done
  372. CI2 $Bh
  373. BGT $Ah,0,.loop
  374. CI2 $Al
  375. BGT $Bl,0,.done
  376. ; end of check
  377. .loop:
  378. ; Store B
  379. PUSH $Bl
  380. PUSH $Bh
  381. ; Load X
  382. LWHI $Xh,generalbuf
  383. LWLO $Xl,generalbuf
  384. ; if A >= X
  385. ;PRINTREG
  386. CI2 $Xh
  387. BGT $Ah,0,.agtx
  388. CI2 $Xl
  389. BGT $Al,0,.agtx
  390. CI2 $Xl
  391. BEQ $Al,0,.agtx
  392. JUMP .next
  393. ; A -= X
  394. .agtx:
  395. SUB $Ah,$Xh
  396. SUB $Al,$Xl
  397. SUBC $Ah
  398. .next:
  399. ; X >>= 1
  400. SRL $Xh,1
  401. PUSH r0
  402. GETAH r0
  403. SRL $Xl,1
  404. OR $Xl,r0
  405. POP r0
  406. ; Pack X
  407. SWHI $Xh
  408. SWLO $Xl,generalbuf
  409. POP $Bh
  410. POP $Bl
  411. JUMP .p2check
  412. .done:
  413. RET
  414. loop:
  415. CPY0 0
  416. PUSH r0
  417. CPY0 '>'
  418. CALL print_char
  419. CPY0 0x20 ; space
  420. CALL print_char
  421. ;.loop
  422. ; CALL read_char
  423. ; CALL print_char
  424. ; ;BEQ r2,0x0a,.start
  425. ; BEQ r0,0x0d,.error
  426. ; JUMP .loop
  427. ;.error
  428. ; CPY1 error_text@0
  429. ; CPY2 error_text@1
  430. ; CALL print_msg
  431. ; JUMP .start
  432. .read:
  433. CALL read_char
  434. BGT r0,57,.readc0
  435. BGT r0,48,.readadd
  436. .readc0:
  437. BEQ r0,0x0d,.done
  438. ;BEQ r0,0x20,.echo
  439. BEQ r0,0x08,.backspace
  440. BEQ r0,0x7F,.backspace
  441. BEQ r0,0x2A,.readadd ; *
  442. BEQ r0,0x2B,.readadd ; +
  443. BEQ r0,0x2D,.readadd ; -
  444. BEQ r0,0x2F,.readadd ; /
  445. JUMP .read
  446. .backspace:
  447. ; POP r1
  448. ; BEQ r1,0,.backspaceCheck
  449. ; CPY0 0x1B
  450. ; CALL print_char
  451. ; CPY0 'c'
  452. ; CALL print_char
  453. ; JUMP .read
  454. ;.backspaceCheck
  455. ; PUSH r1
  456. JUMP .read
  457. .readadd:
  458. LWLO r3,termHiFlag
  459. BZ r3,.readadd0
  460. JUMP .readstore
  461. .readadd0:
  462. CPY3 1
  463. SWHI r0
  464. SWLO r3,termHiFlag
  465. JUMP .echo
  466. .readstore:
  467. CPY2 0
  468. LWHI r3,termHiFlag
  469. SWLO r2,termHiFlag
  470. MOVE r2,r0
  471. CPY0 termBuff@0
  472. CPY1 termBuff@1
  473. CALL arrayPush
  474. ; Check if buffer overflow
  475. BZ r0,.readstore0
  476. MOVE r0,r2
  477. JUMP .echo
  478. .readstore0:
  479. MOVE r0,r2
  480. BZ r1,.error0
  481. .echo:
  482. CALL print_char
  483. JUMP .read
  484. .done:
  485. ; if odd number of chars, push r0, 0 to array
  486. LWLO r3,termHiFlag
  487. BZ r3,.doneC
  488. ;LWHI r2,termHiFlag
  489. ;CPY3 0
  490. ;CPY0 termBuff@0
  491. ;CPY1 termBuff@1
  492. ;CALL arrayPush
  493. .doneC:
  494. CPY1 termBuff@0
  495. CPY2 termBuff@1
  496. CALL Process
  497. CPY0 termBuff@0
  498. CPY1 termBuff@1
  499. CALL arrayClear
  500. JUMP loop
  501. .done0:
  502. POP r0
  503. BEQ r0,0,.done1
  504. CALL print_char
  505. JUMP .done0
  506. .done1:
  507. CALL println
  508. JUMP loop
  509. .error0:
  510. CALL println
  511. CPY1 error0@0
  512. CPY2 error0@1
  513. CALL print_msg
  514. CALL println
  515. JUMP loop
  516. MOVE r1,r0
  517. SUBI r1,48
  518. CALL print_char
  519. CALL read_char
  520. MOVE r2,r0
  521. CALL print_char
  522. CALL read_char
  523. MOVE r3,r0
  524. SUBI r3,48
  525. CALL print_char
  526. BEQ r2,'+',.add0
  527. BEQ r2,'-',.sub0
  528. JUMP .invalid
  529. .add0:
  530. ADD r1,r3
  531. JUMP .result
  532. .sub0:
  533. SUB r1,r3
  534. JUMP .result
  535. .invalid:
  536. CPY1 error_text@0
  537. CPY2 error_text@1
  538. CALL print_msg
  539. JUMP .done
  540. .result:
  541. PUSH r1
  542. CPY0 '='
  543. CALL print_char
  544. POP r0
  545. ADDI r0,48
  546. CALL print_char
  547. Process:
  548. ; Input array *{r2 r1}
  549. ;CPY1 termBuff@0
  550. ;CPY2 termBuff@1
  551. .readnext:
  552. INC r1
  553. ADDC r2
  554. CI1 r2
  555. CI0 r1
  556. SWLO r0,NULL
  557. .isdigit:
  558. ;BGT r0,57,.issymbol
  559. ;BGT r0,48,.digit
  560. .issymbol:
  561. ;JUMP .error
  562. .digit:
  563. ;CI1 r2
  564. ;CI0 r1
  565. ;SWHI r0
  566. .error:
  567. CPY1 error_text@0
  568. CPY2 error_text@1
  569. CALL print_msg
  570. CPY1 termBuff@0
  571. CPY2 termBuff@1
  572. INC r1
  573. ADDC r2
  574. CALL print_msg
  575. .end:
  576. CALL println
  577. RET
  578. print_bin:
  579. ; print r0 as binary
  580. PUSH r2
  581. PUSH r1
  582. PUSH r0
  583. CPY2 0b1000_0000
  584. MOVE r1,r0
  585. .start:
  586. AND r0,r2
  587. BZ r0,.print0
  588. .print1:
  589. CPY0 '1'
  590. CALL print_char
  591. JUMP .end
  592. .print0:
  593. CPY0 '0'
  594. CALL print_char
  595. .end:
  596. SRL r2,1
  597. BZ r2,.done
  598. MOVE r0,r1
  599. JUMP .start
  600. .done:
  601. POP r0
  602. POP r1
  603. POP r2
  604. RET
  605. print_hex:
  606. ; print r0 as hex
  607. PUSH r0
  608. PUSH r1
  609. MOVE r1,r0
  610. SRL r0,4
  611. BGT r0,9,.p0
  612. ADDI r0,48
  613. JUMP .p1
  614. .p0:
  615. ADDI r0,55
  616. .p1:
  617. CALL print_char
  618. MOVE r0,r1
  619. POP r1
  620. ANDI r0,0b0000_1111
  621. BGT r0,9,.p2
  622. ADDI r0,48
  623. JUMP .p3
  624. .p2:
  625. ADDI r0,55
  626. .p3:
  627. CALL print_char
  628. POP r0
  629. RET
  630. ;.done
  631. ;; Equation 1
  632. ;CPY1 eq1_text@0
  633. ;CPY2 eq1_text@1
  634. ;CALL print_msg
  635. ;CPY0 3
  636. ;ADDI r0,2
  637. ;ADDI r0,48 ; Convert to ascii
  638. ;CALL print_char
  639. ;
  640. ;; Equation 2
  641. ;CPY1 eq2_text@0
  642. ;CPY2 eq2_text@1
  643. ;CALL print_msg
  644. ;CPY0 6
  645. ;SUBI r0,2
  646. ;ADDI r0,48 ; Convert to ascii
  647. ;CALL print_char
  648. ;; Equation 3
  649. ;CPY1 eq3_text@0
  650. ;CPY2 eq3_text@1
  651. ;CALL print_msg
  652. ;CPY0 3
  653. ;CPY1 2
  654. ;MUL r0,r1
  655. ;ADDI r0,48 ; Convert to ascii
  656. ;CALL print_char
  657. ;
  658. ;CPY1 eq3x_text@0
  659. ;CPY2 eq3x_text@1
  660. ;CALL print_msg
  661. ;AH r0
  662. ;ADDI r0,48 ; Convert to ascii
  663. ;CALL print_char
  664. ;; Equation 4
  665. ;CPY1 eq4_text@0
  666. ;CPY2 eq4_text@1
  667. ;CALL print_msg
  668. ;CPY0 9
  669. ;CPY1 2
  670. ;DIV r0,r1
  671. ;ADDI r0,48 ; Convert to ascii
  672. ;CALL print_char
  673. ;; Equation 5
  674. ;CPY1 eq5_text@0
  675. ;CPY2 eq5_text@1
  676. ;CALL print_msg
  677. ;AH r0
  678. ;ADDI r0,48 ; Convert to ascii
  679. ;CALL print_char
  680. ;CALL println
  681. ;JUMP .start
  682. ;CPY3 0
  683. start:
  684. INC r3
  685. JUMP start
  686. interrupt:
  687. PUSH r0
  688. GETIF r0
  689. POP r0
  690. RETI
  691. println:
  692. PUSH r0
  693. CPY0 LF
  694. CALL print_char
  695. CPY0 CR
  696. CALL print_char
  697. POP r0
  698. RET
  699. %define SLIMIT 255
  700. sieveOfAtkin:
  701. ; Calculate primes up to limit
  702. CPY0 MEMEND@0
  703. CPY1 MEMEND@1
  704. CPY2 0
  705. CPY3 0
  706. ; Initialising memory with 0s
  707. .clearCell:
  708. CPY2 0
  709. CI0 r0
  710. CI0 r1
  711. SWLO r2,NULL
  712. INC r3
  713. ADDC r3
  714. INC r1
  715. ADDC r0
  716. BZ r3,.clearCell
  717. .main:
  718. CPY0 1 ; x=1
  719. .loopx:
  720. ; FOR loop x
  721. PUSH r0
  722. MUL r0,r0 ; x^2
  723. ; check if more than 2 bytes
  724. AH r2
  725. BZ r2,.loopx0
  726. POP r0
  727. JUMP .p2; to part2
  728. .loopx0: ; Loop content
  729. CPY1 1 ; y=1
  730. .loopy:
  731. ; FOR loop y
  732. PUSH r1
  733. MUL r1,r1 ; y^2
  734. ; check if more than 2 bytes
  735. AH r2
  736. BZ r2,.loopy0
  737. POP r1
  738. JUMP .loopxe; to loop x end
  739. .loopy0: ; Loop content
  740. ; ======================
  741. ; START OF MAIN FUNCTION
  742. ; ======================
  743. ;At this point r0=x^2; r1=y^2
  744. CPY2 4 ; n=4
  745. MUL r2,r0 ; n=4*x^2
  746. AH r3 ; check for overflow
  747. BZ r3,.c1a
  748. JUMP .c2
  749. .c1a:
  750. ADD r2,r1 ; n=4*x^2 + y^2
  751. ADDC r3 ; check for overflow
  752. BZ r3,.c1b
  753. JUMP .c2
  754. .c1b: ; check if n%12==1
  755. PUSH r2
  756. CPY3 12
  757. DIV r2,r3
  758. AH r2
  759. CPY3 1
  760. XOR r3,r2
  761. BZ r3,.c1f
  762. ; check if n%12==5
  763. CPY3 5
  764. XOR r3,r2
  765. BZ r3,.c1f
  766. POP r2; return n from stack
  767. ; else cary on C2
  768. JUMP .c2
  769. .c1f:
  770. POP r2; return n from stack
  771. CALL sieveOfAtkinInvN
  772. .c2:
  773. ; At this point r0=x^2; r1=y^2
  774. CPY2 3 ; n=3
  775. MUL r2,r0 ; n=3*x^2
  776. AH r3 ; check for overflow
  777. BZ r3,.c2a
  778. JUMP .c3
  779. .c2a:
  780. ADD r2,r1 ; n=3*x^2 + y^2
  781. ADDC r3 ; check for overflow
  782. BZ r3,.c2b
  783. JUMP .c3
  784. .c2b: ; check if n%12==7
  785. PUSH r2
  786. CPY3 12
  787. DIV r2,r3
  788. AH r2
  789. CPY3 7
  790. XOR r3,r2
  791. POP r2
  792. BZ r3,.c2f
  793. JUMP .c3
  794. .c2f:
  795. CALL sieveOfAtkinInvN
  796. .c3:
  797. ; At this point r0=x^2; r1=y^2
  798. ; n=3*x^2-y^2
  799. CPY2 3
  800. MUL r2,r0
  801. AH r3
  802. SUB r2,r1
  803. SUBC r3
  804. BZ r3,.c3a ; check for limit
  805. JUMP .loopye
  806. .c3a:; check if x>y
  807. ; r2=n
  808. POP r1 ; get y
  809. POP r0 ; get x
  810. CI2 r1
  811. BGT r0,0,.c3b
  812. PUSH r0
  813. PUSH r1
  814. JUMP .loopye
  815. .c3b:; check if n%12==11
  816. PUSH r0
  817. PUSH r1
  818. PUSH r2
  819. CPY3 12
  820. DIV r2,r3
  821. AH r2 ; n%12
  822. CPY3 11
  823. XOR r3,r2
  824. POP r2
  825. BZ r3,.c3c
  826. JUMP .loopye
  827. .c3c:
  828. CALL sieveOfAtkinInvN
  829. ; ====================
  830. ; END OF MAIN FUNCTION
  831. ; ====================
  832. .loopye:
  833. POP r1
  834. INC r1
  835. JUMP .loopy
  836. .loopxe:
  837. POP r0
  838. INC r0
  839. JUMP .loopx
  840. .p2:
  841. ; for (r=5;r^2<limit;r++)
  842. CPY0 5 ; r=5
  843. .loopr:
  844. MOVE r1,r0
  845. MUL r1,r0 ; r^2
  846. AH r3
  847. BZ r3,.r0e ; check for overflow
  848. JUMP .end
  849. .r0e:
  850. CPY2 MEMEND@0
  851. CPY3 MEMEND@1
  852. ADD r2,r0 ; Add r to pointer
  853. ADDC r3
  854. CI0 r2
  855. CI1 r3
  856. LWLO r2,NULL ; if sieve[r]
  857. BZ r2,.loopre
  858. ; for(i = r^2; i<limit;i+=r^2) sieve[r]=0
  859. ; at this point r0 -> r; r1 -> r^2
  860. PUSH r0
  861. MOVE r0,r1 ; set i=r^2
  862. .loopi:
  863. ; sieve[r] = 0
  864. CPY2 MEMEND@0
  865. CPY3 MEMEND@1
  866. ADD r2,r0
  867. ADDC r3
  868. CPY0 0
  869. CI0 r2
  870. CI1 r3
  871. LWLO r0,NULL
  872. .loopie:
  873. ADD r0,r1
  874. ADDC r2
  875. BZ r2,.loopi ; if carry is zero carry on
  876. POP r0
  877. .loopre:
  878. INC r0
  879. JUMP .loopr
  880. .end:
  881. ; shall we print here?
  882. CPY0 0
  883. CPY1 MEMEND@0
  884. CPY2 MEMEND@1
  885. .print0:
  886. CI0 r1
  887. CI1 r2
  888. LWLO r3,NULL
  889. BZ r3,.print1
  890. CALL printU8
  891. PUSH r0
  892. CPY0 0x20
  893. CALL print_char
  894. POP r0
  895. .print1:
  896. INC r2
  897. ADDC r1
  898. INC r0
  899. ADDC r3
  900. BZ r3,.print0 ; if not overflow, carry on
  901. RET
  902. ;sieveOfAtkinCore
  903. sieveOfAtkinInvN:
  904. ; sieve[n] ^=1 where n=r2
  905. PUSH r0
  906. PUSH r1
  907. PUSH r3
  908. PUSH r2
  909. CPY3 16
  910. DIV r2,r3; n/=16
  911. CPY0 MEMEND@0
  912. CPY1 MEMEND@1
  913. ADD r0,r2 ; add n to pointer
  914. ADDC r1
  915. CI0 r0
  916. CI1 r1
  917. LWHI r2,NULL
  918. CI0 r0
  919. CI1 r1
  920. LWLO r3,NULL
  921. PUSH r0
  922. PUSH r1
  923. ; check if high or low byte
  924. ; n is saved from MSB to LSB e.g.:
  925. ; data in memory address:
  926. ; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  927. ; n= 0 1 2 3 4 5 6 7 8 9 A B C D E F
  928. ; At this point r3=memLO, r2=memHI
  929. CPY0 1
  930. AH r1; n%16
  931. BGE r1,8,.lo
  932. JUMP .hi
  933. .lo:
  934. SUBI r1,8
  935. CI2 r1
  936. SLL r0,0 ; 1 << (n-8)
  937. XOR r3,r0
  938. JUMP .fi
  939. .hi:
  940. CI2 r1
  941. SLL r0,0 ; 1 << n
  942. XOR r2,r0
  943. .fi:
  944. ; Everything's been flipped, time to upload to ram
  945. POP r1
  946. POP r0
  947. SWHI r2
  948. CI0 r0
  949. CI1 r1
  950. SWLO r3,NULL
  951. POP r2
  952. POP r3
  953. POP r1
  954. POP r0
  955. ; MOVE r0,r2
  956. ; CPY1 16
  957. ; DIV r0,r1; n/=16
  958. ; PUSH r2
  959. ; ; Get array pointer + n/=16
  960. ; CPY1 MEMEND@0
  961. ; CPY2 MEMEND@1
  962. ; ADD r2,r0
  963. ; ADDC r1
  964. RET
  965. mulU16:
  966. ; Multiply 2 unsigned 16-bit int
  967. ; {r0 r1} * {r2 r3}
  968. ; A B * X Y
  969. ; Result:
  970. ; r3 = BY0
  971. ; r2 = BY1+BX0+AY0
  972. ; r1 = BX1+AY1+AX0
  973. ; r0 = AX1
  974. ; Carryout must be included to higher bytes
  975. PUSH r3
  976. MUL r3,r1 ; BY0
  977. SWHI r3
  978. AH r3 ; BY1
  979. SWLO r3,mul16buf
  980. POP r3 ; Buffer = [BY0 BY1]
  981. PUSH r2
  982. MUL r2,r1 ; BX0
  983. SWHI r2
  984. AH r2 ; BX1
  985. SWLO r2,mul16buf+1
  986. POP r2 ; Buffer = [BY0 BY1 BX0 BX1]
  987. PUSH r3
  988. MUL r3,r0 ; AY0
  989. SWHI r3
  990. AH r3 ; AY1
  991. SWLO r3,mul16buf+2
  992. POP r3 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1]
  993. PUSH r2
  994. MUL r2,r0 ; AX0
  995. SWHI r2
  996. AH r2 ; AX1
  997. SWLO r2,mul16buf+3
  998. POP r2 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1 AX0 AX1]
  999. ; { 0 } { 1 } { 2 } { 3 }
  1000. ; r3 will be used as spare register as it's equal to BY0
  1001. LWLO r2,mul16buf ; r2=BY1
  1002. LWLO r1,mul16buf+1 ; r1=BX1
  1003. LWLO r0,mul16buf+3 ; r0=AX1
  1004. LWHI r3,mul16buf+1 ; t=BX0
  1005. ADD r2,r3
  1006. ADDC r1
  1007. ADDC r0
  1008. LWHI r3,mul16buf+2 ; t=AY0
  1009. ADD r2,r3
  1010. ADDC r1
  1011. ADDC r0
  1012. LWLO r3,mul16buf+2 ; t=AY1
  1013. ADD r1,r3
  1014. ADDC r0
  1015. LWHI r3,mul16buf+3 ; t=AX0
  1016. ADD r1,r3
  1017. ADDC r0
  1018. LWHI r3,mul16buf ; r3=BY0
  1019. RET
  1020. bin2digit:
  1021. ; Converts U16 to digit
  1022. ; Adopted from http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  1023. ; Digit {r0 r1}, Place in 10^n {r2 r3}
  1024. PUSH r0
  1025. CPY0 0
  1026. SWLO r0,generalbuf ; Using general buf to store number
  1027. POP r0
  1028. .a:
  1029. CI2 r0
  1030. BGT r2,0,.c ; MSB is smaller than digit
  1031. CI2 r2
  1032. BGT r0,0,.b ; MSB is grater than digit
  1033. CI2 r1
  1034. BGT r3,0,.c ; LSB is smaller than digit
  1035. .b:
  1036. PUSH r0
  1037. LWLO r0,generalbuf
  1038. INC r0
  1039. SWLO r0,generalbuf
  1040. POP r0
  1041. SUB r0,r2
  1042. SUB r1,r3
  1043. SUBC r0
  1044. JUMP .a
  1045. .c:
  1046. LWLO r2,generalbuf
  1047. RET
  1048. printU16:
  1049. ; print unsigned 16bit int as base-10 digit
  1050. ; arguments: digit {r0, r1}
  1051. PUSH r0
  1052. PUSH r1
  1053. PUSH r2
  1054. PUSH r3
  1055. CPY2 10000@1
  1056. CPY3 10000@0
  1057. CALL bin2digit
  1058. MOVE r3,r0
  1059. MOVE r0,r2
  1060. ADDI r0,48 ; Convert to ascii digit
  1061. CALL print_char
  1062. MOVE r0,r3
  1063. CPY2 1000@1
  1064. CPY3 1000@0
  1065. CALL bin2digit
  1066. MOVE r3,r0
  1067. MOVE r0,r2
  1068. ADDI r0,48 ; Convert to ascii digit
  1069. CALL print_char
  1070. MOVE r0,r3
  1071. CPY2 0
  1072. CPY3 100
  1073. CALL bin2digit
  1074. MOVE r0,r2
  1075. ADDI r0,48 ; Convert to ascii digit
  1076. CALL print_char
  1077. MOVE r0,r1
  1078. CALL printU8
  1079. POP r3
  1080. POP r2
  1081. POP r1
  1082. POP r0
  1083. RET
  1084. printU8:
  1085. ; Assuing number is 128
  1086. ; a = 128%10 = 8
  1087. ; a = 128%100 - a // 10 = 2
  1088. ; a = 128%1000 - a // 100 = 1
  1089. ; in case of 8bit number quicker is to do 2 if statements for 100s
  1090. ; input argument is in r0
  1091. PUSH r0
  1092. PUSH r1
  1093. PUSH r2
  1094. PUSH r3
  1095. CPY2 10
  1096. MOVE r1,r0
  1097. DIV r1,r2
  1098. AH r1
  1099. PUSH r1 ; Stored last digit
  1100. BGE r0,10,.ge10
  1101. JUMP .p3
  1102. .ge10:
  1103. CPY2 100
  1104. MOVE r3,r0
  1105. DIV r3,r2
  1106. AH r3
  1107. SUB r3,r1
  1108. CPY2 10
  1109. DIV r3,r2
  1110. PUSH r3 ; Stored middle digit
  1111. BGE r0,100,.ge100
  1112. JUMP .p2
  1113. .ge100:
  1114. CPY2 200
  1115. CI2 r2
  1116. BGE r0,0,.s2
  1117. CPY2 100
  1118. CI2 r2
  1119. BGE r0,0,.s1
  1120. JUMP .p2
  1121. .s1:
  1122. CPY0 '1'
  1123. JUMP .p0
  1124. .s2:
  1125. CPY0 '2'
  1126. .p0:
  1127. CALL print_char
  1128. .p2:
  1129. POP r0
  1130. ADDI r0,48
  1131. CALL print_char
  1132. .p3:
  1133. POP r0
  1134. ADDI r0,48
  1135. CALL print_char
  1136. POP r3
  1137. POP r2
  1138. POP r1
  1139. POP r0
  1140. RET
  1141. arrayClear:
  1142. ; Clear array at *{r1 r0}
  1143. PUSH r2
  1144. CI1 r1
  1145. CI0 r0
  1146. LWHI r2,NULL
  1147. SWHI r2
  1148. CPY2 0
  1149. CI1 r1
  1150. CI0 r0
  1151. SWLO r2,NULL
  1152. POP r2
  1153. RET
  1154. arrayPush:
  1155. ; Push to array *{r1 r0} value {r3 r2}
  1156. ; If full, changes r1 r0 to 0x0000
  1157. PUSH r2
  1158. PUSH r3
  1159. CI1 r1
  1160. CI0 r0
  1161. LWLO r2,NULL
  1162. CI1 r1
  1163. CI0 r0
  1164. LWHI r3,NULL ; Stores cap
  1165. ; r2=size, r3=cap
  1166. CI2 r3
  1167. BGE r2,0xFF,.full
  1168. INC r2
  1169. SWHI r3
  1170. CI1 r1
  1171. CI0 r0
  1172. SWLO r2,NULL
  1173. ADD r0,r2
  1174. ADDC r1
  1175. POP r3
  1176. SWHI r3
  1177. POP r2
  1178. CI1 r1
  1179. CI0 r0
  1180. SWLO r2,NULL
  1181. RET
  1182. .full:
  1183. POP r3
  1184. POP r2
  1185. CPY0 0
  1186. CPY1 0
  1187. RET
  1188. arrayPop:
  1189. ; Pop from array *{r1 r0} value {r3 r2}
  1190. ; If empty, changes all regs to 0x00
  1191. CI1 r1
  1192. CI0 r0
  1193. LWLO r2,NULL
  1194. BEQ r2,0,.empty
  1195. DEC r2
  1196. CI1 r1
  1197. CI0 r0
  1198. SWLO r2,NULL
  1199. INC r2
  1200. ADD r0,r2
  1201. ADDC r1
  1202. CI1 r1
  1203. CI0 r0
  1204. LWHI r3,NULL
  1205. CI1 r1
  1206. CI0 r0
  1207. LWLO r2,NULL
  1208. RET
  1209. .empty:
  1210. CPY3 0
  1211. CPY2 0
  1212. CPY1 0
  1213. CPY0 0
  1214. RET
  1215. read_char: ; read char to r0
  1216. COM r0,COM_UARTR
  1217. ANDI r0,0b0000_1000
  1218. BZ r0,read_char
  1219. COM r0,COM_UARTIN
  1220. RET
  1221. malloc: ; returns memory free memory locaion
  1222. ; r0 = size to allocate
  1223. ; {r2, r1} memory pointer
  1224. LWHI r2,mallocPointer
  1225. LWLO r1,mallocPointer
  1226. PUSH r2
  1227. PUSH r1
  1228. ADD r1,r0
  1229. ADDC r2
  1230. SWHI r2
  1231. SWLO r1,mallocPointer
  1232. POP r1
  1233. POP r2
  1234. RET
  1235. print_msg: ; print value in mem pinter {r2 r1}
  1236. PUSH r0
  1237. .loop:
  1238. CI1 r2
  1239. CI0 r1
  1240. LWHI r0,NULL
  1241. BZ r0,.end
  1242. CALL print_char
  1243. CI1 r2
  1244. CI0 r1
  1245. LWLO r0,NULL
  1246. BZ r0,.end
  1247. CALL print_char
  1248. INC r1
  1249. ADDC r2
  1250. JUMP .loop
  1251. .end:
  1252. POP r0
  1253. RET
  1254. print_char: ; print value in r0
  1255. PUSH r0
  1256. .loop:
  1257. COM r0,COM_UARTR
  1258. ANDI r0,0b0000_0010
  1259. XORI r0,0b0000_0010 ; invert
  1260. BZ r0,.loop
  1261. POP r0
  1262. COM r0,COM_UARTW
  1263. RET