%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 REG0 LWHI CALL print_hex REG0 LWLO CALL print_hex REG0 0x20 CALL print_char %endmacro %macro PRINTREG 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 2x3x8192 DBE 1 intro_text: DB 0x1B,"c",0x1B,"[HBooting ",0x1B,"[1m",0x1B,"[36m","OISC",0x1B,"[0m system..",LFCR,0 generalbuf: DBE 1 generalbuf2: 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 section .text 2x3x2048 REG0 intro_text@0 REG1 intro_text@1 CALL print_string ;; test mul_u16 MEMP generalbuf REG0 60001@0 ; num1 lo REG1 60001@1 ; num1 hi MEMLO 344@0 ; num2 lo MEMHI 344@1 ; num2 hi MEMLO CALL mod_u16 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 REG0 '@' CALL print_char CALL calc_sieve REG0 '@' CALL print_char CALL println ;JUMP forever REG0 0 .print_sieve: CALC_SIEVE_POINTER REG0,REG1,.hi,'x' ALU0 MEMLO JUMP .next .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 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: ;JUMP forever $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 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 REG1 ; BRP .endp1 ; BRZ EQ ; if x^2 >= 2^16 ; ALU0 REG0 ; BRZ EQ ; if x^2 >= 2^16 ; ; ; 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 REG1 ; BRP .loopxe ; BRZ EQ ; if y^2 >= 2^16 ; ALU0 REG0 ; BRZ EQ ; if y^2 >= 2^16 ; ; ; ================== ; ; Start of Main loop ; ; ================== ; ; ;MEMP sieve1 ; ; %def $nh,MEMHI ; %def $nl,MEMLO ; %def $tmp,MEMLO ;.c1: ; MEMP sieve_x2 ; COPY sieve1 ; copy x^2 to n ; REG0 4 ; REG1 0 ; CALL mul_u16 ; x^2 * 0x0004 ; ALU0 REG1 ; \ ; ALU1 0 ; | ; BRP .c2 ; | checking if 4*x^2 overflow ; BRZ EQ ; | ; ALU0 REG0 ; | ; BRZ EQ ; / ; ; n += y^2 ; REG0 $nl ; REG1 $nh ; MEMP sieve_y2 ; ALU0 REG0 ; $nl ; ALU1 MEMLO ; $y2l ; REG0 ADD ; ALU0 REG1 ; ALU1 MEMHI ; REG1 ADC ; ALU0 ADDC ; \ ; ALU1 0 ; | chcek for 4*x^2+y^2 oveflow ; BNE .c2 ; / ; ; ; %def $n,REG0; to be deleted ; ALU0 REG0 ; ALU1 4 ; STACK MULLO ; ALU0 MULHI ; \ ; ALU1 0 ; | Checking if 4x^2 > 255 ; ALU1 EQ ; / ; ALU0 STACK ; BRPZ .c2,ALU1 ; if mulhi != 0: goto .c2 ; ALU1 REG1 ; $n ADD ; n = mullo( low{4*x^2} ) + y^2 ; ALU0 ADDC ; \ ; ALU1 0 ; | Checking if 4x^2+y^2 > 255 ; BNE .c2 ; / ; ALU0 $n ; MEMHI := n ; ALU1 12 ; $tmp MOD ; ALU0 $tmp ; ALU1 1 ; BEQ .c1r ; n%12 == 1 ; ALU0 $tmp ; ALU1 5 ; BEQ .c1r ; n%12 == 5 ; JUMP .c2 ;.c1r: ; CALL xorSieveArray ; MEMP sieve1 ;.c2: ; ALU0 REG0 ; ALU1 3 ; STACK MULLO ; ALU0 MULHI ; \ ; ALU1 0 ; | Checking if 3x^2 > 255 ; ALU1 EQ ; / ; ALU0 STACK ; BRPZ .c3,ALU1 ; ALU1 REG1 ; STACK ADD ; ALU0 ADDC ; \ ; ALU1 0 ; | Checking if 3x^2+y^2 > 255 ; ALU1 EQ ; / ; ALU0 STACK ; BRPZ .c3,ALU1 ; $n ALU0 ; MEMHI := n ; ALU1 12 ; ALU0 MOD ; ALU1 7 ; BNE .c3 ; CALL xorSieveArray ;.c3: ; ;MEMP sieve ; ;ALU1 $y ; y ; ;ALU0 $x ; x ; BLE .loopye ; Function needs x>y ; ; MEMP sieve1 ; ALU0 REG0 ; ALU1 3 ; $tmp MULHI ; MEMLO := HIGH(3x^2) ; ALU0 MULLO ; ALU1 REG1 ; $n SUB ; MEMHI := LOW(3x^2)-y^2 ; ALU0 $tmp ; ALU1 0x00 ; ALU0 SBC ; ALU0 := HIGH(3x^2)-CARRY(y^2) ; BNE .c4 ; ALU0 != 0x00: goto .c4 ; ALU0 $n ; \ ; ALU1 12 ; | ; ALU0 MOD ; | Checking if n%12 != 11 ; ALU1 11 ; | ; BNE .c4 ; / ; CALL xorSieveArray ;.c4: ; ;MEMP sieve ; ; ================ ; ; 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: ; n := memhi ; sieve[n;16] ^= 1<