mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-02-08 04:30:46 +00:00
First changes for disk support
This commit is contained in:
parent
5b186f9b15
commit
84f45d9f99
@ -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 {
|
||||
|
@ -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
20
apple2/cardBase.go
Normal 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])
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
4
main.go
4
main.go
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user