This commit is contained in:
Irmen de Jong 2018-12-18 15:12:56 +01:00
parent ca1d6bff56
commit 3a7b341f47
27 changed files with 278 additions and 243 deletions

View File

@ -10,7 +10,7 @@
byte v1
byte v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
v1 = 100
@ -110,7 +110,7 @@
else
c64.STROUT("error in 22>=22!\n")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
}

View File

@ -10,7 +10,7 @@
float v1
float v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
v1 = 1.11
@ -110,7 +110,7 @@
else
c64.STROUT("error in -22.2>=-22.2!\n")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
}

View File

@ -10,7 +10,7 @@
ubyte v1
ubyte v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
v1 = 100
@ -110,7 +110,7 @@
else
c64.STROUT("error in 22>=22!\n")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
}

View File

@ -10,7 +10,7 @@
uword v1
uword v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
v1 = 100
@ -110,7 +110,7 @@
else
c64.STROUT("error in 322>=322!\n")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
}

View File

@ -10,7 +10,7 @@
word v1
word v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
v1 = 100
@ -110,7 +110,7 @@
else
c64.STROUT("error in -222>=-222!\n")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
}

View File

@ -11,7 +11,7 @@
; check stack usage:
c64.STROUT("signed byte ")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT(' ')
cr=v1==v2
@ -39,7 +39,7 @@
cr=v1>=v2
cr=v1>=v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
; comparisons:
@ -58,7 +58,7 @@
c64.STROUT("v1=20, v2=-111\n")
compare()
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
return

View File

@ -13,7 +13,7 @@
; check stack usage:
c64.STROUT("floating point ")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT(' ')
cr=v1==v2
@ -41,7 +41,7 @@
cr=v1>=v2
cr=v1>=v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
; comparisons:
@ -75,7 +75,7 @@
c64.STROUT("v1 = v2 = 0\n")
compare()
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
return

View File

@ -11,7 +11,7 @@
; check stack usage:
c64.STROUT("unsigned byte ")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT(' ')
cr=v1==v2
@ -39,7 +39,7 @@
cr=v1>=v2
cr=v1>=v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
; comparisons:
@ -58,7 +58,7 @@
c64.STROUT("v1=220, v2=10\n")
compare()
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
return

View File

@ -11,7 +11,7 @@
; check stack usage:
c64.STROUT("unsigned word ")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT(' ')
cr=v1==v2
@ -39,7 +39,7 @@
cr=v1>=v2
cr=v1>=v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
; comparisons:
@ -88,7 +88,7 @@
c64.STROUT("v1 = v2 = aa\n")
compare()
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
return

View File

@ -12,7 +12,7 @@
; check stack usage:
c64.STROUT("signed word ")
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT(' ')
cr=v1==v2
@ -40,7 +40,7 @@
cr=v1>=v2
cr=v1>=v2
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
; comparisons:
@ -125,7 +125,7 @@
c64.STROUT("v1 = v2 = aa\n")
compare()
c64scr.print_byte(X)
c64scr.print_ubyte(X)
c64.CHROUT('\n')
return

View File

@ -81,11 +81,11 @@
sub draw_edges() {
sub toscreenx(x: float, z: float) -> word {
return floor(x/(4.2+z) * flt(height)) + width // 2
return fintw(x/(4.2+z) * flt(height)) + width // 2
}
sub toscreeny(y: float, z: float) -> word {
return floor(y/(4.2+z) * flt(height)) + height // 2
return fintw(y/(4.2+z) * flt(height)) + height // 2
}
; draw all edges of the object
@ -93,8 +93,6 @@
ubyte e_from = msb(edge)
ubyte e_to = lsb(edge)
float xxxx=rotatedx[msb(edge)] ; @todo weg
word x1 = toscreenx(rotatedx[e_from], rotatedz[e_from])
word y1 = toscreeny(rotatedy[e_from], rotatedz[e_from])
word x2 = toscreenx(rotatedx[e_to], rotatedz[e_to])

View File

@ -80,11 +80,11 @@
sub draw_edges() {
sub toscreenx(x: float, z: float) -> word {
return floor(x/(4.2+z) * flt(height)) + width // 2
return fintw(x/(4.2+z) * flt(height)) + width // 2
}
sub toscreeny(y: float, z: float) -> word {
return floor(y/(4.2+z) * flt(height)) + height // 2
return fintw(y/(4.2+z) * flt(height)) + height // 2
}
; draw all edges of the object

View File

@ -3,22 +3,30 @@
~ main {
sub start() {
sub start() {
; set screen colors and activate lowercase charset
c64.EXTCOL = 5
c64.BGCOL0 = 0
c64.COLOR = 1
c64.VMCSB |= 2
; set screen colors and activate lowercase charset
c64.EXTCOL = 5
c64.BGCOL0 = 0
c64.COLOR = 1
c64.VMCSB |= 2
; use kernel routine to write text
c64.STROUT("Hello!\n")
; use kernel routine to write text
c64.STROUT("Hello!\n")
str question = "How are you?\n"
; use iteration to write text
for ubyte char in question {
c64.CHROUT(char)
}
; use loop to write characters
str bye = "Goodbye!\n"
for ubyte c in 0 to len(bye) { ; @TODO fix compiler crash
c64.CHROUT(bye[c])
}
str question = "How are you?\n"
for ubyte c in 0 to len(question) {
c64.CHROUT(question[c])
}
return
}
}

View File

@ -0,0 +1,37 @@
%import c64utils
%option enable_floats
~ main {
const uword width = 30
const uword height = 20
sub start() {
c64scr.print_string("calculating mandelbrot fractal...\n")
for ubyte pixely in 0 to height-1 {
float yy = pixely/flt(height)/0.4-1.0
for ubyte pixelx in 0 to width-1 {
float xx = pixelx/flt(width)/0.3-2.0
float xsquared = 0.0
float ysquared = 0.0
float x = 0.0
float y = 0.0
ubyte iter = 0
while (iter<16 and xsquared+ysquared<4.0) {
y = x*y*2.0 + yy
x = xsquared - ysquared + xx
xsquared = x*x
ysquared = y*y
iter++
}
c64.CHROUT(48-iter)
}
c64.CHROUT('\n')
}
c64scr.print_string("finished!\n")
}
}

View File

@ -1,39 +0,0 @@
%import c64utils
%option enable_floats
~ main {
const uword width = 320 // 2
const uword height = 256 // 2
const uword xoffset = 40
const uword yoffset = 30
sub start() {
;vm_gfx_clearscr(11)
;vm_gfx_text(2, 1, 1, "Calculating Mandelbrot Fractal...")
for ubyte pixely in yoffset to yoffset+height-1 {
float yy = flt((pixely-yoffset))/height/3.6+0.4
for uword pixelx in xoffset to xoffset+width-1 {
float xx = flt((pixelx-xoffset))/width/3.0+0.2
float xsquared = 0.0
float ysquared = 0.0
float x = 0.0
float y = 0.0
ubyte iter = 0
while (iter<32 and xsquared+ysquared<4.0) {
y = x*y*2.0 + yy
x = xsquared - ysquared + xx
xsquared = x*x
ysquared = y*y
iter++
}
;vm_gfx_pixel(pixelx, pixely, iter)
}
}
;vm_gfx_text(11, 21, 1, "Finished!")
}
}

View File

@ -0,0 +1,29 @@
%import c64utils
%option enable_floats
~ main {
const uword width = 40
const uword height = 25
sub start() {
float t
ubyte color
while(1) {
float x = sin(t) + cos(t*1.1234)
float y = cos(t) + sin(t*1.44)
c64scr.setchrclr(screenx(x), screeny(y), 81, color)
t += 0.1
color++
}
}
sub screenx(x: float) -> ubyte {
return b2ub(fintb(x * flt(width)/4.2) + width//2)
}
sub screeny(y: float) -> ubyte {
return b2ub(fintb(y * flt(height)/4.2) + height//2)
}
}

View File

@ -1,31 +0,0 @@
%import c64utils
%option enable_floats
~ main {
const uword width = 320
const uword height = 200
sub start() {
;vm_gfx_clearscr(0)
float t
ubyte color
while(1) {
float x = sin(t*1.01) + cos(t*1.1234)
float y = cos(t) + sin(t*0.03456)
;vm_gfx_pixel(screenx(x), screeny(y), color//16)
t += 0.01
color++
}
}
sub screenx(x: float) -> word {
return floor(x * flt(width)/4.1) + width // 2
}
sub screeny(y: float) -> word {
return floor(y * flt(height)/4.1) + height // 2
}
}

View File

@ -23,9 +23,9 @@
}
sub screenx(x: float) -> word {
return floor(x * flt(width)/4.1) + width // 2
return fintw(x * flt(width)/4.1) + width // 2
}
sub screeny(y: float) -> word {
return floor(y * flt(height)/4.1) + height // 2
return fintw(y * flt(height)/4.1) + height // 2
}
}

View File

@ -5,67 +5,14 @@
sub start() {
uword uw1
uword uw2
word w1
word w2
ubyte ub1
ubyte ub2
byte b1
byte b2
float f1
float f2
word[3] wa = [-1000.w,2000.w,3000.w] ; @todo array data type fix (float->word)
word[3] wa2 = [1000,2000,3000] ; @todo array data type fix (uword->word)
ub1 = 200
c64scr.print_ubyte(abs(ub1)) ; ok
c64.CHROUT('\n')
b1 = 100
c64scr.print_byte(abs(b1)) ; ok
c64.CHROUT('\n')
b1 = 0
c64scr.print_byte(abs(b1)) ;ok
c64.CHROUT('\n')
b1 = -100
c64scr.print_byte(abs(b1)) ;ok
c64.CHROUT('\n')
byte[3] ba1 = [-1, 2, 3]
byte[3] ba2 = [100,101,102] ; @todo array data type
uw1 = 1000
c64scr.print_uword(abs(uw1)) ;ok
c64.CHROUT('\n')
w1 = 0
c64scr.print_word(abs(w1)) ;ok
c64.CHROUT('\n')
w1 = -1000
c64scr.print_word(abs(w1)) ;ok
c64.CHROUT('\n')
;return b2ub(fintb(x * flt(width)/4.2) + width//2)
f1 = 11.22
c64flt.print_float(abs(f1)) ;ok
c64.CHROUT('\n')
f1 = 0
c64flt.print_float(abs(f1)) ;ok
c64.CHROUT('\n')
f1 = -22.33
c64flt.print_float(abs(f1)) ;@todo FAIL
c64.CHROUT('\n')
; float t = 0.0
; ubyte color=0
; while(true) {
; ubyte x = lsb(round(sin(t)*17.0))+20
; ubyte y = lsb(round(cos(t*1.3634567)*10.0))+12
;
; c64scr.setchrclr(x,y,color,color)
; color++
;; vm_gfx_text(x, y, 1, "*")
; ;vm_gfx_pixel(x,y,1)
;; c64scr.print_ubyte(x)
;; c64.CHROUT(',')
;; c64scr.print_ubyte(y)
;; c64.CHROUT('\n')
; ;screen[x] = '*'
; t+=0.1
; }
}
}

View File

@ -1007,11 +1007,11 @@ private class StatementTranslator(private val prog: IntermediateProgram,
}
"//" -> {
when(dt) {
DataType.UBYTE -> Opcode.FLOORDIV_UB
DataType.BYTE -> Opcode.FLOORDIV_B
DataType.UWORD -> Opcode.FLOORDIV_UW
DataType.WORD -> Opcode.FLOORDIV_W
DataType.FLOAT -> Opcode.FLOORDIV_F
DataType.UBYTE -> Opcode.DIV_UB
DataType.BYTE -> Opcode.DIV_B
DataType.UWORD -> Opcode.DIV_UW
DataType.WORD -> Opcode.DIV_W
DataType.FLOAT -> Opcode.FLOORDIV
else -> throw CompilerException("only byte/word/float possible")
}
}
@ -1454,6 +1454,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
if(valueDt !in validDt)
throw CompilerException("invalid datatype(s) for operand(s)")
val opcode = when(aug_op) {
// @todo ... need more datatypes here?
"+=" -> {
when (valueDt) {
DataType.UBYTE -> Opcode.ADD_UB
@ -1480,9 +1481,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
}
"//=" -> {
when (valueDt) {
DataType.UBYTE -> Opcode.FLOORDIV_UB
DataType.UWORD -> Opcode.FLOORDIV_UW
DataType.FLOAT -> Opcode.FLOORDIV_F
DataType.UBYTE -> Opcode.DIV_UB
DataType.UWORD -> Opcode.DIV_UW
DataType.FLOAT -> Opcode.FLOORDIV
else -> throw CompilerException("only byte/word/lfoat possible")
}
}

View File

@ -55,11 +55,7 @@ enum class Opcode {
DIV_UW,
DIV_W,
DIV_F,
FLOORDIV_UB,
FLOORDIV_B,
FLOORDIV_UW,
FLOORDIV_W,
FLOORDIV_F,
FLOORDIV,
REMAINDER_UB,
REMAINDER_B,
REMAINDER_UW,

View File

@ -427,6 +427,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
val call = Syscall.values().find { it.callNr==ins.arg.numericValue() }
when(call) {
Syscall.FUNC_WRD, Syscall.FUNC_UWRD -> ""
Syscall.FUNC_STR2UBYTE, Syscall.FUNC_STR2UWORD -> " jsr prog8_lib.func_str2uword"
else -> " jsr prog8_lib.${call.toString().toLowerCase()}"
}
}
@ -2708,19 +2709,29 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// byte var = lsb(word var)
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.LSB, Opcode.POP_VAR_BYTE)) { segment ->
" lda #<${segment[0].callLabel} | sta ${segment[2].callLabel}"
when(segment[2].callLabel) {
"A" -> " lda ${segment[0].callLabel}"
"X" -> " ldx ${segment[0].callLabel}"
"Y" -> " ldy ${segment[0].callLabel}"
else -> " lda ${segment[0].callLabel} | sta ${segment[2].callLabel}"
}
},
// byte var = msb(word var)
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB, Opcode.POP_VAR_BYTE)) { segment ->
" lda #>${segment[0].callLabel} | sta ${segment[2].callLabel}"
when(segment[2].callLabel) {
"A" -> " lda ${segment[0].callLabel}+1"
"X" -> " ldx ${segment[0].callLabel}+1"
"Y" -> " ldy ${segment[0].callLabel}+1"
else -> " lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}"
}
},
// push lsb(word var)
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.LSB)) { segment ->
" lda #<${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
" lda ${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
},
// push msb(word var)
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB)) { segment ->
" lda #>${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
" lda ${segment[0].callLabel}+1 | sta ${ESTACK_LO.toHex()},x | dex "
},
// set a register pair to a certain memory address (of a variable)

View File

@ -38,9 +38,9 @@ val BuiltinFunctions = mapOf(
"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) },
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.FLOAT, ::builtinAvg),
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) },
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) },
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) },
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) },
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) },
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) },
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", IterableDatatypes)), DataType.UBYTE, ::builtinLen),
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
@ -49,6 +49,8 @@ val BuiltinFunctions = mapOf(
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes)), DataType.FLOAT, ::builtinFlt),
"uwrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.WORD))), DataType.UWORD, ::builtinUwrd),
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD))), DataType.WORD, ::builtinWrd),
"fintb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.BYTE, ::builtinFintb),
"fintw" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD, ::builtinFintw),
"b2ub" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.BYTE))), DataType.UBYTE, ::builtinB2ub),
"ub2b" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE))), DataType.BYTE, ::builtinUb2b),
"rnd" to FunctionSignature(true, emptyList(), DataType.UBYTE),
@ -245,6 +247,42 @@ private fun builtinFlt(args: List<IExpression>, position: Position, namespace:IN
return LiteralValue(DataType.FLOAT, floatvalue = number.toDouble(), position = position)
}
private fun builtinFintb(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
// 1 float arg, convert to byte
if(args.size!=1)
throw SyntaxError("fintb requires one floating point argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
if(constval.type!=DataType.FLOAT)
throw SyntaxError("fintb requires one floating point argument", position)
val integer: Short
val flt = constval.floatvalue!!
integer = when {
flt <= -128 -> -128
flt >= 127 -> 127
else -> flt.toShort()
}
return LiteralValue(DataType.BYTE, bytevalue = integer, position = position)
}
private fun builtinFintw(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
// 1 float arg, convert to word
if(args.size!=1)
throw SyntaxError("fintw requires one floating point argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
if(constval.type!=DataType.FLOAT)
throw SyntaxError("fintw requires one floating point argument", position)
val integer: Int
val flt = constval.floatvalue!!
integer = when {
flt <= -32768 -> -32768
flt >= 32767 -> 32767
else -> flt.toInt()
}
return LiteralValue(DataType.WORD, wordvalue = integer, position = position)
}
private fun builtinWrd(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
// 1 byte arg, convert to word
if(args.size!=1)

View File

@ -39,6 +39,8 @@ enum class Syscall(val callNr: Short) {
FUNC_ROUND(79),
FUNC_FLOOR(80),
FUNC_CEIL(81),
FUNC_FINTB(82),
FUNC_FINTW(83),
FUNC_RND(89), // push a random byte on the stack
FUNC_RNDW(90), // push a random word on the stack
FUNC_RNDF(91), // push a random float on the stack (between 0.0 and 1.0)
@ -442,31 +444,7 @@ class StackVm(private var traceOutputFile: String?) {
checkDt(second, DataType.FLOAT)
evalstack.push(second.div(top))
}
Opcode.FLOORDIV_UB -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UBYTE)
checkDt(second, DataType.UBYTE)
evalstack.push(second.floordiv(top))
}
Opcode.FLOORDIV_UW -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UWORD)
checkDt(second, DataType.UWORD)
evalstack.push(second.floordiv(top))
}
Opcode.FLOORDIV_B -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.BYTE)
checkDt(second, DataType.BYTE)
evalstack.push(second.floordiv(top))
}
Opcode.FLOORDIV_W -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.WORD)
checkDt(second, DataType.WORD)
evalstack.push(second.floordiv(top))
}
Opcode.FLOORDIV_F -> {
Opcode.FLOORDIV -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.FLOAT)
checkDt(second, DataType.FLOAT)
@ -1649,6 +1627,34 @@ class StackVm(private var traceOutputFile: String?) {
val y = str.str!!.trim().trimEnd('\u0000')
evalstack.push(Value(DataType.FLOAT, y.toDouble()))
}
Syscall.FUNC_FINTB -> {
val value = evalstack.pop()
if(value.type in NumericDatatypes) {
val integer: Short
val flt = value.numericValue().toDouble()
integer = when {
flt <= -128 -> -128
flt >= 127 -> 127
else -> flt.toShort()
}
evalstack.push(Value(DataType.BYTE, integer))
}
else throw VmExecutionException("cannot fintb $value")
}
Syscall.FUNC_FINTW -> {
val value = evalstack.pop()
if(value.type in NumericDatatypes) {
val integer: Int
val flt = value.numericValue().toDouble()
integer = when {
flt <= -32768 -> -32768
flt >= 32767 -> 32767
else -> flt.toInt()
}
evalstack.push(Value(DataType.WORD, integer))
}
else throw VmExecutionException("cannot fintw $value")
}
Syscall.FUNC_WRD -> {
val value = evalstack.pop()
checkDt(value, DataType.UBYTE, DataType.BYTE, DataType.UWORD)

View File

@ -324,9 +324,7 @@ class TestStackVmOpcodes {
@Test
fun testFloorDiv() {
testBinaryOperator(Value(DataType.UBYTE, 244), Opcode.FLOORDIV_UB, Value(DataType.UBYTE, 33), Value(DataType.UBYTE, 7))
testBinaryOperator(Value(DataType.UWORD, 3999), Opcode.FLOORDIV_UW, Value(DataType.UWORD, 99), Value(DataType.UWORD, 40))
testBinaryOperator(Value(DataType.FLOAT, 4000.25), Opcode.FLOORDIV_F, Value(DataType.FLOAT, 40.2), Value(DataType.FLOAT, 99.0))
testBinaryOperator(Value(DataType.FLOAT, 4000.25), Opcode.FLOORDIV, Value(DataType.FLOAT, 40.2), Value(DataType.FLOAT, 99.0))
}
@Test

View File

@ -551,6 +551,12 @@ flt(x)
Explicitly convert the number x to a floating point number.
This is required if you want calculations to have floating point precision when the values aren't float already.
fintb(x)
Take floor of the floating point into a byte value. (no overflow check). Use together with b2ub() to convert into a unsigned byte instead.
fintw(x)
Take floor of the floating point into a word value. (no overflow check).
wrd(x)
Explicitly convert the value x to a signed word (sign extended).
This is required if you want calculations to have word precision when the values are different types.

View File

@ -922,25 +922,59 @@ func_round .proc
jsr pop_float_fac1
stx SCRATCH_ZPREGX
jsr c64.FADDH
jsr c64.FTOSWORDYA
ldx SCRATCH_ZPREGX
sta ESTACK_HI,x
tya
jsr c64.INT
jmp push_fac1_as_result
.pend
func_floor .proc
jsr pop_float_fac1
stx SCRATCH_ZPREGX
jsr c64.INT
jmp push_fac1_as_result
.pend
func_ceil .proc
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
jsr pop_float_fac1
stx SCRATCH_ZPREGX
lda #<fmath_float1
ldy #>fmath_float1
jsr c64.MOVMF
jsr c64.INT
lda #<fmath_float1
ldy #>fmath_float1
jsr c64.FCOMP
cmp #0
beq +
lda #<c64.FL_FONE
ldy #>c64.FL_FONE
jsr c64.FADD
+ jmp push_fac1_as_result
.pend
func_fintb .proc
jsr pop_float_fac1
stx SCRATCH_ZPREGX
jsr c64.AYINT
lda $65
sta ESTACK_LO,x
dex
rts
.warn "round check outcome"
.pend
func_floor .proc ; @todo check outcome vs round/ceil
func_fintw .proc
jsr pop_float_fac1
stx SCRATCH_ZPREGX
jsr c64.AYINT
lda $64
sta ESTACK_HI,x
lda $65
sta ESTACK_LO,x
dex
rts
.warn "floor not implemented"
.pend
func_ceil .proc ; @todo check outcome vs floor/round
rts
.warn "ceil not implemented"
.pend
peek_address .proc
; -- peek address on stack into SCRATCH_ZPWORD1
@ -1123,11 +1157,6 @@ _rndf_rnum5 .fill 5
.pend
func_str2byte .proc
rts
.warn "str2byte not implemented"
.pend
; @todo python code for a str-to-ubyte function that doesn't use the basic rom:
;def str2ubyte(s, slen):
; hundreds_map = {
@ -1153,12 +1182,8 @@ func_str2byte .proc
; result += digitvalue
; return result
func_str2ubyte .proc
jmp func_str2uword
.pend
func_str2uword .proc
;-- convert string (address on stack) to uword number
;-- convert string (address on stack) to uword number (also used by str2ubyte)
lda ESTACK_LO+1,x
sta $22
lda ESTACK_HI+1,x
@ -1188,6 +1213,11 @@ func_str2word .proc
.warn "str2word not implemented"
.pend
func_str2byte .proc
rts
.warn "str2byte not implemented"
.pend
func_str2float .proc
rts
.warn "str2float not implemented"