oisc8.asm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  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. REG0 LWHI
  44. CALL print_hex
  45. REG0 LWLO
  46. CALL print_hex
  47. REG0 0x20
  48. CALL print_char
  49. %endmacro
  50. %macro PRINTREG 0
  51. STACK REG0
  52. STACK REG0
  53. REG0 REG1
  54. CALL print_hex
  55. REG0 STACK
  56. CALL print_hex
  57. REG0 0x20
  58. CALL print_char
  59. REG0 LWHI
  60. CALL print_hex
  61. REG0 LWLO
  62. CALL print_hex
  63. CALL println
  64. REG0 STACK
  65. %endmacro
  66. ; ==================
  67. ; Jump on conditions
  68. ; ==================
  69. %macro BGT 1
  70. BRPZ %1,LE
  71. %endmacro
  72. %macro BLT 1
  73. BRPZ %1,GE
  74. %endmacro
  75. %macro BGE 1
  76. BRPZ %1,LT
  77. %endmacro
  78. %macro BLE 1
  79. BRPZ %1,GT
  80. %endmacro
  81. %macro BEQ 1
  82. BRPZ %1,NE
  83. %endmacro
  84. %macro BNE 1
  85. BRPZ %1,EQ
  86. %endmacro
  87. %macro CALC_SIEVE_POINTER 4
  88. ; args: [value of n] [shifted value to store to] [jump label] [debug letter]
  89. ;
  90. ;; start debug
  91. ;STACK REG0
  92. ;REG0 %4
  93. ;CALL print_char
  94. ;REG0 STACK
  95. ;STACK REG0
  96. ;REG0 %1
  97. ;CALL print_u8
  98. ;REG0 0x20
  99. ;CALL print_char
  100. ;REG0 STACK
  101. ;; stop debug
  102. ALU0 %1
  103. STACK ALU0
  104. ALU1 16
  105. ALU0 DIV
  106. ALU1 sieve2@0
  107. MEM0 ADD
  108. ALU0 sieve2@1
  109. ALU1 0x00
  110. MEM1 ADC ; Memory pointer ready
  111. ALU0 STACK
  112. ALU1 16
  113. ALU1 MOD
  114. ALU0 1
  115. %2 SLL
  116. ALU0 8 ; if n%16 >= 8
  117. BGE %3 ; is high byte memhi
  118. %endmacro
  119. section .data 2x3x8192
  120. DBE 1
  121. intro_text: DB 0x1B,"c",0x1B,"[HBooting ",0x1B,"[1m",0x1B,"[36m","OISC",0x1B,"[0m system..",LFCR,0
  122. generalbuf: DBE 1
  123. sieve: DBE 1
  124. sieve1: DBE 1
  125. sieve2: DBE 16
  126. section .text 2x3x2048
  127. REG0 intro_text@0
  128. REG1 intro_text@1
  129. CALL print_string
  130. ;ALU0 0x44
  131. ;ALU1 0x44
  132. ;REG0 NE
  133. ;CALL print_hex
  134. ;ALU0 0x33
  135. ;ALU1 0x00
  136. ;REG0 NE
  137. ;CALL print_hex
  138. ;CALL println
  139. REG0 '@'
  140. CALL print_char
  141. CALL calc_sieve
  142. REG0 '@'
  143. CALL print_char
  144. CALL println
  145. ;JUMP forever
  146. REG0 0
  147. .print_sieve:
  148. CALC_SIEVE_POINTER REG0,REG1,.hi,'x'
  149. ALU0 MEMLO
  150. JUMP .next
  151. .hi:
  152. ALU0 MEMHI
  153. .next:
  154. ALU1 REG1
  155. BRPZ .noprint,AND
  156. STACK REG0
  157. CALL print_u8
  158. REG0 0x20
  159. CALL print_char
  160. REG0 STACK
  161. .noprint:
  162. ALU1 1
  163. ALU0 REG0
  164. REG0 ADD
  165. BRPZ forever,REG0
  166. JUMP .print_sieve
  167. ; REG0 0
  168. ;hex_test:
  169. ; ALU0 REG0
  170. ; ALU1 1
  171. ; REG0 ADD
  172. ; CALL print_hex
  173. ; REG1 REG0
  174. ; REG0 0x20
  175. ; CALL print_char
  176. ; REG0 REG1
  177. ; BRPZ .end,REG0
  178. ; JUMP hex_test
  179. ;.end:
  180. forever:
  181. JUMP forever
  182. calc_sieve:
  183. ;; Sieve of Atkin
  184. MEMP sieve
  185. MEMHI 1; x
  186. .loopx:
  187. ALU0 MEMHI
  188. ALU1 MEMHI
  189. REG0 MULLO ; x^2
  190. ;STACK MULHI
  191. ; print x
  192. ;STACK REG0
  193. ;REG0 'x'
  194. ;CALL print_char
  195. ;REG0 STACK
  196. ;STACK REG0
  197. ;CALL print_u8
  198. ;REG0 0x20
  199. ;CALL print_char
  200. ;ALU0 MULHI
  201. ;ALU1 0
  202. ;REG0 STACK
  203. ;; end print x
  204. ;ALU0 STACK
  205. ALU0 MULHI
  206. ALU1 0
  207. BNE .endp1 ; if x^2 > 255
  208. MEMLO 1; y
  209. .loopy:
  210. ALU0 MEMLO
  211. ALU1 MEMLO
  212. REG1 MULLO ; y^2
  213. ;STACK MULHI
  214. ;STACK REG0
  215. ;REG0 'y'
  216. ;CALL print_char
  217. ;REG0 REG1
  218. ;CALL print_u8
  219. ;REG0 0x20
  220. ;CALL print_char
  221. ;REG0 STACK
  222. ;ALU0 STACK
  223. ALU0 MULHI
  224. ALU1 0
  225. BNE .loopxe ; if y^2 > 255
  226. ; ==================
  227. ; Start of Main loop
  228. ; ==================
  229. ; At this point reg0 := x^2, reg1 := y^2
  230. MEMP sieve1
  231. .c1:
  232. ALU0 REG0
  233. ALU1 4
  234. STACK MULLO
  235. ALU0 MULHI ; \
  236. ALU1 0 ; | Checking if 4x^2 > 255
  237. ALU1 EQ ; /
  238. ALU0 STACK
  239. BRPZ .c2,ALU1 ; if mulhi != 0: goto .c2
  240. ALU1 REG1
  241. MEMHI ADD ; n = mullo( low{4*x^2} ) + y^2
  242. ALU0 ADDC ; \
  243. ALU1 0 ; | Checking if 4x^2+y^2 > 255
  244. BNE .c2 ; /
  245. ALU0 MEMHI ; MEMHI := n
  246. ALU1 12
  247. MEMLO MOD
  248. ALU0 MEMLO
  249. ALU1 1
  250. BEQ .c1r ; n%12 == 1
  251. ALU0 MEMLO
  252. ALU1 5
  253. BEQ .c1r ; n%12 == 5
  254. JUMP .c2
  255. .c1r:
  256. CALL xorSieveArray
  257. MEMP sieve1
  258. .c2:
  259. ALU0 REG0
  260. ALU1 3
  261. STACK MULLO
  262. ALU0 MULHI ; \
  263. ALU1 0 ; | Checking if 3x^2 > 255
  264. ALU1 EQ ; /
  265. ALU0 STACK
  266. BRPZ .c3,ALU1
  267. ALU1 REG1
  268. STACK ADD
  269. ALU0 ADDC ; \
  270. ALU1 0 ; | Checking if 3x^2+y^2 > 255
  271. ALU1 EQ ; /
  272. ALU0 STACK
  273. BRPZ .c3,ALU1
  274. MEMHI ALU0 ; MEMHI := n
  275. ALU1 12
  276. ALU0 MOD
  277. ALU1 7
  278. BNE .c3
  279. CALL xorSieveArray
  280. .c3:
  281. MEMP sieve
  282. ALU1 MEMLO ; y
  283. ALU0 MEMHI ; x
  284. BLE .loopye ; Function needs x>y
  285. MEMP sieve1
  286. ALU0 REG0
  287. ALU1 3
  288. MEMLO MULHI ; MEMLO := HIGH(3x^2)
  289. ALU0 MULLO
  290. ALU1 REG1
  291. MEMHI SUB ; MEMHI := LOW(3x^2)-y^2
  292. ALU0 MEMLO
  293. ALU1 0x00
  294. ALU0 SBC ; ALU0 := HIGH(3x^2)-CARRY(y^2)
  295. BNE .c4 ; ALU0 != 0x00: goto .c4
  296. ALU0 MEMHI ; \
  297. ALU1 12 ; |
  298. ALU0 MOD ; | Checking if n%12 != 11
  299. ALU1 11 ; |
  300. BNE .c4 ; /
  301. CALL xorSieveArray
  302. .c4:
  303. MEMP sieve
  304. ; ================
  305. ; End of main loop
  306. ; ================
  307. .loopye:
  308. ALU0 MEMLO
  309. ALU1 1
  310. MEMLO ADD ; y++
  311. JUMP .loopy
  312. .loopxe:
  313. ALU0 MEMHI
  314. ALU1 1
  315. MEMHI ADD ; x++
  316. JUMP .loopx
  317. .endp1:
  318. ; now lets reject squares
  319. REG0 5 ; r:=5
  320. .loopr:
  321. ALU0 REG0
  322. ALU1 REG0
  323. REG1 MULLO ; reg1 := r^2
  324. ALU0 MULHI
  325. ALU1 0x00
  326. BNE .endp2 ; end if r^2 > 255
  327. ; accessing mem cell
  328. STACK REG0
  329. CALC_SIEVE_POINTER REG0,REG0,.hi,'R'
  330. ALU1 MEMLO
  331. JUMP .x1
  332. .hi:
  333. ALU1 MEMHI
  334. .x1:
  335. ALU0 REG0
  336. REG0 STACK
  337. BRPZ .loopre,AND ; if sieve[r] = 0
  338. ; loopi
  339. STACK REG0; reg0 := r
  340. REG0 REG1 ; i := r^2
  341. .loopi:
  342. STACK REG0
  343. CALC_SIEVE_POINTER REG0,REG0,.x2hi,'D'
  344. ALU0 REG0
  345. ALU1 0xFF
  346. ALU0 XOR ; invert REG0
  347. ALU1 MEMLO
  348. MEMLO AND ; set sieve[i] = 0
  349. JUMP .x2
  350. .x2hi:
  351. ALU0 REG0
  352. ALU1 0xFF
  353. ALU0 XOR ; invert REG0
  354. ALU1 MEMHI
  355. MEMHI AND ; set sieve[i] = 0
  356. .x2:
  357. REG0 STACK
  358. .loopie:
  359. ALU0 REG0
  360. ALU1 REG1
  361. REG0 ADD
  362. BRPZ .loopi,ADDC ; if not overflow
  363. REG0 STACK ; restoring stack for r
  364. .loopre:
  365. ALU0 REG0
  366. ALU1 1
  367. REG0 ADD ; r ++
  368. JUMP .loopr
  369. .endp2:
  370. RET
  371. xorSieveArray:
  372. ; n := memhi
  373. ; sieve[n//16] ^= 1<<n%16
  374. STACK REG0
  375. REG0 MEMHI
  376. CALL print_u8
  377. REG0 0x20
  378. CALL print_char
  379. ALU0 MEMHI
  380. ALU1 16
  381. REG0 DIV
  382. CALL print_u8
  383. REG0 0x20
  384. CALL print_char
  385. CALC_SIEVE_POINTER MEMHI,REG0,.hi,'A'
  386. ;; debug
  387. STACK REG0
  388. REG0 'L'
  389. CALL print_char
  390. REG0 MEMLO
  391. CALL print_bin
  392. REG0 '^'
  393. CALL print_char
  394. REG0 STACK
  395. CALL print_bin
  396. ;; debug end
  397. ALU0 MEMLO
  398. ALU1 REG0
  399. MEMLO XOR
  400. JUMP .done
  401. .hi:
  402. ;; debug
  403. STACK REG0
  404. REG0 'H'
  405. CALL print_char
  406. REG0 MEMHI
  407. CALL print_bin
  408. REG0 '^'
  409. CALL print_char
  410. REG0 STACK
  411. CALL print_bin
  412. ;; debug end
  413. ALU0 MEMHI
  414. ALU1 REG0
  415. MEMHI XOR
  416. .done:
  417. ;; debug
  418. STACK XOR
  419. REG0 '='
  420. CALL print_char
  421. REG0 STACK
  422. CALL print_bin
  423. CALL println
  424. ;; debug end
  425. REG0 STACK
  426. RET
  427. bin2digit:
  428. ; Converts U16 to digit
  429. ; Adopted from http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  430. ; Digit {reg1 reg0} Place in 10^n generalbuf
  431. ; Memory pointer must be set to generalbuf
  432. STACK 0
  433. .a:
  434. ALU0 REG1
  435. ALU1 LWHI
  436. BLT .c
  437. BGT .b
  438. ALU0 REG0
  439. ALU1 LWLO
  440. BLT .c
  441. .b:
  442. ALU0 REG0
  443. ALU1 LWLO
  444. REG0 SUB
  445. ALU0 REG1
  446. ALU1 LWHI
  447. REG1 SBC
  448. ALU0 STACK
  449. ALU1 1
  450. STACK ADD
  451. JUMP .a
  452. .c:
  453. SWLO REG0
  454. REG0 STACK
  455. SWHI REG0
  456. REG0 LWLO
  457. RET
  458. print_u16:
  459. ; Prints U16 in {reg1 reg0}
  460. STACK REG0
  461. STACK REG1
  462. MEMP generalbuf
  463. SWHI 10000@1
  464. SWLO 10000@0 ; 10000 in hex
  465. CALL bin2digit
  466. ALU0 48
  467. ALU1 LWHI
  468. STACK REG0
  469. REG0 ADD
  470. CALL print_char
  471. REG0 STACK
  472. SWHI 1000@1
  473. SWLO 1000@0
  474. CALL bin2digit
  475. ALU0 48
  476. ALU1 LWHI
  477. STACK REG0
  478. REG0 ADD
  479. CALL print_char
  480. REG0 STACK
  481. SWHI 0
  482. SWLO 100
  483. CALL bin2digit
  484. ALU0 48
  485. ALU1 LWHI
  486. STACK REG0
  487. REG0 ADD
  488. CALL print_char
  489. REG0 STACK
  490. ALU0 REG0
  491. ALU1 100
  492. REG1 MOD
  493. ALU1 10
  494. ALU0 REG0
  495. STACK MOD
  496. ALU1 MOD
  497. ALU0 REG1
  498. ALU0 SUB
  499. ALU1 10
  500. ALU0 DIV
  501. ALU1 48
  502. REG0 ADD
  503. CALL print_char
  504. ALU0 STACK
  505. ALU1 48
  506. REG0 ADD
  507. CALL print_char
  508. REG1 STACK
  509. REG0 STACK
  510. RET
  511. print_u8:
  512. ; print u8 in reg0
  513. ; a = 128%10 = 8
  514. ; a = 128%100 - a // 10 = 2
  515. ; a = 128%1000 - a // 100 = 1
  516. STACK REG1
  517. REG1 REG0
  518. ALU1 10
  519. ALU0 REG0
  520. ALU0 MOD ; ALU0 = reg0%10
  521. STACK ALU0
  522. REG0 ALU0
  523. ALU0 REG1
  524. BRPZ .p3,GE
  525. ALU1 100
  526. ALU0 REG1
  527. ALU0 MOD
  528. ALU1 STACK
  529. STACK ALU1
  530. ALU0 SUB
  531. ALU1 10
  532. ALU1 DIV
  533. STACK ALU1
  534. ALU0 REG1
  535. ALU1 100
  536. BRPZ .p2,GE
  537. ALU1 200
  538. BRPZ .p1,GE
  539. REG0 '2'
  540. CALL print_char
  541. JUMP .p2
  542. .p1:
  543. REG0 '1'
  544. CALL print_char
  545. .p2:
  546. ALU0 48
  547. ALU1 STACK
  548. REG0 ADD
  549. CALl print_char
  550. .p3:
  551. ALU0 48
  552. ALU1 STACK
  553. REG0 ADD
  554. CALl print_char
  555. REG0 REG1
  556. REG1 STACK
  557. RET
  558. print_bin:
  559. ; print reg0 as binary
  560. STACK REG0
  561. STACK REG1
  562. REG1 REG0 ; Making copy
  563. ALU0 0b1000_0000
  564. .start:
  565. ALU1 REG1
  566. STACK ALU0
  567. BRPZ .print0,AND
  568. .print1:
  569. REG0 '1'
  570. CALL print_char
  571. JUMP .end
  572. .print0:
  573. REG0 '0'
  574. CALL print_char
  575. .end:
  576. ALU1 1
  577. ALU0 STACK
  578. ALU0 SRL
  579. BRPZ .done,ALU0
  580. REG0 REG1
  581. JUMP .start
  582. .done:
  583. REG1 STACK
  584. REG0 STACK
  585. RET
  586. print_hex:
  587. ; prints reg0 as hex
  588. STACK REG0
  589. STACK REG1
  590. REG1 REG0
  591. ALU1 4
  592. ALU0 REG0
  593. ALU1 SRL
  594. ALU0 10
  595. BRPZ .p0,GT
  596. ALU0 48
  597. JUMP .p1
  598. .p0:
  599. ALU0 55
  600. .p1:
  601. REG0 ADD
  602. CALL print_char
  603. REG0 REG1
  604. ALU0 0b0000_1111
  605. ALU1 REG0
  606. ALU1 AND
  607. ALU0 10
  608. BRPZ .p2,GT
  609. ALU0 48
  610. JUMP .p3
  611. .p2:
  612. ALU0 55
  613. .p3:
  614. REG0 ADD
  615. CALL print_char
  616. REG1 STACK
  617. REG0 STACK
  618. RET
  619. println:
  620. STACK REG0
  621. REG0 LF
  622. CALL print_char
  623. REG0 CR
  624. CALL print_char
  625. REG0 STACK
  626. RET
  627. print_string:
  628. ; prints string in memory location {reg0, reg1}
  629. .st:
  630. MEM0 REG0
  631. MEM1 REG1
  632. BRPZ .end,LWHI
  633. COMA COM_UARTR
  634. BRP .loop0
  635. ALU0 COM_UART_RECV
  636. .loop0:
  637. ALU1 COMD
  638. ALU1 AND
  639. BRZ NE
  640. COMA COM_UARTW
  641. COMD LWHI
  642. BRPZ .end,LWLO
  643. COMA COM_UARTR
  644. BRP .loop1
  645. .loop1:
  646. ALU1 COMD
  647. ALU1 AND
  648. BRZ NE
  649. COMA COM_UARTW
  650. COMD LWLO
  651. ALU0 REG0
  652. ALU1 1
  653. REG0 ADD
  654. ALU1 ADDC
  655. ALU0 REG1
  656. REG1 ADD
  657. JUMP .st
  658. .end:
  659. RET
  660. print_char:
  661. ; prints char in reg0
  662. COMA COM_UARTR
  663. BRP .loop0
  664. ALU0 COM_UART_RECV
  665. .loop0:
  666. ALU1 COMD
  667. ALU1 AND
  668. BRZ NE
  669. COMA COM_UARTW
  670. COMD REG0
  671. RET
  672. read_char:
  673. ; waits for char and stores that in reg0
  674. COMA COM_UARTR
  675. ALU0 0b0000_1000
  676. BRP .loop
  677. .loop:
  678. ALU1 COMD
  679. BRZ AND
  680. COMA COM_UARTIN
  681. REG0 COMD
  682. RET