mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-02-07 13:30:57 +00:00
Time based disk reads
This commit is contained in:
parent
a27ab17766
commit
e14b26f876
@ -126,13 +126,16 @@ func (c *cardDisk2) assign(a *Apple2, slot int) {
|
||||
c.cardBase.assign(a, slot)
|
||||
}
|
||||
|
||||
// Q6: shift/load
|
||||
// Q7: read/write
|
||||
|
||||
func (c *cardDisk2) softSwitchQ6Q7(index uint8, in uint8) uint8 {
|
||||
switch index {
|
||||
case 0xC: // Q6L
|
||||
c.q6 = false
|
||||
case 0xD: // Q6H
|
||||
c.q6 = true
|
||||
case 0xE: // Q/L
|
||||
case 0xE: // Q7L
|
||||
c.q7 = false
|
||||
case 0xF: // Q7H
|
||||
c.q7 = true
|
||||
@ -151,13 +154,13 @@ func (c *cardDisk2) processQ6Q7(in uint8) {
|
||||
if d.diskette == nil {
|
||||
return
|
||||
}
|
||||
if !c.q6 {
|
||||
if !c.q6 { // shift
|
||||
if !c.q7 { // Q6L-Q7L: Read
|
||||
c.dataLatch = d.diskette.read(d.tracksStep, c.a.cpu.GetCycles())
|
||||
} else { // Q6L-Q7H: Write the dataLatch value to disk. Shift data out
|
||||
d.diskette.write(d.tracksStep, c.dataLatch, c.a.cpu.GetCycles())
|
||||
}
|
||||
} else {
|
||||
} else { // load
|
||||
if !c.q7 { // Q6H-Q7L: Sense write protect / prewrite state
|
||||
// Bit 7 of the control status register means write protected
|
||||
c.dataLatch = 0 // Never write protected
|
||||
|
@ -20,28 +20,58 @@ const (
|
||||
nibImageSize = numberOfTracks * nibBytesPerTrack
|
||||
dskImageSize = numberOfTracks * numberOfSectors * bytesPerSector
|
||||
defaultVolumeTag = 254
|
||||
cyclesPerBit = 4
|
||||
)
|
||||
|
||||
type diskette16sector struct {
|
||||
track [numberOfTracks][]byte
|
||||
position int
|
||||
track [numberOfTracks][]byte
|
||||
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) {
|
||||
// Not needed
|
||||
func (d *diskette16sector) powerOn(cycle uint64) {
|
||||
d.cycleOn = cycle
|
||||
}
|
||||
func (d *diskette16sector) powerOff(_ uint64) {
|
||||
// Not needed
|
||||
}
|
||||
|
||||
func (d *diskette16sector) read(quarterTrack int, _ uint64) uint8 {
|
||||
track := quarterTrack / stepsPerTrack
|
||||
value := d.track[track][d.position]
|
||||
func (d *diskette16sector) getBitPositionInTrack(cycle uint64) int {
|
||||
// Calculate how long the disk has been spinning. We move one bit every 4 cycles.
|
||||
// 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
|
||||
//fmt.Printf("%v, %v, %v, %x\n", 0, 0, d.position, uint8(value))
|
||||
return value
|
||||
}
|
||||
|
||||
func (d *diskette16sector) write(quarterTrack int, value uint8, _ uint64) {
|
||||
if d.timeBased {
|
||||
panic("Write not implmented on time based disk implementation")
|
||||
}
|
||||
track := quarterTrack / stepsPerTrack
|
||||
d.track[track][d.position] = value
|
||||
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) {
|
||||
var d diskette16sector
|
||||
|
||||
// Experimental
|
||||
d.timeBased = true
|
||||
|
||||
data, err := loadResource(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
Loading…
x
Reference in New Issue
Block a user