First changes for disk support

This commit is contained in:
Ivan Izaguirre 2019-03-02 20:41:25 +01:00
parent 5b186f9b15
commit 84f45d9f99
9 changed files with 140 additions and 98 deletions

View File

@ -102,7 +102,7 @@ func (fe *ansiConsoleFrontend) textModeGoRoutine() {
// See "Understand the Apple II", page 5-10
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
isAltText := fe.apple2.isApple2e && fe.apple2.ioPage.isSoftSwitchExtActive(ioFlagAltChar)
isAltText := fe.apple2.isApple2e && fe.apple2.io.isSoftSwitchExtActive(ioFlagAltChar)
var i, j, h, c uint8
// Top, middle and botton screen
for i = 0; i < 120; i = i + 40 {

View File

@ -6,12 +6,14 @@ import (
"os"
)
// Apple2 represents all the components and state of the emulated machine
type Apple2 struct {
cpu *core6502.State
mmu *memoryManager
io *ioC0Page
cards []cardBase
isApple2e bool
ioPage *ioC0Page // 0xc000 to 0xc080
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
}
// NewApple2 instantiates an apple2
@ -23,17 +25,26 @@ func NewApple2(romFile string) *Apple2 {
a.mmu.resetPaging()
// Set the io in 0xc000
a.ioPage = newIoC0Page(&a)
a.mmu.setPage(0xc0, a.ioPage)
a.io = newIoC0Page(&a)
a.mmu.setPage(0xc0, a.io)
return &a
}
// AddDisk2 insterts a DiskII controller on slot 6
func (a *Apple2) AddDisk2(diskRomFile string) {
d := newCardDisk2(diskRomFile)
d.cardBase.insert(a, 6)
}
// Run starts the Apple2 emulation
func (a *Apple2) Run(log bool) {
// Init frontend
fe := newAnsiConsoleFrontend(a)
a.ioPage.setKeyboardProvider(fe)
go fe.textModeGoRoutine()
a.io.setKeyboardProvider(fe)
if !log {
go fe.textModeGoRoutine()
}
// Start the processor
a.cpu.Reset()

20
apple2/cardBase.go Normal file
View File

@ -0,0 +1,20 @@
package apple2
type cardBase struct {
rom []memoryPage
slot int
ssr [16]softSwitchR
ssw [16]softSwitchW
}
func (c *cardBase) insert(a *Apple2, slot int) {
c.slot = slot
if slot != 0 && c.rom[0] != nil {
a.mmu.setPage(uint8(0xC0+slot), c.rom[0])
}
for i := 0; i < 0x10; i++ {
a.io.addSoftSwitchR(uint8(0xC80+slot*0x10+i), c.ssr[i])
a.io.addSoftSwitchW(uint8(0xC80+slot*0x10+i), c.ssw[i])
}
}

View File

@ -1,13 +1,100 @@
package apple2
type disk2 struct {
mmu *memoryManager
slot int
import (
"bufio"
"fmt"
"os"
)
/*
https://applesaucefdc.com/woz/reference2/
Good explanation of the softswitches and the phases:
http://yesterbits.com/media/pubs/AppleOrchard/articles/disk-ii-part-1-1983-apr.pdf
*/
type cardDisk2 struct {
cardBase
phases [4]bool
power [2]bool
selected int // Only 0 and 1 supported
}
func insertCardDisk2(mmu *memoryManager, slot int) disk2 {
var c disk2
c.mmu = mmu
c.slot = slot
return c
// type softSwitchR func(io *ioC0Page) uint8
func newCardDisk2(filename string) *cardDisk2 {
var c cardDisk2
c.rom = loadCardRom(filename)
// Phase control soft switches
for i := 0; i < 4; i++ {
c.ssr[i<<1] = func(_ *ioC0Page) uint8 {
fmt.Printf("DISKII: Phase %v off\n", i)
return 0
}
c.ssr[(i<<1)+1] = func(_ *ioC0Page) uint8 {
fmt.Printf("DISKII: Phase %v on\n", i)
return 0
}
}
// Other soft switches
c.ssr[0x8] = func(_ *ioC0Page) uint8 {
c.power[c.selected] = false
fmt.Printf("DISKII: Disk %v is off\n", c.selected)
return 0
}
c.ssr[0x9] = func(_ *ioC0Page) uint8 {
c.power[c.selected] = true
fmt.Printf("DISKII: Disk %v is on\n", c.selected)
return 0
}
c.ssr[0xA] = func(_ *ioC0Page) uint8 {
c.selected = 0
fmt.Printf("DISKII: Disk %v selected\n", c.selected)
return 0
}
c.ssr[0xB] = func(_ *ioC0Page) uint8 {
c.selected = 1
fmt.Printf("DISKII: Disk %v selected\n", c.selected)
return 0
}
// TODO: missing C, D, E, and F
return &c
}
func loadCardRom(filename string) []memoryPage {
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
stats, statsErr := f.Stat()
if statsErr != nil {
panic(err)
}
size := stats.Size()
bytes := make([]byte, size)
buf := bufio.NewReader(f)
buf.Read(bytes)
pages := size / 256
if (size % 256) > 0 {
pages++
}
rom := make([]romPage, pages)
for i := int64(0); i < size; i++ {
rom[i>>8].burn(uint8(i), bytes[i])
}
memPages := make([]memoryPage, pages)
for i := range rom {
memPages[i] = &rom[i]
}
return memPages
}

View File

@ -1,78 +0,0 @@
package apple2
import (
"bufio"
"os"
)
type expansionSlots struct {
mmu *memoryManager
cards [7]expansionCard
}
type expansionCard interface {
insert(es *expansionSlots, slot int) cardBase
activateRom()
}
type cardBase struct {
es *expansionSlots
rom []romPage
slot int
softSwitchesR [16]softSwitchR
softSwitchesW [16]softSwitchW
}
/*
https://applesaucefdc.com/woz/reference2/
http://yesterbits.com/media/pubs/AppleOrchard/articles/disk-ii-part-1-1983-apr.pdf
*/
type cardDisk2 struct {
cardBase
}
func newCardDisk2(filename string) *cardDisk2 {
var c cardDisk2
c.rom = loadCardRom(filename)
return &c
}
func (c *cardBase) insert(es *expansionSlots, slot int) {
c.es = es
c.slot = slot
if c.rom != nil {
//rom = c.rom[0]
}
}
func loadCardRom(filename string) []romPage {
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
stats, statsErr := f.Stat()
if statsErr != nil {
panic(err)
}
size := stats.Size()
bytes := make([]byte, size)
buf := bufio.NewReader(f)
buf.Read(bytes)
pages := size / 256
if (size % 256) > 0 {
pages++
}
rom := make([]romPage, pages)
for i := int64(0); i < size; i++ {
rom[i>>8].burn(uint8(i), bytes[i])
}
return rom
}

View File

@ -5,8 +5,8 @@ import (
)
type ioC0Page struct {
softSwitchesR [128]softSwitchR
softSwitchesW [128]softSwitchW
softSwitchesR [256]softSwitchR
softSwitchesW [256]softSwitchW
softSwitchesData [128]uint8
keyboard keyboardProvider
apple2 *Apple2

View File

@ -55,7 +55,7 @@ func (mmu *memoryManager) setPage(index uint8, page memoryPage) {
// When 0xcfff is accessed the card expansion rom is unassigned
func (mmu *memoryManager) resetSlotExpansionRoms() {
if mmu.apple2.ioPage.isSoftSwitchExtActive(ioFlagIntCxRom) {
if mmu.apple2.io.isSoftSwitchExtActive(ioFlagIntCxRom) {
// Ignore if the Apple2 shadow ROM is active
return
}

View File

@ -9,7 +9,7 @@ type unassignedPage struct {
func (p *unassignedPage) Peek(address uint8) uint8 {
fmt.Printf("Read on address 0x%02x%02x\n", p.page, address)
//panic(address)
return 0xcc
return 0xdd
}
func (p *unassignedPage) Poke(address uint8, value uint8) {

View File

@ -6,8 +6,10 @@ func main() {
//romFile := "apple2/romdumps/Apple2.rom"
romFile := "apple2/romdumps/Apple2_Plus.rom"
//romFile := "apple2/romdumps/Apple2e.rom"
disk2RomFile := "apple2/romdumps/DISK2.rom"
log := false
log := true
a := apple2.NewApple2(romFile)
a.AddDisk2(disk2RomFile)
a.Run(log)
}