mirror of https://github.com/KarolS/millfork.git
191 lines
4.3 KiB
Scala
191 lines
4.3 KiB
Scala
package millfork.assembly
|
|
|
|
import java.util.Locale
|
|
|
|
import millfork.error.ErrorReporting
|
|
import millfork.node.Position
|
|
|
|
object State extends Enumeration {
|
|
val A, X, Y, Z, D, C, N, V = Value
|
|
}
|
|
|
|
object Treatment extends Enumeration {
|
|
val Unchanged, Unsure, Changed, Cleared, Set = Value
|
|
|
|
implicit class OverriddenValue(val left: Value) extends AnyVal {
|
|
def ~(right: Treatment.Value): Treatment.Value = right match {
|
|
case Unchanged => left
|
|
case Cleared | Set => if (left == Unsure) Changed else right
|
|
case _ => right
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
object Opcode extends Enumeration {
|
|
val ADC, AND, ASL,
|
|
BIT, BNE, BEQ, BPL, BMI, BVS, BVC, BCC, BCS, BRK,
|
|
CMP, CPX, CPY, CLV, CLC, CLI, CLD,
|
|
DEC, DEX, DEY,
|
|
EOR,
|
|
INC, INX, INY,
|
|
JMP, JSR,
|
|
LDA, LDX, LDY, LSR,
|
|
NOP,
|
|
ORA,
|
|
PHA, PHP, PLA, PLP,
|
|
ROL, ROR, RTS, RTI,
|
|
SBC, SEC, SED, SEI, STA, STX, STY,
|
|
TAX, TAY, TXA, TXS, TSX, TYA,
|
|
|
|
LXA, XAA, ANC, ARR, ALR, SBX,
|
|
LAX, SAX, RLA, RRA, SLO, SRE, DCP, ISC,
|
|
TAS, LAS, SHX, SHY, AHX,
|
|
STZ, PHX, PHY, PLX, PLY,
|
|
BRA, TRB, TSB, STP, WAI,
|
|
DISCARD_AF, DISCARD_XF, DISCARD_YF,
|
|
LABEL = Value
|
|
|
|
def lookup(opcode: String, position: Option[Position]): Opcode.Value = opcode.toUpperCase(Locale.ROOT) match {
|
|
case "ADC" => ADC
|
|
case "AHX" => AHX
|
|
case "ALR" => ALR
|
|
case "ANC" => ANC
|
|
case "AND" => AND
|
|
case "ANE" => XAA
|
|
case "ARR" => ARR
|
|
case "ASL" => ASL
|
|
case "ASO" => SLO
|
|
case "AXA" => AHX
|
|
case "AXS" => SBX // TODO: could mean SAX
|
|
case "BCC" => BCC
|
|
case "BCS" => BCS
|
|
case "BEQ" => BEQ
|
|
case "BIT" => BIT
|
|
case "BMI" => BMI
|
|
case "BNE" => BNE
|
|
case "BPL" => BPL
|
|
case "BRA" => BRA
|
|
case "BRK" => BRK
|
|
case "BVC" => BVC
|
|
case "BVS" => BVS
|
|
case "CLC" => CLC
|
|
case "CLD" => CLD
|
|
case "CLI" => CLI
|
|
case "CLV" => CLV
|
|
case "CMP" => CMP
|
|
case "CPX" => CPX
|
|
case "CPY" => CPY
|
|
case "DCM" => DCP
|
|
case "DCP" => DCP
|
|
case "DEC" => DEC
|
|
case "DEX" => DEX
|
|
case "DEY" => DEY
|
|
case "EOR" => EOR
|
|
case "INC" => INC
|
|
case "INS" => ISC
|
|
case "INX" => INX
|
|
case "INY" => INY
|
|
case "ISC" => ISC
|
|
case "JMP" => JMP
|
|
case "JSR" => JSR
|
|
case "LAS" => LAS
|
|
case "LAX" => LAX
|
|
case "LDA" => LDA
|
|
case "LDX" => LDX
|
|
case "LDY" => LDY
|
|
case "LSE" => SRE
|
|
case "LSR" => LSR
|
|
case "LXA" => LXA
|
|
case "NOP" => NOP
|
|
case "OAL" => LXA
|
|
case "ORA" => ORA
|
|
case "PHA" => PHA
|
|
case "PHP" => PHP
|
|
case "PHX" => PHX
|
|
case "PHY" => PHY
|
|
case "PLA" => PLA
|
|
case "PLP" => PLP
|
|
case "PLX" => PLX
|
|
case "PLY" => PLY
|
|
case "RLA" => RLA
|
|
case "ROL" => ROL
|
|
case "ROR" => ROR
|
|
case "RRA" => RRA
|
|
case "RTI" => RTI
|
|
case "RTS" => RTS
|
|
case "SAX" => SAX // TODO: could mean SBX
|
|
case "SAY" => SHY
|
|
case "SBC" => SBC
|
|
case "SBX" => SBX
|
|
case "SEC" => SEC
|
|
case "SED" => SED
|
|
case "SEI" => SEI
|
|
case "SHX" => SHX
|
|
case "SHY" => SHY
|
|
case "SLO" => SLO
|
|
case "SRE" => SRE
|
|
case "STA" => STA
|
|
case "STP" => STP
|
|
case "STX" => STX
|
|
case "STY" => STY
|
|
case "STZ" => STZ
|
|
case "TAS" => TAS
|
|
case "TAX" => TAX
|
|
case "TAY" => TAY
|
|
case "TRB" => TRB
|
|
case "TSB" => TSB
|
|
case "TSX" => TSX
|
|
case "TXA" => TXA
|
|
case "TXS" => TXS
|
|
case "TYA" => TYA
|
|
case "WAI" => WAI
|
|
case "XAA" => XAA
|
|
case "XAS" => SHX
|
|
case _ =>
|
|
ErrorReporting.error(s"Invalid opcode `$opcode`", position)
|
|
LABEL
|
|
}
|
|
|
|
}
|
|
|
|
object AddrMode extends Enumeration {
|
|
val Implied,
|
|
Immediate,
|
|
Relative,
|
|
ZeroPage,
|
|
ZeroPageX,
|
|
ZeroPageY,
|
|
Absolute,
|
|
AbsoluteX,
|
|
AbsoluteY,
|
|
Indirect,
|
|
IndexedX,
|
|
IndexedY,
|
|
AbsoluteIndexedX,
|
|
ZeroPageIndirect,
|
|
Undecided,
|
|
DoesNotExist = Value
|
|
|
|
|
|
def argumentLength(a: AddrMode.Value): Int = a match {
|
|
case Absolute | AbsoluteX | AbsoluteY | Indirect =>
|
|
2
|
|
case _ =>
|
|
1
|
|
}
|
|
|
|
def addrModeToString(am: AddrMode.Value, argument: String): String = {
|
|
am match {
|
|
case Implied => ""
|
|
case Immediate => "#" + argument
|
|
case AbsoluteX | ZeroPageX => argument + ", X"
|
|
case AbsoluteY | ZeroPageY => argument + ", Y"
|
|
case IndexedX | AbsoluteIndexedX => "(" + argument + ", X)"
|
|
case IndexedY => "(" + argument + "), Y"
|
|
case Indirect | ZeroPageIndirect => "(" + argument + ")"
|
|
case _ => argument;
|
|
}
|
|
}
|
|
}
|