mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-22 09:30:19 +00:00
Separate read and write soft switches. Keyboard works now in Apple2e. Extended char set
This commit is contained in:
parent
69cc4d15d5
commit
590dfb5cec
@ -18,10 +18,17 @@ Those tricks do not work with the Apple2e ROM
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
type ansiConsoleFrontend struct {
|
type ansiConsoleFrontend struct {
|
||||||
|
mmu *memoryManager
|
||||||
keyChannel chan uint8
|
keyChannel chan uint8
|
||||||
extraLineFeeds chan int
|
extraLineFeeds chan int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newAnsiConsoleFrontend(mmu *memoryManager) ansiConsoleFrontend {
|
||||||
|
var fe ansiConsoleFrontend
|
||||||
|
fe.mmu = mmu
|
||||||
|
return fe
|
||||||
|
}
|
||||||
|
|
||||||
const refreshDelayMs = 100
|
const refreshDelayMs = 100
|
||||||
|
|
||||||
func (fe *ansiConsoleFrontend) getKey() (key uint8, ok bool) {
|
func (fe *ansiConsoleFrontend) getKey() (key uint8, ok bool) {
|
||||||
@ -82,6 +89,7 @@ func (fe *ansiConsoleFrontend) textModeGoRoutine(tp *textPages) {
|
|||||||
|
|
||||||
// See "Understand the Apple II", page 5-10
|
// See "Understand the Apple II", page 5-10
|
||||||
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
|
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
|
||||||
|
isAltText := fe.mmu.isApple2e && fe.mmu.ioPage.isSoftSwitchExtActive(ioFlagAltChar)
|
||||||
var i, j, h uint8
|
var i, j, h uint8
|
||||||
// Top, middle and botton screen
|
// Top, middle and botton screen
|
||||||
for i = 0; i < 120; i = i + 40 {
|
for i = 0; i < 120; i = i + 40 {
|
||||||
@ -91,7 +99,7 @@ func (fe *ansiConsoleFrontend) textModeGoRoutine(tp *textPages) {
|
|||||||
for _, h = range []uint8{0, 128} {
|
for _, h = range []uint8{0, 128} {
|
||||||
line := ""
|
line := ""
|
||||||
for j = i + h; j < i+h+40; j++ {
|
for j = i + h; j < i+h+40; j++ {
|
||||||
line += textMemoryByteToString(p.Peek(j))
|
line += textMemoryByteToString(p.Peek(j), isAltText)
|
||||||
}
|
}
|
||||||
fmt.Printf("# %v #\n", line)
|
fmt.Printf("# %v #\n", line)
|
||||||
}
|
}
|
||||||
@ -106,19 +114,34 @@ func (fe *ansiConsoleFrontend) textModeGoRoutine(tp *textPages) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textMemoryByteToString(value uint8) string {
|
func textMemoryByteToString(value uint8, isAltCharSet bool) string {
|
||||||
// See https://en.wikipedia.org/wiki/Apple_II_character_set
|
// See https://en.wikipedia.org/wiki/Apple_II_character_set
|
||||||
|
// Supports the new lowercase characters in the Apple2e
|
||||||
// Only ascii from 0x20 to 0x5F is visible
|
// Only ascii from 0x20 to 0x5F is visible
|
||||||
// Does not support the new lowercase characters in the Apple2e
|
|
||||||
topBits := value >> 6
|
topBits := value >> 6
|
||||||
isInverse := topBits == 0
|
isInverse := topBits == 0
|
||||||
isFlash := topBits == 1
|
isFlash := topBits == 1
|
||||||
|
if isFlash && isAltCharSet {
|
||||||
|
// On the Apple2e with lowercase chars there is not flash mode.
|
||||||
|
isFlash = false
|
||||||
|
isInverse = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if isAltCharSet {
|
||||||
|
value = value & 0x7F
|
||||||
|
} else {
|
||||||
|
value = value & 0x3F
|
||||||
|
}
|
||||||
|
|
||||||
value = (value & 0x3F)
|
|
||||||
if value < 0x20 {
|
if value < 0x20 {
|
||||||
value += 0x40
|
value += 0x40
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if value == 0x7f {
|
||||||
|
// DEL is full box
|
||||||
|
value = '_'
|
||||||
|
}
|
||||||
|
|
||||||
if isFlash {
|
if isFlash {
|
||||||
if value == ' ' {
|
if value == ' ' {
|
||||||
// Flashing space in Apple is the full box. It can't be done with ANSI codes
|
// Flashing space in Apple is the full box. It can't be done with ANSI codes
|
||||||
@ -132,6 +155,6 @@ func textMemoryByteToString(value uint8) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textMemoryByteToStringHex(value uint8) string {
|
func textMemoryByteToStringHex(value uint8, _ bool) string {
|
||||||
return fmt.Sprintf("%02x ", value)
|
return fmt.Sprintf("%02x ", value)
|
||||||
}
|
}
|
||||||
|
33
apple2/ansiConsoleFrontend_test.go
Normal file
33
apple2/ansiConsoleFrontend_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package apple2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTextMemoryByteToString(t *testing.T) {
|
||||||
|
charExpectation(t, 0x01, false, "\033[7mA\033[0m")
|
||||||
|
charExpectation(t, 0x21, false, "\033[7m!\033[0m")
|
||||||
|
charExpectation(t, 0x41, false, "\033[5mA\033[0m")
|
||||||
|
charExpectation(t, 0x61, false, "\033[5m!\033[0m")
|
||||||
|
charExpectation(t, 0x81, false, "A")
|
||||||
|
charExpectation(t, 0xa1, false, "!")
|
||||||
|
charExpectation(t, 0xc1, false, "A")
|
||||||
|
charExpectation(t, 0xe1, false, "!")
|
||||||
|
|
||||||
|
charExpectation(t, 0x01, true, "\033[7mA\033[0m")
|
||||||
|
charExpectation(t, 0x21, true, "\033[7m!\033[0m")
|
||||||
|
charExpectation(t, 0x41, true, "\033[7mA\033[0m")
|
||||||
|
charExpectation(t, 0x61, true, "\033[7ma\033[0m")
|
||||||
|
charExpectation(t, 0x81, true, "A")
|
||||||
|
charExpectation(t, 0xa1, true, "!")
|
||||||
|
charExpectation(t, 0xc1, true, "A")
|
||||||
|
charExpectation(t, 0xe1, true, "a")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func charExpectation(t *testing.T, arg uint8, alt bool, expect string) {
|
||||||
|
s := textMemoryByteToString(arg, alt)
|
||||||
|
if s != expect {
|
||||||
|
t.Errorf("For 0x%02x:%v, got %v, expected %v", arg, alt, s, expect)
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ func Run(romFile string, log bool) {
|
|||||||
var s core6502.State
|
var s core6502.State
|
||||||
s.Mem = mmu
|
s.Mem = mmu
|
||||||
|
|
||||||
var fe ansiConsoleFrontend
|
fe := newAnsiConsoleFrontend(mmu)
|
||||||
mmu.ioPage.setKeyboardProvider(&fe)
|
mmu.ioPage.setKeyboardProvider(&fe)
|
||||||
go fe.textModeGoRoutine(mmu.textPages1)
|
go fe.textModeGoRoutine(mmu.textPages1)
|
||||||
|
|
||||||
|
@ -5,13 +5,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ioC0Page struct {
|
type ioC0Page struct {
|
||||||
softSwitches [128]softSwitch
|
softSwitchesR [128]softSwitchR
|
||||||
|
softSwitchesW [128]softSwitchW
|
||||||
softSwitchesData [128]uint8
|
softSwitchesData [128]uint8
|
||||||
keyboard keyboardProvider
|
keyboard keyboardProvider
|
||||||
mmu *memoryManager
|
mmu *memoryManager
|
||||||
}
|
}
|
||||||
|
|
||||||
type softSwitch func(io *ioC0Page, isWrite bool, value uint8) uint8
|
type softSwitchR func(io *ioC0Page) uint8
|
||||||
|
type softSwitchW func(io *ioC0Page, value uint8)
|
||||||
|
|
||||||
type keyboardProvider interface {
|
type keyboardProvider interface {
|
||||||
getKey() (key uint8, ok bool)
|
getKey() (key uint8, ok bool)
|
||||||
@ -37,6 +39,27 @@ func newIoC0Page(mmu *memoryManager) *ioC0Page {
|
|||||||
return &io
|
return &io
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR) {
|
||||||
|
p.addSoftSwitchR(address, ss)
|
||||||
|
p.addSoftSwitchW(address, func(p *ioC0Page, _ uint8) {
|
||||||
|
ss(p)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ioC0Page) addSoftSwitchR(address uint8, ss softSwitchR) {
|
||||||
|
if p.softSwitchesR[address] != nil {
|
||||||
|
fmt.Printf("Addresss 0x0c%02x is already assigned for read", address)
|
||||||
|
}
|
||||||
|
p.softSwitchesR[address] = ss
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ioC0Page) addSoftSwitchW(address uint8, ss softSwitchW) {
|
||||||
|
if p.softSwitchesW[address] != nil {
|
||||||
|
fmt.Printf("Addresss 0x0c%02x is already assigned for write", address)
|
||||||
|
}
|
||||||
|
p.softSwitchesW[address] = ss
|
||||||
|
}
|
||||||
|
|
||||||
func (p *ioC0Page) isSoftSwitchExtActive(ioFlag uint8) bool {
|
func (p *ioC0Page) isSoftSwitchExtActive(ioFlag uint8) bool {
|
||||||
return (p.softSwitchesData[ioFlag] & ssOn) == ssOn
|
return (p.softSwitchesData[ioFlag] & ssOn) == ssOn
|
||||||
}
|
}
|
||||||
@ -47,25 +70,19 @@ func (p *ioC0Page) setKeyboardProvider(kb keyboardProvider) {
|
|||||||
|
|
||||||
func (p *ioC0Page) Peek(address uint8) uint8 {
|
func (p *ioC0Page) Peek(address uint8) uint8 {
|
||||||
//fmt.Printf("Peek on $C0%02x ", address)
|
//fmt.Printf("Peek on $C0%02x ", address)
|
||||||
return p.access(address, false, 0)
|
ss := p.softSwitchesR[address]
|
||||||
|
if ss == nil {
|
||||||
|
panic(fmt.Sprintf("Unknown softswitch on read to 0xC0%02x", address))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ioC0Page) Poke(address uint8, value uint8) {
|
func (p *ioC0Page) Poke(address uint8, value uint8) {
|
||||||
//fmt.Printf("Poke on $C0%02x with %02x ", address, value)
|
//fmt.Printf("Poke on $C0%02x with %02x ", address, value)
|
||||||
p.access(address, true, value)
|
ss := p.softSwitchesW[address]
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ioC0Page) access(address uint8, isWrite bool, value uint8) uint8 {
|
|
||||||
// The second half of the pages is reserved for slots
|
|
||||||
if address >= 0x90 {
|
|
||||||
// TODO reserved slots data
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ss := p.softSwitches[address]
|
|
||||||
if ss == nil {
|
if ss == nil {
|
||||||
panic(fmt.Sprintf("Unknown softswitch 0xC0%02x", address))
|
panic(fmt.Sprintf("Unknown softswitch on write to 0xC0%02x", address))
|
||||||
}
|
}
|
||||||
|
ss(p, value)
|
||||||
return ss(p, isWrite, value)
|
|
||||||
}
|
}
|
||||||
|
@ -23,64 +23,66 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func addApple2SoftSwitches(io *ioC0Page) {
|
func addApple2SoftSwitches(io *ioC0Page) {
|
||||||
ss := &io.softSwitches
|
|
||||||
|
|
||||||
ss[0x00] = getKeySoftSwitch // Keyboard
|
io.addSoftSwitchRW(0x00, getKeySoftSwitch) // Keyboard
|
||||||
ss[0x10] = strobeKeyboardSoftSwitch // Keyboard Strobe
|
io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch) // Keyboard Strobe
|
||||||
ss[0x20] = notImplementedSoftSwitch // Cassette Output
|
io.addSoftSwitchR(0x20, notImplementedSoftSwitchR) // Cassette Output
|
||||||
ss[0x30] = notImplementedSoftSwitch // Speaker
|
io.addSoftSwitchR(0x30, notImplementedSoftSwitchR) // Speaker
|
||||||
ss[0x40] = notImplementedSoftSwitch // Game connector Strobe
|
io.addSoftSwitchR(0x40, notImplementedSoftSwitchR) // Game connector Strobe
|
||||||
// Note: Some sources indicate that all these cover 16 positions
|
// Note: Some sources indicate that all these cover 16 positions
|
||||||
// for read and write. But the Apple2e take over some of them, with
|
// for read and write. But the Apple2e take over some of them, with
|
||||||
// the prevention on acting only on writes.
|
// the prevention on acting only on writes.
|
||||||
|
|
||||||
ss[0x50] = getSoftSwitch(ioFlagGraphics, false)
|
io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagGraphics, false))
|
||||||
ss[0x51] = getSoftSwitch(ioFlagGraphics, true)
|
io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagGraphics, true))
|
||||||
ss[0x52] = getSoftSwitch(ioFlagMixed, false)
|
io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false))
|
||||||
ss[0x53] = getSoftSwitch(ioFlagMixed, true)
|
io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true))
|
||||||
ss[0x54] = getSoftSwitch(ioFlagSecondPage, false)
|
io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false))
|
||||||
ss[0x55] = getSoftSwitch(ioFlagSecondPage, true)
|
io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true))
|
||||||
ss[0x56] = getSoftSwitch(ioFlagHiRes, false)
|
io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false))
|
||||||
ss[0x57] = getSoftSwitch(ioFlagHiRes, true)
|
io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true))
|
||||||
ss[0x58] = getSoftSwitch(ioFlagAnnunciator0, false)
|
io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false))
|
||||||
ss[0x59] = getSoftSwitch(ioFlagAnnunciator0, true)
|
io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true))
|
||||||
ss[0x5a] = getSoftSwitch(ioFlagAnnunciator1, false)
|
io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false))
|
||||||
ss[0x5b] = getSoftSwitch(ioFlagAnnunciator1, true)
|
io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true))
|
||||||
ss[0x5c] = getSoftSwitch(ioFlagAnnunciator2, false)
|
io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false))
|
||||||
ss[0x5d] = getSoftSwitch(ioFlagAnnunciator2, true)
|
io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true))
|
||||||
ss[0x5e] = getSoftSwitch(ioFlagAnnunciator3, false)
|
io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false))
|
||||||
ss[0x5f] = getSoftSwitch(ioFlagAnnunciator3, true)
|
io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true))
|
||||||
|
|
||||||
ss[0x60] = notImplementedSoftSwitch // Cassetter Input
|
io.addSoftSwitchR(0x60, notImplementedSoftSwitchR) // Cassette Input
|
||||||
ss[0x61] = getStatusSoftSwitch(ioFlagButton0)
|
io.addSoftSwitchR(0x61, getStatusSoftSwitch(ioFlagButton0))
|
||||||
ss[0x62] = getStatusSoftSwitch(ioFlagButton1)
|
io.addSoftSwitchR(0x62, getStatusSoftSwitch(ioFlagButton1))
|
||||||
ss[0x63] = getStatusSoftSwitch(ioFlagButton2)
|
io.addSoftSwitchR(0x63, getStatusSoftSwitch(ioFlagButton2))
|
||||||
ss[0x64] = getStatusSoftSwitch(ioDataPaddle0)
|
io.addSoftSwitchR(0x64, getStatusSoftSwitch(ioDataPaddle0))
|
||||||
ss[0x65] = getStatusSoftSwitch(ioDataPaddle1)
|
io.addSoftSwitchR(0x65, getStatusSoftSwitch(ioDataPaddle1))
|
||||||
ss[0x66] = getStatusSoftSwitch(ioDataPaddle2)
|
io.addSoftSwitchR(0x66, getStatusSoftSwitch(ioDataPaddle2))
|
||||||
ss[0x67] = getStatusSoftSwitch(ioDataPaddle3)
|
io.addSoftSwitchR(0x67, getStatusSoftSwitch(ioDataPaddle3))
|
||||||
ss[0x68] = ss[0x60]
|
|
||||||
ss[0x69] = ss[0x61]
|
// The previous 8 softswitches are repeated
|
||||||
ss[0x6A] = ss[0x62]
|
io.addSoftSwitchR(0x68, notImplementedSoftSwitchR) // Cassette Input
|
||||||
ss[0x6B] = ss[0x63]
|
io.addSoftSwitchR(0x69, getStatusSoftSwitch(ioFlagButton0))
|
||||||
ss[0x6C] = ss[0x64]
|
io.addSoftSwitchR(0x6A, getStatusSoftSwitch(ioFlagButton1))
|
||||||
ss[0x6D] = ss[0x65]
|
io.addSoftSwitchR(0x6B, getStatusSoftSwitch(ioFlagButton2))
|
||||||
ss[0x6E] = ss[0x66]
|
io.addSoftSwitchR(0x6C, getStatusSoftSwitch(ioDataPaddle0))
|
||||||
ss[0x6F] = ss[0x67]
|
io.addSoftSwitchR(0x6D, getStatusSoftSwitch(ioDataPaddle1))
|
||||||
ss[0x70] = notImplementedSoftSwitch // Game controllers reset
|
io.addSoftSwitchR(0x6E, getStatusSoftSwitch(ioDataPaddle2))
|
||||||
|
io.addSoftSwitchR(0x6F, getStatusSoftSwitch(ioDataPaddle3))
|
||||||
|
|
||||||
|
io.addSoftSwitchR(0x70, notImplementedSoftSwitchR) // Game controllers reset
|
||||||
}
|
}
|
||||||
|
|
||||||
func notImplementedSoftSwitch(*ioC0Page, bool, uint8) uint8 {
|
func notImplementedSoftSwitchR(*ioC0Page) uint8 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
func getStatusSoftSwitch(ioFlag uint8) softSwitch {
|
func getStatusSoftSwitch(ioFlag uint8) softSwitchR {
|
||||||
return func(io *ioC0Page, isWrite bool, value uint8) uint8 {
|
return func(io *ioC0Page) uint8 {
|
||||||
return io.softSwitchesData[ioFlag]
|
return io.softSwitchesData[ioFlag]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSoftSwitch(ioFlag uint8, isSet bool) softSwitch {
|
func getSoftSwitch(ioFlag uint8, isSet bool) softSwitchR {
|
||||||
return func(io *ioC0Page, isWrite bool, value uint8) uint8 {
|
return func(io *ioC0Page) uint8 {
|
||||||
if isSet {
|
if isSet {
|
||||||
io.softSwitchesData[ioFlag] = ssOn
|
io.softSwitchesData[ioFlag] = ssOn
|
||||||
} else {
|
} else {
|
||||||
@ -90,18 +92,18 @@ func getSoftSwitch(ioFlag uint8, isSet bool) softSwitch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKeySoftSwitch(p *ioC0Page, _ bool, _ uint8) uint8 {
|
func getKeySoftSwitch(io *ioC0Page) uint8 {
|
||||||
strobed := (p.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0
|
strobed := (io.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0
|
||||||
if strobed && p.keyboard != nil {
|
if strobed && io.keyboard != nil {
|
||||||
if key, ok := p.keyboard.getKey(); ok {
|
if key, ok := io.keyboard.getKey(); ok {
|
||||||
p.softSwitchesData[ioDataKeyboard] = key + (1 << 7)
|
io.softSwitchesData[ioDataKeyboard] = key + (1 << 7)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p.softSwitchesData[ioDataKeyboard]
|
return io.softSwitchesData[ioDataKeyboard]
|
||||||
}
|
}
|
||||||
|
|
||||||
func strobeKeyboardSoftSwitch(p *ioC0Page, _ bool, _ uint8) uint8 {
|
func strobeKeyboardSoftSwitch(io *ioC0Page) uint8 {
|
||||||
result := p.softSwitchesData[ioDataKeyboard]
|
result := io.softSwitchesData[ioDataKeyboard]
|
||||||
p.softSwitchesData[ioDataKeyboard] &^= 1 << 7
|
io.softSwitchesData[ioDataKeyboard] &^= 1 << 7
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -4,45 +4,43 @@ const (
|
|||||||
ioFlagIntCxRom uint8 = 0x15
|
ioFlagIntCxRom uint8 = 0x15
|
||||||
ioFlagSlotC3Rom uint8 = 0x17
|
ioFlagSlotC3Rom uint8 = 0x17
|
||||||
ioFlag80Store uint8 = 0x18
|
ioFlag80Store uint8 = 0x18
|
||||||
|
ioFlagAltChar uint8 = 0x19
|
||||||
ioFlag80Col uint8 = 0x1F
|
ioFlag80Col uint8 = 0x1F
|
||||||
)
|
)
|
||||||
|
|
||||||
func addApple2ESoftSwitches(io *ioC0Page) {
|
func addApple2ESoftSwitches(io *ioC0Page) {
|
||||||
ss := &io.softSwitches
|
|
||||||
|
|
||||||
ss[0x00] = getSoftSwitchExt(ioFlag80Store, ssOff, nil)
|
io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil))
|
||||||
ss[0x01] = getSoftSwitchExt(ioFlag80Store, ssOn, nil)
|
io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil))
|
||||||
ss[0x06] = getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff)
|
io.addSoftSwitchW(0x06, getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff))
|
||||||
ss[0x07] = getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn)
|
io.addSoftSwitchW(0x07, getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn))
|
||||||
ss[0x0A] = getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff)
|
io.addSoftSwitchW(0x0A, getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff))
|
||||||
ss[0x0B] = getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn)
|
io.addSoftSwitchW(0x0B, getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn))
|
||||||
ss[0x0C] = getSoftSwitchExt(ioFlag80Col, ssOff, nil)
|
io.addSoftSwitchW(0x0C, getSoftSwitchExt(ioFlag80Col, ssOff, nil))
|
||||||
ss[0x0D] = getSoftSwitchExt(ioFlag80Col, ssOn, nil)
|
io.addSoftSwitchW(0x0D, getSoftSwitchExt(ioFlag80Col, ssOn, nil))
|
||||||
|
io.addSoftSwitchW(0x0E, getSoftSwitchExt(ioFlagAltChar, ssOff, nil))
|
||||||
|
io.addSoftSwitchW(0x0F, getSoftSwitchExt(ioFlagAltChar, ssOn, nil))
|
||||||
|
io.softSwitchesData[ioFlagAltChar] = ssOn // Not sure about this.
|
||||||
|
|
||||||
ss[0x15] = getStatusSoftSwitch(ioFlagIntCxRom)
|
io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom))
|
||||||
ss[0x17] = getStatusSoftSwitch(ioFlagSlotC3Rom)
|
io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom))
|
||||||
ss[0x18] = getStatusSoftSwitch(ioFlag80Store)
|
io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store))
|
||||||
ss[0x1C] = getStatusSoftSwitch(ioFlagSecondPage)
|
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage))
|
||||||
ss[0x1F] = getStatusSoftSwitch(ioFlag80Col)
|
io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col))
|
||||||
}
|
}
|
||||||
|
|
||||||
type softSwitchExtAction func(io *ioC0Page)
|
type softSwitchExtAction func(io *ioC0Page)
|
||||||
|
|
||||||
func getSoftSwitchExt(ioFlag uint8, dstValue uint8, action softSwitchExtAction) softSwitch {
|
func getSoftSwitchExt(ioFlag uint8, dstValue uint8, action softSwitchExtAction) softSwitchW {
|
||||||
return func(io *ioC0Page, isWrite bool, value uint8) uint8 {
|
return func(io *ioC0Page, _ uint8) {
|
||||||
//fmt.Printf("Softswitch 0x%02x %v %v\n", ioFlag, isWrite, dstValue)
|
|
||||||
if !isWrite {
|
|
||||||
return 0 // New Apple2e softswitches ignore reads
|
|
||||||
}
|
|
||||||
currentValue := io.softSwitchesData[ioFlag]
|
currentValue := io.softSwitchesData[ioFlag]
|
||||||
if currentValue == dstValue {
|
if currentValue == dstValue {
|
||||||
return 0 // Already switched, ignore
|
return // Already switched, ignore
|
||||||
}
|
}
|
||||||
if action != nil {
|
if action != nil {
|
||||||
action(io)
|
action(io)
|
||||||
}
|
}
|
||||||
io.softSwitchesData[ioFlag] = value
|
io.softSwitchesData[ioFlag] = dstValue
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
main.go
4
main.go
@ -4,8 +4,8 @@ import "go6502/apple2"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//romFile := "apple2/romdumps/Apple2.rom"
|
//romFile := "apple2/romdumps/Apple2.rom"
|
||||||
romFile := "apple2/romdumps/Apple2_Plus.rom"
|
//romFile := "apple2/romdumps/Apple2_Plus.rom"
|
||||||
//romFile := "apple2/romdumps/Apple2e.rom"
|
romFile := "apple2/romdumps/Apple2e.rom"
|
||||||
|
|
||||||
log := false
|
log := false
|
||||||
apple2.Run(romFile, log)
|
apple2.Run(romFile, log)
|
||||||
|
Loading…
Reference in New Issue
Block a user