Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit6d08ffeee63a9b4d114542eb9ee59589eed573d2 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-07-31 17:10:06 +0300
Committer
 Syndamia <kamen@syndamia.com>
2025-07-31 17:10:06 +0300
Files7115c0a86624ff600030c1a8b976c82a0861ff45
c64-programs-6d08ffeee63a9b4d114542eb9ee59589eed573d2.tar
c64-programs-6d08ffeee63a9b4d114542eb9ee59589eed573d2.tar.gz
c64-programs-6d08ffeee63a9b4d114542eb9ee59589eed573d2.zip
Parenta2325fbab98108fd061913c3b42ff1b0325f8e27 (diff)
feat(isprime): Print numbers and their prime results for a (dynamic) range of values
2 files changed, 126 insertions, 35 deletions
-rw-r--r--isprime/isprime.oph.s82
-rw-r--r--isprime/kernal.oph.s79
diff --git a/isprime/isprime.oph.s b/isprime/isprime.oph.s
index e4824fa..e58852b 100644
--- a/isprime/isprime.oph.s
+++ b/isprime/isprime.oph.s
@@ -6,50 +6,64 @@
.require "basic_starter.oph.s"
.require "kernal.oph.s"
-number: .word 15
+.alias check_first 97
+.alias check_last 104
main:
+.scope
`lowercase
- jsr isprime ; a = isprime(number)
- bne + ; if (a == 0)
- `print no ; print "No"
- rts ; return
-* `print yes ; else print "Yes"
- rts ; return
-isprime:
-.scope
- lda #1 ; if (number & 0b0001 == 0)
- and number
- beq _end ; return False
- ;`mod number, 3 ; if (number % 3 == 0)
- ;beq _end ; return False
- lda number
- ldx #3
- stx mod_n
- jsr mod_addr
+ ldx #check_first ; x = check_first
+* jsr printx ; do print x
+ lda #32 ; print " "
+ jsr putchar
+ jsr isprimex_cli ; print isprime(x)
+ lda #13 ; print "\n"
+ jsr putchar
+
+ inx ; ++x
+ txa ; while (x <= check_last)
+ cmp #check_last
+ bcc -
+ beq -
+
_end: rts
.scend
-.macro mod ; 12 cycles (2+4+2+2+2) raw
- sec ; carry = 0
- lda _1 ; a = _1
-_loop: sbc #_2 ; do a -= _2 + carry
- beq _end ; if (a == 0) break
- bpl _loop ; while (a >= 0)
-_end:
-.macend
-
-mod_n: .word 0
+isprimex_cli:
+ jsr isprimex ; a = isprime(number)
+ beq + ; if (a != 0)
+ `print yes ; print "Yes"
+ rts ; return
+* `print no ; else print "No"
+ rts ; return
-; a % mod_n
-mod_addr: ; 16 cycles (2+4+2+2+6) raw + 18 cycles (4+4+4+6) raw for arguments
+isprimex:
.scope
- sec ; carry = 0
-_loop: sbc mod_n ; do a -= mod_n + carry
- beq _end ; if (a == 0) break
- bpl _loop ; while (a >= 0)
+ sec ; if (number < 2) // equivalent to "number <= 1"
+ txa ; // a = x
+ sbc #2 ; // a -= 2 + 0
+ bmi _negative ; return False
+
+ sbc #2 ; if (number < 2) // since it was already subtracted, this is equal to "number < 4" or "number <= 3"
+ bmi _end ; return True
+
+ txa ; if (number % 2 == 0)
+ and #1 ; // number & 0b0001 == 0
+ beq _end ; return False
+
+ txa
+ `mod 3 ; if (number % 3 == 0)
+ beq _end ; return False
+
+ ;lda number
+ ;ldx #3
+ ;stx mod_n
+ ;jsr mod_addr
_end: rts
+
+_negative: lda #0
+ rts
.scend
.charmap 'A, "abcdefghijklmnopqrstuvwxyz"
diff --git a/isprime/kernal.oph.s b/isprime/kernal.oph.s
index a9fd007..b39d212 100644
--- a/isprime/kernal.oph.s
+++ b/isprime/kernal.oph.s
@@ -2,13 +2,90 @@
; print [null-terminated string start address]
.macro print
+ txa ; backup = x
+ pha
ldx #0 ; x = 0
_loop: lda _1, x ; while (_1[x] != 0) {
beq _done
jsr putchar ; putchar(_1[x])
inx ; ++x
bne _loop ; if (x == 0) break } This allows max 255 character to be read
- _done:
+ _done: pla ; x = backup
+ tax
+.macend
+
+printx:
+.scope
+ txa ; a = x
+ cmp #10 ; if (a < 10)
+ bcc _1digit
+ cmp #100 ; if (a < 100)
+ bcc _2digit
+
+_3digit: pha
+ `div 100
+ clc
+ adc #'0
+ jsr putchar
+ pla
+ `mod 100
+
+_2digit: pha
+ `div 10
+ clc
+ adc #'0
+ jsr putchar
+ pla
+ `mod 10
+
+_1digit: clc
+ adc #'0
+ jsr putchar
+ rts
+.scend
+
+; a = a % _1
+.macro mod ; 10 cycles (2+2+2+2+2) raw
+ cmp #_1 ; if (a < _1) return
+ bcc _end
+
+ sec ; carry = 1
+_loop: sbc #_1 ; do a -= _1 + !carry
+ beq _end ; if (a == 0) break
+ cmp #_1 ; while (a >= _1)
+ bcs _loop
+_end:
+.macend
+
+buffer: .byte 0
+
+; a = a / _1
+.macro div
+ ora #0 ; The CMP (and friends) instruction changes the carry and zero flag,
+ ; which can cause the flags (and therefore the branch instructions)
+ ; to get "desynced" with the actual accumulator value.
+ ; With this instruction, we force a "refresh" of the flags.
+ ; It took me half an hour to figure this out...
+
+ beq _return ; if (a == 0) return 0
+ cmp #_1 ; if (a < _1) return 0
+ bcc _zero
+
+ stx buffer ; buffer = x
+ ldx #0 ; x = 0
+ sec ; carry = 1
+_loop: sbc #_1 ; a -= _1 + !carry
+ inx ; ++x
+ beq _end ; if (a == 0) break
+ cmp #_1 ; while (a >= _1)
+ bcs _loop
+
+_end: txa ; a = x
+ ldx buffer ; x = buffer
+ jmp _return
+
+_zero: lda #0
+_return:
.macend
.macro lowercase