more sane directory name, updated binaries
This commit is contained in:
1 parent
d4d32095d1
commit
76aaf298b8
697 files changed
+56
-56
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
This is an important floating point math routine, documented in many places.
|
||||
|
||||
XXX - try to find real-life example
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
This is an important floating point math routine, documented in many places.
|
||||
|
||||
XXX - try to find real-life example
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
This is an important floating point math routine, documented in many places.
|
||||
|
||||
XXX - try to find real-life example
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user