added unsigned versions of sin and cos (0..255, 0..65535)

This commit is contained in:
Irmen de Jong 2019-01-06 22:22:12 +01:00
parent 3b6ffc47b2
commit 295f7a6c6e
8 changed files with 146 additions and 75 deletions

View File

@ -12,11 +12,9 @@
ubyte color
while true {
word x = sin8(msb(anglex)) as word
word y = cos8(msb(angley)) as word
ubyte xx=msb(x*39) + 20 ; -127..127 -> 0..39
ubyte yy=msb(y*24) + 12 ; -127..127 -> 0..24
c64scr.setcc(xx, yy, 81, color)
ubyte x = msb(sin8u(msb(anglex)) as uword * width)
ubyte y = msb(cos8u(msb(angley)) as uword * height)
c64scr.setcc(x, y, 81, color)
anglex+=800
angley+=947

View File

@ -2,54 +2,23 @@
~ main {
ubyte ub1
ubyte ub2
ubyte ub3
ubyte ub4
byte b1 = 120
byte b2 = -13
byte b3
byte b4
uword uw1 = 52000
uword uw2 = 1333
uword uw3
uword uw4
word w1 = 22000
word w2 = 1333
word w3
word w4
sub start() {
w1 = 12000
w2 = -333 ; -333
w3 = w1 // w2
c64scr.print_w(w3)
c64.CHROUT('\n')
w1 = -12000 ; -12000
w2 = 333
w3 = w1 // w2
c64scr.print_w(w3)
c64.CHROUT('\n')
w2 = 4444
w3 = w1 // w2
c64scr.print_w(w3)
c64.CHROUT('\n')
w3 = w1 // -5 ; -5
c64scr.print_w(w3)
c64.CHROUT('\n')
w3 = w1 // -7 ; -7
c64scr.print_w(w3)
c64.CHROUT('\n')
w1 = -w1
w3 = w1 // -999 ;-999
c64scr.print_w(w3)
c64.CHROUT('\n')
c64scr.print_ub(X)
ubyte i =0
loop:
byte s = sin8(i)
ubyte su = sin8u(i)
word sw = sin16(i)
uword swu = sin16u(i)
byte c = cos8(i)
ubyte cu = cos8u(i)
word cw = cos16(i)
uword cwu = cos16u(i)
c64scr.print_b(c)
c64.CHROUT(' ')
c64scr.print_w(cw)
c64.CHROUT('\n')
i++
if_nz goto loop
}
}

View File

@ -64,10 +64,10 @@ sub irq() {
ubyte i=14
nextsprite: ; @todo should be a for loop from 14 to 0 step -2 but this causes a value out of range error at the moment
word x = (sin8(angle*2-i*8) as word)+190
byte y = cos8(angle*3-i*8) // 2
uword x = sin8u(angle*2-i*8) as uword + 50
ubyte y = cos8u(angle*3-i*8) // 2 + 70
@(SP0X+i) = lsb(x)
@(SP0Y+i) = y+150 as ubyte
@(SP0Y+i) = y
lsl(c64.MSIGX)
if msb(x) c64.MSIGX++

View File

@ -32,10 +32,14 @@ val BuiltinFunctions = mapOf(
// normal functions follow:
"sin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
"sin8" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.BYTE, ::builtinSin8 ),
"sin8u" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.UBYTE, ::builtinSin8u ),
"sin16" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.WORD, ::builtinSin16 ),
"sin16u" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.UWORD, ::builtinSin16u ),
"cos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
"cos8" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.BYTE, ::builtinCos8 ),
"cos8u" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.UBYTE, ::builtinCos8u ),
"cos16" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.WORD, ::builtinCos16 ),
"cos16u" to FunctionSignature(true, listOf(BuiltinFunctionParam("angle8", setOf(DataType.UBYTE))), DataType.UWORD, ::builtinCos16u ),
"tan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
"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) },
@ -303,7 +307,15 @@ private fun builtinSin8(args: List<IExpression>, position: Position, namespace:I
throw SyntaxError("sin8 requires one argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
return LiteralValue(DataType.BYTE, bytevalue = (32767.0* sin(rad)).toInt().shr(8).toShort(), position = position)
return LiteralValue(DataType.BYTE, bytevalue = (127.0* sin(rad)).toShort(), position = position)
}
private fun builtinSin8u(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 1)
throw SyntaxError("sin8u requires one argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
return LiteralValue(DataType.UBYTE, bytevalue = (128.0+127.5*sin(rad)).toShort(), position = position)
}
private fun builtinCos8(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
@ -311,7 +323,15 @@ private fun builtinCos8(args: List<IExpression>, position: Position, namespace:I
throw SyntaxError("cos8 requires one argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
return LiteralValue(DataType.BYTE, bytevalue = (32767.0* cos(rad)).toInt().shr(8).toShort(), position = position)
return LiteralValue(DataType.BYTE, bytevalue = (127.0* cos(rad)).toShort(), position = position)
}
private fun builtinCos8u(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 1)
throw SyntaxError("cos8u requires one argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
return LiteralValue(DataType.UBYTE, bytevalue = (128.0 + 127.5*cos(rad)).toShort(), position = position)
}
private fun builtinSin16(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
@ -322,6 +342,14 @@ private fun builtinSin16(args: List<IExpression>, position: Position, namespace:
return LiteralValue(DataType.WORD, wordvalue = (32767.0* sin(rad)).toInt(), position = position)
}
private fun builtinSin16u(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 1)
throw SyntaxError("sin16u requires one argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
return LiteralValue(DataType.UWORD, wordvalue = (32768.0+32767.5*sin(rad)).toInt(), position = position)
}
private fun builtinCos16(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 1)
throw SyntaxError("cos16 requires one argument", position)
@ -330,6 +358,14 @@ private fun builtinCos16(args: List<IExpression>, position: Position, namespace:
return LiteralValue(DataType.WORD, wordvalue = (32767.0* cos(rad)).toInt(), position = position)
}
private fun builtinCos16u(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 1)
throw SyntaxError("cos16u requires one argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
return LiteralValue(DataType.UWORD, wordvalue = (32768.0+32767.5* cos(rad)).toInt(), position = position)
}
private fun numericLiteral(value: Number, position: Position): LiteralValue {
val floatNum=value.toDouble()
val tweakedValue: Number =

View File

@ -26,10 +26,14 @@ enum class Syscall(val callNr: Short) {
FUNC_SIN(60),
FUNC_SIN8(61),
FUNC_SIN16(62),
FUNC_COS(63),
FUNC_COS8(64),
FUNC_COS16(65),
FUNC_SIN8U(62),
FUNC_SIN16(63),
FUNC_SIN16U(64),
FUNC_COS(65),
FUNC_COS8(66),
FUNC_COS8U(67),
FUNC_COS16(68),
FUNC_COS16U(69),
FUNC_ABS(70),
FUNC_TAN(71),
FUNC_ATAN(72),
@ -1556,20 +1560,36 @@ class StackVm(private var traceOutputFile: String?) {
Syscall.FUNC_COS -> evalstack.push(Value(DataType.FLOAT, cos(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_SIN8 -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.BYTE, (32767.0* sin(rad)).toInt().shr(8).toShort()))
evalstack.push(Value(DataType.BYTE, (127.0* sin(rad)).toShort()))
}
Syscall.FUNC_SIN8U -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.UBYTE, (128.0+127.5*sin(rad)).toShort()))
}
Syscall.FUNC_SIN16 -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.WORD, (32767.0* sin(rad)).toInt()))
}
Syscall.FUNC_SIN16U -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.WORD, (32768.0+32767.5* sin(rad)).toInt()))
}
Syscall.FUNC_COS8 -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.BYTE, (32767.0* cos(rad)).toInt().shr(8).toShort()))
evalstack.push(Value(DataType.BYTE, (127.0* cos(rad)).toShort()))
}
Syscall.FUNC_COS8U -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.UBYTE, (128.0+127.5*cos(rad)).toShort()))
}
Syscall.FUNC_COS16 -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.WORD, (32767.0* cos(rad)).toInt()))
}
Syscall.FUNC_COS16U -> {
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
evalstack.push(Value(DataType.WORD, (32768.0+32767.5* cos(rad)).toInt()))
}
Syscall.FUNC_ROUND -> evalstack.push(Value(DataType.WORD, evalstack.pop().numericValue().toDouble().roundToInt()))
Syscall.FUNC_ABS -> {
val value = evalstack.pop()

View File

@ -517,17 +517,29 @@ sin(x)
cos(x)
Cosine. (floating point version)
sin8u(x)
Fast 8-bit ubyte sine of angle 0..255, result is in range 0..255
sin8(x)
Fast 8-bit byte sine of angle 0..255
Fast 8-bit byte sine of angle 0..255, result is in range -127..127
sin16u(x)
Fast 16-bit uword sine of angle 0..255, result is in range 0..65535
sin16(x)
Fast 16-bit word sine of angle 0..255
Fast 16-bit word sine of angle 0..255, result is in range -32767..32767
cos8u(x)
Fast 8-bit ubyte cosine of angle 0..255, result is in range 0..255
cos8(x)
Fast 8-bit byte cosine of angle 0..255
Fast 8-bit byte cosine of angle 0..255, result is in range -127..127
cos16u(x)
Fast 16-bit uword cosine of angle 0..255, result is in range 0..65535
cos16(x)
Fast 16-bit word cosine of angle 0..255
Fast 16-bit word cosine of angle 0..255, result is in range -32767..32767
abs(x)
Absolute value.

View File

@ -485,41 +485,77 @@ greatereq_w .proc
func_sin8 .proc
ldy c64.ESTACK_LO+1,x
lda func_sin16.sinecos8hi,y
lda _sinecos8,y
sta c64.ESTACK_LO+1,x
rts
_sinecos8 .char 127 * sin(range(256+64) * rad(360.0/256.0))
.pend
func_sin8u .proc
ldy c64.ESTACK_LO+1,x
lda _sinecos8u,y
sta c64.ESTACK_LO+1,x
rts
_sinecos8u .byte 128 + 127.5 * sin(range(256+64) * rad(360.0/256.0))
.pend
func_sin16 .proc
ldy c64.ESTACK_LO+1,x
lda func_sin16.sinecos8lo,y
lda _sinecos8lo,y
sta c64.ESTACK_LO+1,x
lda func_sin16.sinecos8hi,y
lda _sinecos8hi,y
sta c64.ESTACK_HI+1,x
rts
_ := 32767 * sin(range(256+64) * rad(360.0/256.0))
sinecos8lo .byte <_
sinecos8hi .byte >_
_sinecos8lo .byte <_
_sinecos8hi .byte >_
.pend
func_sin16u .proc
ldy c64.ESTACK_LO+1,x
lda _sinecos8ulo,y
sta c64.ESTACK_LO+1,x
lda _sinecos8uhi,y
sta c64.ESTACK_HI+1,x
rts
_ := 32768 + 32767.5 * sin(range(256+64) * rad(360.0/256.0))
_sinecos8ulo .byte <_
_sinecos8uhi .byte >_
.pend
func_cos8 .proc
ldy c64.ESTACK_LO+1,x
lda func_sin16.sinecos8hi+64,y
lda func_sin8._sinecos8+64,y
sta c64.ESTACK_LO+1,x
rts
.pend
func_cos8u .proc
ldy c64.ESTACK_LO+1,x
lda func_sin8u._sinecos8u+64,y
sta c64.ESTACK_LO+1,x
rts
.pend
func_cos16 .proc
ldy c64.ESTACK_LO+1,x
lda func_sin16.sinecos8lo+64,y
lda func_sin16._sinecos8lo+64,y
sta c64.ESTACK_LO+1,x
lda func_sin16.sinecos8hi+64,y
lda func_sin16._sinecos8hi+64,y
sta c64.ESTACK_HI+1,x
rts
.pend
func_cos16u .proc
ldy c64.ESTACK_LO+1,x
lda func_sin16u._sinecos8ulo+64,y
sta c64.ESTACK_LO+1,x
lda func_sin16u._sinecos8uhi+64,y
sta c64.ESTACK_HI+1,x
rts
.pend
peek_address .proc