more sane directory name, updated binaries

This commit is contained in:
FeralChild64 committed 2020-06-26 19:44:01 +02:00
1 parent d4d32095d1
commit 76aaf298b8
697 files changed
+56 -56

No files matched your search

+97
View File
@@ -0,0 +1,97 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - add FAC2 to FAC1, subtraction part
//
// XXX test this
add_FAC2_FAC1_sub:
// First verify that |FAC1| > |FAC2|, branch to proper variant if it is not
// We ignore FACOV here. Note, that exponents are already equalized
lda FAC1_mantissa+0
cmp FAC2_mantissa+0
bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch
bne !+ // if FAC1 > FAC2, branch
lda FAC1_mantissa+1
cmp FAC2_mantissa+1
bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch
bne !+ // if FAC1 > FAC2, branch
lda FAC1_mantissa+2
cmp FAC2_mantissa+2
bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch
bne !+ // if FAC1 > FAC2, branch
lda FAC1_mantissa+3
cmp FAC2_mantissa+3
bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch
bne !+ // if FAC1 > FAC2, branch
// If we are here, than FAC1 is equal to FAC2 - so just set FAC1 to 0
lda #$00
sta FAC1_exponent
rts
!:
// Perform the subtration, FAC1 = FAC1 - FAC2
sec
lda FAC1_mantissa+3
sbc FAC2_mantissa+3
sta FAC1_mantissa+3
lda FAC1_mantissa+2
sbc FAC2_mantissa+2
sta FAC1_mantissa+2
lda FAC1_mantissa+1
sbc FAC2_mantissa+1
sta FAC1_mantissa+1
lda FAC1_mantissa+0
sbc FAC2_mantissa+0
sta FAC1_mantissa+0
// Exponent should never need adaptation here
jmp normal_FAC1
add_FAC2_FAC1_sub_rev:
// Since |FAC1| < |FAC2|, toggle FAC1 sign before subtraction
jsr toggle_sign_FAC1_skipcheck
// Perform the subtration, FAC1 = FAC2 - FAC1
sec
lda #$00
sbc FACOV
sta FACOV
lda FAC2_mantissa+3
sbc FAC1_mantissa+3
sta FAC1_mantissa+3
lda FAC2_mantissa+2
sbc FAC1_mantissa+2
sta FAC1_mantissa+2
lda FAC2_mantissa+1
sbc FAC1_mantissa+1
sta FAC1_mantissa+1
lda FAC2_mantissa+0
sbc FAC1_mantissa+0
sta FAC1_mantissa+0
// Exponent should never need adaptation here
jmp normal_FAC1
+167
View File
@@ -0,0 +1,167 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - align FAC1 and FAC2 exponents for addition
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 115
// - https://www.c64-wiki.com/wiki/BASIC-ROM
add_align_exponents:
// XXX assume here none of the exponents is 0, check if this is true for orignal ROMs
lda FAC1_exponent
cmp FAC2_exponent
beq add_align_exponents_done // branch if exponents the same
bcs add_align_exponent_FAC2
// FALLTROUGH
add_align_exponent_FAC1:
// First check the exponent difference
lda FAC2_exponent
sec
sbc FAC1_exponent
cmp #$28
bcs add_align_exponent_FAC1_zero // branch if difference is very high
cmp #$08
bcc add_align_exponent_FAC1_bit
// FALLTROUGH
add_align_exponent_FAC1_byte:
// Add 8 to exponent, divide mantissa by 256
lda FAC1_exponent
clc
adc #$08
sta FAC1_exponent
lda FAC1_mantissa+3
sta FACOV
lda FAC1_mantissa+2
sta FAC1_mantissa+3
lda FAC1_mantissa+1
sta FAC1_mantissa+2
lda FAC1_mantissa+0
sta FAC1_mantissa+1
lda #$00
sta FAC1_mantissa+0
beq add_align_exponent_FAC1 // branch always - next iteration
add_align_exponent_FAC1_bit:
// Increment exponent, divide mantissa by 2
inc FAC1_exponent
clc
ror FAC1_mantissa+0
ror FAC1_mantissa+1
ror FAC1_mantissa+2
ror FAC1_mantissa+3
ror FACOV
lda FAC1_exponent
cmp FAC2_exponent
bne add_align_exponent_FAC1_bit // branch if next iteration needed
rts
add_align_exponent_FAC1_zero:
lda #$00
sta FAC1_mantissa+0
sta FAC1_mantissa+1
sta FAC1_mantissa+2
sta FAC1_mantissa+3
sta FACOV
lda FAC2_exponent
sta FAC1_exponent
// FALLTROUGH
add_align_exponents_done:
rts
add_align_exponent_FAC2:
// First check the exponent difference, Carry already set here
lda FAC1_exponent
sbc FAC2_exponent
cmp #$20
bcs add_align_exponent_FAC2_zero // branch if difference is very high
cmp #$08
bcc add_align_exponent_FAC2_bit
// FALLTROUGH
add_align_exponent_FAC2_byte:
// Add 8 to exponent, divide mantissa by 256
lda FAC2_exponent
clc
adc #$08
sta FAC2_exponent
lda FAC2_mantissa+2
sta FAC2_mantissa+3
lda FAC2_mantissa+1
sta FAC2_mantissa+2
lda FAC2_mantissa+0
sta FAC2_mantissa+1
lda #$00
sta FAC2_mantissa+0
beq add_align_exponent_FAC2 // branch always - next iteration
add_align_exponent_FAC2_bit:
// Increment exponent, divide mantissa by 2
inc FAC2_exponent
clc
ror FAC2_mantissa+0
ror FAC2_mantissa+1
ror FAC2_mantissa+2
ror FAC2_mantissa+3
lda FAC1_exponent
cmp FAC2_exponent
bne add_align_exponent_FAC2_bit // branch if next iteration needed
rts
add_align_exponent_FAC2_zero:
lda #$00
sta FAC2_mantissa+0
sta FAC2_mantissa+1
sta FAC2_mantissa+2
sta FAC2_mantissa+3
lda FAC1_exponent
sta FAC2_exponent
rts
+17
View File
@@ -0,0 +1,17 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - add 0.5 to FAC1
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 112
add_HALF_FAC1:
ldy #>const_HALF
lda #<const_HALF
jmp add_MEM_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+3
View File
@@ -0,0 +1,3 @@
This is an important floating point math routine, documented in many places.
XXX - try to find real-life example
+23
View File
@@ -0,0 +1,23 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - subtract FAC1 from memory variable
//
// Input:
// - .A - address low byte
// - .Y - address high byte
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 112
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
sub_MEM_FAC1:
jsr mov_MEM_FAC2
// FALLTROUGH to sub_FAC2_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+25
View File
@@ -0,0 +1,25 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - subtract FAC1 from FAC2
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 112
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
// XXX test this
sub_FAC2_FAC1:
// Toggle FAC1 sign
lda FAC1_sign
eor #$FF
sta FAC1_sign
// Perform addition
jmp add_FAC2_FAC1
@@ -0,0 +1,9 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Just a compatibility jump - our routine is longer than original one
jmp add_align_exponents
+3
View File
@@ -0,0 +1,3 @@
This is an important floating point math routine, documented in many places.
XXX - try to find real-life example
+23
View File
@@ -0,0 +1,23 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - add memory variable to FAC1
//
// Input:
// - .A - address low byte
// - .Y - address high byte
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 112
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
add_MEM_FAC1:
jsr mov_MEM_FAC2
// FALLTROUGH to add_FAC2_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Routine probably used very often, it's call can be seen in a tutorial here:
- https://codebase64.org/doku.php?id=base:generating_sines_with_basic
+96
View File
@@ -0,0 +1,96 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - add FAC2 to FAC1
//
// Input:
// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag
//
// Note:
// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?)
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 112
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
// XXX test this
add_FAC2_FAC1:
// Check if FAC2 is 0; if so leave FAC1 without changes
lda FAC2_exponent
beq add_FAC2_FAC1_done
// If FAC1 is 0, if so just copy FAC2 to FAC1
lda FAC1_exponent
beq_16 mov_FAC2_FAC1
// Make sure the exponents are aligned
jsr add_align_exponents
// Check whether signs are the same
lda FAC1_sign
eor FAC2_sign
bmi_16 add_FAC2_FAC1_sub // branch if signs are opposite
// Perform the addition
clc
lda FAC2_mantissa+3
adc FAC1_mantissa+3
sta FAC1_mantissa+3
lda FAC2_mantissa+2
adc FAC1_mantissa+2
sta FAC1_mantissa+2
lda FAC2_mantissa+1
adc FAC1_mantissa+1
sta FAC1_mantissa+1
lda FAC2_mantissa+0
adc FAC1_mantissa+0
sta FAC1_mantissa+0
bcc_16 normal_FAC1 // end if no need to adapt the exponent
inc FAC1_exponent
bne add_FAC2_FAC1_adapt_mantissa // end if no overflow
// FALLTROUGH
set_FAC1_max: // entry used by other routines too
lda #$FF
sta FAC1_exponent
sta FAC1_mantissa+3
sta FAC1_mantissa+2
sta FAC1_mantissa+1
sta FAC1_mantissa+0
// FALLTROUGH
add_FAC2_FAC1_done:
rts
add_FAC2_FAC1_adapt_mantissa:
sec
ror FAC1_mantissa+0
ror FAC1_mantissa+1
ror FAC1_mantissa+2
ror FAC1_mantissa+3
ror FACOV
rts
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- http://cbm-hackers.2304266.n4.nabble.com/unsigned-to-float-td4668532.html#a4668556
+3
View File
@@ -0,0 +1,3 @@
This is an important floating point math routine, documented in many places.
XXX - try to find real-life example
+8
View File
@@ -0,0 +1,8 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Just a compatibility jump - our routine is longer than original one
jmp normal_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://www.lemon64.com/forum/viewtopic.php?t=42934
+26
View File
@@ -0,0 +1,26 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - multiplies FAC1 by RAM
//
// Input:
// - .A - address low byte
// - .Y - address high byte
//
// Note:
// - C64 Wiki calls it FMULT, this looks like a mistake
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 113
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
mul_MEM_FAC1:
jsr mov_MEM_FAC2
// FALLTROUGH to mul_FAC2_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+8
View File
@@ -0,0 +1,8 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Just a compatibility jump - our routine is longer than original one
jmp mul_FAC2_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://www.lemon64.com/forum/viewtopic.php?t=42934
+8
View File
@@ -0,0 +1,8 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Just a compatibility jump - our routine is longer than original one
jmp mov_MEM_FAC2
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+41
View File
@@ -0,0 +1,41 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - multiply FAC1 by 10
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 114
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
mul10_FAC1:
// Handle special case of FAC1 equal 0
lda FAC1_exponent
beq mul10_FAC1_done
// Start by multiplying FAC1 by 2
jsr mul10_FAC1_mul2
// Move FAC1 to FAC2, so that FAC1 = FAC2 = 2 * initial
jsr mov_FAC1_FAC2
// Multiply FAC1 by 4
jsr mul10_FAC1_mul2
jsr mul10_FAC1_mul2
// Now we have FAC1 = 8 * initial and FAC2 = 2 * initial; so just add these 2 values
jmp add_FAC2_FAC1
mul10_FAC1_done:
rts
+29
View File
@@ -0,0 +1,29 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - divide FAC1 by 10, result is always positive
//
// Notes:
// - shifts FAC1 to FAC2, loads FAC1 with the constant 10, falls through to the division routine
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 114
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
// XXX test this
div10_FAC1_p:
lda #$00
sta FAC1_sign
ldy #>const_TEN
lda #<const_TEN
jmp div_MEM_FAC1
+5
View File
@@ -0,0 +1,5 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+23
View File
@@ -0,0 +1,23 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - divide RAM by FAC1
//
// Input:
// - .A - address low byte
// - .Y - address high byte
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 114
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
div_MEM_FAC1:
jsr mov_MEM_FAC2
// FALLTROUGH to div_FAC2_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://codebase64.org/doku.php?id=base:mandelbrot
+85
View File
@@ -0,0 +1,85 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - divide FAC2 (dividend) by FAC1 (divisor)
//
// Input:
// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag (but our routine does not need this)
//
// Output:
// - FAC1
//
// Note:
// - some documentation suggest this is a division leaving quotient and remainder (left in FAC2),
// but it seems (experimentation) that this is not true
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 114
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
div_FAC2_FAC1:
// 'Pamiętaj, cholero - nie dziel przez zero!' - ancient polish proverb
lda FAC1_exponent
beq_16 do_DIVISION_BY_ZERO_error
// Handle special case - dividing 0 by non-zero value
lda FAC2_exponent
beq_16 set_FAC1_zero
// Multiply signs
lda FAC1_sign
eor FAC2_sign
sta FAC1_sign
// Subtract the exponents
lda #$A0 // correction for bias and FAC2 digits
sta RESHO+0
lda #$00
sta RESHO+1
lda FAC2_exponent // add FAC2 exponent to temporary variable
jsr muldiv_RESHO_01_add_A
lda RESHO+0 // subtract FAC1 exponent from temporary variable
sec
sbc FAC1_exponent
sta RESHO+0
bcs !+
dec RESHO+1
!:
lda RESHO+1
bmi_16 set_FAC1_zero // result too low, set 0 and quit
lda RESHO+0
sta FAC1_exponent
// Divide the mantissas
jsr div_FAC1_denorm
jsr muldiv_RESHO_set_0
jsr div_mantissas
// Copy the result to FAC1 - XXX we probably already have similar code somewhere...
lda FAC2_mantissa+3
sta FAC1_mantissa+3
lda FAC2_mantissa+2
sta FAC1_mantissa+2
lda FAC2_mantissa+1
sta FAC1_mantissa+1
lda FAC2_mantissa+0
sta FAC1_mantissa+0
// Normalize and quit
jmp normal_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing the routine:
- https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing the routine:
- https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3
+9
View File
@@ -0,0 +1,9 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Just a compatibility jump - our routine is longer than original one
jmp round_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+26
View File
@@ -0,0 +1,26 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - evaluate FAC1 sign, to .A
//
// Output:
// - .A - 0 for FAC1 equal 0, 1 for FAC1 > 0, -1 for FAC1 < 0
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 115
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
sgn_FAC1_A:
lda FAC1_exponent
beq !+
lda FAC1_sign
bne !+
lda #$01
!:
rts
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+22
View File
@@ -0,0 +1,22 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - square root of FAC1
//
// Note:
// - transfers FAC1 to FAC2 and falls through to SQR2
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 117
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
sqr_FAC1:
jsr mov_FAC1_FAC2
// FALLLTROUGH to sqr_FAC2
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+24
View File
@@ -0,0 +1,24 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - set FAC1 as RAM raised to the power of FAC2
//
// Input:
// - .A - address low byte
// - .Y - address high byte
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 117 (FPWRT)
// - https://www.c64-wiki.com/wiki/BASIC-ROM
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
pwr_FAC2_MEM:
jsr mov_MEM_FAC1
// FALLTROUGH to pwr_FAC2_FAC1
+4
View File
@@ -0,0 +1,4 @@
This is an important floating point math routine, documented in many places.
Example code utilizing this routine:
- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8
+27
View File
@@ -0,0 +1,27 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - toggle FAC1 sign (if not 0)
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 117
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
//
toggle_sign_FAC1:
lda FAC1_exponent
beq !+ // do not toggle the sign if value is 0
// FALLTROUGH
toggle_sign_FAC1_skipcheck: // entry for other routines
lda FAC1_sign
eor #$FF
sta FAC1_sign
!:
rts
+68
View File
@@ -0,0 +1,68 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - denormalize FAC1 mantissa and adapt its exponent accordingly for division
//
div_FAC1_denorm:
// Set FACOV to 0, no need for increased precision here
lda #$00
sta FACOV
// Start by moving whole bytes, if possible
lda FAC1_mantissa+3
bne div_FAC1_denorm_by_bit // branch if last byte of mantissa is non-zero
lda FAC1_exponent
cmp #$08
bcc div_FAC1_denorm_by_bit // branch if not suitable to increment exponent by 8
// Increment exponent
sbc #$08 // Carry already sec
sta FAC1_exponent
// Move mantissa bytes
lda FAC1_mantissa+2
sta FAC1_mantissa+3
lda FAC1_mantissa+1
sta FAC1_mantissa+2
lda FAC1_mantissa+0
sta FAC1_mantissa+1
lda #$00
sta FAC1_mantissa+0
beq div_FAC1_denorm // branch always
div_FAC1_denorm_by_bit:
lda FAC1_mantissa+3
and #$01
bne div_FAC1_denorm_done // branch if lowest bit of mantissa is already 1
lda FAC1_exponent
beq div_FAC1_denorm_done // branch if not suitable to decrement exponent
// Decrement exponent
dec FAC1_exponent
// Move mantissa bits
clc
ror FAC1_mantissa+0
ror FAC1_mantissa+1
ror FAC1_mantissa+2
ror FAC1_mantissa+3
bcc div_FAC1_denorm_by_bit // branch always
div_FAC1_denorm_done:
rts
+84
View File
@@ -0,0 +1,84 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
// Math package - 32-bit mantissa division, based on code by Verz
//
// divident: FAC2_mantissa, divisor: FAC1_mantissa (without FACOV), result: FAC2_mantissa, remainder: RESHO
// temporary storage: INDEX+0, INDEX+1, INDEX+2, INDEX+3
//
// RESHO (remainder) should be set to 0 before
//
// see https://codebase64.org/doku.php?id=base:24bit_division_24-bit_result
// XXX test this
div_mantissas:
ldx #32 // repeat for each bit
// FALLTROUGH
div_mantissas_loop:
// Multiply divident by 2, msb -> Carry
asl FAC2_mantissa+3
rol FAC2_mantissa+2
rol FAC2_mantissa+1
rol FAC2_mantissa+0
// Multiply remainder by 2, lsb <- Carry
rol RESHO+3
rol RESHO+2
rol RESHO+1
rol RESHO+0
// Subtract divisor from the remainder, result to INDEX and .Y
sec
lda RESHO+3
sbc FAC1_mantissa+3
sta INDEX+3
lda RESHO+2
sbc FAC1_mantissa+2
sta INDEX+2
lda RESHO+1
sbc FAC1_mantissa+1
sta INDEX+1
lda RESHO+0
sbc FAC1_mantissa+0
bcc div_mantissas_skip // if Carry is not set then divisor did not fit in remainder yet
sta INDEX+0
// Save subtraction result as new remainder
lda INDEX+3
sta RESHO+3
lda INDEX+2
sta RESHO+2
lda INDEX+1
sta RESHO+1
lda INDEX+0
sta RESHO+0
// Increment result cause divisor fit in 1 times
inc FAC2_mantissa+3
// FALLTROUGH
div_mantissas_skip:
dex
bne div_mantissas_loop
rts
+3
View File
@@ -0,0 +1,3 @@
This is an important floating point math routine, referenced by ACME SDK, see here:
- https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True
+20
View File
@@ -0,0 +1,20 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Random number generator routine
//
// Input:
// - FAC1 (0 - reinitialize the seed with random value, negative - create seed from FAC1)
//
// Output:
// - FAC1
//
rnd_FAC1:
jsr sgn_FAC1_A
// FALLTROUGH to rnd_A
+5
View File
@@ -0,0 +1,5 @@
This is an important floating point math routine, see:
- https://www.atarimagazines.com/compute/issue72/random_numbers.php
Example code utilizing the routine:
- https://stackoverflow.com/questions/44937759/getting-random-number-from-6502-assembler/44937995
+26
View File
@@ -0,0 +1,26 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Random number generator routine
//
// Input:
// - .A (0 - reinitialize the seed with random value, $80 or above - create seed from FAC1)
//
// Output:
// - FAC1
//
// See also:
// - https://www.atarimagazines.com/compute/issue72/random_numbers.php
//
rnd_A:
cmp #$00
beq_16 rnd_seed_init
cmp #$80
bcc_16 rnd_generate
jmp rnd_seed_from_FAC1
+5
View File
@@ -0,0 +1,5 @@
This is an important floating point math routine, see:
- https://www.atarimagazines.com/compute/issue72/random_numbers.php
Example coode utilizing this routine:
- https://www.lemon64.com/forum/viewtopic.php?t=56934&sid=387926a3f1d6373a384c0f7328b00c30
+77
View File
@@ -0,0 +1,77 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// A fast pseudorandom generator, modified idea from:
// - https://codebase64.org/doku.php?id=base:32bit_galois_lfsr
//
// Output:
// - FAC1
//
// See also:
// - https://www.atarimagazines.com/compute/issue72/random_numbers.php
//
rnd_generate:
asl RNDX+1
rol RNDX+2
rol RNDX+3
rol RNDX+4
bcs rnd_generate_copy
lda RNDX+1
eor #$B7
sta RNDX+1
lda RNDX+2
eor #$1D
sta RNDX+2
lda RNDX+3
eor #$C1
sta RNDX+3
lda RNDX+4
eor #$04
sta RNDX+4
sec // make sure Carry is always set, for adc
// FALLTROUGH
rnd_generate_copy:
// Copy the generated number to FAC1, mangle it a little
lda RNDX+3
adc #$C6
sta FAC1_mantissa+0
lda RNDX+1
eor #$4E
sta FAC1_mantissa+1
lda RNDX+4
eor #$62
sta FAC1_mantissa+2
lda RNDX+2
bit RNDX+2
rol
sta FAC1_mantissa+3
// FALLTROUGH
rnd_generate_finalize:
lda #$00
sta FAC1_sign
lda #$80
sta FACOV // just to prevent 0 after normalization
sta FAC1_exponent
jmp normal_FAC1
+16
View File
@@ -0,0 +1,16 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Multiply FAC1 by 2, do not normalize
//
mul10_FAC1_mul2:
// Increment the exponent
inc FAC1_exponent
beq_16 set_FAC1_max
rts
+195
View File
@@ -0,0 +1,195 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - multiplies FAC1 by FAC2
//
// Input:
// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag
//
// Note:
// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?)
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
set_FAC1_zero:
lda #$00
sta FAC1_exponent
mul_FAC2_FAC1_done:
rts
mul_FAC2_FAC1:
// First handle special case of multiplying by 0
lda FAC1_exponent
beq mul_FAC2_FAC1_done
lda FAC2_exponent
bne !+
sta FAC1_exponent
beq mul_FAC2_FAC1_done
!:
// Multiply signs
lda FAC1_sign
eor FAC2_sign
sta FAC1_sign
// Add the exponents (subtract the bias) - XXX can this be optimized somehow?
jsr muldiv_RESHO_set_0
lda FAC1_exponent
jsr muldiv_RESHO_01_add_A
lda FAC2_exponent
jsr muldiv_RESHO_01_add_A
lda RESHO+0
sbc #$80 // we need to correct double BIAS
sta RESHO+0
bcs !+
lda RESHO+1
sbc #$00
bcc set_FAC1_zero
sta RESHO+1
!:
lda RESHO+1
bne_16 set_FAC1_max // overflow
lda RESHO+0
sta FAC1_exponent
// Multiply the mantissas
jsr muldiv_RESHO_set_0
clc
// XXX maybe we should preserve .X on stack? this will not cost us too much
lda FACOV
jsr mul_FAC2_FAC1_by_A
jsr mul_FAC2_FAC1_shift
bcc !+
inc RESHO+0
!:
lda FAC1_mantissa+3
jsr mul_FAC2_FAC1_by_A
jsr mul_FAC2_FAC1_shift
bcc !+
inc RESHO+0
!:
lda FAC1_mantissa+2
jsr mul_FAC2_FAC1_by_A
jsr mul_FAC2_FAC1_shift
bcc !+
inc RESHO+0
!:
lda FAC1_mantissa+1
jsr mul_FAC2_FAC1_by_A
jsr mul_FAC2_FAC1_shift
bcc !+
inc RESHO+0
!:
lda FAC1_mantissa+0
jsr mul_FAC2_FAC1_by_A
jsr mul_FAC2_FAC1_shift
bcc !+
inc RESHO+0
!:
// Copy RESHO to FAC1 mantissa
lda RESHO+4
sta FACOV
lda RESHO+3
sta FAC1_mantissa+3
lda RESHO+2
sta FAC1_mantissa+2
lda RESHO+1
sta FAC1_mantissa+1
lda RESHO+0
sta FAC1_mantissa+0
// Correct the exponent
lda FAC1_exponent
clc
adc #$08
bcs_16 set_FAC1_max // branch if overflow
sta FAC1_exponent
jmp normal_FAC1
mul_FAC2_FAC1_by_A:
beq mul_FAC2_FAC1_by_A_done
sta INDEX+3
// Multiply FAC2_mantissa+3
lda FAC2_mantissa+3
jsr mul_FAC2_FAC1_8x8
adc RESHO+4
sta RESHO+4
txa
adc RESHO+3
sta RESHO+3
bcc !+
inc RESHO+2
bne !+
inc RESHO+1
bne !+
inc RESHO+0
!:
// Multiply FAC2_mantissa+2
lda FAC2_mantissa+2
jsr mul_FAC2_FAC1_8x8
adc RESHO+3
sta RESHO+3
txa
adc RESHO+2
sta RESHO+2
bcc !+
inc RESHO+1
bne !+
inc RESHO+0
!:
// Multiply FAC2_mantissa+1
lda FAC2_mantissa+1
jsr mul_FAC2_FAC1_8x8
adc RESHO+2
sta RESHO+2
txa
adc RESHO+1
sta RESHO+1
bcc !+
inc RESHO+0
!:
// Multiply FAC2_mantissa+0
lda FAC2_mantissa+0
jsr mul_FAC2_FAC1_8x8
adc RESHO+1
sta RESHO+1
txa
adc RESHO+0
sta RESHO+0
// FALLTROUGH
mul_FAC2_FAC1_by_A_done:
rts
+77
View File
@@ -0,0 +1,77 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper routine, based on code by djmips from:
// - https://codebase64.org/doku.php?id=base:8bit_multiplication_16bit_product_fast_no_tables
//
// input: .A (and Zero flag set according to .A), INDEX+3
// output: .X (high byte), .A (low byte), carry always clear
//
mul_FAC2_FAC1_8x8:
// Special case (optimization) - handle 0 in INDEX+2
beq mul_FAC2_FAC1_8x8_zero
sta INDEX+2
lda #$00
dec INDEX+3 // decrement because we will be adding with carry set for speed (an extra one)
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
bcc !+
adc INDEX+3
!:
ror
ror INDEX+2
inc INDEX+3
tax
lda INDEX+2
clc
rts
mul_FAC2_FAC1_8x8_zero:
lda #$00
tax
clc
rts
+46
View File
@@ -0,0 +1,46 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Shift RESHO by one byte - for multiplication
//
mul_FAC2_FAC1_shift:
// Check if rounding is needed
php
clc
lda RESHO+4
bpl !+
sec
!:
// Copy bytes
lda RESHO+3
sta RESHO+4
lda RESHO+2
sta RESHO+3
lda RESHO+1
sta RESHO+2
lda RESHO+0
sta RESHO+1
lda #$00
sta RESHO+0
bcc !+
// Perform rounding
inc RESHO+4
bne !+
inc RESHO+3
bne !+
inc RESHO+2
bne !+
inc RESHO+1
bne !+
inc RESHO+0
!:
plp
rts
+30
View File
@@ -0,0 +1,30 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - helper routines for RESHO manipulation
//
muldiv_RESHO_set_0:
lda #$00
sta RESHO+0
sta RESHO+1
sta RESHO+2
sta RESHO+3
sta RESHO+4
rts
muldiv_RESHO_01_add_A:
clc
adc RESHO+0
sta RESHO+0
bcc !+
inc RESHO+1
!:
rts
+101
View File
@@ -0,0 +1,101 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - normalize FAC1
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 113
// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
// XXX test this
normal_FAC1:
lda FAC1_exponent
beq normal_FAC1_end // branch if our float is 0
// FALLTROUGH
normal_FAC1_check_mantissa_byte:
lda FAC1_mantissa+0
beq normal_FAC1_by_byte // branch if we can move the whole byte
// FALLTROUGH
normal_FAC1_check_mantissa_bit:
lda FAC1_mantissa+0 // XXX optimize for 65CE02?
and #$80
bne normal_FAC1_end // branch if already normalized
// FALLTROUGH
normal_FAC1_by_bit:
// Decrement the exponent
dec FAC1_exponent
beq normal_FAC1_end // exponent reached 0, nothing more to do
// Multiply the mantissa by 2
asl FACOV
rol FAC1_mantissa+3
rol FAC1_mantissa+2
rol FAC1_mantissa+1
rol FAC1_mantissa+0
bcc normal_FAC1_check_mantissa_bit // branch if next iteration needed
rts
normal_FAC1_by_byte:
// First decrement the exponent by 8, but not below 0
lda FAC1_exponent
sec
sbc #$08
bcs !+
lda #$00
!:
sta FAC1_exponent
beq normal_FAC1_end // branch if our float reached 0
// Now multiply the mantissa by 8 by moving the whole bytes
lda FAC1_mantissa+1
sta FAC1_mantissa+0
lda FAC1_mantissa+2
sta FAC1_mantissa+1
lda FAC1_mantissa+3
sta FAC1_mantissa+2
lda FACOV
sta FAC1_mantissa+3
lda #$00
sta FACOV
// Now check if mantissa is not 0
ora FAC1_mantissa+0
ora FAC1_mantissa+1
ora FAC1_mantissa+2
ora FAC1_mantissa+3
bne normal_FAC1_check_mantissa_byte // not 0 - branch to next iteration
// Our mantissa reached 0 - mark exponent as 0 and finish
sta FAC1_exponent
// FALLTROUGH
normal_FAC1_end:
rts
+27
View File
@@ -0,0 +1,27 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Initialize random seed using values from FAC1,
// afterwards generate random number in FAC1
//
rnd_seed_from_FAC1:
lda FAC1_mantissa+0
sta RNDX+4
eor FAC1_mantissa+1
sta RNDX+3
eor FAC1_mantissa+2
sta RNDX+2
eor FAC1_mantissa+3
sta RNDX+1
eor FAC1_exponent
sta RNDX+0
jmp rnd_generate
+33
View File
@@ -0,0 +1,33 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Initialize random seed, afterwards generate random number in FAC1,
// try to gather as much entropy from different sources as possible
//
rnd_seed_init:
eor CIA1_TIMALO // timer used for IRQ generation, use potential entropy from .A
sta RNDX+3
txa // .X might contain some entropy
eor VIC_RASTER // lowest 8 bits of current raster line
sta RNDX+1
tya // .Y might contain some entropy
eor CIA1_TIMAHI
sta RNDX+4
lda TIME+0 // byte from jiffy counter might be useful too
eor SID_RANDOM // not sure if SID set correctly, but it will not hurt
#if CONFIG_MB_MEGA_65
eor VIC_XPOS // not sure if VIC-IV visible, but it will not hurt
#endif
sta RNDX+2
// RNDX+0 will be overwritten by generator
jmp rnd_generate
+61
View File
@@ -0,0 +1,61 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * BASIC_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Math package - rounds FAC1 before copying
//
// See also:
// - [CM64] Computes Mapping the Commodore 64 - page 115
// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics
//
// XXX test this
round_FAC1:
// If number is 0, do not do anything
lda FAC1_exponent
beq round_FAC1_done
lda FACOV
bpl round_FAC1_zero_FACOV // branch if it is enough to clear FACOV
// Increment the 4 bytes of matissa
// Curse you, who invented this format! Had the mantissa been little endian,
// we could have used INW on 65C02 and above, the code would have been smaller!
inc FAC1_mantissa+3
bne round_FAC1_zero_FACOV
inc FAC1_mantissa+2
bne round_FAC1_zero_FACOV
inc FAC1_mantissa+1
bne round_FAC1_zero_FACOV
inc FAC1_mantissa+0
bne round_FAC1_zero_FACOV
// If we are here, it means mantissa is 0; put it to minimum allowed and increment exponent
lda #$80
sta FAC1_mantissa+0
inc FAC1_exponent
bne round_FAC1_zero_FACOV
// If we are here, it means the exponent wrapped around to $00; put it back to $FF
dec FAC1_exponent
// FALLTROUGH
round_FAC1_zero_FACOV:
lda #$00
sta FACOV
// FALLTROUGH
round_FAC1_done:
rts