oisc8.asm 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472
  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. STACK REG0
  44. REG0 LWHI
  45. CALL print_hex
  46. REG0 LWLO
  47. CALL print_hex
  48. REG0 0x20
  49. CALL print_char
  50. REG0 STACK
  51. %endmacro
  52. %macro PRINTREG 0
  53. STACK REG0
  54. STACK REG0
  55. REG0 REG1
  56. CALL print_hex
  57. REG0 STACK
  58. CALL print_hex
  59. REG0 0x20
  60. CALL print_char
  61. REG0 STACK
  62. %endmacro
  63. %macro PRINTREGLN 0
  64. STACK REG0
  65. STACK REG0
  66. REG0 REG1
  67. CALL print_hex
  68. REG0 STACK
  69. CALL print_hex
  70. ;REG0 0x20
  71. ;CALL print_char
  72. ;REG0 LWHI
  73. ;CALL print_hex
  74. ;REG0 LWLO
  75. ;CALL print_hex
  76. CALL println
  77. REG0 STACK
  78. %endmacro
  79. ; ==================
  80. ; Jump on conditions
  81. ; ==================
  82. %macro BGT 1
  83. BRPZ %1,LE
  84. %endmacro
  85. %macro BLT 1
  86. BRPZ %1,GE
  87. %endmacro
  88. %macro BGE 1
  89. BRPZ %1,LT
  90. %endmacro
  91. %macro BLE 1
  92. BRPZ %1,GT
  93. %endmacro
  94. %macro BEQ 1
  95. BRPZ %1,NE
  96. %endmacro
  97. %macro BNE 1
  98. BRPZ %1,EQ
  99. %endmacro
  100. %macro CALC_SIEVE_POINTER 4
  101. ; args: [value of n] [shifted value to store to] [jump label] [debug letter]
  102. ;; start debug
  103. ;STACK REG0
  104. ;REG0 %4
  105. ;CALL print_char
  106. ;REG0 STACK
  107. ;STACK REG0
  108. ;REG0 %1
  109. ;CALL print_u8
  110. ;REG0 0x20
  111. ;CALL print_char
  112. ;REG0 STACK
  113. ;; stop debug
  114. ALU0 %1
  115. STACK ALU0
  116. ALU1 16
  117. ALU0 DIV
  118. ;ALU1 sieve2@0
  119. MEM0 ADD
  120. ;ALU0 sieve2@1
  121. ALU1 0x00
  122. MEM1 ADC ; Memory pointer ready
  123. ALU0 STACK
  124. ALU1 16
  125. ALU1 MOD
  126. ALU0 1
  127. %2 SLL
  128. ALU0 8 ; if n%16 >= 8
  129. BGE %3 ; is high byte memhi
  130. %endmacro
  131. %macro COPY 1 ; copy current pointer to memory %1
  132. STACK MEMLO
  133. STACK MEMHI
  134. MEMP %1
  135. ALU0 STACK ; can't use 2 memory operations at once.
  136. MEMHI ALU0
  137. ALU0 STACK
  138. MEMLO ALU0
  139. %endmacro
  140. section .data depth=4096,width=2
  141. DBE 1
  142. intro_text: DB "\x1Bc\x1B[2J\x1B[HBooting \x1B[1m\x1B[36mOISC\x1B[0m system\r\n",0
  143. generalbuf: DBE 1
  144. generalbuf2: DBE 1
  145. generalbuf3: DBE 1
  146. sieve_x: DBE 1
  147. sieve_x2: DBE 1
  148. sieve_y: DBE 1
  149. sieve_y2: DBE 1
  150. sieve1: DBE 1
  151. sieve_arr: DBE 16
  152. memend: DBE 1
  153. section .text depth=3072,width=2,bin_width=13,parity=2,fill_bits=27648
  154. ;MEMP generalbuf2
  155. ;MEMP generalbuf
  156. ;MEMLO 0x00
  157. ;MEMHI 0x00
  158. REG0 0xFF
  159. REG1 0xFF
  160. CALL print_u16
  161. REG0 intro_text@0
  162. REG1 intro_text@1
  163. CALL print_string
  164. ;; test mul_u16
  165. ;MEMP generalbuf
  166. ;MEMLO 60059@0 ; num1 lo
  167. ;MEMHI 60059@1 ; num1 hi
  168. ;MEMP generalbuf2
  169. ;MEMLO 60 ; num1 lo
  170. ;MEMHI 0 ; num1 hi
  171. ;CALL div_u16
  172. ;STACK REG0
  173. ;STACK REG1
  174. ;MEMP generalbuf3
  175. ;REG0 MEMLO
  176. ;REG1 MEMHI
  177. ;CALL print_u16
  178. ;REG0 '.'
  179. ;CALL print_char
  180. ;REG1 STACK
  181. ;REG0 STACK
  182. ;CALL print_u16
  183. ;JUMP forever
  184. ;REG0 MEMLO
  185. ;CALL print_hex
  186. ;REG0 MEMHI
  187. ;CALL print_hex
  188. ;ALU0 0x44
  189. ;ALU1 0x44
  190. ;REG0 NE
  191. ;CALL print_hex
  192. ;ALU0 0x33
  193. ;ALU1 0x00
  194. ;REG0 NE
  195. ;CALL print_hex
  196. ;CALL println
  197. ;MEMP memend
  198. ;MEMLO 0x04
  199. REG0 '@'
  200. CALL print_char
  201. CALL clean_ram
  202. REG0 '@'
  203. CALL print_char
  204. CALL calc_sieve
  205. REG0 '@'
  206. CALL print_char
  207. ;JUMP forever
  208. CALL println
  209. REG0 0
  210. REG1 0
  211. .print_sieve:
  212. ; Set memory pointer
  213. ALU0 memend@0
  214. ALU1 REG0
  215. MEM0 ADD
  216. ALU0 memend@1
  217. ALU1 REG1
  218. MEM1 ADC
  219. ; check for overflow
  220. ALU0 MEM1
  221. ALU1 0x0e
  222. BGT .done
  223. STACK REG0
  224. STACK REG1
  225. BR0 MEMHI
  226. STACK BR0
  227. BR0 MEMLO
  228. STACK BR0
  229. ; now is loop for every bit in memory
  230. MEMP generalbuf3
  231. MEMLO 16
  232. MEMHI 0
  233. CALL mul_u16
  234. BR0 STACK
  235. MEMLO BR0
  236. MEMHI 1
  237. .print_loop0:
  238. ALU0 MEMHI
  239. ALU1 MEMLO
  240. BRPZ .z0,AND
  241. ;; This number is prime
  242. CALL print_u16
  243. CALL println
  244. MEMP generalbuf3
  245. ;PRINTREG
  246. ;JUMP .d0
  247. .z0:
  248. ;CALL print_u16
  249. ;PRINTREG
  250. ;; This number is not prime
  251. .d0:
  252. ALU1 1
  253. ALU0 MEMHI
  254. MEMHI SLL
  255. ALU0 REG0
  256. REG0 ADD
  257. ALU0 REG1
  258. ALU1 0
  259. REG1 ADC
  260. BRPZ .print_loop0e,MEMHI
  261. JUMP .print_loop0
  262. .print_loop0e:
  263. BR0 STACK
  264. MEMLO BR0
  265. MEMHI 1
  266. ;PRINTREG
  267. .print_loop1:
  268. ALU0 MEMHI
  269. ALU1 MEMLO
  270. BRPZ .z1,AND
  271. ;; This number is prime
  272. CALL print_u16
  273. CALL println
  274. MEMP generalbuf3
  275. JUMP .d1
  276. .z1:
  277. ;PRINTREG
  278. ;CALL print_u16
  279. ;; This number is not prime
  280. .d1:
  281. ALU1 1
  282. ALU0 MEMHI
  283. MEMHI SLL
  284. BRPZ .print_loop1e,MEMHI
  285. ALU0 REG0
  286. REG0 ADD
  287. ALU0 REG1
  288. ALU1 0
  289. REG1 ADC
  290. JUMP .print_loop1
  291. .print_loop1e:
  292. REG1 STACK
  293. REG0 STACK
  294. ALU0 REG0
  295. ALU1 1
  296. REG0 ADD
  297. ALU0 REG1
  298. ALU1 0
  299. REG1 ADC
  300. JUMP .print_sieve
  301. .done:
  302. REG0 '@'
  303. CALL print_char
  304. JUMP forever
  305. .hi:
  306. ALU0 MEMHI
  307. .next:
  308. ALU1 REG1
  309. BRPZ .noprint,AND
  310. STACK REG0
  311. CALL print_u8
  312. REG0 0x20
  313. CALL print_char
  314. REG0 STACK
  315. .noprint:
  316. ALU1 1
  317. ALU0 REG0
  318. REG0 ADD
  319. BRPZ forever,REG0
  320. JUMP .print_sieve
  321. ; REG0 0
  322. ;hex_test:
  323. ; ALU0 REG0
  324. ; ALU1 1
  325. ; REG0 ADD
  326. ; CALL print_hex
  327. ; REG1 REG0
  328. ; REG0 0x20
  329. ; CALL print_char
  330. ; REG0 REG1
  331. ; BRPZ .end,REG0
  332. ; JUMP hex_test
  333. ;.end:
  334. forever:
  335. JUMP forever
  336. clean_ram:
  337. MEMP memend
  338. .loop:
  339. MEMLO 0x00
  340. MEMHI 0x00
  341. ALU0 1
  342. ALU1 MEM0
  343. MEM0 ADD
  344. ALU0 0
  345. ALU1 MEM1
  346. MEM1 ADC
  347. ALU0 MEM1
  348. ALU1 0x0e
  349. BGT .done
  350. JUMP .loop
  351. .done:
  352. RET
  353. log2n_u8:
  354. ;; Only for 2^n numbers
  355. REG1 0
  356. ALU1 1
  357. .loop:
  358. BRPZ .done,REG0
  359. ALU0 REG0
  360. REG0 SRL
  361. ALU0 REG1
  362. REG1 ADD
  363. JUMP .loop
  364. .done:
  365. RET
  366. mod_u16:
  367. ;; Russian Peasant Multiplication
  368. ;; https://stackoverflow.com/questions/2566010
  369. ;; {reg1,reg0} = {reg1,reg0} % *generalbuf{memhi,memlo}
  370. %def $a0,REG0
  371. %def $a1,REG1
  372. %def $b0,MEMLO
  373. %def $b1,MEMHI
  374. %def $x0,MEMLO
  375. %def $x1,MEMHI
  376. COPY generalbuf2
  377. ; X = B
  378. STACK $a0
  379. STACK $a1
  380. ALU0 $a1 ; \
  381. ALU1 1 ; |
  382. $a1 SRL ; |
  383. ALU0 $a0 ; | A >> 1 (divide by 2)
  384. STACK ROR ; |
  385. ALU0 SRL ; |
  386. ALU1 STACK; |
  387. $a0 OR ; /
  388. ; Do while (X <= A/2)
  389. .while_a_start:
  390. ALU0 $x1
  391. ALU1 $a1
  392. BGT .while_a_end
  393. BLT .while_a_0
  394. ALU0 $x0
  395. ALU1 $a0
  396. BGE .while_a_end
  397. .while_a_0:
  398. ALU0 $x0 ; \
  399. ALU1 1 ; |
  400. $x0 SLL ; |
  401. STACK ROL ; | x <<= 1
  402. ALU0 $x1 ; |
  403. ALU0 SLL ; |
  404. ALU1 STACK ; |
  405. $x1 OR ; /
  406. JUMP .while_a_start
  407. .while_a_end:
  408. $a1 STACK
  409. $a0 STACK ; restore a
  410. .while_b_start:
  411. MEMP generalbuf
  412. ;PRINTREG
  413. ; Do while (A >= B)
  414. ALU0 $a1
  415. ALU1 $b1
  416. BLT .while_b_end
  417. BGT .while_b_0
  418. ALU0 $a0
  419. ALU1 $b0
  420. BLT .while_b_end
  421. .while_b_0:
  422. MEMP generalbuf2
  423. ; Check if A >= X
  424. ALU0 $a1
  425. ALU1 $x1
  426. BLT .next
  427. BGT .a_ge_x
  428. ALU0 $a0
  429. ALU1 $x0
  430. BLT .next
  431. .a_ge_x:
  432. ;PRINTREG
  433. ALU0 $a0
  434. ALU1 $x0
  435. $a0 SUB ; \
  436. ALU0 $a1 ; | A -= X
  437. ALU1 $x1 ; |
  438. $a1 SBC ; /
  439. .next:
  440. ; X >>= 1
  441. ALU0 $x1
  442. ALU1 1
  443. $x1 SRL
  444. STACK ROR
  445. ALU0 $x0
  446. ALU0 SRL
  447. ALU1 STACK
  448. $x0 OR
  449. BRPZ .check_null,$x1
  450. ; Back to while loop
  451. JUMP .while_b_start
  452. .check_null:
  453. BRPZ .while_b_end,$x0
  454. JUMP .while_b_start
  455. .while_b_end:
  456. RET
  457. %macro SLL16 3
  458. ALU0 %2
  459. ALU1 %1 ; multiply by 2
  460. %2 SLL
  461. STACK ROL
  462. ALU0 %3 ; multiply by 2 with carry
  463. ALU0 SLL
  464. ALU1 STACK
  465. %3 OR
  466. %endmacro
  467. div_u16:
  468. ;; Divide 16bit by 16bit (can be expanded)
  469. ;; source: https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder
  470. ;; generalbuf3 = generalbuf / generalbuf2; reg1,reg0 => reminder
  471. %def $Nl,MEMLO ; \
  472. %def $Nh,MEMHI ; / generalbuf
  473. %def $Dl,MEMLO ; \
  474. %def $Dh,MEMHI ; / generalbuf2
  475. %def $Ql,MEMLO ; \
  476. %def $Qh,MEMHI ; / generalbuf3
  477. %def $Rl,REG0
  478. %def $Rh,REG1
  479. $Rl 0
  480. $Rh 0
  481. MEMP generalbuf3
  482. MEMLO 0
  483. MEMHI 0
  484. STACK 0b1000_0000 ; put 0
  485. .for_start0:
  486. SLL16 1,$Rl,$Rh
  487. ;; Finding N(i)
  488. ALU0 STACK
  489. STACK ALU0
  490. MEMP generalbuf
  491. ALU1 $Nh
  492. BRPZ .z0,AND ; Nl & i == 0
  493. ALU0 0b0000_0001
  494. ALU1 $Rl
  495. $Rl OR ; R(0) = N(i) = 1
  496. JUMP .check0
  497. .z0:
  498. ALU0 0b1111_1110
  499. ALU1 $Rl
  500. $Rl AND ; R(0) = N(i) = 0
  501. .check0: ; if R >= D
  502. MEMP generalbuf2
  503. ALU0 $Rh
  504. ALU1 $Dh
  505. BLT .for_end0
  506. BGT .sub0
  507. ALU0 $Rl
  508. ALU1 $Dl
  509. BLT .for_end0
  510. .sub0:
  511. ALU0 $Rl
  512. ALU1 $Dl
  513. $Rl SUB
  514. ALU0 $Rh
  515. ALU1 $Dh
  516. $Rh SBC
  517. MEMP generalbuf3
  518. ALU0 $Qh ; Q(i) = 1
  519. ALU1 STACK
  520. STACK ALU1
  521. $Qh OR
  522. .for_end0:
  523. ALU0 STACK
  524. ALU1 1
  525. ALU0 SRL
  526. BRPZ .done0,ALU0
  527. STACK ALU0
  528. JUMP .for_start0
  529. .done0:
  530. STACK 0b1000_0000 ; put 0
  531. .for_start1:
  532. SLL16 1,$Rl,$Rh
  533. ;; Finding N(i)
  534. ALU0 STACK
  535. STACK ALU0
  536. MEMP generalbuf
  537. ALU1 $Nl
  538. BRPZ .z1,AND
  539. ALU0 0b0000_0001
  540. ALU1 $Rl
  541. $Rl OR ; R(0) = N(i) = 1
  542. JUMP .check1
  543. .z1:
  544. ALU0 0b1111_1110
  545. ALU1 $Rl
  546. $Rl AND ; R(0) = N(i) = 0
  547. .check1: ; if R >= D
  548. MEMP generalbuf2
  549. ALU0 $Rh
  550. ALU1 $Dh
  551. BLT .for_end1
  552. BGT .sub1
  553. ALU0 $Rl
  554. ALU1 $Dl
  555. BLT .for_end1
  556. .sub1:
  557. ALU0 $Rl
  558. ALU1 $Dl
  559. $Rl SUB
  560. ALU0 $Rh
  561. ALU1 $Dh
  562. $Rh SBC
  563. MEMP generalbuf3
  564. ALU0 $Ql ; Q(i) = 1
  565. ALU1 STACK
  566. STACK ALU1
  567. $Ql OR
  568. .for_end1:
  569. ALU0 STACK
  570. ALU1 1
  571. ALU0 SRL
  572. BRPZ .done1,ALU0
  573. STACK ALU0
  574. JUMP .for_start1
  575. .done1:
  576. RET
  577. ;div_u16:
  578. ;; Divide 16bit number by 8bit
  579. ;; Insparation taken from:
  580. ;; http://www.avr-asm-tutorial.net/avr_en/calc/DIV8E.html
  581. ;
  582. ; %def $rd1l,MEMLO
  583. ; %def $rd1h,MEMHI
  584. ; %def $rd2,REG0
  585. ; %def $rd1u,REG1
  586. ; %def $rel,MEMLO
  587. ; %def $reh,MEMHI
  588. ;
  589. ; $rd1u 0
  590. ; MEMP generalbuf2
  591. ; $rel 1
  592. ; $reh 0
  593. ;.div8a:
  594. ; MEMP generalbuf
  595. ; ALU0 1
  596. ; ALU1 $rd1l ; multiply by 2
  597. ; $rd1l SLL
  598. ; STACK ROL
  599. ;
  600. ; ALU1 $rd1h ; multiply by 2 with carry
  601. ; ALU1 SLL
  602. ; ALU0 STACK
  603. ; $rd1h OR
  604. ; STACK ROL
  605. ;
  606. ; ALU0 1
  607. ; ALU1 $rd1u
  608. ; ALU1 SLL
  609. ; ALU0 STACK
  610. ; $rd1u OR
  611. ; ALU0 0
  612. ; ALU1 ROL
  613. ; BNE .div8b
  614. ; ALU0 $rd1u
  615. ; ALU1 $rd2
  616. ; $rd1u SUB
  617. ; ALU1 SUBC
  618. ; ALU0 0
  619. ; BNE .div8c
  620. ;.div8b:
  621. ; ALU0 $rd1u
  622. ; ALU1 $rd2
  623. ; $rd1u SUB
  624. ; STACK 1
  625. ; JUMP .div8d
  626. ;.div8c:
  627. ; STACK 0
  628. ;.div8d:
  629. ; MEMP generalbuf2
  630. ; ALU0 1
  631. ; ALU1 $rel
  632. ; ALU0 SLL
  633. ; ALU1 STACK
  634. ; $rel OR
  635. ; STACK ROL
  636. ;
  637. ; ALU0 1
  638. ; ALU1 $reh
  639. ; ALU0 SLL
  640. ; ALU1 STACK
  641. ; $reh OR
  642. ; BRP .div8a
  643. ; BRZ ROL
  644. ;.done:
  645. ; RET
  646. calc_sieve:
  647. ; Sieve of Atkin
  648. %def $xl,MEMLO
  649. %def $xh,MEMHI
  650. %def $x2l,REG0
  651. %def $x2h,REG1
  652. %def $yl,MEMLO
  653. %def $yh,MEMHI
  654. %def $y2l,REG0
  655. %def $y2h,REG1
  656. ; loop x setup
  657. MEMP sieve_x
  658. $xl 1 ;
  659. $xh 0 ; x=1
  660. .loopx:
  661. COPY sieve_x2 ; temp copy x to x2
  662. REG0 $xl
  663. REG1 $xh
  664. CALL mul_u16
  665. ALU1 0
  666. ALU0 MEMHI
  667. BRP .endp1
  668. BRZ EQ ; if x^2 >= 2^16
  669. ALU0 MEMLO
  670. BRZ EQ ; if x^2 >= 2^16
  671. MEMHI REG1
  672. MEMLO REG0
  673. ; loop y setup
  674. MEMP sieve_y
  675. $yl 1 ;
  676. $yh 0 ; y=1
  677. .loopy:
  678. COPY sieve_y2 ; temp copy y to y2
  679. REG0 $yl
  680. REG1 $yh
  681. CALL mul_u16
  682. ALU1 0
  683. ALU0 MEMHI
  684. BRP .loopxe
  685. BRZ EQ ; if y^2 >= 2^16
  686. ALU0 MEMLO
  687. BRZ EQ ; if y^2 >= 2^16
  688. MEMHI REG1
  689. MEMLO REG0
  690. ; ==================
  691. ; Start of Main loop
  692. ; ==================
  693. ;MEMP sieve1
  694. %def $nh,REG1
  695. %def $nl,REG0
  696. ;MEMP sieve_y2
  697. ;PRINTMEM
  698. ;CALL println
  699. .c1:
  700. MEMP sieve_x2
  701. COPY sieve1 ; copy x^2 to n
  702. REG0 4
  703. REG1 0
  704. CALL mul_u16 ; x^2 * 0x0004
  705. ALU0 MEMHI; \
  706. ALU1 0 ; |
  707. BRP .c2 ; | checking if 4*x^2 overflow
  708. BRZ EQ ; |
  709. ALU0 MEMLO; |
  710. BRZ EQ ; /
  711. ; n += y^2
  712. ;$nl MEMLO
  713. ;$nh MEMHI
  714. MEMP sieve_y2
  715. ALU0 $nl ; $nl
  716. ALU1 MEMLO ; $y2l
  717. $nl ADD
  718. ALU0 $nh
  719. ALU1 MEMHI ; $y2h
  720. $nh ADC
  721. ALU0 ADDC ; \
  722. ALU1 0 ; | check for 4*x^2+y^2 oveflow
  723. BNE .c2 ; /
  724. ;CALL print_u16
  725. ;STACK REG0
  726. ;REG0 0x20
  727. ;CALL print_char
  728. ;REG0 STACK
  729. MEMP sieve1 ; \
  730. MEMLO $nl ; | save n to sieve1
  731. MEMHI $nh ; /
  732. ; checkinf for n%12 == 1 || n%12 == 5
  733. MEMP generalbuf
  734. MEMHI 0
  735. MEMLO 12 ; storing 12
  736. CALL mod_u16 ; n = n%12
  737. ALU0 0
  738. ALU1 $nh ; if n%12 high byte != 0
  739. BNE .c2
  740. ALU0 1 ; if n%12 == 1
  741. ALU1 $nl
  742. BEQ .c1x
  743. ALU0 5 ; if n%12 == 5
  744. BNE .c2
  745. .c1x:
  746. ; call sieve
  747. CALL xorSieveArray
  748. .c2:
  749. MEMP sieve_x2
  750. COPY sieve1 ; copy x^2 to n
  751. REG0 3
  752. REG1 0
  753. CALL mul_u16 ; x^2 * 0x0003
  754. ALU0 MEMHI; \
  755. ALU1 0 ; |
  756. BRP .c3 ; | checking if 3*x^2 overflow
  757. BRZ EQ ; |
  758. ALU0 MEMLO; |
  759. BRZ EQ ; /
  760. ; n += y^2
  761. MEMP sieve_y2
  762. ALU0 $nl ; $nl
  763. ALU1 MEMLO ; $y2l
  764. $nl ADD
  765. ALU0 $nh
  766. ALU1 MEMHI
  767. $nh ADC
  768. ALU0 ADDC ; \
  769. ALU1 0 ; | chcek for 3*x^2+y^2 overflow
  770. BNE .c3 ; /
  771. MEMP sieve1
  772. MEMHI $nh
  773. MEMLO $nl
  774. ; checkinf for n%12 == 7
  775. MEMP generalbuf
  776. MEMHI 0
  777. MEMLO 12 ; storing 12
  778. CALL mod_u16 ; n = n%12
  779. ALU0 0
  780. ALU1 REG1 ; if n%12 high byte != 0
  781. BRP .c3
  782. BRZ EQ
  783. ALU0 7 ; if n%12 == 7
  784. ALU1 REG0
  785. BRZ EQ
  786. CALL xorSieveArray
  787. .c3:
  788. ; checking if x > y
  789. MEMP sieve_y
  790. REG0 MEMLO
  791. REG1 MEMHI
  792. MEMP sieve_x
  793. ALU0 REG1 ; xh
  794. ALU1 MEMHI ; yh
  795. BGT .c3c
  796. BLT .loopye ; jump if x < y
  797. ALU0 REG0 ; xl
  798. ALU1 MEMLO ; yl
  799. BGE .loopye ; jump to .loopy if x < y
  800. .c3c:
  801. MEMP sieve_x2
  802. COPY sieve1 ; copy x^2 to n
  803. REG0 3
  804. REG1 0
  805. CALL mul_u16 ; x^2 * 0x0003
  806. ; now n is 32bit in {MEMHI, MEMLO, REG1, REG0}
  807. ; where do we store y^2? Should be in stack but for test lets use BRP
  808. BR0 MEMLO
  809. BR1 MEMHI
  810. MEMP sieve_y2
  811. COPY sieve1
  812. ALU0 REG0
  813. ALU1 MEMLO
  814. REG0 SUB
  815. ALU0 REG1
  816. ALU1 MEMHI
  817. REG1 SBC
  818. ALU0 BR0
  819. ALU1 0
  820. MEMLO SBC
  821. ALU0 BR1
  822. ALU1 0
  823. MEMHI SBC
  824. ; now 32bit in {MEMHI, MEMLO, REG1, REG0}
  825. ; has been subtraced with y^2
  826. ALU0 MEMHI ; \
  827. ALU1 0 ; |
  828. BRP .loopye; | checking if 3*x^2-y^2 overflow
  829. BRZ EQ ; |
  830. ALU0 MEMLO ; |
  831. BRZ EQ ; /
  832. MEMLO $nl
  833. MEMHI $nh
  834. ; checkinf for n%12 == 11
  835. MEMP generalbuf
  836. MEMHI 0
  837. MEMLO 12 ; storing 12
  838. CALL mod_u16 ; n = n%12
  839. ALU0 0
  840. ALU1 $nh ; if n%12 high byte != 0
  841. BRP .loopye
  842. BRZ NE
  843. ALU0 7 ; if n%12 == 7
  844. ALU1 $nl
  845. BRZ NE
  846. ; n should be in *sieve1
  847. CALL xorSieveArray
  848. ; ================
  849. ; End of main loop
  850. ; ================
  851. .loopye:
  852. MEMP sieve_y
  853. ALU0 $yl ; \
  854. ALU1 1 ; |
  855. $yl ADD ; | y++
  856. ALU1 ADDC ; |
  857. ALU0 $yh ; |
  858. $yh ADD ; /
  859. JUMP .loopy
  860. .loopxe:
  861. MEMP sieve_x
  862. ALU0 $xl ; \
  863. ALU1 1 ; |
  864. $xl ADD ; | x++
  865. ALU1 ADDC ; |
  866. ALU0 $xh ; |
  867. $xh ADD ; /
  868. JUMP .loopx
  869. ; =============
  870. ; End of part 1
  871. ; =============
  872. .endp1:
  873. ; ; now lets reject squares
  874. ; %def $r,REG0
  875. ; %def $r2,REG1
  876. ; $r 5 ; r:=5
  877. ;.loopr:
  878. ; ALU0 $r
  879. ; ALU1 $r
  880. ; $r2 MULLO ; reg1 := r^2
  881. ; ALU0 MULHI
  882. ; ALU1 0x00
  883. ; BNE .endp2 ; end if r^2 > 255
  884. ; ; accessing mem cell
  885. ; STACK REG0
  886. ; CALC_SIEVE_POINTER REG0,REG0,.hi,'R'
  887. ; ALU1 MEMLO
  888. ; JUMP .x1
  889. ;.hi:
  890. ; ALU1 MEMHI
  891. ;.x1:
  892. ; ALU0 REG0
  893. ; REG0 STACK
  894. ; BRPZ .loopre,AND ; if sieve[r] = 0
  895. ; ; loopi
  896. ; STACK $r; reg0 := r
  897. ; REG0 $r2 ; i := r^2
  898. ;.loopi:
  899. ; STACK REG0
  900. ; CALC_SIEVE_POINTER REG0,REG0,.x2hi,'D'
  901. ; ALU0 REG0
  902. ; ALU1 0xFF
  903. ; ALU0 XOR ; invert REG0
  904. ; ALU1 MEMLO
  905. ; MEMLO AND ; set sieve[i] = 0
  906. ; JUMP .x2
  907. ;.x2hi:
  908. ; ALU0 REG0
  909. ; ALU1 0xFF
  910. ; ALU0 XOR ; invert REG0
  911. ; ALU1 MEMHI
  912. ; MEMHI AND ; set sieve[i] = 0
  913. ;.x2:
  914. ; REG0 STACK
  915. ;.loopie:
  916. ; ALU0 REG0
  917. ; ALU1 REG1
  918. ; REG0 ADD
  919. ; BRPZ .loopi,ADDC ; if not overflow
  920. ; $r STACK ; restoring stack for r
  921. ;
  922. ;.loopre:
  923. ; ALU0 $r
  924. ; ALU1 1
  925. ; $r ADD ; r ++
  926. ; JUMP .loopr
  927. ;.endp2:
  928. RET
  929. xorSieveArray:
  930. ; short n = *sieve1
  931. ; sieve[n//16] ^= 1<<n%16
  932. ;jump forever
  933. MEMP sieve1
  934. ;PRINTMEM
  935. ;CALL println
  936. ;ALU0 MEMHI
  937. ;ALU1 1000@1
  938. ;BGT forever
  939. COPY generalbuf
  940. MEMP generalbuf2
  941. MEMLO 16
  942. MEMHI 0
  943. CALL div_u16
  944. MEMP generalbuf3
  945. ALU0 MEMLO
  946. ALU1 memend@0
  947. MEM0 ADD
  948. ALU0 MEMHI
  949. ALU1 memend@1
  950. MEM1 ADC
  951. MEM2 0
  952. ; memory pointer ready
  953. ; checking if there's enough ram to not corrupt stack
  954. ; mem1 should be less or equal to 0x0e, making ~ 3839 memory spaces or
  955. ; about 60800 bits
  956. ALU0 MEM1
  957. ALU1 0x0e
  958. BGT .done
  959. .mpr:
  960. ;; DEBUG
  961. ;STACK REG0
  962. ;REG0 MEM2
  963. ;CALL print_hex
  964. ;REG0 MEM1
  965. ;CALL print_hex
  966. ;REG0 MEM0
  967. ;CALL print_hex
  968. ;REG0 ":"
  969. ;CALL print_char
  970. ;REG0 STACK
  971. ;; DEBUG END
  972. ALU1 REG0 ; dividion reminder lower byte
  973. ALU0 8
  974. BLT .hi
  975. ; memory lower
  976. ALU0 1
  977. ALU1 REG0 ; reminder
  978. ALU0 SLL
  979. ;; debug
  980. ;STACK REG0
  981. ;STACK ALU0
  982. ;REG0 'L'
  983. ;CALL print_char
  984. ;REG0 MEMLO
  985. ;CALL print_bin
  986. ;REG0 '^'
  987. ;CALL print_char
  988. ;REG0 STACK
  989. ;CALL print_bin
  990. ;ALU0 REG0
  991. ;REG0 STACK
  992. ;; debug end
  993. ALU1 MEMLO
  994. MEMLO XOR
  995. JUMP .done
  996. .hi:
  997. ALU0 1
  998. ALU1 REG0 ; reminder
  999. ALU0 SLL
  1000. ;ALU0 ROL
  1001. ;; debug
  1002. ;STACK REG0
  1003. ;STACK ALU0
  1004. ;REG0 'H'
  1005. ;CALL print_char
  1006. ;REG0 MEMHI
  1007. ;CALL print_bin
  1008. ;REG0 '^'
  1009. ;CALL print_char
  1010. ;REG0 STACK
  1011. ;CALL print_bin
  1012. ;ALU0 REG0
  1013. ;REG0 STACK
  1014. ;; debug end
  1015. ALU1 MEMHI
  1016. MEMHI XOR
  1017. ;STACK REG0
  1018. ;REG0 MEMHI
  1019. ;CALL print_u8
  1020. ;REG0 0x20
  1021. ;CALL print_char
  1022. ;ALU0 MEMHI
  1023. ;ALU1 16
  1024. ;REG0 DIV
  1025. ;CALL print_u8
  1026. ;REG0 0x20
  1027. ;CALL print_char
  1028. ;CALC_SIEVE_POINTER MEMHI,REG0,.hi,'A'
  1029. ;; debug
  1030. ;STACK REG0
  1031. ;REG0 'L'
  1032. ;CALL print_char
  1033. ;REG0 MEMLO
  1034. ;CALL print_bin
  1035. ;REG0 '^'
  1036. ;CALL print_char
  1037. ;REG0 STACK
  1038. ;CALL print_bin
  1039. ;; debug end
  1040. ; ALU0
  1041. ; ALU1 REG0
  1042. ; MEMLO XOR
  1043. ; JUMP .done
  1044. ;.hi:
  1045. ; ;; debug
  1046. ; STACK REG0
  1047. ; REG0 'H'
  1048. ; CALL print_char
  1049. ; REG0 MEMHI
  1050. ; CALL print_bin
  1051. ; REG0 '^'
  1052. ; CALL print_char
  1053. ; REG0 STACK
  1054. ; CALL print_bin
  1055. ; ;; debug end
  1056. ; ALU0 MEMHI
  1057. ; ALU1 REG0
  1058. ; MEMHI XOR
  1059. .done:
  1060. ;; debug
  1061. ;STACK XOR
  1062. ;REG0 '='
  1063. ;CALL print_char
  1064. ;REG0 STACK
  1065. ;CALL print_bin
  1066. ;CALL println
  1067. ;; debug end
  1068. RET
  1069. mul_u16:
  1070. ; m1H, m1L, m2H, m2L, MEMHI, MEMLO, REG1, REG0
  1071. ; answer = {MEMHI, MEMLO, REG1, REG0}
  1072. %def $m1H,REG1
  1073. %def $m2H,MEMHI
  1074. %def $m1L,REG0
  1075. %def $m2L,MEMLO
  1076. %def $res3,MEMHI
  1077. %def $res2,MEMLO
  1078. %def $res1,REG1
  1079. %def $res0,REG0
  1080. ;MEMP generalbuf
  1081. ;REG0 -> m1L
  1082. ;REG1 -> m2L
  1083. ALU0 $m2L
  1084. ALU1 $m2H
  1085. STACK ALU1 ;m2H
  1086. STACK $m1L
  1087. STACK ALU0 ;m2L
  1088. STACK $m1H ;m1H
  1089. STACK ALU0 ;m2L
  1090. STACK $m1L
  1091. ALU0 $m1H
  1092. $res2 MULLO
  1093. $res3 MULHI
  1094. ALU0 STACK ;m1L
  1095. ALU1 STACK ;m2L
  1096. $res0 MULLO
  1097. $res1 MULHI
  1098. ALU0 STACK ;m1H
  1099. ALU1 STACK ;m2L
  1100. STACK MULHI
  1101. ALU0 MULLO
  1102. ALU1 $res1
  1103. $res1 ADD
  1104. ALU0 STACK
  1105. ALU1 $res2
  1106. $res2 ADC
  1107. ALU1 ADDC
  1108. ALU0 $res3
  1109. $res3 ADD
  1110. ALU0 STACK ;m1L
  1111. ALU1 STACK ;m2H
  1112. STACK MULHI
  1113. ALU0 MULLO
  1114. ALU1 $res1
  1115. $res1 ADD
  1116. ALU0 $res2
  1117. ALU1 STACK
  1118. $res2 ADC
  1119. ALU0 ADDC
  1120. ALU1 $res3
  1121. $res3 ADD
  1122. RET
  1123. bin2digit:
  1124. ; Converts U16 to digit
  1125. ; Adopted from http:;www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  1126. ; Digit {reg1 reg0} Place in 10^n generalbuf
  1127. ; Memory pointer must be set to generalbuf
  1128. STACK 0
  1129. .a:
  1130. ALU0 REG1
  1131. ALU1 LWHI
  1132. BLT .c
  1133. BGT .b
  1134. ALU0 REG0
  1135. ALU1 LWLO
  1136. BLT .c
  1137. .b:
  1138. ALU0 REG0
  1139. ALU1 LWLO
  1140. REG0 SUB
  1141. ALU0 REG1
  1142. ALU1 LWHI
  1143. REG1 SBC
  1144. ALU0 STACK
  1145. ALU1 1
  1146. STACK ADD
  1147. JUMP .a
  1148. .c:
  1149. SWLO REG0
  1150. REG0 STACK
  1151. SWHI REG0
  1152. REG0 LWLO
  1153. RET
  1154. print_u16:
  1155. ; Prints U16 in {reg1 reg0}
  1156. STACK REG0
  1157. STACK REG1
  1158. MEMP generalbuf
  1159. SWHI 10000@1
  1160. SWLO 10000@0 ; 10000 in hex
  1161. CALL bin2digit
  1162. ALU0 48
  1163. ALU1 LWHI
  1164. STACK REG0
  1165. REG0 ADD
  1166. CALL print_char
  1167. REG0 STACK
  1168. SWHI 1000@1
  1169. SWLO 1000@0
  1170. CALL bin2digit
  1171. ALU0 48
  1172. ALU1 LWHI
  1173. STACK REG0
  1174. REG0 ADD
  1175. CALL print_char
  1176. REG0 STACK
  1177. SWHI 0
  1178. SWLO 100
  1179. CALL bin2digit
  1180. ALU0 48
  1181. ALU1 LWHI
  1182. STACK REG0
  1183. REG0 ADD
  1184. CALL print_char
  1185. REG0 STACK
  1186. ALU0 REG0
  1187. ALU1 100
  1188. REG1 MOD
  1189. ALU1 10
  1190. ALU0 REG0
  1191. STACK MOD
  1192. ALU1 MOD
  1193. ALU0 REG1
  1194. ALU0 SUB
  1195. ALU1 10
  1196. ALU0 DIV
  1197. ALU1 48
  1198. REG0 ADD
  1199. CALL print_char
  1200. ALU0 STACK
  1201. ALU1 48
  1202. REG0 ADD
  1203. CALL print_char
  1204. REG1 STACK
  1205. REG0 STACK
  1206. RET
  1207. print_u8:
  1208. ; print u8 in reg0
  1209. ; a = 128%10 = 8
  1210. ; a = 128%100 - a // 10 = 2
  1211. ; a = 128%1000 - a // 100 = 1
  1212. STACK REG1
  1213. REG1 REG0
  1214. ALU1 10
  1215. ALU0 REG0
  1216. ALU0 MOD ; ALU0 = reg0%10
  1217. STACK ALU0
  1218. REG0 ALU0
  1219. ALU0 REG1
  1220. BRPZ .p3,GE
  1221. ALU1 100
  1222. ALU0 REG1
  1223. ALU0 MOD
  1224. ALU1 STACK
  1225. STACK ALU1
  1226. ALU0 SUB
  1227. ALU1 10
  1228. ALU1 DIV
  1229. STACK ALU1
  1230. ALU0 REG1
  1231. ALU1 100
  1232. BRPZ .p2,GE
  1233. ALU1 200
  1234. BRPZ .p1,GE
  1235. REG0 '2'
  1236. CALL print_char
  1237. JUMP .p2
  1238. .p1:
  1239. REG0 '1'
  1240. CALL print_char
  1241. .p2:
  1242. ALU0 48
  1243. ALU1 STACK
  1244. REG0 ADD
  1245. CALl print_char
  1246. .p3:
  1247. ALU0 48
  1248. ALU1 STACK
  1249. REG0 ADD
  1250. CALl print_char
  1251. REG0 REG1
  1252. REG1 STACK
  1253. RET
  1254. print_bin:
  1255. ; print reg0 as binary
  1256. STACK REG0
  1257. STACK REG1
  1258. REG1 REG0 ; Making copy
  1259. ALU0 0b1000_0000
  1260. .start:
  1261. ALU1 REG1
  1262. STACK ALU0
  1263. BRPZ .print0,AND
  1264. .print1:
  1265. REG0 '1'
  1266. CALL print_char
  1267. JUMP .end
  1268. .print0:
  1269. REG0 '0'
  1270. CALL print_char
  1271. .end:
  1272. ALU1 1
  1273. ALU0 STACK
  1274. ALU0 SRL
  1275. BRPZ .done,ALU0
  1276. REG0 REG1
  1277. JUMP .start
  1278. .done:
  1279. REG1 STACK
  1280. REG0 STACK
  1281. RET
  1282. print_hex:
  1283. ; prints reg0 as hex
  1284. STACK REG0
  1285. STACK REG1
  1286. REG1 REG0
  1287. ALU1 4
  1288. ALU0 REG0
  1289. ALU1 SRL
  1290. ALU0 10
  1291. BRPZ .p0,GT
  1292. ALU0 48
  1293. JUMP .p1
  1294. .p0:
  1295. ALU0 55
  1296. .p1:
  1297. REG0 ADD
  1298. CALL print_char
  1299. REG0 REG1
  1300. ALU0 0b0000_1111
  1301. ALU1 REG0
  1302. ALU1 AND
  1303. ALU0 10
  1304. BRPZ .p2,GT
  1305. ALU0 48
  1306. JUMP .p3
  1307. .p2:
  1308. ALU0 55
  1309. .p3:
  1310. REG0 ADD
  1311. CALL print_char
  1312. REG1 STACK
  1313. REG0 STACK
  1314. RET
  1315. println:
  1316. STACK REG0
  1317. REG0 LF
  1318. CALL print_char
  1319. REG0 CR
  1320. CALL print_char
  1321. REG0 STACK
  1322. RET
  1323. print_string:
  1324. ; prints string in memory location {reg0, reg1}
  1325. .st:
  1326. MEM0 REG0
  1327. MEM1 REG1
  1328. BRPZ .end,LWHI
  1329. COMA COM_UARTR
  1330. BRP .loop0
  1331. ALU0 COM_UART_RECV
  1332. .loop0:
  1333. ALU1 COMD
  1334. ALU1 AND
  1335. BRZ NE
  1336. COMA COM_UARTW
  1337. COMD LWHI
  1338. BRPZ .end,LWLO
  1339. COMA COM_UARTR
  1340. BRP .loop1
  1341. .loop1:
  1342. ALU1 COMD
  1343. ALU1 AND
  1344. BRZ NE
  1345. COMA COM_UARTW
  1346. COMD LWLO
  1347. ALU0 REG0
  1348. ALU1 1
  1349. REG0 ADD
  1350. ALU1 ADDC
  1351. ALU0 REG1
  1352. REG1 ADD
  1353. JUMP .st
  1354. .end:
  1355. RET
  1356. print_char:
  1357. ; prints char in reg0
  1358. COMA COM_UARTR
  1359. BRP .loop0
  1360. ALU0 COM_UART_RECV
  1361. .loop0:
  1362. ALU1 COMD
  1363. ALU1 AND
  1364. BRZ NE
  1365. COMA COM_UARTW
  1366. COMD REG0
  1367. RET
  1368. read_char:
  1369. ; waits for char and stores that in reg0
  1370. COMA COM_UARTR
  1371. ALU0 0b0000_1000
  1372. BRP .loop
  1373. .loop:
  1374. ALU1 COMD
  1375. BRZ AND
  1376. COMA COM_UARTIN
  1377. REG0 COMD
  1378. RET