Change ints to specific uints

This commit is contained in:
Terence Boldt 2024-03-11 08:05:23 -05:00
parent 0aa838ffe1
commit bf94ac8822
11 changed files with 225 additions and 250 deletions

32
main.go
View File

@ -25,21 +25,21 @@ func main() {
var command string var command string
var outFileName string var outFileName string
var inFileName string var inFileName string
var blockNumber int var blockNumber uint
var volumeSize int var volumeSize uint
var volumeName string var volumeName string
var fileType int var fileType uint
var auxType int var auxType uint
flag.StringVar(&fileName, "d", "", "A ProDOS format drive image") flag.StringVar(&fileName, "d", "", "A ProDOS format drive image")
flag.StringVar(&pathName, "p", "", "Path name in ProDOS drive image (default is root of volume)") flag.StringVar(&pathName, "p", "", "Path name in ProDOS drive image (default is root of volume)")
flag.StringVar(&command, "c", "ls", "Command to execute: ls, get, put, rm, mkdir, readblock, writeblock, create, putall, putallrecursive") flag.StringVar(&command, "c", "ls", "Command to execute: ls, get, put, rm, mkdir, readblock, writeblock, create, putall, putallrecursive")
flag.StringVar(&outFileName, "o", "", "Name of file to write") flag.StringVar(&outFileName, "o", "", "Name of file to write")
flag.StringVar(&inFileName, "i", "", "Name of file to read") flag.StringVar(&inFileName, "i", "", "Name of file to read")
flag.IntVar(&volumeSize, "s", 65535, "Number of blocks to create the volume with (default 65535, 64 to 65535, 0x0040 to 0xFFFF hex input accepted)") flag.UintVar(&volumeSize, "s", 65535, "Number of blocks to create the volume with (default 65535, 64 to 65535, 0x0040 to 0xFFFF hex input accepted)")
flag.StringVar(&volumeName, "v", "NO.NAME", "Specifiy a name for the volume from 1 to 15 characters") flag.StringVar(&volumeName, "v", "NO.NAME", "Specifiy a name for the volume from 1 to 15 characters")
flag.IntVar(&blockNumber, "b", 0, "A block number to read/write from 0 to 65535 (0x0000 to 0xFFFF hex input accepted)") flag.UintVar(&blockNumber, "b", 0, "A block number to read/write from 0 to 65535 (0x0000 to 0xFFFF hex input accepted)")
flag.IntVar(&fileType, "t", 0, "ProDOS FileType: 0x04 for TXT, 0x06 for BIN, 0xFC for BAS, 0xFF for SYS etc., omit to autodetect") flag.UintVar(&fileType, "t", 0, "ProDOS FileType: 0x04 for TXT, 0x06 for BIN, 0xFC for BAS, 0xFF for SYS etc., omit to autodetect")
flag.IntVar(&auxType, "a", 0, "ProDOS AuxType from 0 to 65535 (0x0000 to 0xFFFF hex input accepted), omit to autodetect") flag.UintVar(&auxType, "a", 0, "ProDOS AuxType from 0 to 65535 (0x0000 to 0xFFFF hex input accepted), omit to autodetect")
flag.Parse() flag.Parse()
if len(fileName) == 0 { if len(fileName) == 0 {
@ -54,13 +54,13 @@ func main() {
case "get": case "get":
get(fileName, pathName, outFileName) get(fileName, pathName, outFileName)
case "put": case "put":
put(fileName, pathName, fileType, auxType, inFileName) put(fileName, pathName, uint8(fileType), uint16(auxType), inFileName)
case "readblock": case "readblock":
readBlock(blockNumber, fileName) readBlock(uint16(blockNumber), fileName)
case "writeblock": case "writeblock":
writeBlock(blockNumber, fileName, inFileName) writeBlock(uint16(blockNumber), fileName, inFileName)
case "create": case "create":
create(fileName, volumeName, volumeSize) create(fileName, volumeName, uint16(volumeSize))
case "putall": case "putall":
putall(fileName, inFileName, pathName, false) putall(fileName, inFileName, pathName, false)
case "putallrecursive": case "putallrecursive":
@ -147,7 +147,7 @@ func putall(fileName string, inFileName string, pathName string, recursive bool)
} }
} }
func create(fileName string, volumeName string, volumeSize int) { func create(fileName string, volumeName string, volumeSize uint16) {
file, err := os.Create(fileName) file, err := os.Create(fileName)
if err != nil { if err != nil {
fmt.Printf("failed to create file: %s\n", err) fmt.Printf("failed to create file: %s\n", err)
@ -157,7 +157,7 @@ func create(fileName string, volumeName string, volumeSize int) {
prodos.CreateVolume(file, volumeName, volumeSize) prodos.CreateVolume(file, volumeName, volumeSize)
} }
func writeBlock(blockNumber int, fileName string, inFileName string) { func writeBlock(blockNumber uint16, fileName string, inFileName string) {
checkInFileName(inFileName) checkInFileName(inFileName)
fmt.Printf("Writing block 0x%04X (%d):\n\n", blockNumber, blockNumber) fmt.Printf("Writing block 0x%04X (%d):\n\n", blockNumber, blockNumber)
file, err := os.OpenFile(fileName, os.O_RDWR, 0755) file, err := os.OpenFile(fileName, os.O_RDWR, 0755)
@ -174,7 +174,7 @@ func writeBlock(blockNumber int, fileName string, inFileName string) {
prodos.WriteBlock(file, blockNumber, inFile) prodos.WriteBlock(file, blockNumber, inFile)
} }
func readBlock(blockNumber int, fileName string) { func readBlock(blockNumber uint16, fileName string) {
fmt.Printf("Reading block 0x%04X (%d):\n\n", blockNumber, blockNumber) fmt.Printf("Reading block 0x%04X (%d):\n\n", blockNumber, blockNumber)
file, err := os.OpenFile(fileName, os.O_RDONLY, 0755) file, err := os.OpenFile(fileName, os.O_RDONLY, 0755)
if err != nil { if err != nil {
@ -190,7 +190,7 @@ func readBlock(blockNumber int, fileName string) {
prodos.DumpBlock(block) prodos.DumpBlock(block)
} }
func put(fileName string, pathName string, fileType int, auxType int, inFileName string) { func put(fileName string, pathName string, fileType uint8, auxType uint16, inFileName string) {
checkPathName(pathName) checkPathName(pathName)
checkInFileName(inFileName) checkInFileName(inFileName)
file, err := os.OpenFile(fileName, os.O_RDWR, 0755) file, err := os.OpenFile(fileName, os.O_RDWR, 0755)

View File

@ -33,13 +33,13 @@ func ReadVolumeBitmap(reader io.ReaderAt) ([]byte, error) {
totalBitmapBlocks++ totalBitmapBlocks++
} }
for i := 0; i < totalBitmapBlocks; i++ { for i := uint16(0); i < totalBitmapBlocks; i++ {
bitmapBlock, err := ReadBlock(reader, i+volumeHeader.BitmapStartBlock) bitmapBlock, err := ReadBlock(reader, i+volumeHeader.BitmapStartBlock)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for j := 0; j < 512 && i*512+j < totalBitmapBytes; j++ { for j := uint16(0); j < 512 && i*512+j < totalBitmapBytes; j++ {
bitmap[i*512+j] = bitmapBlock[j] bitmap[i*512+j] = bitmapBlock[j]
} }
} }
@ -48,10 +48,10 @@ func ReadVolumeBitmap(reader io.ReaderAt) ([]byte, error) {
} }
// GetFreeBlockCount gets the number of free blocks on a ProDOS image // GetFreeBlockCount gets the number of free blocks on a ProDOS image
func GetFreeBlockCount(volumeBitmap []byte, totalBlocks int) int { func GetFreeBlockCount(volumeBitmap []byte, totalBlocks uint16) uint16 {
freeBlockCount := 0 freeBlockCount := uint16(0)
for i := 0; i < totalBlocks; i++ { for i := uint16(0); i < totalBlocks; i++ {
if checkFreeBlockInVolumeBitmap(volumeBitmap, i) { if checkFreeBlockInVolumeBitmap(volumeBitmap, i) {
freeBlockCount++ freeBlockCount++
} }
@ -77,13 +77,13 @@ func writeVolumeBitmap(readerWriter ReaderWriterAt, bitmap []byte) error {
totalBitmapBlocks++ totalBitmapBlocks++
} }
for i := 0; i < totalBitmapBlocks; i++ { for i := uint16(0); i < totalBitmapBlocks; i++ {
bitmapBlock, err := ReadBlock(readerWriter, i+volumeHeader.BitmapStartBlock) bitmapBlock, err := ReadBlock(readerWriter, i+volumeHeader.BitmapStartBlock)
if err != nil { if err != nil {
return err return err
} }
for j := 0; j < 512 && i*512+j < totalBitmapBytes; j++ { for j := uint16(0); j < 512 && i*512+j < totalBitmapBytes; j++ {
bitmapBlock[j] = bitmap[i*512+j] bitmapBlock[j] = bitmap[i*512+j]
} }
@ -96,9 +96,10 @@ func writeVolumeBitmap(readerWriter ReaderWriterAt, bitmap []byte) error {
return nil return nil
} }
func createVolumeBitmap(numberOfBlocks int) []byte { func createVolumeBitmap(numberOfBlocks uint16) []byte {
volumeBitmapBlocks := numberOfBlocks / 512 / 8 // needs to be > uint16 because it's multiplying by a uint16
if volumeBitmapBlocks*8*512 < numberOfBlocks { volumeBitmapBlocks := uint32(numberOfBlocks / 512 / 8)
if volumeBitmapBlocks*8*512 < uint32(numberOfBlocks) {
volumeBitmapBlocks++ volumeBitmapBlocks++
} }
@ -119,30 +120,31 @@ func createVolumeBitmap(numberOfBlocks int) []byte {
markBlockInVolumeBitmap(volumeBitmap, 5) markBlockInVolumeBitmap(volumeBitmap, 5)
// volume bitmap blocks // volume bitmap blocks
for i := 0; i < volumeBitmapBlocks; i++ { for i := uint32(0); i < volumeBitmapBlocks; i++ {
markBlockInVolumeBitmap(volumeBitmap, 6+i) markBlockInVolumeBitmap(volumeBitmap, uint16(6+i))
} }
// blocks beyond the volume // blocks beyond the volume
totalBlocksInBitmap := volumeBitmapBlocks * 512 * 8 totalBlocksInBitmap := volumeBitmapBlocks * 512 * 8
blocksBeyondEnd := totalBlocksInBitmap - numberOfBlocks blocksBeyondEnd := totalBlocksInBitmap - uint32(numberOfBlocks)
if blocksBeyondEnd > 0 { if blocksBeyondEnd > 0 {
for i := totalBlocksInBitmap - blocksBeyondEnd; i < totalBlocksInBitmap; i++ { for i := totalBlocksInBitmap - blocksBeyondEnd; i < totalBlocksInBitmap; i++ {
markBlockInVolumeBitmap(volumeBitmap, i) markBlockInVolumeBitmap(volumeBitmap, uint16(i))
} }
} }
return volumeBitmap return volumeBitmap
} }
func findFreeBlocks(volumeBitmap []byte, numberOfBlocks int) []int { func findFreeBlocks(volumeBitmap []byte, numberOfBlocks uint16) []uint16 {
blocks := make([]int, numberOfBlocks) blocks := make([]uint16, numberOfBlocks)
blocksFound := 0 blocksFound := uint16(0)
for i := 0; i < len(volumeBitmap)*8; i++ { // needs to be > uint16 because it's multiplying by a uint16
if checkFreeBlockInVolumeBitmap(volumeBitmap, i) { for i := uint32(0); i < uint32(len(volumeBitmap))*8; i++ {
blocks[blocksFound] = i if checkFreeBlockInVolumeBitmap(volumeBitmap, uint16(i)) {
blocks[blocksFound] = uint16(i)
blocksFound++ blocksFound++
if blocksFound == numberOfBlocks { if blocksFound == numberOfBlocks {
return blocks return blocks
@ -153,87 +155,29 @@ func findFreeBlocks(volumeBitmap []byte, numberOfBlocks int) []int {
return nil return nil
} }
func markBlockInVolumeBitmap(volumeBitmap []byte, blockNumber int) { func markBlockInVolumeBitmap(volumeBitmap []byte, blockNumber uint16) {
bitToChange := blockNumber % 8 bitToChange := blockNumber % 8
byteToChange := blockNumber / 8 byteToChange := blockNumber / 8
byteToAnd := 0b11111111 byteToAnd := (uint8(0b10000000) >> uint8(bitToChange)) ^ 0b11111111
switch bitToChange {
case 0:
byteToAnd = 0b01111111
case 1:
byteToAnd = 0b10111111
case 2:
byteToAnd = 0b11011111
case 3:
byteToAnd = 0b11101111
case 4:
byteToAnd = 0b11110111
case 5:
byteToAnd = 0b11111011
case 6:
byteToAnd = 0b11111101
case 7:
byteToAnd = 0b11111110
}
//fmt.Printf("blockNumber: $%04X byteToWrite: 0b%08b volumeBitmap: $%02X byteToChange: $%04X\n", blockNumber, byteToWrite, volumeBitmap[byteToChange], byteToChange)
volumeBitmap[byteToChange] &= byte(byteToAnd) volumeBitmap[byteToChange] &= byte(byteToAnd)
} }
func freeBlockInVolumeBitmap(volumeBitmap []byte, blockNumber int) { func freeBlockInVolumeBitmap(volumeBitmap []byte, blockNumber uint16) {
bitToChange := blockNumber % 8 bitToChange := blockNumber % 8
byteToChange := blockNumber / 8 byteToChange := blockNumber / 8
byteToOr := 0b00000000 byteToOr := uint8(0b10000000) >> uint8(bitToChange)
switch bitToChange {
case 0:
byteToOr = 0b10000000
case 1:
byteToOr = 0b01000000
case 2:
byteToOr = 0b00100000
case 3:
byteToOr = 0b00010000
case 4:
byteToOr = 0b00001000
case 5:
byteToOr = 0b00000100
case 6:
byteToOr = 0b00000010
case 7:
byteToOr = 0b00000001
}
volumeBitmap[byteToChange] |= byte(byteToOr) volumeBitmap[byteToChange] |= byte(byteToOr)
} }
func checkFreeBlockInVolumeBitmap(volumeBitmap []byte, blockNumber int) bool { func checkFreeBlockInVolumeBitmap(volumeBitmap []byte, blockNumber uint16) bool {
bitToCheck := blockNumber % 8 bitToCheck := blockNumber % 8
byteToCheck := blockNumber / 8 byteToCheck := blockNumber / 8
byteToAnd := 0b00000000 byteToAnd := uint8(0b10000000) >> uint8(bitToCheck)
switch bitToCheck {
case 0:
byteToAnd = 0b10000000
case 1:
byteToAnd = 0b01000000
case 2:
byteToAnd = 0b00100000
case 3:
byteToAnd = 0b00010000
case 4:
byteToAnd = 0b00001000
case 5:
byteToAnd = 0b00000100
case 6:
byteToAnd = 0b00000010
case 7:
byteToAnd = 0b00000001
}
return (volumeBitmap[byteToCheck] & byte(byteToAnd)) > 0 return (volumeBitmap[byteToCheck] & byte(byteToAnd)) > 0
} }

View File

@ -14,10 +14,10 @@ import (
func TestCreateVolumeBitmap(t *testing.T) { func TestCreateVolumeBitmap(t *testing.T) {
var tests = []struct { var tests = []struct {
blocks int blocks uint16
want int want uint16
}{ }{
{65536, 8192}, {65535, 8192},
{65533, 8192}, {65533, 8192},
{140, 512}, {140, 512},
} }
@ -26,7 +26,7 @@ func TestCreateVolumeBitmap(t *testing.T) {
testname := fmt.Sprintf("%d", tt.blocks) testname := fmt.Sprintf("%d", tt.blocks)
t.Run(testname, func(t *testing.T) { t.Run(testname, func(t *testing.T) {
volumeBitMap := createVolumeBitmap(tt.blocks) volumeBitMap := createVolumeBitmap(tt.blocks)
ans := len(volumeBitMap) ans := uint16(len(volumeBitMap))
if ans != tt.want { if ans != tt.want {
t.Errorf("got %d, want %d", ans, tt.want) t.Errorf("got %d, want %d", ans, tt.want)
} }
@ -36,7 +36,7 @@ func TestCreateVolumeBitmap(t *testing.T) {
func TestCheckFreeBlockInVolumeBitmap(t *testing.T) { func TestCheckFreeBlockInVolumeBitmap(t *testing.T) {
var tests = []struct { var tests = []struct {
blocks int blocks uint16
want bool want bool
}{ }{
{0, false}, // boot block {0, false}, // boot block
@ -63,7 +63,7 @@ func TestCheckFreeBlockInVolumeBitmap(t *testing.T) {
func TestMarkBlockInVolumeBitmap(t *testing.T) { func TestMarkBlockInVolumeBitmap(t *testing.T) {
var tests = []struct { var tests = []struct {
blocks int blocks uint16
want bool want bool
}{ }{
{0, false}, // boot block {0, false}, // boot block

View File

@ -14,7 +14,7 @@ import (
) )
// ReadBlock reads a block from a ProDOS volume into a byte array // ReadBlock reads a block from a ProDOS volume into a byte array
func ReadBlock(reader io.ReaderAt, block int) ([]byte, error) { func ReadBlock(reader io.ReaderAt, block uint16) ([]byte, error) {
buffer := make([]byte, 512) buffer := make([]byte, 512)
_, err := reader.ReadAt(buffer, int64(block)*512) _, err := reader.ReadAt(buffer, int64(block)*512)
@ -27,7 +27,7 @@ func ReadBlock(reader io.ReaderAt, block int) ([]byte, error) {
} }
// WriteBlock writes a block to a ProDOS volume from a byte array // WriteBlock writes a block to a ProDOS volume from a byte array
func WriteBlock(writer io.WriterAt, block int, buffer []byte) error { func WriteBlock(writer io.WriterAt, block uint16, buffer []byte) error {
_, err := writer.WriteAt(buffer, int64(block)*512) _, err := writer.WriteAt(buffer, int64(block)*512)
if err != nil { if err != nil {
errString := fmt.Sprintf("failed to write block %04X: %s", block, err.Error()) errString := fmt.Sprintf("failed to write block %04X: %s", block, err.Error())

View File

@ -19,33 +19,33 @@ import (
type VolumeHeader struct { type VolumeHeader struct {
VolumeName string VolumeName string
CreationTime time.Time CreationTime time.Time
ActiveFileCount int ActiveFileCount uint16
BitmapStartBlock int BitmapStartBlock uint16
TotalBlocks int TotalBlocks uint16
NextBlock int NextBlock uint16
EntryLength int EntryLength uint8
EntriesPerBlock int EntriesPerBlock uint8
MinVersion int MinVersion uint8
Version int Version uint8
} }
// DirectoryHeader from ProDOS // DirectoryHeader from ProDOS
type DirectoryHeader struct { type DirectoryHeader struct {
PreviousBlock int PreviousBlock uint16
NextBlock int NextBlock uint16
IsSubDirectory bool IsSubDirectory bool
Name string Name string
CreationTime time.Time CreationTime time.Time
Version int Version uint8
MinVersion int MinVersion uint8
Access int Access uint8
EntryLength int EntryLength uint8
EntriesPerBlock int EntriesPerBlock uint8
ActiveFileCount int ActiveFileCount uint16
StartingBlock int StartingBlock uint16
ParentBlock int ParentBlock uint16
ParentEntry int ParentEntry uint16
ParentEntryLength int ParentEntryLength uint8
} }
const ( const (
@ -65,22 +65,22 @@ const (
// FileEntry from ProDOS // FileEntry from ProDOS
type FileEntry struct { type FileEntry struct {
StorageType int StorageType uint8
FileName string FileName string
FileType int FileType uint8
CreationTime time.Time CreationTime time.Time
KeyPointer int KeyPointer uint16
Version int Version uint8
MinVersion int MinVersion uint8
BlocksUsed int BlocksUsed uint16
EndOfFile int EndOfFile uint32
Access int Access uint8
AuxType int AuxType uint16
ModifiedTime time.Time ModifiedTime time.Time
HeaderPointer int HeaderPointer uint16
DirectoryBlock int DirectoryBlock uint16
DirectoryOffset int DirectoryOffset uint16
} }
// ReadDirectory reads the directory information from a specified path // ReadDirectory reads the directory information from a specified path
@ -183,7 +183,7 @@ func CreateDirectory(readerWriter ReaderWriterAt, path string) error {
ActiveFileCount: 0, ActiveFileCount: 0,
StartingBlock: blockList[0], StartingBlock: blockList[0],
ParentBlock: fileEntry.DirectoryBlock, ParentBlock: fileEntry.DirectoryBlock,
ParentEntry: (fileEntry.DirectoryOffset - 0x04) / 0x27, ParentEntry: uint16(fileEntry.DirectoryOffset-0x04) / 0x27,
ParentEntryLength: 0x27, ParentEntryLength: 0x27,
} }
@ -219,18 +219,18 @@ func getFreeFileEntryInDirectory(readerWriter ReaderWriterAt, directory string)
if err != nil { if err != nil {
return FileEntry{}, err return FileEntry{}, err
} }
entryOffset := 43 // start at offset after header entryOffset := uint16(43) // start at offset after header
entryNumber := 2 // header is essentially the first entry so start at 2 entryNumber := 2 // header is essentially the first entry so start at 2
for { for {
if entryNumber > 13 { if entryNumber > 13 {
nextBlockNumber := int(buffer[2]) + int(buffer[3])*256 nextBlockNumber := uint16(buffer[2]) + uint16(buffer[3])*256
// if we ran out of blocks in the directory, expand directory or fail // if we ran out of blocks in the directory, expand directory or fail
if nextBlockNumber == 0 { if nextBlockNumber == 0 {
if !directoryHeader.IsSubDirectory { if !directoryHeader.IsSubDirectory {
return FileEntry{}, errors.New("no free file entries found") return FileEntry{}, errors.New("no free file entries found")
} }
nextBlockNumber, err = expandDirectory(readerWriter, nextBlockNumber, buffer, blockNumber, directoryHeader) nextBlockNumber, err = expandDirectory(readerWriter, buffer, blockNumber, directoryHeader)
if err != nil { if err != nil {
return FileEntry{}, err return FileEntry{}, err
} }
@ -260,7 +260,7 @@ func getFreeFileEntryInDirectory(readerWriter ReaderWriterAt, directory string)
} }
} }
func expandDirectory(readerWriter ReaderWriterAt, nextBlockNumber int, buffer []byte, blockNumber int, directoryHeader DirectoryHeader) (int, error) { func expandDirectory(readerWriter ReaderWriterAt, buffer []byte, blockNumber uint16, directoryHeader DirectoryHeader) (uint16, error) {
volumeBitMap, err := ReadVolumeBitmap(readerWriter) volumeBitMap, err := ReadVolumeBitmap(readerWriter)
if err != nil { if err != nil {
errString := fmt.Sprintf("failed to get volume bitmap to expand directory: %s", err) errString := fmt.Sprintf("failed to get volume bitmap to expand directory: %s", err)
@ -271,7 +271,7 @@ func expandDirectory(readerWriter ReaderWriterAt, nextBlockNumber int, buffer []
return 0, errors.New("failed to get free block to expand directory") return 0, errors.New("failed to get free block to expand directory")
} }
nextBlockNumber = blockList[0] nextBlockNumber := blockList[0]
buffer[0x02] = byte(nextBlockNumber & 0x00FF) buffer[0x02] = byte(nextBlockNumber & 0x00FF)
buffer[0x03] = byte(nextBlockNumber >> 8) buffer[0x03] = byte(nextBlockNumber >> 8)
WriteBlock(readerWriter, blockNumber, buffer) WriteBlock(readerWriter, blockNumber, buffer)
@ -296,8 +296,8 @@ func expandDirectory(readerWriter ReaderWriterAt, nextBlockNumber int, buffer []
errString := fmt.Sprintf("failed to read parent block to expand directory: %s", err) errString := fmt.Sprintf("failed to read parent block to expand directory: %s", err)
return 0, errors.New(errString) return 0, errors.New(errString)
} }
directoryEntryOffset := directoryHeader.ParentEntry*directoryHeader.EntryLength + 0x04 directoryEntryOffset := directoryHeader.ParentEntry*uint16(directoryHeader.EntryLength) + 0x04
directoryFileEntry := parseFileEntry(buffer[directoryEntryOffset:directoryEntryOffset+0x28], directoryHeader.ParentBlock, directoryHeader.ParentEntry*directoryHeader.EntryLength+0x04) directoryFileEntry := parseFileEntry(buffer[directoryEntryOffset:directoryEntryOffset+0x28], directoryHeader.ParentBlock, directoryHeader.ParentEntry*uint16(directoryHeader.EntryLength)+0x04)
directoryFileEntry.BlocksUsed++ directoryFileEntry.BlocksUsed++
directoryFileEntry.EndOfFile += 0x200 directoryFileEntry.EndOfFile += 0x200
writeFileEntry(readerWriter, directoryFileEntry) writeFileEntry(readerWriter, directoryFileEntry)
@ -305,7 +305,7 @@ func expandDirectory(readerWriter ReaderWriterAt, nextBlockNumber int, buffer []
return nextBlockNumber, nil return nextBlockNumber, nil
} }
func getFileEntriesInDirectory(reader io.ReaderAt, blockNumber int, currentPath int, paths []string) (DirectoryHeader, []FileEntry, error) { func getFileEntriesInDirectory(reader io.ReaderAt, blockNumber uint16, currentPath int, paths []string) (DirectoryHeader, []FileEntry, error) {
buffer, err := ReadBlock(reader, blockNumber) buffer, err := ReadBlock(reader, blockNumber)
if err != nil { if err != nil {
return DirectoryHeader{}, nil, err return DirectoryHeader{}, nil, err
@ -314,9 +314,9 @@ func getFileEntriesInDirectory(reader io.ReaderAt, blockNumber int, currentPath
directoryHeader := parseDirectoryHeader(buffer, blockNumber) directoryHeader := parseDirectoryHeader(buffer, blockNumber)
fileEntries := make([]FileEntry, directoryHeader.ActiveFileCount) fileEntries := make([]FileEntry, directoryHeader.ActiveFileCount)
entryOffset := 43 // start at offset after header entryOffset := uint16(43) // start at offset after header
activeEntries := 0 activeEntries := uint16(0)
entryNumber := 2 // header is essentially the first entry so start at 2 entryNumber := uint8(2) // header is essentially the first entry so start at 2
nextBlock := directoryHeader.NextBlock nextBlock := directoryHeader.NextBlock
@ -338,7 +338,7 @@ func getFileEntriesInDirectory(reader io.ReaderAt, blockNumber int, currentPath
if err != nil { if err != nil {
return DirectoryHeader{}, nil, err return DirectoryHeader{}, nil, err
} }
nextBlock = int(buffer[2]) + int(buffer[3])*256 nextBlock = uint16(buffer[2]) + uint16(buffer[3])*256
} }
fileEntry := parseFileEntry(buffer[entryOffset:entryOffset+40], blockNumber, entryOffset) fileEntry := parseFileEntry(buffer[entryOffset:entryOffset+40], blockNumber, entryOffset)
@ -359,21 +359,21 @@ func getFileEntriesInDirectory(reader io.ReaderAt, blockNumber int, currentPath
} }
} }
func parseFileEntry(buffer []byte, blockNumber int, entryOffset int) FileEntry { func parseFileEntry(buffer []byte, blockNumber uint16, entryOffset uint16) FileEntry {
storageType := int(buffer[0] >> 4) storageType := buffer[0] >> 4
fileNameLength := int(buffer[0] & 15) fileNameLength := buffer[0] & 15
fileName := string(buffer[1 : fileNameLength+1]) fileName := string(buffer[1 : fileNameLength+1])
fileType := int(buffer[16]) fileType := buffer[16]
startingBlock := int(buffer[17]) + int(buffer[18])*256 startingBlock := uint16(buffer[17]) + uint16(buffer[18])*256
blocksUsed := int(buffer[19]) + int(buffer[20])*256 blocksUsed := uint16(buffer[19]) + uint16(buffer[20])*256
endOfFile := int(buffer[21]) + int(buffer[22])*256 + int(buffer[23])*65536 endOfFile := uint32(buffer[21]) + uint32(buffer[22])*256 + uint32(buffer[23])*65536
creationTime := DateTimeFromProDOS(buffer[24:28]) creationTime := DateTimeFromProDOS(buffer[24:28])
version := int(buffer[28]) version := buffer[28]
minVersion := int(buffer[29]) minVersion := buffer[29]
access := int(buffer[30]) access := buffer[30]
auxType := int(buffer[31]) + int(buffer[32])*256 auxType := uint16(buffer[31]) + uint16(buffer[32])*256
modifiedTime := DateTimeFromProDOS((buffer[33:37])) modifiedTime := DateTimeFromProDOS((buffer[33:37]))
headerPointer := int(buffer[0x25]) + int(buffer[0x26])*256 headerPointer := uint16(buffer[0x25]) + uint16(buffer[0x26])*256
fileEntry := FileEntry{ fileEntry := FileEntry{
StorageType: storageType, StorageType: storageType,
@ -427,24 +427,24 @@ func writeFileEntry(writer io.WriterAt, fileEntry FileEntry) {
buffer[0x26] = byte(fileEntry.HeaderPointer >> 8) buffer[0x26] = byte(fileEntry.HeaderPointer >> 8)
//fmt.Printf("Writing file entry at block: %04X offset: %04X\n", fileEntry.DirectoryBlock, fileEntry.DirectoryOffset) //fmt.Printf("Writing file entry at block: %04X offset: %04X\n", fileEntry.DirectoryBlock, fileEntry.DirectoryOffset)
_, err := writer.WriteAt(buffer, int64(fileEntry.DirectoryBlock*512+fileEntry.DirectoryOffset)) _, err := writer.WriteAt(buffer, int64(fileEntry.DirectoryBlock)*512+int64(fileEntry.DirectoryOffset))
if err != nil { if err != nil {
} }
} }
func parseVolumeHeader(buffer []byte) VolumeHeader { func parseVolumeHeader(buffer []byte) VolumeHeader {
nextBlock := int(buffer[2]) + int(buffer[3])*256 nextBlock := uint16(buffer[2]) + uint16(buffer[3])*256
filenameLength := buffer[4] & 15 filenameLength := buffer[4] & 15
volumeName := string(buffer[5 : filenameLength+5]) volumeName := string(buffer[5 : filenameLength+5])
creationTime := DateTimeFromProDOS(buffer[28:32]) creationTime := DateTimeFromProDOS(buffer[28:32])
version := int(buffer[32]) version := buffer[32]
minVersion := int(buffer[33]) minVersion := buffer[33]
entryLength := int(buffer[35]) entryLength := buffer[35]
entriesPerBlock := int(buffer[36]) entriesPerBlock := buffer[36]
fileCount := int(buffer[37]) + int(buffer[38])*256 fileCount := uint16(buffer[37]) + uint16(buffer[38])*256
bitmapBlock := int(buffer[39]) + int(buffer[40])*256 bitmapBlock := uint16(buffer[39]) + uint16(buffer[40])*256
totalBlocks := int(buffer[41]) + int(buffer[42])*256 totalBlocks := uint16(buffer[41]) + uint16(buffer[42])*256
if minVersion > 0 { if minVersion > 0 {
panic("Unsupported ProDOS version") panic("Unsupported ProDOS version")
@ -465,22 +465,22 @@ func parseVolumeHeader(buffer []byte) VolumeHeader {
return volumeHeader return volumeHeader
} }
func parseDirectoryHeader(buffer []byte, blockNumber int) DirectoryHeader { func parseDirectoryHeader(buffer []byte, blockNumber uint16) DirectoryHeader {
previousBlock := int(buffer[0x00]) + int(buffer[0x01])*256 previousBlock := uint16(buffer[0x00]) + uint16(buffer[0x01])*256
nextBlock := int(buffer[0x02]) + int(buffer[0x03])*256 nextBlock := uint16(buffer[0x02]) + uint16(buffer[0x03])*256
isSubDirectory := (buffer[0x04] & 0xF0) == 0xE0 isSubDirectory := (buffer[0x04] & 0xF0) == 0xE0
filenameLength := buffer[0x04] & 0x0F filenameLength := buffer[0x04] & 0x0F
name := string(buffer[0x05 : filenameLength+0x05]) name := string(buffer[0x05 : filenameLength+0x05])
creationTime := DateTimeFromProDOS(buffer[0x1C:0x20]) creationTime := DateTimeFromProDOS(buffer[0x1C:0x20])
version := int(buffer[0x20]) version := buffer[0x20]
minVersion := int(buffer[0x21]) minVersion := buffer[0x21]
access := int(buffer[0x22]) access := buffer[0x22]
entryLength := int(buffer[0x23]) entryLength := buffer[0x23]
entriesPerBlock := int(buffer[0x24]) entriesPerBlock := buffer[0x24]
fileCount := int(buffer[0x25]) + int(buffer[0x26])*256 fileCount := uint16(buffer[0x25]) + uint16(buffer[0x26])*256
parentBlock := int(buffer[0x27]) + int(buffer[0x28])*256 parentBlock := uint16(buffer[0x27]) + uint16(buffer[0x28])*256
parentEntry := int(buffer[0x29]) parentEntry := uint16(buffer[0x29])
parentEntryLength := int(buffer[0x2A]) parentEntryLength := buffer[0x2A]
directoryEntry := DirectoryHeader{ directoryEntry := DirectoryHeader{
PreviousBlock: previousBlock, PreviousBlock: previousBlock,

View File

@ -29,12 +29,12 @@ func LoadFile(reader io.ReaderAt, path string) ([]byte, error) {
buffer := make([]byte, fileEntry.EndOfFile) buffer := make([]byte, fileEntry.EndOfFile)
for i := 0; i < len(blockList); i++ { for i := uint16(0); i < uint16(len(blockList)); i++ {
block, err := ReadBlock(reader, blockList[i]) block, err := ReadBlock(reader, blockList[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
for j := 0; j < 512 && i*512+j < fileEntry.EndOfFile; j++ { for j := uint16(0); j < 512 && uint32(i)*512+uint32(j) < fileEntry.EndOfFile; j++ {
buffer[i*512+j] = block[j] buffer[i*512+j] = block[j]
} }
} }
@ -43,7 +43,7 @@ func LoadFile(reader io.ReaderAt, path string) ([]byte, error) {
} }
// WriteFile writes a file to a ProDOS volume from a byte array // WriteFile writes a file to a ProDOS volume from a byte array
func WriteFile(readerWriter ReaderWriterAt, path string, fileType int, auxType int, createdTime time.Time, modifiedTime time.Time, buffer []byte) error { func WriteFile(readerWriter ReaderWriterAt, path string, fileType uint8, auxType uint16, createdTime time.Time, modifiedTime time.Time, buffer []byte) error {
directory, fileName := GetDirectoryAndFileNameFromPath(path) directory, fileName := GetDirectoryAndFileNameFromPath(path)
if len(fileName) > 15 { if len(fileName) > 15 {
@ -56,7 +56,7 @@ func WriteFile(readerWriter ReaderWriterAt, path string, fileType int, auxType i
} }
// get list of blocks to write file to // get list of blocks to write file to
blockList, err := createBlockList(readerWriter, len(buffer)) blockList, err := createBlockList(readerWriter, uint32(len(buffer)))
if err != nil { if err != nil {
return err return err
} }
@ -88,11 +88,11 @@ func WriteFile(readerWriter ReaderWriterAt, path string, fileType int, auxType i
return err return err
} }
fileEntry.FileName = fileName fileEntry.FileName = fileName
fileEntry.BlocksUsed = len(blockList) fileEntry.BlocksUsed = uint16(len(blockList))
fileEntry.CreationTime = createdTime fileEntry.CreationTime = createdTime
fileEntry.ModifiedTime = modifiedTime fileEntry.ModifiedTime = modifiedTime
fileEntry.AuxType = auxType fileEntry.AuxType = auxType
fileEntry.EndOfFile = len(buffer) fileEntry.EndOfFile = uint32(len(buffer))
fileEntry.FileType = fileType fileEntry.FileType = fileType
fileEntry.KeyPointer = blockList[0] fileEntry.KeyPointer = blockList[0]
fileEntry.Version = 0x24 fileEntry.Version = 0x24
@ -197,24 +197,24 @@ func GetDirectoryAndFileNameFromPath(path string) (string, string) {
return directory, fileName return directory, fileName
} }
func updateVolumeBitmap(readerWriter ReaderWriterAt, blockList []int) error { func updateVolumeBitmap(readerWriter ReaderWriterAt, blockList []uint16) error {
volumeBitmap, err := ReadVolumeBitmap(readerWriter) volumeBitmap, err := ReadVolumeBitmap(readerWriter)
if err != nil { if err != nil {
fmt.Printf("%s", err) fmt.Printf("%s", err)
return err return err
} }
for i := 0; i < len(blockList); i++ { for i := uint16(0); i < uint16(len(blockList)); i++ {
markBlockInVolumeBitmap(volumeBitmap, blockList[i]) markBlockInVolumeBitmap(volumeBitmap, blockList[i])
} }
return writeVolumeBitmap(readerWriter, volumeBitmap) return writeVolumeBitmap(readerWriter, volumeBitmap)
} }
func writeSeedlingFile(writer io.WriterAt, buffer []byte, blockList []int) { func writeSeedlingFile(writer io.WriterAt, buffer []byte, blockList []uint16) {
WriteBlock(writer, blockList[0], buffer) WriteBlock(writer, blockList[0], buffer)
} }
func writeSaplingFile(writer io.WriterAt, buffer []byte, blockList []int) { func writeSaplingFile(writer io.WriterAt, buffer []byte, blockList []uint16) {
// write index block with pointers to data blocks // write index block with pointers to data blocks
indexBuffer := make([]byte, 512) indexBuffer := make([]byte, 512)
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
@ -249,7 +249,7 @@ func writeSaplingFile(writer io.WriterAt, buffer []byte, blockList []int) {
} }
} }
func writeTreeFile(writer io.WriterAt, buffer []byte, blockList []int) { func writeTreeFile(writer io.WriterAt, buffer []byte, blockList []uint16) {
// write master index block with pointers to index blocks // write master index block with pointers to index blocks
indexBuffer := make([]byte, 512) indexBuffer := make([]byte, 512)
numberOfIndexBlocks := len(blockList)/256 + 1 numberOfIndexBlocks := len(blockList)/256 + 1
@ -303,17 +303,17 @@ func writeTreeFile(writer io.WriterAt, buffer []byte, blockList []int) {
} }
} }
func getDataBlocklist(reader io.ReaderAt, fileEntry FileEntry) ([]int, error) { func getDataBlocklist(reader io.ReaderAt, fileEntry FileEntry) ([]uint16, error) {
return getBlocklist(reader, fileEntry, true) return getBlocklist(reader, fileEntry, true)
} }
func getAllBlockList(reader io.ReaderAt, fileEntry FileEntry) ([]int, error) { func getAllBlockList(reader io.ReaderAt, fileEntry FileEntry) ([]uint16, error) {
return getBlocklist(reader, fileEntry, false) return getBlocklist(reader, fileEntry, false)
} }
// Returns all blocks, including index blocks // Returns all blocks, including index blocks
func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]int, error) { func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]uint16, error) {
blocks := make([]int, fileEntry.BlocksUsed) blocks := make([]uint16, fileEntry.BlocksUsed)
switch fileEntry.StorageType { switch fileEntry.StorageType {
case StorageSeedling: case StorageSeedling:
@ -324,10 +324,10 @@ func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]int
if err != nil { if err != nil {
return nil, err return nil, err
} }
blockOffset := 1 blockOffset := uint16(1)
blocks[0] = fileEntry.KeyPointer blocks[0] = fileEntry.KeyPointer
for i := 0; i < fileEntry.BlocksUsed-1; i++ { for i := uint16(0); i < fileEntry.BlocksUsed-1; i++ {
blocks[i+blockOffset] = int(index[i]) + int(index[i+256])*256 blocks[i+blockOffset] = uint16(index[i]) + uint16(index[i+256])*256
} }
if dataOnly { if dataOnly {
return blocks[1:], nil return blocks[1:], nil
@ -335,10 +335,10 @@ func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]int
return blocks, nil return blocks, nil
case StorageTree: case StorageTree:
// this is actually too large // this is actually too large
dataBlocks := make([]int, fileEntry.BlocksUsed) dataBlocks := make([]uint16, fileEntry.BlocksUsed)
// this is also actually too large // this is also actually too large
numberOfIndexBlocks := fileEntry.BlocksUsed/256 + 2 numberOfIndexBlocks := fileEntry.BlocksUsed/256 + 2
indexBlocks := make([]int, numberOfIndexBlocks) indexBlocks := make([]uint16, numberOfIndexBlocks)
masterIndex, err := ReadBlock(reader, fileEntry.KeyPointer) masterIndex, err := ReadBlock(reader, fileEntry.KeyPointer)
if err != nil { if err != nil {
return nil, err return nil, err
@ -348,8 +348,8 @@ func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]int
indexBlocks[0] = fileEntry.KeyPointer indexBlocks[0] = fileEntry.KeyPointer
indexBlockCount := 1 indexBlockCount := 1
for i := 0; i < 128; i++ { for i := uint16(0); i < 128; i++ {
indexBlock := int(masterIndex[i]) + int(masterIndex[i+256])*256 indexBlock := uint16(masterIndex[i]) + uint16(masterIndex[i+256])*256
if indexBlock == 0 { if indexBlock == 0 {
break break
} }
@ -359,12 +359,12 @@ func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]int
if err != nil { if err != nil {
return nil, err return nil, err
} }
for j := 0; j < 256 && i*256+j < fileEntry.BlocksUsed; j++ { for j := uint16(0); j < 256 && i*256+j < fileEntry.BlocksUsed; j++ {
if (int(index[j]) + int(index[j+256])*256) == 0 { if (uint16(index[j]) + uint16(index[j+256])*256) == 0 {
break break
} }
numberOfDataBlocks++ numberOfDataBlocks++
dataBlocks[i*256+j] = int(index[j]) + int(index[j+256])*256 dataBlocks[i*256+j] = uint16(index[j]) + uint16(index[j+256])*256
} }
} }
@ -379,8 +379,8 @@ func getBlocklist(reader io.ReaderAt, fileEntry FileEntry, dataOnly bool) ([]int
return nil, errors.New("unsupported file storage type") return nil, errors.New("unsupported file storage type")
} }
func createBlockList(reader io.ReaderAt, fileSize int) ([]int, error) { func createBlockList(reader io.ReaderAt, fileSize uint32) ([]uint16, error) {
numberOfBlocks := fileSize / 512 numberOfBlocks := uint16(fileSize / 512)
if fileSize%512 > 0 { if fileSize%512 > 0 {
numberOfBlocks++ numberOfBlocks++

View File

@ -11,8 +11,8 @@ import (
func TestCreateBlocklist(t *testing.T) { func TestCreateBlocklist(t *testing.T) {
var tests = []struct { var tests = []struct {
fileSize int fileSize uint32
wantBlocks int wantBlocks uint16
}{ }{
{1, 1}, {1, 1},
{512, 1}, {512, 1},
@ -33,7 +33,7 @@ func TestCreateBlocklist(t *testing.T) {
if err != nil { if err != nil {
t.Error("got error, want nil") t.Error("got error, want nil")
} }
if len(blockList) != tt.wantBlocks { if uint16(len(blockList)) != tt.wantBlocks {
t.Errorf("got %d blocks, want %d", len(blockList), tt.wantBlocks) t.Errorf("got %d blocks, want %d", len(blockList), tt.wantBlocks)
} }
}) })
@ -41,7 +41,7 @@ func TestCreateBlocklist(t *testing.T) {
} }
func TestUpdateVolumeBitmap(t *testing.T) { func TestUpdateVolumeBitmap(t *testing.T) {
blockList := []int{10, 11, 12, 100, 120} blockList := []uint16{10, 11, 12, 100, 120}
virtualDisk := NewMemoryFile(0x2000000) virtualDisk := NewMemoryFile(0x2000000)
CreateVolume(virtualDisk, "VIRTUAL.DISK", 0xFFFE) CreateVolume(virtualDisk, "VIRTUAL.DISK", 0xFFFE)

View File

@ -14,7 +14,7 @@ import (
// CreateVolume formats a new ProDOS volume including boot block, // CreateVolume formats a new ProDOS volume including boot block,
// volume bitmap and empty directory // volume bitmap and empty directory
func CreateVolume(readerWriter ReaderWriterAt, volumeName string, numberOfBlocks int) { func CreateVolume(readerWriter ReaderWriterAt, volumeName string, numberOfBlocks uint16) {
if numberOfBlocks > 65535 || numberOfBlocks < 64 { if numberOfBlocks > 65535 || numberOfBlocks < 64 {
return return
} }
@ -26,7 +26,7 @@ func CreateVolume(readerWriter ReaderWriterAt, volumeName string, numberOfBlocks
} }
blankBlock := make([]byte, 512) blankBlock := make([]byte, 512)
for i := 0; i < numberOfBlocks; i++ { for i := uint16(0); i < numberOfBlocks; i++ {
WriteBlock(readerWriter, i, blankBlock) WriteBlock(readerWriter, i, blankBlock)
} }

View File

@ -13,9 +13,9 @@ import (
func TestCreateVolume(t *testing.T) { func TestCreateVolume(t *testing.T) {
var tests = []struct { var tests = []struct {
blocks int blocks uint16
wantVolumeName string wantVolumeName string
wantFreeBlocks int wantFreeBlocks uint16
}{ }{
{65535, "MAX", 65513}, {65535, "MAX", 65513},
{65500, "ALMOST.MAX", 65478}, {65500, "ALMOST.MAX", 65478},

View File

@ -12,6 +12,8 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -75,8 +77,8 @@ func AddFilesFromHostDirectory(
func WriteFileFromFile( func WriteFileFromFile(
readerWriter ReaderWriterAt, readerWriter ReaderWriterAt,
pathName string, pathName string,
fileType int, fileType uint8,
auxType int, auxType uint16,
modifiedTime time.Time, modifiedTime time.Time,
inFileName string, inFileName string,
ignoreDuplicates bool, ignoreDuplicates bool,
@ -117,6 +119,11 @@ func WriteFileFromFile(
case ".SYS", ".TXT", ".BAS", ".BIN": case ".SYS", ".TXT", ".BAS", ".BIN":
pathName = strings.TrimSuffix(pathName, ext) pathName = strings.TrimSuffix(pathName, ext)
} }
match, err := regexp.MatchString("^\\.(BIN|SYS|TXT|BAS)\\$[0-9]{4}", ext)
if err == nil && match {
pathName = strings.TrimSuffix(pathName, ext)
}
} }
} }
@ -140,9 +147,12 @@ func WriteFileFromFile(
return WriteFile(readerWriter, pathName, fileType, auxType, time.Now(), modifiedTime, inFile) return WriteFile(readerWriter, pathName, fileType, auxType, time.Now(), modifiedTime, inFile)
} }
func convertFileByType(inFileName string, inFile []byte) (int, int, []byte, error) { func convertFileByType(inFileName string, inFile []byte) (uint16, uint8, []byte, error) {
fileType := 0x06 // default to BIN var auxType uint16
auxType := 0x2000 // default to $2000 var fileType uint8
fileType = 0x06 // default to BIN
auxType = 0x2000 // default to $2000
var err error var err error
@ -166,36 +176,57 @@ func convertFileByType(inFileName string, inFile []byte) (int, int, []byte, erro
// Length // Length
binary.BigEndian.Uint32(inFile[0x2E:]) == 0x00000008 { binary.BigEndian.Uint32(inFile[0x2E:]) == 0x00000008 {
fileType = int(binary.BigEndian.Uint16(inFile[0x34:])) fileType = uint8(binary.BigEndian.Uint16(inFile[0x34:]))
auxType = int(binary.BigEndian.Uint32(inFile[0x36:])) auxType = uint16(binary.BigEndian.Uint32(inFile[0x36:]))
inFile = inFile[0x3A:] inFile = inFile[0x3A:]
} else { } else {
// use extension to determine file type // use extension to determine file type
ext := strings.ToUpper(filepath.Ext(inFileName)) ext := strings.ToUpper(filepath.Ext(inFileName))
switch ext { match, err := regexp.MatchString("^\\.(BIN|SYS|TXT|BAS)\\$[0-9]{4}", ext)
case ".BAS":
inFile, err = ConvertTextToBasic(string(inFile))
fileType = 0xFC
auxType = 0x0801
if err == nil && match {
parts := strings.Split(ext, "$")
extAuxType, err := strconv.ParseUint(parts[1], 16, 16)
if err != nil { if err != nil {
return 0, 0, nil, err return 0, 0, nil, err
} }
case ".SYS": auxType = uint16(extAuxType)
fileType = 0xFF switch parts[0] {
auxType = 0x2000 case ".BAS":
case ".BIN": fileType = 0xFC
fileType = 0x06 case ".SYS":
auxType = 0x2000 fileType = 0xFF
case ".TXT": case ".BIN":
inFile = []byte(strings.ReplaceAll(strings.ReplaceAll(string(inFile), "\r\n", "r"), "\n", "\r")) fileType = 0x06
fileType = 0x04 case ".TXT":
auxType = 0x0000 fileType = 0x04
case ".JPG", ".PNG": }
inFile = ConvertImageToHiResMonochrome(inFile) } else {
fileType = 0x06 switch ext {
auxType = 0x2000 case ".BAS":
inFile, err = ConvertTextToBasic(string(inFile))
fileType = 0xFC
auxType = 0x0801
if err != nil {
return 0, 0, nil, err
}
case ".SYS":
fileType = 0xFF
auxType = 0x2000
case ".BIN":
fileType = 0x06
auxType = 0x2000
case ".TXT":
inFile = []byte(strings.ReplaceAll(strings.ReplaceAll(string(inFile), "\r\n", "r"), "\n", "\r"))
fileType = 0x04
auxType = 0x0000
case ".JPG", ".PNG":
inFile = ConvertImageToHiResMonochrome(inFile)
fileType = 0x06
auxType = 0x2000
}
} }
} }

View File

@ -25,7 +25,7 @@ func TimeToString(printTime time.Time) string {
} }
// FileTypeToString display the file type as a string // FileTypeToString display the file type as a string
func FileTypeToString(fileType int) string { func FileTypeToString(fileType uint8) string {
switch fileType { switch fileType {
case 1: case 1:
return "BAD" return "BAD"
@ -159,7 +159,7 @@ func DumpBlock(buffer []byte) {
} }
// DumpDirectory displays the directory similar to ProDOS catalog // DumpDirectory displays the directory similar to ProDOS catalog
func DumpDirectory(blocksFree int, totalBlocks int, path string, fileEntries []FileEntry) { func DumpDirectory(blocksFree uint16, totalBlocks uint16, path string, fileEntries []FileEntry) {
fmt.Printf("%s\n\n", path) fmt.Printf("%s\n\n", path)
fmt.Printf("NAME TYPE BLOCKS MODIFIED CREATED ENDFILE SUBTYPE\n\n") fmt.Printf("NAME TYPE BLOCKS MODIFIED CREATED ENDFILE SUBTYPE\n\n")