diff --git a/compiler/res/prog8lib/c128/floats.asm b/compiler/res/prog8lib/c128/floats.asm new file mode 100644 index 000000000..a5fcf0fc9 --- /dev/null +++ b/compiler/res/prog8lib/c128/floats.asm @@ -0,0 +1,683 @@ +; --- low level floating point assembly routines for the C128 +; these are almost all identical to the C64 except for a few details +; so we have to have a separate library file for the C128 unfortunately. + + +FL_ONE_const .byte 129 ; 1.0 +FL_ZERO_const .byte 0,0,0,0,0 ; 0.0 +FL_LOG2_const .byte $80, $31, $72, $17, $f8 ; log(2) + + +floats_store_reg .byte 0 ; temp storage + + +ub2float .proc + ; -- convert ubyte in SCRATCH_ZPB1 to float at address A/Y + ; clobbers A, Y + stx P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy P8ZP_SCRATCH_B1 + lda #0 + jsr GIVAYF +_fac_to_mem ldx P8ZP_SCRATCH_W2 + ldy P8ZP_SCRATCH_W2+1 + jsr MOVMF + ldx P8ZP_SCRATCH_REG + rts + .pend + +b2float .proc + ; -- convert byte in SCRATCH_ZPB1 to float at address A/Y + ; clobbers A, Y + stx P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda P8ZP_SCRATCH_B1 + jsr FREADSA + jmp ub2float._fac_to_mem + .pend + +uw2float .proc + ; -- convert uword in SCRATCH_ZPWORD1 to float at address A/Y + stx P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr GIVUAYFAY + jmp ub2float._fac_to_mem + .pend + +w2float .proc + ; -- convert word in SCRATCH_ZPWORD1 to float at address A/Y + stx P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy P8ZP_SCRATCH_W1 + lda P8ZP_SCRATCH_W1+1 + jsr GIVAYF + jmp ub2float._fac_to_mem + .pend + + +cast_from_uw .proc + ; -- uword in A/Y into float var at (P8ZP_SCRATCH_W2) + stx P8ZP_SCRATCH_REG + jsr GIVUAYFAY + jmp ub2float._fac_to_mem + .pend + + +cast_from_w .proc + ; -- word in A/Y into float var at (P8ZP_SCRATCH_W2) + stx P8ZP_SCRATCH_REG + jsr GIVAYFAY + jmp ub2float._fac_to_mem + .pend + + +cast_from_ub .proc + ; -- ubyte in Y into float var at (P8ZP_SCRATCH_W2) + stx P8ZP_SCRATCH_REG + jsr FREADUY + jmp ub2float._fac_to_mem + .pend + + +cast_from_b .proc + ; -- byte in A into float var at (P8ZP_SCRATCH_W2) + stx P8ZP_SCRATCH_REG + jsr FREADSA + jmp ub2float._fac_to_mem + .pend + +cast_as_uw_into_ya .proc ; also used for float 2 ub + ; -- cast float at A/Y to uword into Y/A + jsr MOVFM + jmp cast_FAC1_as_uw_into_ya + .pend + +cast_as_w_into_ay .proc ; also used for float 2 b + ; -- cast float at A/Y to word into A/Y + jsr MOVFM + jmp cast_FAC1_as_w_into_ay + .pend + +cast_FAC1_as_uw_into_ya .proc ; also used for float 2 ub + ; -- cast fac1 to uword into Y/A + stx P8ZP_SCRATCH_REG + jsr GETADR ; into Y/A + ldx P8ZP_SCRATCH_REG + rts + .pend + +cast_FAC1_as_w_into_ay .proc ; also used for float 2 b + ; -- cast fac1 to word into A/Y + stx P8ZP_SCRATCH_REG + jsr AYINT + ldy $66 + lda $67 + ldx P8ZP_SCRATCH_REG + rts + .pend + + +stack_b2float .proc + ; -- b2float operating on the stack + inx + lda P8ESTACK_LO,x + stx P8ZP_SCRATCH_REG + jsr FREADSA + jmp push_fac1._internal + .pend + +stack_w2float .proc + ; -- w2float operating on the stack + inx + ldy P8ESTACK_LO,x + lda P8ESTACK_HI,x + stx P8ZP_SCRATCH_REG + jsr GIVAYF + jmp push_fac1._internal + .pend + +stack_ub2float .proc + ; -- ub2float operating on the stack + inx + lda P8ESTACK_LO,x + stx P8ZP_SCRATCH_REG + tay + lda #0 + jsr GIVAYF + jmp push_fac1._internal + .pend + +stack_uw2float .proc + ; -- uw2float operating on the stack + inx + lda P8ESTACK_LO,x + ldy P8ESTACK_HI,x + stx P8ZP_SCRATCH_REG + jsr GIVUAYFAY + jmp push_fac1._internal + .pend + +stack_float2w .proc ; also used for float2b + jsr pop_float_fac1 + stx P8ZP_SCRATCH_REG + jsr AYINT + ldx P8ZP_SCRATCH_REG + lda $66 + sta P8ESTACK_HI,x + lda $67 + sta P8ESTACK_LO,x + dex + rts + .pend + +stack_float2uw .proc ; also used for float2ub + jsr pop_float_fac1 + stx P8ZP_SCRATCH_REG + jsr GETADR + ldx P8ZP_SCRATCH_REG + sta P8ESTACK_HI,x + tya + sta P8ESTACK_LO,x + dex + rts + .pend + +push_float .proc + ; ---- push mflpt5 in A/Y onto stack + ; (taking 3 stack positions = 6 bytes of which 1 is padding) + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + ldy #0 + lda (P8ZP_SCRATCH_W1),y + sta P8ESTACK_LO,x + iny + lda (P8ZP_SCRATCH_W1),y + sta P8ESTACK_HI,x + dex + iny + lda (P8ZP_SCRATCH_W1),y + sta P8ESTACK_LO,x + iny + lda (P8ZP_SCRATCH_W1),y + sta P8ESTACK_HI,x + dex + iny + lda (P8ZP_SCRATCH_W1),y + sta P8ESTACK_LO,x + dex + rts + .pend + +pop_float .proc + ; ---- pops mflpt5 from stack to memory A/Y + ; (frees 3 stack positions = 6 bytes of which 1 is padding) + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + ldy #4 + inx + lda P8ESTACK_LO,x + sta (P8ZP_SCRATCH_W1),y + dey + inx + lda P8ESTACK_HI,x + sta (P8ZP_SCRATCH_W1),y + dey + lda P8ESTACK_LO,x + sta (P8ZP_SCRATCH_W1),y + dey + inx + lda P8ESTACK_HI,x + sta (P8ZP_SCRATCH_W1),y + dey + lda P8ESTACK_LO,x + sta (P8ZP_SCRATCH_W1),y + rts + .pend + +pop_float_fac1 .proc + ; -- pops float from stack into FAC1 + lda #fmath_float1 + jsr pop_float + lda #fmath_float1 + jmp MOVFM + .pend + +copy_float .proc + ; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_ZPWORD1, + ; into the 5 bytes pointed to by A/Y. Clobbers A,Y. + sta _target+1 + sty _target+2 + ldy #4 +_loop lda (P8ZP_SCRATCH_W1),y +_target sta $ffff,y ; modified + dey + bpl _loop + rts + .pend + +inc_var_f .proc + ; -- add 1 to float pointed to by A/Y + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + stx P8ZP_SCRATCH_REG + jsr MOVFM + lda #FL_ONE_const + jsr FADD + ldx P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr MOVMF + ldx P8ZP_SCRATCH_REG + rts + .pend + +dec_var_f .proc + ; -- subtract 1 from float pointed to by A/Y + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + stx P8ZP_SCRATCH_REG + lda #FL_ONE_const + jsr MOVFM + lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr FSUB + ldx P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr MOVMF + ldx P8ZP_SCRATCH_REG + rts + .pend + + +pop_2_floats_f2_in_fac1 .proc + ; -- pop 2 floats from stack, load the second one in FAC1 as well + lda #fmath_float2 + jsr pop_float + lda #fmath_float1 + jsr pop_float + lda #fmath_float2 + jmp MOVFM + .pend + + +fmath_float1 .byte 0,0,0,0,0 ; storage for a mflpt5 value +fmath_float2 .byte 0,0,0,0,0 ; storage for a mflpt5 value + + +push_fac1 .proc + ; -- push the float in FAC1 onto the stack + stx P8ZP_SCRATCH_REG +_internal ldx #fmath_float1 + jsr MOVMF + lda #fmath_float1 + ldx P8ZP_SCRATCH_REG + jmp push_float + .pend + + +pow_f .proc + ; -- push f1 ** f2 on stack + lda #fmath_float2 + jsr pop_float + lda #fmath_float1 + jsr pop_float + stx P8ZP_SCRATCH_REG + lda #fmath_float1 + jsr ROMUPK ; fac2 = float1 + lda #fmath_float2 + jsr FPWR + jmp push_fac1._internal + .pend + +div_f .proc + ; -- push f1/f2 on stack + jsr pop_2_floats_f2_in_fac1 + stx P8ZP_SCRATCH_REG + lda #fmath_float1 + jsr FDIV + jmp push_fac1._internal + .pend + +add_f .proc + ; -- push f1+f2 on stack + jsr pop_2_floats_f2_in_fac1 + stx P8ZP_SCRATCH_REG + lda #fmath_float1 + jsr FADD + jmp push_fac1._internal + .pend + +sub_f .proc + ; -- push f1-f2 on stack + jsr pop_2_floats_f2_in_fac1 + stx P8ZP_SCRATCH_REG + lda #fmath_float1 + jsr FSUB + jmp push_fac1._internal + .pend + +mul_f .proc + ; -- push f1*f2 on stack + jsr pop_2_floats_f2_in_fac1 + stx P8ZP_SCRATCH_REG + lda #fmath_float1 + jsr FMULT + jmp push_fac1._internal + .pend + +neg_f .proc + ; -- toggle the sign bit on the stack + lda P8ESTACK_HI+3,x + eor #$80 + sta P8ESTACK_HI+3,x + rts + .pend + +var_fac1_less_f .proc + ; -- is the float in FAC1 < the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #255 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_lesseq_f .proc + ; -- is the float in FAC1 <= the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #0 + beq + + cmp #255 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_greater_f .proc + ; -- is the float in FAC1 > the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #1 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_greatereq_f .proc + ; -- is the float in FAC1 >= the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #0 + beq + + cmp #1 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_notequal_f .proc + ; -- are the floats numbers in FAC1 and the variable AY *not* identical? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + and #1 + rts + .pend + +vars_equal_f .proc + ; -- are the mflpt5 numbers in P8ZP_SCRATCH_W1 and AY identical? + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy #0 + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + lda #1 + rts +_false lda #0 + rts + .pend + +equal_f .proc + ; -- are the two mflpt5 numbers on the stack identical? + inx + inx + inx + inx + lda P8ESTACK_LO-3,x + cmp P8ESTACK_LO,x + bne _equals_false + lda P8ESTACK_LO-2,x + cmp P8ESTACK_LO+1,x + bne _equals_false + lda P8ESTACK_LO-1,x + cmp P8ESTACK_LO+2,x + bne _equals_false + lda P8ESTACK_HI-2,x + cmp P8ESTACK_HI+1,x + bne _equals_false + lda P8ESTACK_HI-1,x + cmp P8ESTACK_HI+2,x + bne _equals_false +_equals_true lda #1 +_equals_store inx + sta P8ESTACK_LO+1,x + rts +_equals_false lda #0 + beq _equals_store + .pend + +notequal_f .proc + ; -- are the two mflpt5 numbers on the stack different? + jsr equal_f + eor #1 ; invert the result + sta P8ESTACK_LO+1,x + rts + .pend + +vars_less_f .proc + ; -- is float in AY < float in P8ZP_SCRATCH_W2 ? + jsr MOVFM + lda P8ZP_SCRATCH_W2 + ldy P8ZP_SCRATCH_W2+1 + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #255 + bne + + lda #1 + rts ++ lda #0 + rts + .pend + +vars_lesseq_f .proc + ; -- is float in AY <= float in P8ZP_SCRATCH_W2 ? + jsr MOVFM + lda P8ZP_SCRATCH_W2 + ldy P8ZP_SCRATCH_W2+1 + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #255 + bne + +- lda #1 + rts ++ cmp #0 + beq - + lda #0 + rts + .pend + +less_f .proc + ; -- is f1 < f2? + jsr compare_floats + cmp #255 + beq compare_floats._return_true + bne compare_floats._return_false + .pend + + +lesseq_f .proc + ; -- is f1 <= f2? + jsr compare_floats + cmp #255 + beq compare_floats._return_true + cmp #0 + beq compare_floats._return_true + bne compare_floats._return_false + .pend + +greater_f .proc + ; -- is f1 > f2? + jsr compare_floats + cmp #1 + beq compare_floats._return_true + bne compare_floats._return_false + .pend + +greatereq_f .proc + ; -- is f1 >= f2? + jsr compare_floats + cmp #1 + beq compare_floats._return_true + cmp #0 + beq compare_floats._return_true + bne compare_floats._return_false + .pend + +compare_floats .proc + lda #fmath_float2 + jsr pop_float + lda #fmath_float1 + jsr pop_float + lda #fmath_float1 + jsr MOVFM ; fac1 = flt1 + lda #fmath_float2 + stx P8ZP_SCRATCH_REG + jsr FCOMP ; A = flt1 compared with flt2 (0=equal, 1=flt1>flt2, 255=flt1 signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY) +romsub $af00 = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 102-103 ($66-$67) MSB FIRST. (might throw ILLEGAL QUANTITY) ; GIVAYF: signed word in Y/A (note different lsb/msb order) -> float in fac1 ; there is also floats.GIVUAYFAY - unsigned word in A/Y (lo/hi) to fac1 ; (tip: use GIVAYFAY to use A/Y input; lo/hi switched to normal order) -romsub $fe03 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) +romsub $af03 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) +romsub $af09 = VAL(ubyte length @ A) clobbers(A,X,Y) ; str -> fac1, $24/25 must point to string in bank1, A=string length Don't call this from bank0 -; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15) +; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $16/17) ; (tip: use GETADRAY to get A/Y output; lo/hi switched to normal little endian order) -romsub $fe06 = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A +romsub $af0c = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A -romsub $fe09 = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for rounding- call this before INT -romsub $fe0c = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1 -romsub $fe0f = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands -romsub $fe12 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y -romsub $fe15 = FADDT() clobbers(A,X,Y) ; fac1 += fac2 -romsub $fe1b = ZEROFC() clobbers(A,X,Y) ; fac1 = 0 -romsub $fe1e = NORMAL() clobbers(A,X,Y) ; normalize fac1 (?) -romsub $fe24 = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) -romsub $fe27 = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y -romsub $fe2a = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 -romsub $fe30 = CONUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac2 -romsub $fe33 = MUL10() clobbers(A,X,Y) ; fac1 *= 10 -romsub $fe36 = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! -romsub $fe39 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 (remainder in fac2) -romsub $fe3c = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands +romsub $af12 = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1 +romsub $af15 = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands +romsub $af18 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y in bank 1 +romsub $af1b = FADDT() clobbers(A,X,Y) ; fac1 += fac2 +romsub $af2a = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) +romsub $af1e = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y +romsub $af21 = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 +romsub $af5a = CONUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory bank 1 in A/Y into fac2 +romsub $af5d = ROMUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in current bank in A/Y into fac2 +romsub $af24 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 (remainder in fac2) +romsub $af27 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands -romsub $fe42 = MOVFM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 -romsub $fe45 = MOVMF(uword mflpt @ XY) clobbers(A,X,Y) ; store fac1 to memory X/Y as 5-byte mflpt -romsub $fe48 = MOVFA() clobbers(A,X) ; copy fac2 to fac1 -romsub $fe4b = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded) -romsub $fe4e = MOVEF() clobbers(A,X) ; copy fac1 to fac2 -romsub $fe54 = SIGN() clobbers(X,Y) -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive -romsub $fe57 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) -romsub $fe5a = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1 -romsub $fe66 = ABS() clobbers(A,X,Y) ; fac1 = ABS(fac1) -romsub $fe69 = FCOMP(uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than -romsub $fe72 = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to round instead of trunc -romsub $fe78 = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A -romsub $fe7b = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY -romsub $fe81 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) -romsub $fe84 = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 -romsub $fe8a = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) -romsub $fe8d = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) -romsub $fe96 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator -romsub $fe99 = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) -romsub $fe9c = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) -romsub $fe9f = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) -romsub $fea2 = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) +romsub $af63 = MOVFM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 +romsub $af60 = MOVFRM() clobbers(A,X,Y) ; load mflpt value from memory in $24/$25 into fac2 +romsub $af66 = MOVMF(uword mflpt @ XY) clobbers(A,X,Y) ; store fac1 to memory X/Y as 5-byte mflpt +romsub $af69 = MOVFA() clobbers(A,X) ; copy fac2 to fac1 +romsub $af6c = MOVAF() clobbers(A,X) ; copy fac1 to fac2 +romsub $af6c = MOVEF() clobbers(A,X) ; copy fac1 to fac2 +romsub $af51 = SIGN() clobbers(X,Y) -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive +romsub $af4e = ABS() clobbers(A,X,Y) ; fac1 = ABS(fac1) +romsub $af54 = FCOMP(uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than +romsub $af2d = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to round instead of trunc +romsub $af06 = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY ($0100) +romsub $af30 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) +romsub $af36 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** mflpt from A/Y +romsub $af39 = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 +romsub $af33 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) +romsub $af3c = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) +romsub $af57 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator +romsub $af3f = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) +romsub $af42 = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) +romsub $af45 = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) +romsub $af48 = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) +asmsub FREADSA (byte value @A) clobbers(A,X,Y) { + ; ---- 8 bit signed A -> float in fac1 + %asm {{ + tay + bpl + + lda #$ff + jmp GIVAYF ++ lda #0 + jmp GIVAYF + }} +} + asmsub GIVUAYFAY (uword value @ AY) clobbers(A,X,Y) { ; ---- unsigned 16 bit word in A/Y (lo/hi) to fac1 %asm {{ @@ -87,7 +93,8 @@ asmsub GIVUAYFAY (uword value @ AY) clobbers(A,X,Y) { bpl + lda #<_flt65536 ldy #>_flt65536 - jsr FADD + jsr ROMUPK + jsr FADDT + ldx P8ZP_SCRATCH_REG rts _tmp .byte 0 @@ -106,17 +113,6 @@ asmsub GIVAYFAY (uword value @ AY) clobbers(A,X,Y) { }} } -asmsub FTOSWRDAY () clobbers(X) -> uword @ AY { - ; ---- fac1 to signed word in A/Y - %asm {{ - jsr FTOSWORDYA ; note the inverse Y/A order - sta P8ZP_SCRATCH_B1 - tya - ldy P8ZP_SCRATCH_B1 - rts - }} -} - asmsub GETADRAY () clobbers(X) -> uword @ AY { ; ---- fac1 to unsigned word in A/Y %asm {{ @@ -157,7 +153,7 @@ sub print_f (float value) { }} } -%asminclude "library:c64/floats.asm" +%asminclude "library:c128/floats.asm" %asminclude "library:c64/floats_funcs.asm" } diff --git a/examples/test.p8 b/examples/test.p8 index 2edcb4761..75c94e97a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,16 +1,104 @@ %import textio +%import floats main { sub start() { - str input = "?" * 20 - c128.disable_basic() - txt.lowercase() - txt.print("Hello There! Enter Your Name: ") - void txt.input_chars(input) - txt.nl() + + test_val() + repeat { - txt.print(input) - txt.spc() } } + + sub test_val() { + + ; TODO c128 how do I set this in "bank 1" ? VAL() needs that... + + str @shared value = "-1.23456" + uword @shared result + %asm {{ + stx P8ZP_SCRATCH_B1 + lda #value + sta $25 + lda #8 + jsr floats.VAL + jsr floats.FOUT + sta result + sty result+1 + ldx P8ZP_SCRATCH_B1 + }} + txt.print_uwhex(result, true) + txt.nl() + txt.print(result) + txt.nl() + txt.print($0100) + txt.nl() + } + + sub test_freadsa() { + uword @shared result + %asm {{ + stx P8ZP_SCRATCH_B1 + ;lda #-123 + ;jsr floats.FREADSA + lda #<55444 + ldy #>55444 + jsr floats.GIVUAYFAY + jsr floats.FOUT + sta result + sty result+1 + ldx P8ZP_SCRATCH_B1 + }} + txt.print_uwhex(result, true) + txt.nl() + txt.print(result) + txt.nl() + txt.print($0100) + txt.nl() + } + + sub test_getadr() { + uword @shared value + %asm {{ + stx P8ZP_SCRATCH_B1 + lda #<23456 + ldy #>23456 + jsr floats.GIVAYFAY + jsr floats.GETADRAY + sta value + sty value+1 + ldx P8ZP_SCRATCH_B1 + }} + txt.print_uw(value) + txt.nl() + } + + sub test_ayint() { + %asm {{ + stx P8ZP_SCRATCH_B1 + lda #<-23456 + ldy #>-23456 + jsr floats.GIVAYFAY + jsr floats.AYINT + ldx P8ZP_SCRATCH_B1 + }} + word value = mkword(@($66), @($67)) as word + txt.print_w(value) + txt.nl() + } + + sub test_printf() { + floats.print_f(0) + txt.nl() + floats.print_f(1) + txt.nl() + floats.print_f(-1) + txt.nl() + floats.print_f(floats.PI) + txt.nl() + floats.print_f(floats.TWOPI) + txt.nl() + } }