added sqrt16() integer square root

This commit is contained in:
Irmen de Jong 2019-03-16 19:25:47 +01:00
parent 191707cd37
commit 0820716e7b
6 changed files with 74 additions and 34 deletions

View File

@ -649,7 +649,57 @@ func_read_flags .proc
rts rts
.pend .pend
func_sqrt16 .proc
lda c64.ESTACK_LO+1,x
sta c64.SCRATCH_ZPWORD2
lda c64.ESTACK_HI+1,x
sta c64.SCRATCH_ZPWORD2+1
stx c64.SCRATCH_ZPREGX
ldy #$00 ; r = 0
ldx #$07
clc ; clear bit 16 of m
_loop
tya
ora _stab-1,x
sta c64.SCRATCH_ZPB1 ; (r asl 8) | (d asl 7)
lda c64.SCRATCH_ZPWORD2+1
bcs _skip0 ; m >= 65536? then t <= m is always true
cmp c64.SCRATCH_ZPB1
bcc _skip1 ; t <= m
_skip0
sbc c64.SCRATCH_ZPB1
sta c64.SCRATCH_ZPWORD2+1 ; m = m - t
tya
ora _stab,x
tay ; r = r or d
_skip1
asl c64.SCRATCH_ZPWORD2
rol c64.SCRATCH_ZPWORD2+1 ; m = m asl 1
dex
bne _loop
; last iteration
bcs _skip2
sty c64.SCRATCH_ZPB1
lda c64.SCRATCH_ZPWORD2
cmp #$80
lda c64.SCRATCH_ZPWORD2+1
sbc c64.SCRATCH_ZPB1
bcc _skip3
_skip2
iny ; r = r or d (d is 1 here)
_skip3
ldx c64.SCRATCH_ZPREGX
tya
sta c64.ESTACK_LO+1,x
lda #0
sta c64.ESTACK_HI+1,x
rts
_stab .byte $01,$02,$04,$08,$10,$20,$40,$80
.pend
func_sin8 .proc func_sin8 .proc
ldy c64.ESTACK_LO+1,x ldy c64.ESTACK_LO+1,x
lda _sinecos8,y lda _sinecos8,y

View File

@ -1255,9 +1255,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.ROR2_WORD -> { Opcode.ROR2_WORD -> {
AsmFragment(" lsr $variable+1 | ror $variable | bcc + | lda $variable+1 | ora #\$80 | sta $variable+1 |+", 30) AsmFragment(" lsr $variable+1 | ror $variable | bcc + | lda $variable+1 | ora #\$80 | sta $variable+1 |+", 30)
} }
// Opcode.SYSCALL -> {
// TODO("optimize SYSCALL $ins in-place on variable $variable")
// }
else -> null else -> null
} }
} }

View File

@ -46,7 +46,7 @@ val BuiltinFunctions = mapOf(
"atan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) }, "atan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
"ln" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) }, "ln" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
"log2" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) }, "log2" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
// TODO: sqrt() should have integer versions too "sqrt16" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { Math.sqrt(it.toDouble()).toInt() } },
"sqrt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) }, "sqrt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
"rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) }, "rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
"deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) }, "deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },

View File

@ -40,6 +40,7 @@ enum class Syscall(val callNr: Short) {
FUNC_ATAN(72), FUNC_ATAN(72),
FUNC_LN(73), FUNC_LN(73),
FUNC_LOG2(74), FUNC_LOG2(74),
FUNC_SQRT16(75),
FUNC_SQRT(76), FUNC_SQRT(76),
FUNC_RAD(77), FUNC_RAD(77),
FUNC_DEG(78), FUNC_DEG(78),
@ -2064,6 +2065,7 @@ class StackVm(private var traceOutputFile: String?) {
Syscall.FUNC_LN -> evalstack.push(Value(DataType.FLOAT, ln(evalstack.pop().numericValue().toDouble()))) Syscall.FUNC_LN -> evalstack.push(Value(DataType.FLOAT, ln(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_LOG2 -> evalstack.push(Value(DataType.FLOAT, log2(evalstack.pop().numericValue().toDouble()))) Syscall.FUNC_LOG2 -> evalstack.push(Value(DataType.FLOAT, log2(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_SQRT -> evalstack.push(Value(DataType.FLOAT, sqrt(evalstack.pop().numericValue().toDouble()))) Syscall.FUNC_SQRT -> evalstack.push(Value(DataType.FLOAT, sqrt(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_SQRT16 -> evalstack.push(Value(DataType.UBYTE, sqrt(evalstack.pop().numericValue().toDouble()).toInt()))
Syscall.FUNC_RAD -> evalstack.push(Value(DataType.FLOAT, Math.toRadians(evalstack.pop().numericValue().toDouble()))) Syscall.FUNC_RAD -> evalstack.push(Value(DataType.FLOAT, Math.toRadians(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_DEG -> evalstack.push(Value(DataType.FLOAT, Math.toDegrees(evalstack.pop().numericValue().toDouble()))) Syscall.FUNC_DEG -> evalstack.push(Value(DataType.FLOAT, Math.toDegrees(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_FLOOR -> { Syscall.FUNC_FLOOR -> {

View File

@ -604,8 +604,11 @@ ln(x)
log2(x) log2(x)
Base 2 logarithm. Base 2 logarithm.
sqrt16(w)
16 bit unsigned integer Square root. Result is unsigned byte.
sqrt(x) sqrt(x)
Square root. Floating point Square root.
round(x) round(x)
Rounds the floating point to the closest integer. Rounds the floating point to the closest integer.

View File

@ -6,47 +6,35 @@
; @todo see problem in looplabelproblem.p8 ; @todo see problem in looplabelproblem.p8
sub start() { sub start() {
uword z2 = sqrt16(50000)
uword z = c64utils.str2uword(" 1 2 3 4 5 ") c64scr.print_ub(sqrt16(0))
c64scr.print_uw(c64utils.str2uword(" "))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_uw(c64utils.str2uword(" 222 ")) c64scr.print_ub(sqrt16(200))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_uw(c64utils.str2uword("1234 567")) c64scr.print_ub(sqrt16(20000))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_uw(c64utils.str2uword("1234x567")) c64scr.print_ub(sqrt16(63333))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_uw(c64utils.str2uword("+1234x567")) c64scr.print_ub(sqrt16(65535))
c64.CHROUT('\n')
c64scr.print_uw(c64utils.str2uword("00065534"))
c64.CHROUT('\n')
c64scr.print_uw(c64utils.str2uword("0006553x4"))
c64.CHROUT('\n') c64.CHROUT('\n')
c64.CHROUT('\n') c64.CHROUT('\n')
z2=0
word z2 = c64utils.str2word(" 1 2 3 4 5 ") c64scr.print_ub(sqrt16(z2))
c64scr.print_w(c64utils.str2word(" "))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("0000000")) z2=200
c64scr.print_ub(sqrt16(z2))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("12345")) z2=20000
c64scr.print_ub(sqrt16(z2))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("64444")) z2=63333
c64scr.print_ub(sqrt16(z2))
c64.CHROUT('\n') c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word(" 12345")) z2=65535
c64.CHROUT('\n') c64scr.print_ub(sqrt16(z2))
c64scr.print_w(c64utils.str2word("-12345"))
c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word(" - 123 45"))
c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("+1234 567 "))
c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("-1234 567 "))
c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("-31999"))
c64.CHROUT('\n')
c64scr.print_w(c64utils.str2word("31999"))
c64.CHROUT('\n') c64.CHROUT('\n')
A=99
} }
} }