oisc8.asm 21 KB

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