2020-06-19 05:44:04 -04: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/>.
|
|
|
|
|
|
|
|
package disassembly
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
|
|
|
|
"github.com/jetsetilly/gopher2600/prefs"
|
2021-10-03 06:40:31 -04:00
|
|
|
"github.com/jetsetilly/gopher2600/resources"
|
2020-06-19 05:44:04 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
type Preferences struct {
|
|
|
|
dsm *Disassembly
|
|
|
|
dsk *prefs.Disk
|
|
|
|
|
|
|
|
// whether to apply the high mirror bits to the displayed address
|
|
|
|
FxxxMirror prefs.Bool
|
2020-10-03 12:48:17 -04:00
|
|
|
Symbols prefs.Bool
|
2020-10-01 18:27:49 -04:00
|
|
|
|
|
|
|
// the lowest value to use when formatting address values. changed by the
|
|
|
|
// preferences system
|
|
|
|
mirrorOrigin uint16
|
2020-06-19 05:44:04 -04:00
|
|
|
}
|
|
|
|
|
2020-10-15 11:18:03 -04:00
|
|
|
func (p *Preferences) String() string {
|
2020-06-19 05:44:04 -04:00
|
|
|
return p.dsk.String()
|
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// newPreferences is the preferred method of initialisation for the Preferences type.
|
2020-06-19 05:44:04 -04:00
|
|
|
func newPreferences(dsm *Disassembly) (*Preferences, error) {
|
2021-01-19 14:02:07 -05:00
|
|
|
p := &Preferences{dsm: dsm}
|
|
|
|
|
2021-11-30 09:18:19 -05:00
|
|
|
p.FxxxMirror.SetHookPost(func(v prefs.Value) error {
|
|
|
|
if v.(bool) {
|
|
|
|
p.mirrorOrigin = memorymap.OriginCartFxxxMirror
|
|
|
|
} else {
|
|
|
|
p.mirrorOrigin = memorymap.OriginCart
|
|
|
|
}
|
|
|
|
dsm.setCartMirror()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
p.SetDefaults()
|
2020-06-19 05:44:04 -04:00
|
|
|
|
2021-10-03 06:40:31 -04:00
|
|
|
pth, err := resources.JoinPath(prefs.DefaultPrefsFile)
|
2020-06-19 05:44:04 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
p.dsk, err = prefs.NewDisk(pth)
|
2020-10-16 09:50:23 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-10-17 04:47:49 -04:00
|
|
|
err = p.dsk.Add("disassembly.fxxxMirror", &p.FxxxMirror)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = p.dsk.Add("disassembly.symbols", &p.Symbols)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-06-19 05:44:04 -04:00
|
|
|
|
2020-09-18 14:10:26 -04:00
|
|
|
err = p.dsk.Load(true)
|
2020-06-19 05:44:04 -04:00
|
|
|
if err != nil {
|
2020-10-16 09:50:23 -04:00
|
|
|
return nil, err
|
2020-06-19 05:44:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return p, nil
|
|
|
|
}
|
|
|
|
|
2021-11-30 09:18:19 -05:00
|
|
|
// SetDefaults reverts all settings to default values.
|
|
|
|
func (p *Preferences) SetDefaults() {
|
|
|
|
p.FxxxMirror.Set(true)
|
|
|
|
p.Symbols.Set(true)
|
|
|
|
p.mirrorOrigin = memorymap.OriginCartFxxxMirror
|
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// Load disassembly preferences and apply to the current disassembly.
|
2020-06-19 05:44:04 -04:00
|
|
|
func (p *Preferences) Load() error {
|
2020-11-19 00:57:34 -05:00
|
|
|
return p.dsk.Load(false)
|
2020-06-19 05:44:04 -04:00
|
|
|
}
|
|
|
|
|
2020-10-16 11:03:36 -04:00
|
|
|
// Save current disassembly preferences to disk.
|
2020-06-19 05:44:04 -04:00
|
|
|
func (p *Preferences) Save() error {
|
|
|
|
return p.dsk.Save()
|
|
|
|
}
|
|
|
|
|
|
|
|
// setCartMirror sets the mirror bits to the user's preference. called by the
|
|
|
|
// FxxxMirror callback.
|
2020-10-17 04:47:49 -04:00
|
|
|
func (dsm *Disassembly) setCartMirror() {
|
2020-06-19 05:44:04 -04:00
|
|
|
dsm.crit.Lock()
|
|
|
|
defer dsm.crit.Unlock()
|
|
|
|
|
2022-01-07 09:12:55 -05:00
|
|
|
for b := range dsm.disasmEntries.Entries {
|
|
|
|
for _, e := range dsm.disasmEntries.Entries[b] {
|
2022-10-18 02:03:26 -04:00
|
|
|
if e == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-06-19 05:44:04 -04:00
|
|
|
// mask off bits that indicate the cartridge/segment origin and reset
|
|
|
|
// them with the chosen origin
|
2020-10-01 18:27:49 -04:00
|
|
|
a := e.Result.Address&memorymap.CartridgeBits | dsm.Prefs.mirrorOrigin
|
2020-06-19 05:44:04 -04:00
|
|
|
e.Address = fmt.Sprintf("$%04x", a)
|
|
|
|
|
|
|
|
// branch instructions need special handling because for readability we
|
|
|
|
// translate the offset to an absolute address, which has changed.
|
2024-01-16 05:54:54 -05:00
|
|
|
if e.Result.Defn != nil && e.Result.Defn.IsBranch() {
|
2020-06-19 05:44:04 -04:00
|
|
|
// mask off bits that indicate the cartridge/segment origin and reset
|
|
|
|
// them with the chosen origin
|
2020-10-01 18:27:49 -04:00
|
|
|
a := e.Result.Address&memorymap.CartridgeBits | dsm.Prefs.mirrorOrigin
|
2023-11-14 10:18:32 -05:00
|
|
|
e.Operand.partial = fmt.Sprintf("$%04x", absoluteBranchDestination(a, e.Result.InstructionData))
|
2020-06-19 05:44:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|