Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit8a50432af0d883ba9ff4680004c70b6dbbc7b445 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-08-03 11:12:53 +0300
Committer
 Syndamia <kamen@syndamia.com>
2025-08-03 11:12:53 +0300
Files30a8984694e09c74c7d72280dd8428ef637c0189
c64-programs-8a50432af0d883ba9ff4680004c70b6dbbc7b445.tar
c64-programs-8a50432af0d883ba9ff4680004c70b6dbbc7b445.tar.gz
c64-programs-8a50432af0d883ba9ff4680004c70b6dbbc7b445.zip
Parentc898780ae18a1864c2d98cb56a73dd535b208a5a (diff)
feat(catalan): Implement catalan and move math subroutines to a separate file
2 files changed, 120 insertions, 101 deletions
-rw-r--r--catalan/catalan.a65151
-rw-r--r--catalan/math.a6570
diff --git a/catalan/catalan.a65 b/catalan/catalan.a65
index 36cf7c1..1a04a3e 100644
--- a/catalan/catalan.a65
+++ b/catalan/catalan.a65
@@ -1,123 +1,72 @@
#include "basic_starter.a65"
#include "kernal.a65"
+#include "math.a65"
hello .byt "HELLO, WORLD!",0
-// accumulator = a * b
-#define multiply(a, b) .( :\
- lda a ; if (a == 0) :\
- beq return ; return 0 :\
- sta buffer ; buffer = a :\
- \
- lda b ; if (b == 0) :\
- beq return ; return 0 :\
- tax ; x = b :\
- \
- lda #0 ; a = 0 :\
-loop clc ; do carry = 0 :\
- adc buffer ; a += buffer + carry :\
- dex ; --x :\
- cpx #0 ; while (x > 0) :\
- bne loop :\
-return :\
-.)
-
-// accumulator = a / b
-#define divide(a, b) .( :\
- lda b ; if (b == 0) :\
- beq return ; return 0 :\
- sta buffer ; buffer = b :\
- \
- lda a ; if (a == 0) :\
- beq return ; return 0 :\
- ldx #0 ; x = 0 :\
- \
-loop sec ; do carry = 1 :\
- sbc buffer ; a -= buffer + !carry :\
- inx ; ++x :\
- cmp buffer ; while (a >= buffer) :\
- bcs loop :\
-return txa :\
-.)
-cat_n .byt 1
-n .byt 0
-
-main
- lda #9
- sta diva_arg1
- lda #144
- jsr diva
- clc
- adc #49
+main .(
+ jsr catalan
+ lda cat_n
putchar()
rts
-
-// a *= multa_arg1
-multa .(
- ora #0 ; Update flags, so they're accurate with the accumulator value
- beq return ; if (a == 0) return a
- cmp #1 ; if (a == 1)
- beq r_arg1 ; return arg1
-
- ldx arg1 ; x = arg1
- cpx #0 ; if (x == 0)
- beq r_zero ; return 0
- cpx #1 ; if (x == 1)
- beq return ; return a
-
- dex ; --x // accumulator already has the first value
- sta addend ; addend = a
-loop clc ; do carry = 0
- adc addend ; a += addend + carry
- dex ; --x
- cpx #1 ; while (x >= 1)
- bcs loop
-
-return ora #0 ; Update flags, so they're accurate with the accumulator value
- rts
-
-r_zero lda #0
- rts
-
-r_arg1 lda arg1
- rts
-
-+multa_arg1
-arg1 .byt 0
-addend .byt 0
.)
-// a /= diva_arg1
-diva .(
- ora #0 ; Update flags, so they're accurate with the accumulator value
- beq return ; if (a == 0) return a
+#define store_in_memory(memory, value) .( :\
+ pha ; push a :\
+ lda value ; a = value :\
+ sta memory ; memory = a :\
+ pla ; pop a :\
+.)
- ldx arg1 ; x = arg1
- cpx #0 ; if (x == 0)
- beq r_zero ; return 0
- cpx #1 ; if (x == 1)
- beq return ; return a
+/* a = x
+ * a *= 4
+ * a -= 2
+ * b = x
+ * ++b
+ * a /= b
+ * a *= cat_n
+ * cat_n = a
+ */
+catalan .(
+ lda n ; a = n
+ cmp #1 ; if (a < 1)
+ bcc return ; return
- stx subtrahend ; subtrahend = x
ldx #0 ; x = 0
-loop sec ; do carry = 1
- sbc subtrahend ; a -= addend + !carry
+loop inx ; do ++x
+
+ txa ; a = x
+ ; a *= 4
+ store_in_memory(multa_arg1, #4)
+ jsr multa
+ sec ; a -= 2
+ sbc #2
+
inx ; ++x
- cmp subtrahend ; while (a >= subtrahend)
- bcs loop
+ stx divisor ; divisor = x
+ dex ; --x
-return txa
- rts
+ ; a /= divisor
+ store_in_memory(diva_arg1, divisor)
+ jsr diva
+ ; a *= cat_n
+ store_in_memory(multa_arg1, cat_n)
+ jsr multa
+ sta Cn ; Cn = a
-r_zero lda #0
- rts
+ cpx n ; while (x < n)
+ bcc loop
+return rts
-+diva_arg1
-arg1 .byt 0
-subtrahend .byt 0
++cat_Cn
+Cn .byt 1
++cat_n
+n .byt 0
+divisor .byt 0
.)
+
buffer .byt 0
// vim: noet ts=8 sw=0 lcs=tab\:\ \
diff --git a/catalan/math.a65 b/catalan/math.a65
new file mode 100644
index 0000000..ea45675
--- /dev/null
+++ b/catalan/math.a65
@@ -0,0 +1,70 @@
+#ifndef CATALAN_MATH
+#define CATALAN_MATH
+
+; a *= multa_arg1
+multa .(
+ ora #0 ; Update flags, so they're accurate with the accumulator value
+ beq return ; if (a == 0) return a
+ cmp #1 ; if (a == 1)
+ beq r_arg1 ; return arg1
+
+ ldx arg1 ; x = arg1
+ cpx #0 ; if (x == 0)
+ beq r_zero ; return 0
+ cpx #1 ; if (x == 1)
+ beq return ; return a
+
+ dex ; --x // accumulator already has the first value
+ sta addend ; addend = a
+loop clc ; do carry = 0
+ adc addend ; a += addend + carry
+ dex ; --x
+ cpx #1 ; while (x >= 1)
+ bcs loop
+
+return ora #0 ; Update flags, so they're accurate with the accumulator value
+ rts
+
+r_zero lda #0
+ rts
+
+r_arg1 lda arg1
+ rts
+
++multa_arg1
+arg1 .byt 0
+addend .byt 0
+.)
+
+; a /= diva_arg1
+diva .(
+ ora #0 ; Update flags, so they're accurate with the accumulator value
+ beq return ; if (a == 0) return a
+
+ ldx arg1 ; x = arg1
+ cpx #0 ; if (x == 0)
+ beq r_zero ; return 0
+ cpx #1 ; if (x == 1)
+ beq return ; return a
+
+ stx subtrahend ; subtrahend = x
+ ldx #0 ; x = 0
+loop sec ; do carry = 1
+ sbc subtrahend ; a -= addend + !carry
+ inx ; ++x
+ cmp subtrahend ; while (a >= subtrahend)
+ bcs loop
+
+return txa
+ rts
+
+r_zero lda #0
+ rts
+
++diva_arg1
+arg1 .byt 0
+subtrahend .byt 0
+.)
+
+#endif /* CATALAN_MATH */
+// vim: noet ts=9 sw=0 lcs=tab\:\ \