save X register automatically when calling sub that clobbers X

This commit is contained in:
Irmen de Jong 2018-12-09 19:48:59 +01:00
parent b8150f645d
commit f070dc22bb
13 changed files with 249 additions and 588 deletions

View File

@ -9,20 +9,10 @@
byte v2
ubyte cr
; done:
; ubyte all 6 comparisons
; byte all 6 comparisons
; check stack usage:
rsave()
c64.STROUT("signed byte ")
rrestore()
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT(' ')
rrestore()
cr=v1==v2
cr=v1==v2
@ -49,103 +39,63 @@
cr=v1>=v2
cr=v1>=v2
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
rrestore()
; comparisons:
rsave()
v1=-20
v2=125
c64.STROUT("v1=-20, v2=125\n")
rrestore()
compare()
rsave()
v1=80
v2=80
c64.STROUT("v1 = v2 = 80\n")
rrestore()
compare()
rsave()
v1=20
v2=-111
c64.STROUT("v1=20, v2=-111\n")
rrestore()
compare()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
return
sub compare() {
rsave()
c64.STROUT(" == != < > <= >=\n")
rrestore()
if v1==v2 {
rsave()
if v1==v2
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
else
c64.STROUT(" . ")
rrestore()
}
if v1!=v2 {
rsave()
if v1!=v2
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
else
c64.STROUT(" . ")
rrestore()
}
if v1<v2 {
rsave()
if v1<v2
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
else
c64.STROUT(" . ")
rrestore()
}
if v1>v2 {
rsave()
if v1>v2
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
else
c64.STROUT(" . ")
rrestore()
}
if v1<=v2 {
rsave()
if v1<=v2
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
else
c64.STROUT(" . ")
rrestore()
}
if v1>=v2 {
rsave()
if v1>=v2
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
else
c64.STROUT(" . ")
rrestore()
}
c64.CHROUT('\n')
}
}

View File

@ -11,22 +11,10 @@
float v2
ubyte cr
; done:
; ubyte all 6 comparisons
; byte all 6 comparisons
; uword all 6 comparisons
; word all 6 comparisons
; float all 6 comparisons
; check stack usage:
rsave()
c64.STROUT("floating point ")
rrestore()
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT(' ')
rrestore()
cr=v1==v2
cr=v1==v2
@ -53,123 +41,81 @@
cr=v1>=v2
cr=v1>=v2
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
rrestore()
; comparisons:
rsave()
v1=20
v2=666.66
c64.STROUT("v1=20, v2=666.66\n")
rrestore()
compare()
rsave()
v1=-20
v2=666.66
c64.STROUT("v1=-20, v2=666.66\n")
rrestore()
compare()
rsave()
v1=666.66
v2=555.55
c64.STROUT("v1=666.66, v2=555.55\n")
rrestore()
compare()
rsave()
v1=3.1415
v2=-3.1415
c64.STROUT("v1 = 3.1415, v2 = -3.1415\n")
rrestore()
compare()
rsave()
v1=3.1415
v2=3.1415
c64.STROUT("v1 = v2 = 3.1415\n")
rrestore()
compare()
rsave()
v1=0
v2=0
c64.STROUT("v1 = v2 = 0\n")
rrestore()
compare()
sub compare() {
rsave()
c64.STROUT(" == != < > <= >=\n")
rrestore()
if v1==v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1!=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
return
sub compare() {
c64.STROUT(" == != < > <= >=\n")
if v1==v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1!=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
c64.CHROUT('\n')
}
}
}

View File

@ -9,19 +9,10 @@
ubyte v2
ubyte cr
; done:
; ubyte all 6 comparisons
; check stack usage:
rsave()
c64.STROUT("unsigned byte ")
rrestore()
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT(' ')
rrestore()
cr=v1==v2
cr=v1==v2
@ -48,102 +39,62 @@
cr=v1>=v2
cr=v1>=v2
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
rrestore()
; comparisons:
rsave()
v1=20
v2=199
c64.STROUT("v1=20, v2=199\n")
rrestore()
compare()
rsave()
v1=80
v2=80
c64.STROUT("v1 = v2 = 80\n")
rrestore()
compare()
rsave()
v1=220
v2=10
c64.STROUT("v1=220, v2=10\n")
rrestore()
compare()
sub compare() {
rsave()
c64.STROUT(" == != < > <= >=\n")
rrestore()
if v1==v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1!=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
return
sub compare() {
c64.STROUT(" == != < > <= >=\n")
if v1==v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1!=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
c64.CHROUT('\n')
}

View File

@ -9,21 +9,10 @@
uword v2
ubyte cr
; done:
; ubyte all 6 comparisons
; byte all 6 comparisons
; uword all 6 comparisons
; check stack usage:
rsave()
c64.STROUT("unsigned word ")
rrestore()
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT(' ')
rrestore()
cr=v1==v2
cr=v1==v2
@ -50,141 +39,92 @@
cr=v1>=v2
cr=v1>=v2
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
rrestore()
; comparisons:
rsave()
v1=20
v2=$00aa
c64.STROUT("v1=20, v2=$00aa\n")
rrestore()
compare()
rsave()
v1=20
v2=$ea00
c64.STROUT("v1=20, v2=$ea00\n")
rrestore()
compare()
rsave()
v1=$c400
v2=$22
c64.STROUT("v1=$c400, v2=$22\n")
rrestore()
compare()
rsave()
v1=$c400
v2=$2a00
c64.STROUT("v1=$c400, v2=$2a00\n")
rrestore()
compare()
rsave()
v1=$c433
v2=$2a00
c64.STROUT("v1=$c433, v2=$2a00\n")
rrestore()
compare()
rsave()
v1=$c433
v2=$2aff
c64.STROUT("v1=$c433, v2=$2aff\n")
rrestore()
compare()
rsave()
v1=$aabb
v2=$aabb
c64.STROUT("v1 = v2 = aabb\n")
rrestore()
compare()
rsave()
v1=$aa00
v2=$aa00
c64.STROUT("v1 = v2 = aa00\n")
rrestore()
compare()
rsave()
v1=$aa
v2=$aa
c64.STROUT("v1 = v2 = aa\n")
rrestore()
compare()
sub compare() {
rsave()
c64.STROUT(" == != < > <= >=\n")
rrestore()
if v1==v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1!=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
return
sub compare() {
c64.STROUT(" == != < > <= >=\n")
if v1==v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1!=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
c64.CHROUT('\n')
}

View File

@ -9,22 +9,11 @@
word v2
ubyte cr
; done:
; ubyte all 6 comparisons
; byte all 6 comparisons
; uword all 6 comparisons
; word all 6 comparisons
; check stack usage:
rsave()
c64.STROUT("signed word ")
rrestore()
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT(' ')
rrestore()
cr=v1==v2
cr=v1==v2
@ -51,191 +40,128 @@
cr=v1>=v2
cr=v1>=v2
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
rrestore()
; comparisons:
rsave()
v1=20
v2=$00aa
c64.STROUT("v1=20, v2=$00aa\n")
rrestore()
compare()
rsave()
v1=20
v2=$7a00
c64.STROUT("v1=20, v2=$7a00\n")
rrestore()
compare()
rsave()
v1=$7400
v2=$22
c64.STROUT("v1=$7400, v2=$22\n")
rrestore()
compare()
rsave()
v1=$7400
v2=$2a00
c64.STROUT("v1=$7400, v2=$2a00\n")
rrestore()
compare()
rsave()
v1=$7433
v2=$2a00
c64.STROUT("v1=$7433, v2=$2a00\n")
rrestore()
compare()
rsave()
v1=$7433
v2=$2aff
c64.STROUT("v1=$7433, v2=$2aff\n")
rrestore()
compare()
; with negative numbers:
rsave()
v1=-512
v2=$00aa
c64.STROUT("v1=-512, v2=$00aa\n")
rrestore()
compare()
rsave()
v1=-512
v2=$7a00
c64.STROUT("v1=-512, v2=$7a00\n")
rrestore()
compare()
rsave()
v1=$7400
v2=-512
c64.STROUT("v1=$7400, v2=-512\n")
rrestore()
compare()
rsave()
v1=-20000
v2=-1000
c64.STROUT("v1=-20000, v2=-1000\n")
rrestore()
compare()
rsave()
v1=-1000
v2=-20000
c64.STROUT("v1=-1000, v2=-20000\n")
rrestore()
compare()
rsave()
v1=-1
v2=32767
c64.STROUT("v1=-1, v2=32767\n")
rrestore()
compare()
rsave()
v1=32767
v2=-1
c64.STROUT("v1=32767, v2=-1\n")
rrestore()
compare()
rsave()
v1=$7abb
v2=$7abb
c64.STROUT("v1 = v2 = 7abb\n")
rrestore()
compare()
rsave()
v1=$7a00
v2=$7a00
c64.STROUT("v1 = v2 = 7a00\n")
rrestore()
compare()
rsave()
v1=$aa
v2=$aa
c64.STROUT("v1 = v2 = aa\n")
rrestore()
compare()
sub compare() {
rsave()
c64.STROUT(" == != < > <= >=\n")
rrestore()
if v1==v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1!=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
return
sub compare() {
c64.STROUT(" == != < > <= >=\n")
if v1==v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1!=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
c64.CHROUT('\n')
}

View File

@ -9,17 +9,15 @@ sub start() {
c64.EXTCOL = 5
c64.BGCOL0 = 0
c64.COLOR = 1
c64.VMCSB = %10111
c64.VMCSB |= 2
; use kernel routine to write text (sorry, loops don't work in asm yet)
c64.CHROUT('H')
c64.CHROUT('e')
c64.CHROUT('l')
c64.CHROUT('l')
c64.CHROUT('o')
c64.CHROUT('!')
c64.CHROUT('\n')
; use kernel routine to write text
c64.STROUT("Hello!\n")
str question = "How are you?\n"
for ubyte c in 0 to len(question) {
c64.CHROUT(question[c])
}
return
}

View File

@ -41,11 +41,9 @@ ask_guess:
c64scr.input_chars(guessstr)
c64.CHROUT('\n')
freadstr_arg = guessstr
rsave()
c64.FREADSTR(Y)
A, Y = c64flt.GETADRAY()
guess=A
rrestore()
c64.EXTCOL=guess ; @debug
c64.BGCOL0=secretnumber ;@debug
if(guess==secretnumber) { ; @todo equal_b doesn't work

View File

@ -1,28 +1,20 @@
%import c64utils
%import mathlib
%option enable_floats
~ main {
sub start() {
uword v1
uword v2
float v1
float v2
ubyte cr
; done:
; ubyte all 6 comparisons
; byte all 6 comparisons
; check stack usage:
rsave()
c64.STROUT("unsigned word ")
rrestore()
rsave()
c64.STROUT("floating point ")
c64scr.print_byte_decimal(X)
c64.CHROUT(' ')
rrestore()
cr=v1==v2
cr=v1==v2
@ -49,144 +41,81 @@
cr=v1>=v2
cr=v1>=v2
rsave()
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
rrestore()
; comparisons:
rsave()
v1=20
v2=$00aa
c64.STROUT("v1=20, v2=$00aa\n")
rrestore()
v2=666.66
c64.STROUT("v1=20, v2=666.66\n")
compare()
rsave()
v1=20
v2=$ea00
c64.STROUT("v1=20, v2=$ea00\n")
rrestore()
v1=-20
v2=666.66
c64.STROUT("v1=-20, v2=666.66\n")
compare()
rsave()
v1=$c400
v2=$22
c64.STROUT("v1=$c400, v2=$22\n")
rrestore()
v1=666.66
v2=555.55
c64.STROUT("v1=666.66, v2=555.55\n")
compare()
rsave()
v1=$c400
v2=$2a00
c64.STROUT("v1=$c400, v2=$2a00\n")
rrestore()
v1=3.1415
v2=-3.1415
c64.STROUT("v1 = 3.1415, v2 = -3.1415\n")
compare()
rsave()
v1=$c433
v2=$2a00
c64.STROUT("v1=$c433, v2=$2a00\n")
rrestore()
v1=3.1415
v2=3.1415
c64.STROUT("v1 = v2 = 3.1415\n")
compare()
rsave()
v1=$c433
v2=$2aff
c64.STROUT("v1=$c433, v2=$2aff\n")
rrestore()
v1=0
v2=0
c64.STROUT("v1 = v2 = 0\n")
compare()
; rsave()
; v1=$aabb
; v2=$aabb
; c64.STROUT("v1 = v2 = aabb\n")
; rrestore()
; compare()
;
; rsave()
; v1=$aa00
; v2=$aa00
; c64.STROUT("v1 = v2 = aa00\n")
; rrestore()
; compare()
;
; rsave()
; v1=$aa
; v2=$aa
; c64.STROUT("v1 = v2 = aa\n")
; rrestore()
; compare()
sub compare() {
rsave()
c64.STROUT(" == != < > <= >=\n")
rrestore()
if v1==v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1!=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1<=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
if v1>=v2 {
rsave()
c64.STROUT(" Q ")
rrestore()
} else {
rsave()
c64.STROUT(" . ")
rrestore()
}
c64scr.print_byte_decimal(X)
c64.CHROUT('\n')
return
sub compare() {
c64.STROUT(" == != < > <= >=\n")
if v1==v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1!=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1<=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
if v1>=v2
c64.STROUT(" Q ")
else
c64.STROUT(" . ")
c64.CHROUT('\n')
}
}
}

View File

@ -763,10 +763,14 @@ private class StatementTranslator(private val prog: IntermediateProgram,
private fun translateSubroutineCall(subroutine: Subroutine, arguments: List<IExpression>, callPosition: Position) {
// evaluate the arguments and assign them into the subroutine's argument variables.
var restoreX = Register.X in subroutine.asmClobbers
if(subroutine.asmParameterRegisters.isNotEmpty()) {
if(subroutine.parameters.size!=subroutine.asmParameterRegisters.size)
throw CompilerException("no support for mix of register and non-register subroutine arguments")
if(restoreX)
prog.instr(Opcode.RSAVEX)
// only register arguments (or status-flag bits)
var carryParam: Boolean? = null
for(arg in arguments.zip(subroutine.asmParameterRegisters)) {
@ -783,7 +787,10 @@ private class StatementTranslator(private val prog: IntermediateProgram,
translate(assign)
}
X -> {
// TODO: save X on stack & restore after call
if(!restoreX) {
prog.instr(Opcode.RSAVEX)
restoreX = true
}
val assign = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, arg.first, callPosition)
assign.linkParents(arguments[0].parent)
translate(assign)
@ -794,7 +801,10 @@ private class StatementTranslator(private val prog: IntermediateProgram,
translate(assign)
}
AX -> {
// TODO: save X on stack & restore after call
if(!restoreX) {
prog.instr(Opcode.RSAVEX)
restoreX = true
}
val valueA: IExpression
val valueX: IExpression
val paramDt = arg.first.resultingDatatype(namespace, heap)
@ -847,7 +857,10 @@ private class StatementTranslator(private val prog: IntermediateProgram,
}
}
XY -> {
// TODO: save X on stack & restore after call
if(!restoreX) {
prog.instr(Opcode.RSAVEX)
restoreX = true
}
val valueX: IExpression
val valueY: IExpression
val paramDt = arg.first.resultingDatatype(namespace, heap)
@ -882,7 +895,6 @@ private class StatementTranslator(private val prog: IntermediateProgram,
true -> prog.instr(Opcode.SEC)
false -> prog.instr(Opcode.CLC)
}
} else {
// only regular (non-register) arguments
for (arg in arguments.zip(subroutine.parameters)) {
@ -892,6 +904,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
}
}
prog.instr(Opcode.CALL, callLabel = subroutine.scopedname)
if(restoreX)
prog.instr(Opcode.RRESTOREX)
}
private fun translateBinaryOperator(operator: String, dt: DataType) {

View File

@ -219,7 +219,9 @@ enum class Opcode {
SEI, // set irq-disable status flag
CLI, // clear irq-disable status flag
RSAVE, // save all internal registers and status flags
RSAVEX, // save just X (the evaluation stack pointer)
RRESTORE, // restore all internal registers and status flags
RRESTOREX, // restore just X (the evaluation stack pointer)
NOP, // do nothing
BREAKPOINT, // breakpoint
TERMINATE, // end the program

View File

@ -424,6 +424,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// restore all registers and cpu status flag
" pla | tay | pla | tax | pla | plp"
}
Opcode.RSAVEX -> " stx ${C64Zeropage.SCRATCH_REG_X}"
Opcode.RRESTOREX -> " ldx ${C64Zeropage.SCRATCH_REG_X}"
Opcode.DISCARD_BYTE -> " inx"
Opcode.DISCARD_WORD -> " inx"
Opcode.DISCARD_FLOAT -> " inx | inx | inx"

View File

@ -1377,6 +1377,8 @@ class StackVm(private var traceOutputFile: String?) {
P_carry = evalstack.pop().asBooleanValue
P_irqd = evalstack.pop().asBooleanValue
}
Opcode.RSAVEX -> evalstack.push(variables["X"])
Opcode.RRESTOREX -> variables["X"] = evalstack.pop()
Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code")
Opcode.PUSH_ADDR_HEAPVAR -> {
val heapId = variables[ins.callLabel]!!.heapId

View File

@ -650,6 +650,9 @@ rsave()
Saves the CPU registers and the status flags.
You can now more or less 'safely' use the registers directly, until you
restore them again so the generated code can carry on normally.
Note: it's not needed to rsave() before an asm subroutine that clobbers the X register
(which is used as the internal evaluation stack pointer).
The compiler will take care of this situation automatically.
rrestore()
Restores the CPU registers and the status flags from previously saved values.