summaryrefslogtreecommitdiff
path: root/disasm.h
blob: 017a8bc99084af8e18bbc677372e9f160d391112 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#pragma once

#include "data_buffer.h"
#include "common.h"

#include <cstddef>
#include <cstdint>

enum class TracedNodeType {
    kInstruction,
    kData,
};

constexpr size_t kRefsCountPerBuffer = 10;

constexpr size_t kMnemonicBufferSize = 8;
constexpr size_t kArgsBufferSize = 80;
constexpr size_t kMarkBufferSize = 64;

enum class ReferenceType {
    kUnknown = 0,
    kBranch,
    kCall,
};

struct ReferenceRecord {
    ReferenceType type{};
    uint32_t address{};
};

struct ReferenceNode {
    ReferenceNode *next{};
    ReferenceRecord refs[kRefsCountPerBuffer];
    uint32_t refs_count{};
};

struct DisasmNode {
    const TracedNodeType type{};
    /// Absolute offset of the instruction (PC value basically)
    const uint32_t offset{};
    /// Instruction size in bytes
    size_t size{kInstructionSizeStepBytes};
    /// Indicates whether `branch_addr` should be interpreted
    bool has_branch_addr{};
    /// Absolute address of where to branch to
    uint32_t branch_addr{};
    /// Indicates whether instruction is a call (BSR, JSR) or just a branch
    /// (Bcc, JMP) if `has_branch_addr` is set
    bool is_call{};
    /// Mnemonic of the instruction at the current offset
    char mnemonic[kMnemonicBufferSize]{};
    /// Formatted arguments of the instruction;
    char arguments[kArgsBufferSize]{};
    /// Additional instruction specific info to put in a comment
    char additional[kArgsBufferSize]{};
    /// Additional instruction specific info to put in a comment
    ReferenceNode *ref_by{};
    ReferenceNode *last_ref_by{};
    void Disasm(const DataBuffer &code, const Settings&);
    void AddReferencedBy(uint32_t offset, ReferenceType);
    ~DisasmNode();
private:
};