|
|
|
@ -29,81 +29,86 @@ const (
|
|
|
|
|
|
|
|
|
|
func addApple2SoftSwitches(io *ioC0Page) {
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchRW(0x00, keySoftSwitch, "KEYBOARD") // Keyboard
|
|
|
|
|
io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch, "AKD") // Keyboard Strobe
|
|
|
|
|
io.addSoftSwitchR(0x20, notImplementedSoftSwitchR, "TAPEOUT") // Cassette Output
|
|
|
|
|
io.addSoftSwitchRW(0x30, speakerSoftSwitch, "SPEAKER") // Speaker
|
|
|
|
|
io.addSoftSwitchR(0x40, notImplementedSoftSwitchR, "STROBE") // Game connector Strobe
|
|
|
|
|
io.addSoftSwitchRW(0x00, buildKeySoftSwitch(io), "KEYBOARD") // Keyboard
|
|
|
|
|
io.addSoftSwitchRW(0x10, buildStrobeKeyboardSoftSwitch(io), "AKD") // Keyboard Strobe
|
|
|
|
|
io.addSoftSwitchR(0x20, buildNotImplementedSoftSwitchR(io), "TAPEOUT") // Cassette Output
|
|
|
|
|
io.addSoftSwitchRW(0x30, buildSpeakerSoftSwitch(io), "SPEAKER") // Speaker
|
|
|
|
|
io.addSoftSwitchR(0x40, buildNotImplementedSoftSwitchR(io), "STROBE") // Game connector Strobe
|
|
|
|
|
// Note: Some sources indicate that all these cover 16 positions
|
|
|
|
|
// for read and write. But the Apple2e takes over some of them, with
|
|
|
|
|
// the prevention on acting only on writes.
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagText, false), "TEXTOFF")
|
|
|
|
|
io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagText, true), "TEXTON")
|
|
|
|
|
io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false), "MIXEDOFF")
|
|
|
|
|
io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true), "MIXEDON")
|
|
|
|
|
io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false), "PAGE2OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true), "PAGE2ON")
|
|
|
|
|
io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false), "HIRESOFF")
|
|
|
|
|
io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true), "HIRESON")
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false), "ANN0OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true), "ANN0ON")
|
|
|
|
|
io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false), "ANN1OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true), "ANN1ON")
|
|
|
|
|
io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false), "ANN2OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true), "ANN2ON")
|
|
|
|
|
io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false), "ANN3OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true), "ANN3ON")
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchR(0x60, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input
|
|
|
|
|
io.addSoftSwitchR(0x61, getButtonSoftSwitch(0), "PB0")
|
|
|
|
|
io.addSoftSwitchR(0x62, getButtonSoftSwitch(1), "PB1")
|
|
|
|
|
io.addSoftSwitchR(0x63, getButtonSoftSwitch(2), "PB2")
|
|
|
|
|
io.addSoftSwitchR(0x64, getPaddleSoftSwitch(0), "PDL0")
|
|
|
|
|
io.addSoftSwitchR(0x65, getPaddleSoftSwitch(1), "PDL1")
|
|
|
|
|
io.addSoftSwitchR(0x66, getPaddleSoftSwitch(2), "PDL2")
|
|
|
|
|
io.addSoftSwitchR(0x67, getPaddleSoftSwitch(3), "PDL3")
|
|
|
|
|
io.addSoftSwitchRW(0x50, getSoftSwitch(io, ioFlagText, false), "TEXTOFF")
|
|
|
|
|
io.addSoftSwitchRW(0x51, getSoftSwitch(io, ioFlagText, true), "TEXTON")
|
|
|
|
|
io.addSoftSwitchRW(0x52, getSoftSwitch(io, ioFlagMixed, false), "MIXEDOFF")
|
|
|
|
|
io.addSoftSwitchRW(0x53, getSoftSwitch(io, ioFlagMixed, true), "MIXEDON")
|
|
|
|
|
io.addSoftSwitchRW(0x54, getSoftSwitch(io, ioFlagSecondPage, false), "PAGE2OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x55, getSoftSwitch(io, ioFlagSecondPage, true), "PAGE2ON")
|
|
|
|
|
io.addSoftSwitchRW(0x56, getSoftSwitch(io, ioFlagHiRes, false), "HIRESOFF")
|
|
|
|
|
io.addSoftSwitchRW(0x57, getSoftSwitch(io, ioFlagHiRes, true), "HIRESON")
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchRW(0x58, getSoftSwitch(io, ioFlagAnnunciator0, false), "ANN0OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x59, getSoftSwitch(io, ioFlagAnnunciator0, true), "ANN0ON")
|
|
|
|
|
io.addSoftSwitchRW(0x5a, getSoftSwitch(io, ioFlagAnnunciator1, false), "ANN1OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x5b, getSoftSwitch(io, ioFlagAnnunciator1, true), "ANN1ON")
|
|
|
|
|
io.addSoftSwitchRW(0x5c, getSoftSwitch(io, ioFlagAnnunciator2, false), "ANN2OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x5d, getSoftSwitch(io, ioFlagAnnunciator2, true), "ANN2ON")
|
|
|
|
|
io.addSoftSwitchRW(0x5e, getSoftSwitch(io, ioFlagAnnunciator3, false), "ANN3OFF")
|
|
|
|
|
io.addSoftSwitchRW(0x5f, getSoftSwitch(io, ioFlagAnnunciator3, true), "ANN3ON")
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchR(0x60, buildNotImplementedSoftSwitchR(io), "CASSETTE") // Cassette Input
|
|
|
|
|
io.addSoftSwitchR(0x61, buildButtonSoftSwitch(io, 0), "PB0")
|
|
|
|
|
io.addSoftSwitchR(0x62, buildButtonSoftSwitch(io, 1), "PB1")
|
|
|
|
|
io.addSoftSwitchR(0x63, buildButtonSoftSwitch(io, 2), "PB2")
|
|
|
|
|
io.addSoftSwitchR(0x64, buildPaddleSoftSwitch(io, 0), "PDL0")
|
|
|
|
|
io.addSoftSwitchR(0x65, buildPaddleSoftSwitch(io, 1), "PDL1")
|
|
|
|
|
io.addSoftSwitchR(0x66, buildPaddleSoftSwitch(io, 2), "PDL2")
|
|
|
|
|
io.addSoftSwitchR(0x67, buildPaddleSoftSwitch(io, 3), "PDL3")
|
|
|
|
|
|
|
|
|
|
// The previous 8 softswitches are repeated
|
|
|
|
|
io.addSoftSwitchR(0x68, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input
|
|
|
|
|
io.addSoftSwitchR(0x69, getButtonSoftSwitch(0), "PB0")
|
|
|
|
|
io.addSoftSwitchR(0x6A, getButtonSoftSwitch(1), "PB1")
|
|
|
|
|
io.addSoftSwitchR(0x6B, getButtonSoftSwitch(2), "PB2")
|
|
|
|
|
io.addSoftSwitchR(0x6C, getPaddleSoftSwitch(0), "PDL0")
|
|
|
|
|
io.addSoftSwitchR(0x6D, getPaddleSoftSwitch(1), "PDL1")
|
|
|
|
|
io.addSoftSwitchR(0x6E, getPaddleSoftSwitch(2), "PDL2")
|
|
|
|
|
io.addSoftSwitchR(0x6F, getPaddleSoftSwitch(3), "PDL3")
|
|
|
|
|
io.addSoftSwitchR(0x68, buildNotImplementedSoftSwitchR(io), "CASSETTE") // Cassette Input
|
|
|
|
|
io.addSoftSwitchR(0x69, buildButtonSoftSwitch(io, 0), "PB0")
|
|
|
|
|
io.addSoftSwitchR(0x6A, buildButtonSoftSwitch(io, 1), "PB1")
|
|
|
|
|
io.addSoftSwitchR(0x6B, buildButtonSoftSwitch(io, 2), "PB2")
|
|
|
|
|
io.addSoftSwitchR(0x6C, buildPaddleSoftSwitch(io, 0), "PDL0")
|
|
|
|
|
io.addSoftSwitchR(0x6D, buildPaddleSoftSwitch(io, 1), "PDL1")
|
|
|
|
|
io.addSoftSwitchR(0x6E, buildPaddleSoftSwitch(io, 2), "PDL2")
|
|
|
|
|
io.addSoftSwitchR(0x6F, buildPaddleSoftSwitch(io, 3), "PDL3")
|
|
|
|
|
|
|
|
|
|
io.addSoftSwitchR(0x70, strobePaddlesSoftSwitch, "RESETPDL") // Game controllers reset
|
|
|
|
|
io.addSoftSwitchR(0x70, buildStrobePaddlesSoftSwitch(io), "RESETPDL") // Game controllers reset
|
|
|
|
|
|
|
|
|
|
// For RGB screen modes. Default to NTSC artifacts
|
|
|
|
|
io.softSwitchesData[ioFlag1RGBCard] = ssOn
|
|
|
|
|
io.softSwitchesData[ioFlag2RGBCard] = ssOn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func notImplementedSoftSwitchR(io *ioC0Page) uint8 {
|
|
|
|
|
// Return random info. Some games (Serpentine) used CASSETTE and get stuck if not changing.
|
|
|
|
|
return uint8(io.apple2.cpu.GetCycles())
|
|
|
|
|
func buildNotImplementedSoftSwitchR(io *ioC0Page) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
// Return random info. Some games (Serpentine) used CASSETTE and get stuck if not changing.
|
|
|
|
|
return uint8(io.apple2.cpu.GetCycles())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func notImplementedSoftSwitchW(*ioC0Page, uint8) {
|
|
|
|
|
func buildNotImplementedSoftSwitchW(io *ioC0Page) softSwitchW {
|
|
|
|
|
return func(uint8) {
|
|
|
|
|
// Do nothing
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setStatusSoftSwitch(ioFlag uint8) softSwitchW {
|
|
|
|
|
return func(io *ioC0Page, value uint8) {
|
|
|
|
|
func setStatusSoftSwitch(io *ioC0Page, ioFlag uint8) softSwitchW {
|
|
|
|
|
return func(value uint8) {
|
|
|
|
|
io.softSwitchesData[ioFlag] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getStatusSoftSwitch(ioFlag uint8) softSwitchR {
|
|
|
|
|
return func(io *ioC0Page) uint8 {
|
|
|
|
|
func getStatusSoftSwitch(io *ioC0Page, ioFlag uint8) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
return io.softSwitchesData[ioFlag]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getSoftSwitch(ioFlag uint8, isSet bool) softSwitchR {
|
|
|
|
|
return func(io *ioC0Page) uint8 {
|
|
|
|
|
func getSoftSwitch(io *ioC0Page, ioFlag uint8, isSet bool) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
if isSet {
|
|
|
|
|
io.softSwitchesData[ioFlag] = ssOn
|
|
|
|
|
} else {
|
|
|
|
@ -113,35 +118,40 @@ func getSoftSwitch(ioFlag uint8, isSet bool) softSwitchR {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func speakerSoftSwitch(io *ioC0Page) uint8 {
|
|
|
|
|
if io.speaker != nil {
|
|
|
|
|
io.speaker.Click(io.apple2.cpu.GetCycles())
|
|
|
|
|
func buildSpeakerSoftSwitch(io *ioC0Page) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
if io.speaker != nil {
|
|
|
|
|
io.speaker.Click(io.apple2.cpu.GetCycles())
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func keySoftSwitch(io *ioC0Page) uint8 {
|
|
|
|
|
strobed := (io.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0
|
|
|
|
|
if io.keyboard != nil {
|
|
|
|
|
if key, ok := io.keyboard.GetKey(strobed); ok {
|
|
|
|
|
io.softSwitchesData[ioDataKeyboard] = key + (1 << 7)
|
|
|
|
|
func buildKeySoftSwitch(io *ioC0Page) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
strobed := (io.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0
|
|
|
|
|
if io.keyboard != nil {
|
|
|
|
|
if key, ok := io.keyboard.GetKey(strobed); ok {
|
|
|
|
|
io.softSwitchesData[ioDataKeyboard] = key + (1 << 7)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
value := io.softSwitchesData[ioDataKeyboard]
|
|
|
|
|
//fmt.Printf("Key $%02x, %v\n", value, strobed)
|
|
|
|
|
return value
|
|
|
|
|
}
|
|
|
|
|
value := io.softSwitchesData[ioDataKeyboard]
|
|
|
|
|
//fmt.Printf("Key $%02x, %v\n", value, strobed)
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func strobeKeyboardSoftSwitch(io *ioC0Page) uint8 {
|
|
|
|
|
result := io.softSwitchesData[ioDataKeyboard]
|
|
|
|
|
//fmt.Printf("Strobe $%02x\n", result)
|
|
|
|
|
io.softSwitchesData[ioDataKeyboard] &^= 1 << 7
|
|
|
|
|
return result
|
|
|
|
|
func buildStrobeKeyboardSoftSwitch(io *ioC0Page) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
result := io.softSwitchesData[ioDataKeyboard]
|
|
|
|
|
//fmt.Printf("Strobe $%02x\n", result)
|
|
|
|
|
io.softSwitchesData[ioDataKeyboard] &^= 1 << 7
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getButtonSoftSwitch(i int) softSwitchR {
|
|
|
|
|
return func(io *ioC0Page) uint8 {
|
|
|
|
|
func buildButtonSoftSwitch(io *ioC0Page, i int) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
if io.joysticks != nil && io.joysticks.ReadButton(i) {
|
|
|
|
|
return 128
|
|
|
|
|
}
|
|
|
|
@ -161,8 +171,8 @@ func getButtonSoftSwitch(i int) softSwitchR {
|
|
|
|
|
|
|
|
|
|
const paddleToCyclesFactor = 11
|
|
|
|
|
|
|
|
|
|
func getPaddleSoftSwitch(i int) softSwitchR {
|
|
|
|
|
return func(io *ioC0Page) uint8 {
|
|
|
|
|
func buildPaddleSoftSwitch(io *ioC0Page, i int) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
if io.joysticks == nil {
|
|
|
|
|
return 255 // Capacitors never discharge if there is not joystick
|
|
|
|
|
}
|
|
|
|
@ -180,8 +190,10 @@ func getPaddleSoftSwitch(i int) softSwitchR {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func strobePaddlesSoftSwitch(io *ioC0Page) uint8 {
|
|
|
|
|
// On the real machine this discharges the capacitors.
|
|
|
|
|
io.paddlesStrobeCycle = io.apple2.cpu.GetCycles()
|
|
|
|
|
return 0
|
|
|
|
|
func buildStrobePaddlesSoftSwitch(io *ioC0Page) softSwitchR {
|
|
|
|
|
return func() uint8 {
|
|
|
|
|
// On the real machine this discharges the capacitors.
|
|
|
|
|
io.paddlesStrobeCycle = io.apple2.cpu.GetCycles()
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|