mirror of
https://github.com/irmen/prog8.git
synced 2025-10-25 05:18:38 +00:00
added sys.pushl() and sys.popl()
This commit is contained in:
@@ -1056,6 +1056,32 @@ _no_msb_size
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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.
|
||||
|
||||
@@ -1065,6 +1065,32 @@ _no_msb_size
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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.
|
||||
|
||||
@@ -2141,6 +2141,32 @@ save_SCRATCH_ZPWORD2 .word ?
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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 {{
|
||||
|
||||
@@ -532,6 +532,32 @@ save_SCRATCH_ZPWORD2 .word ?
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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
|
||||
|
||||
@@ -192,6 +192,14 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
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 {{
|
||||
@@ -222,6 +230,14 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -12,6 +12,7 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
|
||||
var pushTypecast: DataType? = null
|
||||
var pushWord = false
|
||||
var pushFloat = false
|
||||
var pushLong = false
|
||||
|
||||
when {
|
||||
value.type.isBool -> {
|
||||
@@ -29,13 +30,14 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
|
||||
}
|
||||
value.type.isUnsignedByte -> {}
|
||||
value.type.isUnsignedWord -> pushWord = true
|
||||
value.type.isLong -> pushLong = true
|
||||
value.type.isPassByRef -> pushWord = true
|
||||
value.type.isFloat -> pushFloat = true
|
||||
else -> throw FatalAstException("unsupported return value type ${value.type} with defer")
|
||||
}
|
||||
|
||||
val pushFunc = if(pushFloat) "floats.push" else if(pushWord) "sys.pushw" else "sys.push"
|
||||
val popFunc = if(pushFloat) "floats.pop" else if(pushWord) "sys.popw" else "sys.pop"
|
||||
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)
|
||||
if(pushTypecast!=null) {
|
||||
val typecast = PtTypeCast(pushTypecast, value.position).also {
|
||||
@@ -47,7 +49,7 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
|
||||
}
|
||||
val popCall = if(popTypecast!=null) {
|
||||
PtTypeCast(popTypecast, value.position).also {
|
||||
val returnDt = if(pushWord) DataType.UWORD else DataType.UBYTE
|
||||
val returnDt = if(pushWord) DataType.UWORD else if(pushLong) DataType.LONG else if(pushFloat) DataType.FLOAT else DataType.UBYTE
|
||||
it.add(PtFunctionCall(popFunc, false, returnDt, value.position))
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -372,7 +372,7 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
||||
else if(literalText.length>2)
|
||||
datatype = BaseDataType.UWORD
|
||||
try {
|
||||
integer = literalText.toInt(16)
|
||||
integer = literalText.lowercase().toLong(16).toInt()
|
||||
} catch(x: NumberFormatException) {
|
||||
throw SyntaxError("invalid hexadecimal literal ${x.message}", ctx.toPosition())
|
||||
}
|
||||
|
||||
@@ -1177,12 +1177,19 @@ sys (part of syslib)
|
||||
This allows other code to run that might clobber these values temporarily.
|
||||
|
||||
``push (value)``
|
||||
pushes a byte value on the CPU hardware stack. Low-level function that should normally not be used.
|
||||
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 should normally not be used.
|
||||
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.
|
||||
|
||||
``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
|
||||
@@ -1190,11 +1197,15 @@ sys (part of syslib)
|
||||
|
||||
``pop ()``
|
||||
pops a byte value off the CPU hardware stack and returns it.
|
||||
Low-level function that should normally not be used.
|
||||
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 should normally not be used.
|
||||
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.*)
|
||||
|
||||
@@ -3,8 +3,7 @@ TODO
|
||||
|
||||
LONG TYPE
|
||||
---------
|
||||
= add pushl popl
|
||||
- scan through more library routines if there are opportunities to use the long?
|
||||
- scan through more library routines if there are opportunities to use a long param or returnvalue?
|
||||
- document the new long type! and mklong(a,b,c,d) and mklong2(w1,w2) , print_l , print_ulhex (& conv.str_l) and pokel, peekl, cbm.SETTIML/RDTIML, and the use of R0:R1 when doing LONG calculations
|
||||
- asmsub call convention: @R0R1_32 to specify a 32 bits long combined register R0:R1
|
||||
- how hard is it to also implement the other comparison operators (<,>,<=,>=) on longs?
|
||||
|
||||
@@ -411,6 +411,32 @@ save_SCRATCH_ZPWORD2 .word ?
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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
|
||||
|
||||
@@ -672,6 +672,32 @@ save_SCRATCH_ZPWORD2 .word ?
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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
|
||||
|
||||
@@ -344,6 +344,32 @@ save_SCRATCH_ZPWORD2 .word ?
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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
|
||||
|
||||
@@ -49,6 +49,32 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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 {{
|
||||
|
||||
@@ -49,6 +49,32 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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.
|
||||
|
||||
@@ -49,6 +49,32 @@ sys {
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushl(long value @R0R1_32) {
|
||||
%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_32 {
|
||||
%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 {{
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%import bcd
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
cbm.SETTIML($12fe56)
|
||||
repeat {
|
||||
txt.home()
|
||||
txt.print_ulhex(cbm.RDTIML(), false)
|
||||
}
|
||||
sys.pushl($aabb1234)
|
||||
long lv = sys.popl()
|
||||
txt.print_ulhex(lv, false)
|
||||
|
||||
; cx16.r0 = sys.popw()
|
||||
; cx16.r1 = sys.popw()
|
||||
|
||||
; txt.print_uwhex(cx16.r0, false)
|
||||
; txt.print_uwhex(cx16.r1, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ Program to execute is not stored in the system memory, it's just a separate list
|
||||
100K virtual registers, 16 bits wide, can also be used as 8 bits. r0-r99999
|
||||
reserved 99000 - 99099 : WORD registers for syscall arguments and response value(s)
|
||||
reserved 99100 - 99199 : BYTE registers for syscall arguments and response value(s)
|
||||
reseverd 99200 - 99299 : LONG registers for syscall arguments and response value(s)
|
||||
100K virtual floating point registers (64 bits double precision) fr0-fr99999
|
||||
65536 bytes of memory. Thus memory pointers (addresses) are limited to 16 bits.
|
||||
Value stack, max 128 entries of 1 byte each.
|
||||
|
||||
@@ -3141,7 +3141,7 @@ internal fun ArrayDeque<UByte>.popl(): Int {
|
||||
val b1 = removeLast().toUInt()
|
||||
val b2 = removeLast().toUInt()
|
||||
val b3 = removeLast().toUInt()
|
||||
return (b0 shl 24 or b1 shl 16 or b2 shl 8 or b3).toInt()
|
||||
return ((b0 shl 24) or (b1 shl 16) or (b2 shl 8) or b3).toInt()
|
||||
}
|
||||
|
||||
internal fun ArrayDeque<UByte>.popf(): Double {
|
||||
|
||||
Reference in New Issue
Block a user