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-02-16 04:01:31 -05:00
|
|
|
package disassembly
|
|
|
|
|
2019-08-11 16:49:58 -04:00
|
|
|
import (
|
2020-10-05 14:20:21 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
2020-03-21 18:39:56 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
|
2019-08-11 16:49:58 -04:00
|
|
|
)
|
2019-02-16 04:01:31 -05:00
|
|
|
|
2019-11-18 08:40:11 -05:00
|
|
|
// disasmMemory is a simplified memory model that allows the emulated CPU to
|
2020-10-05 14:20:21 -04:00
|
|
|
// read cartridge memory without touching the actual cartridge.
|
2019-04-08 12:55:33 -04:00
|
|
|
type disasmMemory struct {
|
2021-06-30 10:03:52 -04:00
|
|
|
// the bank which the cartridge starts on
|
|
|
|
startingBank int
|
|
|
|
|
|
|
|
// current bank to index the banks array
|
|
|
|
currentBank int
|
|
|
|
banks []mapper.BankContent
|
|
|
|
|
|
|
|
// the current origin for the mapped bank
|
2020-06-28 06:35:25 -04:00
|
|
|
origin uint16
|
2019-02-16 04:01:31 -05:00
|
|
|
}
|
|
|
|
|
2021-06-30 10:03:52 -04:00
|
|
|
func newDisasmMemory(startingBank int, copiedBanks []mapper.BankContent) *disasmMemory {
|
|
|
|
dismem := &disasmMemory{
|
|
|
|
startingBank: startingBank,
|
|
|
|
currentBank: startingBank,
|
|
|
|
banks: copiedBanks,
|
|
|
|
}
|
|
|
|
return dismem
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dismem *disasmMemory) reset() {
|
|
|
|
dismem.currentBank = dismem.startingBank
|
|
|
|
dismem.origin = dismem.banks[dismem.currentBank].Origins[0]
|
|
|
|
}
|
|
|
|
|
2019-11-18 08:40:11 -05:00
|
|
|
func (dismem *disasmMemory) Read(address uint16) (uint8, error) {
|
2019-02-16 04:01:31 -05:00
|
|
|
// map address
|
2020-10-03 12:48:17 -04:00
|
|
|
address, area := memorymap.MapAddress(address, true)
|
|
|
|
if area == memorymap.Cartridge {
|
2021-06-30 10:03:52 -04:00
|
|
|
// bring address into range. if it's still outside of range return a
|
|
|
|
// zero byte (with no error)
|
|
|
|
//
|
|
|
|
// the alternative to this strategy is to use a mask based on the
|
|
|
|
// actual length of the bank. in most cases this will be the same as
|
|
|
|
// memorymap.CartridgeBits but some cartridge mappers use banks that
|
|
|
|
// are smaller than that:
|
|
|
|
//
|
|
|
|
// address = address & uint16(len(dismem.banks[0].Data)-1)
|
|
|
|
//
|
|
|
|
// the problem with this is that the Read() function will return a byte
|
|
|
|
// which may be misleading to the disassembler. using the strategy
|
|
|
|
// below a value of zero is returned.
|
|
|
|
//
|
|
|
|
// no error is returned, even though it might seem we should, because
|
|
|
|
// it would only cause the CPU to halt mid-instruction, which would
|
|
|
|
// only cause other complications.
|
2020-06-28 06:35:25 -04:00
|
|
|
address = (address - dismem.origin) & memorymap.CartridgeBits
|
2021-06-30 10:03:52 -04:00
|
|
|
if address >= uint16(len(dismem.banks[dismem.currentBank].Data)) {
|
2020-06-28 06:35:25 -04:00
|
|
|
return 0, nil
|
|
|
|
}
|
2021-06-30 10:03:52 -04:00
|
|
|
return dismem.banks[dismem.currentBank].Data[address], nil
|
2019-02-16 04:01:31 -05:00
|
|
|
}
|
|
|
|
|
2020-10-05 14:20:21 -04:00
|
|
|
// address outside of cartridge range return nothing
|
2019-02-16 04:01:31 -05:00
|
|
|
return 0, nil
|
2020-01-19 16:46:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (dismem *disasmMemory) ReadZeroPage(address uint8) (uint8, error) {
|
|
|
|
return dismem.Read(uint16(address))
|
2019-02-16 04:01:31 -05:00
|
|
|
}
|
|
|
|
|
2019-11-18 08:40:11 -05:00
|
|
|
func (dismem *disasmMemory) Write(address uint16, data uint8) error {
|
2019-02-16 04:01:31 -05:00
|
|
|
return nil
|
|
|
|
}
|