Experiments with WOZ writing

This commit is contained in:
Ivan Izaguirre 2021-07-01 18:15:49 +02:00
parent a765ac8033
commit 511f1bc8c7
5 changed files with 58 additions and 12 deletions

View File

@ -30,7 +30,7 @@ type CardDisk2Sequencer struct {
motorDelay uint64 // NE556 timer, used to delay motor off
drive [2]cardDisk2SequencerDrive
lastPulse bool
lastWriteValue bool // We write transitions to the WOZ file. We store the last value to send a pulse on change.
lastPulseCycles uint8 // There is a new pulse every 4ms, that's 8 cycles of 2Mhz
lastCycle uint64 // 2 Mhz cycles
@ -110,8 +110,8 @@ func (c *CardDisk2Sequencer) catchUp(data uint8) {
motorOn := c.step(data, true)
if motorOn && currentCycle > c.lastCycle+disk2CyclestoLoseSsync {
// We have losy sync. We start the count.
//We do at least a couple 2 Mhz cycles
// We have lost sync. We start the count.
// We do at least a couple 2 Mhz cycles
c.lastCycle = currentCycle - 2
}
c.lastCycle++
@ -187,6 +187,7 @@ func (c *CardDisk2Sequencer) step(data uint8, firstStep bool) bool {
pulse := false
c.lastPulseCycles++
if c.lastPulseCycles == disk2PulseCyles {
// Read
pulse = c.drive[0].readPulse() ||
c.drive[1].readPulse()
c.lastPulseCycles = 0
@ -254,6 +255,15 @@ func (c *CardDisk2Sequencer) step(data uint8, firstStep bool) bool {
// Load
c.register = data
}
if c.q[7] && (inst&0x3) != 0 {
currentWriteValue := next >= 0x8
writePulse := currentWriteValue != c.lastWriteValue
c.drive[0].writePulse(writePulse)
c.drive[1].writePulse(writePulse)
c.lastWriteValue = currentWriteValue
}
}
//fmt.Printf("[D2SEQ] Step. seq:%x inst:%x next:%x reg:%02x\n",

View File

@ -66,12 +66,15 @@ func (d *cardDisk2SequencerDrive) readPulse() bool {
}
// Get next bit taking into account the MC3470 latency and weak bits
var fluxBit uint8
var fluxBit bool
fluxBit, d.position, d.positionMax = d.data.GetNextBitAndPosition(
d.position,
d.positionMax,
d.currentQuarterTrack)
d.mc3470Buffer = (d.mc3470Buffer<<1 + fluxBit) & 0x0f
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.
@ -82,6 +85,14 @@ func (d *cardDisk2SequencerDrive) readPulse() bool {
return bit
}
func (d *cardDisk2SequencerDrive) writePulse(value uint8) {
panic("Write not implemented on woz disk implementation")
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)
}

View File

@ -16,6 +16,7 @@ type Diskette interface {
func IsDiskette(filename string) bool {
data, _, err := LoadResource(filename)
if err != nil {
panic(err)
return false
}

View File

@ -122,9 +122,12 @@ func (d *disketteWoz) Read(quarterTrack int, cycle uint64) uint8 {
// TODO: avoid processing too many bits if delta is big
for i := uint64(0); i < deltaBits; i++ {
// Get next bit taking into account the MC3470 latency and weak bits
var fluxBit uint8
var fluxBit bool
fluxBit, d.position, d.positionMax = d.data.GetNextBitAndPosition(d.position, d.positionMax, quarterTrack)
d.mc3470Buffer = (d.mc3470Buffer<<1 + fluxBit) & 0x0f
d.mc3470Buffer = (d.mc3470Buffer << 1) & 0x0f
if fluxBit {
d.mc3470Buffer++
}
bit := (d.mc3470Buffer >> 1) & 0x1 // Use the previous to last bit to add latency
if d.mc3470Buffer == 0 && rand.Intn(100) < 3 {
// Four consecutive zeros. It'a a fake bit.

View File

@ -80,7 +80,7 @@ const (
var headerWoz1 = []uint8{0x57, 0x4f, 0x5A, 0x31, 0xFF, 0x0A, 0x0D, 0x0A}
var headerWoz2 = []uint8{0x57, 0x4f, 0x5A, 0x32, 0xFF, 0x0A, 0x0D, 0x0A}
func (f *FileWoz) GetNextBitAndPosition(position uint32, positionMax uint32, quarterTrack int) (uint8, uint32, uint32) {
func (f *FileWoz) GetNextBitAndPosition(position uint32, positionMax uint32, quarterTrack int) (bool, uint32, uint32) {
if positionMax == 0 {
// First unitialised use
positionMax = ^uint32(0) // MaxUint32
@ -93,7 +93,7 @@ func (f *FileWoz) GetNextBitAndPosition(position uint32, positionMax uint32, qua
if trackIndex == 0xff {
// No track defined
// TODO: return random value
return 0, position, positionMax
return false, position, positionMax
}
trackWoz := f.tracks[trackIndex]
@ -103,7 +103,28 @@ func (f *FileWoz) GetNextBitAndPosition(position uint32, positionMax uint32, qua
positionMax = trackWoz.bitCount
}
return trackWoz.data[position/8] >> (7 - position%8) & 1, position, positionMax
value := (trackWoz.data[position/8] >> (7 - position%8) & 1) == 1
return value, position, positionMax
}
func (f *FileWoz) SetBit(value bool, position uint32, positionMax uint32, quarterTrack int) {
// The position is not moved, GetNextBitAndPosition() would have been called previously.
trackIndex := f.trackMap[quarterTrack]
if trackIndex == 0xff {
// No track defined. Nothing is saved
return
}
trackWoz := f.tracks[trackIndex]
mask := uint8(1) << (7 - position%8)
if value {
trackWoz.data[position/8] |= mask
} else {
trackWoz.data[position/8] &= ^mask
}
fmt.Printf("Saving %v at %v\n", value, position)
}
func isFileWoz(data []uint8) bool {