Skip to content
This repository was archived by the owner on Sep 10, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 12 additions & 36 deletions cpm/cpm_bdos.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,8 +635,10 @@ func BdosSysCallFileClose(cpm *CPM) error {

// BdosSysCallFindFirst finds the first filename, on disk, that matches the glob in the FCB supplied in DE.
func BdosSysCallFindFirst(cpm *CPM) error {

// The pointer to the FCB
ptr := cpm.CPU.States.DE.U16()

// Get the bytes which make up the FCB entry.
xxx := cpm.Memory.GetRange(ptr, fcb.SIZE)

Expand Down Expand Up @@ -727,25 +729,12 @@ func BdosSysCallFindFirst(cpm *CPM) error {
// Create a new FCB and store it in the DMA entry
x := fcb.FromString(res[0].Name)

// Get the file-size in records, and add to the FCB
tmp, err := os.OpenFile(res[0].Host, os.O_RDONLY, 0644)
if err == nil {
defer tmp.Close()

fi, err := tmp.Stat()
if err == nil {

fileSize := fi.Size()
// Get file size, in blocks.
x.RC = uint8(res[0].Size / blkSize)

// Get file size, in blocks
x.RC = uint8(fileSize / blkSize)

// If the size is bigger than a multiple we deal with that.
if fileSize > int64(int64(x.RC)*int64(blkSize)) {
x.RC++
}

}
// If the size is bigger than a multiple we deal with that.
if res[0].Size > int64(int64(x.RC)*int64(blkSize)) {
x.RC++
}

// Log the first result we're returning.
Expand Down Expand Up @@ -783,25 +772,12 @@ func BdosSysCallFindNext(cpm *CPM) error {
// Create a new FCB and store it in the DMA entry
x := fcb.FromString(res.Name)

// Get the file-size in records, and add to the FCB
tmp, err := os.OpenFile(res.Host, os.O_RDONLY, 0644)
if err == nil {
defer tmp.Close()

fi, err := tmp.Stat()
if err == nil {

fileSize := fi.Size()

// Get file size, in blocks
x.RC = uint8(fileSize / blkSize)
// Get file size, in blocks.
x.RC = uint8(res.Size / blkSize)

// If the size is bigger than a multiple we deal with that.
if fileSize > int64(int64(x.RC)*int64(blkSize)) {
x.RC++
}

}
// If the size is bigger than a multiple we deal with that.
if res.Size > int64(int64(x.RC)*int64(blkSize)) {
x.RC++
}

// Log that we're returning the next result.
Expand Down
37 changes: 22 additions & 15 deletions fcb/fcb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
package fcb

import (
"io/fs"
"log/slog"
"os"
"path/filepath"
"strings"
"unicode"
Expand Down Expand Up @@ -71,6 +71,9 @@ type Find struct {
// Name is the name as CP/M would see it.
// This will be upper-cased and in 8.3 format.
Name string

// Size contains the size of the file.
Size int64
}

// GetName returns the name component of an FCB entry.
Expand Down Expand Up @@ -377,36 +380,40 @@ func (f *FCB) DoesMatch(name string) bool {
func (f *FCB) GetMatches(prefix string) ([]Find, error) {
var ret []Find

// Find files in the directory
files, err := os.ReadDir(prefix)
if err != nil {
return ret, err
}
err := filepath.Walk(prefix, func(path string, info fs.FileInfo, err error) error {

// For each file
for _, file := range files {
if err != nil {
return err
}

// Ignore directories, we only care about files.
if file.IsDir() {
continue
if info.IsDir() {
return nil
}

name := strings.ToUpper(file.Name())
// Upper-case, and remove prefix.
name := filepath.Base(strings.ToUpper(path))

if f.DoesMatch(name) {

var ent Find

// Populate the host-path before we do anything else.
ent.Host = filepath.Join(prefix, file.Name())
ent.Host = filepath.Join(path)

// populate the name, but note it needs to be upper-cased
// populate the name
ent.Name = name

// populate the size too
ent.Size = info.Size()

// append
ret = append(ret, ent)
}
}

return nil
})

// Return the entries we found, if any.
return ret, nil
return ret, err
}
24 changes: 21 additions & 3 deletions fcb/fcb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fcb

import (
"fmt"
"sort"
"testing"
)

Expand Down Expand Up @@ -207,13 +208,30 @@ func TestGetMatches(t *testing.T) {
t.Fatalf("failed to get matches")
}

if len(out) != 1 {
t.Fatalf("unexpected number of matches")
if len(out) < 10 {
t.Fatalf("unexpected number of matches got %d", len(out))
}
if out[0].Host != "../main.go" {

// sort the files - so we can be predictable
sort.Slice(out, func(i, j int) bool {
return out[i].Name < out[j].Name
})

// first file, alphabetically
if out[0].Host != "../ccp/ccp.go" {
t.Fatalf("unexpected name %s", out[0].Host)
}

found := false
for _, e := range out {
if e.Host == "../static/static.go" {
found = true
}
}
if !found {
t.Fatalf("failed to find static.go")
}

_, err = f.GetMatches("!>>//path/not/found")
if err == nil {
t.Fatalf("expected error on bogus directory, got none")
Expand Down