Documentation ¶
Overview ¶
Package disassembly coordinates the disassembly of Atari2600 (6507) cartridges.
Should not be confused with the disassembly sub-package that is found in the coprocessor package.
For quick disassemblies the FromCartridge() function can be used. Debuggers will probably find it more useful however, to disassemble from the memory of an already instantiated VCS.
disasm, _ := disassembly.FromMemory(cartMem, symbols.NewTable())
The FromMemory() function takes an instance of a symbols.Table or nil. In the example above, the result of NewTable() has been used, which is fine but limits the potential of the disassembly package. For best results, the symbols.ReadSymbolsFile() function should be used (see symbols package for details). Note that the FromCartridge() function handles symbols files for you.
The Write() group of functions "print" disassambly entries of type EntryTypeBlessed only. Useful for printing static disassemblies of a cartridge but probably not much else.
The iteration types provides a convenient way of iterating of the disassembly entries. It takes care of empty entries and entries not of the correct entry type. IterateAll() in particular is useful and flexible enough for many applications.
The Grep() function provides a quick way of searching the disassembly with a scope directive. More complex search schemes can be written with the iteration types.
A Disassembly instance also keeps a reference to the symbols tables (see symbols package). The GetSymbols() function can be used to get a reference to the Symbol tables. This reference will be valid throughout the lifetime of the Disassembly instance and will "survive" calls to the FromMemory() and FromCartridge() functions.
Segmented Cartridges ¶
The disassembly package treats small bank sized (those less than 4k) by performing the disassembly with the cartridge rooted at each origin point - in each possible segment allowed by the mapper.
Origin information is held in the mappers.BankContent type returned by the cartridge.CopyBanks() function.
Index ¶
- type ColumnAttr
- type DisasmEntries
- type Disassembly
- func (dsm *Disassembly) BorrowDisasm(f func(*DisasmEntries))
- func (dsm *Disassembly) ExecutedEntry(bank mapper.BankInfo, result execution.Result, checkNextAddr bool, ...) *Entry
- func (dsm *Disassembly) FormatResult(bank mapper.BankInfo, result execution.Result, level EntryLevel) *Entry
- func (dsm *Disassembly) FromMemory() error
- func (dsm *Disassembly) GetEntryByAddress(address uint16) *Entry
- func (dsm *Disassembly) Grep(output io.Writer, scope GrepScope, search string, caseSensitive bool) error
- func (dsm *Disassembly) Write(output io.Writer, attr ColumnAttr) error
- func (dsm *Disassembly) WriteAddr(output io.Writer, attr ColumnAttr, addr uint16) error
- func (dsm *Disassembly) WriteBank(output io.Writer, attr ColumnAttr, bank int) error
- type Entry
- type EntryLevel
- type Field
- type GrepScope
- type Label
- type Operand
- type Preferences
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ColumnAttr ¶ added in v0.10.1
ColumnAttr controls what is included in the string returned by Entry.StringColumnated().
type DisasmEntries ¶ added in v0.16.0
type DisasmEntries struct { // indexed by bank and address. address should be masked with memorymap.CartridgeBits before access Entries [][]*Entry }
DisasmEntries contains the individual disassembled entries of the current ROM.
type Disassembly ¶
type Disassembly struct { Prefs *Preferences // symbols used to format disassembly output Sym symbols.Symbols // contains filtered or unexported fields }
Disassembly represents the annotated disassembly of a 6507 binary.
func FromCartridge ¶
func FromCartridge(cartload cartridgeloader.Loader) (*Disassembly, error)
FromCartridge initialises a new partial emulation and returns a disassembly from the supplied cartridge filename. Useful for one-shot disassemblies, like the gopher2600 "disasm" mode.
func NewDisassembly ¶ added in v0.3.1
NewDisassembly is the preferred method of initialisation for the Disassembly type.
Also returns a reference to the disassembly's symbol table. This reference will never change over the course of the lifetime of the Disassembly type itself. ie. the returned reference is safe to use after calls to FromMemory() or FromCartridge().
func (*Disassembly) BorrowDisasm ¶ added in v0.16.0
func (dsm *Disassembly) BorrowDisasm(f func(*DisasmEntries))
BorrowDisasm will lock the DisasmEntries structure for the durction of the supplied function, which will be executed with the disasm structure as an argument.
Function will be executed with a nil argument if disassembly is not valid.
Should not be called from the emulation goroutine.
func (*Disassembly) ExecutedEntry ¶ added in v0.7.1
func (dsm *Disassembly) ExecutedEntry(bank mapper.BankInfo, result execution.Result, checkNextAddr bool, nextAddr uint16) *Entry
ExecutedEntry should be called after execution of a CPU instruction. In many instances it behaves the same as FormatResult with an EntryLevel of EntryLevelExecuted. Those intances are:
- a coprocessor is executing (and is interfering with what is being executed) - the instruction being disassembled was retrieved from a non-Cartridge address - the instruction is from an unknown bank
ExecutedEntry will update the disassembly corresponding to the result. If there is no existing entry, a new entry is added and a messsage is logged saying that there has been a "late decoding" - this suggests a flaw in the decoding process.
checkNextAddr should be false if the result does no represent a completed instruction. in other words, if the instruction has only partially completed
func (*Disassembly) FormatResult ¶
func (dsm *Disassembly) FormatResult(bank mapper.BankInfo, result execution.Result, level EntryLevel) *Entry
FormatResult creates an Entry for supplied result/bank. It will be assigned the specified EntryLevel.
If EntryLevel is EntryLevelExecuted then the disassembly will be updated but only if result.Final is true.
func (*Disassembly) FromMemory ¶ added in v0.2.1
func (dsm *Disassembly) FromMemory() error
FromMemory disassembles an existing instance of cartridge memory using a cpu with no flow control. Unlike the FromCartridge() function this function requires an existing instance of Disassembly.
Disassembly will start/assume the cartridge is in the correct starting bank.
func (*Disassembly) GetEntryByAddress ¶
func (dsm *Disassembly) GetEntryByAddress(address uint16) *Entry
GetEntryByAddress returns the disassembly entry at the specified bank/address. a returned value of nil indicates the entry is not in the cartridge; this will usually mean the address is in main VCS RAM.
also returns whether cartridge is currently working from another source meaning that the disassembly entry might not be reliable.
func (*Disassembly) Grep ¶
func (dsm *Disassembly) Grep(output io.Writer, scope GrepScope, search string, caseSensitive bool) error
Grep searches the disassembly for the specified search string.
func (*Disassembly) Write ¶
func (dsm *Disassembly) Write(output io.Writer, attr ColumnAttr) error
Write the entire disassembly to io.Writer.
func (*Disassembly) WriteAddr ¶ added in v0.10.1
func (dsm *Disassembly) WriteAddr(output io.Writer, attr ColumnAttr, addr uint16) error
WriteAddr writes the disassembly of the specified address to the io.Writer.
func (*Disassembly) WriteBank ¶
func (dsm *Disassembly) WriteBank(output io.Writer, attr ColumnAttr, bank int) error
WriteBank writes the disassembly of the selected bank to io.Writer.
type Entry ¶
type Entry struct { // the bank this entry belongs to. note that this is just the bank number; // we're not storing a copy of mapper.BankInfo. that's not needed for // disassembly purposes Bank int // the level of reliability of the information in the Entry. // // note that it is possible for EntryLevelExecuted entries to be partially // executed. check Result.Final if required. Level EntryLevel // copy of the CPU execution. must not be updated except through // updateExecutionEntry() function. // // not that the the Final field of execution.Result may be false is the // emulation is stopped mid-execution. Result execution.Result // string representations of information in execution.Result // entry.GetField() will apply white spacing padding suitable for columnation Label Label Bytecode string Address string Operator string Operand Operand // contains filtered or unexported fields }
Entry is a disassambled instruction. The constituent parts of the disassembly. It is a representation of execution.Instruction.
func (*Entry) Cycles ¶ added in v0.7.1
Cycles returns the number of cycles annotated if actual cycles differs from the number of cycles in the definition. for executed branch instructions this will always be the case.
func (*Entry) GetField ¶ added in v0.7.1
GetField returns the formatted field from the speficied Entry.
func (*Entry) Notes ¶ added in v0.16.0
Notes returns a string returning notes about the most recent execution. The information is made up of the BranchSuccess, PageFault and CPUBug fields.
func (*Entry) String ¶ added in v0.2.1
String returns a very basic representation of an Entry. Provided for convenience. Probably not of any use except for the simplest of tools.
See StringColumnated() for a fancier option.
func (*Entry) StringColumnated ¶ added in v0.10.1
func (e *Entry) StringColumnated(attr ColumnAttr) string
StringColumnated returns a columnated string representation of the Entry.
Trailing newline is not included. However, if attr.Label is true then a newline will be added after any label.
type EntryLevel ¶
type EntryLevel int
EntryLevel describes the level of the Entry.
const ( EntryLevelUnmappable EntryLevel = iota EntryLevelDecoded EntryLevelBlessed EntryLevelExecuted )
List of valid EntryLevel in increasing reliability.
Decoded entries have been decoded as though every byte point is a valid instruction. Blessed entries meanwhile take into consideration the preceding instruction and the number of bytes it would have consumed.
Decoded entries are useful in the event of the CPU landing on an address that didn't look like an instruction at disassembly time.
Blessed instructions are deemed to be more accurate because they have been reached according to the flow of the instructions from the start address.
For normal debugging operations there is no need to use EntryLevelUnmappable outside of the disassembly package. It used for the unusual case where a bank is not able to be referenced from the Entry address. See M-Network for an example of this, where Bank 7 cannot be mapped to the lower segment.
type Label ¶ added in v0.7.1
type Label struct {
// contains filtered or unexported fields
}
Label implements the Stringer interface. The String() implementation returns any address label for the entry. Use GetField() function for a white-space padded label.
type Operand ¶ added in v0.7.1
type Operand struct {
// contains filtered or unexported fields
}
Operand implements the Stringer interface. The String() implementation returns the operand (with symbols if appropriate). Use GetField function for white-space padded operand string.
type Preferences ¶ added in v0.3.1
type Preferences struct { // whether to apply the high mirror bits to the displayed address FxxxMirror prefs.Bool Symbols prefs.Bool // contains filtered or unexported fields }
func (*Preferences) Load ¶ added in v0.3.1
func (p *Preferences) Load() error
Load disassembly preferences and apply to the current disassembly.
func (*Preferences) Save ¶ added in v0.3.1
func (p *Preferences) Save() error
Save current disassembly preferences to disk.
func (*Preferences) SetDefaults ¶ added in v0.16.0
func (p *Preferences) SetDefaults()
SetDefaults reverts all settings to default values.
func (*Preferences) String ¶ added in v0.3.1
func (p *Preferences) String() string