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
apple2e.rom
dos33.dsk
prodos.dsk

View File

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