created mkword function

This commit is contained in:
Irmen de Jong 2019-01-09 01:03:33 +01:00
parent 0ab0f02e75
commit 46c282d6d5
7 changed files with 121 additions and 9 deletions

View File

@ -823,6 +823,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
}
}
"msb" -> prog.instr(Opcode.MSB) // note: LSB is not a function, it's just an alias for the cast "... as ubyte"
"mkword" -> prog.instr(Opcode.MKWORD)
"lsl" -> {
val arg = args.single()
val dt = arg.resultingDatatype(namespace, heap)

View File

@ -133,6 +133,7 @@ enum class Opcode {
// numeric type conversions
MSB, // note: lsb is equivalent to CAST_UW_TO_UB or CAST_W_TO_UB
MKWORD, // create a word from lsb + msb
CAST_UB_TO_B,
CAST_UB_TO_UW,
CAST_UB_TO_W,

View File

@ -783,6 +783,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.CAST_UB_TO_UW, Opcode.CAST_UB_TO_W -> " lda #0 | sta ${(ESTACK_HI+1).toHex()},x" // clear the msb
Opcode.CAST_B_TO_UW, Opcode.CAST_B_TO_W -> " lda ${(ESTACK_LO+1).toHex()},x | ${signExtendA("${(ESTACK_HI+1).toHex()},x")}" // sign extend the lsb
Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x"
// TODO: Opcode.MKWORD -> " inx | lda ${ESTACK_LO.toHex()},x | sta ${(ESTACK_HI+1).toHex()},x "
Opcode.ADD_UB, Opcode.ADD_B -> { // TODO inline better?
"""
@ -3011,6 +3012,66 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
adc ${(ESTACK_HI+1).toHex()},x
sta ${(ESTACK_HI+1).toHex()},x
"""
},
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD)) { segment ->
"""
lda ${segment[0].callLabel}
sta ${ESTACK_LO.toHex()},x
lda ${segment[1].callLabel}
sta ${ESTACK_HI.toHex()},x
dex
"""
},
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD)) { segment ->
"""
lda #${hexVal(segment[0])}
sta ${ESTACK_LO.toHex()},x
lda ${segment[1].callLabel}
sta ${ESTACK_HI.toHex()},x
dex
"""
},
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.MKWORD)) { segment ->
"""
lda ${segment[0].callLabel}
sta ${ESTACK_LO.toHex()},x
lda #${hexVal(segment[1])}
sta ${ESTACK_HI.toHex()},x
dex
"""
},
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD, Opcode.POP_VAR_WORD)) { segment ->
"""
lda ${segment[0].callLabel}
sta ${segment[3].callLabel}
lda ${segment[1].callLabel}
sta ${segment[3].callLabel}+1
"""
},
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.MKWORD, Opcode.POP_VAR_WORD)) { segment ->
"""
lda ${segment[0].callLabel}
sta ${segment[3].callLabel}
lda #${hexVal(segment[1])}
sta ${segment[3].callLabel}+1
"""
},
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD, Opcode.POP_VAR_WORD)) { segment ->
"""
lda #${hexVal(segment[0])}
sta ${segment[3].callLabel}
lda ${segment[1].callLabel}
sta ${segment[3].callLabel}+1
"""
},
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD, Opcode.CAST_UW_TO_W, Opcode.POP_VAR_WORD)) { segment ->
"""
lda ${segment[0].callLabel}
sta ${segment[4].callLabel}
lda ${segment[1].callLabel}
sta ${segment[4].callLabel}+1
"""
}
)

View File

@ -56,6 +56,9 @@ val BuiltinFunctions = mapOf(
"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} }},
"lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
"msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
"mkword" to FunctionSignature(true, listOf(
BuiltinFunctionParam("lsb", setOf(DataType.UBYTE)),
BuiltinFunctionParam("msb", setOf(DataType.UBYTE))), DataType.UWORD, ::builtinMkword),
"rnd" to FunctionSignature(true, emptyList(), DataType.UBYTE),
"rndw" to FunctionSignature(true, emptyList(), DataType.UWORD),
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
@ -302,6 +305,16 @@ private fun builtinLen(args: List<IExpression>, position: Position, namespace:IN
}
}
private fun builtinMkword(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 2)
throw SyntaxError("mkword requires lsb and msb arguments", position)
val constLsb = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
val constMsb = args[1].constValue(namespace, heap) ?: throw NotConstArgumentException()
val result = (constMsb.asIntegerValue!! shl 8) or constLsb.asIntegerValue!!
return LiteralValue(DataType.UWORD, wordvalue = result, position = position)
}
private fun builtinSin8(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
if (args.size != 1)
throw SyntaxError("sin8 requires one argument", position)

View File

@ -1028,6 +1028,13 @@ class StackVm(private var traceOutputFile: String?) {
checkDt(v, DataType.UWORD, DataType.WORD)
evalstack.push(v.msb())
}
Opcode.MKWORD -> {
val msb = evalstack.pop()
val lsb = evalstack.pop()
checkDt(lsb, DataType.UBYTE)
checkDt(msb, DataType.UBYTE)
evalstack.push(Value(DataType.UWORD, (msb.integerValue() shl 8) or lsb.integerValue()))
}
Opcode.AND_BYTE -> {
val (top, second) = evalstack.pop2()
checkDt(top, DataType.UBYTE)

View File

@ -605,6 +605,9 @@ lsb(x)
msb(x)
Get the most significant byte of the word x.
mkword(lsb, msb)
Efficiently create a word value from two bytes (the lsb and the msb). Avoids multiplication and shifting.
any(x)
1 ('true') if any of the values in the array value x is 'true' (not zero), else 0 ('false')

View File

@ -1,20 +1,46 @@
%import c64utils
%import c64flt
~ main {
sub start() {
; @todo create word function ;c64.SPXY[i] = (rnd() as uword) * 256 + (50+25*i)
; @todo more efficient +1/-1 additions in expressions
float f1 = c64flt.TWOPI
c64flt.print_fln(3.1415)
c64flt.print_fln(f1)
f1 = 3.1415
f1 = 3.1415
f1 = 3.1415
f1 = 3.1415
ubyte lsbb = $aa
ubyte msbb = $44
uword[4] uwarr
uword uw = (msbb as uword)*256 + lsbb
c64scr.print_uwhex(0, uw)
c64.CHROUT('\n')
uw = mkword(lsbb, msbb)
c64scr.print_uwhex(0, uw)
c64.CHROUT('\n')
uw = mkword($aa, $44)
c64scr.print_uwhex(0, uw)
c64.CHROUT('\n')
uw = mkword(lsbb, $44)
c64scr.print_uwhex(0, uw)
c64.CHROUT('\n')
uw = mkword($aa, msbb)
c64scr.print_uwhex(0, uw)
c64.CHROUT('\n')
uwarr[2] = mkword(lsbb, msbb)
c64scr.print_uwhex(0, uwarr[2])
c64.CHROUT('\n')
uwarr[2] = mkword(lsbb, $44)
c64scr.print_uwhex(0, uwarr[2])
c64.CHROUT('\n')
uwarr[2] = mkword($aa, msbb)
c64scr.print_uwhex(0, uwarr[2])
c64.CHROUT('\n')
word w = mkword(lsbb,msbb) as word
c64scr.print_w(w)
c64.CHROUT('\n')
}
}