risc8.asm 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. %define COM_UARTF 0x03
  2. %define COM_UARTW 0x05
  3. %define COM_UARTR 0x04
  4. %define COM_LED 0x06
  5. %define COM_DIP 0x08
  6. %define COM_UARTIN 0x09
  7. %define NULL 0x000000
  8. %define LF 0x0a
  9. %define CR 0x0d
  10. %define LFCR 0x0a0d
  11. %define COM_UART_TRANS 0b0000_0001
  12. %define COM_UART_RECV 0b0000_0010
  13. %define COM_UART_ECHO 0b0000_0100
  14. %define COM_UART_RR 0b0000_1000 ; Read Ready
  15. section .data 2x3x8192
  16. intro_text DB 0x1B63,0x1B5B324A,0x1B5B34303B33313B316D,"GLaDOS v0.0",0x1B5B303B33323B34306D," starting..",LFCR,0
  17. eq1_text DB LFCR,"1) 0x1194 * 0x2710 = 0x",0
  18. eq2_text DB LFCR,"2) 3*2=",0
  19. eq3_text DB LFCR,"3) 3*2=",0
  20. initial_vt100 DB 0x1B,'c',0x1B,"[2J",0x1B,"[40;32m",0
  21. error_text DB LFCR,"Invalid operation: ",0
  22. error0 DB "Buffer is full",0
  23. mul16buf DBE 8
  24. generalbuf DBE 1
  25. termHiFlag DB 0x0000
  26. termBuff DB 10,0
  27. DBE 10
  28. mallocPointer DB 0
  29. section .text 1x2x4096
  30. setup
  31. CPY0 65432@1
  32. CPY1 65432@0
  33. CALL printU16
  34. ; Run init
  35. INTRE interrupt
  36. ;CALL read_char
  37. ;CALL print_char
  38. ;.echo
  39. ; JUMP .echo
  40. ; CALL read_char
  41. ; CALL print_char
  42. CPY1 intro_text@0
  43. CPY2 intro_text@1
  44. CALL print_msg
  45. ;CALL read_char
  46. ;CPY1 COM_UART_ECHO
  47. ;COM r1,COM_UARTF
  48. CPY1 eq1_text@0
  49. CPY2 eq1_text@1
  50. CALL print_msg
  51. CPY0 0x11 ; 4500
  52. CPY1 0x94
  53. CPY2 0x27 ; 10000
  54. CPY3 0x10
  55. CALL mulU16
  56. CALL printhex
  57. MOVE r0,r1
  58. CALL printhex
  59. MOVE r0,r2
  60. CALL printhex
  61. MOVE r0,r3
  62. CALL printhex
  63. CALL println
  64. loop
  65. CPY0 0
  66. PUSH r0
  67. CPY0 '>'
  68. CALL print_char
  69. CPY0 0x20 ; space
  70. CALL print_char
  71. ;.loop
  72. ; CALL read_char
  73. ; CALL print_char
  74. ; ;BEQ r2,0x0a,.start
  75. ; BEQ r0,0x0d,.error
  76. ; JUMP .loop
  77. ;.error
  78. ; CPY1 error_text@0
  79. ; CPY2 error_text@1
  80. ; CALL print_msg
  81. ; JUMP .start
  82. .read
  83. CALL read_char
  84. BGT r0,57,.readc0
  85. BGT r0,48,.readadd
  86. .readc0
  87. BEQ r0,0x0d,.done
  88. ;BEQ r0,0x20,.echo
  89. BEQ r0,0x08,.backspace
  90. BEQ r0,0x7F,.backspace
  91. BEQ r0,0x2A,.readadd ; *
  92. BEQ r0,0x2B,.readadd ; +
  93. BEQ r0,0x2D,.readadd ; -
  94. BEQ r0,0x2F,.readadd ; /
  95. JUMP .read
  96. .backspace
  97. ; POP r1
  98. ; BEQ r1,0,.backspaceCheck
  99. ; CPY0 0x1B
  100. ; CALL print_char
  101. ; CPY0 'c'
  102. ; CALL print_char
  103. ; JUMP .read
  104. ;.backspaceCheck
  105. ; PUSH r1
  106. JUMP .read
  107. .readadd
  108. LWLO r3,termHiFlag
  109. BZ r3,.readadd0
  110. JUMP .readstore
  111. .readadd0
  112. CPY3 1
  113. SWHI r0
  114. SWLO r3,termHiFlag
  115. JUMP .echo
  116. .readstore
  117. CPY2 0
  118. LWHI r3,termHiFlag
  119. SWLO r2,termHiFlag
  120. MOVE r2,r0
  121. CPY0 termBuff@0
  122. CPY1 termBuff@1
  123. CALL arrayPush
  124. ; Check if buffer overflow
  125. BZ r0,.readstore0
  126. MOVE r0,r2
  127. JUMP .echo
  128. .readstore0
  129. MOVE r0,r2
  130. BZ r1,.error0
  131. .echo
  132. CALL print_char
  133. JUMP .read
  134. .done
  135. ; if odd number of chars, push r0, 0 to array
  136. LWLO r3,termHiFlag
  137. BZ r3,.doneC
  138. ;LWHI r2,termHiFlag
  139. ;CPY3 0
  140. ;CPY0 termBuff@0
  141. ;CPY1 termBuff@1
  142. ;CALL arrayPush
  143. .doneC
  144. CPY1 termBuff@0
  145. CPY2 termBuff@1
  146. CALL Process
  147. CPY0 termBuff@0
  148. CPY1 termBuff@1
  149. CALL arrayClear
  150. JUMP loop
  151. .done0
  152. POP r0
  153. BEQ r0,0,.done1
  154. CALL print_char
  155. JUMP .done0
  156. .done1
  157. CALL println
  158. JUMP loop
  159. .error0
  160. CALL println
  161. CPY1 error0@0
  162. CPY2 error0@1
  163. CALL print_msg
  164. CALL println
  165. JUMP loop
  166. MOVE r1,r0
  167. SUBI r1,48
  168. CALL print_char
  169. CALL read_char
  170. MOVE r2,r0
  171. CALL print_char
  172. CALL read_char
  173. MOVE r3,r0
  174. SUBI r3,48
  175. CALL print_char
  176. BEQ r2,'+',.add
  177. BEQ r2,'-',.sub
  178. JUMP .invalid
  179. .add
  180. ADD r1,r3
  181. JUMP .result
  182. .sub
  183. SUB r1,r3
  184. JUMP .result
  185. .invalid
  186. CPY1 error_text@0
  187. CPY2 error_text@1
  188. CALL print_msg
  189. JUMP .done
  190. .result
  191. PUSH r1
  192. CPY0 '='
  193. CALL print_char
  194. POP r0
  195. ADDI r0,48
  196. CALL print_char
  197. Process
  198. ; Input array *{r2 r1}
  199. ;CPY1 termBuff@0
  200. ;CPY2 termBuff@1
  201. .readnext
  202. INC r1
  203. ADDC r2
  204. CI1 r2
  205. CI0 r1
  206. SWLO r0,NULL
  207. .isdigit
  208. ;BGT r0,57,.issymbol
  209. ;BGT r0,48,.digit
  210. .issymbol
  211. ;JUMP .error
  212. .digit
  213. ;CI1 r2
  214. ;CI0 r1
  215. ;SWHI r0
  216. .error
  217. CPY1 error_text@0
  218. CPY2 error_text@1
  219. CALL print_msg
  220. CPY1 termBuff@0
  221. CPY2 termBuff@1
  222. INC r1
  223. ADDC r2
  224. CALL print_msg
  225. .end
  226. CALL println
  227. RET
  228. printbin
  229. ; print r0 as binary
  230. PUSH r2
  231. PUSH r1
  232. CPY2 0b1000_0000
  233. MOVE r1,r0
  234. .start
  235. AND r0,r2
  236. BZ r0,.print0
  237. .print1
  238. CPY0 '1'
  239. CALL print_char
  240. JUMP .end
  241. .print0
  242. CPY0 '0'
  243. CALL print_char
  244. .end
  245. SRL r2,1
  246. BZ r2,.done
  247. MOVE r0,r1
  248. JUMP .start
  249. .done
  250. POP r1
  251. POP r2
  252. RET
  253. printhex
  254. ; print r0 as hex
  255. PUSH r0
  256. PUSH r1
  257. MOVE r1,r0
  258. SRL r0,4
  259. BGT r0,9,.p0
  260. ADDI r0,48
  261. JUMP .p1
  262. .p0
  263. ADDI r0,55
  264. .p1
  265. CALL print_char
  266. MOVE r0,r1
  267. POP r1
  268. ANDI r0,0b0000_1111
  269. BGT r0,9,.p2
  270. ADDI r0,48
  271. JUMP .p3
  272. .p2
  273. ADDI r0,55
  274. .p3
  275. CALL print_char
  276. POP r0
  277. RET
  278. ;.done
  279. ;; Equation 1
  280. ;CPY1 eq1_text@0
  281. ;CPY2 eq1_text@1
  282. ;CALL print_msg
  283. ;CPY0 3
  284. ;ADDI r0,2
  285. ;ADDI r0,48 ; Convert to ascii
  286. ;CALL print_char
  287. ;
  288. ;; Equation 2
  289. ;CPY1 eq2_text@0
  290. ;CPY2 eq2_text@1
  291. ;CALL print_msg
  292. ;CPY0 6
  293. ;SUBI r0,2
  294. ;ADDI r0,48 ; Convert to ascii
  295. ;CALL print_char
  296. ;; Equation 3
  297. ;CPY1 eq3_text@0
  298. ;CPY2 eq3_text@1
  299. ;CALL print_msg
  300. ;CPY0 3
  301. ;CPY1 2
  302. ;MUL r0,r1
  303. ;ADDI r0,48 ; Convert to ascii
  304. ;CALL print_char
  305. ;
  306. ;CPY1 eq3x_text@0
  307. ;CPY2 eq3x_text@1
  308. ;CALL print_msg
  309. ;GETAH r0
  310. ;ADDI r0,48 ; Convert to ascii
  311. ;CALL print_char
  312. ;; Equation 4
  313. ;CPY1 eq4_text@0
  314. ;CPY2 eq4_text@1
  315. ;CALL print_msg
  316. ;CPY0 9
  317. ;CPY1 2
  318. ;DIV r0,r1
  319. ;ADDI r0,48 ; Convert to ascii
  320. ;CALL print_char
  321. ;; Equation 5
  322. ;CPY1 eq5_text@0
  323. ;CPY2 eq5_text@1
  324. ;CALL print_msg
  325. ;GETAH r0
  326. ;ADDI r0,48 ; Convert to ascii
  327. ;CALL print_char
  328. ;CALL println
  329. ;JUMP .start
  330. ;CPY3 0
  331. start
  332. INC r3
  333. JUMP start
  334. interrupt
  335. PUSH r0
  336. GETIF r0
  337. POP r0
  338. RETI
  339. println
  340. PUSH r0
  341. CPY0 LF
  342. CALL print_char
  343. CPY0 CR
  344. CALL print_char
  345. POP r0
  346. RET
  347. mulU16
  348. ; Multiply 2 unsigned 16-bit int
  349. ; {r0 r1} * {r2 r3}
  350. ; A B * X Y
  351. ; Result:
  352. ; r3 = BY0
  353. ; r2 = BY1+BX0+AY0
  354. ; r1 = BX1+AY1+AX0
  355. ; r0 = AX1
  356. ; Carryout must be included to higher bytes
  357. PUSH r3
  358. MUL r3,r1 ; BY0
  359. SWHI r3
  360. GETAH r3 ; BY1
  361. SWLO r3,mul16buf
  362. POP r3 ; Buffer = [BY0 BY1]
  363. PUSH r2
  364. MUL r2,r1 ; BX0
  365. SWHI r2
  366. GETAH r2 ; BX1
  367. SWLO r2,mul16buf+1
  368. POP r2 ; Buffer = [BY0 BY1 BX0 BX1]
  369. PUSH r3
  370. MUL r3,r0 ; AY0
  371. SWHI r3
  372. GETAH r3 ; AY1
  373. SWLO r3,mul16buf+2
  374. POP r3 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1]
  375. PUSH r2
  376. MUL r2,r0 ; AX0
  377. SWHI r2
  378. GETAH r2 ; AX1
  379. SWLO r2,mul16buf+3
  380. POP r2 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1 AX0 AX1]
  381. ; { 0 } { 1 } { 2 } { 3 }
  382. ; r3 will be used as spare register as it's equal to BY0
  383. LWLO r2,mul16buf ; r2=BY1
  384. LWLO r1,mul16buf+1 ; r1=BX1
  385. LWLO r0,mul16buf+3 ; r0=AX1
  386. LWHI r3,mul16buf+1 ; t=BX0
  387. ADD r2,r3
  388. ADDC r1
  389. ADDC r0
  390. LWHI r3,mul16buf+2 ; t=AY0
  391. ADD r2,r3
  392. ADDC r1
  393. ADDC r0
  394. LWLO r3,mul16buf+2 ; t=AY1
  395. ADD r1,r3
  396. ADDC r0
  397. LWHI r3,mul16buf+3 ; t=AX0
  398. ADD r1,r3
  399. ADDC r0
  400. LWHI r3,mul16buf ; r3=BY0
  401. RET
  402. bin2digit
  403. ; Converts U16 to digit
  404. ; Adopted from http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
  405. ; Digit {r0 r1}, Place in 10^n {r2 r3}
  406. PUSH r0
  407. CPY0 0
  408. SWLO r0,generalbuf ; Using general buf to store number
  409. POP r0
  410. .a
  411. CI2 r0
  412. BGT r2,0,.c ; MSB is smaller than digit
  413. CI2 r2
  414. BGT r0,0,.b ; MSB is grater than digit
  415. CI2 r1
  416. BGT r3,0,.c ; LSB is smaller than digit
  417. .b
  418. PUSH r0
  419. LWLO r0,generalbuf
  420. INC r0
  421. SWLO r0,generalbuf
  422. POP r0
  423. SUB r0,r2
  424. SUB r1,r3
  425. SUBC r0
  426. JUMP .a
  427. .c
  428. LWLO r2,generalbuf
  429. RET
  430. printU16
  431. ; print unsigned 16bit int as base-10 digit
  432. ; arguments: digit {r0, r1}
  433. PUSH r0
  434. PUSH r1
  435. PUSH r2
  436. PUSH r3
  437. CPY2 10000@1
  438. CPY3 10000@0
  439. CALL bin2digit
  440. MOVE r3,r0
  441. MOVE r0,r2
  442. ADDI r0,48 ; Convert to ascii digit
  443. CALL print_char
  444. MOVE r0,r3
  445. CPY2 1000@1
  446. CPY3 1000@0
  447. CALL bin2digit
  448. MOVE r3,r0
  449. MOVE r0,r2
  450. ADDI r0,48 ; Convert to ascii digit
  451. CALL print_char
  452. MOVE r0,r3
  453. CPY2 0
  454. CPY3 100
  455. CALL bin2digit
  456. MOVE r0,r2
  457. ADDI r0,48 ; Convert to ascii digit
  458. CALL print_char
  459. MOVE r0,r1
  460. CALL printU8
  461. POP r3
  462. POP r2
  463. POP r1
  464. POP r0
  465. RET
  466. printU8
  467. ; Assuing number is 128
  468. ; a = 128%10 = 8
  469. ; a = 128%100 - a // 10 = 2
  470. ; a = 128%1000 - a // 100 = 1
  471. ; in case of 8bit number quicker is to do 2 if statements for 100s
  472. ; input argument is in r0
  473. PUSH r0
  474. PUSH r1
  475. PUSH r2
  476. PUSH r3
  477. CPY2 10
  478. MOVE r1,r0
  479. DIV r1,r2
  480. GETAH r1
  481. PUSH r1 ; Stored last digit
  482. BGE r0,10,.ge10
  483. JUMP .p3
  484. .ge10
  485. CPY2 100
  486. MOVE r3,r0
  487. DIV r3,r2
  488. GETAH r3
  489. SUB r3,r1
  490. CPY2 10
  491. DIV r3,r2
  492. PUSH r3 ; Stored middle digit
  493. BGE r0,100,.ge100
  494. JUMP .p2
  495. .ge100
  496. CPY2 200
  497. CI2 r2
  498. BGE r0,0,.s2
  499. CPY2 100
  500. CI2 r2
  501. BGE r0,0,.s1
  502. JUMP .p2
  503. .s1 CPY0 '1'
  504. JUMP .p0
  505. .s2 CPY0 '2'
  506. .p0 CALL print_char
  507. .p2
  508. POP r0
  509. ADDI r0,48
  510. CALL print_char
  511. .p3
  512. POP r0
  513. ADDI r0,48
  514. CALL print_char
  515. POP r3
  516. POP r2
  517. POP r1
  518. POP r0
  519. RET
  520. arrayClear
  521. ; Clear array at *{r1 r0}
  522. PUSH r2
  523. CI1 r1
  524. CI0 r0
  525. LWHI r2,NULL
  526. SWHI r2
  527. CPY2 0
  528. CI1 r1
  529. CI0 r0
  530. SWLO r2,NULL
  531. POP r2
  532. RET
  533. arrayPush
  534. ; Push to array *{r1 r0} value {r3 r2}
  535. ; If full, changes r1 r0 to 0x0000
  536. PUSH r2
  537. PUSH r3
  538. CI1 r1
  539. CI0 r0
  540. LWLO r2,NULL
  541. CI1 r1
  542. CI0 r0
  543. LWHI r3,NULL ; Stores cap
  544. ; r2=size, r3=cap
  545. CI2 r3
  546. BGE r2,0xFF,.full
  547. INC r2
  548. SWHI r3
  549. CI1 r1
  550. CI0 r0
  551. SWLO r2,NULL
  552. ADD r0,r2
  553. ADDC r1
  554. POP r3
  555. SWHI r3
  556. POP r2
  557. CI1 r1
  558. CI0 r0
  559. SWLO r2,NULL
  560. RET
  561. .full
  562. POP r3
  563. POP r2
  564. CPY0 0
  565. CPY1 0
  566. RET
  567. arrayPop
  568. ; Pop from array *{r1 r0} value {r3 r2}
  569. ; If empty, changes all regs to 0x00
  570. CI1 r1
  571. CI0 r0
  572. LWLO r2,NULL
  573. BEQ r2,0,.empty
  574. DEC r2
  575. CI1 r1
  576. CI0 r0
  577. SWLO r2,NULL
  578. INC r2
  579. ADD r0,r2
  580. ADDC r1
  581. CI1 r1
  582. CI0 r0
  583. LWHI r3,NULL
  584. CI1 r1
  585. CI0 r0
  586. LWLO r2,NULL
  587. RET
  588. .empty
  589. CPY3 0
  590. CPY2 0
  591. CPY1 0
  592. CPY0 0
  593. RET
  594. read_char ; read char to r0
  595. COM r0,COM_UARTR
  596. ANDI r0,0b0000_1000
  597. BZ r0,read_char
  598. COM r0,COM_UARTIN
  599. RET
  600. malloc ; returns memory free memory locaion
  601. ; r0 = size to allocate
  602. ; {r2, r1} memory pointer
  603. LWHI r2,mallocPointer
  604. LWLO r1,mallocPointer
  605. PUSH r2
  606. PUSH r1
  607. ADD r1,r0
  608. ADDC r2
  609. SWHI r2
  610. SWLO r1,mallocPointer
  611. POP r1
  612. POP r2
  613. RET
  614. print_msg ; print value in mem pinter {r2 r1}
  615. PUSH r0
  616. .loop
  617. CI1 r2
  618. CI0 r1
  619. LWHI r0,NULL
  620. BZ r0,.end
  621. CALL print_char
  622. CI1 r2
  623. CI0 r1
  624. LWLO r0,NULL
  625. BZ r0,.end
  626. CALL print_char
  627. INC r1
  628. ADDC r2
  629. JUMP .loop
  630. .end
  631. POP r0
  632. RET
  633. print_char ; print value in r0
  634. PUSH r0
  635. .loop
  636. COM r0,COM_UARTR
  637. ANDI r0,0b0000_0010
  638. XORI r0,0b0000_0010 ; invert
  639. BZ r0,.loop
  640. POP r0
  641. COM r0,COM_UARTW
  642. RET