working on character ROM generation

This commit is contained in:
Zellyn Hunter 2014-05-10 15:10:48 -07:00
parent 5c89db1649
commit 4279c0e0eb
4 changed files with 148 additions and 0 deletions

3
INSTALL.md Normal file
View File

@ -0,0 +1,3 @@
brew install sdl sdl_image sdl_mixer sdl_ttf
go get github.com/zellyn/Go-SDL/sdl --with-x11-driver
go get github.com/zellyn/Go-SDL/sdl/audio

50
a2/charrom.go Normal file
View File

@ -0,0 +1,50 @@
package main
import (
"io/ioutil"
"github.com/gonuts/commander"
"github.com/zellyn/goapple2/videoscan"
)
var cmdCharROM = &commander.Command{
Run: runCharROM,
UsageLine: "charrom infile outfile",
Short: "convert apple II character ROMs to text and back",
Long: `
CharROM is a simple character ROM conversion utility.
`,
}
var decompile bool
var reverse bool
func init() {
cmdCharROM.Flag.BoolVar(&decompile, "d", false, "decompile: convert from ROM to text.")
cmdCharROM.Flag.BoolVar(&reverse, "r", false, "reverse: put bits in opposite order.")
}
func runCharROM(cmd *commander.Command, args []string) error {
if len(args) != 2 {
cmd.Usage()
return nil
}
in, err := ioutil.ReadFile(args[0])
if err != nil {
panic("Cannot read file: " + args[0])
}
if decompile {
out := videoscan.BytesToText(in, reverse)
err := ioutil.WriteFile(args[1], out, 0644)
return err
}
out, err := videoscan.TextToBytes(in, reverse)
if err != nil {
return err
}
err = ioutil.WriteFile(args[1], out, 0644)
return err
}

View File

@ -16,6 +16,7 @@ func init() {
Subcommands: []*commander.Command{
cmdDisasm,
cmdDiskConvert,
cmdCharROM,
},
Flag: *flag.NewFlagSet("a2", flag.ExitOnError),
}

94
videoscan/convert.go Normal file
View File

@ -0,0 +1,94 @@
// convert.go contains routines to convert from character ROMs to text and back.
package videoscan
import (
"fmt"
"strings"
)
var chars = []rune{'.', '#'}
func reverseByte(in byte) byte {
hi := in & 0x80
var out byte
for i := 0; i < 7; i++ {
out = out << 1
out = out | in&1
in = in >> 1
}
out |= hi
return out
}
func BytesToText(rom []byte, reverse bool) []byte {
result := []byte{}
for i, b := range rom {
if reverse {
b = reverseByte(b)
}
if i > 0 && i%8 == 0 {
result = append(result, '\n')
}
if b >= 0x80 {
result = append(result, 'i')
} else {
result = append(result, 'n')
}
result = append(result, ' ')
for i := 0; i < 7; i++ {
result = append(result, byte(chars[b&1]))
b = b >> 1
}
result = append(result, '\n')
}
return result
}
func TextToBytes(text []byte, reverse bool) ([]byte, error) {
result := []byte{}
lines := strings.Split(string(text), "\n")
for i, l := range lines {
l = strings.TrimSpace(l)
lines[i] = l
if i != 0 && i%9 == 8 {
if l != "" {
return nil, fmt.Errorf("line %d: expected empty line, got '%s'", i+1, l)
}
continue
}
if len(l) != 9 {
return nil, fmt.Errorf("line %d: expected 9 characters, got %d: '%s'", i+1, len(l), l)
}
var hi byte
switch l[0] {
case 'i':
hi = 0x80
case 'n':
default:
return nil, fmt.Errorf("line %d: should start with 'n' or 'i'; got '%s'", i+1, l[0])
}
if l[1] != ' ' {
return nil, fmt.Errorf("line %d: second char should be space; got '%s'", i+1, l[1])
}
var b byte
var bit byte = 1
for _, c := range l[2:] {
switch c {
case chars[0]: // do nothing
case chars[1]:
b |= bit
default:
return nil, fmt.Errorf("line %d: expected character: '%s'", i+1, c)
}
bit <<= 1
}
b |= hi
if reverse {
b = reverseByte(b)
}
result = append(result, b)
}
return result, nil
}