aboutsummaryrefslogtreecommitdiff
path: root/bignum.s
diff options
context:
space:
mode:
Diffstat (limited to 'bignum.s')
-rw-r--r--bignum.s117
1 files changed, 115 insertions, 2 deletions
diff --git a/bignum.s b/bignum.s
index 56f1299..06e99ab 100644
--- a/bignum.s
+++ b/bignum.s
@@ -1,14 +1,18 @@
.importzp ptr3, ptr4, sreg
- .import popeax, popax
- .export _ulong_to_big, _big_to_ulong
+ .import popeax, popax, pushax, _memcmp
+ .export _ulong_to_big, _big_to_ulong, _big_add, _big_sub, _big_mul, _big_div
+ .export _bank_maxed_out, _big_cmp
.include "atari.inc"
;IFP = $d9aa
fptemp = $a0 ; for now
+ trampoline = $c0
+
+ NORMALIZE = $dc00
.rodata
BIG_64K:
@@ -75,6 +79,7 @@ ptr4_to_fr1:
bpl @l
rts
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; truncate FR0 to integer (no rounding: 2.8 -> 2)
trunc_fr0:
lda FR0
@@ -100,7 +105,70 @@ trunc_fr0:
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void __fastcall__ big_binary_op(bignump dest, bignump a, bignump b, unsigned int jsraddr);
+_big_binary_op:
+
+ ; JSR address in A/X pair, set up JMP instruction
+ sta trampoline+1
+ stx trampoline+2
+ lda #$4c ; JMP opcode
+ sta trampoline
+
+ ; get 2nd operand (b), load into FR1
+ jsr popax
+ sta FLPTR
+ stx FLPTR+1
+ jsr PLD1P
+
+ ; get 1st operand (a), load into FR0
+ jsr popax
+ sta FLPTR
+ stx FLPTR+1
+ jsr FLD0P
+
+ ; call the FP routine
+ jsr trampoline
+
+; jsr NORMALIZE
+; .byte $02
+
+ ; result now in FR0, get destination & copy
+ jsr popax
+ sta FLPTR
+ stx FLPTR+1
+ jmp FST0P
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void __cdecl__ big_add(bignump dest, bignump a, bignump b);
+_big_add:
+ lda #<FADD
+ ldx #>FADD
+ jmp _big_binary_op
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void __cdecl__ big_sub(bignump dest, bignump a, bignump b);
+_big_sub:
+ lda #<FSUB
+ ldx #>FSUB
+ jmp _big_binary_op
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void __cdecl__ big_mul(bignump dest, bignump a, bignump b);
+_big_mul:
+ lda #<FMUL
+ ldx #>FMUL
+ jmp _big_binary_op
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void __cdecl__ big_div(bignump dest, bignump a, bignump b);
+_big_div:
+ lda #<FDIV
+ ldx #>FDIV
+ jmp _big_binary_op
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; void __fastcall__ big_trunc(bignump b);
+; C-callable wrapper for trunc_fr0
sta FLPTR
stx FLPTR+1
jsr FLD0P
@@ -188,6 +256,7 @@ _big_to_ulong:
ldx sreg ; reload original *b in FR0
ldy sreg+1
jsr FLD0R
+ jsr trunc_fr0 ; grrr. If we don't do this, we get rounding (not desired)
jsr FSUB ; FR0 = FR0 - FR1
jsr FPI
@@ -203,3 +272,47 @@ _big_to_ulong:
tya
ldx #0
rts
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; char __fastcall__ bank_maxed_out(bignump b);
+_bank_maxed_out:
+ sta FLPTR
+ stx FLPTR+1
+ jsr FLD0P
+ jsr NORMALIZE ; just in case
+ lda FR0 ; get exponent
+ ldx #0
+ eor #$7f ; remove sign bit (should never be negative anyway!)
+ cmp #$46
+ bcc @false
+ lda #1
+ rts
+@false:
+ txa
+ rts
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; signed char __fastcall__ big_cmp(bignump a, bignump b)
+;
+; this could be better: it could be a wrapper for _big_binary_op. But
+; I'd have to move stuff all around on the stack.
+_big_cmp:
+ sta FLPTR
+ stx FLPTR+1
+ jsr FLD0P
+
+ jsr FMOVE ; move to FR1 (since it's the 2nd arg)
+
+ jsr popax ; get a arg
+
+ sta FLPTR
+ stx FLPTR+1
+ jsr FLD0P
+
+ ; subtract (and throw away the result, only care about sign)
+ jsr FSUB ; FR0 = FR0 - FR1
+
+ ldx #0
+ lda FR0 ; exponent has sign bit, and happily is 0 if the result was 0!
+ rts
+