Turns out if I want to actually play with my 6502 simulator, I need an interface for it, so I spent some time learning a little bit of SwiftUI.
It's neat, if a bit opaque. I love the declarative model, where you just write out what you want and Swift figures out when to display or update.
struct RegisterView : View {
let name: String
let value: Int
var body: some View {
HStack() {
Text(name)
Spacer()
Text(String(format: "$%02X", value))
.fontDesign(.monospaced)
}
}
}Put my virtual machine into the environment, stick a few of those views into my window, and a similar thing for the flag register, and ta-dah! I can now monitor my VM.
struct EnvironmentView: View {
@Environment(Hardware.Environment.self) var env
var body: some View {
VStack {
RegisterView(name: "A", value: Int(env.reg.a))
RegisterView(name: "X", value: Int(env.reg.x))
RegisterView(name: "Y", value: Int(env.reg.y))
...
The downside is that I feel SwiftUI is both large and extremely underdocumented. It is really hard to get a complete picture of all the widgets, modifiers, and such that are available. It's also extremely magic. Everything is a closure, but it's not actually Swift, per se. It's a variant of Swift (the Result Builder DSL support I guess), so some things are subtly different, like using the ForEach() function rather than just a for loop. And it changes, quickly. Even in that simple example, I'm using some features that are only available in macOS 14 (Sonoma) or iOS 17. Luckily, there are lots of tutorials and example code supplied by Apple and others which at least help give an intuitive understanding.
With this and a few more buttons, I should be able to implement and test some simple opcodes.