MMU and IOU reset on the Apple IIe

This commit is contained in:
Ivan Izaguirre 2020-10-28 00:43:33 +01:00
parent 2eb16b4c3d
commit d8293e2dda
6 changed files with 87 additions and 9 deletions

View File

@ -113,6 +113,16 @@ func (a *Apple2) Run() {
} }
} }
func (a *Apple2) reset() {
a.cpu.Reset()
a.mmu.reset()
for _, c := range a.cards {
if c != nil {
c.reset()
}
}
}
// IsPaused returns true when emulator is paused // IsPaused returns true when emulator is paused
func (a *Apple2) IsPaused() bool { func (a *Apple2) IsPaused() bool {
return a.paused return a.paused
@ -171,7 +181,7 @@ func (a *Apple2) executeCommand(command int) {
case CommandToggleCPUTrace: case CommandToggleCPUTrace:
a.cpu.SetTrace(!a.cpu.GetTrace()) a.cpu.SetTrace(!a.cpu.GetTrace())
case CommandReset: case CommandReset:
a.cpu.Reset() a.reset()
} }
} }

View File

@ -6,6 +6,7 @@ import "github.com/ivanizag/izapple2/storage"
type Card interface { type Card interface {
loadRom(data []uint8) loadRom(data []uint8)
assign(a *Apple2, slot int) assign(a *Apple2, slot int)
reset()
GetName() string GetName() string
GetInfo() map[string]string GetInfo() map[string]string
@ -33,6 +34,10 @@ func (c *cardBase) GetInfo() map[string]string {
return nil return nil
} }
func (c *cardBase) reset() {
// nothing
}
func (c *cardBase) loadRomFromResource(resource string) { func (c *cardBase) loadRomFromResource(resource string) {
data, err := storage.LoadResource(resource) data, err := storage.LoadResource(resource)
if err != nil { if err != nil {

View File

@ -74,6 +74,16 @@ func (c *CardDisk2) GetInfo() map[string]string {
return info return info
} }
func (c *CardDisk2) reset() {
// UtA2e 9-12, all sowtches forced to off
drive := &c.drive[c.selected]
drive.phases = 0 // q0, q1, q2, q3
c.softSwitchQ4(false) // q4
c.selected = 0 // q5
c.q6 = false
c.q7 = false
}
func (c *CardDisk2) assign(a *Apple2, slot int) { func (c *CardDisk2) assign(a *Apple2, slot int) {
// Q1, Q2, Q3 and Q4 phase control soft switches, // Q1, Q2, Q3 and Q4 phase control soft switches,
for i := uint8(0); i < 4; i++ { for i := uint8(0); i < 4; i++ {
@ -99,17 +109,11 @@ func (c *CardDisk2) assign(a *Apple2, slot int) {
// Q4, power switch // Q4, power switch
c.addCardSoftSwitchR(0x8, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(0x8, func(_ *ioC0Page) uint8 {
drive := &c.drive[c.selected] c.softSwitchQ4(false)
if drive.power {
drive.power = false
c.a.releaseFastMode()
if drive.diskette != nil {
drive.diskette.PowerOff(c.a.cpu.GetCycles())
}
}
return c.dataLatch return c.dataLatch
}, "Q4DRIVEOFF") }, "Q4DRIVEOFF")
c.addCardSoftSwitchR(0x9, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(0x9, func(_ *ioC0Page) uint8 {
c.softSwitchQ4(true)
drive := &c.drive[c.selected] drive := &c.drive[c.selected]
if !drive.power { if !drive.power {
drive.power = true drive.power = true
@ -145,6 +149,25 @@ func (c *CardDisk2) assign(a *Apple2, slot int) {
c.cardBase.assign(a, slot) c.cardBase.assign(a, slot)
} }
func (c *CardDisk2) softSwitchQ4(value bool) {
drive := &c.drive[c.selected]
if !value && drive.power {
// Turn off
drive.power = false
c.a.releaseFastMode()
if drive.diskette != nil {
drive.diskette.PowerOff(c.a.cpu.GetCycles())
}
} else if value && !drive.power {
// Turn on
drive.power = true
c.a.requestFastMode()
if drive.diskette != nil {
drive.diskette.PowerOn(c.a.cpu.GetCycles())
}
}
}
// Q6: shift/load // Q6: shift/load
// Q7: read/write // Q7: read/write

View File

@ -49,6 +49,17 @@ const (
lcWriteEnabled = 2 lcWriteEnabled = 2
) )
func (c *CardLanguage) reset() {
if c.a.isApple2e {
// UtA2e 1-3, 5-23
c.readState = false
c.writeState = lcWriteEnabled
c.altBank = true // Start on bank2
c.applyState()
}
}
func (c *CardLanguage) assign(a *Apple2, slot int) { func (c *CardLanguage) assign(a *Apple2, slot int) {
c.readState = false c.readState = false
c.writeState = lcWriteEnabled c.writeState = lcWriteEnabled

View File

@ -304,3 +304,25 @@ func (mmu *memoryManager) setExtendedRAMActiveBlock(block uint8) {
} }
mmu.extendedRAMBlock = block mmu.extendedRAMBlock = block
} }
func (mmu *memoryManager) reset() {
if mmu.apple2.isApple2e {
// MMU UtA2e 4-14, 5-22
mmu.altZeroPage = false
mmu.altMainRAMActiveRead = false
mmu.altMainRAMActiveWrite = false
mmu.store80Active = false
mmu.slotC3ROMActive = false
mmu.intCxROMActive = false
mmu.intC8ROMActive = false
// IOU UtaA2e 7-3
// "All softswitches except KEYSTROKE, TEXT and MIXED are reset
// when the RESET line drops low"
mmu.apple2.io.softSwitchesData[ioFlagSecondPage] = ssOff
mmu.apple2.io.softSwitchesData[ioFlagHiRes] = ssOff
mmu.apple2.io.softSwitchesData[ioFlag80Col] = ssOff
mmu.apple2.io.softSwitchesData[ioDataNewVideo] = ssOff
// ioFlagText ?
}
}

View File

@ -16,6 +16,13 @@ See:
It is not enough to intercept the ROM accesses. RomX intercept the 74LS138 in It is not enough to intercept the ROM accesses. RomX intercept the 74LS138 in
position F12, that has access to the full 0xc000-0xf000 on the Apple II+ position F12, that has access to the full 0xc000-0xf000 on the Apple II+
Firmware:
- It first copies $D000-$DFFF to $6000 and runs there.
go run *.go -rom ROMX.FIRM.dump -disk ROM\ X\ 20-10-22.dsk
*/ */
type romX struct { type romX struct {