From 67761f7d5710fa93e2cd60726c1b8a02776077b5 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 13 Jan 2016 06:28:21 -0500 Subject: more floating point test code --- bignum.s | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 2 deletions(-) (limited to 'bignum.s') 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 @@ -99,8 +104,71 @@ trunc_fr0: @done: 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 + jmp _big_binary_op + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; void __cdecl__ big_sub(bignump dest, bignump a, bignump b); +_big_sub: + lda #FSUB + jmp _big_binary_op + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; void __cdecl__ big_mul(bignump dest, bignump a, bignump b); +_big_mul: + lda #FMUL + jmp _big_binary_op + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; void __cdecl__ big_div(bignump dest, bignump a, bignump b); +_big_div: + lda #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 + -- cgit v1.2.3