1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-12 06:29:34 +00:00

Interrupt functions in assembly should not have prologue (fixes #62)

This commit is contained in:
Karol Stasiak 2020-09-09 01:46:34 +02:00
parent 75c8ac19e1
commit 615a0d7dc1
5 changed files with 49 additions and 2 deletions

View File

@ -37,7 +37,7 @@ object MosCompiler extends AbstractCompiler[AssemblyLine] {
List(AssemblyLine.absolute(LDA, ctx.env.get[ThingInMemory]("__sp")), AssemblyLine.implied(PHA))
} else Nil)
val prefix = storeParamsFromRegisters ++ (if (ctx.function.interrupt) {
val prefix = storeParamsFromRegisters ++ (if (ctx.function.interrupt && !ctx.function.inAssembly) {
if (ctx.options.flag(CompilationFlag.EmitNative65816Opcodes)) {
if (zpRegisterSize > 0) {

View File

@ -68,7 +68,7 @@ object Z80Compiler extends AbstractCompiler[ZLine] {
def preserveRegisters(ctx: CompilationContext): List[ZLine] = {
import millfork.assembly.z80.ZOpcode._
import ZRegister._
if (ctx.function.interrupt) {
if (ctx.function.interrupt && !ctx.function.inAssembly) {
if (ctx.options.flag(CompilationFlag.EmitZ80Opcodes)) {
if (ctx.options.flag(CompilationFlag.UseShadowRegistersForInterrupts)) {
List(

View File

@ -1378,6 +1378,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
hasElidedReturnVariable = hasElidedReturnVariable,
interrupt = stmt.interrupt,
kernalInterrupt = stmt.kernalInterrupt,
inAssembly = stmt.assembly,
reentrant = stmt.reentrant,
isConstPure = stmt.constPure,
position = stmt.position,

View File

@ -481,6 +481,7 @@ case class NormalFunction(name: String,
hasElidedReturnVariable: Boolean,
interrupt: Boolean,
kernalInterrupt: Boolean,
inAssembly: Boolean,
isConstPure: Boolean,
reentrant: Boolean,
position: Option[Position],

View File

@ -460,4 +460,49 @@ class AssemblySuite extends FunSuite with Matchers with AppendedClues {
m.readByte(0xc001) should equal(1)
m.readByte(0xc002) should equal(2)
}
test("Interrupt functions in assembly should not have prologue (6502)") {
val m = EmuUnoptimizedRun(
"""
|byte output @$c000
|noinline interrupt asm void i() {
| nop
| rti
|}
|void main() {
| output = pointer(i.addr)[0]
|}
|""".stripMargin)
m.readByte(0xc000) should equal(0xea)
}
test("Interrupt functions in assembly should not have prologue (Z80)") {
val m = EmuUnoptimizedZ80Run(
"""
|byte output @$c000
|noinline interrupt asm void i() {
| nop
| reti
|}
|void main() {
| output = pointer(i.addr)[0]
|}
|""".stripMargin)
m.readByte(0xc000) should equal(0)
}
test("Interrupt functions in assembly should not have prologue (M6809)") {
val m = EmuUnoptimizedM6809Run(
"""
|byte output @$c000
|noinline interrupt asm void i() {
| nop
| rti
|}
|void main() {
| output = pointer(i.addr)[0]
|}
|""".stripMargin)
m.readByte(0xc000) should equal(0x12)
}
}