mirror of
https://github.com/tjboldt/ProDOS-Utilities.git
synced 2024-12-27 20:29:18 +00:00
Improve comments for documentation
This commit is contained in:
parent
b295288d05
commit
ea08fd6edc
@ -151,4 +151,4 @@ ProDOS-Utilities -d ../Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.hdv -c get -o Upd
|
|||||||
1060 NEXT PG
|
1060 NEXT PG
|
||||||
1900 PRINT
|
1900 PRINT
|
||||||
2000 PRINT "Firmware Update Complete"
|
2000 PRINT "Firmware Update Complete"
|
||||||
```
|
```
|
||||||
|
@ -121,6 +121,7 @@ var tokens = map[byte]string{
|
|||||||
0xEA: "MID$",
|
0xEA: "MID$",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConvertBasicToText converts AppleSoft BASIC to text
|
||||||
func ConvertBasicToText(basic []byte) string {
|
func ConvertBasicToText(basic []byte) string {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ReadVolumeBitmap reads the volume bitmap from a ProDOS image
|
||||||
func ReadVolumeBitmap(reader io.ReaderAt) []byte {
|
func ReadVolumeBitmap(reader io.ReaderAt) []byte {
|
||||||
headerBlock := ReadBlock(reader, 2)
|
headerBlock := ReadBlock(reader, 2)
|
||||||
|
|
||||||
@ -40,6 +41,18 @@ func ReadVolumeBitmap(reader io.ReaderAt) []byte {
|
|||||||
return bitmap
|
return bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFreeBlockCount gets the number of free blocks on a ProDOS image
|
||||||
|
func GetFreeBlockCount(volumeBitmap []byte, totalBlocks int) int {
|
||||||
|
freeBlockCount := 0
|
||||||
|
|
||||||
|
for i := 0; i < totalBlocks; i++ {
|
||||||
|
if checkFreeBlockInVolumeBitmap(volumeBitmap, i) {
|
||||||
|
freeBlockCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return freeBlockCount
|
||||||
|
}
|
||||||
|
|
||||||
func writeVolumeBitmap(writer io.WriterAt, reader io.ReaderAt, bitmap []byte) {
|
func writeVolumeBitmap(writer io.WriterAt, reader io.ReaderAt, bitmap []byte) {
|
||||||
headerBlock := ReadBlock(reader, 2)
|
headerBlock := ReadBlock(reader, 2)
|
||||||
|
|
||||||
@ -108,17 +121,6 @@ func findFreeBlocks(volumeBitmap []byte, numberOfBlocks int) []int {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFreeBlockCount(volumeBitmap []byte, totalBlocks int) int {
|
|
||||||
freeBlockCount := 0
|
|
||||||
|
|
||||||
for i := 0; i < totalBlocks; i++ {
|
|
||||||
if checkFreeBlockInVolumeBitmap(volumeBitmap, i) {
|
|
||||||
freeBlockCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return freeBlockCount
|
|
||||||
}
|
|
||||||
|
|
||||||
func markBlockInVolumeBitmap(volumeBitmap []byte, blockNumber int) {
|
func markBlockInVolumeBitmap(volumeBitmap []byte, blockNumber int) {
|
||||||
bitToChange := blockNumber % 8
|
bitToChange := blockNumber % 8
|
||||||
byteToChange := blockNumber / 8
|
byteToChange := blockNumber / 8
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ReadBlock reads a block from a ProDOS volume into a byte array
|
||||||
func ReadBlock(reader io.ReaderAt, block int) []byte {
|
func ReadBlock(reader io.ReaderAt, block int) []byte {
|
||||||
buffer := make([]byte, 512)
|
buffer := make([]byte, 512)
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ func ReadBlock(reader io.ReaderAt, block int) []byte {
|
|||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteBlock writes a block to a ProDOS volume from a byte array
|
||||||
func WriteBlock(writer io.WriterAt, block int, buffer []byte) {
|
func WriteBlock(writer io.WriterAt, block int, buffer []byte) {
|
||||||
writer.WriteAt(buffer, int64(block)*512)
|
writer.WriteAt(buffer, int64(block)*512)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VolumeHeader from ProDOS
|
||||||
type VolumeHeader struct {
|
type VolumeHeader struct {
|
||||||
VolumeName string
|
VolumeName string
|
||||||
CreationTime time.Time
|
CreationTime time.Time
|
||||||
@ -28,6 +29,7 @@ type VolumeHeader struct {
|
|||||||
Version int
|
Version int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DirectoryHeader from ProDOS
|
||||||
type DirectoryHeader struct {
|
type DirectoryHeader struct {
|
||||||
Name string
|
Name string
|
||||||
ActiveFileCount int
|
ActiveFileCount int
|
||||||
@ -45,6 +47,7 @@ const (
|
|||||||
StorageDirectory = 13
|
StorageDirectory = 13
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FileEntry from ProDOS
|
||||||
type FileEntry struct {
|
type FileEntry struct {
|
||||||
StorageType int
|
StorageType int
|
||||||
FileName string
|
FileName string
|
||||||
@ -63,6 +66,8 @@ type FileEntry struct {
|
|||||||
DirectoryOffset int
|
DirectoryOffset int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadDirectory reads the directory information from a specified path
|
||||||
|
// on a ProDOS image
|
||||||
func ReadDirectory(reader io.ReaderAt, path string) (VolumeHeader, DirectoryHeader, []FileEntry) {
|
func ReadDirectory(reader io.ReaderAt, path string) (VolumeHeader, DirectoryHeader, []FileEntry) {
|
||||||
buffer := ReadBlock(reader, 2)
|
buffer := ReadBlock(reader, 2)
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ func LoadFile(reader io.ReaderAt, path string) ([]byte, error) {
|
|||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteFile writes a file to a ProDOS volume from a byte array
|
||||||
func WriteFile(writer io.WriterAt, reader io.ReaderAt, path string, fileType int, auxType int, buffer []byte) error {
|
func WriteFile(writer io.WriterAt, reader io.ReaderAt, path string, fileType int, auxType int, buffer []byte) error {
|
||||||
directory, fileName := GetDirectoryAndFileNameFromPath(path)
|
directory, fileName := GetDirectoryAndFileNameFromPath(path)
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ func WriteFile(writer io.WriterAt, reader io.ReaderAt, path string, fileType int
|
|||||||
|
|
||||||
// TODO: add tree file
|
// TODO: add tree file
|
||||||
if len(buffer) > 0x20000 {
|
if len(buffer) > 0x20000 {
|
||||||
return errors.New("Files > 128KB not supported yet.")
|
return errors.New("files > 128KB not supported yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
updateVolumeBitmap(writer, reader, blockList)
|
updateVolumeBitmap(writer, reader, blockList)
|
||||||
@ -99,6 +100,7 @@ func WriteFile(writer io.WriterAt, reader io.ReaderAt, path string, fileType int
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteFile deletes a file from a ProDOS volume
|
||||||
func DeleteFile(writer io.WriterAt, reader io.ReaderAt, path string) error {
|
func DeleteFile(writer io.WriterAt, reader io.ReaderAt, path string) error {
|
||||||
fileEntry, err := getFileEntry(reader, path)
|
fileEntry, err := getFileEntry(reader, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -137,6 +139,7 @@ func DeleteFile(writer io.WriterAt, reader io.ReaderAt, path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDirectoryAndFileNameFromPath gets the directory and filename from a path
|
||||||
func GetDirectoryAndFileNameFromPath(path string) (string, string) {
|
func GetDirectoryAndFileNameFromPath(path string) (string, string) {
|
||||||
path = strings.ToUpper(path)
|
path = strings.ToUpper(path)
|
||||||
paths := strings.Split(path, "/")
|
paths := strings.Split(path, "/")
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TimeToString displays the date and time in ProDOS format
|
||||||
func TimeToString(printTime time.Time) string {
|
func TimeToString(printTime time.Time) string {
|
||||||
return fmt.Sprintf("%04d-%s-%02d %02d:%02d",
|
return fmt.Sprintf("%04d-%s-%02d %02d:%02d",
|
||||||
printTime.Year(),
|
printTime.Year(),
|
||||||
@ -23,6 +24,7 @@ func TimeToString(printTime time.Time) string {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileTypeToString display the file type as a string
|
||||||
func FileTypeToString(fileType int) string {
|
func FileTypeToString(fileType int) string {
|
||||||
switch fileType {
|
switch fileType {
|
||||||
case 1:
|
case 1:
|
||||||
@ -85,6 +87,7 @@ func FileTypeToString(fileType int) string {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpFileEntry dumps the file entry values as text
|
||||||
func DumpFileEntry(fileEntry FileEntry) {
|
func DumpFileEntry(fileEntry FileEntry) {
|
||||||
fmt.Printf("FileName: %s\n", fileEntry.FileName)
|
fmt.Printf("FileName: %s\n", fileEntry.FileName)
|
||||||
fmt.Printf("Creation time: %d-%s-%d %02d:%02d\n", fileEntry.CreationTime.Year(), fileEntry.CreationTime.Month(), fileEntry.CreationTime.Day(), fileEntry.CreationTime.Hour(), fileEntry.CreationTime.Minute())
|
fmt.Printf("Creation time: %d-%s-%d %02d:%02d\n", fileEntry.CreationTime.Year(), fileEntry.CreationTime.Month(), fileEntry.CreationTime.Day(), fileEntry.CreationTime.Hour(), fileEntry.CreationTime.Minute())
|
||||||
@ -99,6 +102,7 @@ func DumpFileEntry(fileEntry FileEntry) {
|
|||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpVolumeHeader dumps the volume header values as text
|
||||||
func DumpVolumeHeader(volumeHeader VolumeHeader) {
|
func DumpVolumeHeader(volumeHeader VolumeHeader) {
|
||||||
fmt.Printf("Next block: %d\n", volumeHeader.NextBlock)
|
fmt.Printf("Next block: %d\n", volumeHeader.NextBlock)
|
||||||
fmt.Printf("Volume name: %s\n", volumeHeader.VolumeName)
|
fmt.Printf("Volume name: %s\n", volumeHeader.VolumeName)
|
||||||
@ -112,6 +116,7 @@ func DumpVolumeHeader(volumeHeader VolumeHeader) {
|
|||||||
fmt.Printf("Total blocks: %d\n", volumeHeader.TotalBlocks)
|
fmt.Printf("Total blocks: %d\n", volumeHeader.TotalBlocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpDirectoryHeader dumps the directory header as text
|
||||||
func DumpDirectoryHeader(directoryHeader DirectoryHeader) {
|
func DumpDirectoryHeader(directoryHeader DirectoryHeader) {
|
||||||
fmt.Printf("Name: %s\n", directoryHeader.Name)
|
fmt.Printf("Name: %s\n", directoryHeader.Name)
|
||||||
fmt.Printf("File count: %d\n", directoryHeader.ActiveFileCount)
|
fmt.Printf("File count: %d\n", directoryHeader.ActiveFileCount)
|
||||||
@ -120,6 +125,7 @@ func DumpDirectoryHeader(directoryHeader DirectoryHeader) {
|
|||||||
fmt.Printf("Next block: %04X\n", directoryHeader.NextBlock)
|
fmt.Printf("Next block: %04X\n", directoryHeader.NextBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpBlock dumps the block as hexadecimal and text
|
||||||
func DumpBlock(buffer []byte) {
|
func DumpBlock(buffer []byte) {
|
||||||
for i := 0; i < len(buffer); i += 16 {
|
for i := 0; i < len(buffer); i += 16 {
|
||||||
fmt.Printf("%04X: ", i)
|
fmt.Printf("%04X: ", i)
|
||||||
@ -138,6 +144,7 @@ func DumpBlock(buffer []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpDirectory displays the directory similar to ProDOS catalog
|
||||||
func DumpDirectory(blocksFree int, totalBlocks int, path string, fileEntries []FileEntry) {
|
func DumpDirectory(blocksFree int, totalBlocks int, 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")
|
||||||
|
@ -10,21 +10,20 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* 49041 ($BF91) 49040 ($BF90)
|
// DateTimeToProDOS converts Time to ProDOS date time
|
||||||
|
// 49041 ($BF91) 49040 ($BF90)
|
||||||
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
//
|
||||||
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
// 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||||
DATE: | year | month | day |
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
||||||
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
// DATE: | year | month | day |
|
||||||
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
||||||
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
//
|
||||||
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
// 49043 ($BF93) 49042 ($BF92)
|
||||||
TIME: | hour | | minute |
|
//
|
||||||
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
// 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||||
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
||||||
49043 ($BF93) 49042 ($BF92)
|
// TIME: | hour | | minute |
|
||||||
*/
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
func DateTimeToProDOS(dateTime time.Time) []byte {
|
func DateTimeToProDOS(dateTime time.Time) []byte {
|
||||||
year := dateTime.Year() % 100
|
year := dateTime.Year() % 100
|
||||||
month := dateTime.Month()
|
month := dateTime.Month()
|
||||||
@ -41,6 +40,7 @@ func DateTimeToProDOS(dateTime time.Time) []byte {
|
|||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DateTimeToProDOS converts Time from ProDOS date time
|
||||||
func DateTimeFromProDOS(buffer []byte) time.Time {
|
func DateTimeFromProDOS(buffer []byte) time.Time {
|
||||||
if buffer[0] == 0 &&
|
if buffer[0] == 0 &&
|
||||||
buffer[1] == 0 &&
|
buffer[1] == 0 &&
|
||||||
|
Loading…
Reference in New Issue
Block a user