mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-23 00:30:21 +00:00
103 lines
2.3 KiB
Go
103 lines
2.3 KiB
Go
package izapple2
|
|
|
|
import (
|
|
"errors"
|
|
"math/rand"
|
|
|
|
"github.com/ivanizag/izapple2/component"
|
|
"github.com/ivanizag/izapple2/storage"
|
|
)
|
|
|
|
type cardDisk2SequencerDrive struct {
|
|
data *storage.FileWoz
|
|
enabled bool
|
|
writeProtected bool
|
|
currentQuarterTrack int
|
|
|
|
position uint32 // Current position on the track
|
|
positionMax uint32 // As tracks may have different lengths position is related of positionMax of the las track
|
|
|
|
mc3470Buffer uint8 // Four bit buffer to detect weak bits and to add latency
|
|
}
|
|
|
|
func (d *cardDisk2SequencerDrive) insertDiskette(filename string) error {
|
|
data, writeable, err := LoadResource(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
f, err := storage.NewFileWoz(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Discard not supported features
|
|
if f.Info.DiskType != 1 {
|
|
return errors.New("only 5.25 disks are supported")
|
|
}
|
|
if f.Info.BootSectorFormat == 2 { // Info not available in WOZ 1.0
|
|
return errors.New("woz 13 sector disks are not supported")
|
|
}
|
|
|
|
d.data = f
|
|
d.writeProtected = !writeable
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *cardDisk2SequencerDrive) enable(enabled bool) {
|
|
d.enabled = enabled
|
|
}
|
|
|
|
func (d *cardDisk2SequencerDrive) moveHead(q0, q1, q2, q3 bool, trackTracer trackTracer) {
|
|
if !d.enabled {
|
|
return
|
|
}
|
|
|
|
phases := component.PinsToByte([8]bool{
|
|
q0, q1, q2, q3,
|
|
false, false, false, false,
|
|
})
|
|
d.currentQuarterTrack = moveDriveStepper(phases, d.currentQuarterTrack)
|
|
|
|
if trackTracer != nil {
|
|
trackTracer.traceTrack(d.currentQuarterTrack)
|
|
}
|
|
}
|
|
|
|
func (d *cardDisk2SequencerDrive) readPulse() bool {
|
|
if !d.enabled || d.data == nil {
|
|
return false
|
|
}
|
|
|
|
// Get next bit taking into account the MC3470 latency and weak bits
|
|
var fluxBit bool
|
|
fluxBit, d.position, d.positionMax = d.data.GetNextBitAndPosition(
|
|
d.position,
|
|
d.positionMax,
|
|
d.currentQuarterTrack)
|
|
d.mc3470Buffer = (d.mc3470Buffer << 1) & 0x0f
|
|
if fluxBit {
|
|
d.mc3470Buffer++
|
|
}
|
|
bit := ((d.mc3470Buffer >> 1) & 0x1) != 0 // Use the previous to last bit to add latency
|
|
if d.mc3470Buffer == 0 && rand.Intn(100) < 30 {
|
|
// Four consecutive zeros. It'a a fake bit.
|
|
// Output a random value. 70% zero, 30% one
|
|
bit = true
|
|
}
|
|
|
|
return bit
|
|
}
|
|
|
|
func (d *cardDisk2SequencerDrive) writePulse(value bool) {
|
|
if d.writeProtected || !d.enabled || d.data == nil {
|
|
return
|
|
}
|
|
|
|
d.data.SetBit(
|
|
value,
|
|
d.position,
|
|
d.positionMax,
|
|
d.currentQuarterTrack)
|
|
}
|