Updated drive head move logic to handle Prodos's head move logic

This commit is contained in:
Will Angenent 2018-05-20 19:46:12 +01:00
parent 6f19957ee7
commit 9f2226d968
3 changed files with 78 additions and 23 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ mem.prof
mos6502go.test mos6502go.test
apple2e.rom apple2e.rom
dos33.dsk dos33.dsk
prodos.dsk

View File

@ -93,8 +93,8 @@ const (
var DriveState struct { var DriveState struct {
Drive uint8 Drive uint8
Spinning bool Spinning bool
Phase uint8 Phase int8
ArmPosition uint8 Phases uint8
BytePosition int BytePosition int
Q6 bool Q6 bool
Q7 bool Q7 bool
@ -116,7 +116,6 @@ func InitIO() {
DriveState.Drive = 1 DriveState.Drive = 1
DriveState.Spinning = false DriveState.Spinning = false
DriveState.Phase = 0 DriveState.Phase = 0
DriveState.ArmPosition = 0
DriveState.BytePosition = 0 DriveState.BytePosition = 0
DriveState.Q6 = false DriveState.Q6 = false
DriveState.Q7 = false DriveState.Q7 = false
@ -193,31 +192,41 @@ func readWrite(address uint16, isRead bool) bool {
// Ignore not implemented memory management reg // Ignore not implemented memory management reg
return true return true
// Drive stepper motor phase change // Drive stepper motor phase change
case S6CLRDRVP0, S6SETDRVP0, S6CLRDRVP1, S6SETDRVP1, S6CLRDRVP2, S6SETDRVP2, S6CLRDRVP3, S6SETDRVP3: case S6CLRDRVP0, S6SETDRVP0, S6CLRDRVP1, S6SETDRVP1, S6CLRDRVP2, S6SETDRVP2, S6CLRDRVP3, S6SETDRVP3:
if ((address - S6CLRDRVP0) % 2) == 1 { magnet := (address - S6CLRDRVP0) / 2
// When the magnet coil is energized, move the arm by half a track on := ((address - S6CLRDRVP0) % 2) == 1
phase := int8(address-S6CLRDRVP0) / 2
change := int8(DriveState.Phase) - phase if on {
if change < 0 { DriveState.Phases |= (1 << magnet)
change += 4
// Move head if a neighboring magnet is on and all others are off
direction := int8(0)
if (DriveState.Phases & (1 << uint8((DriveState.Phase+1)&3))) != 0 {
direction += 1
}
if (DriveState.Phases & (1 << uint8((DriveState.Phase+3)&3))) != 0 {
direction -= 1
} }
if change == 1 { // Inward if direction != 0 {
if DriveState.ArmPosition > 0 { DriveState.Phase += direction
DriveState.ArmPosition--
}
} else if change == 3 { // Outward
if DriveState.ArmPosition < 79 {
DriveState.ArmPosition++
}
}
DriveState.Phase = uint8(phase) if DriveState.Phase < 0 {
MakeTrackData(DriveState.ArmPosition) DriveState.Phase = 0
if audio.ClickWhenDriveHeadMoves { }
audio.Click() if DriveState.Phase == 80 {
DriveState.Phase = 79
}
MakeTrackData(uint8(DriveState.Phase))
if audio.ClickWhenDriveHeadMoves {
audio.Click()
}
} }
} else {
DriveState.Phases &= ^(1 << magnet)
} }
return true return true

45
prodos_boot_test.go Normal file
View File

@ -0,0 +1,45 @@
package main
import (
"fmt"
"mos6502go/cpu"
"mos6502go/keyboard"
"mos6502go/mmu"
"mos6502go/system"
"mos6502go/utils"
"mos6502go/video"
"testing"
"time"
)
const prodosDiskImage = "prodos.dsk"
func TestProdosBoot(t *testing.T) {
cpu.InitInstructionDecoder()
mmu.InitRAM()
mmu.InitApple2eROM()
mmu.InitIO()
mmu.ReadDiskImage(prodosDiskImage)
cpu.Init()
keyboard.Init()
video.Init()
system.Init()
cpu.SetColdStartReset()
cpu.Reset()
t0 := time.Now()
utils.RunUntilBreakPoint(t, 0xc600, 2, false, "Boot ROM")
utils.RunUntilBreakPoint(t, 0x0801, 2, false, "Loader")
utils.RunUntilBreakPoint(t, 0x2000, 3, false, "Relocator")
utils.RunUntilBreakPoint(t, 0x0080, 1, false, "AUX RAM test")
utils.RunUntilBreakPoint(t, 0x2932, 1, false, "Relocation done")
utils.RunUntilBreakPoint(t, 0x21f3, 1, false, "The first JSR $bf00 - ONLINE - get names of one or all online volumes")
utils.RunUntilBreakPoint(t, 0xd000, 1, false, "First call to MLI kernel")
// utils.RunUntilBreakPoint(t, 0x0800, 1, false, "BI loader")
elapsed := float64(time.Since(t0) / time.Millisecond)
fmt.Printf("CPU Cycles: %d\n", system.FrameCycles)
fmt.Printf("Time elapsed: %0.2f ms\n", elapsed)
fmt.Printf("Speed: %0.2f cycles/ms\n", float64(system.FrameCycles)/elapsed)
}