mirror of
https://github.com/irmen/prog8.git
synced 2026-04-26 20:17:57 +00:00
sys.push(), sys.pop() etc etc are now builtin functions again push() pop() to avoid storing value in temporary variables
this means that all of the syslib.p8 library files no longer contain all those stack related asmsubs
This commit is contained in:
1 parent
9aff85f08a
commit
093be9f2dd
55 files changed
+502
-1256
No files matched your search
@@ -113,14 +113,14 @@ btree {
|
||||
sub count_node(^^Node r) {
|
||||
count++
|
||||
if r.left!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
count_node(r.left)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
if r.right!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
count_node(r.right)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,15 +179,15 @@ btree {
|
||||
|
||||
sub process_tree(^^Node r) {
|
||||
if r.left!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
process_tree(r.left)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
cx16.r0 = r.value
|
||||
if r.right!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
process_tree(r.right)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,18 +200,18 @@ btree {
|
||||
sub process_tree(^^Node r, ubyte depth) {
|
||||
cx16.r0 = r.value
|
||||
if r.left!=0 {
|
||||
sys.pushw(r)
|
||||
sys.push(depth)
|
||||
pushw(r)
|
||||
push(depth)
|
||||
process_tree(r.left, depth+1)
|
||||
depth = sys.pop()
|
||||
r = sys.popw()
|
||||
depth = pop()
|
||||
r = popw()
|
||||
}
|
||||
if r.right!=0 {
|
||||
sys.pushw(r)
|
||||
sys.push(depth)
|
||||
pushw(r)
|
||||
push(depth)
|
||||
process_tree(r.right, depth+1)
|
||||
depth = sys.pop()
|
||||
r = sys.popw()
|
||||
depth = pop()
|
||||
r = popw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,12 @@ queens {
|
||||
if could_place(row, col) {
|
||||
board[row] = col
|
||||
; we need to save the local variables row and col.
|
||||
sys.push(row)
|
||||
sys.push(col)
|
||||
push(row)
|
||||
push(col)
|
||||
continue_running = place_queen(row + 1)
|
||||
; restore the local variables after the recursive call.
|
||||
col = sys.pop()
|
||||
row = sys.pop()
|
||||
col = pop()
|
||||
row = pop()
|
||||
board[row] = 0
|
||||
|
||||
if not continue_running
|
||||
|
||||
@@ -164,6 +164,14 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
|
||||
"callfar" to FSignature(false, BaseDataType.UWORD, FParam("bank", BaseDataType.UBYTE), FParam("address", BaseDataType.UWORD), FParam("arg", BaseDataType.UWORD)),
|
||||
"callfar2" to FSignature(false, BaseDataType.UWORD, FParam("bank", BaseDataType.UBYTE), FParam("address", BaseDataType.UWORD), FParam("argA", BaseDataType.UBYTE), FParam("argX", BaseDataType.UBYTE), FParam("argY", BaseDataType.UBYTE), FParam("argC", BaseDataType.BOOL)),
|
||||
"call" to FSignature(false, BaseDataType.UWORD, FParam("address", BaseDataType.UWORD)),
|
||||
"push" to FSignature(false, null, FParam("value", BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.BOOL)),
|
||||
"pushw" to FSignature(false, null, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.POINTER)),
|
||||
"pushl" to FSignature(false, null, FParam("value", BaseDataType.LONG)),
|
||||
"pushf" to FSignature(false, null, FParam("value", BaseDataType.FLOAT)),
|
||||
"pop" to FSignature(false, BaseDataType.UBYTE),
|
||||
"popw" to FSignature(false, BaseDataType.UWORD),
|
||||
"popl" to FSignature(false, BaseDataType.LONG),
|
||||
"popf" to FSignature(false, BaseDataType.FLOAT),
|
||||
)
|
||||
|
||||
val InplaceModifyingBuiltinFunctions = setOf(
|
||||
|
||||
@@ -68,6 +68,14 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
"callfar" -> funcCallFar(fcall, resultRegister)
|
||||
"callfar2" -> funcCallFar2(fcall, resultRegister)
|
||||
"call" -> funcCall(fcall)
|
||||
"push" -> funcPush(fcall)
|
||||
"pushw" -> funcPushW(fcall)
|
||||
"pushl" -> funcPushL(fcall)
|
||||
"pushf" -> funcPushF(fcall)
|
||||
"pop" -> funcPop()
|
||||
"popw" -> funcPopW()
|
||||
"popl" -> funcPopL()
|
||||
"popf" -> funcPopF()
|
||||
"prog8_lib_structalloc" -> funcStructAlloc(fcall, discardResult, resultRegister)
|
||||
"prog8_lib_stringcompare" -> funcStringCompare(fcall, resultRegister)
|
||||
"prog8_lib_square_byte" -> funcSquare(fcall, BaseDataType.UBYTE, resultRegister)
|
||||
@@ -80,6 +88,91 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
return BuiltinFunctions.getValue(fcall.name).returnType
|
||||
}
|
||||
|
||||
private fun funcPush(fcall: PtBuiltinFunctionCall) {
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A)
|
||||
asmgen.out(" pha")
|
||||
}
|
||||
|
||||
private fun funcPushW(fcall: PtBuiltinFunctionCall) {
|
||||
val value = fcall.args.single()
|
||||
if(value is PtIdentifier) {
|
||||
val varname = asmgen.asmVariableName(value)
|
||||
asmgen.out("""
|
||||
lda $varname
|
||||
pha
|
||||
lda $varname+1
|
||||
pha""")
|
||||
} else {
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65C02)) {
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||
asmgen.out(" pha | phy")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||
asmgen.out(" pha | tya | pha")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcPushL(fcall: PtBuiltinFunctionCall) {
|
||||
val value = fcall.args.single()
|
||||
if(value is PtIdentifier) {
|
||||
val varname = asmgen.asmVariableName(value)
|
||||
asmgen.out("""
|
||||
lda $varname
|
||||
pha
|
||||
lda $varname+1
|
||||
pha
|
||||
lda $varname+2
|
||||
pha
|
||||
lda $varname+3
|
||||
pha""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R14R15, true)
|
||||
asmgen.out("""
|
||||
lda cx16.r14
|
||||
pha
|
||||
lda cx16.r14+1
|
||||
pha
|
||||
lda cx16.r14+2
|
||||
pha
|
||||
lda cx16.r14+3
|
||||
pha""")
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcPushF(fcall: PtBuiltinFunctionCall) {
|
||||
asmgen.assignExpressionToRegister(fcall.args.single(), RegisterOrPair.FAC1, true)
|
||||
asmgen.out(" jsr floats.pushFAC1")
|
||||
}
|
||||
|
||||
private fun funcPop() {
|
||||
asmgen.out(" pla")
|
||||
}
|
||||
|
||||
private fun funcPopW() {
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65C02)) {
|
||||
asmgen.out(" ply | pla")
|
||||
} else {
|
||||
asmgen.out(" pla | tay | pla")
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcPopL() {
|
||||
asmgen.out("""
|
||||
pla
|
||||
sta cx16.r14+3
|
||||
pla
|
||||
sta cx16.r14+2
|
||||
pla
|
||||
sta cx16.r14+1
|
||||
pla
|
||||
sta cx16.r14""")
|
||||
}
|
||||
|
||||
private fun funcPopF() {
|
||||
asmgen.out(" clc | jsr floats.popFAC")
|
||||
}
|
||||
|
||||
private fun funcCopyFromPointer1ToPointer2(fcall: PtBuiltinFunctionCall, type: BaseDataType) {
|
||||
if(fcall.args[1].isSimple()) {
|
||||
asmgen.assignExpressionToVariable(fcall.args[0], asmgen.asmVariableName("P8ZP_SCRATCH_W1"), DataType.UWORD)
|
||||
|
||||
@@ -60,12 +60,80 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
"prog8_lib_structalloc" -> funcStructAlloc(call)
|
||||
"prog8_lib_copylong" -> funcCopyFromPointer1ToPointer2(call, IRDataType.LONG)
|
||||
"prog8_lib_copyfloat" -> funcCopyFromPointer1ToPointer2(call, IRDataType.FLOAT)
|
||||
"push" -> funcPush(call)
|
||||
"pushw" -> funcPushW(call)
|
||||
"pushl" -> funcPushL(call)
|
||||
"pushf" -> funcPushF(call)
|
||||
"pop" -> funcPop()
|
||||
"popw" -> funcPopW()
|
||||
"popl" -> funcPopL()
|
||||
"popf" -> funcPopF()
|
||||
"sizeof" -> throw AssemblyError("sizeof must have been replaced with a constant")
|
||||
"offsetof" -> throw AssemblyError("offsetof must have been replaced with a constant")
|
||||
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcPush(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=tr.resultReg), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPushW(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1=tr.resultReg), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPushL(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.PUSH, IRDataType.LONG, reg1=tr.resultReg), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPushF(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, -1, tr.resultFpReg)
|
||||
addInstr(result, IRInstruction(Opcode.PUSH, IRDataType.FLOAT, fpReg1 = tr.resultFpReg), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPop(): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.next(IRDataType.BYTE)
|
||||
addInstr(result, IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=resultRegister), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
|
||||
private fun funcPopW(): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.next(IRDataType.WORD)
|
||||
addInstr(result, IRInstruction(Opcode.POP, IRDataType.WORD, reg1=resultRegister), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
|
||||
private fun funcPopL(): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.next(IRDataType.LONG)
|
||||
addInstr(result, IRInstruction(Opcode.POP, IRDataType.LONG, reg1=resultRegister), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
|
||||
private fun funcPopF(): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(result, IRInstruction(Opcode.POP, IRDataType.FLOAT, fpReg1 = resultRegister), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, resultRegister)
|
||||
}
|
||||
|
||||
private fun funcCopyFromPointer1ToPointer2(call: PtBuiltinFunctionCall, type: IRDataType): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val trSourceAddr = exprGen.translateExpression(call.args[0])
|
||||
|
||||
@@ -882,10 +882,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
internal fun translate(fcall: PtFunctionCall): ExpressionCodeResult {
|
||||
val callTarget = codeGen.symbolTable.lookup(fcall.name)!!
|
||||
|
||||
if(callTarget.scopedNameString in listOf("sys.push", "sys.pushw", "sys.pop", "sys.popw", "floats.push", "floats.pop")) {
|
||||
// special case, these should be inlined, or even use specialized instructions. Instead of doing a normal subroutine call.
|
||||
return translateStackFunctions(fcall, callTarget)
|
||||
}
|
||||
when(callTarget.scopedNameString) {
|
||||
"sys.clear_carry" -> {
|
||||
val chunk = mutableListOf<IRCodeChunkBase>()
|
||||
@@ -1109,52 +1105,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun translateStackFunctions(fcall: PtFunctionCall, callTarget: StNode): ExpressionCodeResult {
|
||||
val chunk = mutableListOf<IRCodeChunkBase>()
|
||||
when(callTarget.scopedNameString) {
|
||||
"sys.push" -> {
|
||||
// push byte
|
||||
val tr = translateExpression(fcall.args.single())
|
||||
chunk += tr.chunks
|
||||
addInstr(chunk, IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=tr.resultReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"sys.pushw" -> {
|
||||
// push word
|
||||
val tr = translateExpression(fcall.args.single())
|
||||
chunk += tr.chunks
|
||||
addInstr(chunk, IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1=tr.resultReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.WORD, -1, -1)
|
||||
}
|
||||
"sys.pop" -> {
|
||||
// pop byte
|
||||
val popReg = codeGen.registers.next(IRDataType.BYTE)
|
||||
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=popReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.BYTE, popReg, -1)
|
||||
}
|
||||
"sys.popw" -> {
|
||||
// pop word
|
||||
val popReg = codeGen.registers.next(IRDataType.WORD)
|
||||
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.WORD, reg1=popReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.WORD, popReg, -1)
|
||||
}
|
||||
"floats.push" -> {
|
||||
// push float
|
||||
val tr = translateExpression(fcall.args.single())
|
||||
chunk += tr.chunks
|
||||
addInstr(chunk, IRInstruction(Opcode.PUSH, IRDataType.FLOAT, fpReg1 = tr.resultFpReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.FLOAT, -1, -1)
|
||||
}
|
||||
"floats.pop" -> {
|
||||
// pop float
|
||||
val popReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.FLOAT, fpReg1 = popReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.FLOAT, -1, resultFpReg = popReg)
|
||||
}
|
||||
else -> throw AssemblyError("unknown stack subroutine called")
|
||||
}
|
||||
}
|
||||
|
||||
private fun callExtSubWithMultipleReturnValues(
|
||||
callTarget: StExtSub,
|
||||
fcall: PtFunctionCall,
|
||||
|
||||
@@ -25,25 +25,8 @@ class UnusedCodeRemover(private val program: Program,
|
||||
init {
|
||||
neverRemoveSubroutines.add(program.entrypoint)
|
||||
|
||||
program.allBlocks.singleOrNull { it.name=="sys" } ?.let {
|
||||
val subroutines = it.statements.filterIsInstance<Subroutine>()
|
||||
val push = subroutines.single { s -> s.name == "push" }
|
||||
val pushw = subroutines.single { s -> s.name == "pushw" }
|
||||
val pop = subroutines.single { s -> s.name == "pop" }
|
||||
val popw = subroutines.single { s -> s.name == "popw" }
|
||||
neverRemoveSubroutines.add(push)
|
||||
neverRemoveSubroutines.add(pushw)
|
||||
neverRemoveSubroutines.add(pop)
|
||||
neverRemoveSubroutines.add(popw)
|
||||
}
|
||||
|
||||
program.allBlocks.singleOrNull { it.name=="floats" } ?.let {
|
||||
val subroutines = it.statements.filterIsInstance<Subroutine>()
|
||||
val push = subroutines.single { s -> s.name == "push" }
|
||||
val pop = subroutines.single { s -> s.name == "pop" }
|
||||
neverRemoveSubroutines.add(push)
|
||||
neverRemoveSubroutines.add(pop)
|
||||
|
||||
subroutines
|
||||
.filter { s -> s.name == "internal_long_R1_to_float_AY" || s.name=="internal_long_AY_to_FAC" }
|
||||
.forEach { sub -> neverRemoveSubroutines.add(sub) }
|
||||
|
||||
@@ -74,7 +74,7 @@ smallringbuffer {
|
||||
smallstack {
|
||||
; -- A small stack (LIFO) that uses just 256 bytes and is independent of the CPU stack. Stack is growing downward from the top of the buffer.
|
||||
; You can store and retrieve bytes and words. There are no guards against stack over/underflow.
|
||||
; note: for a "small stack" (256 bytes size) you might also perhaps just use the CPU stack via sys.push[w] / sys.pop[w].
|
||||
; note: for a "small stack" (256 bytes size) you might also perhaps just use the CPU stack via push[w] / pop[w].
|
||||
|
||||
ubyte[256] buffer
|
||||
ubyte sp = 255
|
||||
@@ -99,13 +99,13 @@ smallstack {
|
||||
return sp==255
|
||||
}
|
||||
|
||||
sub push(ubyte value) {
|
||||
sub push_b(ubyte value) {
|
||||
; -- put a byte on the stack
|
||||
buffer[sp] = value
|
||||
sp--
|
||||
}
|
||||
|
||||
sub pushw(uword value) {
|
||||
sub push_w(uword value) {
|
||||
; -- put a word on the stack (lsb first then msb)
|
||||
buffer[sp] = lsb(value)
|
||||
sp--
|
||||
@@ -113,13 +113,13 @@ smallstack {
|
||||
sp--
|
||||
}
|
||||
|
||||
sub pop() -> ubyte {
|
||||
sub pop_b() -> ubyte {
|
||||
; -- pops a byte off the stack
|
||||
sp++
|
||||
return buffer[sp]
|
||||
}
|
||||
|
||||
sub popw() -> uword {
|
||||
sub pop_w() -> uword {
|
||||
; -- pops a word off the stack.
|
||||
sp++
|
||||
cx16.r0H = buffer[sp]
|
||||
@@ -157,13 +157,13 @@ stack {
|
||||
return sp==8191
|
||||
}
|
||||
|
||||
sub push(ubyte value) {
|
||||
sub push_b(ubyte value) {
|
||||
; -- put a byte on the stack
|
||||
buffer_ptr[sp] = value
|
||||
sp--
|
||||
}
|
||||
|
||||
sub pushw(uword value) {
|
||||
sub push_w(uword value) {
|
||||
; -- put a word on the stack (lsb first then msb)
|
||||
buffer_ptr[sp] = lsb(value)
|
||||
sp--
|
||||
@@ -171,13 +171,13 @@ stack {
|
||||
sp--
|
||||
}
|
||||
|
||||
sub pop() -> ubyte {
|
||||
sub pop_b() -> ubyte {
|
||||
; -- pops a byte off the stack
|
||||
sp++
|
||||
return buffer_ptr[sp]
|
||||
}
|
||||
|
||||
sub popw() -> uword {
|
||||
sub pop_w() -> uword {
|
||||
; -- pops a word off the stack.
|
||||
sp++
|
||||
cx16.r0H = buffer_ptr[sp]
|
||||
|
||||
@@ -817,20 +817,6 @@ _larger
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -857,46 +843,6 @@ _larger
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
; The SuperCPU expansion for the C64/C128 contains a 65816.
|
||||
|
||||
@@ -795,20 +795,6 @@ _larger
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -835,46 +821,6 @@ _larger
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
; The SuperCPU expansion for the C64/C128 contains a 65816.
|
||||
|
||||
@@ -83,7 +83,7 @@ coroutines {
|
||||
; activate the termination handler and start the first task
|
||||
; note: cannot use pushw() because JSR doesn't push the return address in the same way
|
||||
sys.push_returnaddress(&termination)
|
||||
sys.pushw(tasklist[active_task])
|
||||
pushw(tasklist[active_task])
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -94,11 +94,11 @@ coroutines {
|
||||
; Returns the associated userdata value.
|
||||
; NOTE: CAN ONLY BE CALLED FROM THE SCOPE OF THE SUBROUTINE THAT HAS BEEN REGISTERED AS THE TASK!
|
||||
uword task_return_address
|
||||
tasklist[active_task] = sys.popw()
|
||||
tasklist[active_task] = popw()
|
||||
|
||||
skip_task:
|
||||
if not next_task() {
|
||||
void sys.popw() ; remove return to the termination handler
|
||||
void popw() ; remove return to the termination handler
|
||||
return 0 ; exiting here will now actually return back to the calling program that called run()
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ skip_task:
|
||||
goto skip_task
|
||||
|
||||
; returning from yield then continues with the next coroutine:
|
||||
sys.pushw(task_return_address)
|
||||
pushw(task_return_address)
|
||||
return userdatas[active_task]
|
||||
|
||||
sub next_task() -> bool {
|
||||
|
||||
@@ -72,7 +72,7 @@ smallringbuffer {
|
||||
smallstack {
|
||||
; -- A small stack (LIFO) that uses just 256 bytes and is independent of the CPU stack. Stack is growing downward from the top of the buffer.
|
||||
; You can store and retrieve bytes and words. There are no guards against stack over/underflow.
|
||||
; note: for a "small stack" (256 bytes size) you might also perhaps just use the CPU stack via sys.push[w] / sys.pop[w].
|
||||
; note: for a "small stack" (256 bytes size) you might also perhaps just use the CPU stack via push[w] / pop[w].
|
||||
|
||||
ubyte[256] buffer
|
||||
ubyte sp = 255
|
||||
@@ -97,13 +97,13 @@ smallstack {
|
||||
return sp==255
|
||||
}
|
||||
|
||||
sub push(ubyte value) {
|
||||
sub push_b(ubyte value) {
|
||||
; -- put a byte on the stack
|
||||
buffer[sp] = value
|
||||
sp--
|
||||
}
|
||||
|
||||
sub pushw(uword value) {
|
||||
sub push_w(uword value) {
|
||||
; -- put a word on the stack (lsb first then msb)
|
||||
buffer[sp] = lsb(value)
|
||||
sp--
|
||||
@@ -111,13 +111,13 @@ smallstack {
|
||||
sp--
|
||||
}
|
||||
|
||||
sub pop() -> ubyte {
|
||||
sub pop_b() -> ubyte {
|
||||
; -- pops a byte off the stack
|
||||
sp++
|
||||
return buffer[sp]
|
||||
}
|
||||
|
||||
sub popw() -> uword {
|
||||
sub pop_w() -> uword {
|
||||
; -- pops a word off the stack.
|
||||
sp++
|
||||
cx16.r0H = buffer[sp]
|
||||
@@ -157,20 +157,20 @@ stack {
|
||||
return sp==$bfff
|
||||
}
|
||||
|
||||
sub push(ubyte value) {
|
||||
sub push_b(ubyte value) {
|
||||
; -- put a byte on the stack
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
@(sp) = value
|
||||
sp--
|
||||
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
}
|
||||
|
||||
sub pushw(uword value) {
|
||||
sub push_w(uword value) {
|
||||
; -- put a word on the stack (lsb first then msb)
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
@(sp) = lsb(value)
|
||||
@@ -178,30 +178,30 @@ stack {
|
||||
@(sp) = msb(value)
|
||||
sp--
|
||||
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
}
|
||||
|
||||
sub pop() -> ubyte {
|
||||
sub pop_b() -> ubyte {
|
||||
; -- pops a byte off the stack
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
sp++
|
||||
cx16.r0L = @(sp)
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
return cx16.r0L
|
||||
}
|
||||
|
||||
sub popw() -> uword {
|
||||
sub pop_w() -> uword {
|
||||
; -- pops a word off the stack.
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
sp++
|
||||
cx16.r0H = @(sp)
|
||||
sp++
|
||||
cx16.r0L = @(sp)
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
return cx16.r0
|
||||
}
|
||||
}
|
||||
@@ -240,42 +240,42 @@ ringbuffer {
|
||||
|
||||
sub put(ubyte value) {
|
||||
; -- store a byte in the buffer
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
@(head) = value
|
||||
fill++
|
||||
inc_head()
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
}
|
||||
|
||||
sub putw(uword value) {
|
||||
; -- store a word in the buffer
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
pokew(head, value)
|
||||
fill += 2
|
||||
inc_head()
|
||||
inc_head()
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
}
|
||||
|
||||
sub get() -> ubyte {
|
||||
; -- retrieves a byte from the buffer
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
fill--
|
||||
inc_tail()
|
||||
cx16.r0L= @(tail)
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
return cx16.r0L
|
||||
}
|
||||
|
||||
sub getw() -> uword {
|
||||
; -- retrieves a word from the buffer
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.rambank(bank)
|
||||
|
||||
fill -= 2
|
||||
@@ -283,7 +283,7 @@ ringbuffer {
|
||||
cx16.r0L = @(tail)
|
||||
inc_tail()
|
||||
cx16.r0H = @(tail)
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
return cx16.r0
|
||||
}
|
||||
|
||||
|
||||
@@ -717,16 +717,14 @@ io_error:
|
||||
goto io_error
|
||||
void cbm.CHKIN(15) ; use #15 as input channel
|
||||
|
||||
cx16.r0L = (cbm.CHRIN()-'0') * 10
|
||||
cx16.r0L += (cbm.CHRIN()-'0')
|
||||
|
||||
push( (cbm.CHRIN()-'0') *10 + (cbm.CHRIN()-'0') )
|
||||
while cbm.READST()==0 {
|
||||
void cbm.CHRIN()
|
||||
}
|
||||
|
||||
cbm.CLRCHN() ; restore default i/o devices
|
||||
cbm.CLOSE(15)
|
||||
return cx16.r0L
|
||||
return pop()
|
||||
|
||||
io_error:
|
||||
cbm.CLRCHN()
|
||||
|
||||
@@ -567,17 +567,17 @@ gfx_hires {
|
||||
sub push_stack(word sxl, word sxr, word sy, byte sdy) {
|
||||
cx16.r0s = sy+sdy
|
||||
if cx16.r0s>=0 and cx16.r0s<=HEIGHT-1 {
|
||||
stack.pushw(sxl as uword)
|
||||
stack.pushw(sxr as uword)
|
||||
stack.pushw(sy as uword)
|
||||
stack.push(sdy as ubyte)
|
||||
stack.push_w(sxl as uword)
|
||||
stack.push_w(sxr as uword)
|
||||
stack.push_w(sy as uword)
|
||||
stack.push_b(sdy as ubyte)
|
||||
}
|
||||
}
|
||||
sub pop_stack() {
|
||||
dy = stack.pop() as byte
|
||||
yy = stack.popw() as word
|
||||
x2 = stack.popw() as word
|
||||
x1 = stack.popw() as word
|
||||
dy = stack.pop_b() as byte
|
||||
yy = stack.pop_w() as word
|
||||
x2 = stack.pop_w() as word
|
||||
x1 = stack.pop_w() as word
|
||||
yy+=dy
|
||||
}
|
||||
cx16.r11L = pget(xx as uword, yy as uword) ; old_color
|
||||
|
||||
@@ -620,17 +620,17 @@ gfx_lores {
|
||||
sub push_stack(word sxl, word sxr, word sy, byte sdy) {
|
||||
cx16.r0s = sy+sdy
|
||||
if cx16.r0s>=0 and cx16.r0s<=HEIGHT-1 {
|
||||
stack.pushw(sxl as uword)
|
||||
stack.pushw(sxr as uword)
|
||||
stack.pushw(sy as uword)
|
||||
stack.push(sdy as ubyte)
|
||||
stack.push_w(sxl as uword)
|
||||
stack.push_w(sxr as uword)
|
||||
stack.push_w(sy as uword)
|
||||
stack.push_b(sdy as ubyte)
|
||||
}
|
||||
}
|
||||
sub pop_stack() {
|
||||
dy = stack.pop() as byte
|
||||
yy = stack.popw() as word
|
||||
x2 = stack.popw() as word
|
||||
x1 = stack.popw() as word
|
||||
dy = stack.pop_b() as byte
|
||||
yy = stack.pop_w() as word
|
||||
x2 = stack.pop_w() as word
|
||||
x1 = stack.pop_w() as word
|
||||
yy+=dy
|
||||
}
|
||||
cx16.r11L = pget(xx as uword, lsb(yy)) ; old_color
|
||||
|
||||
@@ -807,17 +807,17 @@ invert:
|
||||
sub push_stack(word sxl, word sxr, word sy, byte sdy) {
|
||||
cx16.r0s = sy+sdy
|
||||
if cx16.r0s>=0 and cx16.r0s<=height-1 {
|
||||
stack.pushw(sxl as uword)
|
||||
stack.pushw(sxr as uword)
|
||||
stack.pushw(sy as uword)
|
||||
stack.push(sdy as ubyte)
|
||||
stack.push_w(sxl as uword)
|
||||
stack.push_w(sxr as uword)
|
||||
stack.push_w(sy as uword)
|
||||
stack.push_b(sdy as ubyte)
|
||||
}
|
||||
}
|
||||
sub pop_stack() {
|
||||
dy = stack.pop() as byte
|
||||
yy = stack.popw() as word
|
||||
x2 = stack.popw() as word
|
||||
x1 = stack.popw() as word
|
||||
dy = stack.pop_b() as byte
|
||||
yy = stack.pop_w() as word
|
||||
x2 = stack.pop_w() as word
|
||||
x1 = stack.pop_w() as word
|
||||
yy+=dy
|
||||
}
|
||||
cx16.r11L = pget(xx as uword, yy as uword) as ubyte ; old_color
|
||||
|
||||
@@ -136,10 +136,10 @@ psg {
|
||||
; cx16.r0 = the volume word (volume scaled by 256)
|
||||
; cx16.r1L = the voice number
|
||||
; cx16.r2L = attack value
|
||||
sys.pushw(cx16.r0)
|
||||
sys.push(cx16.r1L)
|
||||
sys.push(cx16.r2L)
|
||||
sys.pushw(cx16.r9)
|
||||
pushw(cx16.r0)
|
||||
push(cx16.r1L)
|
||||
push(cx16.r2L)
|
||||
pushw(cx16.r9)
|
||||
; calculate new volumes
|
||||
for cx16.r1L in 0 to 15 {
|
||||
if not voice_enabled[cx16.r1L]
|
||||
@@ -193,10 +193,10 @@ psg {
|
||||
cx16.VERA_DATA0 = cx16.VERA_DATA1
|
||||
}
|
||||
cx16.restore_vera_context()
|
||||
cx16.r9 = sys.popw()
|
||||
cx16.r2L = sys.pop()
|
||||
cx16.r1L = sys.pop()
|
||||
cx16.r0 = sys.popw()
|
||||
cx16.r9 = popw()
|
||||
cx16.r2L = pop()
|
||||
cx16.r1L = pop()
|
||||
cx16.r0 = popw()
|
||||
return true ; run the system IRQ handler afterwards
|
||||
}
|
||||
|
||||
|
||||
@@ -137,10 +137,10 @@ psg2 {
|
||||
; you have to call this routine every 1/60th second, for example from your vsync irq handler.
|
||||
; Or just install this routine as the only irq handler if you don't have to do other things there.
|
||||
|
||||
sys.push(cx16.r0L)
|
||||
sys.pushw(cx16.r1)
|
||||
sys.pushw(cx16.r2)
|
||||
sys.pushw(cx16.r3)
|
||||
push(cx16.r0L)
|
||||
pushw(cx16.r1)
|
||||
pushw(cx16.r2)
|
||||
pushw(cx16.r3)
|
||||
|
||||
vptr = voices
|
||||
alias voice = cx16.r0L
|
||||
@@ -206,10 +206,10 @@ psg2 {
|
||||
vptr++
|
||||
}
|
||||
cx16.restore_vera_context()
|
||||
cx16.r3 = sys.popw()
|
||||
cx16.r2 = sys.popw()
|
||||
cx16.r1 = sys.popw()
|
||||
cx16.r0L = sys.pop()
|
||||
cx16.r3 = popw()
|
||||
cx16.r2 = popw()
|
||||
cx16.r1 = popw()
|
||||
cx16.r0L = pop()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1584,12 +1584,12 @@ sub search_x16edit() -> ubyte {
|
||||
; -- Set the inter-program arguments.
|
||||
; standardized way to pass arguments between programs is in ram bank 0, address $bf00-$bfff.
|
||||
; see https://github.com/X16Community/x16-docs/blob/r49/X16%20Reference%20-%2008%20-%20Memory%20Map.md#bank-0
|
||||
sys.push(getrambank())
|
||||
push(getrambank())
|
||||
rambank(0)
|
||||
sys.memcopy(args_ptr, $bf00, args_size)
|
||||
if args_size<255
|
||||
@($bf00+args_size) = 0
|
||||
rambank(sys.pop())
|
||||
rambank(pop())
|
||||
}
|
||||
|
||||
asmsub get_program_args(^^ubyte buffer @R0, ubyte buf_size @R1, bool binary @Pc) {
|
||||
@@ -1974,19 +1974,6 @@ _larger
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
phy
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -2011,45 +1998,6 @@ _larger
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
ply
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub cpu_is_65816() -> bool @A {
|
||||
; -- Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
%asm {{
|
||||
|
||||
@@ -317,20 +317,6 @@ _loop lda P8ZP_SCRATCH_W1
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -357,46 +343,6 @@ _loop lda P8ZP_SCRATCH_W1
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
return false
|
||||
|
||||
@@ -19,10 +19,10 @@ prog8_lib {
|
||||
alias numzp = cx16.r4r5sl
|
||||
alias res = cx16.r6r7sl
|
||||
|
||||
sys.pushl(cx16.r0r1sl)
|
||||
sys.pushl(cx16.r2r3sl)
|
||||
sys.pushl(cx16.r4r5sl)
|
||||
sys.pushl(cx16.r6r7sl)
|
||||
pushl(cx16.r0r1sl)
|
||||
pushl(cx16.r2r3sl)
|
||||
pushl(cx16.r4r5sl)
|
||||
pushl(cx16.r6r7sl)
|
||||
|
||||
; Start with the most significant pair of bits
|
||||
; For the digit-by-digit algorithm, we process the numzpber in groups of 2 bits
|
||||
@@ -49,10 +49,10 @@ prog8_lib {
|
||||
|
||||
uword @nozp resultword = lsw(res)
|
||||
|
||||
cx16.r6r7sl = sys.popl()
|
||||
cx16.r4r5sl = sys.popl()
|
||||
cx16.r2r3sl = sys.popl()
|
||||
cx16.r0r1sl = sys.popl()
|
||||
cx16.r6r7sl = popl()
|
||||
cx16.r4r5sl = popl()
|
||||
cx16.r2r3sl = popl()
|
||||
cx16.r0r1sl = popl()
|
||||
|
||||
return resultword
|
||||
}
|
||||
|
||||
@@ -270,19 +270,6 @@ sub clampf(float value, float minimum, float maximum) -> float {
|
||||
return minimum
|
||||
}
|
||||
|
||||
inline asmsub push(float value @FAC1) {
|
||||
%asm {{
|
||||
jsr floats.pushFAC1
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> float @FAC1 {
|
||||
%asm {{
|
||||
clc
|
||||
jsr floats.popFAC
|
||||
}}
|
||||
}
|
||||
|
||||
sub lerp(float v0, float v1, float t) -> float {
|
||||
; Linear interpolation (LERP)
|
||||
; Precise method, which guarantees v = v1 when t = 1.
|
||||
|
||||
@@ -10,7 +10,7 @@ strings {
|
||||
if s==0 or s[0]==0
|
||||
return 0
|
||||
|
||||
sys.push(cx16.r0L)
|
||||
push(cx16.r0L)
|
||||
alias index = cx16.r0L
|
||||
ubyte numparts
|
||||
|
||||
@@ -34,7 +34,7 @@ strings {
|
||||
parts--
|
||||
strings.strip(parts^^)
|
||||
}
|
||||
cx16.r0L = sys.pop()
|
||||
cx16.r0L = pop()
|
||||
return numparts
|
||||
|
||||
sub skipwhitespace() {
|
||||
|
||||
@@ -210,22 +210,6 @@ sub normalize(float value) -> float {
|
||||
return value
|
||||
}
|
||||
|
||||
sub push(float value) {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
loadm.f fr99000,floats.push.value
|
||||
push.f fr99000
|
||||
}}
|
||||
}
|
||||
|
||||
sub pop() -> float {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
pop.f fr99000
|
||||
returnr.f fr99000
|
||||
}}
|
||||
}
|
||||
|
||||
sub lerp(float v0, float v1, float t) -> float {
|
||||
; Linear interpolation (LERP)
|
||||
; Precise method, which guarantees v = v1 when t = 1.
|
||||
|
||||
@@ -388,17 +388,17 @@ monogfx {
|
||||
sub push_stack(word sxl, word sxr, word sy, byte sdy) {
|
||||
cx16.r0s = sy+sdy
|
||||
if cx16.r0s>=0 and cx16.r0s<=height-1 {
|
||||
stack.pushw(sxl as uword)
|
||||
stack.pushw(sxr as uword)
|
||||
stack.pushw(sy as uword)
|
||||
stack.push(sdy as ubyte)
|
||||
stack.push_w(sxl as uword)
|
||||
stack.push_w(sxr as uword)
|
||||
stack.push_w(sy as uword)
|
||||
stack.push_b(sdy as ubyte)
|
||||
}
|
||||
}
|
||||
sub pop_stack() {
|
||||
dy = stack.pop() as byte
|
||||
yy = stack.popw() as word
|
||||
x2 = stack.popw() as word
|
||||
x1 = stack.popw() as word
|
||||
dy = stack.pop_b() as byte
|
||||
yy = stack.pop_w() as word
|
||||
x2 = stack.pop_w() as word
|
||||
x1 = stack.pop_w() as word
|
||||
yy+=dy
|
||||
}
|
||||
cx16.r11L = pget(xx as uword, yy as uword) as ubyte ; old_color
|
||||
|
||||
@@ -177,34 +177,11 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
sub push(ubyte b) {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
loadm.b r99100,sys.push.b
|
||||
push.b r99100
|
||||
}}
|
||||
}
|
||||
|
||||
sub pushw(uword w) {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
loadm.w r99000,sys.pushw.w
|
||||
push.w r99000
|
||||
}}
|
||||
}
|
||||
|
||||
sub pushl(long l) {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
loadm.l r99200,sys.pushl.l
|
||||
push.l r99200
|
||||
}}
|
||||
}
|
||||
|
||||
sub push_returnaddress(uword w) {
|
||||
; note: this actually doesn't do anything useful on the VM because the code execution doesn't use the simulated cpu stack
|
||||
%ir {{
|
||||
loadm.w r99000,sys.pushw.w
|
||||
loadm.w r99000,sys.push_returnaddress.w
|
||||
push.w r99000
|
||||
}}
|
||||
}
|
||||
@@ -215,30 +192,6 @@ sys {
|
||||
return mkword(lsb(address), msb(address))
|
||||
}
|
||||
|
||||
sub pop() -> ubyte {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
pop.b r99100
|
||||
returnr.b r99100
|
||||
}}
|
||||
}
|
||||
|
||||
sub popw() -> uword {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
pop.w r99000
|
||||
returnr.w r99000
|
||||
}}
|
||||
}
|
||||
|
||||
sub popl() -> long {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
pop.l r99200
|
||||
returnr.l r99200
|
||||
}}
|
||||
}
|
||||
|
||||
sub read_flags() -> ubyte {
|
||||
; "simulate" the 6502 status register a little bit
|
||||
if_neg {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.FatalAstException
|
||||
import prog8.code.ast.PtBuiltinFunctionCall
|
||||
import prog8.code.ast.PtExpression
|
||||
import prog8.code.ast.PtFunctionCall
|
||||
import prog8.code.ast.PtTypeCast
|
||||
import prog8.code.core.DataType
|
||||
|
||||
|
||||
internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall, PtExpression> {
|
||||
internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtBuiltinFunctionCall, PtExpression> {
|
||||
var popTypecast: DataType? = null
|
||||
var pushTypecast: DataType? = null
|
||||
var pushWord = false
|
||||
@@ -36,9 +37,9 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
|
||||
else -> throw FatalAstException("unsupported return value type ${value.type} with defer")
|
||||
}
|
||||
|
||||
val pushFunc = if(pushFloat) "floats.push" else if(pushWord) "sys.pushw" else if (pushLong) "sys.pushl" else "sys.push"
|
||||
val popFunc = if(pushFloat) "floats.pop" else if(pushWord) "sys.popw" else if(pushLong) "sys.popl" else "sys.pop"
|
||||
val pushCall = PtFunctionCall(pushFunc, true, DataType.UNDEFINED, value.position)
|
||||
val pushFunc = if(pushFloat) "pushf" else if(pushWord) "pushw" else if (pushLong) "pushl" else "push"
|
||||
val popFunc = if(pushFloat) "popf" else if(pushWord) "popw" else if(pushLong) "popl" else "pop"
|
||||
val pushCall = PtBuiltinFunctionCall(pushFunc, true, false, DataType.UNDEFINED, value.position)
|
||||
if(pushTypecast!=null) {
|
||||
val typecast = PtTypeCast(pushTypecast, true, value.position).also {
|
||||
it.add(value)
|
||||
@@ -53,7 +54,7 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
|
||||
it.add(PtFunctionCall(popFunc, false, returnDt, value.position))
|
||||
}
|
||||
} else
|
||||
PtFunctionCall(popFunc, false, value.type, value.position)
|
||||
PtBuiltinFunctionCall(popFunc, false, false, value.type, value.position)
|
||||
|
||||
return Pair(pushCall, popCall)
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ main {
|
||||
xyz {
|
||||
uword buffer_ptr = memory("buffers_stack", 8192, 0)
|
||||
|
||||
sub pop() -> ubyte { ; pop is also an IR instruction
|
||||
sub loadm() -> ubyte { ; loadm is also an IR instruction
|
||||
return buffer_ptr[2]
|
||||
}
|
||||
}"""
|
||||
|
||||
@@ -246,9 +246,9 @@ main {
|
||||
sub start() {
|
||||
uword variable
|
||||
|
||||
sys.pushw(variable)
|
||||
sys.pushw(handler)
|
||||
sys.pushw(&handler)
|
||||
pushw(variable)
|
||||
pushw(handler)
|
||||
pushw(&handler)
|
||||
handler(variable)
|
||||
handler(handler)
|
||||
handler(&handler)
|
||||
|
||||
@@ -1151,12 +1151,12 @@ main {
|
||||
|
||||
val ifelse = sub.children[5] as PtIfElse
|
||||
val ifscope = ifelse.ifScope.children[0] as PtNodeGroup
|
||||
val ifscope_push = ifscope.children[0] as PtFunctionCall
|
||||
val ifscope_push = ifscope.children[0] as PtBuiltinFunctionCall
|
||||
val ifscope_defer = ifscope.children[1] as PtFunctionCall
|
||||
val ifscope_return = ifscope.children[2] as PtReturn
|
||||
ifscope_defer.name shouldBe "p8b_main.p8s_test.p8s_prog8_invoke_defers"
|
||||
ifscope_push.name shouldBe "sys.pushw"
|
||||
(ifscope_return.children.single() as PtFunctionCall).name shouldBe "sys.popw"
|
||||
ifscope_push.name shouldBe "pushw"
|
||||
(ifscope_return.children.single() as PtBuiltinFunctionCall).name shouldBe "popw"
|
||||
|
||||
val ending = sub.children[7] as PtFunctionCall
|
||||
ending.name shouldBe "p8b_main.p8s_test.p8s_prog8_invoke_defers"
|
||||
|
||||
@@ -353,28 +353,6 @@ main {
|
||||
compileText(Cx16Target(), true, src, outputDir, writeAssembly = false) shouldNotBe null
|
||||
}
|
||||
|
||||
test("push pop are inlined also with noopt") {
|
||||
val text = """
|
||||
main {
|
||||
sub start() {
|
||||
sys.push(11)
|
||||
sys.pushw(2222)
|
||||
sys.push_returnaddress(3333)
|
||||
cx16.r2++
|
||||
cx16.r1 = sys.popw()
|
||||
cx16.r0L = sys.pop()
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), false, text, outputDir, writeAssembly = true)!!
|
||||
val assemblyFile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".asm")
|
||||
val assembly = assemblyFile.readText()
|
||||
assembly shouldContain "inlined routine follows: push"
|
||||
assembly shouldContain "inlined routine follows: pushw"
|
||||
assembly shouldContain "inlined routine follows: push_returnaddress"
|
||||
assembly shouldContain "inlined routine follows: pop"
|
||||
assembly shouldContain "inlined routine follows: popw"
|
||||
}
|
||||
|
||||
test("syslib correctly available for raw outputs") {
|
||||
val text = """
|
||||
%output raw
|
||||
|
||||
@@ -505,12 +505,12 @@ main {
|
||||
sub start() {
|
||||
ubyte bb
|
||||
uword ww
|
||||
sys.push(42)
|
||||
push(42)
|
||||
bb++
|
||||
bb=sys.pop()
|
||||
sys.pushw(9999)
|
||||
bb=pop()
|
||||
pushw(9999)
|
||||
ww++
|
||||
ww=sys.popw()
|
||||
ww=popw()
|
||||
}
|
||||
}"""
|
||||
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
Prog8 compiler v12.1.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prog8 compiler v12.2-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit 9aff85f0 in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-c128.p8
|
||||
@@ -52,10 +53,10 @@ smallstack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> ubyte
|
||||
}
|
||||
|
||||
@@ -66,10 +67,10 @@ stack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> uword
|
||||
}
|
||||
|
||||
@@ -645,15 +646,9 @@ sys {
|
||||
memcopy (uword source @R0, uword target @R1, uword count @AY) clobbers (A,X,Y)
|
||||
memset (uword mem @R0, uword numbytes @R1, ubyte value @A) clobbers (A,X,Y)
|
||||
memsetw (uword mem @R0, uword numwords @R1, uword value @AY) clobbers (A,X,Y)
|
||||
pop () -> ubyte @A
|
||||
popl () -> long @R0R1
|
||||
popw () -> uword @AY
|
||||
progend () -> uword @AY
|
||||
progstart () -> uword @AY
|
||||
push (ubyte value @A)
|
||||
push_returnaddress (uword address @XY)
|
||||
pushl (long value @R0R1)
|
||||
pushw (uword value @AY)
|
||||
read_flags () -> ubyte @A
|
||||
reset_system ()
|
||||
restore_irq () clobbers (A)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
Prog8 compiler v12.1.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prog8 compiler v12.2-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit 9aff85f0 in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-c64.p8
|
||||
@@ -52,10 +53,10 @@ smallstack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> ubyte
|
||||
}
|
||||
|
||||
@@ -66,10 +67,10 @@ stack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> uword
|
||||
}
|
||||
|
||||
@@ -307,10 +308,8 @@ floats {
|
||||
minf (float f1, float f2) -> float
|
||||
normalize (float value @FAC1) -> float @FAC1
|
||||
parse (str value @AY) -> float @FAC1
|
||||
pop () -> float @FAC1
|
||||
pow (float value, float power) -> float
|
||||
print (float value @FAC1) clobbers (A,X,Y)
|
||||
push (float value @FAC1)
|
||||
rad (float angle) -> float
|
||||
rnd () -> float
|
||||
rndseed (float seed)
|
||||
@@ -758,15 +757,9 @@ sys {
|
||||
memcopy (uword source @R0, uword target @R1, uword count @AY) clobbers (A,X,Y)
|
||||
memset (uword mem @R0, uword numbytes @R1, ubyte value @A) clobbers (A,X,Y)
|
||||
memsetw (uword mem @R0, uword numwords @R1, uword value @AY) clobbers (A,X,Y)
|
||||
pop () -> ubyte @A
|
||||
popl () -> long @R0R1
|
||||
popw () -> uword @AY
|
||||
progend () -> uword @AY
|
||||
progstart () -> uword @AY
|
||||
push (ubyte value @A)
|
||||
push_returnaddress (uword address @XY)
|
||||
pushl (long value @R0R1)
|
||||
pushw (uword value @AY)
|
||||
read_flags () -> ubyte @A
|
||||
reset_system ()
|
||||
restore_irq () clobbers (A)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
Prog8 compiler v12.1.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prog8 compiler v12.2-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit 9aff85f0 in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-cx16.p8
|
||||
@@ -91,10 +92,10 @@ smallstack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> ubyte
|
||||
}
|
||||
|
||||
@@ -105,10 +106,10 @@ stack {
|
||||
init (ubyte rambank)
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> uword
|
||||
}
|
||||
|
||||
@@ -403,10 +404,8 @@ floats {
|
||||
minf (float f1, float f2) -> float
|
||||
normalize (float value @FAC1) -> float @FAC1
|
||||
parse (str value @AY) -> float @FAC1
|
||||
pop () -> float @FAC1
|
||||
pow (float value, float power) -> float
|
||||
print (float value @FAC1) clobbers (A,X,Y)
|
||||
push (float value @FAC1)
|
||||
rad (float angle) -> float
|
||||
rnd () -> float
|
||||
rndseed (float seed)
|
||||
@@ -1421,16 +1420,10 @@ sys {
|
||||
memcopy (uword source @R0, uword target @R1, uword count @AY) clobbers (A,X,Y)
|
||||
memset (uword mem @R0, uword numbytes @R1, ubyte value @A) clobbers (A,X,Y)
|
||||
memsetw (uword mem @R0, uword numwords @R1, uword value @AY) clobbers (A,X,Y)
|
||||
pop () -> ubyte @A
|
||||
popl () -> long @R0R1
|
||||
popw () -> uword @AY
|
||||
poweroff_system ()
|
||||
progend () -> uword @AY
|
||||
progstart () -> uword @AY
|
||||
push (ubyte value @A)
|
||||
push_returnaddress (uword address @XY)
|
||||
pushl (long value @R0R1)
|
||||
pushw (uword value @AY)
|
||||
read_flags () -> ubyte @A
|
||||
reset_system ()
|
||||
restore_irq () clobbers (A)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
Prog8 compiler v12.1.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prog8 compiler v12.2-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit 9aff85f0 in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-pet32.p8
|
||||
@@ -52,10 +53,10 @@ smallstack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> ubyte
|
||||
}
|
||||
|
||||
@@ -66,10 +67,10 @@ stack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> uword
|
||||
}
|
||||
|
||||
@@ -271,10 +272,8 @@ floats {
|
||||
log2 (float value) -> float
|
||||
maxf (float f1, float f2) -> float
|
||||
minf (float f1, float f2) -> float
|
||||
pop () -> float @FAC1
|
||||
pow (float value, float power) -> float
|
||||
print (float value @FAC1) clobbers (A,X,Y)
|
||||
push (float value @FAC1)
|
||||
rad (float angle) -> float
|
||||
rndseed (float seed)
|
||||
round (float value) -> float
|
||||
@@ -582,15 +581,9 @@ sys {
|
||||
memcopy (uword source @R0, uword target @R1, uword count @AY) clobbers (A,X,Y)
|
||||
memset (uword mem @R0, uword numbytes @R1, ubyte value @A) clobbers (A,X,Y)
|
||||
memsetw (uword mem @R0, uword numwords @R1, uword value @AY) clobbers (A,X,Y)
|
||||
pop () -> ubyte @A
|
||||
popl () -> long @R0R1
|
||||
popw () -> uword @AY
|
||||
progend () -> uword @AY
|
||||
progstart () -> uword @AY
|
||||
push (ubyte value @A)
|
||||
push_returnaddress (uword address @XY)
|
||||
pushl (long value @R0R1)
|
||||
pushw (uword value @AY)
|
||||
read_flags () -> ubyte @A
|
||||
reset_system ()
|
||||
restore_prog8_internals ()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
Prog8 compiler v12.1.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prog8 compiler v12.2-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit 9aff85f0 in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-virtual.p8
|
||||
@@ -32,10 +33,10 @@ smallstack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> ubyte
|
||||
}
|
||||
|
||||
@@ -46,10 +47,10 @@ stack {
|
||||
init ()
|
||||
isempty () -> bool
|
||||
isfull () -> bool
|
||||
pop () -> ubyte
|
||||
popw () -> uword
|
||||
push (ubyte value)
|
||||
pushw (uword value)
|
||||
pop_b () -> ubyte
|
||||
pop_w () -> uword
|
||||
push_b (ubyte value)
|
||||
push_w (uword value)
|
||||
size () -> uword
|
||||
}
|
||||
|
||||
@@ -192,10 +193,8 @@ floats {
|
||||
minf (float f1, float f2) -> float
|
||||
normalize (float value) -> float
|
||||
parse (str value) -> float
|
||||
pop () -> float
|
||||
pow (float value, float power) -> float
|
||||
print (float value)
|
||||
push (float value)
|
||||
rad (float angle) -> float
|
||||
rnd () -> float
|
||||
rndseed (float seed)
|
||||
@@ -391,15 +390,9 @@ sys {
|
||||
memcopy (uword source, uword tgt, uword count)
|
||||
memset (uword mem, uword numbytes, ubyte value)
|
||||
memsetw (uword mem, uword numwords, uword value)
|
||||
pop () -> ubyte
|
||||
popl () -> long
|
||||
popw () -> uword
|
||||
progend () -> uword
|
||||
progstart () -> uword
|
||||
push (ubyte b)
|
||||
push_returnaddress (uword w)
|
||||
pushl (long l)
|
||||
pushw (uword w)
|
||||
read_flags () -> ubyte
|
||||
reset_system ()
|
||||
restore_prog8_internals ()
|
||||
|
||||
+39
-24
@@ -88,6 +88,43 @@ Math
|
||||
Accepts unsigned integer (result is ubyte), long (result is uword), and floating point numbers.
|
||||
To do the reverse - squaring a number - just write ``x*x``.
|
||||
|
||||
CPU Stack
|
||||
^^^^^^^^^
|
||||
:index:`push` (value)
|
||||
pushes a byte value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
:index:`pushw` (value)
|
||||
pushes a 16-bit word value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
Don't assume anything about the order in which the bytes are pushed - popw will make sense of them again.
|
||||
|
||||
:index:`pushl` (value)
|
||||
pushes a 32-bit value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
Don't assume anything about the order in which the bytes are pushed - popl will make sense of them again.
|
||||
|
||||
:index:`pushf` (value)
|
||||
pushes a floating point value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
Don't assume anything about the order in which the bytes are pushed - popf will make sense of them again.
|
||||
|
||||
:index:`pop` ()
|
||||
pops a byte value off the CPU hardware stack and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
:index:`popw` ()
|
||||
pops a 16-bit word value off the CPU hardware stack that was pushed before by pushw, and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
:index:`popl` ()
|
||||
pops a 32-bit value off the CPU hardware stack that was pushed before by pushl, and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
:index:`popf` ()
|
||||
pops a floating point value off the CPU hardware stack that was pushed before by pushl, and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
|
||||
Miscellaneous
|
||||
^^^^^^^^^^^^^
|
||||
@@ -1433,36 +1470,14 @@ processor stack
|
||||
'''''''''''''''
|
||||
.. index:: pair: Libraries; processor stack
|
||||
|
||||
``push (value)``
|
||||
pushes a byte value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
``pushw (value)``
|
||||
pushes a 16-bit word value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
Don't assume anything about the order in which the bytes are pushed - popw will make sense of them again.
|
||||
|
||||
``pushl (value)``
|
||||
pushes a 32-bit value on the CPU hardware stack.
|
||||
Low-level function that is seldomly used in user code.
|
||||
Don't assume anything about the order in which the bytes are pushed - popl will make sense of them again.
|
||||
Pushing and popping values on the CPU hardware stack can be done via the stack related :ref:`builtinfunctions` (pop, push etc).
|
||||
There is a very specialized function in the sys module here as well:
|
||||
|
||||
``push_returnaddress (address)``
|
||||
pushes a 16 bit memory address on the CPU hardware stack in the same byte order as a JSR instruction would,
|
||||
which means the next RTS instruction will jump to that address instead.you
|
||||
You cannot use pushw() for this because the bytes pushed by JSR are different
|
||||
|
||||
``pop ()``
|
||||
pops a byte value off the CPU hardware stack and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
``popw ()``
|
||||
pops a 16-bit word value off the CPU hardware stack that was pushed before by pushw, and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
``popl ()``
|
||||
pops a 32-bit value off the CPU hardware stack that was pushed before by pushl, and returns it.
|
||||
Low-level function that is seldomly used in user code.
|
||||
|
||||
|
||||
textio (txt.*)
|
||||
|
||||
@@ -1193,17 +1193,12 @@ flag such as Carry (Pc).
|
||||
|
||||
It is not possible to use floating point arguments or return values in an asmsub.
|
||||
|
||||
**inline:** Trivial ``asmsub`` routines can be tagged as ``inline`` to tell the compiler to copy their code
|
||||
in-place to the locations where the subroutine is called, rather than inserting an actual call and return to the
|
||||
subroutine. This may increase code size significantly and can only be used in limited scenarios, so YMMV.
|
||||
Note that the routine's code is copied verbatim into the place of the subroutine call in this case,
|
||||
so pay attention to any jumps and rts instructions in the inlined code!
|
||||
|
||||
.. note::
|
||||
Asmsubs can also be tagged as ``inline asmsub`` to make trivial pieces of assembly inserted
|
||||
directly instead of a call to them. Note that it is literal copy-paste of code that is done,
|
||||
so make sure the assembly is actually written to behave like such - which probably means you
|
||||
don't want a ``rts`` or ``jmp`` or ``bra`` in it!
|
||||
Inlining may increase code size significantly and can only be used in limited scenarios
|
||||
|
||||
.. note::
|
||||
The **sixteen 'virtual' 16-bit registers** from the Commander X16 can also be specified as ``R0`` .. ``R15`` .
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
push() and pop() (and pushw, pushl etc) should be builtin functions again instead of subs in sys, because you really want to avoid filling an intermediate parameter variable first before it actually does the pha/pla's
|
||||
add a nice conversion error message for that.
|
||||
|
||||
|
||||
Known bugs:
|
||||
- fix chained aliasing errors see test "chained aliasing"
|
||||
- fix crash in ir loader/vm for deeply nested symbol reference, see test "deeply scoped variable references"
|
||||
|
||||
@@ -112,20 +112,6 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -152,46 +138,6 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
return false
|
||||
|
||||
@@ -444,20 +444,6 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -472,46 +458,6 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
return false
|
||||
|
||||
@@ -104,20 +104,6 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push_returnaddress(uword address @XY) {
|
||||
%asm {{
|
||||
; push like JSR would: address-1, MSB first then LSB
|
||||
@@ -144,46 +130,6 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
return false
|
||||
|
||||
@@ -9,60 +9,6 @@ sys {
|
||||
|
||||
; these push/pop routines are always required by the compiler:
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub reset_system() {
|
||||
; Soft-reset the system back to initial power-on Basic prompt.
|
||||
%asm {{
|
||||
|
||||
@@ -9,60 +9,6 @@ sys {
|
||||
|
||||
; these push/pop routines are always required by the compiler:
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub reset_system() {
|
||||
; Soft-reset the system back to initial power-on Basic prompt.
|
||||
; We do this via the SMC so that a true reset is performed that also resets the Vera fully.
|
||||
|
||||
@@ -9,60 +9,6 @@ sys {
|
||||
|
||||
; these push/pop routines are always required by the compiler:
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1) {
|
||||
%asm {{
|
||||
lda cx16.r0
|
||||
pha
|
||||
lda cx16.r0+1
|
||||
pha
|
||||
lda cx16.r0+2
|
||||
pha
|
||||
lda cx16.r0+3
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popl() -> long @R0R1 {
|
||||
%asm {{
|
||||
pla
|
||||
sta cx16.r0+3
|
||||
pla
|
||||
sta cx16.r0+2
|
||||
pla
|
||||
sta cx16.r0+1
|
||||
pla
|
||||
sta cx16.r0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub reset_system() {
|
||||
; Soft-reset the system back to initial power-on Basic prompt.
|
||||
%asm {{
|
||||
|
||||
@@ -79,9 +79,9 @@ fileselector {
|
||||
str defaultpattern="*"
|
||||
if pattern==0
|
||||
pattern = &defaultpattern
|
||||
sys.push(cx16.getrambank())
|
||||
push(cx16.getrambank())
|
||||
cx16.r0 = internal_select(pattern)
|
||||
cx16.rambank(sys.pop())
|
||||
cx16.rambank(pop())
|
||||
return cx16.r0
|
||||
}
|
||||
|
||||
|
||||
@@ -74,13 +74,13 @@ main {
|
||||
interpolate(half, e)
|
||||
|
||||
; recurse
|
||||
sys.pushw(e)
|
||||
sys.pushw(half)
|
||||
sys.push(displacement)
|
||||
pushw(e)
|
||||
pushw(half)
|
||||
push(displacement)
|
||||
recursive_midpoint(s, half, displacement-smoothness)
|
||||
displacement = sys.pop()
|
||||
half = sys.popw()
|
||||
e = sys.popw()
|
||||
displacement = pop()
|
||||
half = popw()
|
||||
e = popw()
|
||||
recursive_midpoint(half, e, displacement-smoothness)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,14 +111,14 @@ btree {
|
||||
sub count_node(^^Node r) {
|
||||
count++
|
||||
if r.left!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
count_node(r.left)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
if r.right!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
count_node(r.right)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,16 +178,16 @@ btree {
|
||||
|
||||
sub print_tree(^^Node r) {
|
||||
if r.left!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
print_tree(r.left)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
txt.print_uw(r.value)
|
||||
txt.print(", ")
|
||||
if r.right!=0 {
|
||||
sys.pushw(r)
|
||||
pushw(r)
|
||||
print_tree(r.right)
|
||||
r = sys.popw()
|
||||
r = popw()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,18 +203,18 @@ btree {
|
||||
txt.print_uw(r.value)
|
||||
txt.nl()
|
||||
if r.left!=0 {
|
||||
sys.pushw(r)
|
||||
sys.push(depth)
|
||||
pushw(r)
|
||||
push(depth)
|
||||
print_tree(r.left, depth+1)
|
||||
depth = sys.pop()
|
||||
r = sys.popw()
|
||||
depth = pop()
|
||||
r = popw()
|
||||
}
|
||||
if r.right!=0 {
|
||||
sys.pushw(r)
|
||||
sys.push(depth)
|
||||
pushw(r)
|
||||
push(depth)
|
||||
print_tree(r.right, depth+1)
|
||||
depth = sys.pop()
|
||||
r = sys.popw()
|
||||
depth = pop()
|
||||
r = popw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -48,12 +48,12 @@ main {
|
||||
if could_place(row, col) {
|
||||
board[row] = col
|
||||
; we need to save the local variables row and col.
|
||||
sys.push(row)
|
||||
sys.push(col)
|
||||
push(row)
|
||||
push(col)
|
||||
place_queen(row + 1)
|
||||
; restore the local variables after the recursive call.
|
||||
col = sys.pop()
|
||||
row = sys.pop()
|
||||
col = pop()
|
||||
row = pop()
|
||||
board[row] = 0
|
||||
}
|
||||
}
|
||||
|
||||
+73
-265
@@ -1,276 +1,84 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import strings
|
||||
%import floats
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
main {
|
||||
; Test the routine
|
||||
sub testsgn() {
|
||||
byte @shared b1 = -100
|
||||
word @shared w1 = -1000
|
||||
long @shared l1 = -1000000
|
||||
|
||||
cx16.r0sL = sgn(b1)
|
||||
cx16.r1sL = sgn(w1)
|
||||
cx16.r2sL = sgn(l1)
|
||||
sub start() {
|
||||
old()
|
||||
new()
|
||||
}
|
||||
|
||||
sub start() {
|
||||
testsgn()
|
||||
|
||||
long @shared lv
|
||||
uword @shared wv
|
||||
ubyte @shared bv
|
||||
|
||||
txt.print_l(0) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(0) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(0)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 0
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(55555555) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(7453) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(55555555)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 55555555
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
; Additional test cases for square root
|
||||
txt.print_l(1) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(1) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(1)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 1
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(4) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(2) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(4)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 4
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(9) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(3) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(9)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 9
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(16) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(4) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(16)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 16
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(25) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(5) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(25)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 25
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(36) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(6) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(36)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 36
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(49) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(7) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(49)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 49
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(64) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(8) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(64)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 64
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(81) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(9) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(81)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 81
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(100) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(10) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(100)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 100
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(121) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(11) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(121)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 121
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(144) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(12) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(144)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 144
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(255) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(15) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(255)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 255
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(256) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(16) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(256)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 256
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(1024) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(32) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(1024)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 1024
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(65536) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(256) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(65536)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 65536
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(1000000) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(1000) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(1000000)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 1000000
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(16777216) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(4096) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(16777216)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 16777216
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(2147483647) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(46340) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(2147483647)) ; calculated result
|
||||
txt.spc()
|
||||
lv = 2147483647
|
||||
txt.print_uw(sqrt(lv)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
txt.print_l(4294967295) ; value
|
||||
txt.spc()
|
||||
txt.print_uw(65535) ; expected result
|
||||
txt.spc()
|
||||
txt.print_uw(prog8_lib.sqrt_long(4294967295)) ; calculated result
|
||||
txt.nl()
|
||||
|
||||
; test_b()
|
||||
; test_w()
|
||||
; test_long()
|
||||
sub old() {
|
||||
; sys.push(99)
|
||||
; sys.pushw(2222)
|
||||
; sys.pushl(66663333)
|
||||
; floats.push(99.7777)
|
||||
; cx16.r0++
|
||||
;
|
||||
; sub test_b() {
|
||||
; bv = 99
|
||||
; txt.print_ub(min(bv, 200))
|
||||
; txt.spc()
|
||||
; bv = min(bv, 200)
|
||||
; txt.print_ub(bv)
|
||||
; txt.nl()
|
||||
; }
|
||||
; txt.print_f(floats.pop())
|
||||
; txt.spc()
|
||||
; txt.print_l(sys.popl())
|
||||
; txt.spc()
|
||||
; txt.print_uw(sys.popw())
|
||||
; txt.spc()
|
||||
; txt.print_ub(sys.pop())
|
||||
; txt.nl()
|
||||
;
|
||||
; sub test_w() {
|
||||
; wv = 22211
|
||||
; txt.print_uw(min(wv, 55555))
|
||||
; txt.spc()
|
||||
; wv = min(wv, 55555)
|
||||
; txt.print_uw(wv)
|
||||
; txt.nl()
|
||||
; }
|
||||
; cx16.r0L = 42
|
||||
; cx16.r1 = 9999
|
||||
; cx16.r2r3sl = 44445555
|
||||
; float @shared fl = 33.8888
|
||||
;
|
||||
; sub test_long() {
|
||||
; lv = 55551111
|
||||
; txt.print_uw(min(lv, 88888888))
|
||||
; txt.spc()
|
||||
; lv = min(lv, 88888888)
|
||||
; txt.print_uw(lv)
|
||||
; txt.nl()
|
||||
; }
|
||||
; sys.push(cx16.r0L)
|
||||
; sys.pushw(cx16.r1)
|
||||
; sys.pushl(cx16.r2r3sl)
|
||||
; floats.push(fl)
|
||||
; cx16.r0++
|
||||
;
|
||||
; txt.print_f(floats.pop())
|
||||
; txt.spc()
|
||||
; txt.print_l(sys.popl())
|
||||
; txt.spc()
|
||||
; txt.print_uw(sys.popw())
|
||||
; txt.spc()
|
||||
; txt.print_ub(sys.pop())
|
||||
; txt.nl()
|
||||
}
|
||||
|
||||
sub new() {
|
||||
push(99)
|
||||
pushw(2222)
|
||||
pushl(66663333)
|
||||
pushf(99.7777)
|
||||
cx16.r0++
|
||||
|
||||
txt.print_f(popf())
|
||||
txt.spc()
|
||||
txt.print_l(popl())
|
||||
txt.spc()
|
||||
txt.print_uw(popw())
|
||||
txt.spc()
|
||||
txt.print_ub(pop())
|
||||
txt.nl()
|
||||
|
||||
cx16.r0L = 42
|
||||
cx16.r1 = 9999
|
||||
cx16.r2r3sl = 44445555
|
||||
float @shared fl = 33.8888
|
||||
|
||||
push(cx16.r0L)
|
||||
pushw(cx16.r1)
|
||||
pushl(cx16.r2r3sl)
|
||||
pushf(fl)
|
||||
cx16.r0++
|
||||
|
||||
txt.print_f(popf())
|
||||
txt.spc()
|
||||
txt.print_l(popl())
|
||||
txt.spc()
|
||||
txt.print_uw(popw())
|
||||
txt.spc()
|
||||
txt.print_ub(pop())
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<keywords keywords="&;&&;&<;&>;->;@;^^;alias;and;as;asmsub;break;clobbers;continue;do;downto;else;extsub;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;on;or;repeat;return;step;sub;then;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
|
||||
<keywords2 keywords="%address;%align;%asm;%asmbinary;%asminclude;%breakpoint;%encoding;%import;%ir;%jmptable;%launcher;%memtop;%option;%output;%zeropage;%zpallowed;%zpreserved;@align64;@alignpage;@alignword;@bank;@dirty;@nosplit;@nozp;@requirezp;@shared;@split;@zp;atascii:;c64os:;cp437:;default:;iso16:;iso5:;iso:;kata:;petscii:;sc:" />
|
||||
<keywords3 keywords="^^bool;^^byte;^^float;^^long;^^str;^^ubyte;^^uword;^^word;bool;byte;const;float;long;str;struct;ubyte;uword;void;word" />
|
||||
<keywords4 keywords="abs;bmx;call;callfar;callfar2;cbm;clamp;cmp;conv;cx16;defer;diskio;divmod;floats;len;lsb;lsw;math;max;memory;min;mkword;msb;msw;offsetof;peek;peekbool;peekf;peekl;peekw;poke;pokebool;pokef;pokel;pokew;psg;psg2;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt;strings;swap;sys;txt;verafx" />
|
||||
<keywords4 keywords="abs;bmx;call;callfar;callfar2;cbm;clamp;cmp;conv;cx16;defer;diskio;divmod;floats;len;lsb;lsw;math;max;memory;min;mkword;msb;msw;offsetof;peek;peekbool;peekf;peekl;peekw;poke;pokebool;pokef;pokel;pokew;pop;popf;popl;popw;psg;psg2;push;pushf;pushl;pushw;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt;strings;swap;sys;txt;verafx" />
|
||||
</highlighting>
|
||||
<extensionMap>
|
||||
<mapping ext="p8" />
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte bool
long word uword
float
zp shared split nosplit requirezp nozp struct</Keywords>
|
||||
<Keywords name="Keywords2">%address
%asm
%ir
%asmbinary
%asminclude
%align
%breakpoint
%encoding
%import
%jmptable
%memtop
%launcher
%option
%output
%zeropage
%zpreserved
%zpallowed</Keywords>
|
||||
<Keywords name="Keywords3">inline sub asmsub extsub
clobbers
asm
if
when then else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat unroll
break continue return goto</Keywords>
|
||||
<Keywords name="Keywords4">alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lsl lsr memory mkword min max msb msw peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof offsetof sqrtw swap</Keywords>
|
||||
<Keywords name="Keywords4">alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lsl lsr memory mkword min max msb msw peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool push pushw pushl pushf pop popw popl popf rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof offsetof sqrtw swap</Keywords>
|
||||
<Keywords name="Keywords5">true false
not and or xor
as to downto |></Keywords>
|
||||
<Keywords name="Keywords6"></Keywords>
|
||||
<Keywords name="Keywords7"></Keywords>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte bool
long word uword
float
zp shared split nosplit requirezp nozp struct</Keywords>
|
||||
<Keywords name="Keywords2">%address
%asm
%ir
%asmbinary
%asminclude
%align
%breakpoint
%encoding
%import
%jmptable
%memtop
%launcher
%option
%output
%zeropage
%zpreserved
%zpallowed</Keywords>
|
||||
<Keywords name="Keywords3">inline sub asmsub extsub
clobbers
asm
if
when else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat unroll
break continue return goto</Keywords>
|
||||
<Keywords name="Keywords4">alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lsl lsr memory mkword min max msb msw peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof offsetof sqrtw swap</Keywords>
|
||||
<Keywords name="Keywords4">alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lsl lsr memory mkword min max msb msw peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool push pushw pushl pushf pop popw popl popf rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof offsetof sqrtw swap</Keywords>
|
||||
<Keywords name="Keywords5">true false
not and or xor
as to downto |></Keywords>
|
||||
<Keywords name="Keywords6"></Keywords>
|
||||
<Keywords name="Keywords7"></Keywords>
|
||||
|
||||
@@ -13,7 +13,7 @@ syn keyword prog8BuiltInFunc sgn sqrtw
|
||||
syn keyword prog8BuiltInFunc len
|
||||
|
||||
" Miscellaneous functions
|
||||
syn keyword prog8BuiltInFunc cmp divmod lsb msb lsw msw mkword min max peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool rsave rsavex rrestore rrestorex
|
||||
syn keyword prog8BuiltInFunc cmp divmod lsb msb lsw msw mkword min max peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool push pushw pushl pushf pop popw popl popf rsave rsavex rrestore rrestorex
|
||||
syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof offsetof setlsb setmsb swap
|
||||
syn keyword prog8BuiltInFunc memory call callfar callfar2 clamp defer alias
|
||||
|
||||
|
||||
Reference in new issue
Block a user