Experiments with WOZ writing
This commit is contained in:
parent
a765ac8033
commit
511f1bc8c7
|
@ -30,7 +30,7 @@ type CardDisk2Sequencer struct {
|
||||||
motorDelay uint64 // NE556 timer, used to delay motor off
|
motorDelay uint64 // NE556 timer, used to delay motor off
|
||||||
drive [2]cardDisk2SequencerDrive
|
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
|
lastPulseCycles uint8 // There is a new pulse every 4ms, that's 8 cycles of 2Mhz
|
||||||
|
|
||||||
lastCycle uint64 // 2 Mhz cycles
|
lastCycle uint64 // 2 Mhz cycles
|
||||||
|
@ -110,8 +110,8 @@ func (c *CardDisk2Sequencer) catchUp(data uint8) {
|
||||||
|
|
||||||
motorOn := c.step(data, true)
|
motorOn := c.step(data, true)
|
||||||
if motorOn && currentCycle > c.lastCycle+disk2CyclestoLoseSsync {
|
if motorOn && currentCycle > c.lastCycle+disk2CyclestoLoseSsync {
|
||||||
// We have losy sync. We start the count.
|
// We have lost sync. We start the count.
|
||||||
//We do at least a couple 2 Mhz cycles
|
// We do at least a couple 2 Mhz cycles
|
||||||
c.lastCycle = currentCycle - 2
|
c.lastCycle = currentCycle - 2
|
||||||
}
|
}
|
||||||
c.lastCycle++
|
c.lastCycle++
|
||||||
|
@ -187,6 +187,7 @@ func (c *CardDisk2Sequencer) step(data uint8, firstStep bool) bool {
|
||||||
pulse := false
|
pulse := false
|
||||||
c.lastPulseCycles++
|
c.lastPulseCycles++
|
||||||
if c.lastPulseCycles == disk2PulseCyles {
|
if c.lastPulseCycles == disk2PulseCyles {
|
||||||
|
// Read
|
||||||
pulse = c.drive[0].readPulse() ||
|
pulse = c.drive[0].readPulse() ||
|
||||||
c.drive[1].readPulse()
|
c.drive[1].readPulse()
|
||||||
c.lastPulseCycles = 0
|
c.lastPulseCycles = 0
|
||||||
|
@ -254,6 +255,15 @@ func (c *CardDisk2Sequencer) step(data uint8, firstStep bool) bool {
|
||||||
// Load
|
// Load
|
||||||
c.register = data
|
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",
|
//fmt.Printf("[D2SEQ] Step. seq:%x inst:%x next:%x reg:%02x\n",
|
||||||
|
|
|
@ -66,12 +66,15 @@ func (d *cardDisk2SequencerDrive) readPulse() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get next bit taking into account the MC3470 latency and weak bits
|
// 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(
|
fluxBit, d.position, d.positionMax = d.data.GetNextBitAndPosition(
|
||||||
d.position,
|
d.position,
|
||||||
d.positionMax,
|
d.positionMax,
|
||||||
d.currentQuarterTrack)
|
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
|
bit := ((d.mc3470Buffer >> 1) & 0x1) != 0 // Use the previous to last bit to add latency
|
||||||
if d.mc3470Buffer == 0 && rand.Intn(100) < 30 {
|
if d.mc3470Buffer == 0 && rand.Intn(100) < 30 {
|
||||||
// Four consecutive zeros. It'a a fake bit.
|
// Four consecutive zeros. It'a a fake bit.
|
||||||
|
@ -82,6 +85,14 @@ func (d *cardDisk2SequencerDrive) readPulse() bool {
|
||||||
return bit
|
return bit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cardDisk2SequencerDrive) writePulse(value uint8) {
|
func (d *cardDisk2SequencerDrive) writePulse(value bool) {
|
||||||
panic("Write not implemented on woz disk implementation")
|
if d.writeProtected || !d.enabled || d.data == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.data.SetBit(
|
||||||
|
value,
|
||||||
|
d.position,
|
||||||
|
d.positionMax,
|
||||||
|
d.currentQuarterTrack)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ type Diskette interface {
|
||||||
func IsDiskette(filename string) bool {
|
func IsDiskette(filename string) bool {
|
||||||
data, _, err := LoadResource(filename)
|
data, _, err := LoadResource(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,9 +122,12 @@ func (d *disketteWoz) Read(quarterTrack int, cycle uint64) uint8 {
|
||||||
// TODO: avoid processing too many bits if delta is big
|
// TODO: avoid processing too many bits if delta is big
|
||||||
for i := uint64(0); i < deltaBits; i++ {
|
for i := uint64(0); i < deltaBits; i++ {
|
||||||
// Get next bit taking into account the MC3470 latency and weak bits
|
// 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)
|
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
|
bit := (d.mc3470Buffer >> 1) & 0x1 // Use the previous to last bit to add latency
|
||||||
if d.mc3470Buffer == 0 && rand.Intn(100) < 3 {
|
if d.mc3470Buffer == 0 && rand.Intn(100) < 3 {
|
||||||
// Four consecutive zeros. It'a a fake bit.
|
// Four consecutive zeros. It'a a fake bit.
|
||||||
|
|
|
@ -80,7 +80,7 @@ const (
|
||||||
var headerWoz1 = []uint8{0x57, 0x4f, 0x5A, 0x31, 0xFF, 0x0A, 0x0D, 0x0A}
|
var headerWoz1 = []uint8{0x57, 0x4f, 0x5A, 0x31, 0xFF, 0x0A, 0x0D, 0x0A}
|
||||||
var headerWoz2 = []uint8{0x57, 0x4f, 0x5A, 0x32, 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 {
|
if positionMax == 0 {
|
||||||
// First unitialised use
|
// First unitialised use
|
||||||
positionMax = ^uint32(0) // MaxUint32
|
positionMax = ^uint32(0) // MaxUint32
|
||||||
|
@ -93,7 +93,7 @@ func (f *FileWoz) GetNextBitAndPosition(position uint32, positionMax uint32, qua
|
||||||
if trackIndex == 0xff {
|
if trackIndex == 0xff {
|
||||||
// No track defined
|
// No track defined
|
||||||
// TODO: return random value
|
// TODO: return random value
|
||||||
return 0, position, positionMax
|
return false, position, positionMax
|
||||||
}
|
}
|
||||||
trackWoz := f.tracks[trackIndex]
|
trackWoz := f.tracks[trackIndex]
|
||||||
|
|
||||||
|
@ -103,7 +103,28 @@ func (f *FileWoz) GetNextBitAndPosition(position uint32, positionMax uint32, qua
|
||||||
positionMax = trackWoz.bitCount
|
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 {
|
func isFileWoz(data []uint8) bool {
|
||||||
|
|
Loading…
Reference in New Issue