diff options
| Commit | 6d08ffeee63a9b4d114542eb9ee59589eed573d2 (patch) | |
|---|---|---|
| Author | 2025-07-31 17:10:06 +0300 | |
| Committer | 2025-07-31 17:10:06 +0300 | |
| Files | 7115c0a86624ff600030c1a8b976c82a0861ff45 | |
| c64-programs-6d08ffeee63a9b4d114542eb9ee59589eed573d2.tar c64-programs-6d08ffeee63a9b4d114542eb9ee59589eed573d2.tar.gz c64-programs-6d08ffeee63a9b4d114542eb9ee59589eed573d2.zip | ||
| Parent | a2325fbab98108fd061913c3b42ff1b0325f8e27 (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.s | 82 | ||||
| -rw-r--r-- | isprime/kernal.oph.s | 79 |
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 |
