MMU and IOU reset on the Apple IIe
This commit is contained in:
parent
2eb16b4c3d
commit
d8293e2dda
12
apple2.go
12
apple2.go
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
39
cardDisk2.go
39
cardDisk2.go
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
7
romX.go
7
romX.go
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue