2020-01-05 13:54:01 -05:00
|
|
|
// This file is part of Gopher2600.
|
|
|
|
//
|
|
|
|
// Gopher2600 is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// Gopher2600 is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
2019-12-12 13:30:32 -05:00
|
|
|
package cartridge
|
2019-06-01 09:06:38 -04:00
|
|
|
|
|
|
|
import (
|
2019-06-02 08:31:52 -04:00
|
|
|
"fmt"
|
2024-04-15 05:23:57 -04:00
|
|
|
"io"
|
2020-03-21 18:39:56 -04:00
|
|
|
|
2024-04-15 05:23:57 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
2023-04-16 11:39:36 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/environment"
|
2020-09-15 16:21:13 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
2020-06-19 05:44:04 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
|
2019-06-01 09:06:38 -04:00
|
|
|
)
|
|
|
|
|
2019-09-16 09:32:54 -04:00
|
|
|
// from bankswitch_sizes.txt:
|
|
|
|
//
|
|
|
|
// -E0: Parker Brothers was the main user of this method. This cart is
|
|
|
|
// segmented into 4 1K segments. Each segment can point to one 1K slice of the
|
|
|
|
// ROM image. You select the desired 1K slice by accessing 1FE0 to 1FE7 for
|
|
|
|
// the first 1K (1FE0 selects slice 0, 1FE1 selects slice 1, etc). 1FE8 to
|
|
|
|
// 1FEF selects the slice for the second 1K, and 1FF0 to 1FF8 selects the slice
|
|
|
|
// for the third 1K. The last 1K always points to the last 1K of the ROM image
|
|
|
|
// so that the cart always starts up in the exact same place.
|
2020-10-24 17:57:57 -04:00
|
|
|
//
|
|
|
|
// cartridges:
|
2023-02-12 08:07:49 -05:00
|
|
|
// - Montezuma's Revenge
|
|
|
|
// - Lord of the Rings
|
|
|
|
// - etc.
|
2019-06-01 09:06:38 -04:00
|
|
|
type parkerBros struct {
|
2023-04-16 11:39:36 -04:00
|
|
|
env *environment.Environment
|
2021-11-28 06:37:51 -05:00
|
|
|
|
2022-01-05 11:22:26 -05:00
|
|
|
mappingID string
|
2020-04-01 10:02:14 -04:00
|
|
|
|
2020-06-17 05:30:41 -04:00
|
|
|
// parkerBros cartridges have 8 banks of 1024 bytes
|
2020-06-11 08:14:29 -04:00
|
|
|
bankSize int
|
|
|
|
banks [][]uint8
|
2019-06-01 09:06:38 -04:00
|
|
|
|
2020-10-24 17:57:57 -04:00
|
|
|
// rewindable state
|
|
|
|
state *parkerBrosState
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:57 -04:00
|
|
|
func newParkerBros(env *environment.Environment, loader cartridgeloader.Loader) (mapper.CartMapper, error) {
|
|
|
|
data, err := io.ReadAll(loader)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("E0: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-06-11 08:14:29 -04:00
|
|
|
cart := &parkerBros{
|
2023-04-16 11:39:36 -04:00
|
|
|
env: env,
|
2022-01-05 11:22:26 -05:00
|
|
|
mappingID: "E0",
|
|
|
|
bankSize: 1024,
|
|
|
|
state: newParkerBrosState(),
|
2020-06-11 08:14:29 -04:00
|
|
|
}
|
2019-06-01 09:06:38 -04:00
|
|
|
|
2020-05-30 04:38:52 -04:00
|
|
|
cart.banks = make([][]uint8, cart.NumBanks())
|
2019-06-01 09:06:38 -04:00
|
|
|
|
2020-06-11 08:14:29 -04:00
|
|
|
if len(data) != cart.bankSize*cart.NumBanks() {
|
2023-02-13 06:08:52 -05:00
|
|
|
return nil, fmt.Errorf("E0: wrong number of bytes in the cartridge data")
|
2019-11-03 14:10:50 -05:00
|
|
|
}
|
2019-06-01 09:06:38 -04:00
|
|
|
|
2020-05-30 04:38:52 -04:00
|
|
|
for k := 0; k < cart.NumBanks(); k++ {
|
2020-06-11 08:14:29 -04:00
|
|
|
cart.banks[k] = make([]uint8, cart.bankSize)
|
|
|
|
offset := k * cart.bankSize
|
|
|
|
copy(cart.banks[k], data[offset:offset+cart.bankSize])
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return cart, nil
|
|
|
|
}
|
|
|
|
|
2021-11-19 03:54:54 -05:00
|
|
|
// MappedBanks implements the mapper.CartMapper interface.
|
|
|
|
func (cart *parkerBros) MappedBanks() string {
|
2021-02-18 17:13:18 -05:00
|
|
|
return fmt.Sprintf("Banks: %d %d %d %d", cart.state.segment[0], cart.state.segment[1], cart.state.segment[2], cart.state.segment[3])
|
2020-04-01 10:02:14 -04:00
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// ID implements the mapper.CartMapper interface.
|
2020-11-21 18:12:34 -05:00
|
|
|
func (cart *parkerBros) ID() string {
|
2020-04-30 17:06:48 -04:00
|
|
|
return cart.mappingID
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
2020-10-23 14:26:34 -04:00
|
|
|
// Snapshot implements the mapper.CartMapper interface.
|
2020-12-30 16:20:56 -05:00
|
|
|
func (cart *parkerBros) Snapshot() mapper.CartMapper {
|
|
|
|
n := *cart
|
|
|
|
n.state = cart.state.Snapshot()
|
|
|
|
return &n
|
2020-10-23 14:26:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Plumb implements the mapper.CartMapper interface.
|
2023-04-16 16:42:20 -04:00
|
|
|
func (cart *parkerBros) Plumb(env *environment.Environment) {
|
|
|
|
cart.env = env
|
2020-10-23 14:26:34 -04:00
|
|
|
}
|
|
|
|
|
2020-10-19 07:50:21 -04:00
|
|
|
// Reset implements the mapper.CartMapper interface.
|
2021-11-28 06:37:51 -05:00
|
|
|
func (cart *parkerBros) Reset() {
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = cart.NumBanks() - 4
|
|
|
|
cart.state.segment[1] = cart.NumBanks() - 3
|
|
|
|
cart.state.segment[2] = cart.NumBanks() - 2
|
|
|
|
cart.state.segment[3] = cart.NumBanks() - 1
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
2023-01-11 06:33:02 -05:00
|
|
|
// Access implements the mapper.CartMapper interface.
|
|
|
|
func (cart *parkerBros) Access(addr uint16, peek bool) (uint8, uint8, error) {
|
2019-06-01 09:06:38 -04:00
|
|
|
var data uint8
|
|
|
|
if addr >= 0x0000 && addr <= 0x03ff {
|
2020-10-24 17:57:57 -04:00
|
|
|
data = cart.banks[cart.state.segment[0]][addr&0x03ff]
|
2019-06-01 09:06:38 -04:00
|
|
|
} else if addr >= 0x0400 && addr <= 0x07ff {
|
2020-10-24 17:57:57 -04:00
|
|
|
data = cart.banks[cart.state.segment[1]][addr&0x03ff]
|
2019-06-01 09:06:38 -04:00
|
|
|
} else if addr >= 0x0800 && addr <= 0x0bff {
|
2020-10-24 17:57:57 -04:00
|
|
|
data = cart.banks[cart.state.segment[2]][addr&0x03ff]
|
2019-06-01 09:06:38 -04:00
|
|
|
} else if addr >= 0x0c00 && addr <= 0x0fff {
|
2020-10-24 17:57:57 -04:00
|
|
|
data = cart.banks[cart.state.segment[3]][addr&0x03ff]
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
2020-08-25 13:33:37 -04:00
|
|
|
|
2023-01-10 14:31:15 -05:00
|
|
|
if !peek {
|
|
|
|
cart.bankswitch(addr)
|
|
|
|
}
|
2020-08-25 13:33:37 -04:00
|
|
|
|
2023-01-10 16:10:11 -05:00
|
|
|
return data, mapper.CartDrivenPins, nil
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
2023-02-06 04:14:28 -05:00
|
|
|
// AccessVolatile implements the mapper.CartMapper interface.
|
|
|
|
func (cart *parkerBros) AccessVolatile(addr uint16, data uint8, poke bool) error {
|
2023-01-10 14:31:15 -05:00
|
|
|
if !poke {
|
|
|
|
if cart.bankswitch(addr) {
|
|
|
|
return nil
|
|
|
|
}
|
2022-05-23 14:14:36 -04:00
|
|
|
}
|
|
|
|
|
2020-06-11 08:14:29 -04:00
|
|
|
if poke {
|
|
|
|
if addr >= 0x0000 && addr <= 0x03ff {
|
2021-03-20 06:50:21 -04:00
|
|
|
cart.banks[cart.state.segment[0]][addr&0x3ff] = data
|
2020-06-11 08:14:29 -04:00
|
|
|
} else if addr >= 0x0400 && addr <= 0x07ff {
|
2021-03-20 06:50:21 -04:00
|
|
|
cart.banks[cart.state.segment[1]][addr&0x3ff] = data
|
2020-06-11 08:14:29 -04:00
|
|
|
} else if addr >= 0x0800 && addr <= 0x0bff {
|
2021-03-20 06:50:21 -04:00
|
|
|
cart.banks[cart.state.segment[2]][addr&0x3ff] = data
|
2020-06-11 08:14:29 -04:00
|
|
|
} else if addr >= 0x0c00 && addr <= 0x0fff {
|
2021-03-20 06:50:21 -04:00
|
|
|
cart.banks[cart.state.segment[3]][addr&0x3ff] = data
|
2020-06-11 08:14:29 -04:00
|
|
|
}
|
2022-05-23 14:14:36 -04:00
|
|
|
return nil
|
2020-06-11 08:14:29 -04:00
|
|
|
}
|
|
|
|
|
2023-02-06 04:14:28 -05:00
|
|
|
return nil
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
2022-05-23 14:14:36 -04:00
|
|
|
// bankswitch on hotspot access. returns false if address wasn't recognised
|
2023-01-10 14:31:15 -05:00
|
|
|
func (cart *parkerBros) bankswitch(addr uint16) bool {
|
2020-06-17 05:30:41 -04:00
|
|
|
if addr >= 0xfe0 && addr <= 0xff7 {
|
|
|
|
switch addr {
|
|
|
|
// segment 0
|
|
|
|
case 0x0fe0:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 0
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe1:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 1
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe2:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 2
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe3:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 3
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe4:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 4
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe5:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 5
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe6:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 6
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe7:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[0] = 7
|
2020-06-17 05:30:41 -04:00
|
|
|
|
|
|
|
// segment 1
|
|
|
|
case 0x0fe8:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 0
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fe9:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 1
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fea:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 2
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0feb:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 3
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fec:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 4
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fed:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 5
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fee:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 6
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0fef:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[1] = 7
|
2020-06-17 05:30:41 -04:00
|
|
|
|
|
|
|
// segment 2
|
|
|
|
case 0x0ff0:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 0
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff1:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 1
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff2:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 2
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff3:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 3
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff4:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 4
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff5:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 5
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff6:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 6
|
2020-06-17 05:30:41 -04:00
|
|
|
case 0x0ff7:
|
2020-10-24 17:57:57 -04:00
|
|
|
cart.state.segment[2] = 7
|
2020-06-17 05:30:41 -04:00
|
|
|
}
|
2022-05-23 14:14:36 -04:00
|
|
|
|
|
|
|
return true
|
2019-09-16 09:32:54 -04:00
|
|
|
}
|
2022-05-23 14:14:36 -04:00
|
|
|
|
|
|
|
return false
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// NumBanks implements the mapper.CartMapper interface.
|
2020-11-21 18:12:34 -05:00
|
|
|
func (cart *parkerBros) NumBanks() int {
|
2019-06-01 09:06:38 -04:00
|
|
|
return 8
|
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// GetBank implements the mapper.CartMapper interface.
|
2020-11-21 18:12:34 -05:00
|
|
|
func (cart *parkerBros) GetBank(addr uint16) mapper.BankInfo {
|
2020-06-19 05:44:04 -04:00
|
|
|
var seg int
|
2019-06-01 09:06:38 -04:00
|
|
|
if addr >= 0x0000 && addr <= 0x03ff {
|
2020-06-19 05:44:04 -04:00
|
|
|
seg = 0
|
2019-06-01 09:06:38 -04:00
|
|
|
} else if addr >= 0x0400 && addr <= 0x07ff {
|
2020-06-19 05:44:04 -04:00
|
|
|
seg = 1
|
2019-06-01 09:06:38 -04:00
|
|
|
} else if addr >= 0x0800 && addr <= 0x0bff {
|
2020-06-19 05:44:04 -04:00
|
|
|
seg = 2
|
|
|
|
} else { // remaining address is between 0x0c00 and 0x0fff
|
|
|
|
seg = 3
|
2019-06-01 09:06:38 -04:00
|
|
|
}
|
2020-06-19 05:44:04 -04:00
|
|
|
|
2021-02-18 17:13:18 -05:00
|
|
|
return mapper.BankInfo{Number: cart.state.segment[seg], IsRAM: false, IsSegmented: true, Segment: seg}
|
2019-06-02 08:31:52 -04:00
|
|
|
}
|
|
|
|
|
2023-11-26 04:16:39 -05:00
|
|
|
// Patch implements the mapper.CartPatchable interface.
|
2020-06-11 08:14:29 -04:00
|
|
|
func (cart *parkerBros) Patch(offset int, data uint8) error {
|
|
|
|
if offset >= cart.bankSize*len(cart.banks) {
|
2023-02-13 06:08:52 -05:00
|
|
|
return fmt.Errorf("E0: patch offset too high (%d)", offset)
|
2020-06-11 08:14:29 -04:00
|
|
|
}
|
|
|
|
|
2020-10-15 16:51:41 -04:00
|
|
|
bank := offset / cart.bankSize
|
2020-10-16 07:19:11 -04:00
|
|
|
offset %= cart.bankSize
|
2020-06-11 08:14:29 -04:00
|
|
|
cart.banks[bank][offset] = data
|
|
|
|
return nil
|
2019-09-16 09:32:54 -04:00
|
|
|
}
|
2020-02-27 02:37:55 -05:00
|
|
|
|
2023-01-11 06:33:02 -05:00
|
|
|
// AccessPassive implements the mapper.CartMapper interface.
|
2023-10-23 13:26:27 -04:00
|
|
|
func (cart *parkerBros) AccessPassive(_ uint16, _ uint8) error {
|
|
|
|
return nil
|
2020-02-27 02:37:55 -05:00
|
|
|
}
|
2020-04-22 14:49:42 -04:00
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// Step implements the mapper.CartMapper interface.
|
2020-12-29 17:37:20 -05:00
|
|
|
func (cart *parkerBros) Step(_ float32) {
|
2020-04-22 14:49:42 -04:00
|
|
|
}
|
2020-06-28 06:35:25 -04:00
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// IterateBank implements the mapper.CartMapper interface.
|
2020-11-21 18:12:34 -05:00
|
|
|
func (cart *parkerBros) CopyBanks() []mapper.BankContent {
|
2020-10-05 14:20:21 -04:00
|
|
|
c := make([]mapper.BankContent, len(cart.banks))
|
|
|
|
|
|
|
|
// banks 0 to len-1 can occupy any of the three segments
|
|
|
|
for b := 0; b < len(cart.banks)-1; b++ {
|
|
|
|
c[b] = mapper.BankContent{Number: b,
|
2020-06-28 06:35:25 -04:00
|
|
|
Data: cart.banks[b],
|
|
|
|
Origins: []uint16{
|
|
|
|
memorymap.OriginCart,
|
|
|
|
memorymap.OriginCart + uint16(cart.bankSize),
|
|
|
|
memorymap.OriginCart + uint16(cart.bankSize)*2,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2020-10-05 14:20:21 -04:00
|
|
|
|
|
|
|
// last bank can occupy any of the four segments (the last segment always
|
|
|
|
// points to bank 7 but bank 7 can also be in another segment at the
|
|
|
|
// same time)
|
|
|
|
b := len(cart.banks) - 1
|
|
|
|
c[b] = mapper.BankContent{Number: b,
|
|
|
|
Data: cart.banks[b],
|
|
|
|
Origins: []uint16{
|
|
|
|
memorymap.OriginCart,
|
|
|
|
memorymap.OriginCart + uint16(cart.bankSize),
|
|
|
|
memorymap.OriginCart + uint16(cart.bankSize)*2,
|
|
|
|
memorymap.OriginCart + uint16(cart.bankSize)*3,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return c
|
2020-06-28 06:35:25 -04:00
|
|
|
}
|
2020-10-07 17:17:53 -04:00
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// ReadHotspots implements the mapper.CartHotspotsBus interface.
|
2020-11-21 18:12:34 -05:00
|
|
|
func (cart *parkerBros) ReadHotspots() map[uint16]mapper.CartHotspotInfo {
|
2020-10-07 17:17:53 -04:00
|
|
|
return map[uint16]mapper.CartHotspotInfo{
|
|
|
|
// segment 0
|
2021-11-18 05:54:19 -05:00
|
|
|
0x1fe0: {Symbol: "B0S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe1: {Symbol: "B1S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe2: {Symbol: "B2S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe3: {Symbol: "B3S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe4: {Symbol: "B4S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe5: {Symbol: "B5S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe6: {Symbol: "B6S0", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe7: {Symbol: "B7S0", Action: mapper.HotspotBankSwitch},
|
2020-10-07 17:17:53 -04:00
|
|
|
|
|
|
|
// segment 1
|
2021-11-18 05:54:19 -05:00
|
|
|
0x1fe8: {Symbol: "B0S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fe9: {Symbol: "B1S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fea: {Symbol: "B2S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1feb: {Symbol: "B3S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fec: {Symbol: "B4S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fed: {Symbol: "B5S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fee: {Symbol: "B6S1", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1fef: {Symbol: "B7S1", Action: mapper.HotspotBankSwitch},
|
2020-10-07 17:17:53 -04:00
|
|
|
|
|
|
|
// segment 2
|
2021-11-18 05:54:19 -05:00
|
|
|
0x1ff0: {Symbol: "B0S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff1: {Symbol: "B1S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff2: {Symbol: "B2S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff3: {Symbol: "B3S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff4: {Symbol: "B4S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff5: {Symbol: "B5S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff6: {Symbol: "B6S2", Action: mapper.HotspotBankSwitch},
|
|
|
|
0x1ff7: {Symbol: "B7S2", Action: mapper.HotspotBankSwitch},
|
2020-10-07 17:17:53 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// WriteHotspots implements the mapper.CartHotspotsBus interface.
|
2020-11-21 18:12:34 -05:00
|
|
|
func (cart *parkerBros) WriteHotspots() map[uint16]mapper.CartHotspotInfo {
|
2020-10-07 17:17:53 -04:00
|
|
|
return cart.ReadHotspots()
|
|
|
|
}
|
2020-10-24 17:57:57 -04:00
|
|
|
|
|
|
|
// rewindable state for the parker bros. cartridges.
|
|
|
|
type parkerBrosState struct {
|
|
|
|
// parkerBros cartridges divide memory into 4 segments
|
|
|
|
// o the last segment always points to the last bank
|
|
|
|
// o the other segments can point to any one of the eight banks in the ROM
|
|
|
|
// (including the last bank)
|
|
|
|
segment [4]int
|
|
|
|
}
|
|
|
|
|
|
|
|
func newParkerBrosState() *parkerBrosState {
|
|
|
|
return &parkerBrosState{}
|
|
|
|
}
|
|
|
|
|
2020-12-30 16:20:56 -05:00
|
|
|
// Snapshot implements the mapper.CartMapper interface.
|
|
|
|
func (s *parkerBrosState) Snapshot() *parkerBrosState {
|
2020-10-24 17:57:57 -04:00
|
|
|
n := *s
|
|
|
|
return &n
|
|
|
|
}
|