mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
Fix some FP related assignment issues in 6502 codegen.
This commit is contained in:
parent
f2273c0acc
commit
a82b2da16e
@ -27,13 +27,6 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
translateNormalAssignment(assign)
|
translateNormalAssignment(assign)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun virtualRegsToVariables(origtarget: AsmAssignTarget): AsmAssignTarget {
|
|
||||||
return if(origtarget.kind==TargetStorageKind.REGISTER && origtarget.register in Cx16VirtualRegisters) {
|
|
||||||
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, origtarget.datatype, origtarget.scope,
|
|
||||||
variableAsmName = "cx16.${origtarget.register!!.name.lowercase()}", origAstTarget = origtarget.origAstTarget)
|
|
||||||
} else origtarget
|
|
||||||
}
|
|
||||||
|
|
||||||
fun translateNormalAssignment(assign: AsmAssignment) {
|
fun translateNormalAssignment(assign: AsmAssignment) {
|
||||||
if(assign.isAugmentable) {
|
if(assign.isAugmentable) {
|
||||||
augmentableAsmGen.translate(assign)
|
augmentableAsmGen.translate(assign)
|
||||||
@ -940,11 +933,9 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
is NumericLiteral -> {
|
is NumericLiteral -> {
|
||||||
val address = (value.addressExpression as NumericLiteral).number.toUInt()
|
val address = (value.addressExpression as NumericLiteral).number.toUInt()
|
||||||
assignMemoryByteIntoWord(target, address, null)
|
assignMemoryByteIntoWord(target, address, null)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
assignMemoryByteIntoWord(target, null, value.addressExpression as IdentifierReference)
|
assignMemoryByteIntoWord(target, null, value.addressExpression as IdentifierReference)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
is BinaryExpression -> {
|
is BinaryExpression -> {
|
||||||
if(asmgen.tryOptimizedPointerAccessWithA(value.addressExpression as BinaryExpression, false)) {
|
if(asmgen.tryOptimizedPointerAccessWithA(value.addressExpression as BinaryExpression, false)) {
|
||||||
@ -958,6 +949,7 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
assignViaExprEval(value.addressExpression)
|
assignViaExprEval(value.addressExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is NumericLiteral -> throw AssemblyError("a cast of a literal value should have been const-folded away")
|
is NumericLiteral -> throw AssemblyError("a cast of a literal value should have been const-folded away")
|
||||||
@ -966,7 +958,7 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
|
|
||||||
|
|
||||||
// special case optimizations
|
// special case optimizations
|
||||||
if(target.kind== TargetStorageKind.VARIABLE) {
|
if(target.kind == TargetStorageKind.VARIABLE) {
|
||||||
if(value is IdentifierReference && valueDt != DataType.UNDEFINED)
|
if(value is IdentifierReference && valueDt != DataType.UNDEFINED)
|
||||||
return assignTypeCastedIdentifier(target.asmVarname, targetDt, asmgen.asmVariableName(value), valueDt)
|
return assignTypeCastedIdentifier(target.asmVarname, targetDt, asmgen.asmVariableName(value), valueDt)
|
||||||
|
|
||||||
@ -1044,11 +1036,12 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
assignExpressionToRegister(value, RegisterOrPair.FAC1, target.datatype in SignedDatatypes)
|
assignExpressionToRegister(value, RegisterOrPair.FAC1, target.datatype in SignedDatatypes)
|
||||||
assignTypeCastedFloatFAC1("P8ZP_SCRATCH_W1", target.datatype)
|
assignTypeCastedFloatFAC1("P8ZP_SCRATCH_W1", target.datatype)
|
||||||
assignVariableToRegister("P8ZP_SCRATCH_W1", target.register!!, target.datatype in SignedDatatypes)
|
assignVariableToRegister("P8ZP_SCRATCH_W1", target.register!!, target.datatype in SignedDatatypes)
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
if(!(valueDt isAssignableTo targetDt)) {
|
if(!(valueDt isAssignableTo targetDt)) {
|
||||||
if(valueDt in WordDatatypes && targetDt in ByteDatatypes) {
|
return if(valueDt in WordDatatypes && targetDt in ByteDatatypes) {
|
||||||
// word to byte, just take the lsb
|
// word to byte, just take the lsb
|
||||||
return assignCastViaLsbFunc(value, target)
|
assignCastViaLsbFunc(value, target)
|
||||||
} else if(valueDt in WordDatatypes && targetDt in WordDatatypes) {
|
} else if(valueDt in WordDatatypes && targetDt in WordDatatypes) {
|
||||||
// word to word, just assign
|
// word to word, just assign
|
||||||
assignExpressionToRegister(value, target.register!!, targetDt==DataType.BYTE || targetDt==DataType.WORD)
|
assignExpressionToRegister(value, target.register!!, targetDt==DataType.BYTE || targetDt==DataType.WORD)
|
||||||
@ -1058,43 +1051,85 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
} else if(valueDt in ByteDatatypes && targetDt in WordDatatypes) {
|
} else if(valueDt in ByteDatatypes && targetDt in WordDatatypes) {
|
||||||
// byte to word, just assign
|
// byte to word, just assign
|
||||||
assignExpressionToRegister(value, target.register!!, targetDt==DataType.WORD)
|
assignExpressionToRegister(value, target.register!!, targetDt==DataType.WORD)
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
throw AssemblyError("can't cast $valueDt to $targetDt, this should have been checked in the astchecker")
|
throw AssemblyError("can't cast $valueDt to $targetDt, this should have been checked in the astchecker")
|
||||||
}
|
}
|
||||||
assignExpressionToRegister(value, target.register!!, targetDt==DataType.BYTE || targetDt==DataType.WORD)
|
|
||||||
}
|
}
|
||||||
return
|
}
|
||||||
|
|
||||||
|
if(targetDt in IntegerDatatypes && valueDt in IntegerDatatypes && valueDt.isAssignableTo(targetDt)) {
|
||||||
|
require(targetDt in WordDatatypes && valueDt in ByteDatatypes) { "should be byte to word assignment ${origTypeCastExpression.position}"}
|
||||||
|
when(target.kind) {
|
||||||
|
// TargetStorageKind.VARIABLE -> {
|
||||||
|
// This has been handled already earlier on line 961.
|
||||||
|
// // byte to word, just assign to registers first, then assign to variable
|
||||||
|
// assignExpressionToRegister(value, RegisterOrPair.AY, targetDt==DataType.WORD)
|
||||||
|
// assignTypeCastedRegisters(target.asmVarname, targetDt, RegisterOrPair.AY, targetDt)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
TargetStorageKind.ARRAY -> {
|
||||||
|
// byte to word, just assign to registers first, then assign into array
|
||||||
|
assignExpressionToRegister(value, RegisterOrPair.AY, targetDt==DataType.WORD)
|
||||||
|
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
TargetStorageKind.REGISTER -> {
|
||||||
|
// byte to word, just assign to registers
|
||||||
|
assignExpressionToRegister(value, target.register!!, targetDt==DataType.WORD)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
TargetStorageKind.STACK -> {
|
||||||
|
// byte to word, just assign to registers first, then push onto stack
|
||||||
|
assignExpressionToRegister(value, RegisterOrPair.AY, targetDt==DataType.WORD)
|
||||||
|
asmgen.out("""
|
||||||
|
sta P8ESTACK_LO,x
|
||||||
|
tya
|
||||||
|
sta P8ESTACK_HI,x
|
||||||
|
dex""")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird target")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(targetDt==DataType.FLOAT && (target.register==RegisterOrPair.FAC1 || target.register==RegisterOrPair.FAC2)) {
|
if(targetDt==DataType.FLOAT && (target.register==RegisterOrPair.FAC1 || target.register==RegisterOrPair.FAC2)) {
|
||||||
when(valueDt) {
|
when(valueDt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
assignExpressionToRegister(value, RegisterOrPair.Y, false)
|
assignExpressionToRegister(value, RegisterOrPair.Y, false)
|
||||||
|
asmgen.saveRegisterLocal(CpuRegister.X, origTypeCastExpression.definingSubroutine!!)
|
||||||
asmgen.out(" jsr floats.FREADUY")
|
asmgen.out(" jsr floats.FREADUY")
|
||||||
|
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||||
}
|
}
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
assignExpressionToRegister(value, RegisterOrPair.A, true)
|
assignExpressionToRegister(value, RegisterOrPair.A, true)
|
||||||
|
asmgen.saveRegisterLocal(CpuRegister.X, origTypeCastExpression.definingSubroutine!!)
|
||||||
asmgen.out(" jsr floats.FREADSA")
|
asmgen.out(" jsr floats.FREADSA")
|
||||||
|
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
assignExpressionToRegister(value, RegisterOrPair.AY, false)
|
assignExpressionToRegister(value, RegisterOrPair.AY, false)
|
||||||
|
asmgen.saveRegisterLocal(CpuRegister.X, origTypeCastExpression.definingSubroutine!!)
|
||||||
asmgen.out(" jsr floats.GIVUAYFAY")
|
asmgen.out(" jsr floats.GIVUAYFAY")
|
||||||
|
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||||
}
|
}
|
||||||
DataType.WORD -> {
|
DataType.WORD -> {
|
||||||
assignExpressionToRegister(value, RegisterOrPair.AY, true)
|
assignExpressionToRegister(value, RegisterOrPair.AY, true)
|
||||||
|
asmgen.saveRegisterLocal(CpuRegister.X, origTypeCastExpression.definingSubroutine!!)
|
||||||
asmgen.out(" jsr floats.GIVAYFAY")
|
asmgen.out(" jsr floats.GIVAYFAY")
|
||||||
|
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid dt")
|
else -> throw AssemblyError("invalid dt")
|
||||||
}
|
}
|
||||||
if(target.register==RegisterOrPair.FAC2) {
|
if(target.register==RegisterOrPair.FAC2) {
|
||||||
asmgen.out(" jsr floats.MOVEF")
|
asmgen.out(" jsr floats.MOVEF")
|
||||||
}
|
}
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
// No more special optmized cases yet. Do the rest via more complex evaluation
|
// No more special optmized cases yet. Do the rest via more complex evaluation
|
||||||
// note: cannot use assignTypeCastedValue because that is ourselves :P
|
// note: cannot use assignTypeCastedValue because that is ourselves :P
|
||||||
// NOTE: THIS MAY TURN INTO A STACK OVERFLOW ERROR IF IT CAN'T SIMPLIFY THE TYPECAST..... :-/
|
// NOTE: THIS MAY TURN INTO A STACK OVERFLOW ERROR IF IT CAN'T SIMPLIFY THE TYPECAST..... :-/
|
||||||
asmgen.assignExpressionTo(origTypeCastExpression, target)
|
asmgen.assignExpressionTo(origTypeCastExpression, target)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1251,14 +1286,10 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
asmgen.out(
|
asmgen.out(
|
||||||
" st${
|
" st${regs.toString().lowercase()} $targetAsmVarName | stz $targetAsmVarName+1")
|
||||||
regs.toString().lowercase()
|
|
||||||
} $targetAsmVarName | stz $targetAsmVarName+1")
|
|
||||||
else
|
else
|
||||||
asmgen.out(
|
asmgen.out(
|
||||||
" st${
|
" st${regs.toString().lowercase()} $targetAsmVarName | lda #0 | sta $targetAsmVarName+1")
|
||||||
regs.toString().lowercase()
|
|
||||||
} $targetAsmVarName | lda #0 | sta $targetAsmVarName+1")
|
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
when(regs) {
|
when(regs) {
|
||||||
|
@ -44,7 +44,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
val keepIR by cli.option(ArgType.Boolean, fullName = "keepIR", description = "keep the IR code file (for targets that use it)")
|
val keepIR by cli.option(ArgType.Boolean, fullName = "keepIR", description = "keep the IR code file (for targets that use it)")
|
||||||
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
||||||
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform any optimizations")
|
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform any optimizations")
|
||||||
val dontReinitGlobals by cli.option(ArgType.Boolean, fullName = "noreinit", description = "don't create code to reinitialize globals on multiple runs of the program (experimental!)")
|
val dontReinitGlobals by cli.option(ArgType.Boolean, fullName = "noreinit", description = "don't create code to reinitialize globals on multiple runs of the program (experimental)")
|
||||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||||
val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)")
|
val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)")
|
||||||
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
||||||
|
@ -14,6 +14,7 @@ import prog8.ast.statements.VarDecl
|
|||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.Position
|
import prog8.code.core.Position
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
|
import prog8.code.target.VMTarget
|
||||||
import prog8tests.helpers.ErrorReporterForTests
|
import prog8tests.helpers.ErrorReporterForTests
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
|
|
||||||
@ -934,4 +935,34 @@ main {
|
|||||||
}"""
|
}"""
|
||||||
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("various floating point casts don't crash the compiler") {
|
||||||
|
val text="""
|
||||||
|
%import floats
|
||||||
|
|
||||||
|
main {
|
||||||
|
sub score() -> ubyte {
|
||||||
|
cx16.r15++
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
float @shared total = 0
|
||||||
|
ubyte bb = 5
|
||||||
|
|
||||||
|
cx16.r0 = 5
|
||||||
|
total += cx16.r0 as float
|
||||||
|
total += score() as float
|
||||||
|
uword ww = 5
|
||||||
|
total += ww as float
|
||||||
|
total += bb as float
|
||||||
|
float result = score() as float
|
||||||
|
total += result
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
||||||
|
compileText(C64Target(), true, text, writeAssembly = true) shouldNotBe null
|
||||||
|
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
|
||||||
|
compileText(VMTarget(), true, text, writeAssembly = true) shouldNotBe null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@ -140,8 +140,8 @@ One or more .p8 module files
|
|||||||
Don't create code to reinitialize the global (block level) variables on every run of the program.
|
Don't create code to reinitialize the global (block level) variables on every run of the program.
|
||||||
Also means that all such variables are no longer placed in the zeropage.
|
Also means that all such variables are no longer placed in the zeropage.
|
||||||
Sometimes the program will be a lot shorter when using this, but sometimes the opposite happens.
|
Sometimes the program will be a lot shorter when using this, but sometimes the opposite happens.
|
||||||
When using this option, it is no longer be possible to run the program correctly more than once!
|
When using this option, it may no longer be possible to run the program correctly more than once!
|
||||||
*Experimental feature*: still has some problems!
|
*Experimental feature*: this feature has not been tested much yet.
|
||||||
|
|
||||||
``-optfloatx``
|
``-optfloatx``
|
||||||
Also optimize float expressions if optimizations are enabled.
|
Also optimize float expressions if optimizations are enabled.
|
||||||
|
@ -3,6 +3,8 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
- fix compiler crash when compiling %import test_stack on virtual target.
|
||||||
|
- bss in IR: with -noreinit, variables that have init value 0 should still be bss.
|
||||||
- 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with bss=true.
|
- 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with bss=true.
|
||||||
Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE if possible.
|
Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE if possible.
|
||||||
Note that bss can still contain variables that have @zp tag and those are already dealt with differently
|
Note that bss can still contain variables that have @zp tag and those are already dealt with differently
|
||||||
|
117
examples/test.p8
117
examples/test.p8
@ -1,54 +1,79 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%import floats
|
||||||
%option no_sysinit
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
sub score() -> ubyte {
|
||||||
|
cx16.r15++
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
; TODO ALSO TEST AS GLOBALS
|
float @shared total = 0
|
||||||
ubyte @requirezp zpvar = 10
|
ubyte bb = 5
|
||||||
ubyte @zp zpvar2 = 20
|
|
||||||
uword empty
|
|
||||||
ubyte[10] bssarray
|
|
||||||
uword[10] bsswordarray
|
|
||||||
ubyte[10] nonbssarray = 99
|
|
||||||
str name="irmen"
|
|
||||||
|
|
||||||
txt.print("10 ")
|
cx16.r0 = 5
|
||||||
txt.print_ub(zpvar)
|
total += cx16.r0 as float
|
||||||
txt.nl()
|
total += score() as float
|
||||||
zpvar++
|
uword ww = 5
|
||||||
|
total += ww as float
|
||||||
txt.print("20 ")
|
total += bb as float
|
||||||
txt.print_ub(zpvar2)
|
float result = score() as float
|
||||||
txt.nl()
|
total += result
|
||||||
zpvar2++
|
|
||||||
|
|
||||||
txt.print("0 ")
|
|
||||||
txt.print_uw(empty)
|
|
||||||
txt.nl()
|
|
||||||
empty++
|
|
||||||
|
|
||||||
txt.print("0 ")
|
|
||||||
txt.print_ub(bssarray[1])
|
|
||||||
txt.nl()
|
|
||||||
bssarray[1]++
|
|
||||||
|
|
||||||
txt.print("0 ")
|
|
||||||
txt.print_uw(bsswordarray[1])
|
|
||||||
txt.nl()
|
|
||||||
bsswordarray[1]++
|
|
||||||
|
|
||||||
txt.print("99 ")
|
|
||||||
txt.print_ub(nonbssarray[1])
|
|
||||||
txt.nl()
|
|
||||||
nonbssarray[1]++
|
|
||||||
|
|
||||||
txt.print("r ")
|
|
||||||
txt.chrout(name[1])
|
|
||||||
txt.nl()
|
|
||||||
name[1] = (name[1] as ubyte +1)
|
|
||||||
|
|
||||||
txt.print("try running again.\n")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
;%import textio
|
||||||
|
;%zeropage basicsafe
|
||||||
|
;%option no_sysinit
|
||||||
|
;
|
||||||
|
;main {
|
||||||
|
;
|
||||||
|
; sub start() {
|
||||||
|
; ; TODO ALSO TEST AS GLOBALS
|
||||||
|
; ubyte @requirezp zpvar = 10
|
||||||
|
; ubyte @zp zpvar2 = 20
|
||||||
|
; uword empty
|
||||||
|
; ubyte[10] bssarray
|
||||||
|
; uword[10] bsswordarray
|
||||||
|
; ubyte[10] nonbssarray = 99
|
||||||
|
; str name="irmen"
|
||||||
|
;
|
||||||
|
; txt.print("10 ")
|
||||||
|
; txt.print_ub(zpvar)
|
||||||
|
; txt.nl()
|
||||||
|
; zpvar++
|
||||||
|
;
|
||||||
|
; txt.print("20 ")
|
||||||
|
; txt.print_ub(zpvar2)
|
||||||
|
; txt.nl()
|
||||||
|
; zpvar2++
|
||||||
|
;
|
||||||
|
; txt.print("0 ")
|
||||||
|
; txt.print_uw(empty)
|
||||||
|
; txt.nl()
|
||||||
|
; empty++
|
||||||
|
;
|
||||||
|
; txt.print("0 ")
|
||||||
|
; txt.print_ub(bssarray[1])
|
||||||
|
; txt.nl()
|
||||||
|
; bssarray[1]++
|
||||||
|
;
|
||||||
|
; txt.print("0 ")
|
||||||
|
; txt.print_uw(bsswordarray[1])
|
||||||
|
; txt.nl()
|
||||||
|
; bsswordarray[1]++
|
||||||
|
;
|
||||||
|
; txt.print("99 ")
|
||||||
|
; txt.print_ub(nonbssarray[1])
|
||||||
|
; txt.nl()
|
||||||
|
; nonbssarray[1]++
|
||||||
|
;
|
||||||
|
; txt.print("r ")
|
||||||
|
; txt.chrout(name[1])
|
||||||
|
; txt.nl()
|
||||||
|
; name[1] = (name[1] as ubyte +1)
|
||||||
|
;
|
||||||
|
; txt.print("try running again.\n")
|
||||||
|
; }
|
||||||
|
;}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user