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:
Irmen de Jong committed 2026-02-21 02:11:34 +01:00
1 parent 9aff85f08a
commit 093be9f2dd
55 files changed
+502 -1256

No files matched your search

+16 -16
View File
@@ -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()
}
}
}
+4 -4
View File
@@ -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) }
+9 -9
View File
@@ -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]
-54
View File
@@ -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.
-54
View File
@@ -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.
+4 -4
View File
@@ -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 {
+25 -25
View File
@@ -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
}
+2 -4
View File
@@ -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()
+8 -8
View File
@@ -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
+8 -8
View File
@@ -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
+8 -8
View File
@@ -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
+8 -8
View File
@@ -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
}
+8 -8
View File
@@ -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
}
+2 -54
View File
@@ -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 {{
-54
View File
@@ -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
+8 -8
View File
@@ -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() {
-16
View File
@@ -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.
+8 -8
View File
@@ -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
+1 -48
View File
@@ -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)
}
+1 -1
View File
@@ -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]
}
}"""
+3 -3
View File
@@ -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)
+3 -3
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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.*)
+1 -6
View File
@@ -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`` .
-4
View File
@@ -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 {{
+2 -2
View File
@@ -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
}
+6 -6
View File
@@ -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)
}
}
+16 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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()
}
}
+1 -1
View File
@@ -14,7 +14,7 @@
<keywords keywords="&amp;;&amp;&amp;;&amp;&lt;;&amp;&gt;;-&gt;;@;^^;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" />
+1 -1
View File
@@ -27,7 +27,7 @@
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;long word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared split nosplit requirezp nozp struct</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%align&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%encoding&#x000D;&#x000A;%import&#x000D;&#x000A;%jmptable&#x000D;&#x000A;%memtop&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved&#x000D;&#x000A;%zpallowed</Keywords>
<Keywords name="Keywords3">inline sub asmsub extsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when then else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat unroll&#x000D;&#x000A;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&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords>
<Keywords name="Keywords6"></Keywords>
<Keywords name="Keywords7"></Keywords>
+1 -1
View File
@@ -27,7 +27,7 @@
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;long word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared split nosplit requirezp nozp struct</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%align&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%encoding&#x000D;&#x000A;%import&#x000D;&#x000A;%jmptable&#x000D;&#x000A;%memtop&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved&#x000D;&#x000A;%zpallowed</Keywords>
<Keywords name="Keywords3">inline sub asmsub extsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat unroll&#x000D;&#x000A;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&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords>
<Keywords name="Keywords6"></Keywords>
<Keywords name="Keywords7"></Keywords>
+1 -1
View File
@@ -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