mirror of
https://github.com/mcanlas/6502-opcodes.git
synced 2025-01-21 17:32:13 +00:00
just checking in
This commit is contained in:
parent
fcdeb9ffe2
commit
e250dfb67e
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
*.class
|
||||
*.log
|
||||
.idea
|
||||
target
|
||||
|
3
build.sbt
Normal file
3
build.sbt
Normal file
@ -0,0 +1,3 @@
|
||||
initialCommands in console := "import com.htmlism._"
|
||||
|
||||
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
|
1
project/build.properties
Normal file
1
project/build.properties
Normal file
@ -0,0 +1 @@
|
||||
sbt.version=1.0.3
|
15
src/main/scala/com/htmlism/AddressingMode.scala
Normal file
15
src/main/scala/com/htmlism/AddressingMode.scala
Normal file
@ -0,0 +1,15 @@
|
||||
package com.htmlism
|
||||
|
||||
sealed trait AddressingMode
|
||||
|
||||
case object Immediate extends AddressingMode
|
||||
case object ZeroPage extends AddressingMode
|
||||
case object ZeroPageX extends AddressingMode
|
||||
case object Absolute extends AddressingMode
|
||||
case object AbsoluteX extends AddressingMode
|
||||
case object AbsoluteY extends AddressingMode
|
||||
case object IndirectX extends AddressingMode
|
||||
case object IndirectY extends AddressingMode
|
||||
case object Accumulator extends AddressingMode
|
||||
case object Implied extends AddressingMode
|
||||
case object NoMode extends AddressingMode
|
95
src/main/scala/com/htmlism/Instruction.scala
Normal file
95
src/main/scala/com/htmlism/Instruction.scala
Normal file
@ -0,0 +1,95 @@
|
||||
package com.htmlism
|
||||
|
||||
sealed trait Instruction { def theme: String; def color: String }
|
||||
|
||||
case object NoInstruction extends Instruction { def theme: String = "noop"; def color: String = "white" }
|
||||
|
||||
sealed trait Logical extends Instruction { def theme: String = "logical"; def color: String = "OliveDrab" }
|
||||
|
||||
case object AND extends Logical
|
||||
case object EOR extends Logical
|
||||
case object ORA extends Logical
|
||||
case object BIT extends Logical
|
||||
|
||||
sealed trait Arithmetic extends Instruction { def theme: String = "arithmetic"; def color: String = "CadetBlue" }
|
||||
|
||||
case object ADC extends Arithmetic
|
||||
case object SBC extends Arithmetic
|
||||
case object CMP extends Arithmetic
|
||||
case object CPX extends Arithmetic
|
||||
case object CPY extends Arithmetic
|
||||
|
||||
sealed trait Load extends Instruction { def theme: String = "load"; def color: String = "BurlyWood" }
|
||||
case object LDA extends Load
|
||||
case object LDX extends Load
|
||||
case object LDY extends Load
|
||||
|
||||
sealed trait Store extends Instruction { def theme: String = "store"; def color: String = "Bisque" }
|
||||
|
||||
case object STA extends Store
|
||||
case object STX extends Store
|
||||
case object STY extends Store
|
||||
|
||||
sealed trait Shift extends Instruction { def theme: String = "shift"; def color: String = "SlateBlue" }
|
||||
|
||||
case object ASL extends Shift
|
||||
case object LSR extends Shift
|
||||
case object ROL extends Shift
|
||||
case object ROR extends Shift
|
||||
|
||||
sealed trait Increment extends Instruction { def theme: String = "increment"; def color: String = "LightPink" }
|
||||
|
||||
case object INC extends Increment
|
||||
case object INX extends Increment
|
||||
case object INY extends Increment
|
||||
|
||||
sealed trait Decrement extends Instruction { def theme: String = "decrement"; def color: String = "Khaki" }
|
||||
|
||||
case object DEC extends Decrement
|
||||
case object DEX extends Decrement
|
||||
case object DEY extends Decrement
|
||||
|
||||
sealed trait Jump extends Instruction { def theme: String = "jump"; def color: String = "Salmon" }
|
||||
case object JMP extends Jump
|
||||
case object JSR extends Jump
|
||||
case object RTS extends Jump
|
||||
|
||||
sealed trait Branch extends Instruction { def theme: String = "branch"; def color: String = "DodgerBlue" }
|
||||
case object BCC extends Branch
|
||||
case object BCS extends Branch
|
||||
case object BEQ extends Branch
|
||||
case object BMI extends Branch
|
||||
case object BNE extends Branch
|
||||
case object BPL extends Branch
|
||||
case object BVC extends Branch
|
||||
case object BVS extends Branch
|
||||
|
||||
sealed trait System extends Instruction { def theme: String = "system"; def color: String = "Peru" }
|
||||
case object BRK extends System
|
||||
case object NOP extends System
|
||||
case object RTI extends System
|
||||
|
||||
sealed trait Stack extends Instruction { def theme: String = "stack"; def color: String = "Wheat" }
|
||||
case object TSX extends Stack
|
||||
case object TXS extends Stack
|
||||
case object PHA extends Stack
|
||||
case object PHP extends Stack
|
||||
case object PLA extends Stack
|
||||
case object PLP extends Stack
|
||||
|
||||
sealed trait Transfer extends Instruction { def theme: String = "transfer"; def color: String = "Teal" }
|
||||
case object TAX extends Transfer
|
||||
case object TAY extends Transfer
|
||||
case object TXA extends Transfer
|
||||
case object TYA extends Transfer
|
||||
|
||||
sealed trait Clear extends Instruction { def theme: String = "clear"; def color: String = "LightSteelBlue" }
|
||||
case object CLC extends Clear
|
||||
case object CLD extends Clear
|
||||
case object CLI extends Clear
|
||||
case object CLV extends Clear
|
||||
|
||||
sealed trait SetFlag extends Instruction { def theme: String = "set"; def color: String = "Thistle" }
|
||||
case object SEC extends SetFlag
|
||||
case object SED extends SetFlag
|
||||
case object SEI extends SetFlag
|
214
src/main/scala/com/htmlism/MatchOpcodes.scala
Normal file
214
src/main/scala/com/htmlism/MatchOpcodes.scala
Normal file
@ -0,0 +1,214 @@
|
||||
package com.htmlism
|
||||
|
||||
import java.io.PrintWriter
|
||||
|
||||
object MatchOpcodes {
|
||||
def paddedBinary(n: Int, width: Int) =
|
||||
String.format(s"%${width}s", Integer.toBinaryString(n)).replace(" ", "0")
|
||||
|
||||
def main(args: Array[String]): Unit =
|
||||
write(args(0))(doStuff)
|
||||
|
||||
def doStuff(out: PrintWriter): Unit = {
|
||||
val generated =
|
||||
(0 to 255)
|
||||
.map(n => n -> toOpcode(n))
|
||||
.collect { case (n, Some(x)) => (n, x) }
|
||||
.toMap
|
||||
|
||||
val injected =
|
||||
Map(
|
||||
0x10 -> BPL,
|
||||
0x30 -> BMI,
|
||||
0x50 -> BVC,
|
||||
0x70 -> BVS,
|
||||
0x90 -> BCC,
|
||||
0xB0 -> BCS,
|
||||
0xD0 -> BNE,
|
||||
0xF0 -> BEQ,
|
||||
|
||||
0x00 -> BRK,
|
||||
0x20 -> JSR,
|
||||
0x40 -> RTI,
|
||||
0x60 -> RTS,
|
||||
|
||||
0x08 -> PHP,
|
||||
0x28 -> PLP,
|
||||
0x48 -> PHA,
|
||||
0x68 -> PLA,
|
||||
0x88 -> DEY,
|
||||
0xA8 -> TAY,
|
||||
0xC8 -> INY,
|
||||
0xE8 -> INX,
|
||||
|
||||
0x18 -> CLC,
|
||||
0x38 -> SEC,
|
||||
0x58 -> CLI,
|
||||
0x78 -> SEI,
|
||||
0x98 -> TYA,
|
||||
0xB8 -> CLV,
|
||||
0xD8 -> CLD,
|
||||
0xF8 -> SED,
|
||||
|
||||
0x8A -> TXA,
|
||||
0x9A -> TXS,
|
||||
0xAA -> TAX,
|
||||
0xBA -> TSX,
|
||||
0xCA -> DEX,
|
||||
0xEA -> NOP
|
||||
).mapValues(x => x -> Implied)
|
||||
|
||||
val lookup = generated ++ injected
|
||||
|
||||
out.print("<table>")
|
||||
|
||||
// print headers
|
||||
out.print("<tr>")
|
||||
out.print("<th/>")
|
||||
|
||||
for (c <- wideColumns)
|
||||
out.print(s"<th>${paddedBinary(c, 5)}</th>")
|
||||
|
||||
out.print("</tr>")
|
||||
|
||||
|
||||
for (r <- wideRows) {
|
||||
out.print("<tr>")
|
||||
|
||||
// left header
|
||||
out.print(s"<th>${paddedBinary(r, 3)}</th>")
|
||||
|
||||
for (c <- wideColumns) {
|
||||
val fullInt = (r << 5) + c
|
||||
|
||||
lookup.get(fullInt) match {
|
||||
case Some((ints, mode)) =>
|
||||
val hex = f"$fullInt%2X"
|
||||
out.print(s"<th class=${'"' + ints.theme + '"'} style=${'"' + "background-color: " + ints.color + '"'}>$ints $mode<br>$hex</th>")
|
||||
|
||||
case None =>
|
||||
out.print(s"<td>UNDEF</td>")
|
||||
}
|
||||
}
|
||||
|
||||
out.print("</tr>")
|
||||
}
|
||||
|
||||
out.print("</table>")
|
||||
|
||||
quartile(out, 0, lookup)
|
||||
quartile(out, 1, lookup)
|
||||
quartile(out, 2, lookup)
|
||||
quartile(out, 3, lookup)
|
||||
}
|
||||
|
||||
def quartile(out: PrintWriter, n: Int, lookup: Map[Int, (Instruction, AddressingMode)]) = {
|
||||
out.print(s"<h2>${paddedBinary(n, 2)}</h2>")
|
||||
|
||||
out.print("<table>")
|
||||
|
||||
// print headers
|
||||
out.print("<tr>")
|
||||
out.print("<th/>")
|
||||
|
||||
val columns =
|
||||
for {
|
||||
y <- 0 to 1
|
||||
xx <- Seq(3, 1, 2, 0)
|
||||
} yield (xx << 1) + y
|
||||
|
||||
val rows =
|
||||
0 to 7
|
||||
|
||||
for (c <- columns)
|
||||
out.print(s"<th>${paddedBinary(c, 3)}</th>")
|
||||
|
||||
out.print("</tr>")
|
||||
|
||||
|
||||
for (r <- rows) {
|
||||
out.print("<tr>")
|
||||
|
||||
// left header
|
||||
out.print(s"<th>${paddedBinary(r, 3)}</th>")
|
||||
|
||||
for (c <- columns) {
|
||||
val fullInt = (r << (3 + 2)) + (c << 2) + n
|
||||
|
||||
lookup.get(fullInt) match {
|
||||
case Some((ints, mode)) =>
|
||||
val hex = f"$fullInt%2X"
|
||||
out.print(s"<th class=${'"' + ints.theme + '"'} style=${'"' + "background-color: " + ints.color + '"'}>$ints $mode<br>$hex</th>")
|
||||
|
||||
case None =>
|
||||
out.print(s"<td>UNDEF</td>")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out.print("</tr>")
|
||||
}
|
||||
|
||||
out.print("</table>")
|
||||
}
|
||||
|
||||
def wideColumns: Seq[Int] =
|
||||
for {
|
||||
cc <- 0 to 3
|
||||
y <- 0 to 1
|
||||
xx <- 0 to 3
|
||||
} yield (xx << 3) + (y << 2) + cc
|
||||
|
||||
def wideRows: Seq[Int] =
|
||||
0 to 7
|
||||
|
||||
private def write(file: String)(f: PrintWriter => Unit) = {
|
||||
val out = new PrintWriter(file)
|
||||
f(out)
|
||||
out.close()
|
||||
}
|
||||
|
||||
def toOpcode(n: Int): Option[(Instruction, AddressingMode)] = {
|
||||
val BitPattern = ThreeBits >> ThreeBits >> TwoBits
|
||||
|
||||
n match {
|
||||
case BitPattern(aaabbb, cc) =>
|
||||
cc match {
|
||||
case 0 => (c00 _).tupled(aaabbb)
|
||||
case 1 => (c01 _).tupled(aaabbb)
|
||||
case 2 => (c10 _).tupled(aaabbb)
|
||||
case 3 => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def c01(aaa: Int, bbb: Int): Option[(Instruction, AddressingMode)] = {
|
||||
val instruction =
|
||||
Seq(ORA, AND, EOR, ADC, STA, LDA, CMP, SBC)(aaa)
|
||||
|
||||
val addressingMode =
|
||||
Seq(IndirectX, ZeroPage, Immediate, Absolute, IndirectY, ZeroPageX, AbsoluteY, AbsoluteX)(bbb)
|
||||
|
||||
Some(instruction -> addressingMode)
|
||||
}
|
||||
|
||||
def c10(aaa: Int, bbb: Int): Option[(Instruction, AddressingMode)] = {
|
||||
val instruction =
|
||||
Seq(ASL, ROL, LSR, ROR, STX, LDX, DEC, INC)(aaa)
|
||||
|
||||
val addressingMode =
|
||||
Seq(Immediate, ZeroPage, Accumulator, Absolute, NoMode, ZeroPageX, NoMode, AbsoluteX)(bbb)
|
||||
|
||||
Some(instruction -> addressingMode)
|
||||
}
|
||||
|
||||
def c00(aaa: Int, bbb: Int): Option[(Instruction, AddressingMode)] = {
|
||||
val instruction =
|
||||
Seq(NoInstruction, BIT, JMP, JMP, STY, LDY, CPY, CPX)(aaa)
|
||||
|
||||
val addressingMode =
|
||||
Seq(Immediate, ZeroPage, NoMode, Absolute, NoMode, ZeroPageX, NoMode, AbsoluteX)(bbb)
|
||||
|
||||
Some(instruction -> addressingMode)
|
||||
}
|
||||
}
|
39
src/main/scala/com/htmlism/ShiftExtractor.scala
Normal file
39
src/main/scala/com/htmlism/ShiftExtractor.scala
Normal file
@ -0,0 +1,39 @@
|
||||
package com.htmlism
|
||||
|
||||
trait BitExtractor[A] {
|
||||
self =>
|
||||
|
||||
def length: Int
|
||||
|
||||
def unapply(n: Int): Option[A]
|
||||
|
||||
def >>[B](that: BitExtractor[B]): BitExtractor[(A, B)] =
|
||||
new BitExtractor[(A, B)] {
|
||||
def length: Int = self.length + that.length
|
||||
|
||||
def unapply(n: Int): Option[(A, B)] =
|
||||
for {
|
||||
b <- that.unapply(n)
|
||||
shifted = n >> that.length
|
||||
a <- self.unapply(shifted)
|
||||
} yield (a, b)
|
||||
}
|
||||
}
|
||||
|
||||
object AtomExtractor {
|
||||
def pow(ex: Int, acc: Int = 1): Int =
|
||||
if (ex == 0)
|
||||
acc
|
||||
else
|
||||
pow(ex - 1, acc * 2)
|
||||
}
|
||||
|
||||
abstract class PrimitiveBitExtractor(val length: Int) extends BitExtractor[Int] {
|
||||
private lazy val mask = AtomExtractor.pow(length) - 1
|
||||
|
||||
def unapply(n: Int): Option[Int] = Some(n & mask)
|
||||
}
|
||||
|
||||
object OneBit extends PrimitiveBitExtractor(1)
|
||||
object TwoBits extends PrimitiveBitExtractor(2)
|
||||
object ThreeBits extends PrimitiveBitExtractor(3)
|
7
src/test/scala/com/htmlism/BitMatchingSpec.scala
Normal file
7
src/test/scala/com/htmlism/BitMatchingSpec.scala
Normal file
@ -0,0 +1,7 @@
|
||||
package com.htmlism
|
||||
|
||||
import org.scalatest.FlatSpec
|
||||
|
||||
class BitMatchingSpec extends FlatSpec {
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user