From 07e0bacab39ec9f1ab3efef0d32fb45c53c98e85 Mon Sep 17 00:00:00 2001 From: Terence Boldt Date: Thu, 1 Jul 2021 22:35:26 -0400 Subject: [PATCH] Add format test, fix dump block and bitmap bug --- prodos/bitmap.go | 28 +++++++++++++++++++++---- prodos/format_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++ prodos/text.go | 2 +- 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 prodos/format_test.go diff --git a/prodos/bitmap.go b/prodos/bitmap.go index 7343744..426211f 100644 --- a/prodos/bitmap.go +++ b/prodos/bitmap.go @@ -9,14 +9,23 @@ func ReadVolumeBitmap(file *os.File) []byte { volumeHeader := parseVolumeHeader(headerBlock) - bitmap := make([]byte, volumeHeader.TotalBlocks/8+1) + totalBitmapBytes := volumeHeader.TotalBlocks / 8 + if volumeHeader.TotalBlocks%8 > 0 { + totalBitmapBytes++ + } - totalBitmapBlocks := volumeHeader.TotalBlocks / 8 / 512 + bitmap := make([]byte, totalBitmapBytes) - for i := 0; i <= totalBitmapBlocks; i++ { + totalBitmapBlocks := totalBitmapBytes / 512 + + if totalBitmapBytes%512 > 0 { + totalBitmapBlocks++ + } + + for i := 0; i < totalBitmapBlocks; i++ { bitmapBlock := ReadBlock(file, i+volumeHeader.BitmapStartBlock) - for j := 0; j < 512; j++ { + for j := 0; j < 512 && i*512+j < totalBitmapBytes; j++ { bitmap[i*512+j] = bitmapBlock[j] } } @@ -92,6 +101,17 @@ func findFreeBlocks(volumeBitmap []byte, numberOfBlocks int) []int { 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) { bitToChange := blockNumber % 8 byteToChange := blockNumber / 8 diff --git a/prodos/format_test.go b/prodos/format_test.go new file mode 100644 index 0000000..f935d13 --- /dev/null +++ b/prodos/format_test.go @@ -0,0 +1,49 @@ +package prodos + +import ( + "fmt" + "os" + "testing" +) + +func TestCreateVolume(t *testing.T) { + var tests = []struct { + blocks int + wantVolumeName string + wantFreeBlocks int + }{ + {65535, "MAX", 65513}, + {65500, "ALMOST.MAX", 65478}, + {280, "FLOPPY", 273}, + } + + for _, tt := range tests { + testname := fmt.Sprintf("%d", tt.blocks) + t.Run(testname, func(t *testing.T) { + fileName := os.TempDir() + "test-volume.hdv" + os.Remove(fileName) + CreateVolume(fileName, tt.wantVolumeName, tt.blocks) + + file, err := os.Open(fileName) + if err != nil { + t.Error(err) + } + volumeHeader, _, fileEntries := ReadDirectory(file, "") + if volumeHeader.VolumeName != tt.wantVolumeName { + t.Errorf("got volume name %s, want %s", volumeHeader.VolumeName, tt.wantVolumeName) + } + if volumeHeader.TotalBlocks != tt.blocks { + t.Errorf("got total blocks %d, want %d", volumeHeader.TotalBlocks, tt.blocks) + } + if len(fileEntries) > 0 { + t.Errorf("got files %d, want 0", len(fileEntries)) + } + + volumeBitmap := ReadVolumeBitmap(file) + freeBlockCount := getFreeBlockCount(volumeBitmap, tt.blocks) + if freeBlockCount != tt.wantFreeBlocks { + t.Errorf("got free blocks: %d, want %d", freeBlockCount, tt.wantFreeBlocks) + } + }) + } +} diff --git a/prodos/text.go b/prodos/text.go index 201e7ef..5c86789 100644 --- a/prodos/text.go +++ b/prodos/text.go @@ -120,7 +120,7 @@ func DumpBlock(buffer []byte) { } for j := i; j < i+16; j++ { c := buffer[j] & 127 - if c >= 32 { + if c >= 32 && c < 127 { fmt.Printf("%c", c) } else { fmt.Printf(".")