Moved disk module out of mmu
This commit is contained in:
parent
2aa16a20f0
commit
7ce52edf93
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"mos6502go/audio"
|
"mos6502go/audio"
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
|
"mos6502go/disk"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
|
@ -95,7 +96,7 @@ func main() {
|
||||||
mmu.InitIO()
|
mmu.InitIO()
|
||||||
|
|
||||||
if diskImage != "" {
|
if diskImage != "" {
|
||||||
mmu.ReadDiskImage(diskImage)
|
disk.ReadDiskImage(diskImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.Init()
|
cpu.Init()
|
||||||
|
@ -110,5 +111,5 @@ func main() {
|
||||||
|
|
||||||
ebiten.Run(update, 280*video.ScreenSizeFactor, 192*video.ScreenSizeFactor, 2, "Apple //e")
|
ebiten.Run(update, 280*video.ScreenSizeFactor, 192*video.ScreenSizeFactor, 2, "Apple //e")
|
||||||
|
|
||||||
mmu.FlushImage()
|
disk.FlushImage()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
"mos6502go/video"
|
"mos6502go/video"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBankSwitching(t *testing.T) {
|
func TestBankSwitching(t *testing.T) {
|
||||||
|
|
|
@ -2,12 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
"mos6502go/video"
|
"mos6502go/video"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func testBellCycles(delay int) {
|
func testBellCycles(delay int) {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package mmu
|
package disk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"mos6502go/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tracksPerDisk = 35
|
const tracksPerDisk = 35
|
||||||
|
@ -301,7 +303,7 @@ func MakeTrackData(armPosition uint8) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
DriveState.BytePosition = 0 // Point the head at the first sector
|
system.DriveState.BytePosition = 0 // Point the head at the first sector
|
||||||
|
|
||||||
// For each sector, encode the data and add it to trackData
|
// For each sector, encode the data and add it to trackData
|
||||||
for physicalSector := uint8(0); physicalSector < sectorsPerTrack; physicalSector++ {
|
for physicalSector := uint8(0); physicalSector < sectorsPerTrack; physicalSector++ {
|
||||||
|
@ -319,22 +321,22 @@ func decodeAddressField(data []uint8) addressField {
|
||||||
|
|
||||||
// Read a byte from the disk head and spin the disk along
|
// Read a byte from the disk head and spin the disk along
|
||||||
func ReadTrackData() (result uint8) {
|
func ReadTrackData() (result uint8) {
|
||||||
result = trackData[DriveState.BytePosition]
|
result = trackData[system.DriveState.BytePosition]
|
||||||
|
|
||||||
if DriveState.BytePosition >= 9 {
|
if system.DriveState.BytePosition >= 9 {
|
||||||
if trackData[DriveState.BytePosition-9] == 0xd5 &&
|
if trackData[system.DriveState.BytePosition-9] == 0xd5 &&
|
||||||
trackData[DriveState.BytePosition-8] == 0xaa &&
|
trackData[system.DriveState.BytePosition-8] == 0xaa &&
|
||||||
trackData[DriveState.BytePosition-7] == 0x96 {
|
trackData[system.DriveState.BytePosition-7] == 0x96 {
|
||||||
var addressData []uint8
|
var addressData []uint8
|
||||||
addressData = trackData[DriveState.BytePosition-6 : DriveState.BytePosition]
|
addressData = trackData[system.DriveState.BytePosition-6 : system.DriveState.BytePosition]
|
||||||
lastReadAddress = decodeAddressField(addressData)
|
lastReadAddress = decodeAddressField(addressData)
|
||||||
lastReadSectorDataPosition = DriveState.BytePosition + 8
|
lastReadSectorDataPosition = system.DriveState.BytePosition + 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DriveState.BytePosition++
|
system.DriveState.BytePosition++
|
||||||
if DriveState.BytePosition == trackDataBytes {
|
if system.DriveState.BytePosition == trackDataBytes {
|
||||||
DriveState.BytePosition = 0
|
system.DriveState.BytePosition = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
|
@ -2,14 +2,16 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
|
"mos6502go/disk"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
"mos6502go/utils"
|
"mos6502go/utils"
|
||||||
"mos6502go/video"
|
"mos6502go/video"
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const dosDiskImage = "dos33.dsk"
|
const dosDiskImage = "dos33.dsk"
|
||||||
|
@ -27,7 +29,7 @@ func TestDOS33Boot(t *testing.T) {
|
||||||
mmu.InitRAM()
|
mmu.InitRAM()
|
||||||
mmu.InitApple2eROM()
|
mmu.InitApple2eROM()
|
||||||
mmu.InitIO()
|
mmu.InitIO()
|
||||||
mmu.ReadDiskImage(dosDiskImage)
|
disk.ReadDiskImage(dosDiskImage)
|
||||||
cpu.Init()
|
cpu.Init()
|
||||||
keyboard.Init()
|
keyboard.Init()
|
||||||
video.Init()
|
video.Init()
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
"mos6502go/video"
|
"mos6502go/video"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIoBankSwitching(t *testing.T) {
|
func TestIoBankSwitching(t *testing.T) {
|
||||||
|
|
69
mmu/io.go
69
mmu/io.go
|
@ -2,8 +2,11 @@ package mmu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"mos6502go/audio"
|
"mos6502go/audio"
|
||||||
|
"mos6502go/disk"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
|
"mos6502go/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Adapted from
|
// Adapted from
|
||||||
|
@ -90,16 +93,6 @@ const (
|
||||||
S6Q7H = 0xC0EF // write
|
S6Q7H = 0xC0EF // write
|
||||||
)
|
)
|
||||||
|
|
||||||
var DriveState struct {
|
|
||||||
Drive uint8
|
|
||||||
Spinning bool
|
|
||||||
Phase int8
|
|
||||||
Phases uint8
|
|
||||||
BytePosition int
|
|
||||||
Q6 bool
|
|
||||||
Q7 bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var VideoState struct {
|
var VideoState struct {
|
||||||
TextMode bool
|
TextMode bool
|
||||||
HiresMode bool
|
HiresMode bool
|
||||||
|
@ -113,22 +106,22 @@ func InitIO() {
|
||||||
emptySlot(7)
|
emptySlot(7)
|
||||||
|
|
||||||
// Initialize slot 6 drive
|
// Initialize slot 6 drive
|
||||||
DriveState.Drive = 1
|
system.DriveState.Drive = 1
|
||||||
DriveState.Spinning = false
|
system.DriveState.Spinning = false
|
||||||
DriveState.Phase = 0
|
system.DriveState.Phase = 0
|
||||||
DriveState.BytePosition = 0
|
system.DriveState.BytePosition = 0
|
||||||
DriveState.Q6 = false
|
system.DriveState.Q6 = false
|
||||||
DriveState.Q7 = false
|
system.DriveState.Q7 = false
|
||||||
|
|
||||||
VideoState.TextMode = true
|
VideoState.TextMode = true
|
||||||
VideoState.HiresMode = false
|
VideoState.HiresMode = false
|
||||||
VideoState.Mixed = false
|
VideoState.Mixed = false
|
||||||
|
|
||||||
InitDiskImage()
|
disk.InitDiskImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
func driveIsreadSequencing() bool {
|
func driveIsreadSequencing() bool {
|
||||||
return (!DriveState.Q6) && (!DriveState.Q7)
|
return (!system.DriveState.Q6) && (!system.DriveState.Q7)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle soft switch addresses where both a read and a write has a side
|
// Handle soft switch addresses where both a read and a write has a side
|
||||||
|
@ -209,68 +202,68 @@ func readWrite(address uint16, isRead bool) bool {
|
||||||
on := ((address - S6CLRDRVP0) % 2) == 1
|
on := ((address - S6CLRDRVP0) % 2) == 1
|
||||||
|
|
||||||
if on {
|
if on {
|
||||||
DriveState.Phases |= (1 << magnet)
|
system.DriveState.Phases |= (1 << magnet)
|
||||||
|
|
||||||
// Move head if a neighboring magnet is on and all others are off
|
// Move head if a neighboring magnet is on and all others are off
|
||||||
direction := int8(0)
|
direction := int8(0)
|
||||||
if (DriveState.Phases & (1 << uint8((DriveState.Phase+1)&3))) != 0 {
|
if (system.DriveState.Phases & (1 << uint8((system.DriveState.Phase+1)&3))) != 0 {
|
||||||
direction += 1
|
direction += 1
|
||||||
}
|
}
|
||||||
if (DriveState.Phases & (1 << uint8((DriveState.Phase+3)&3))) != 0 {
|
if (system.DriveState.Phases & (1 << uint8((system.DriveState.Phase+3)&3))) != 0 {
|
||||||
direction -= 1
|
direction -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if direction != 0 {
|
if direction != 0 {
|
||||||
DriveState.Phase += direction
|
system.DriveState.Phase += direction
|
||||||
|
|
||||||
if DriveState.Phase < 0 {
|
if system.DriveState.Phase < 0 {
|
||||||
DriveState.Phase = 0
|
system.DriveState.Phase = 0
|
||||||
}
|
}
|
||||||
if DriveState.Phase == 80 {
|
if system.DriveState.Phase == 80 {
|
||||||
DriveState.Phase = 79
|
system.DriveState.Phase = 79
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeTrackData(uint8(DriveState.Phase))
|
disk.MakeTrackData(uint8(system.DriveState.Phase))
|
||||||
|
|
||||||
if audio.ClickWhenDriveHeadMoves {
|
if audio.ClickWhenDriveHeadMoves {
|
||||||
audio.Click()
|
audio.Click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DriveState.Phases &= ^(1 << magnet)
|
system.DriveState.Phases &= ^(1 << magnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case S6MOTOROFF:
|
case S6MOTOROFF:
|
||||||
DriveState.Spinning = false
|
system.DriveState.Spinning = false
|
||||||
return true
|
return true
|
||||||
case S6MOTORON:
|
case S6MOTORON:
|
||||||
DriveState.Spinning = true
|
system.DriveState.Spinning = true
|
||||||
return true
|
return true
|
||||||
case S6SELDRV1:
|
case S6SELDRV1:
|
||||||
DriveState.Drive = 1
|
system.DriveState.Drive = 1
|
||||||
return true
|
return true
|
||||||
case S6SELDRV2:
|
case S6SELDRV2:
|
||||||
DriveState.Drive = 2
|
system.DriveState.Drive = 2
|
||||||
return true
|
return true
|
||||||
case S6Q6L:
|
case S6Q6L:
|
||||||
if !isRead {
|
if !isRead {
|
||||||
DriveState.Q6 = false
|
system.DriveState.Q6 = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
case S6Q6H:
|
case S6Q6H:
|
||||||
if isRead {
|
if isRead {
|
||||||
DriveState.Q6 = true
|
system.DriveState.Q6 = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
case S6Q7L:
|
case S6Q7L:
|
||||||
DriveState.Q7 = false
|
system.DriveState.Q7 = false
|
||||||
return true
|
return true
|
||||||
case S6Q7H:
|
case S6Q7H:
|
||||||
DriveState.Q7 = true
|
system.DriveState.Q7 = true
|
||||||
return true
|
return true
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -332,7 +325,7 @@ func ReadIO(address uint16) uint8 {
|
||||||
case SPEAKER:
|
case SPEAKER:
|
||||||
audio.Click()
|
audio.Click()
|
||||||
case S6Q6L:
|
case S6Q6L:
|
||||||
return ReadTrackData()
|
return disk.ReadTrackData()
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("TODO read %04x\n", address))
|
panic(fmt.Sprintf("TODO read %04x\n", address))
|
||||||
}
|
}
|
||||||
|
@ -364,7 +357,7 @@ func WriteIO(address uint16, value uint8) {
|
||||||
case SETC3ROM:
|
case SETC3ROM:
|
||||||
// SETC3ROM not implemented
|
// SETC3ROM not implemented
|
||||||
case S6Q6H:
|
case S6Q6H:
|
||||||
WriteTrackData(value)
|
disk.WriteTrackData(value)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("TODO write %04x\n", address))
|
panic(fmt.Sprintf("TODO write %04x\n", address))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
|
"mos6502go/disk"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
"mos6502go/utils"
|
"mos6502go/utils"
|
||||||
"mos6502go/video"
|
"mos6502go/video"
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const prodosDiskImage = "prodos.dsk"
|
const prodosDiskImage = "prodos.dsk"
|
||||||
|
@ -19,7 +21,7 @@ func TestProdosBoot(t *testing.T) {
|
||||||
mmu.InitRAM()
|
mmu.InitRAM()
|
||||||
mmu.InitApple2eROM()
|
mmu.InitApple2eROM()
|
||||||
mmu.InitIO()
|
mmu.InitIO()
|
||||||
mmu.ReadDiskImage(prodosDiskImage)
|
disk.ReadDiskImage(prodosDiskImage)
|
||||||
cpu.Init()
|
cpu.Init()
|
||||||
keyboard.Init()
|
keyboard.Init()
|
||||||
video.Init()
|
video.Init()
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"mos6502go/cpu"
|
"mos6502go/cpu"
|
||||||
|
"mos6502go/disk"
|
||||||
"mos6502go/keyboard"
|
"mos6502go/keyboard"
|
||||||
"mos6502go/mmu"
|
"mos6502go/mmu"
|
||||||
"mos6502go/system"
|
"mos6502go/system"
|
||||||
"mos6502go/utils"
|
"mos6502go/utils"
|
||||||
"mos6502go/video"
|
"mos6502go/video"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const rwtsDosDiskImage = "dos33.dsk"
|
const rwtsDosDiskImage = "dos33.dsk"
|
||||||
|
@ -25,7 +26,7 @@ func TestDos33RwtsWriteRead(t *testing.T) {
|
||||||
mmu.InitRAM()
|
mmu.InitRAM()
|
||||||
mmu.InitApple2eROM()
|
mmu.InitApple2eROM()
|
||||||
mmu.InitIO()
|
mmu.InitIO()
|
||||||
mmu.ReadDiskImage(rwtsDosDiskImage)
|
disk.ReadDiskImage(rwtsDosDiskImage)
|
||||||
cpu.Init()
|
cpu.Init()
|
||||||
keyboard.Init()
|
keyboard.Init()
|
||||||
video.Init()
|
video.Init()
|
||||||
|
|
|
@ -19,6 +19,16 @@ var (
|
||||||
AudioAttenuationCounter uint64
|
AudioAttenuationCounter uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var DriveState struct {
|
||||||
|
Drive uint8
|
||||||
|
Spinning bool
|
||||||
|
Phase int8
|
||||||
|
Phases uint8
|
||||||
|
BytePosition int
|
||||||
|
Q6 bool
|
||||||
|
Q7 bool
|
||||||
|
}
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
Cycles = 0
|
Cycles = 0
|
||||||
AudioChannel = make(chan int16, AudioSampleRate*4) // 1 second
|
AudioChannel = make(chan int16, AudioSampleRate*4) // 1 second
|
||||||
|
|
Loading…
Reference in New Issue