Time based disk reads

This commit is contained in:
Ivan Izaguirre 2019-12-09 20:40:00 +01:00 committed by Iván Izaguirre
parent a27ab17766
commit e14b26f876
2 changed files with 46 additions and 10 deletions

View File

@ -126,13 +126,16 @@ func (c *cardDisk2) assign(a *Apple2, slot int) {
c.cardBase.assign(a, slot) c.cardBase.assign(a, slot)
} }
// Q6: shift/load
// Q7: read/write
func (c *cardDisk2) softSwitchQ6Q7(index uint8, in uint8) uint8 { func (c *cardDisk2) softSwitchQ6Q7(index uint8, in uint8) uint8 {
switch index { switch index {
case 0xC: // Q6L case 0xC: // Q6L
c.q6 = false c.q6 = false
case 0xD: // Q6H case 0xD: // Q6H
c.q6 = true c.q6 = true
case 0xE: // Q/L case 0xE: // Q7L
c.q7 = false c.q7 = false
case 0xF: // Q7H case 0xF: // Q7H
c.q7 = true c.q7 = true
@ -151,13 +154,13 @@ func (c *cardDisk2) processQ6Q7(in uint8) {
if d.diskette == nil { if d.diskette == nil {
return return
} }
if !c.q6 { if !c.q6 { // shift
if !c.q7 { // Q6L-Q7L: Read if !c.q7 { // Q6L-Q7L: Read
c.dataLatch = d.diskette.read(d.tracksStep, c.a.cpu.GetCycles()) c.dataLatch = d.diskette.read(d.tracksStep, c.a.cpu.GetCycles())
} else { // Q6L-Q7H: Write the dataLatch value to disk. Shift data out } else { // Q6L-Q7H: Write the dataLatch value to disk. Shift data out
d.diskette.write(d.tracksStep, c.dataLatch, c.a.cpu.GetCycles()) d.diskette.write(d.tracksStep, c.dataLatch, c.a.cpu.GetCycles())
} }
} else { } else { // load
if !c.q7 { // Q6H-Q7L: Sense write protect / prewrite state if !c.q7 { // Q6H-Q7L: Sense write protect / prewrite state
// Bit 7 of the control status register means write protected // Bit 7 of the control status register means write protected
c.dataLatch = 0 // Never write protected c.dataLatch = 0 // Never write protected

View File

@ -20,28 +20,58 @@ const (
nibImageSize = numberOfTracks * nibBytesPerTrack nibImageSize = numberOfTracks * nibBytesPerTrack
dskImageSize = numberOfTracks * numberOfSectors * bytesPerSector dskImageSize = numberOfTracks * numberOfSectors * bytesPerSector
defaultVolumeTag = 254 defaultVolumeTag = 254
cyclesPerBit = 4
) )
type diskette16sector struct { type diskette16sector struct {
track [numberOfTracks][]byte track [numberOfTracks][]byte
position int timeBased bool
// Not time based implementation
position int // For not time based implemenation
// Time based implementation, expermiental
cycleOn uint64 // Cycle when the disk was last turned on
} }
func (d *diskette16sector) powerOn(_ uint64) { func (d *diskette16sector) powerOn(cycle uint64) {
// Not needed d.cycleOn = cycle
} }
func (d *diskette16sector) powerOff(_ uint64) { func (d *diskette16sector) powerOff(_ uint64) {
// Not needed // Not needed
} }
func (d *diskette16sector) read(quarterTrack int, _ uint64) uint8 { func (d *diskette16sector) getBitPositionInTrack(cycle uint64) int {
track := quarterTrack / stepsPerTrack // Calculate how long the disk has been spinning. We move one bit every 4 cycles.
value := d.track[track][d.position] // In this implementation we don't take into account hot long the motor takes to be at full speed.
cycles := cycle - d.cycleOn
position := cycles / cyclesPerBit
return int(position % (8 * nibBytesPerTrack)) // Ignore full turns
}
func (d *diskette16sector) read(quarterTrack int, cycle uint64) uint8 {
track := d.track[quarterTrack/stepsPerTrack]
if d.timeBased {
bitPosition := d.getBitPositionInTrack(cycle)
bytePosition := bitPosition / 8
shift := uint(bitPosition % 8)
if shift == 1 {
// We continue having the previous data for a little longer
shift = 0
}
value := track[bytePosition]
value >>= shift
//fmt.Printf("%v, %v, %v, %x\n", bitPosition, shift, bytePosition, uint8(data))
return value
}
value := track[d.position]
d.position = (d.position + 1) % nibBytesPerTrack d.position = (d.position + 1) % nibBytesPerTrack
//fmt.Printf("%v, %v, %v, %x\n", 0, 0, d.position, uint8(value))
return value return value
} }
func (d *diskette16sector) write(quarterTrack int, value uint8, _ uint64) { func (d *diskette16sector) write(quarterTrack int, value uint8, _ uint64) {
if d.timeBased {
panic("Write not implmented on time based disk implementation")
}
track := quarterTrack / stepsPerTrack track := quarterTrack / stepsPerTrack
d.track[track][d.position] = value d.track[track][d.position] = value
d.position = (d.position + 1) % nibBytesPerTrack d.position = (d.position + 1) % nibBytesPerTrack
@ -50,6 +80,9 @@ func (d *diskette16sector) write(quarterTrack int, value uint8, _ uint64) {
func loadDisquette(filename string) (*diskette16sector, error) { func loadDisquette(filename string) (*diskette16sector, error) {
var d diskette16sector var d diskette16sector
// Experimental
d.timeBased = true
data, err := loadResource(filename) data, err := loadResource(filename)
if err != nil { if err != nil {
return nil, err return nil, err