From 69cc4d15d584479d2f04fb8dd5632891ff7ad161 Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Sun, 24 Feb 2019 15:05:50 +0100 Subject: [PATCH] Refactor ioC0Page --- apple2/apple2.go | 3 - apple2/ioC0Page.go | 118 +++------------------------------------ apple2/softSwitches2.go | 107 +++++++++++++++++++++++++++++++++++ apple2/softSwitches2e.go | 4 +- 4 files changed, 118 insertions(+), 114 deletions(-) create mode 100644 apple2/softSwitches2.go diff --git a/apple2/apple2.go b/apple2/apple2.go index cbda391..c5db64f 100644 --- a/apple2/apple2.go +++ b/apple2/apple2.go @@ -5,9 +5,6 @@ import "go6502/core6502" // Run instantiates an apple2 and start emulation func Run(romFile string, log bool) { mmu := newAddressSpace(romFile) - if mmu.isApple2e { - addApple2ESoftSwitches(mmu) - } var s core6502.State s.Mem = mmu diff --git a/apple2/ioC0Page.go b/apple2/ioC0Page.go index ace87c8..6224fbb 100644 --- a/apple2/ioC0Page.go +++ b/apple2/ioC0Page.go @@ -13,7 +13,6 @@ type ioC0Page struct { type softSwitch func(io *ioC0Page, isWrite bool, value uint8) uint8 -// TODO: change interface to func type keyboardProvider interface { getKey() (key uint8, ok bool) } @@ -26,84 +25,22 @@ const ( ssOff uint8 = 0x00 ) -const ( - ioDataKeyboard uint8 = 0x10 +func newIoC0Page(mmu *memoryManager) *ioC0Page { + var io ioC0Page + io.mmu = mmu - ioFlagGraphics uint8 = 0x50 - ioFlagMixed uint8 = 0x52 - ioFlagSecondPage uint8 = 0x54 - ioFlagHiRes uint8 = 0x56 - ioFlagAnnunciator0 uint8 = 0x58 - ioFlagAnnunciator1 uint8 = 0x5a - ioFlagAnnunciator2 uint8 = 0x5c - ioFlagAnnunciator3 uint8 = 0x5e + addApple2SoftSwitches(&io) + if mmu.isApple2e { + addApple2ESoftSwitches(&io) + } - ioDataCassette uint8 = 0x60 - ioFlagButton0 uint8 = 0x61 - ioFlagButton1 uint8 = 0x62 - ioFlagButton2 uint8 = 0x63 - ioDataPaddle0 uint8 = 0x64 - ioDataPaddle1 uint8 = 0x65 - ioDataPaddle2 uint8 = 0x66 - ioDataPaddle3 uint8 = 0x67 -) + return &io +} func (p *ioC0Page) isSoftSwitchExtActive(ioFlag uint8) bool { return (p.softSwitchesData[ioFlag] & ssOn) == ssOn } -func newIoC0Page(mmu *memoryManager) *ioC0Page { - var p ioC0Page - p.mmu = mmu - ss := &p.softSwitches - - ss[0x00] = getKeySoftSwitch // Keyboard - ss[0x10] = strobeKeyboardSoftSwitch // Keyboard Strobe - ss[0x20] = notImplementedSoftSwitch // Cassette Output - ss[0x30] = notImplementedSoftSwitch // Speaker - ss[0x40] = notImplementedSoftSwitch // Game connector Strobe - // Note: Some sources indicate that all these cover 16 positions - // for read and write. But the Apple2e take over some of them, with - // the prevention on acting only on writes. - - ss[0x50] = getSoftSwitch(ioFlagGraphics, false) - ss[0x51] = getSoftSwitch(ioFlagGraphics, true) - ss[0x52] = getSoftSwitch(ioFlagMixed, false) - ss[0x53] = getSoftSwitch(ioFlagMixed, true) - ss[0x54] = getSoftSwitch(ioFlagSecondPage, false) - ss[0x55] = getSoftSwitch(ioFlagSecondPage, true) - ss[0x56] = getSoftSwitch(ioFlagHiRes, false) - ss[0x57] = getSoftSwitch(ioFlagHiRes, true) - ss[0x58] = getSoftSwitch(ioFlagAnnunciator0, false) - ss[0x59] = getSoftSwitch(ioFlagAnnunciator0, true) - ss[0x5a] = getSoftSwitch(ioFlagAnnunciator1, false) - ss[0x5b] = getSoftSwitch(ioFlagAnnunciator1, true) - ss[0x5c] = getSoftSwitch(ioFlagAnnunciator2, false) - ss[0x5d] = getSoftSwitch(ioFlagAnnunciator2, true) - ss[0x5e] = getSoftSwitch(ioFlagAnnunciator3, false) - ss[0x5f] = getSoftSwitch(ioFlagAnnunciator3, true) - - ss[0x60] = notImplementedSoftSwitch // Cassetter Input - ss[0x61] = getStatusSoftSwitch(ioFlagButton0) - ss[0x62] = getStatusSoftSwitch(ioFlagButton1) - ss[0x63] = getStatusSoftSwitch(ioFlagButton2) - ss[0x64] = getStatusSoftSwitch(ioDataPaddle0) - ss[0x65] = getStatusSoftSwitch(ioDataPaddle1) - ss[0x66] = getStatusSoftSwitch(ioDataPaddle2) - ss[0x67] = getStatusSoftSwitch(ioDataPaddle3) - ss[0x68] = ss[0x60] - ss[0x69] = ss[0x61] - ss[0x6A] = ss[0x62] - ss[0x6B] = ss[0x63] - ss[0x6C] = ss[0x64] - ss[0x6D] = ss[0x65] - ss[0x6E] = ss[0x66] - ss[0x6F] = ss[0x67] - ss[0x70] = notImplementedSoftSwitch // Game controllers reset - - return &p -} - func (p *ioC0Page) setKeyboardProvider(kb keyboardProvider) { p.keyboard = kb } @@ -132,40 +69,3 @@ func (p *ioC0Page) access(address uint8, isWrite bool, value uint8) uint8 { return ss(p, isWrite, value) } - -func getStatusSoftSwitch(ioFlag uint8) softSwitch { - return func(io *ioC0Page, isWrite bool, value uint8) uint8 { - return io.softSwitchesData[ioFlag] - } -} - -func getSoftSwitch(ioFlag uint8, isSet bool) softSwitch { - return func(io *ioC0Page, isWrite bool, value uint8) uint8 { - if isSet { - io.softSwitchesData[ioFlag] = ssOn - } else { - io.softSwitchesData[ioFlag] = ssOff - } - return 0 - } -} - -func notImplementedSoftSwitch(*ioC0Page, bool, uint8) uint8 { - return 0 -} - -func getKeySoftSwitch(p *ioC0Page, _ bool, _ uint8) uint8 { - strobed := (p.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0 - if strobed && p.keyboard != nil { - if key, ok := p.keyboard.getKey(); ok { - p.softSwitchesData[ioDataKeyboard] = key + (1 << 7) - } - } - return p.softSwitchesData[ioDataKeyboard] -} - -func strobeKeyboardSoftSwitch(p *ioC0Page, _ bool, _ uint8) uint8 { - result := p.softSwitchesData[ioDataKeyboard] - p.softSwitchesData[ioDataKeyboard] &^= 1 << 7 - return result -} diff --git a/apple2/softSwitches2.go b/apple2/softSwitches2.go new file mode 100644 index 0000000..010f104 --- /dev/null +++ b/apple2/softSwitches2.go @@ -0,0 +1,107 @@ +package apple2 + +const ( + ioDataKeyboard uint8 = 0x10 + + ioFlagGraphics uint8 = 0x50 + ioFlagMixed uint8 = 0x52 + ioFlagSecondPage uint8 = 0x54 + ioFlagHiRes uint8 = 0x56 + ioFlagAnnunciator0 uint8 = 0x58 + ioFlagAnnunciator1 uint8 = 0x5a + ioFlagAnnunciator2 uint8 = 0x5c + ioFlagAnnunciator3 uint8 = 0x5e + + ioDataCassette uint8 = 0x60 + ioFlagButton0 uint8 = 0x61 + ioFlagButton1 uint8 = 0x62 + ioFlagButton2 uint8 = 0x63 + ioDataPaddle0 uint8 = 0x64 + ioDataPaddle1 uint8 = 0x65 + ioDataPaddle2 uint8 = 0x66 + ioDataPaddle3 uint8 = 0x67 +) + +func addApple2SoftSwitches(io *ioC0Page) { + ss := &io.softSwitches + + ss[0x00] = getKeySoftSwitch // Keyboard + ss[0x10] = strobeKeyboardSoftSwitch // Keyboard Strobe + ss[0x20] = notImplementedSoftSwitch // Cassette Output + ss[0x30] = notImplementedSoftSwitch // Speaker + ss[0x40] = notImplementedSoftSwitch // Game connector Strobe + // Note: Some sources indicate that all these cover 16 positions + // for read and write. But the Apple2e take over some of them, with + // the prevention on acting only on writes. + + ss[0x50] = getSoftSwitch(ioFlagGraphics, false) + ss[0x51] = getSoftSwitch(ioFlagGraphics, true) + ss[0x52] = getSoftSwitch(ioFlagMixed, false) + ss[0x53] = getSoftSwitch(ioFlagMixed, true) + ss[0x54] = getSoftSwitch(ioFlagSecondPage, false) + ss[0x55] = getSoftSwitch(ioFlagSecondPage, true) + ss[0x56] = getSoftSwitch(ioFlagHiRes, false) + ss[0x57] = getSoftSwitch(ioFlagHiRes, true) + ss[0x58] = getSoftSwitch(ioFlagAnnunciator0, false) + ss[0x59] = getSoftSwitch(ioFlagAnnunciator0, true) + ss[0x5a] = getSoftSwitch(ioFlagAnnunciator1, false) + ss[0x5b] = getSoftSwitch(ioFlagAnnunciator1, true) + ss[0x5c] = getSoftSwitch(ioFlagAnnunciator2, false) + ss[0x5d] = getSoftSwitch(ioFlagAnnunciator2, true) + ss[0x5e] = getSoftSwitch(ioFlagAnnunciator3, false) + ss[0x5f] = getSoftSwitch(ioFlagAnnunciator3, true) + + ss[0x60] = notImplementedSoftSwitch // Cassetter Input + ss[0x61] = getStatusSoftSwitch(ioFlagButton0) + ss[0x62] = getStatusSoftSwitch(ioFlagButton1) + ss[0x63] = getStatusSoftSwitch(ioFlagButton2) + ss[0x64] = getStatusSoftSwitch(ioDataPaddle0) + ss[0x65] = getStatusSoftSwitch(ioDataPaddle1) + ss[0x66] = getStatusSoftSwitch(ioDataPaddle2) + ss[0x67] = getStatusSoftSwitch(ioDataPaddle3) + ss[0x68] = ss[0x60] + ss[0x69] = ss[0x61] + ss[0x6A] = ss[0x62] + ss[0x6B] = ss[0x63] + ss[0x6C] = ss[0x64] + ss[0x6D] = ss[0x65] + ss[0x6E] = ss[0x66] + ss[0x6F] = ss[0x67] + ss[0x70] = notImplementedSoftSwitch // Game controllers reset +} + +func notImplementedSoftSwitch(*ioC0Page, bool, uint8) uint8 { + return 0 +} +func getStatusSoftSwitch(ioFlag uint8) softSwitch { + return func(io *ioC0Page, isWrite bool, value uint8) uint8 { + return io.softSwitchesData[ioFlag] + } +} + +func getSoftSwitch(ioFlag uint8, isSet bool) softSwitch { + return func(io *ioC0Page, isWrite bool, value uint8) uint8 { + if isSet { + io.softSwitchesData[ioFlag] = ssOn + } else { + io.softSwitchesData[ioFlag] = ssOff + } + return 0 + } +} + +func getKeySoftSwitch(p *ioC0Page, _ bool, _ uint8) uint8 { + strobed := (p.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0 + if strobed && p.keyboard != nil { + if key, ok := p.keyboard.getKey(); ok { + p.softSwitchesData[ioDataKeyboard] = key + (1 << 7) + } + } + return p.softSwitchesData[ioDataKeyboard] +} + +func strobeKeyboardSoftSwitch(p *ioC0Page, _ bool, _ uint8) uint8 { + result := p.softSwitchesData[ioDataKeyboard] + p.softSwitchesData[ioDataKeyboard] &^= 1 << 7 + return result +} diff --git a/apple2/softSwitches2e.go b/apple2/softSwitches2e.go index b61f5ee..40abe8b 100644 --- a/apple2/softSwitches2e.go +++ b/apple2/softSwitches2e.go @@ -7,8 +7,8 @@ const ( ioFlag80Col uint8 = 0x1F ) -func addApple2ESoftSwitches(mmu *memoryManager) { - ss := &mmu.ioPage.softSwitches +func addApple2ESoftSwitches(io *ioC0Page) { + ss := &io.softSwitches ss[0x00] = getSoftSwitchExt(ioFlag80Store, ssOff, nil) ss[0x01] = getSoftSwitchExt(ioFlag80Store, ssOn, nil)