2020-08-13 04:16:30 +00:00
|
|
|
package com.htmlism.mos6502.dsl
|
|
|
|
|
|
|
|
import scala.collection.mutable.ListBuffer
|
|
|
|
|
|
|
|
object DslDemo extends App {
|
|
|
|
val cpu =
|
|
|
|
new CPU
|
|
|
|
|
|
|
|
import registers.{A, X}
|
|
|
|
|
|
|
|
// address demonstration
|
2020-08-13 04:21:15 +00:00
|
|
|
withAssemblyContext { implicit ctx =>
|
2020-08-13 04:16:30 +00:00
|
|
|
val payloadLocation =
|
|
|
|
0x01.z
|
|
|
|
|
|
|
|
cpu.A = 0x40
|
|
|
|
|
|
|
|
A.add(payloadLocation)
|
|
|
|
}
|
|
|
|
|
|
|
|
// a becomes others
|
2020-08-13 04:21:15 +00:00
|
|
|
withAssemblyContext { implicit ctx =>
|
2020-08-13 04:16:30 +00:00
|
|
|
cpu.A = cpu.X
|
|
|
|
cpu.A = cpu.Y
|
|
|
|
}
|
|
|
|
|
|
|
|
// demonstrate first example
|
2020-08-13 04:21:15 +00:00
|
|
|
withAssemblyContext { implicit ctx =>
|
2020-08-13 04:16:30 +00:00
|
|
|
cpu.A = 0xC0
|
|
|
|
|
|
|
|
cpu.X = cpu.A
|
|
|
|
|
|
|
|
X.incr
|
|
|
|
|
|
|
|
A.add(0xc4)
|
|
|
|
}
|
|
|
|
|
2020-08-13 04:21:15 +00:00
|
|
|
def withAssemblyContext(f: AssemblyContext => Unit): Unit = {
|
|
|
|
val ctx: AssemblyContext =
|
|
|
|
new AssemblyContext
|
|
|
|
|
|
|
|
f(ctx)
|
2020-08-13 04:16:30 +00:00
|
|
|
|
|
|
|
ctx.printOut()
|
|
|
|
println()
|
|
|
|
println()
|
|
|
|
}
|
|
|
|
|
|
|
|
implicit class AddressOps(n: Int) {
|
|
|
|
def z: ZeroAddress =
|
|
|
|
ZeroAddress(n)
|
|
|
|
|
|
|
|
def addr: GlobalAddress =
|
|
|
|
GlobalAddress(n)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
object registers {
|
|
|
|
sealed trait Register
|
|
|
|
|
|
|
|
sealed trait DestinationA
|
|
|
|
|
|
|
|
case object A extends Register {
|
|
|
|
def add(n: Int)(implicit ctx: AssemblyContext): Unit = {
|
|
|
|
ctx.describe(s"add $n to a")
|
2020-08-13 04:30:00 +00:00
|
|
|
ctx.pushAsm(f"ADC #$$$n%h")
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def add(n: ZeroAddress)(implicit ctx: AssemblyContext): Unit = {
|
|
|
|
ctx.describe(s"add to A value from zero page $n")
|
2020-08-13 04:30:00 +00:00
|
|
|
ctx.pushAsm(f"ADC $$$n%h")
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case object X extends Register with DestinationA {
|
|
|
|
def incr(implicit ctx: AssemblyContext): Unit = {
|
|
|
|
ctx.describe("incr x")
|
2020-08-13 04:30:00 +00:00
|
|
|
ctx.pushAsm("INX")
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case object Y extends Register with DestinationA
|
|
|
|
}
|
|
|
|
|
|
|
|
class CPU {
|
|
|
|
def A: registers.A.type =
|
|
|
|
registers.A
|
|
|
|
|
|
|
|
def A_=(n: Int)(implicit ctx: AssemblyContext): Unit = {
|
|
|
|
ctx.describe(s"set a to value $n")
|
2020-08-13 04:30:00 +00:00
|
|
|
ctx.pushAsm(f"LDA #$$$n%h")
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def A_=(reg: registers.DestinationA)(implicit ctx: AssemblyContext): Unit =
|
|
|
|
ctx.describe(s"set a to register $reg")
|
|
|
|
|
|
|
|
def X: registers.X.type =
|
|
|
|
registers.X
|
|
|
|
|
2020-08-13 04:30:00 +00:00
|
|
|
def X_=(reg: registers.A.type)(implicit ctx: AssemblyContext): Unit = {
|
2020-08-13 04:16:30 +00:00
|
|
|
ctx.describe(s"set x to register $reg")
|
2020-08-13 04:30:00 +00:00
|
|
|
ctx.pushAsm("TAX")
|
|
|
|
}
|
2020-08-13 04:16:30 +00:00
|
|
|
|
|
|
|
def Y: registers.Y.type =
|
|
|
|
registers.Y
|
|
|
|
|
|
|
|
def Y_=(reg: registers.A.type)(implicit ctx: AssemblyContext): Unit =
|
|
|
|
ctx.describe(s"set y to register $reg")
|
|
|
|
}
|
|
|
|
|
|
|
|
class AssemblyContext {
|
|
|
|
val xs: ListBuffer[String] =
|
|
|
|
ListBuffer()
|
|
|
|
|
2020-08-13 04:30:00 +00:00
|
|
|
val asm: ListBuffer[String] =
|
|
|
|
ListBuffer()
|
|
|
|
|
|
|
|
def pushAsm(s: String): Unit =
|
|
|
|
asm.append(s)
|
|
|
|
|
2020-08-13 04:16:30 +00:00
|
|
|
def describe(s: String): Unit =
|
|
|
|
xs.append(s)
|
|
|
|
|
2020-08-13 04:30:00 +00:00
|
|
|
def printOut(): Unit = {
|
|
|
|
asm.foreach(println)
|
2020-08-13 04:16:30 +00:00
|
|
|
xs.foreach(println)
|
2020-08-13 04:30:00 +00:00
|
|
|
}
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|