//zig build run -- -file assembly_src/demonstrations/primes.asm -out hexdmp.txt -outfmt spi_loader4 -constants "TEXT=40000;BSS=45000;MAX_PRIME=200" // ----- RAM SECTION ----- start_section BSS index: pad 1 counter: pad 1 temp1: pad 1 sieve_data: pad MAX_PRIME pad 1 // since I'm too lazy to support arithmetics in the assembler and this isn't emitted anyways // ----- TEXT SECTION ----- start_section TEXT export __include_spi_loader 1 export __start @init // ----- ENTRYPOINT/INIT ----- init: // breakpoint to e.g. increase clock speed mv NULL, BREAK // ----- MEMORY CLEARING ----- // clear sieve memory region mv const 0, &index mem_clear_loop: mv const 0, ALU_A mv &index, ALU_B mv ALU_SUB, ALU_B mv const &sieve_data, ALU_A store_ptr const TRUE, ALU_SUB // increase index mv &index, ALU_A mv const 65535, ALU_B mv ALU_SUB, &index // jump out if we are done mv &index, ALU_B mv const MAX_PRIME, ALU_A mv ALU_SUB, ALU_A mv const @after_mem_clear, CIP_NEG mv const @mem_clear_loop, IP after_mem_clear: mv const 2, &index // ----- PRIME SEARCH ALGORITHM ----- sieve_loop: // check sieve data, if true this is a prime // add offset from index to sieve_data and store pointer mv const 0, ALU_A mv &index, ALU_B mv ALU_SUB, ALU_B mv const &sieve_data, ALU_A load_ptr ALU_SUB, ALU_A mv const @is_prime, CIP mv const @sieve_inner_loop_end, IP sieve_inner_loop_prepare: mv const 0, ALU_A mv &index, ALU_B mv ALU_SUB, &temp1 mv &index, &counter sieve_inner_loop: // add offset from counter to sieve_data and store pointer mv const 0, ALU_A mv &counter, ALU_B mv ALU_SUB, ALU_B mv const &sieve_data, ALU_A store_ptr const FALSE, ALU_SUB // increase counter by index mv &counter, ALU_A mv &temp1, ALU_B mv ALU_SUB, &counter //check if we reached or exceeded the limit mv &counter, ALU_B mv const MAX_PRIME, ALU_A mv ALU_SUB, ALU_A mv const @sieve_inner_loop_end, CIP_NEG mv const @sieve_inner_loop, IP //jump back to loop sieve_inner_loop_end: // increment index mv &index, ALU_A mv const 65535, ALU_B mv ALU_SUB, &index // check if we should be done by checking if max-index is negative mv &index, ALU_B mv const MAX_PRIME, ALU_A mv ALU_SUB, ALU_A mv const @end, CIP_NEG mv const @sieve_loop, IP is_prime: mv &index, IO_SPI_WRITE mv const @sieve_inner_loop_prepare, IP end: mv NULL, BREAK mv const @init, IP