Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement sequential file read #24

Merged
merged 1 commit into from
Apr 16, 2024
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
4 changes: 4 additions & 0 deletions cpm/cpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ func New(filename string, logger *slog.Logger) *CPM {
Desc: "F_DELETE",
Handler: SysCallDeleteFile,
}
sys[20] = CPMHandler{
Desc: "F_READ",
Handler: SysCallRead,
}
sys[21] = CPMHandler{
Desc: "F_WRITE",
Handler: SysCallWrite,
Expand Down
73 changes: 72 additions & 1 deletion cpm/cpm_syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,77 @@ func SysCallDeleteFile(cpm *CPM) error {
return err
}

// SysCallRead writes a record to the file named in the FCB given in DE
func SysCallRead(cpm *CPM) error {

// Don't have a file open? That's a bug
if !cpm.fileIsOpen {
cpm.Logger.Error("attempting to write to a file that isn't open")
cpm.CPU.States.AF.Hi = 0xff
return nil
}

// 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, 36)

// Create a structure with the contents
fcbPtr := fcb.FromBytes(xxx)

// offset
BlkS2 := 4096
BlkEx := 128
offset := int(int(fcbPtr.S2)&MaxS2)*BlkS2*blkSize +
int(fcbPtr.Ex)*BlkEx*blkSize +
int(fcbPtr.Cr)*blkSize

_, err := cpm.file.Seek(int64(offset), io.SeekStart)
if err != nil {
return fmt.Errorf("cannot seek to position %d: %s", offset, err)
}

// Temporary area to read into
data := make([]byte, blkSize)

// Fill the area with data
for i := range data {
data[i] = 0x1a
}

// Read from the file, now we're in the right place
_, err = cpm.file.Read(data)
if err != nil {
return fmt.Errorf("error writing to file %s", err)
}

// Copy the data to the DMA area
cpm.Memory.PutRange(dma, data[:]...)

MaxCR := 128
MaxEX := 31

fcbPtr.S2 &= 0x7F // reset unmodified flag
fcbPtr.Cr++
if int(fcbPtr.Cr) > MaxCR {
fcbPtr.Cr = 1
fcbPtr.Ex++
}
if int(fcbPtr.Ex) > MaxEX {
fcbPtr.Ex = 0
fcbPtr.S2++
}
fcbPtr.RC++

// Update the FCB in memory
cpm.Memory.PutRange(ptr, fcbPtr.AsBytes()...)

// All done
cpm.CPU.States.AF.Hi = 0x00
return nil

}

// SysCallWrite writes a record to the file named in the FCB given in DE
func SysCallWrite(cpm *CPM) error {

Expand Down Expand Up @@ -506,7 +577,7 @@ func SysCallReadRand(cpm *CPM) error {
return 1
}

cpm.Memory.PutRange(0x80, data[:]...)
cpm.Memory.PutRange(dma, data[:]...)
return 0
}

Expand Down
Loading