2020-08-13 04:16:30 +00:00
|
|
|
package com.htmlism.mos6502.dsl
|
|
|
|
|
|
|
|
import scala.collection.mutable.ListBuffer
|
2020-08-14 20:54:29 +00:00
|
|
|
import cats.implicits._
|
|
|
|
import com.htmlism._
|
2020-08-13 04:16:30 +00:00
|
|
|
|
|
|
|
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:42:21 +00:00
|
|
|
// first color example
|
|
|
|
withAssemblyContext { implicit ctx =>
|
2020-08-14 02:41:22 +00:00
|
|
|
val scr =
|
|
|
|
0x0200.indexed
|
|
|
|
|
|
|
|
scr(0).write[Color](Color.White)
|
|
|
|
scr(1).write[Color](Color.Green)
|
|
|
|
scr(2).write[Color](Color.Orange)
|
2020-08-13 04:42:21 +00:00
|
|
|
}
|
|
|
|
|
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)
|
2020-08-14 02:41:22 +00:00
|
|
|
|
|
|
|
def indexed: IndexedAddressCollection =
|
|
|
|
IndexedAddressCollection(n)
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
object registers {
|
|
|
|
sealed trait Register
|
|
|
|
|
|
|
|
sealed trait DestinationA
|
|
|
|
|
|
|
|
case object A extends Register {
|
2020-08-14 20:54:29 +00:00
|
|
|
def add[A](x: A)(implicit ctx: AssemblyContext, ev: Operand[A]): Unit =
|
2020-08-15 03:06:09 +00:00
|
|
|
ev.operandType match {
|
|
|
|
case ValueLiteral =>
|
|
|
|
ctx.push(ADC, x, s"add LITERAL to a")
|
|
|
|
|
|
|
|
case MemoryLocation =>
|
|
|
|
ctx.push(ADC, x, s"add ADDR to a")
|
|
|
|
}
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case object X extends Register with DestinationA {
|
2020-08-14 20:54:29 +00:00
|
|
|
def incr(implicit ctx: AssemblyContext): Unit =
|
|
|
|
ctx.push(INX, "incr x")
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case object Y extends Register with DestinationA
|
|
|
|
}
|
|
|
|
|
|
|
|
class CPU {
|
|
|
|
def A: registers.A.type =
|
|
|
|
registers.A
|
|
|
|
|
2020-08-14 21:13:55 +00:00
|
|
|
def A_=[A](x: A)(implicit ctx: AssemblyContext, ev: Operand[A]): Unit =
|
2020-08-15 02:02:34 +00:00
|
|
|
ctx.push(LDA, x, "set A to value " + ev.toAddressLiteral(x))
|
2020-08-13 04:42:21 +00:00
|
|
|
|
2020-08-13 04:16:30 +00:00
|
|
|
def A_=(reg: registers.DestinationA)(implicit ctx: AssemblyContext): Unit =
|
2020-08-14 20:54:29 +00:00
|
|
|
reg match {
|
|
|
|
case registers.X =>
|
|
|
|
ctx.push(TXA)
|
|
|
|
case registers.Y =>
|
|
|
|
ctx.push(TYA)
|
|
|
|
}
|
2020-08-13 04:16:30 +00:00
|
|
|
|
|
|
|
def X: registers.X.type =
|
|
|
|
registers.X
|
|
|
|
|
2020-08-14 20:54:29 +00:00
|
|
|
def X_=(reg: registers.A.type)(implicit ctx: AssemblyContext): Unit =
|
|
|
|
ctx.push(TAX, s"set x to register $reg")
|
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 =
|
2020-08-14 20:54:29 +00:00
|
|
|
ctx.push(TAY, s"set x to register $reg")
|
2020-08-13 04:16:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class AssemblyContext {
|
2020-08-14 20:54:29 +00:00
|
|
|
val xs: ListBuffer[Statement] =
|
2020-08-13 04:16:30 +00:00
|
|
|
ListBuffer()
|
|
|
|
|
2020-08-14 20:54:29 +00:00
|
|
|
def push(instruction: Instruction): Unit =
|
|
|
|
xs.append(UnaryInstruction(instruction, None))
|
|
|
|
|
|
|
|
def push(instruction: Instruction, s: String): Unit =
|
|
|
|
xs.append(UnaryInstruction(instruction, s.some))
|
2020-08-13 04:30:00 +00:00
|
|
|
|
2020-08-14 20:54:29 +00:00
|
|
|
def push[A : Operand](instruction: Instruction, x: A): Unit =
|
|
|
|
xs.append(InstructionWithOperand(instruction, x, None))
|
2020-08-13 04:30:00 +00:00
|
|
|
|
2020-08-14 20:54:29 +00:00
|
|
|
def push[A : Operand](instruction: Instruction, x: A, s: String): Unit =
|
|
|
|
xs.append(InstructionWithOperand(instruction, x: A, s.some))
|
2020-08-13 04:16:30 +00:00
|
|
|
|
2020-08-13 04:30:00 +00:00
|
|
|
def printOut(): Unit = {
|
2020-08-14 21:08:59 +00:00
|
|
|
xs
|
|
|
|
.map(_.toAsm)
|
|
|
|
.foreach(println)
|
2020-08-13 04:30:00 +00:00
|
|
|
}
|
2020-08-14 20:54:29 +00:00
|
|
|
}
|