6502-opcodes/firepower-demo/src/main/scala/com/htmlism/firepower/demo/PrintThree.scala

92 lines
2.7 KiB
Scala
Raw Normal View History

2022-12-06 17:56:29 +00:00
package com.htmlism.firepower.demo
2022-12-06 19:58:20 +00:00
import scala.collection.immutable._
2022-12-06 17:56:29 +00:00
import scala.util.chaining._
import cats.syntax.all._
import com.htmlism.firepower.core.AsmBlock._
import com.htmlism.firepower.core._
object PrintThree:
2022-12-06 19:58:20 +00:00
case class Move[A: Definable](src: A, dest: String):
def defines: Option[ListMap[String, String]] =
implicitly[Definable[A]]
.table
.some
2022-12-06 18:43:48 +00:00
2022-12-06 19:30:35 +00:00
val program: List[Move[Easy6502.Color]] =
2022-12-06 17:56:29 +00:00
List(
2022-12-06 19:30:35 +00:00
Move(Easy6502.Color.White, "$0200"),
Move(Easy6502.Color.Green, "$0201"),
Move(Easy6502.Color.Orange, "$0202")
2022-12-06 18:43:48 +00:00
)
2022-12-06 19:58:20 +00:00
def assemble(opts: AssemblerOptions): String =
(defines(opts) ++ codes(opts))
.map(AsmBlock.toLines)
.pipe(xs => AsmBlock.interFlatMap(xs)(List("", ""), identity))
.pipe(str.Line.mkString)
private def defines(opts: AssemblerOptions) =
opts.definitionsMode match
case AssemblerOptions.DefinitionsMode.UseLiterals =>
Nil
case AssemblerOptions.DefinitionsMode.UseDefinitions =>
program
.flatMap(_.defines.toList)
.distinct
.map { xs =>
xs
.toList
.map { case (k, v) =>
s"define $k $v"
}
.pipe(AsmBlock.CommentBlock(_))
}
case AssemblerOptions.DefinitionsMode.UseDefinitionsWithMath =>
program
.flatMap(_.defines.toList)
.distinct
.map { xs =>
xs
.toList
.map { case (k, v) =>
s"define $k $v"
}
.pipe(AsmBlock.CommentBlock(_))
}
private def codes(opts: AssemblerOptions) =
2022-12-06 18:43:48 +00:00
program
.map { mv =>
2022-12-06 19:58:20 +00:00
val argument =
opts.definitionsMode match
case AssemblerOptions.DefinitionsMode.UseLiterals =>
f"#$$${mv.src.toValue}%02X"
case AssemblerOptions.DefinitionsMode.UseDefinitions |
AssemblerOptions.DefinitionsMode.UseDefinitionsWithMath =>
mv.src.toDefine
2022-12-06 19:30:35 +00:00
2022-12-06 18:43:48 +00:00
AsmBlock.Intent(
2022-12-06 19:30:35 +00:00
s"${mv.dest} = ${mv.src.toComment}".some,
2022-12-06 18:43:48 +00:00
List(
2022-12-06 19:58:20 +00:00
AsmBlock.Intent.Instruction(instruction("LDA", opts.instructionCase) + " " + argument, None),
AsmBlock.Intent.Instruction(instruction("STA", opts.instructionCase) + " " + mv.dest, None)
2022-12-06 17:56:29 +00:00
)
)
2022-12-06 18:43:48 +00:00
}
.pipe(AnonymousCodeBlock(_))
.pipe(List(_))
def instruction(s: String, instructionCase: AssemblerOptions.InstructionCase): String =
instructionCase match
case AssemblerOptions.InstructionCase.Uppercase =>
s.toUpperCase
case AssemblerOptions.InstructionCase.Lowercase =>
s.toLowerCase