mirror of
https://github.com/zellyn/goapple2.git
synced 2024-11-30 00:49:24 +00:00
texty: allow executing binary file
This commit is contained in:
parent
ab0712fe68
commit
22a6e29678
32
goapple2.go
32
goapple2.go
@ -55,7 +55,16 @@ type Apple2 struct {
|
||||
cycle uint64
|
||||
}
|
||||
|
||||
func NewApple2(p videoscan.Plotter, rom []byte, charRom [2048]byte) *Apple2 {
|
||||
// Option is an optional param to NewApple2.
|
||||
type Option func(*Apple2)
|
||||
|
||||
func WithRAM(address uint16, bytes []byte) Option {
|
||||
return func(a2 *Apple2) {
|
||||
copy(a2.mem[address:], bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func NewApple2(p videoscan.Plotter, rom []byte, charRom [2048]byte, options ...Option) *Apple2 {
|
||||
a2 := &Apple2{
|
||||
// BUG(zellyn): this is not how the apple2 keyboard actually works
|
||||
keys: make(chan byte, 16),
|
||||
@ -64,6 +73,11 @@ func NewApple2(p videoscan.Plotter, rom []byte, charRom [2048]byte) *Apple2 {
|
||||
copy(a2.mem[len(a2.mem)-len(rom):len(a2.mem)], rom)
|
||||
a2.scanner = videoscan.NewScanner(a2, p, charRom)
|
||||
a2.cpu = cpu.NewCPU(a2, a2.Tick, cpu.VERSION_6502)
|
||||
|
||||
for _, o := range options {
|
||||
o(a2)
|
||||
}
|
||||
|
||||
a2.cpu.Reset()
|
||||
return a2
|
||||
}
|
||||
@ -106,28 +120,28 @@ func (a2 *Apple2) handleC00X(address uint16, value byte, write bool) byte {
|
||||
}
|
||||
switch address {
|
||||
case 0xC050: // GRAPHICS
|
||||
fmt.Printf("$%04X: GRAPHICS\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: GRAPHICS\n", a2.cpu.PC())
|
||||
a2.scanner.SetGraphics(true)
|
||||
case 0xC051: // TEXT
|
||||
fmt.Printf("$%04X: NO GRAPHICS\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: NO GRAPHICS\n", a2.cpu.PC())
|
||||
a2.scanner.SetGraphics(false)
|
||||
case 0xC052: // NOMIX
|
||||
fmt.Printf("$%04X: NOMIX\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: NOMIX\n", a2.cpu.PC())
|
||||
a2.scanner.SetMix(false)
|
||||
case 0xC053: // MIX
|
||||
fmt.Printf("$%04X: MIX\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: MIX\n", a2.cpu.PC())
|
||||
a2.scanner.SetMix(true)
|
||||
case 0xC054: // PAGE 1
|
||||
fmt.Printf("$%04X: PAGE1\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: PAGE1\n", a2.cpu.PC())
|
||||
a2.scanner.SetPage(1)
|
||||
case 0xC055: // PAGE 2
|
||||
fmt.Printf("$%04X: PAGE2\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: PAGE2\n", a2.cpu.PC())
|
||||
a2.scanner.SetPage(2)
|
||||
case 0xC056: // LORES
|
||||
fmt.Printf("$%04X: LORES\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: LORES\n", a2.cpu.PC())
|
||||
a2.scanner.SetHires(false)
|
||||
case 0xC057: // HIRES
|
||||
fmt.Printf("$%04X: HIRES\n", a2.cpu.PC())
|
||||
// fmt.Printf("$%04X: HIRES\n", a2.cpu.PC())
|
||||
a2.scanner.SetHires(true)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/nsf/termbox-go"
|
||||
@ -14,14 +17,17 @@ import (
|
||||
// Mapping of screen bytes to character values
|
||||
var AppleChars = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
|
||||
var ColorFG = termbox.ColorGreen
|
||||
var ColorBG = termbox.ColorBlack
|
||||
|
||||
// Translate to termbox
|
||||
func translateToTermbox(value byte) (char rune, fg, bg termbox.Attribute) {
|
||||
// BUG(zellyn): change this to return char, MODE_ENUM.
|
||||
ch := rune(AppleChars[value&0x3F])
|
||||
if value&0x80 > 0 {
|
||||
return ch, termbox.ColorGreen, termbox.ColorBlack
|
||||
return ch, ColorFG, ColorBG
|
||||
}
|
||||
return ch, termbox.ColorGreen, termbox.ColorBlack + termbox.AttrReverse
|
||||
return ch, ColorBG, ColorFG
|
||||
}
|
||||
|
||||
func termboxToAppleKeyboard(ev termbox.Event) (key byte, err error) {
|
||||
@ -76,16 +82,32 @@ func (p TextPlotter) OncePerFrame() {
|
||||
}
|
||||
|
||||
// Run the emulator
|
||||
func RunEmulator() {
|
||||
rom := util.ReadRomOrDie("../data/roms/apple2+.rom")
|
||||
func RunEmulator(file string) error {
|
||||
var options []goapple2.Option
|
||||
if file != "" {
|
||||
ColorFG = termbox.ColorDefault
|
||||
ColorBG = termbox.ColorDefault
|
||||
bytes, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options = append(options, goapple2.WithRAM(0x6000, bytes))
|
||||
}
|
||||
rom := util.ReadRomOrDie("../data/roms/apple2+.rom", 12288)
|
||||
charRom := util.ReadSmallCharacterRomOrDie("../data/roms/apple2-chars.rom")
|
||||
plotter := TextPlotter(0)
|
||||
a2 := goapple2.NewApple2(plotter, rom, charRom)
|
||||
a2 := goapple2.NewApple2(plotter, rom, charRom, options...)
|
||||
if err := termbox.Init(); err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
events := make(chan termbox.Event)
|
||||
go func() {
|
||||
if file != "" {
|
||||
for _, ch := range "CALL 24576" {
|
||||
a2.Keypress(byte(ch))
|
||||
}
|
||||
a2.Keypress(13)
|
||||
}
|
||||
for {
|
||||
events <- termbox.PollEvent()
|
||||
}
|
||||
@ -99,8 +121,15 @@ func RunEmulator() {
|
||||
time.Sleep(1 * time.Nanosecond) // So the keyboard-reading goroutines can run
|
||||
}
|
||||
termbox.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
var binfile = flag.String("binfile", "", "binary file to load at $6000 and CALL")
|
||||
|
||||
func main() {
|
||||
RunEmulator()
|
||||
flag.Parse()
|
||||
if err := RunEmulator(*binfile); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user