| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361 |
- %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 NULL 0x000000
- %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 PRINTREGS 0
- PUSH r0
- CALL print_hex
- MOVE r0,r1
- CALL print_hex
- MOVE r0,r2
- CALL print_hex
- MOVE r0,r3
- CALL print_hex
- CALL println
- POP r0
- %endmacro
- %macro PRINTREG 1
- PUSH r0
- MOVE r0,%1
- CALL print_hex
- POP r0
- %endmacro
- %macro SLL16 4
- ; 1 2 3 4
- ; shift by, low byte, high byte, temp reg
- SLL %2,%1
- PUSH %4
- GETAH %4
- SLL %3,%1
- OR %3,%4
- POP %4
- %endmacro
- %macro LOAD 3
- LWLO %3,%1
- LWHI %2,%1
- %endmacro
- %macro SAVE 3
- SWHI %2
- SWLO %3,%1
- %endmacro
- %macro PRINTMEM 1
- PUSH r0
- LWHI r0,%1
- CALL print_hex
- LWLO r0,%1
- CALL print_hex
- POP r0
- %endmacro
- %macro CH 1
- PUSH r0
- CPY0 %1
- CALL print_char
- POP r0
- %endmacro
- %macro BGE16 5
- ; 1 2 3 4 5
- ; Brach to if, A{H,L} >= B{H,L}
- CI2 %4
- BGT %2,0,%1
- CI2 %2
- BGT %4,0,%%continue
- CI2 %5
- BGE %3,0,%1
- %%continue:
- %endmacro
- section .data depth=4096,width=2
- intro_text: DB "\x1Bc\x1B[2J\x1B[HBooting \x1B[1m\x1B[33mRISC\x1B[0m system\r\n",0
- eq1_text: DB LFCR,"1) 0x1194 * 0x2710 = 0x",0
- eq2_text: DB LFCR,"2) 3*2=",0
- eq3_text: DB LFCR,"3) 3*2=",0
- initial_vt100: DB 0x1B,'c',0x1B,"[2J",0x1B,"[40;32m",0
- error_text: DB LFCR,"Invalid operation: ",0
- error0: DB "Buffer is full",0
- error1: DB "Number value overflow",0
- mul16buf: DBE 8
- generalbuf: DBE 1
- generalbuf2: DBE 1
- generalbuf3: DBE 1
- termHiFlag: DB 0x0000
- termBuff: DB 10,0
- DBE 10
- mallocPointer: DB 0
- MEMEND: DB 0
- section .text depth=4096,width=1,length=2
- setup:
- CPY1 intro_text@0
- CPY2 intro_text@1
- CALL print_msg
- ;JUMP forever
- CPY0 0x00
- CPY1 0x02
- SAVE generalbuf,r0,r1
- PRINTMEM generalbuf
- CALL println
- CALL println
- CPY0 50000@1
- CPY1 50000@0
- CALL div_u16
-
- CALL println
- PRINTMEM generalbuf2
- CH 0x20
- PRINTREGS
- CALL println
- JUMP forever
- ;CALL printU16
- ;PRINTREG
- ;CALL printU16
- ;CALL println
- JUMP forever
- SRL r0,1
- GETAH r1
- CALL println
- CALL print_bin
- CALL println
- MOVE r0,r1
- CALL print_bin
- CALL println
- forever:
- CALL read_char
- CALL print_char
- JUMP forever
-
- ; Run init
- ;INTRE interrupt
- ;CALL read_char
- ;CALL print_char
- ;.echo
- ; JUMP .echo
- ; CALL read_char
- ; CALL print_char
- ;CPY0 65432@1
- ;CPY1 65432@0
- ;CALL printU16
- ;CALL read_char
- ;CPY1 COM_UART_ECHO
- ;COM r1,COM_UARTF
- ;CPY1 eq1_text@0
- ;CPY2 eq1_text@1
- ;CALL print_msg
-
- CPY0 0x0A ;
- CPY1 0x0B ; a = 0
- CPY2 0x03 ;
- CPY3 0x00 ; b = 0
- loopyloop:
- PUSH r0
- PUSH r1
- PUSH r2
- PUSH r3
- CALL mulU16
- ;CALL print_hex
- ;MOVE r0,r1
- ;CALL print_hex
- ;MOVE r0,r2
- ;CALL print_hex
- ;MOVE r0,r3
- ;CALL print_hex
- ;CALL println
- POP r3
- POP r2
- POP r1
- POP r0
- INC r3
- ADDC r2
- BZ r3,.ztest0
- JUMP loopyloop
- .ztest0:
- BZ r2,.ztest1
- JUMP loopyloop
- .ztest1:
- INC r1
- ADDC r0
- ;PUSH r0
- ;CALL print_hex
- ;MOVE r0,r1
- ;CALL print_hex
- ;CPY0 '*'
- ;CALL print_char
- ;MOVE r0,r2
- ;CALL print_hex
- ;MOVE r0,r3
- ;CALL print_hex
- ;POP r0
- JUMP loopyloop
- CALL sieveOfAtkin
- CALL println
- div_u16:
- %def $Rh,r2
- %def $Rl,r3
-
- CPY2 0 ; set R = 0
- CPY3 0
-
- ; Keep r1 <= Nl
- PUSH r1 ; keep Nl for second loop
- CALL print_hex
- PRINTREG r1
- CALL println
- MOVE r1,r0
- ; for i=0;i<15;i++
- CPY0 0b1000_0000
- .for_start0:
- CALL println
- ;CALL print_bin
- ;CALL println
- SLL16 1,$Rl,$Rh,r0
- CH 'N'
- PRINTREG r1
- ;; Finding N(i)
- PUSH r1 ;; copy Nh
- AND r1,r0 ; AND i,N
-
- BEQ r1,0,.z0 ; if N&i == 0, do nothing
- PUSH r0
- CPY0 0x01
- OR $Rl,r0 ; R[0] = 1
- POP r0
- .z0:
- CH 0x20
- CH 'R'
- PRINTREG $Rh
- PRINTREG $Rl
- ; check if R >= D
- PUSH r0
- %def $Dl,r1
- %def $Dh,r0
- LOAD generalbuf,$Dh,$Dl
-
- CH 0x20
- CH 'D'
- CALL print_hex
- PRINTREG r1
- CH 0x20
- BGE16 .sub0,$Rh,$Rl,$Dh,$Dl
- POP r0
- JUMP .fin0
- .sub0:
- ; R -= D
- SUB $Rl,$Dl
- SUB $Rh,$Dh
- SUBC $Rh
- CH 'R'
- PRINTREG $Rh
- PRINTREG $Rl
- CH 0x20
- ; Q[i] = 1
- POP r0
- LWHI r1,generalbuf2
- OR r1,r0
- PRINTREG r1
- SWHI r1
- LWLO r1,generalbuf2
- SWLO r1,generalbuf2
- .fin0:
- POP r1 ;; restore Nh
- .for_end0:
- SRL r0,1
- BEQ r0,0,.done0
- JUMP .for_start0
- .done0:
- POP r1 ; restore Nh
- CPY0 0b1000_0000
- .for_start1:
- ;CALL print_bin
- ;CALL println
- CALL println
- SLL16 1,$Rl,$Rh,r0
- CH 'N'
- PRINTREG r1
- ;; Finding N(i)
- PUSH r1 ;; copy Nl
- AND r1,r0 ; AND i,N
-
- BEQ r1,0,.z1 ; if N&i == 0, do nothing
- PUSH r0
- CPY0 0x01
- OR $Rl,r0 ; R[0] = 1
- POP r0
- .z1:
- CH 0x20
- CH 'R'
- PRINTREG $Rh
- PRINTREG $Rl
- ; check if R >= D
- PUSH r0
- %def $Dl,r1
- %def $Dh,r0
- LOAD generalbuf,$Dh,$Dl
-
- CH 0x20
- CH 'D'
- CALL print_hex
- PRINTREG r1
- CH 0x20
- BGE16 .sub1,$Rh,$Rl,$Dh,$Dl
- POP r0
- JUMP .fin1
- .sub1:
- ; R -= D
- SUB $Rl,$Dl
- SUB $Rh,$Dh
- SUBC $Rh
- ; Q[i] = 1
- POP r0
- LWHI r1,generalbuf2 ; \ keep high byte
- SWHI r1 ; /
- LWLO r1,generalbuf2
- OR r1,r0
- PRINTREG r1
- SWLO r1,generalbuf2
- .fin1:
- POP r1 ;; restore Nl
- .for_end1:
- SRL r0,1
- BEQ r0,0,.done1
- JUMP .for_start1
- .done1:
- RET
- mod_u16:
- ; {Ah, Al} = {Ah, Al} % {Bh, Bl}
- %def $Al,r1
- %def $Ah,r0
- %def $Bl,r3
- %def $Bh,r2
- %def $Xl,r3
- %def $Xh,r2
- PUSH $Bl
- PUSH $Bh
- PUSH $Al
- PUSH $Ah
- ; Assume X = B
- ; Change A /= 2
- PUSH r2
- SRL $Ah,1
- GETAH r2
- SRL $Al,1
- OR $Al,r2
- POP r2
- ; While x <= A/2
- .part1:
- CI2 $Ah
- BGT $Xh,0,.part2
- CI2 $Xh
- BGT $Ah,0,.xsl
- CI2 $Al
- BGT $Xl,0,.part2
- .xsl:
- PUSH r0
- SLL $Xl,1
- GETAH r0
- SLL $Xh,1
- OR $Xh,r0
- POP r0
- JUMP .part1
- .part2:
- ; Saving X
- SWHI $Xh
- SWLO $Xl,generalbuf
- ; Returning A
- POP $Ah
- POP $Al
- ; Returning B
- POP $Bh
- POP $Bl
- .p2check:
- ; Check A>=B
- ;PRINTREG
- CI2 $Ah
- BGT $Bh,0,.done
- CI2 $Bh
- BGT $Ah,0,.loop
- CI2 $Al
- BGT $Bl,0,.done
- ; end of check
- .loop:
- ; Store B
- PUSH $Bl
- PUSH $Bh
- ; Load X
- LWHI $Xh,generalbuf
- LWLO $Xl,generalbuf
- ; if A >= X
- ;PRINTREG
- CI2 $Xh
- BGT $Ah,0,.agtx
- CI2 $Xl
- BGT $Al,0,.agtx
- CI2 $Xl
- BEQ $Al,0,.agtx
- JUMP .next
- ; A -= X
- .agtx:
- SUB $Ah,$Xh
- SUB $Al,$Xl
- SUBC $Ah
- .next:
- ; X >>= 1
- SRL $Xh,1
- PUSH r0
- GETAH r0
- SRL $Xl,1
- OR $Xl,r0
- POP r0
-
- ; Pack X
- SWHI $Xh
- SWLO $Xl,generalbuf
- POP $Bh
- POP $Bl
- JUMP .p2check
- .done:
- RET
-
-
- loop:
- CPY0 0
- PUSH r0
- CPY0 '>'
- CALL print_char
- CPY0 0x20 ; space
- CALL print_char
- ;.loop
- ; CALL read_char
- ; CALL print_char
- ; ;BEQ r2,0x0a,.start
- ; BEQ r0,0x0d,.error
- ; JUMP .loop
- ;.error
- ; CPY1 error_text@0
- ; CPY2 error_text@1
- ; CALL print_msg
- ; JUMP .start
- .read:
- CALL read_char
- BGT r0,57,.readc0
- BGT r0,48,.readadd
- .readc0:
- BEQ r0,0x0d,.done
- ;BEQ r0,0x20,.echo
- BEQ r0,0x08,.backspace
- BEQ r0,0x7F,.backspace
- BEQ r0,0x2A,.readadd ; *
- BEQ r0,0x2B,.readadd ; +
- BEQ r0,0x2D,.readadd ; -
- BEQ r0,0x2F,.readadd ; /
- JUMP .read
- .backspace:
- ; POP r1
- ; BEQ r1,0,.backspaceCheck
- ; CPY0 0x1B
- ; CALL print_char
- ; CPY0 'c'
- ; CALL print_char
- ; JUMP .read
- ;.backspaceCheck
- ; PUSH r1
- JUMP .read
- .readadd:
- LWLO r3,termHiFlag
- BZ r3,.readadd0
- JUMP .readstore
- .readadd0:
- CPY3 1
- SWHI r0
- SWLO r3,termHiFlag
- JUMP .echo
- .readstore:
- CPY2 0
- LWHI r3,termHiFlag
- SWLO r2,termHiFlag
- MOVE r2,r0
- CPY0 termBuff@0
- CPY1 termBuff@1
- CALL arrayPush
- ; Check if buffer overflow
- BZ r0,.readstore0
- MOVE r0,r2
- JUMP .echo
- .readstore0:
- MOVE r0,r2
- BZ r1,.error0
- .echo:
- CALL print_char
- JUMP .read
- .done:
- ; if odd number of chars, push r0, 0 to array
- LWLO r3,termHiFlag
- BZ r3,.doneC
- ;LWHI r2,termHiFlag
- ;CPY3 0
- ;CPY0 termBuff@0
- ;CPY1 termBuff@1
- ;CALL arrayPush
- .doneC:
- CPY1 termBuff@0
- CPY2 termBuff@1
- CALL Process
- CPY0 termBuff@0
- CPY1 termBuff@1
- CALL arrayClear
- JUMP loop
- .done0:
- POP r0
- BEQ r0,0,.done1
- CALL print_char
- JUMP .done0
- .done1:
- CALL println
- JUMP loop
- .error0:
- CALL println
- CPY1 error0@0
- CPY2 error0@1
- CALL print_msg
- CALL println
- JUMP loop
- MOVE r1,r0
- SUBI r1,48
- CALL print_char
- CALL read_char
- MOVE r2,r0
- CALL print_char
-
- CALL read_char
- MOVE r3,r0
- SUBI r3,48
- CALL print_char
-
- BEQ r2,'+',.add0
- BEQ r2,'-',.sub0
- JUMP .invalid
- .add0:
- ADD r1,r3
- JUMP .result
- .sub0:
- SUB r1,r3
- JUMP .result
- .invalid:
- CPY1 error_text@0
- CPY2 error_text@1
- CALL print_msg
- JUMP .done
- .result:
- PUSH r1
- CPY0 '='
- CALL print_char
- POP r0
- ADDI r0,48
- CALL print_char
- Process:
- ; Input array *{r2 r1}
- ;CPY1 termBuff@0
- ;CPY2 termBuff@1
- .readnext:
- INC r1
- ADDC r2
- CI1 r2
- CI0 r1
- SWLO r0,NULL
- .isdigit:
- ;BGT r0,57,.issymbol
- ;BGT r0,48,.digit
- .issymbol:
- ;JUMP .error
- .digit:
- ;CI1 r2
- ;CI0 r1
- ;SWHI r0
- .error:
- CPY1 error_text@0
- CPY2 error_text@1
- CALL print_msg
- CPY1 termBuff@0
- CPY2 termBuff@1
- INC r1
- ADDC r2
- CALL print_msg
- .end:
- CALL println
- RET
- print_bin:
- ; print r0 as binary
- PUSH r2
- PUSH r1
- PUSH r0
- CPY2 0b1000_0000
- MOVE r1,r0
- .start:
- AND r0,r2
- BZ r0,.print0
- .print1:
- CPY0 '1'
- CALL print_char
- JUMP .end
- .print0:
- CPY0 '0'
- CALL print_char
- .end:
- SRL r2,1
- BZ r2,.done
- MOVE r0,r1
- JUMP .start
- .done:
- POP r0
- POP r1
- POP r2
- RET
- print_hex:
- ; print r0 as hex
- PUSH r0
- PUSH r1
- MOVE r1,r0
- SRL r0,4
- BGT r0,9,.p0
- ADDI r0,48
- JUMP .p1
- .p0:
- ADDI r0,55
- .p1:
- CALL print_char
- MOVE r0,r1
- POP r1
- ANDI r0,0b0000_1111
- BGT r0,9,.p2
- ADDI r0,48
- JUMP .p3
- .p2:
- ADDI r0,55
- .p3:
- CALL print_char
- POP r0
- RET
-
- ;.done
- ;; Equation 1
- ;CPY1 eq1_text@0
- ;CPY2 eq1_text@1
- ;CALL print_msg
- ;CPY0 3
- ;ADDI r0,2
- ;ADDI r0,48 ; Convert to ascii
- ;CALL print_char
- ;
- ;; Equation 2
- ;CPY1 eq2_text@0
- ;CPY2 eq2_text@1
- ;CALL print_msg
- ;CPY0 6
- ;SUBI r0,2
- ;ADDI r0,48 ; Convert to ascii
- ;CALL print_char
- ;; Equation 3
- ;CPY1 eq3_text@0
- ;CPY2 eq3_text@1
- ;CALL print_msg
- ;CPY0 3
- ;CPY1 2
- ;MUL r0,r1
- ;ADDI r0,48 ; Convert to ascii
- ;CALL print_char
- ;
- ;CPY1 eq3x_text@0
- ;CPY2 eq3x_text@1
- ;CALL print_msg
- ;AH r0
- ;ADDI r0,48 ; Convert to ascii
- ;CALL print_char
- ;; Equation 4
- ;CPY1 eq4_text@0
- ;CPY2 eq4_text@1
- ;CALL print_msg
- ;CPY0 9
- ;CPY1 2
- ;DIV r0,r1
- ;ADDI r0,48 ; Convert to ascii
- ;CALL print_char
- ;; Equation 5
- ;CPY1 eq5_text@0
- ;CPY2 eq5_text@1
- ;CALL print_msg
- ;AH r0
- ;ADDI r0,48 ; Convert to ascii
- ;CALL print_char
-
- ;CALL println
- ;JUMP .start
- ;CPY3 0
- start:
- INC r3
- JUMP start
- interrupt:
- PUSH r0
- GETIF r0
- POP r0
- RETI
- println:
- PUSH r0
- CPY0 LF
- CALL print_char
- CPY0 CR
- CALL print_char
- POP r0
- RET
- %define SLIMIT 255
- sieveOfAtkin:
- ; Calculate primes up to limit
- CPY0 MEMEND@0
- CPY1 MEMEND@1
- CPY2 0
- CPY3 0
- ; Initialising memory with 0s
- .clearCell:
- CPY2 0
- CI0 r0
- CI0 r1
- SWLO r2,NULL
- INC r3
- ADDC r3
- INC r1
- ADDC r0
- BZ r3,.clearCell
- .main:
- CPY0 1 ; x=1
- .loopx:
- ; FOR loop x
- PUSH r0
- MUL r0,r0 ; x^2
- ; check if more than 2 bytes
- AH r2
- BZ r2,.loopx0
- POP r0
- JUMP .p2; to part2
- .loopx0: ; Loop content
- CPY1 1 ; y=1
- .loopy:
- ; FOR loop y
- PUSH r1
- MUL r1,r1 ; y^2
- ; check if more than 2 bytes
- AH r2
- BZ r2,.loopy0
- POP r1
- JUMP .loopxe; to loop x end
- .loopy0: ; Loop content
- ; ======================
- ; START OF MAIN FUNCTION
- ; ======================
- ;At this point r0=x^2; r1=y^2
- CPY2 4 ; n=4
- MUL r2,r0 ; n=4*x^2
- AH r3 ; check for overflow
- BZ r3,.c1a
- JUMP .c2
- .c1a:
- ADD r2,r1 ; n=4*x^2 + y^2
- ADDC r3 ; check for overflow
- BZ r3,.c1b
- JUMP .c2
- .c1b: ; check if n%12==1
- PUSH r2
- CPY3 12
- DIV r2,r3
- AH r2
- CPY3 1
- XOR r3,r2
- BZ r3,.c1f
- ; check if n%12==5
- CPY3 5
- XOR r3,r2
- BZ r3,.c1f
- POP r2; return n from stack
- ; else cary on C2
- JUMP .c2
- .c1f:
- POP r2; return n from stack
- CALL sieveOfAtkinInvN
- .c2:
- ; At this point r0=x^2; r1=y^2
- CPY2 3 ; n=3
- MUL r2,r0 ; n=3*x^2
- AH r3 ; check for overflow
- BZ r3,.c2a
- JUMP .c3
- .c2a:
- ADD r2,r1 ; n=3*x^2 + y^2
- ADDC r3 ; check for overflow
- BZ r3,.c2b
- JUMP .c3
- .c2b: ; check if n%12==7
- PUSH r2
- CPY3 12
- DIV r2,r3
- AH r2
- CPY3 7
- XOR r3,r2
- POP r2
- BZ r3,.c2f
- JUMP .c3
- .c2f:
- CALL sieveOfAtkinInvN
- .c3:
- ; At this point r0=x^2; r1=y^2
- ; n=3*x^2-y^2
- CPY2 3
- MUL r2,r0
- AH r3
- SUB r2,r1
- SUBC r3
- BZ r3,.c3a ; check for limit
- JUMP .loopye
- .c3a:; check if x>y
- ; r2=n
- POP r1 ; get y
- POP r0 ; get x
- CI2 r1
- BGT r0,0,.c3b
- PUSH r0
- PUSH r1
- JUMP .loopye
- .c3b:; check if n%12==11
- PUSH r0
- PUSH r1
- PUSH r2
- CPY3 12
- DIV r2,r3
- AH r2 ; n%12
- CPY3 11
- XOR r3,r2
- POP r2
- BZ r3,.c3c
- JUMP .loopye
- .c3c:
- CALL sieveOfAtkinInvN
- ; ====================
- ; END OF MAIN FUNCTION
- ; ====================
- .loopye:
- POP r1
- INC r1
- JUMP .loopy
- .loopxe:
- POP r0
- INC r0
- JUMP .loopx
- .p2:
- ; for (r=5;r^2<limit;r++)
- CPY0 5 ; r=5
- .loopr:
- MOVE r1,r0
- MUL r1,r0 ; r^2
- AH r3
- BZ r3,.r0e ; check for overflow
- JUMP .end
- .r0e:
- CPY2 MEMEND@0
- CPY3 MEMEND@1
- ADD r2,r0 ; Add r to pointer
- ADDC r3
- CI0 r2
- CI1 r3
- LWLO r2,NULL ; if sieve[r]
- BZ r2,.loopre
- ; for(i = r^2; i<limit;i+=r^2) sieve[r]=0
- ; at this point r0 -> r; r1 -> r^2
- PUSH r0
- MOVE r0,r1 ; set i=r^2
- .loopi:
- ; sieve[r] = 0
- CPY2 MEMEND@0
- CPY3 MEMEND@1
- ADD r2,r0
- ADDC r3
- CPY0 0
- CI0 r2
- CI1 r3
- LWLO r0,NULL
- .loopie:
- ADD r0,r1
- ADDC r2
- BZ r2,.loopi ; if carry is zero carry on
- POP r0
- .loopre:
- INC r0
- JUMP .loopr
- .end:
- ; shall we print here?
- CPY0 0
- CPY1 MEMEND@0
- CPY2 MEMEND@1
- .print0:
- CI0 r1
- CI1 r2
- LWLO r3,NULL
- BZ r3,.print1
- CALL printU8
- PUSH r0
- CPY0 0x20
- CALL print_char
- POP r0
- .print1:
- INC r2
- ADDC r1
- INC r0
- ADDC r3
- BZ r3,.print0 ; if not overflow, carry on
- RET
- ;sieveOfAtkinCore
- sieveOfAtkinInvN:
- ; sieve[n] ^=1 where n=r2
- PUSH r0
- PUSH r1
- PUSH r3
- PUSH r2
-
- CPY3 16
- DIV r2,r3; n/=16
- CPY0 MEMEND@0
- CPY1 MEMEND@1
- ADD r0,r2 ; add n to pointer
- ADDC r1
- CI0 r0
- CI1 r1
- LWHI r2,NULL
- CI0 r0
- CI1 r1
- LWLO r3,NULL
- PUSH r0
- PUSH r1
- ; check if high or low byte
- ; n is saved from MSB to LSB e.g.:
- ; data in memory address:
- ; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- ; n= 0 1 2 3 4 5 6 7 8 9 A B C D E F
- ; At this point r3=memLO, r2=memHI
- CPY0 1
- AH r1; n%16
- BGE r1,8,.lo
- JUMP .hi
- .lo:
- SUBI r1,8
- CI2 r1
- SLL r0,0 ; 1 << (n-8)
- XOR r3,r0
- JUMP .fi
- .hi:
- CI2 r1
- SLL r0,0 ; 1 << n
- XOR r2,r0
- .fi:
- ; Everything's been flipped, time to upload to ram
- POP r1
- POP r0
- SWHI r2
- CI0 r0
- CI1 r1
- SWLO r3,NULL
-
- POP r2
- POP r3
- POP r1
- POP r0
- ; MOVE r0,r2
- ; CPY1 16
- ; DIV r0,r1; n/=16
- ; PUSH r2
- ; ; Get array pointer + n/=16
- ; CPY1 MEMEND@0
- ; CPY2 MEMEND@1
- ; ADD r2,r0
- ; ADDC r1
- RET
- mulU16:
- ; Multiply 2 unsigned 16-bit int
- ; {r0 r1} * {r2 r3}
- ; A B * X Y
- ; Result:
- ; r3 = BY0
- ; r2 = BY1+BX0+AY0
- ; r1 = BX1+AY1+AX0
- ; r0 = AX1
- ; Carryout must be included to higher bytes
- PUSH r3
- MUL r3,r1 ; BY0
- SWHI r3
- AH r3 ; BY1
- SWLO r3,mul16buf
- POP r3 ; Buffer = [BY0 BY1]
- PUSH r2
- MUL r2,r1 ; BX0
- SWHI r2
- AH r2 ; BX1
- SWLO r2,mul16buf+1
- POP r2 ; Buffer = [BY0 BY1 BX0 BX1]
- PUSH r3
- MUL r3,r0 ; AY0
- SWHI r3
- AH r3 ; AY1
- SWLO r3,mul16buf+2
- POP r3 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1]
- PUSH r2
- MUL r2,r0 ; AX0
- SWHI r2
- AH r2 ; AX1
- SWLO r2,mul16buf+3
- POP r2 ; Buffer = [BY0 BY1 BX0 BX1 AY0 AY1 AX0 AX1]
- ; { 0 } { 1 } { 2 } { 3 }
- ; r3 will be used as spare register as it's equal to BY0
-
- LWLO r2,mul16buf ; r2=BY1
- LWLO r1,mul16buf+1 ; r1=BX1
- LWLO r0,mul16buf+3 ; r0=AX1
- LWHI r3,mul16buf+1 ; t=BX0
- ADD r2,r3
- ADDC r1
- ADDC r0
- LWHI r3,mul16buf+2 ; t=AY0
- ADD r2,r3
- ADDC r1
- ADDC r0
- LWLO r3,mul16buf+2 ; t=AY1
- ADD r1,r3
- ADDC r0
- LWHI r3,mul16buf+3 ; t=AX0
- ADD r1,r3
- ADDC r0
- LWHI r3,mul16buf ; r3=BY0
- RET
- bin2digit:
- ; Converts U16 to digit
- ; Adopted from http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
- ; Digit {r0 r1}, Place in 10^n {r2 r3}
- PUSH r0
- CPY0 0
- SWLO r0,generalbuf ; Using general buf to store number
- POP r0
- .a:
- CI2 r0
- BGT r2,0,.c ; MSB is smaller than digit
- CI2 r2
- BGT r0,0,.b ; MSB is grater than digit
- CI2 r1
- BGT r3,0,.c ; LSB is smaller than digit
- .b:
- PUSH r0
- LWLO r0,generalbuf
- INC r0
- SWLO r0,generalbuf
- POP r0
- SUB r0,r2
- SUB r1,r3
- SUBC r0
- JUMP .a
- .c:
- LWLO r2,generalbuf
- RET
- printU16:
- ; print unsigned 16bit int as base-10 digit
- ; arguments: digit {r0, r1}
- PUSH r0
- PUSH r1
- PUSH r2
- PUSH r3
- CPY2 10000@1
- CPY3 10000@0
- CALL bin2digit
- MOVE r3,r0
- MOVE r0,r2
- ADDI r0,48 ; Convert to ascii digit
- CALL print_char
- MOVE r0,r3
-
- CPY2 1000@1
- CPY3 1000@0
- CALL bin2digit
- MOVE r3,r0
- MOVE r0,r2
- ADDI r0,48 ; Convert to ascii digit
- CALL print_char
- MOVE r0,r3
- CPY2 0
- CPY3 100
- CALL bin2digit
- MOVE r0,r2
- ADDI r0,48 ; Convert to ascii digit
- CALL print_char
- MOVE r0,r1
- CALL printU8
- POP r3
- POP r2
- POP r1
- POP r0
- RET
- printU8:
- ; Assuing number is 128
- ; a = 128%10 = 8
- ; a = 128%100 - a // 10 = 2
- ; a = 128%1000 - a // 100 = 1
- ; in case of 8bit number quicker is to do 2 if statements for 100s
- ; input argument is in r0
- PUSH r0
- PUSH r1
- PUSH r2
- PUSH r3
- CPY2 10
-
- MOVE r1,r0
- DIV r1,r2
- AH r1
- PUSH r1 ; Stored last digit
- BGE r0,10,.ge10
- JUMP .p3
- .ge10:
- CPY2 100
- MOVE r3,r0
- DIV r3,r2
- AH r3
- SUB r3,r1
- CPY2 10
- DIV r3,r2
- PUSH r3 ; Stored middle digit
- BGE r0,100,.ge100
- JUMP .p2
- .ge100:
- CPY2 200
- CI2 r2
- BGE r0,0,.s2
- CPY2 100
- CI2 r2
- BGE r0,0,.s1
- JUMP .p2
- .s1:
- CPY0 '1'
- JUMP .p0
- .s2:
- CPY0 '2'
- .p0:
- CALL print_char
- .p2:
- POP r0
- ADDI r0,48
- CALL print_char
- .p3:
- POP r0
- ADDI r0,48
- CALL print_char
- POP r3
- POP r2
- POP r1
- POP r0
- RET
- arrayClear:
- ; Clear array at *{r1 r0}
- PUSH r2
- CI1 r1
- CI0 r0
- LWHI r2,NULL
- SWHI r2
- CPY2 0
- CI1 r1
- CI0 r0
- SWLO r2,NULL
- POP r2
- RET
- arrayPush:
- ; Push to array *{r1 r0} value {r3 r2}
- ; If full, changes r1 r0 to 0x0000
- PUSH r2
- PUSH r3
- CI1 r1
- CI0 r0
- LWLO r2,NULL
- CI1 r1
- CI0 r0
- LWHI r3,NULL ; Stores cap
- ; r2=size, r3=cap
- CI2 r3
- BGE r2,0xFF,.full
- INC r2
- SWHI r3
- CI1 r1
- CI0 r0
- SWLO r2,NULL
-
- ADD r0,r2
- ADDC r1
- POP r3
- SWHI r3
- POP r2
- CI1 r1
- CI0 r0
- SWLO r2,NULL
- RET
- .full:
- POP r3
- POP r2
- CPY0 0
- CPY1 0
- RET
- arrayPop:
- ; Pop from array *{r1 r0} value {r3 r2}
- ; If empty, changes all regs to 0x00
- CI1 r1
- CI0 r0
- LWLO r2,NULL
- BEQ r2,0,.empty
- DEC r2
- CI1 r1
- CI0 r0
- SWLO r2,NULL
- INC r2
- ADD r0,r2
- ADDC r1
- CI1 r1
- CI0 r0
- LWHI r3,NULL
- CI1 r1
- CI0 r0
- LWLO r2,NULL
- RET
- .empty:
- CPY3 0
- CPY2 0
- CPY1 0
- CPY0 0
- RET
- read_char: ; read char to r0
- COM r0,COM_UARTR
- ANDI r0,0b0000_1000
- BZ r0,read_char
- COM r0,COM_UARTIN
- RET
- malloc: ; returns memory free memory locaion
- ; r0 = size to allocate
- ; {r2, r1} memory pointer
- LWHI r2,mallocPointer
- LWLO r1,mallocPointer
- PUSH r2
- PUSH r1
- ADD r1,r0
- ADDC r2
- SWHI r2
- SWLO r1,mallocPointer
- POP r1
- POP r2
- RET
- print_msg: ; print value in mem pinter {r2 r1}
- PUSH r0
- .loop:
- CI1 r2
- CI0 r1
- LWHI r0,NULL
- BZ r0,.end
- CALL print_char
- CI1 r2
- CI0 r1
- LWLO r0,NULL
- BZ r0,.end
- CALL print_char
- INC r1
- ADDC r2
- JUMP .loop
- .end:
- POP r0
- RET
- print_char: ; print value in r0
- PUSH r0
- .loop:
- COM r0,COM_UARTR
- ANDI r0,0b0000_0010
- XORI r0,0b0000_0010 ; invert
- BZ r0,.loop
- POP r0
- COM r0,COM_UARTW
- RET
|