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 21:39:00 +00:00
|
|
|
case class Move[A: Definable, B: Definable](src: A, dest: B):
|
|
|
|
def defines: List[ListMap[String, Int]] =
|
|
|
|
List(
|
|
|
|
Definable[A]
|
|
|
|
.table(src),
|
|
|
|
Definable[B]
|
|
|
|
.table(dest)
|
|
|
|
)
|
2022-12-06 18:43:48 +00:00
|
|
|
|
2022-12-06 20:22:37 +00:00
|
|
|
def build(screen: Easy6502.Screen): List[Move[Easy6502.Color, Easy6502.Screen.Pixel]] =
|
2022-12-06 17:56:29 +00:00
|
|
|
List(
|
2022-12-06 20:22:37 +00:00
|
|
|
Move(Easy6502.Color.White, screen(0)),
|
|
|
|
Move(Easy6502.Color.Green, screen(1)),
|
|
|
|
Move(Easy6502.Color.Orange, screen(2))
|
2022-12-06 18:43:48 +00:00
|
|
|
)
|
|
|
|
|
2022-12-06 20:22:37 +00:00
|
|
|
val program: List[Move[Easy6502.Color, Easy6502.Screen.Pixel]] =
|
2022-12-06 21:53:40 +00:00
|
|
|
build(Easy6502.Screen(0x200))
|
2022-12-06 20:22:37 +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
|
|
|
|
|
2022-12-06 20:38:39 +00:00
|
|
|
case AssemblerOptions.DefinitionsMode.UseDefinitions | AssemblerOptions.DefinitionsMode.UseDefinitionsWithMath =>
|
2022-12-06 19:58:20 +00:00
|
|
|
program
|
2022-12-06 20:22:37 +00:00
|
|
|
.flatMap(_.defines)
|
2022-12-06 19:58:20 +00:00
|
|
|
.distinct
|
|
|
|
.map { xs =>
|
|
|
|
xs
|
|
|
|
.toList
|
2022-12-06 20:38:39 +00:00
|
|
|
.pipe(AsmBlock.DefinesBlock(_))
|
2022-12-06 19:58:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 =>
|
2022-12-06 20:22:37 +00:00
|
|
|
"#" + mv.src.toDefine
|
2022-12-06 19:30:35 +00:00
|
|
|
|
2022-12-06 22:06:53 +00:00
|
|
|
val argumentTwo =
|
|
|
|
opts.definitionsMode match
|
|
|
|
case AssemblerOptions.DefinitionsMode.UseLiterals =>
|
|
|
|
AsmBlock.toHex(mv.dest.toValue)
|
|
|
|
|
|
|
|
case AssemblerOptions.DefinitionsMode.UseDefinitions =>
|
|
|
|
mv.dest.toDefine
|
|
|
|
|
|
|
|
case AssemblerOptions.DefinitionsMode.UseDefinitionsWithMath =>
|
|
|
|
mv.dest.toDefineWithMath
|
|
|
|
|
2022-12-06 18:43:48 +00:00
|
|
|
AsmBlock.Intent(
|
2022-12-06 20:22:37 +00:00
|
|
|
s"${mv.dest.toComment} = ${mv.src.toComment}".some,
|
2022-12-06 18:43:48 +00:00
|
|
|
List(
|
2022-12-06 21:53:40 +00:00
|
|
|
AsmBlock
|
|
|
|
.Intent
|
2022-12-06 22:55:51 +00:00
|
|
|
.Instruction
|
|
|
|
.One(instruction("LDA", opts.instructionCase), argument, s"a = ${mv.src.toComment}".some),
|
2022-12-06 22:20:30 +00:00
|
|
|
AsmBlock
|
|
|
|
.Intent
|
2022-12-06 22:55:51 +00:00
|
|
|
.Instruction
|
|
|
|
.One(
|
|
|
|
instruction("STA", opts.instructionCase),
|
|
|
|
argumentTwo,
|
2022-12-06 22:20:30 +00:00
|
|
|
s"${mv.dest.toComment} = a".some
|
|
|
|
)
|
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
|