| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472 |
- %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
- ;MEMP generalbuf2
- ;MEMP generalbuf
- ;MEMLO 0x00
- ;MEMHI 0x00
- REG0 0xFF
- REG1 0xFF
- CALL print_u16
- 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
|