Skip to content

Commit

Permalink
Moved the sequential read offset calculations into the FCB object
Browse files Browse the repository at this point in the history
This makes sense as they are used for the F_READ/F_WRITE syscalls
so there's no point duplicating them needlessly.  Now both calls
can get the current read/write offset, and increment it (i.e. move
to the next block) via FCB-calls.
  • Loading branch information
skx committed Apr 16, 2024
1 parent 6f536c5 commit 31ab824
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 43 deletions.
53 changes: 10 additions & 43 deletions cpm/cpm_syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ const maxRC = 128
// dma holds the default DMA address
const dma = 0x80

const MaxS2 = 15

// SysCallExit implements the Exit syscall
func SysCallExit(cpm *CPM) error {
return ErrExit
Expand Down Expand Up @@ -372,12 +370,8 @@ func SysCallRead(cpm *CPM) error {
// 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
// Get the next read position
offset := fcbPtr.GetSequentialOffset()

_, err := cpm.file.Seek(int64(offset), io.SeekStart)
if err != nil {
Expand All @@ -401,20 +395,8 @@ func SysCallRead(cpm *CPM) error {
// 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 next read position
fcbPtr.IncreaseSequentialOffset()

// Update the FCB in memory
cpm.Memory.PutRange(ptr, fcbPtr.AsBytes()...)
Expand Down Expand Up @@ -443,16 +425,13 @@ func SysCallWrite(cpm *CPM) error {
// Create a structure with the contents
fcbPtr := fcb.FromBytes(xxx)

// Get the next write position
offset := fcbPtr.GetSequentialOffset()

// Get the data range from the DMA area
data := cpm.Memory.GetRange(dma, 128)

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

// Move to the correct place
_, err := cpm.file.Seek(int64(offset), io.SeekStart)
if err != nil {
return fmt.Errorf("cannot seek to position %d: %s", offset, err)
Expand All @@ -464,20 +443,8 @@ func SysCallWrite(cpm *CPM) error {
return fmt.Errorf("error writing to file %s", err)
}

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 next write position
fcbPtr.IncreaseSequentialOffset()

// Update the FCB in memory
cpm.Memory.PutRange(ptr, fcbPtr.AsBytes()...)
Expand Down
40 changes: 40 additions & 0 deletions fcb/fcb.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,46 @@ func (f *FCB) AsBytes() []uint8 {
return r
}

// GetSequentialOffset returns the offset the FCB contains for
// the sequential read/write calls - as used by the BDOS functions
// F_READ and F_WRITE.
//
// IncreaseSequentialOffset updates the value
func (f *FCB) GetSequentialOffset() int64 {

// Helpers
BlkS2 := 4096
BlkEx := 128
MaxS2 := 15
blkSize := 128

offset := int64((int(f.S2)&MaxS2)*BlkS2*blkSize +
int(f.Ex)*BlkEx*blkSize +
int(f.Cr)*blkSize)
return offset
}

// IncreaseSequentialOffset updates the read/write offset which
// would be used for the sequential read functions.
func (f *FCB) IncreaseSequentialOffset() {

MaxCR := 128
MaxEX := 31

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

}

// FromString returns an FCB entry from the given string.
//
// This is currently just used for processing command-line arguments.
Expand Down

0 comments on commit 31ab824

Please sign in to comment.