| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464 |
- %define COM_UARTF 0x03
- %define COM_UARTW 0x05
- %define COM_UARTR 0x04
- %define COM_LED 0x06
- %define COM_DIP 0x08
- %define COM_UARTIN 0x09
- %define LF 0x0a
- %define CR 0x0d
- %define LFCR 0x0a0d
- %define COM_UART_TRANS 0b0000_0001
- %define COM_UART_RECV 0b0000_0010
- %define COM_UART_ECHO 0b0000_0100
- %define COM_UART_RR 0b0000_1000 ; Read Ready
- %macro MEMP 1
- MEM1 %1@1
- MEM0 %1@0
- %endmacro
- %macro BRP 1
- BR1 %1@1
- BR0 %1@0
- %endmacro
- %macro RET 0
- BR0 STACK
- BR1 STACK
- BRZ NULL
- %endmacro
- %macro CALL 1
- BRP %1
- STACK %%return@1
- STACK %%return@0
- BRZ NULL
- %%return:
- %endmacro
- %macro JUMP 1
- BRP %1
- BRZ NULL
- %endmacro
- %macro BRPZ 2
- BRP %1
- BRZ %2
- %endmacro
- %macro PRINTMEM 0
- STACK REG0
- REG0 LWHI
- CALL print_hex
- REG0 LWLO
- CALL print_hex
- REG0 0x20
- CALL print_char
- REG0 STACK
- %endmacro
- %macro PRINTREG 0
- STACK REG0
- STACK REG0
- REG0 REG1
- CALL print_hex
- REG0 STACK
- CALL print_hex
- REG0 0x20
- CALL print_char
- REG0 STACK
- %endmacro
- %macro PRINTREGLN 0
- STACK REG0
- STACK REG0
- REG0 REG1
- CALL print_hex
- REG0 STACK
- CALL print_hex
- ;REG0 0x20
- ;CALL print_char
- ;REG0 LWHI
- ;CALL print_hex
- ;REG0 LWLO
- ;CALL print_hex
- CALL println
- REG0 STACK
- %endmacro
- ; ==================
- ; Jump on conditions
- ; ==================
- %macro BGT 1
- BRPZ %1,LE
- %endmacro
- %macro BLT 1
- BRPZ %1,GE
- %endmacro
- %macro BGE 1
- BRPZ %1,LT
- %endmacro
- %macro BLE 1
- BRPZ %1,GT
- %endmacro
- %macro BEQ 1
- BRPZ %1,NE
- %endmacro
- %macro BNE 1
- BRPZ %1,EQ
- %endmacro
- %macro CALC_SIEVE_POINTER 4
- ; args: [value of n] [shifted value to store to] [jump label] [debug letter]
-
- ;; start debug
- ;STACK REG0
- ;REG0 %4
- ;CALL print_char
- ;REG0 STACK
- ;STACK REG0
- ;REG0 %1
- ;CALL print_u8
- ;REG0 0x20
- ;CALL print_char
- ;REG0 STACK
- ;; stop debug
- ALU0 %1
- STACK ALU0
- ALU1 16
- ALU0 DIV
- ;ALU1 sieve2@0
- MEM0 ADD
- ;ALU0 sieve2@1
- ALU1 0x00
- MEM1 ADC ; Memory pointer ready
- ALU0 STACK
- ALU1 16
- ALU1 MOD
- ALU0 1
- %2 SLL
- ALU0 8 ; if n%16 >= 8
- BGE %3 ; is high byte memhi
- %endmacro
- %macro COPY 1 ; copy current pointer to memory %1
- STACK MEMLO
- STACK MEMHI
- MEMP %1
- ALU0 STACK ; can't use 2 memory operations at once.
- MEMHI ALU0
- ALU0 STACK
- MEMLO ALU0
- %endmacro
- section .data depth=4096,width=2
- DBE 1
- intro_text: DB "\x1Bc\x1B[2J\x1B[HBooting \x1B[1m\x1B[36mOISC\x1B[0m system\r\n",0
- generalbuf: DBE 1
- generalbuf2: DBE 1
- generalbuf3: DBE 1
- sieve_x: DBE 1
- sieve_x2: DBE 1
- sieve_y: DBE 1
- sieve_y2: DBE 1
- sieve1: DBE 1
- sieve_arr: DBE 16
- memend: DBE 1
- section .text depth=3072,width=2,bin_width=13,parity=2,fill_bits=27648
- REG0 intro_text@0
- REG1 intro_text@1
- CALL print_string
- ;; test mul_u16
- ;MEMP generalbuf
- ;MEMLO 60059@0 ; num1 lo
- ;MEMHI 60059@1 ; num1 hi
- ;MEMP generalbuf2
- ;MEMLO 60 ; num1 lo
- ;MEMHI 0 ; num1 hi
- ;CALL div_u16
- ;STACK REG0
- ;STACK REG1
- ;MEMP generalbuf3
- ;REG0 MEMLO
- ;REG1 MEMHI
- ;CALL print_u16
- ;REG0 '.'
- ;CALL print_char
- ;REG1 STACK
- ;REG0 STACK
- ;CALL print_u16
- ;JUMP forever
- ;REG0 MEMLO
- ;CALL print_hex
- ;REG0 MEMHI
- ;CALL print_hex
- ;ALU0 0x44
- ;ALU1 0x44
- ;REG0 NE
- ;CALL print_hex
- ;ALU0 0x33
- ;ALU1 0x00
- ;REG0 NE
- ;CALL print_hex
- ;CALL println
- ;MEMP memend
- ;MEMLO 0x04
- REG0 '@'
- CALL print_char
- CALL clean_ram
- REG0 '@'
- CALL print_char
- CALL calc_sieve
- REG0 '@'
- CALL print_char
- ;JUMP forever
- CALL println
- REG0 0
- REG1 0
- .print_sieve:
- ; Set memory pointer
- ALU0 memend@0
- ALU1 REG0
- MEM0 ADD
- ALU0 memend@1
- ALU1 REG1
- MEM1 ADC
- ; check for overflow
- ALU0 MEM1
- ALU1 0x0e
- BGT .done
-
- STACK REG0
- STACK REG1
- BR0 MEMHI
- STACK BR0
- BR0 MEMLO
- STACK BR0
- ; now is loop for every bit in memory
- MEMP generalbuf3
- MEMLO 16
- MEMHI 0
- CALL mul_u16
-
- BR0 STACK
- MEMLO BR0
-
- MEMHI 1
- .print_loop0:
- ALU0 MEMHI
- ALU1 MEMLO
- BRPZ .z0,AND
- ;; This number is prime
-
- CALL print_u16
- CALL println
- MEMP generalbuf3
- ;PRINTREG
- ;JUMP .d0
- .z0:
- ;CALL print_u16
- ;PRINTREG
- ;; This number is not prime
- .d0:
- ALU1 1
- ALU0 MEMHI
- MEMHI SLL
- ALU0 REG0
- REG0 ADD
- ALU0 REG1
- ALU1 0
- REG1 ADC
- BRPZ .print_loop0e,MEMHI
- JUMP .print_loop0
- .print_loop0e:
- BR0 STACK
- MEMLO BR0
- MEMHI 1
- ;PRINTREG
- .print_loop1:
- ALU0 MEMHI
- ALU1 MEMLO
- BRPZ .z1,AND
- ;; This number is prime
- CALL print_u16
- CALL println
- MEMP generalbuf3
- JUMP .d1
- .z1:
- ;PRINTREG
- ;CALL print_u16
- ;; This number is not prime
- .d1:
- ALU1 1
- ALU0 MEMHI
- MEMHI SLL
- BRPZ .print_loop1e,MEMHI
- ALU0 REG0
- REG0 ADD
- ALU0 REG1
- ALU1 0
- REG1 ADC
- JUMP .print_loop1
- .print_loop1e:
- REG1 STACK
- REG0 STACK
- ALU0 REG0
- ALU1 1
- REG0 ADD
- ALU0 REG1
- ALU1 0
- REG1 ADC
- JUMP .print_sieve
- .done:
- REG0 '@'
- CALL print_char
- JUMP forever
- .hi:
- ALU0 MEMHI
- .next:
- ALU1 REG1
- BRPZ .noprint,AND
- STACK REG0
- CALL print_u8
- REG0 0x20
- CALL print_char
- REG0 STACK
- .noprint:
- ALU1 1
- ALU0 REG0
- REG0 ADD
- BRPZ forever,REG0
- JUMP .print_sieve
- ; REG0 0
- ;hex_test:
- ; ALU0 REG0
- ; ALU1 1
- ; REG0 ADD
- ; CALL print_hex
- ; REG1 REG0
- ; REG0 0x20
- ; CALL print_char
- ; REG0 REG1
- ; BRPZ .end,REG0
- ; JUMP hex_test
- ;.end:
- forever:
- JUMP forever
- clean_ram:
- MEMP memend
- .loop:
- MEMLO 0x00
- MEMHI 0x00
- ALU0 1
- ALU1 MEM0
- MEM0 ADD
- ALU0 0
- ALU1 MEM1
- MEM1 ADC
- ALU0 MEM1
- ALU1 0x0e
- BGT .done
- JUMP .loop
- .done:
- RET
- log2n_u8:
- ;; Only for 2^n numbers
- REG1 0
- ALU1 1
- .loop:
- BRPZ .done,REG0
- ALU0 REG0
- REG0 SRL
- ALU0 REG1
- REG1 ADD
- JUMP .loop
- .done:
- RET
-
- mod_u16:
- ;; Russian Peasant Multiplication
- ;; https://stackoverflow.com/questions/2566010
- ;; {reg1,reg0} = {reg1,reg0} % *generalbuf{memhi,memlo}
- %def $a0,REG0
- %def $a1,REG1
- %def $b0,MEMLO
- %def $b1,MEMHI
- %def $x0,MEMLO
- %def $x1,MEMHI
-
- COPY generalbuf2
- ; X = B
- STACK $a0
- STACK $a1
- ALU0 $a1 ; \
- ALU1 1 ; |
- $a1 SRL ; |
- ALU0 $a0 ; | A >> 1 (divide by 2)
- STACK ROR ; |
- ALU0 SRL ; |
- ALU1 STACK; |
- $a0 OR ; /
- ; Do while (X <= A/2)
- .while_a_start:
- ALU0 $x1
- ALU1 $a1
- BGT .while_a_end
- BLT .while_a_0
- ALU0 $x0
- ALU1 $a0
- BGE .while_a_end
- .while_a_0:
- ALU0 $x0 ; \
- ALU1 1 ; |
- $x0 SLL ; |
- STACK ROL ; | x <<= 1
- ALU0 $x1 ; |
- ALU0 SLL ; |
- ALU1 STACK ; |
- $x1 OR ; /
- JUMP .while_a_start
- .while_a_end:
- $a1 STACK
- $a0 STACK ; restore a
- .while_b_start:
- MEMP generalbuf
- ;PRINTREG
- ; Do while (A >= B)
- ALU0 $a1
- ALU1 $b1
- BLT .while_b_end
- BGT .while_b_0
- ALU0 $a0
- ALU1 $b0
- BLT .while_b_end
- .while_b_0:
- MEMP generalbuf2
- ; Check if A >= X
- ALU0 $a1
- ALU1 $x1
- BLT .next
- BGT .a_ge_x
- ALU0 $a0
- ALU1 $x0
- BLT .next
- .a_ge_x:
- ;PRINTREG
- ALU0 $a0
- ALU1 $x0
- $a0 SUB ; \
- ALU0 $a1 ; | A -= X
- ALU1 $x1 ; |
- $a1 SBC ; /
- .next:
- ; X >>= 1
- ALU0 $x1
- ALU1 1
- $x1 SRL
- STACK ROR
- ALU0 $x0
- ALU0 SRL
- ALU1 STACK
- $x0 OR
- BRPZ .check_null,$x1
- ; Back to while loop
- JUMP .while_b_start
- .check_null:
- BRPZ .while_b_end,$x0
- JUMP .while_b_start
- .while_b_end:
- RET
- %macro SLL16 3
- ALU0 %2
- ALU1 %1 ; multiply by 2
- %2 SLL
- STACK ROL
- ALU0 %3 ; multiply by 2 with carry
- ALU0 SLL
- ALU1 STACK
- %3 OR
- %endmacro
- div_u16:
- ;; Divide 16bit by 16bit (can be expanded)
- ;; source: https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder
- ;; generalbuf3 = generalbuf / generalbuf2; reg1,reg0 => reminder
- %def $Nl,MEMLO ; \
- %def $Nh,MEMHI ; / generalbuf
- %def $Dl,MEMLO ; \
- %def $Dh,MEMHI ; / generalbuf2
- %def $Ql,MEMLO ; \
- %def $Qh,MEMHI ; / generalbuf3
- %def $Rl,REG0
- %def $Rh,REG1
-
- $Rl 0
- $Rh 0
- MEMP generalbuf3
- MEMLO 0
- MEMHI 0
- STACK 0b1000_0000 ; put 0
- .for_start0:
- SLL16 1,$Rl,$Rh
- ;; Finding N(i)
- ALU0 STACK
- STACK ALU0
- MEMP generalbuf
- ALU1 $Nh
- BRPZ .z0,AND ; Nl & i == 0
- ALU0 0b0000_0001
- ALU1 $Rl
- $Rl OR ; R(0) = N(i) = 1
- JUMP .check0
- .z0:
- ALU0 0b1111_1110
- ALU1 $Rl
- $Rl AND ; R(0) = N(i) = 0
- .check0: ; if R >= D
- MEMP generalbuf2
- ALU0 $Rh
- ALU1 $Dh
- BLT .for_end0
- BGT .sub0
- ALU0 $Rl
- ALU1 $Dl
- BLT .for_end0
- .sub0:
- ALU0 $Rl
- ALU1 $Dl
- $Rl SUB
- ALU0 $Rh
- ALU1 $Dh
- $Rh SBC
- MEMP generalbuf3
- ALU0 $Qh ; Q(i) = 1
- ALU1 STACK
- STACK ALU1
- $Qh OR
- .for_end0:
- ALU0 STACK
- ALU1 1
- ALU0 SRL
- BRPZ .done0,ALU0
- STACK ALU0
- JUMP .for_start0
- .done0:
- STACK 0b1000_0000 ; put 0
- .for_start1:
- SLL16 1,$Rl,$Rh
- ;; Finding N(i)
- ALU0 STACK
- STACK ALU0
- MEMP generalbuf
- ALU1 $Nl
- BRPZ .z1,AND
- ALU0 0b0000_0001
- ALU1 $Rl
- $Rl OR ; R(0) = N(i) = 1
- JUMP .check1
- .z1:
- ALU0 0b1111_1110
- ALU1 $Rl
- $Rl AND ; R(0) = N(i) = 0
- .check1: ; if R >= D
- MEMP generalbuf2
- ALU0 $Rh
- ALU1 $Dh
- BLT .for_end1
- BGT .sub1
- ALU0 $Rl
- ALU1 $Dl
- BLT .for_end1
- .sub1:
- ALU0 $Rl
- ALU1 $Dl
- $Rl SUB
- ALU0 $Rh
- ALU1 $Dh
- $Rh SBC
- MEMP generalbuf3
- ALU0 $Ql ; Q(i) = 1
- ALU1 STACK
- STACK ALU1
- $Ql OR
- .for_end1:
- ALU0 STACK
- ALU1 1
- ALU0 SRL
- BRPZ .done1,ALU0
- STACK ALU0
- JUMP .for_start1
- .done1:
- RET
-
- ;div_u16:
- ;; Divide 16bit number by 8bit
- ;; Insparation taken from:
- ;; http://www.avr-asm-tutorial.net/avr_en/calc/DIV8E.html
- ;
- ; %def $rd1l,MEMLO
- ; %def $rd1h,MEMHI
- ; %def $rd2,REG0
- ; %def $rd1u,REG1
- ; %def $rel,MEMLO
- ; %def $reh,MEMHI
- ;
- ; $rd1u 0
- ; MEMP generalbuf2
- ; $rel 1
- ; $reh 0
- ;.div8a:
- ; MEMP generalbuf
- ; ALU0 1
- ; ALU1 $rd1l ; multiply by 2
- ; $rd1l SLL
- ; STACK ROL
- ;
- ; ALU1 $rd1h ; multiply by 2 with carry
- ; ALU1 SLL
- ; ALU0 STACK
- ; $rd1h OR
- ; STACK ROL
- ;
- ; ALU0 1
- ; ALU1 $rd1u
- ; ALU1 SLL
- ; ALU0 STACK
- ; $rd1u OR
- ; ALU0 0
- ; ALU1 ROL
- ; BNE .div8b
- ; ALU0 $rd1u
- ; ALU1 $rd2
- ; $rd1u SUB
- ; ALU1 SUBC
- ; ALU0 0
- ; BNE .div8c
- ;.div8b:
- ; ALU0 $rd1u
- ; ALU1 $rd2
- ; $rd1u SUB
- ; STACK 1
- ; JUMP .div8d
- ;.div8c:
- ; STACK 0
- ;.div8d:
- ; MEMP generalbuf2
- ; ALU0 1
- ; ALU1 $rel
- ; ALU0 SLL
- ; ALU1 STACK
- ; $rel OR
- ; STACK ROL
- ;
- ; ALU0 1
- ; ALU1 $reh
- ; ALU0 SLL
- ; ALU1 STACK
- ; $reh OR
- ; BRP .div8a
- ; BRZ ROL
- ;.done:
- ; RET
- calc_sieve:
- ; Sieve of Atkin
- %def $xl,MEMLO
- %def $xh,MEMHI
- %def $x2l,REG0
- %def $x2h,REG1
- %def $yl,MEMLO
- %def $yh,MEMHI
- %def $y2l,REG0
- %def $y2h,REG1
-
- ; loop x setup
- MEMP sieve_x
- $xl 1 ;
- $xh 0 ; x=1
- .loopx:
- COPY sieve_x2 ; temp copy x to x2
- REG0 $xl
- REG1 $xh
- CALL mul_u16
-
- ALU1 0
- ALU0 MEMHI
- BRP .endp1
- BRZ EQ ; if x^2 >= 2^16
- ALU0 MEMLO
- BRZ EQ ; if x^2 >= 2^16
- MEMHI REG1
- MEMLO REG0
- ; loop y setup
- MEMP sieve_y
- $yl 1 ;
- $yh 0 ; y=1
- .loopy:
- COPY sieve_y2 ; temp copy y to y2
- REG0 $yl
- REG1 $yh
- CALL mul_u16
- ALU1 0
- ALU0 MEMHI
- BRP .loopxe
- BRZ EQ ; if y^2 >= 2^16
- ALU0 MEMLO
- BRZ EQ ; if y^2 >= 2^16
- MEMHI REG1
- MEMLO REG0
- ; ==================
- ; Start of Main loop
- ; ==================
- ;MEMP sieve1
-
- %def $nh,REG1
- %def $nl,REG0
-
- ;MEMP sieve_y2
- ;PRINTMEM
- ;CALL println
- .c1:
- MEMP sieve_x2
- COPY sieve1 ; copy x^2 to n
- REG0 4
- REG1 0
- CALL mul_u16 ; x^2 * 0x0004
- ALU0 MEMHI; \
- ALU1 0 ; |
- BRP .c2 ; | checking if 4*x^2 overflow
- BRZ EQ ; |
- ALU0 MEMLO; |
- BRZ EQ ; /
- ; n += y^2
- ;$nl MEMLO
- ;$nh MEMHI
- MEMP sieve_y2
- ALU0 $nl ; $nl
- ALU1 MEMLO ; $y2l
- $nl ADD
- ALU0 $nh
- ALU1 MEMHI ; $y2h
- $nh ADC
- ALU0 ADDC ; \
- ALU1 0 ; | check for 4*x^2+y^2 oveflow
- BNE .c2 ; /
- ;CALL print_u16
- ;STACK REG0
- ;REG0 0x20
- ;CALL print_char
- ;REG0 STACK
- MEMP sieve1 ; \
- MEMLO $nl ; | save n to sieve1
- MEMHI $nh ; /
- ; checkinf for n%12 == 1 || n%12 == 5
- MEMP generalbuf
- MEMHI 0
- MEMLO 12 ; storing 12
- CALL mod_u16 ; n = n%12
- ALU0 0
- ALU1 $nh ; if n%12 high byte != 0
- BNE .c2
- ALU0 1 ; if n%12 == 1
- ALU1 $nl
- BEQ .c1x
- ALU0 5 ; if n%12 == 5
- BNE .c2
- .c1x:
- ; call sieve
- CALL xorSieveArray
- .c2:
- MEMP sieve_x2
- COPY sieve1 ; copy x^2 to n
- REG0 3
- REG1 0
- CALL mul_u16 ; x^2 * 0x0003
- ALU0 MEMHI; \
- ALU1 0 ; |
- BRP .c3 ; | checking if 3*x^2 overflow
- BRZ EQ ; |
- ALU0 MEMLO; |
- BRZ EQ ; /
- ; n += y^2
- MEMP sieve_y2
- ALU0 $nl ; $nl
- ALU1 MEMLO ; $y2l
- $nl ADD
- ALU0 $nh
- ALU1 MEMHI
- $nh ADC
- ALU0 ADDC ; \
- ALU1 0 ; | chcek for 3*x^2+y^2 overflow
- BNE .c3 ; /
-
- MEMP sieve1
- MEMHI $nh
- MEMLO $nl
- ; checkinf for n%12 == 7
- MEMP generalbuf
- MEMHI 0
- MEMLO 12 ; storing 12
- CALL mod_u16 ; n = n%12
- ALU0 0
- ALU1 REG1 ; if n%12 high byte != 0
- BRP .c3
- BRZ EQ
- ALU0 7 ; if n%12 == 7
- ALU1 REG0
- BRZ EQ
- CALL xorSieveArray
- .c3:
- ; checking if x > y
- MEMP sieve_y
- REG0 MEMLO
- REG1 MEMHI
- MEMP sieve_x
- ALU0 REG1 ; xh
- ALU1 MEMHI ; yh
- BGT .c3c
- BLT .loopye ; jump if x < y
- ALU0 REG0 ; xl
- ALU1 MEMLO ; yl
- BGE .loopye ; jump to .loopy if x < y
- .c3c:
- MEMP sieve_x2
- COPY sieve1 ; copy x^2 to n
- REG0 3
- REG1 0
- CALL mul_u16 ; x^2 * 0x0003
- ; now n is 32bit in {MEMHI, MEMLO, REG1, REG0}
- ; where do we store y^2? Should be in stack but for test lets use BRP
- BR0 MEMLO
- BR1 MEMHI
- MEMP sieve_y2
- COPY sieve1
- ALU0 REG0
- ALU1 MEMLO
- REG0 SUB
- ALU0 REG1
- ALU1 MEMHI
- REG1 SBC
- ALU0 BR0
- ALU1 0
- MEMLO SBC
- ALU0 BR1
- ALU1 0
- MEMHI SBC
- ; now 32bit in {MEMHI, MEMLO, REG1, REG0}
- ; has been subtraced with y^2
-
- ALU0 MEMHI ; \
- ALU1 0 ; |
- BRP .loopye; | checking if 3*x^2-y^2 overflow
- BRZ EQ ; |
- ALU0 MEMLO ; |
- BRZ EQ ; /
-
- MEMLO $nl
- MEMHI $nh
- ; checkinf for n%12 == 11
- MEMP generalbuf
- MEMHI 0
- MEMLO 12 ; storing 12
- CALL mod_u16 ; n = n%12
- ALU0 0
- ALU1 $nh ; if n%12 high byte != 0
- BRP .loopye
- BRZ NE
- ALU0 7 ; if n%12 == 7
- ALU1 $nl
- BRZ NE
- ; n should be in *sieve1
- CALL xorSieveArray
- ; ================
- ; End of main loop
- ; ================
- .loopye:
- MEMP sieve_y
- ALU0 $yl ; \
- ALU1 1 ; |
- $yl ADD ; | y++
- ALU1 ADDC ; |
- ALU0 $yh ; |
- $yh ADD ; /
- JUMP .loopy
- .loopxe:
- MEMP sieve_x
- ALU0 $xl ; \
- ALU1 1 ; |
- $xl ADD ; | x++
- ALU1 ADDC ; |
- ALU0 $xh ; |
- $xh ADD ; /
- JUMP .loopx
- ; =============
- ; End of part 1
- ; =============
- .endp1:
- ; ; now lets reject squares
- ; %def $r,REG0
- ; %def $r2,REG1
- ; $r 5 ; r:=5
- ;.loopr:
- ; ALU0 $r
- ; ALU1 $r
- ; $r2 MULLO ; reg1 := r^2
- ; ALU0 MULHI
- ; ALU1 0x00
- ; BNE .endp2 ; end if r^2 > 255
- ; ; accessing mem cell
- ; STACK REG0
- ; CALC_SIEVE_POINTER REG0,REG0,.hi,'R'
- ; ALU1 MEMLO
- ; JUMP .x1
- ;.hi:
- ; ALU1 MEMHI
- ;.x1:
- ; ALU0 REG0
- ; REG0 STACK
- ; BRPZ .loopre,AND ; if sieve[r] = 0
- ; ; loopi
- ; STACK $r; reg0 := r
- ; REG0 $r2 ; i := r^2
- ;.loopi:
- ; STACK REG0
- ; CALC_SIEVE_POINTER REG0,REG0,.x2hi,'D'
- ; ALU0 REG0
- ; ALU1 0xFF
- ; ALU0 XOR ; invert REG0
- ; ALU1 MEMLO
- ; MEMLO AND ; set sieve[i] = 0
- ; JUMP .x2
- ;.x2hi:
- ; ALU0 REG0
- ; ALU1 0xFF
- ; ALU0 XOR ; invert REG0
- ; ALU1 MEMHI
- ; MEMHI AND ; set sieve[i] = 0
- ;.x2:
- ; REG0 STACK
- ;.loopie:
- ; ALU0 REG0
- ; ALU1 REG1
- ; REG0 ADD
- ; BRPZ .loopi,ADDC ; if not overflow
- ; $r STACK ; restoring stack for r
- ;
- ;.loopre:
- ; ALU0 $r
- ; ALU1 1
- ; $r ADD ; r ++
- ; JUMP .loopr
- ;.endp2:
- RET
- xorSieveArray:
- ; short n = *sieve1
- ; sieve[n//16] ^= 1<<n%16
- ;jump forever
- MEMP sieve1
- ;PRINTMEM
- ;CALL println
- ;ALU0 MEMHI
- ;ALU1 1000@1
- ;BGT forever
- COPY generalbuf
- MEMP generalbuf2
- MEMLO 16
- MEMHI 0
- CALL div_u16
- MEMP generalbuf3
- ALU0 MEMLO
- ALU1 memend@0
- MEM0 ADD
- ALU0 MEMHI
- ALU1 memend@1
- MEM1 ADC
- MEM2 0
- ; memory pointer ready
- ; checking if there's enough ram to not corrupt stack
- ; mem1 should be less or equal to 0x0e, making ~ 3839 memory spaces or
- ; about 60800 bits
- ALU0 MEM1
- ALU1 0x0e
- BGT .done
- .mpr:
- ;; DEBUG
- ;STACK REG0
- ;REG0 MEM2
- ;CALL print_hex
- ;REG0 MEM1
- ;CALL print_hex
- ;REG0 MEM0
- ;CALL print_hex
- ;REG0 ":"
- ;CALL print_char
- ;REG0 STACK
- ;; DEBUG END
- ALU1 REG0 ; dividion reminder lower byte
- ALU0 8
- BLT .hi
- ; memory lower
- ALU0 1
- ALU1 REG0 ; reminder
- ALU0 SLL
- ;; debug
- ;STACK REG0
- ;STACK ALU0
- ;REG0 'L'
- ;CALL print_char
- ;REG0 MEMLO
- ;CALL print_bin
- ;REG0 '^'
- ;CALL print_char
- ;REG0 STACK
- ;CALL print_bin
- ;ALU0 REG0
- ;REG0 STACK
- ;; debug end
- ALU1 MEMLO
- MEMLO XOR
- JUMP .done
- .hi:
- ALU0 1
- ALU1 REG0 ; reminder
- ALU0 SLL
- ;ALU0 ROL
- ;; debug
- ;STACK REG0
- ;STACK ALU0
- ;REG0 'H'
- ;CALL print_char
- ;REG0 MEMHI
- ;CALL print_bin
- ;REG0 '^'
- ;CALL print_char
- ;REG0 STACK
- ;CALL print_bin
- ;ALU0 REG0
- ;REG0 STACK
- ;; debug end
- ALU1 MEMHI
- MEMHI XOR
-
- ;STACK REG0
- ;REG0 MEMHI
- ;CALL print_u8
- ;REG0 0x20
- ;CALL print_char
- ;ALU0 MEMHI
- ;ALU1 16
- ;REG0 DIV
- ;CALL print_u8
- ;REG0 0x20
- ;CALL print_char
- ;CALC_SIEVE_POINTER MEMHI,REG0,.hi,'A'
- ;; debug
- ;STACK REG0
- ;REG0 'L'
- ;CALL print_char
- ;REG0 MEMLO
- ;CALL print_bin
- ;REG0 '^'
- ;CALL print_char
- ;REG0 STACK
- ;CALL print_bin
- ;; debug end
- ; ALU0
- ; ALU1 REG0
- ; MEMLO XOR
- ; JUMP .done
- ;.hi:
- ; ;; debug
- ; STACK REG0
- ; REG0 'H'
- ; CALL print_char
- ; REG0 MEMHI
- ; CALL print_bin
- ; REG0 '^'
- ; CALL print_char
- ; REG0 STACK
- ; CALL print_bin
- ; ;; debug end
- ; ALU0 MEMHI
- ; ALU1 REG0
- ; MEMHI XOR
- .done:
- ;; debug
- ;STACK XOR
- ;REG0 '='
- ;CALL print_char
- ;REG0 STACK
- ;CALL print_bin
- ;CALL println
- ;; debug end
- RET
- mul_u16:
- ; m1H, m1L, m2H, m2L, MEMHI, MEMLO, REG1, REG0
- ; answer = {MEMHI, MEMLO, REG1, REG0}
- %def $m1H,REG1
- %def $m2H,MEMHI
- %def $m1L,REG0
- %def $m2L,MEMLO
- %def $res3,MEMHI
- %def $res2,MEMLO
- %def $res1,REG1
- %def $res0,REG0
- ;MEMP generalbuf
- ;REG0 -> m1L
- ;REG1 -> m2L
-
- ALU0 $m2L
- ALU1 $m2H
- STACK ALU1 ;m2H
- STACK $m1L
- STACK ALU0 ;m2L
- STACK $m1H ;m1H
- STACK ALU0 ;m2L
- STACK $m1L
- ALU0 $m1H
- $res2 MULLO
- $res3 MULHI
- ALU0 STACK ;m1L
- ALU1 STACK ;m2L
- $res0 MULLO
- $res1 MULHI
- ALU0 STACK ;m1H
- ALU1 STACK ;m2L
- STACK MULHI
- ALU0 MULLO
- ALU1 $res1
- $res1 ADD
- ALU0 STACK
- ALU1 $res2
- $res2 ADC
- ALU1 ADDC
- ALU0 $res3
- $res3 ADD
- ALU0 STACK ;m1L
- ALU1 STACK ;m2H
- STACK MULHI
- ALU0 MULLO
- ALU1 $res1
- $res1 ADD
- ALU0 $res2
- ALU1 STACK
- $res2 ADC
- ALU0 ADDC
- ALU1 $res3
- $res3 ADD
- RET
- bin2digit:
- ; Converts U16 to digit
- ; Adopted from http:;www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
- ; Digit {reg1 reg0} Place in 10^n generalbuf
- ; Memory pointer must be set to generalbuf
- STACK 0
- .a:
- ALU0 REG1
- ALU1 LWHI
- BLT .c
- BGT .b
- ALU0 REG0
- ALU1 LWLO
- BLT .c
- .b:
- ALU0 REG0
- ALU1 LWLO
- REG0 SUB
- ALU0 REG1
- ALU1 LWHI
- REG1 SBC
- ALU0 STACK
- ALU1 1
- STACK ADD
- JUMP .a
- .c:
- SWLO REG0
- REG0 STACK
- SWHI REG0
- REG0 LWLO
- RET
- print_u16:
- ; Prints U16 in {reg1 reg0}
- STACK REG0
- STACK REG1
- MEMP generalbuf
- SWHI 10000@1
- SWLO 10000@0 ; 10000 in hex
- CALL bin2digit
- ALU0 48
- ALU1 LWHI
- STACK REG0
- REG0 ADD
- CALL print_char
- REG0 STACK
- SWHI 1000@1
- SWLO 1000@0
- CALL bin2digit
- ALU0 48
- ALU1 LWHI
- STACK REG0
- REG0 ADD
- CALL print_char
- REG0 STACK
- SWHI 0
- SWLO 100
- CALL bin2digit
- ALU0 48
- ALU1 LWHI
- STACK REG0
- REG0 ADD
- CALL print_char
- REG0 STACK
- ALU0 REG0
- ALU1 100
- REG1 MOD
- ALU1 10
- ALU0 REG0
- STACK MOD
- ALU1 MOD
- ALU0 REG1
- ALU0 SUB
- ALU1 10
- ALU0 DIV
- ALU1 48
- REG0 ADD
- CALL print_char
- ALU0 STACK
- ALU1 48
- REG0 ADD
- CALL print_char
- REG1 STACK
- REG0 STACK
- RET
- print_u8:
- ; print u8 in reg0
- ; a = 128%10 = 8
- ; a = 128%100 - a // 10 = 2
- ; a = 128%1000 - a // 100 = 1
- STACK REG1
- REG1 REG0
- ALU1 10
- ALU0 REG0
- ALU0 MOD ; ALU0 = reg0%10
- STACK ALU0
- REG0 ALU0
- ALU0 REG1
- BRPZ .p3,GE
- ALU1 100
- ALU0 REG1
- ALU0 MOD
- ALU1 STACK
- STACK ALU1
- ALU0 SUB
- ALU1 10
- ALU1 DIV
- STACK ALU1
- ALU0 REG1
- ALU1 100
- BRPZ .p2,GE
- ALU1 200
- BRPZ .p1,GE
- REG0 '2'
- CALL print_char
- JUMP .p2
- .p1:
- REG0 '1'
- CALL print_char
- .p2:
- ALU0 48
- ALU1 STACK
- REG0 ADD
- CALl print_char
- .p3:
- ALU0 48
- ALU1 STACK
- REG0 ADD
- CALl print_char
- REG0 REG1
- REG1 STACK
- RET
- print_bin:
- ; print reg0 as binary
- STACK REG0
- STACK REG1
- REG1 REG0 ; Making copy
- ALU0 0b1000_0000
- .start:
- ALU1 REG1
- STACK ALU0
- BRPZ .print0,AND
- .print1:
- REG0 '1'
- CALL print_char
- JUMP .end
- .print0:
- REG0 '0'
- CALL print_char
- .end:
- ALU1 1
- ALU0 STACK
- ALU0 SRL
- BRPZ .done,ALU0
- REG0 REG1
- JUMP .start
- .done:
- REG1 STACK
- REG0 STACK
- RET
- print_hex:
- ; prints reg0 as hex
- STACK REG0
- STACK REG1
- REG1 REG0
- ALU1 4
- ALU0 REG0
- ALU1 SRL
- ALU0 10
- BRPZ .p0,GT
- ALU0 48
- JUMP .p1
- .p0:
- ALU0 55
- .p1:
- REG0 ADD
- CALL print_char
- REG0 REG1
- ALU0 0b0000_1111
- ALU1 REG0
- ALU1 AND
- ALU0 10
- BRPZ .p2,GT
- ALU0 48
- JUMP .p3
- .p2:
- ALU0 55
- .p3:
- REG0 ADD
- CALL print_char
- REG1 STACK
- REG0 STACK
- RET
- println:
- STACK REG0
- REG0 LF
- CALL print_char
- REG0 CR
- CALL print_char
- REG0 STACK
- RET
- print_string:
- ; prints string in memory location {reg0, reg1}
- .st:
- MEM0 REG0
- MEM1 REG1
- BRPZ .end,LWHI
- COMA COM_UARTR
- BRP .loop0
- ALU0 COM_UART_RECV
- .loop0:
- ALU1 COMD
- ALU1 AND
- BRZ NE
- COMA COM_UARTW
- COMD LWHI
- BRPZ .end,LWLO
- COMA COM_UARTR
- BRP .loop1
- .loop1:
- ALU1 COMD
- ALU1 AND
- BRZ NE
- COMA COM_UARTW
- COMD LWLO
- ALU0 REG0
- ALU1 1
- REG0 ADD
- ALU1 ADDC
- ALU0 REG1
- REG1 ADD
- JUMP .st
- .end:
- RET
- print_char:
- ; prints char in reg0
- COMA COM_UARTR
- BRP .loop0
- ALU0 COM_UART_RECV
- .loop0:
- ALU1 COMD
- ALU1 AND
- BRZ NE
- COMA COM_UARTW
- COMD REG0
- RET
- read_char:
- ; waits for char and stores that in reg0
- COMA COM_UARTR
- ALU0 0b0000_1000
- BRP .loop
- .loop:
- ALU1 COMD
- BRZ AND
- COMA COM_UARTIN
- REG0 COMD
- RET
|