mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-22 08:32:29 +00:00
6502: Use zeropage addressing mode when accessing fixed zeropage locations
This commit is contained in:
parent
cbe6d03e60
commit
3736b5ae56
@ -339,6 +339,21 @@ object OpcodeClasses {
|
||||
val DiscardsD = OverwritesD
|
||||
val DiscardsI = NoopDiscardsFlags | OverwritesI
|
||||
|
||||
val SupportsZeropage = Set(
|
||||
LDA, LDX, LDY, LAX, // LDZ doesn't!
|
||||
LDA_W, LDX_W, LDY_W,
|
||||
STA, STX, STY, SAX, STZ,
|
||||
STA_W, LDX_W, LDY_W,
|
||||
BIT,
|
||||
CPX, CPY, CPZ,
|
||||
ADC, SBC, CMP, AND, ORA, EOR,
|
||||
ADC_W, SBC_W, CMP_W, AND_W, ORA_W, EOR_W,
|
||||
INC, DEC, ROL, ROR, ASL, LSR,
|
||||
INC_W, DEC_W, ROL_W, ROR_W, ASL_W, LSR_W,
|
||||
ISC, DCP, RLA, RRA, SLO, SRE,
|
||||
TSB, TRB,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
object AssemblyLine {
|
||||
|
@ -156,6 +156,7 @@ object MosStatementCompiler extends AbstractStatementCompiler[AssemblyLine] {
|
||||
}
|
||||
val actualAddrMode = a match {
|
||||
case Absolute if OpcodeClasses.ShortBranching(o) => Relative
|
||||
case Absolute if OpcodeClasses.SupportsZeropage(o) && c.fitsProvablyIntoByte => ZeroPage
|
||||
case IndexedX if o == JMP => AbsoluteIndexedX
|
||||
case Indirect if o != JMP => IndexedZ
|
||||
case _ => a
|
||||
|
4
src/main/scala/millfork/env/Constant.scala
vendored
4
src/main/scala/millfork/env/Constant.scala
vendored
@ -26,6 +26,7 @@ sealed trait Constant {
|
||||
case NumericConstant(0, _) => true
|
||||
case _ => false
|
||||
}
|
||||
def fitsProvablyIntoByte: Boolean = false
|
||||
|
||||
def asl(i: Constant): Constant = i match {
|
||||
case NumericConstant(sa, _) => asl(sa.toInt)
|
||||
@ -100,6 +101,7 @@ case class AssertByte(c: Constant) extends Constant {
|
||||
override def isProvablyZero: Boolean = c.isProvablyZero
|
||||
override def isProvably(i: Int): Boolean = c.isProvably(i)
|
||||
override def isProvablyNonnegative: Boolean = c.isProvablyNonnegative
|
||||
override def fitsProvablyIntoByte: Boolean = true
|
||||
|
||||
override def requiredSize: Int = 1
|
||||
|
||||
@ -132,6 +134,7 @@ case class NumericConstant(value: Long, requiredSize: Int) extends Constant {
|
||||
override def isProvablyZero: Boolean = value == 0
|
||||
override def isProvably(i: Int): Boolean = value == i
|
||||
override def isProvablyNonnegative: Boolean = value >= 0
|
||||
override def fitsProvablyIntoByte: Boolean = requiredSize == 1
|
||||
|
||||
override def isLowestByteAlwaysEqual(i: Int) : Boolean = (value & 0xff) == (i&0xff)
|
||||
|
||||
@ -211,6 +214,7 @@ case class SubbyteConstant(base: Constant, index: Int) extends Constant {
|
||||
override def requiredSize = 1
|
||||
|
||||
override def isProvablyNonnegative: Boolean = true
|
||||
override def fitsProvablyIntoByte: Boolean = true
|
||||
|
||||
override def toString: String = index match {
|
||||
case 0 => s"lo($base)"
|
||||
|
@ -1,11 +1,11 @@
|
||||
package millfork.test
|
||||
import millfork.test.emu.EmuBenchmarkRun
|
||||
import org.scalatest.{FunSuite, Matchers}
|
||||
import millfork.test.emu.{EmuBenchmarkRun, EmuOptimizedCmosRun, EmuOptimizedRun}
|
||||
import org.scalatest.{AppendedClues, FunSuite, Matchers}
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
class AssemblySuite extends FunSuite with Matchers {
|
||||
class AssemblySuite extends FunSuite with Matchers with AppendedClues {
|
||||
|
||||
test("Inline assembly") {
|
||||
EmuBenchmarkRun(
|
||||
@ -163,4 +163,52 @@ class AssemblySuite extends FunSuite with Matchers {
|
||||
| }
|
||||
""".stripMargin)(_.readByte(0xc000) should equal(10))
|
||||
}
|
||||
|
||||
test("Correctly use zeropage for CPU port on C64") {
|
||||
val m = EmuOptimizedRun(
|
||||
"""
|
||||
| byte port @1
|
||||
| const byte port_addr = 1
|
||||
| byte port_alt @port_addr
|
||||
| void main () {
|
||||
| a()
|
||||
| b()
|
||||
| c()
|
||||
| d()
|
||||
| e()
|
||||
| f()
|
||||
| }
|
||||
| noinline void a() {
|
||||
| port = 1
|
||||
| }
|
||||
| noinline void b() {
|
||||
| port_alt = 2
|
||||
| }
|
||||
| noinline asm void c() {
|
||||
| lda #3
|
||||
| sta 1
|
||||
| rts
|
||||
| }
|
||||
| noinline asm void d() {
|
||||
| lda #4
|
||||
| sta port
|
||||
| rts
|
||||
| }
|
||||
| noinline asm void e() {
|
||||
| lda #5
|
||||
| sta port_addr
|
||||
| rts
|
||||
| }
|
||||
| noinline asm void f() {
|
||||
| lda #6
|
||||
| sta port_alt
|
||||
| rts
|
||||
| }
|
||||
""".stripMargin)
|
||||
for (addr <- 0x0200 to 0x02ff) {
|
||||
m.readable(addr) = true
|
||||
m.readByte(addr) should not equal 0x8d withClue f"STA abs at $addr%04x"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user