texty: allow executing binary file

This commit is contained in:
Zellyn Hunter 2016-09-09 20:49:21 -04:00
parent ab0712fe68
commit 22a6e29678
2 changed files with 59 additions and 16 deletions

View File

@ -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)
}
}

View File

@ -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)
}
}