mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 04:31:20 +00:00
retain type of consts better to avoid precision loss
this also fixed a difference in const calculation where the result could differ if you were using optimzations or not.
This commit is contained in:
parent
aba1a73e28
commit
0d3ad80659
@ -66,7 +66,7 @@ class ConstExprEvaluator {
|
|||||||
// DataType.WORD -> result = result.toShort().toInt()
|
// DataType.WORD -> result = result.toShort().toInt()
|
||||||
// else -> { /* keep as it is */ }
|
// else -> { /* keep as it is */ }
|
||||||
// }
|
// }
|
||||||
return NumericLiteral.optimalNumeric(result.toDouble(), left.position)
|
return NumericLiteral.optimalNumeric(left.type, null, result.toDouble(), left.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bitwiseXor(left: NumericLiteral, right: NumericLiteral): NumericLiteral {
|
private fun bitwiseXor(left: NumericLiteral, right: NumericLiteral): NumericLiteral {
|
||||||
@ -133,7 +133,7 @@ class ConstExprEvaluator {
|
|||||||
val error = "cannot add $left and $right"
|
val error = "cannot add $left and $right"
|
||||||
return when (left.type) {
|
return when (left.type) {
|
||||||
in IntegerDatatypes -> when (right.type) {
|
in IntegerDatatypes -> when (right.type) {
|
||||||
in IntegerDatatypes -> NumericLiteral.optimalInteger(left.number.toInt() + right.number.toInt(), left.position)
|
in IntegerDatatypes -> NumericLiteral.optimalInteger(left.type, right.type, left.number.toInt() + right.number.toInt(), left.position)
|
||||||
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt() + right.number, left.position)
|
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt() + right.number, left.position)
|
||||||
else -> throw ExpressionError(error, left.position)
|
else -> throw ExpressionError(error, left.position)
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ class ConstExprEvaluator {
|
|||||||
val error = "cannot subtract $left and $right"
|
val error = "cannot subtract $left and $right"
|
||||||
return when (left.type) {
|
return when (left.type) {
|
||||||
in IntegerDatatypes -> when (right.type) {
|
in IntegerDatatypes -> when (right.type) {
|
||||||
in IntegerDatatypes -> NumericLiteral.optimalInteger(left.number.toInt() - right.number.toInt(), left.position)
|
in IntegerDatatypes -> NumericLiteral.optimalInteger(left.type, right.type, left.number.toInt() - right.number.toInt(), left.position)
|
||||||
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt() - right.number, left.position)
|
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt() - right.number, left.position)
|
||||||
else -> throw ExpressionError(error, left.position)
|
else -> throw ExpressionError(error, left.position)
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ class ConstExprEvaluator {
|
|||||||
val error = "cannot multiply ${left.type} and ${right.type}"
|
val error = "cannot multiply ${left.type} and ${right.type}"
|
||||||
return when (left.type) {
|
return when (left.type) {
|
||||||
in IntegerDatatypes -> when (right.type) {
|
in IntegerDatatypes -> when (right.type) {
|
||||||
in IntegerDatatypes -> NumericLiteral.optimalInteger(left.number.toInt() * right.number.toInt(), left.position)
|
in IntegerDatatypes -> NumericLiteral.optimalInteger(left.type, right.type, left.number.toInt() * right.number.toInt(), left.position)
|
||||||
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt() * right.number, left.position)
|
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt() * right.number, left.position)
|
||||||
else -> throw ExpressionError(error, left.position)
|
else -> throw ExpressionError(error, left.position)
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ class ConstExprEvaluator {
|
|||||||
in IntegerDatatypes -> {
|
in IntegerDatatypes -> {
|
||||||
if(right.number.toInt()==0) divideByZeroError(right.position)
|
if(right.number.toInt()==0) divideByZeroError(right.position)
|
||||||
val result: Int = left.number.toInt() / right.number.toInt()
|
val result: Int = left.number.toInt() / right.number.toInt()
|
||||||
NumericLiteral.optimalInteger(result, left.position)
|
NumericLiteral.optimalInteger(left.type, right.type, result, left.position)
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
if(right.number==0.0) divideByZeroError(right.position)
|
if(right.number==0.0) divideByZeroError(right.position)
|
||||||
@ -219,7 +219,7 @@ class ConstExprEvaluator {
|
|||||||
in IntegerDatatypes -> when (right.type) {
|
in IntegerDatatypes -> when (right.type) {
|
||||||
in IntegerDatatypes -> {
|
in IntegerDatatypes -> {
|
||||||
if(right.number.toInt()==0) divideByZeroError(right.position)
|
if(right.number.toInt()==0) divideByZeroError(right.position)
|
||||||
NumericLiteral.optimalNumeric(left.number.toInt().toDouble() % right.number.toInt().toDouble(), left.position)
|
NumericLiteral.optimalNumeric(left.type, right.type, left.number.toInt().toDouble() % right.number.toInt().toDouble(), left.position)
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
if(right.number ==0.0) divideByZeroError(right.position)
|
if(right.number ==0.0) divideByZeroError(right.position)
|
||||||
|
@ -33,6 +33,14 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(numLiteral: NumericLiteral, parent: Node): Iterable<IAstModification> {
|
override fun after(numLiteral: NumericLiteral, parent: Node): Iterable<IAstModification> {
|
||||||
|
|
||||||
|
if(numLiteral.type==DataType.LONG) {
|
||||||
|
// see if LONG values may be reduced to something smaller
|
||||||
|
val smaller = NumericLiteral.optimalInteger(numLiteral.number.toInt(), numLiteral.position)
|
||||||
|
if(smaller.type!=DataType.LONG)
|
||||||
|
return listOf(IAstModification.ReplaceNode(numLiteral, smaller, parent))
|
||||||
|
}
|
||||||
|
|
||||||
if(parent is Assignment) {
|
if(parent is Assignment) {
|
||||||
val iDt = parent.target.inferType(program)
|
val iDt = parent.target.inferType(program)
|
||||||
if(iDt.isKnown && !iDt.isBool && !iDt.istype(numLiteral.type)) {
|
if(iDt.isKnown && !iDt.isBool && !iDt.istype(numLiteral.type)) {
|
||||||
@ -164,13 +172,13 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
|||||||
if(leftconst==null && rightconst!=null && rightconst.number<0.0) {
|
if(leftconst==null && rightconst!=null && rightconst.number<0.0) {
|
||||||
if (expr.operator == "-") {
|
if (expr.operator == "-") {
|
||||||
// X - -1 ---> X + 1
|
// X - -1 ---> X + 1
|
||||||
val posNumber = NumericLiteral.optimalNumeric(-rightconst.number, rightconst.position)
|
val posNumber = NumericLiteral.optimalNumeric(rightconst.type, null, -rightconst.number, rightconst.position)
|
||||||
val plusExpr = BinaryExpression(expr.left, "+", posNumber, expr.position)
|
val plusExpr = BinaryExpression(expr.left, "+", posNumber, expr.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent))
|
return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent))
|
||||||
}
|
}
|
||||||
else if (expr.operator == "+") {
|
else if (expr.operator == "+") {
|
||||||
// X + -1 ---> X - 1
|
// X + -1 ---> X - 1
|
||||||
val posNumber = NumericLiteral.optimalNumeric(-rightconst.number, rightconst.position)
|
val posNumber = NumericLiteral.optimalNumeric(rightconst.type, null, -rightconst.number, rightconst.position)
|
||||||
val plusExpr = BinaryExpression(expr.left, "-", posNumber, expr.position)
|
val plusExpr = BinaryExpression(expr.left, "-", posNumber, expr.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent))
|
return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent))
|
||||||
}
|
}
|
||||||
@ -384,12 +392,13 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
|||||||
val numval = decl.value as? NumericLiteral
|
val numval = decl.value as? NumericLiteral
|
||||||
if(decl.type== VarDeclType.CONST && numval!=null) {
|
if(decl.type== VarDeclType.CONST && numval!=null) {
|
||||||
val valueDt = numval.inferType(program)
|
val valueDt = numval.inferType(program)
|
||||||
|
if(valueDt istype DataType.LONG) {
|
||||||
|
return noModifications // this is handled in the numericalvalue case
|
||||||
|
}
|
||||||
if(valueDt isnot decl.datatype) {
|
if(valueDt isnot decl.datatype) {
|
||||||
if(decl.datatype!=DataType.BOOL || valueDt.isnot(DataType.UBYTE)) {
|
val cast = numval.cast(decl.datatype, true)
|
||||||
val cast = numval.cast(decl.datatype, true)
|
if (cast.isValid)
|
||||||
if (cast.isValid)
|
return listOf(IAstModification.ReplaceNode(numval, cast.valueOrZero(), decl))
|
||||||
return listOf(IAstModification.ReplaceNode(numval, cast.valueOrZero(), decl))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noModifications
|
return noModifications
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
;
|
;
|
||||||
; NOTE: the bitmap screen data is positioned in vram at $0:0000
|
; NOTE: the bitmap screen data is positioned in vram at $0:0000
|
||||||
;
|
;
|
||||||
|
; NOTE: In the future, these routines might be split out to separate modules, 1 for each screen mode,
|
||||||
|
; so they can be optimized a lot better. There's already a "gfx_lores" module with a few routines for lores 256C mode.
|
||||||
|
;
|
||||||
; SCREEN MODE LIST:
|
; SCREEN MODE LIST:
|
||||||
; mode 0 = reset back to default text mode
|
; mode 0 = reset back to default text mode
|
||||||
; mode 1 = bitmap 320 x 240 x 256c (8 bpp)
|
; mode 1 = bitmap 320 x 240 x 256c (8 bpp)
|
||||||
|
@ -233,7 +233,7 @@ math {
|
|||||||
sub direction(ubyte x1, ubyte y1, ubyte x2, ubyte y2) -> ubyte {
|
sub direction(ubyte x1, ubyte y1, ubyte x2, ubyte y2) -> ubyte {
|
||||||
; From a pair of positive coordinates, calculate discrete direction between 0 and 23 into A.
|
; From a pair of positive coordinates, calculate discrete direction between 0 and 23 into A.
|
||||||
; This adjusts the atan() result so that the direction N is centered on the angle=N instead of having it as a boundary
|
; This adjusts the atan() result so that the direction N is centered on the angle=N instead of having it as a boundary
|
||||||
ubyte angle = atan2(x1, y1, x2, y2) - 256/48
|
ubyte angle = atan2(x1, y1, x2, y2) - (256/48 as ubyte)
|
||||||
return 23-lsb(mkword(angle,0) / 2730)
|
return 23-lsb(mkword(angle,0) / 2730)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,21 +190,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
}
|
}
|
||||||
val cvalue = assignment.value.constValue(program)
|
val cvalue = assignment.value.constValue(program)
|
||||||
if(cvalue!=null) {
|
if(cvalue!=null) {
|
||||||
val number = cvalue.number
|
return castLiteral(cvalue)
|
||||||
// more complex comparisons if the type is different, but the constant value is compatible
|
|
||||||
if (valuetype == DataType.BYTE && targettype == DataType.UBYTE) {
|
|
||||||
if(number>0)
|
|
||||||
return castLiteral(cvalue)
|
|
||||||
} else if (valuetype == DataType.WORD && targettype == DataType.UWORD) {
|
|
||||||
if(number>0)
|
|
||||||
return castLiteral(cvalue)
|
|
||||||
} else if (valuetype == DataType.UBYTE && targettype == DataType.BYTE) {
|
|
||||||
if(number<0x80)
|
|
||||||
return castLiteral(cvalue)
|
|
||||||
} else if (valuetype == DataType.UWORD && targettype == DataType.WORD) {
|
|
||||||
if(number<0x8000)
|
|
||||||
return castLiteral(cvalue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,15 +343,72 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(range: RangeExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(range: RangeExpression, parent: Node): Iterable<IAstModification> {
|
||||||
|
val fromConst = range.from.constValue(program)
|
||||||
|
val toConst = range.to.constValue(program)
|
||||||
|
|
||||||
|
if(fromConst!=null) {
|
||||||
|
val smaller = NumericLiteral.optimalInteger(fromConst.number.toInt(), fromConst.position)
|
||||||
|
if(fromConst.type.largerThan(smaller.type)) {
|
||||||
|
val toType = range.to.inferType(program)
|
||||||
|
if(toType isnot smaller.type) {
|
||||||
|
if(toConst!=null) {
|
||||||
|
// can we make the to value into the same smaller type?
|
||||||
|
val smallerTo = NumericLiteral.optimalInteger(toConst.number.toInt(), toConst.position)
|
||||||
|
if(smaller.type==smallerTo.type) {
|
||||||
|
val newRange = RangeExpression(smaller, smallerTo, range.step, range.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(range, newRange, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val newRange = RangeExpression(smaller, range.to, range.step, range.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(range, newRange, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(toConst!=null) {
|
||||||
|
val smaller = NumericLiteral.optimalInteger(toConst.number.toInt(), toConst.position)
|
||||||
|
if(toConst.type.largerThan(smaller.type)) {
|
||||||
|
val fromType = range.from.inferType(program)
|
||||||
|
if(fromType isnot smaller.type) {
|
||||||
|
if(fromConst!=null) {
|
||||||
|
// can we make the from value into the same smaller type?
|
||||||
|
val smallerFrom = NumericLiteral.optimalInteger(fromConst.number.toInt(), fromConst.position)
|
||||||
|
if(smaller.type==smallerFrom.type) {
|
||||||
|
val newRange = RangeExpression(smallerFrom, smaller, range.step, range.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(range, newRange, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val newRange = RangeExpression(range.from, smaller, range.step, range.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(range, newRange, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val modifications = mutableListOf<IAstModification>()
|
||||||
val fromDt = range.from.inferType(program).getOr(DataType.UNDEFINED)
|
val fromDt = range.from.inferType(program).getOr(DataType.UNDEFINED)
|
||||||
val toDt = range.to.inferType(program).getOr(DataType.UNDEFINED)
|
val toDt = range.to.inferType(program).getOr(DataType.UNDEFINED)
|
||||||
val modifications = mutableListOf<IAstModification>()
|
|
||||||
val (commonDt, toChange) = BinaryExpression.commonDatatype(fromDt, toDt, range.from, range.to)
|
val (commonDt, toChange) = BinaryExpression.commonDatatype(fromDt, toDt, range.from, range.to)
|
||||||
if(toChange!=null)
|
if(toChange!=null)
|
||||||
addTypecastOrCastedValueModification(modifications, toChange, commonDt, range)
|
addTypecastOrCastedValueModification(modifications, toChange, commonDt, range)
|
||||||
|
|
||||||
return modifications
|
return modifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||||
|
val constIdx = arrayIndexedExpression.indexer.constIndex()
|
||||||
|
if(constIdx!=null) {
|
||||||
|
val smaller = NumericLiteral.optimalInteger(constIdx, arrayIndexedExpression.indexer.position)
|
||||||
|
val idxDt = arrayIndexedExpression.indexer.indexExpr.inferType(program).getOr(DataType.UNDEFINED)
|
||||||
|
if(idxDt.largerThan(smaller.type)) {
|
||||||
|
val newIdx = ArrayIndex(smaller, smaller.position)
|
||||||
|
val newIndexer = ArrayIndexedExpression(arrayIndexedExpression.arrayvar, newIdx, arrayIndexedExpression.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, newIndexer, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noModifications
|
||||||
|
}
|
||||||
|
|
||||||
private fun addTypecastOrCastedValueModification(
|
private fun addTypecastOrCastedValueModification(
|
||||||
modifications: MutableList<IAstModification>,
|
modifications: MutableList<IAstModification>,
|
||||||
expressionToCast: Expression,
|
expressionToCast: Expression,
|
||||||
|
@ -498,6 +498,24 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
|||||||
fun fromBoolean(bool: Boolean, position: Position) =
|
fun fromBoolean(bool: Boolean, position: Position) =
|
||||||
NumericLiteral(DataType.BOOL, if(bool) 1.0 else 0.0, position)
|
NumericLiteral(DataType.BOOL, if(bool) 1.0 else 0.0, position)
|
||||||
|
|
||||||
|
fun optimalNumeric(origType1: DataType, origType2: DataType?, value: Number, position: Position) : NumericLiteral {
|
||||||
|
val optimal = optimalNumeric(value, position)
|
||||||
|
val largestOrig = if(origType2==null) origType1 else if(origType1.largerThan(origType2)) origType1 else origType2
|
||||||
|
if(largestOrig.largerThan(optimal.type))
|
||||||
|
return NumericLiteral(largestOrig, optimal.number, position)
|
||||||
|
else
|
||||||
|
return optimal
|
||||||
|
}
|
||||||
|
|
||||||
|
fun optimalInteger(origType1: DataType, origType2: DataType?, value: Int, position: Position): NumericLiteral {
|
||||||
|
val optimal = optimalInteger(value, position)
|
||||||
|
val largestOrig = if(origType2==null) origType1 else if(origType1.largerThan(origType2)) origType1 else origType2
|
||||||
|
if(largestOrig.largerThan(optimal.type))
|
||||||
|
return NumericLiteral(largestOrig, optimal.number, position)
|
||||||
|
else
|
||||||
|
return optimal
|
||||||
|
}
|
||||||
|
|
||||||
fun optimalNumeric(value: Number, position: Position): NumericLiteral {
|
fun optimalNumeric(value: Number, position: Position): NumericLiteral {
|
||||||
val digits = floor(value.toDouble()) - value.toDouble()
|
val digits = floor(value.toDouble()) - value.toDouble()
|
||||||
return if(value is Double && digits!=0.0) {
|
return if(value is Double && digits!=0.0) {
|
||||||
@ -1090,7 +1108,16 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
|||||||
} else if(vardecl.type!= VarDeclType.CONST) {
|
} else if(vardecl.type!= VarDeclType.CONST) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return vardecl.value?.constValue(program)
|
|
||||||
|
// the value of a variable can (temporarily) be a different type as the vardecl itself.
|
||||||
|
// don't return the value if the types don't match yet!
|
||||||
|
val value = vardecl.value?.constValue(program)
|
||||||
|
if(value==null || value.type==vardecl.datatype)
|
||||||
|
return value
|
||||||
|
val optimal = NumericLiteral.optimalNumeric(value.number, value.position)
|
||||||
|
if(optimal.type==vardecl.datatype)
|
||||||
|
return optimal
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
wrong answer if cast as uword is not done in:
|
Should give type error, but seems to make num a word !?:
|
||||||
const uword W=320; uword x1 = ((WIDTH-256)/2 as uword) + math.sin8u(i)
|
const uword screenwidth = txt.DEFAULT_WIDTH
|
||||||
|
const ubyte num = (screenwidth-1) / 2
|
||||||
|
|
||||||
|
|
||||||
callgraph issue? : if a sub contains another sub and it calls that, the outer sub is never removed even if it doesn't get called?
|
callgraph issue? : if a sub contains another sub and it calls that, the outer sub is never removed even if it doesn't get called?
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if fastserial
|
if fastserial
|
||||||
diskio.fastmode(3)
|
void diskio.fastmode(3)
|
||||||
else
|
else
|
||||||
diskio.fastmode(0)
|
void diskio.fastmode(0)
|
||||||
|
|
||||||
test_save()
|
test_save()
|
||||||
test_save_blocks()
|
test_save_blocks()
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const uword width = 60
|
const ubyte width = 60
|
||||||
const uword height = 50
|
const ubyte height = 50
|
||||||
const ubyte max_iter = 16
|
const ubyte max_iter = 16
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
; Note: this program can be compiled for multiple target systems.
|
; Note: this program can be compiled for multiple target systems.
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const uword width = 30
|
const ubyte width = 30
|
||||||
const uword height = 20
|
const ubyte height = 20
|
||||||
const ubyte max_iter = 16
|
const ubyte max_iter = 16
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
@ -1,61 +1,16 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import gfx_lores
|
|
||||||
%import emudbg
|
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const uword WIDTH = 320
|
|
||||||
const ubyte HEIGHT = 240
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
uword clo, chi
|
uword @shared large = (320*240/8/8)
|
||||||
|
const uword WIDTH=320
|
||||||
void cx16.set_screen_mode(128)
|
uword x1 = ((WIDTH-256)/2 as uword) + 200
|
||||||
|
txt.print_uw(x1)
|
||||||
word x1, y1, x2, y2
|
|
||||||
ubyte i
|
|
||||||
ubyte color = 2
|
|
||||||
|
|
||||||
sys.set_irqd()
|
|
||||||
emudbg.reset_cpu_cycles()
|
|
||||||
for i in 0 to 254 step 4 {
|
|
||||||
x1 = ((WIDTH-256)/2 as word) + math.sin8u(i) as word
|
|
||||||
y1 = (HEIGHT-128)/2 + math.cos8u(i)/2
|
|
||||||
x2 = ((WIDTH-64)/2 as word) + math.sin8u(i)/4 as word
|
|
||||||
y2 = (HEIGHT-64)/2 + math.cos8u(i)/4
|
|
||||||
cx16.GRAPH_set_colors(color, 0, 1)
|
|
||||||
cx16.GRAPH_draw_line(x1 as uword, y1 as uword, x2 as uword, y2 as uword)
|
|
||||||
}
|
|
||||||
clo, chi = emudbg.cpu_cycles()
|
|
||||||
sys.clear_irqd()
|
|
||||||
|
|
||||||
txt.print_uwhex(chi, true)
|
|
||||||
txt.print_uwhex(clo, false)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
x1 = ((WIDTH-256)/2) + 200
|
||||||
sys.wait(50)
|
txt.print_uw(x1)
|
||||||
cx16.GRAPH_clear()
|
|
||||||
sys.wait(50)
|
|
||||||
|
|
||||||
sys.set_irqd()
|
|
||||||
emudbg.reset_cpu_cycles()
|
|
||||||
color = 5
|
|
||||||
for i in 0 to 254 step 4 {
|
|
||||||
x1 = ((WIDTH-256)/2 as word) + math.sin8u(i) as word
|
|
||||||
y1 = (HEIGHT-128)/2 + math.cos8u(i)/2
|
|
||||||
x2 = ((WIDTH-64)/2 as word) + math.sin8u(i)/4 as word
|
|
||||||
y2 = (HEIGHT-64)/2 + math.cos8u(i)/4
|
|
||||||
gfx_lores.line(x1 as uword, y1 as ubyte, x2 as uword, y2 as ubyte, color)
|
|
||||||
}
|
|
||||||
clo, chi = emudbg.cpu_cycles()
|
|
||||||
sys.clear_irqd()
|
|
||||||
|
|
||||||
txt.print_uwhex(chi, true)
|
|
||||||
txt.print_uwhex(clo, false)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user