Compare commits
No commits in common. "bf2afab07d65a52f1e2a4b0f207f5796ce950795" and "ccdb696c2dc4b69b3253a6caae6e51d78d8213d2" have entirely different histories.
bf2afab07d
...
ccdb696c2d
3
Makefile
3
Makefile
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
CMDS= \
|
CMDS= \
|
||||||
bin/fdslist \
|
bin/fdslist
|
||||||
bin/fdsextract
|
|
||||||
|
|
||||||
all: bin $(CMDS)
|
all: bin $(CMDS)
|
||||||
|
|
||||||
|
|
|
||||||
19
blocks.go
19
blocks.go
|
|
@ -2,7 +2,6 @@ package fds
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlockType byte
|
type BlockType byte
|
||||||
|
|
@ -12,7 +11,6 @@ const (
|
||||||
BtFileAmount BlockType = 0x02
|
BtFileAmount BlockType = 0x02
|
||||||
BtFileHeader BlockType = 0x03
|
BtFileHeader BlockType = 0x03
|
||||||
BtFileData BlockType = 0x04
|
BtFileData BlockType = 0x04
|
||||||
BtTest BlockType = 0x05
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (bt BlockType) String() string {
|
func (bt BlockType) String() string {
|
||||||
|
|
@ -194,20 +192,3 @@ func (b *BlockFileData) Type() BlockType {
|
||||||
func (b *BlockFileData) String() string {
|
func (b *BlockFileData) String() string {
|
||||||
return "BlockFileData"
|
return "BlockFileData"
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockTest struct {
|
|
||||||
Raw []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BlockTest) Type() BlockType {
|
|
||||||
return BtTest
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BlockTest) String() string {
|
|
||||||
bytes := []string{}
|
|
||||||
for _, byt := range b.Raw {
|
|
||||||
bytes = append(bytes, fmt.Sprintf("$%02X", byt))
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("BlockTest Raw:[%s]", strings.Join(bytes, " "))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/alexflint/go-arg"
|
|
||||||
|
|
||||||
"git.zorchenhimer.com/zorchenhimer/go-fds"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Arguments struct {
|
|
||||||
Input string `arg:"positional,required"`
|
|
||||||
|
|
||||||
// for getting a specific file
|
|
||||||
Side int `arg:"--side" default:"-1"`
|
|
||||||
|
|
||||||
FileNum int `arg:"--file-num" default:"-1"`
|
|
||||||
Range string `arg:"--range"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
args := &Arguments{}
|
|
||||||
arg.MustParse(args)
|
|
||||||
|
|
||||||
err := run(args)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func run(args *Arguments) error {
|
|
||||||
rom, err := fds.ReadRomFile(args.Input)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
outdir := strings.TrimSuffix(args.Input, filepath.Ext(args.Input))
|
|
||||||
err = os.MkdirAll(outdir, 0775)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if args.Side >= 0 && args.FileNum == -1 {
|
|
||||||
if args.Side >= len(rom.Sides) {
|
|
||||||
return fmt.Errorf("--side out of range")
|
|
||||||
}
|
|
||||||
|
|
||||||
num := 0
|
|
||||||
for _, s := range rom.Sides[:args.Side] {
|
|
||||||
num += len(s.Files)
|
|
||||||
}
|
|
||||||
|
|
||||||
side := rom.Sides[args.Side]
|
|
||||||
sideName := fmt.Sprintf("Side%d", side.Header.PhysicalSide)
|
|
||||||
for _, file := range side.Files {
|
|
||||||
fileName := filepath.Join(outdir, fmt.Sprintf("%03d_%s_%02d_%02X", num, sideName, file.Number, file.Id))
|
|
||||||
err := os.WriteFile(fileName, file.Data, 0664)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
num++
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
} else if args.Side >= 0 && args.FileNum >= 0 {
|
|
||||||
if args.Side >= len(rom.Sides) {
|
|
||||||
return fmt.Errorf("--side out of range")
|
|
||||||
}
|
|
||||||
|
|
||||||
side := rom.Sides[args.Side]
|
|
||||||
|
|
||||||
if len(side.Files) <= args.FileNum {
|
|
||||||
return fmt.Errorf("--file-num out of range; %d", len(side.Files))
|
|
||||||
}
|
|
||||||
|
|
||||||
sideName := fmt.Sprintf("Side%d", side.Header.PhysicalSide)
|
|
||||||
file := side.Files[args.FileNum]
|
|
||||||
|
|
||||||
var start int
|
|
||||||
var end int
|
|
||||||
if args.Range != "" {
|
|
||||||
start, end, err = parseRange(args.Range)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("start: %04X\nend: %04X\n", start, end)
|
|
||||||
|
|
||||||
start = start - int(file.Address)
|
|
||||||
end = end - int(file.Address)
|
|
||||||
|
|
||||||
fmt.Printf("start: %04X\nend: %04X\n", start, end)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
start = 0
|
|
||||||
end = file.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName := filepath.Join(outdir, fmt.Sprintf("%03d_%s_%02d_%02X", args.FileNum, sideName, file.Number, file.Id))
|
|
||||||
fmt.Println("fileName:", fileName)
|
|
||||||
err := os.WriteFile(fileName, file.Data[start:end], 0664)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
|
|
||||||
} else if args.Range != "" && (args.Side < 0 || args.FileNum < 0) {
|
|
||||||
return fmt.Errorf("--range cannot be given alone")
|
|
||||||
}
|
|
||||||
|
|
||||||
num := 0
|
|
||||||
for _, side := range rom.Sides {
|
|
||||||
sideName := fmt.Sprintf("Side%d", side.Header.PhysicalSide)
|
|
||||||
for _, file := range side.Files {
|
|
||||||
fileName := filepath.Join(outdir, fmt.Sprintf("%03d_%s_%02d_%02X", args.FileNum, sideName, file.Number, file.Id))
|
|
||||||
err := os.WriteFile(fileName, file.Data, 0664)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
num++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// $6000-$5000
|
|
||||||
func parseRange(input string) (int, int, error) {
|
|
||||||
splits := strings.Split(input, "-")
|
|
||||||
if len(splits) != 2 {
|
|
||||||
return 0, 0, fmt.Errorf("invalid range: %q", input)
|
|
||||||
}
|
|
||||||
fmt.Println("splits:", splits)
|
|
||||||
|
|
||||||
splits[0] = strings.Replace(splits[0], "$", "0x", 1)
|
|
||||||
splits[1] = strings.Replace(splits[1], "$", "0x", 1)
|
|
||||||
|
|
||||||
fmt.Println("splits:", splits)
|
|
||||||
|
|
||||||
start, err := strconv.ParseInt(splits[0], 0, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, fmt.Errorf("invalid range: %q", input)
|
|
||||||
}
|
|
||||||
|
|
||||||
end, err := strconv.ParseInt(splits[1], 0, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, fmt.Errorf("invalid range: %q", input)
|
|
||||||
}
|
|
||||||
|
|
||||||
return int(start), int(end), nil
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,10 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
//"encoding/binary"
|
||||||
|
//"bufio"
|
||||||
|
//"bytes"
|
||||||
|
//"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/alexflint/go-arg"
|
"github.com/alexflint/go-arg"
|
||||||
|
|
@ -12,8 +16,7 @@ import (
|
||||||
|
|
||||||
type Arguments struct {
|
type Arguments struct {
|
||||||
Input string `arg:"positional,required"`
|
Input string `arg:"positional,required"`
|
||||||
|
Extract string `arg:"--extract" help:"Extract files to the given directory"`
|
||||||
Blocks bool `arg:"--blocks"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -29,25 +32,6 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(args *Arguments) error {
|
func run(args *Arguments) error {
|
||||||
if args.Blocks {
|
|
||||||
file, err := os.Open(args.Input)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
blocks, err := fds.ReadRomBlocks(file, filepath.Ext(args.Input) == ".fds")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, block := range blocks {
|
|
||||||
fmt.Println(block.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rom, err := fds.ReadRomFile(args.Input)
|
rom, err := fds.ReadRomFile(args.Input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -55,6 +39,26 @@ func run(args *Arguments) error {
|
||||||
|
|
||||||
fmt.Println(rom.Info())
|
fmt.Println(rom.Info())
|
||||||
|
|
||||||
|
if args.Extract != "" {
|
||||||
|
err = os.MkdirAll(args.Extract, 0775)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
num := 0
|
||||||
|
for _, side := range rom.Sides {
|
||||||
|
sideName := fmt.Sprintf("Side%d", side.Header.PhysicalSide)
|
||||||
|
for _, file := range side.Files {
|
||||||
|
fileName := filepath.Join(args.Extract, fmt.Sprintf("%03d_%s_%02d_%02X", num, sideName, file.Number, file.Id))
|
||||||
|
err := os.WriteFile(fileName, file.Data, 0664)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
num++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
28
reader.go
28
reader.go
|
|
@ -52,7 +52,6 @@ func ReadBlocks(r io.Reader, IsFds bool) ([]DiskBlock, error) {
|
||||||
|
|
||||||
reader := bufio.NewReader(r)
|
reader := bufio.NewReader(r)
|
||||||
|
|
||||||
outerLoop:
|
|
||||||
for {
|
for {
|
||||||
raw, err := reader.Peek(1)
|
raw, err := reader.Peek(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -80,31 +79,6 @@ func ReadBlocks(r io.Reader, IsFds bool) ([]DiskBlock, error) {
|
||||||
// variable length
|
// variable length
|
||||||
readLen = dataSize+3
|
readLen = dataSize+3
|
||||||
|
|
||||||
case 0x05: // some weird test block??
|
|
||||||
reader.Discard(1)
|
|
||||||
bt := &BlockTest{}
|
|
||||||
for {
|
|
||||||
b, err := reader.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
blocks = append(blocks, bt)
|
|
||||||
break outerLoop
|
|
||||||
}
|
|
||||||
return blocks, fmt.Errorf("error reading 0x05 block type: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch b {
|
|
||||||
case 0x6D, 0xB6, 0xDB:
|
|
||||||
bt.Raw = append(bt.Raw, b)
|
|
||||||
continue
|
|
||||||
case 0x00:
|
|
||||||
blocks = append(blocks, bt)
|
|
||||||
continue outerLoop
|
|
||||||
}
|
|
||||||
|
|
||||||
return blocks, fmt.Errorf("Read unknown byte in 0x05 block: 0x%02X", b)
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
reader.Discard(1)
|
reader.Discard(1)
|
||||||
continue
|
continue
|
||||||
|
|
@ -170,9 +144,9 @@ func ReadBlocks(r io.Reader, IsFds bool) ([]DiskBlock, error) {
|
||||||
db.Data = buf[1:readLen]
|
db.Data = buf[1:readLen]
|
||||||
//fmt.Println("len(db.Data)", len(db.Data))
|
//fmt.Println("len(db.Data)", len(db.Data))
|
||||||
block = db
|
block = db
|
||||||
|
//fmt.Printf("Block:%#v\n", block)
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Printf("Block:%s\n", block.String())
|
|
||||||
blocks = append(blocks, block)
|
blocks = append(blocks, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue