SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Core/cheat_search.c
1 #include "gb.h"
2
3 void GB_cheat_search_reset(GB_gameboy_t *gb)
4 {
5 if (gb->cheat_search_data) {
6 free(gb->cheat_search_data);
7 gb->cheat_search_data = NULL;
8 }
9 if (gb->cheat_search_bitmap) {
10 free(gb->cheat_search_bitmap);
11 gb->cheat_search_bitmap = NULL;
12 }
13 gb->cheat_search_count = 0;
14 }
15
16 bool GB_cheat_search_filter(GB_gameboy_t *gb, const char *expression, GB_cheat_search_data_type_t data_type)
17 {
18 GB_ASSERT_NOT_RUNNING(gb)
19
20 // Make sure the expression is valid first
21 if (GB_debugger_evaluate_cheat_filter(gb, expression, NULL, 0, 0)) {
22 return false;
23 }
24 gb->cheat_search_data_type = data_type;
25
26 if (gb->cheat_search_count == 0) {
27 GB_cheat_search_reset(gb);
28 gb->cheat_search_count = gb->ram_size + gb->mbc_ram_size + sizeof(gb->hram);
29 gb->cheat_search_data = malloc(gb->cheat_search_count);
30 gb->cheat_search_bitmap = malloc((gb->cheat_search_count + 7) / 8);
31 memset(gb->cheat_search_data, 0, gb->cheat_search_count);
32 memset(gb->cheat_search_bitmap, 0, (gb->cheat_search_count + 7) / 8);
33 }
34
35 uint8_t mask = 1;
36 uint8_t *old_data = gb->cheat_search_data;
37 uint8_t *bitmap = gb->cheat_search_bitmap;
38 uint8_t *new_data = gb->ram;
39
40 for (unsigned i = gb->ram_size + gb->mbc_ram_size + sizeof(gb->hram); i--;) {
41 if (*bitmap & mask) {
42 goto skip;
43 }
44 bool result = false;
45 if (data_type & GB_CHEAT_SEARCH_DATA_TYPE_16BIT) {
46 // The last byte of each section always fails on 16-bit searches
47 if ((new_data != gb->ram + gb->ram_size - 1 &&
48 new_data != gb->mbc_ram + gb->mbc_ram_size - 1 &&
49 new_data != gb->hram + sizeof(gb->hram) - 1)) {
50 uint16_t old = old_data[0] | (old_data[1] << 8);
51 uint16_t new = new_data[0] | (new_data[1] << 8);
52 if (data_type & GB_CHEAT_SEARCH_DATA_TYPE_BE_BIT) {
53 old = __builtin_bswap16(old);
54 new = __builtin_bswap16(new);
55 }
56 GB_debugger_evaluate_cheat_filter(gb, expression, &result, old, new);
57 }
58 }
59 else {
60 GB_debugger_evaluate_cheat_filter(gb, expression, &result, *old_data, *new_data);
61 }
62 if (result) {
63 // Filter passed, update old value
64 *old_data = *new_data;
65 if (data_type & GB_CHEAT_SEARCH_DATA_TYPE_16BIT) {
66 old_data[1] = new_data[1];
67 }
68 }
69 else {
70 // Did not pass filter, remove address
71 *bitmap |= mask;
72 gb->cheat_search_count--;
73 }
74 skip:;
75 old_data++;
76 if (new_data == gb->ram + gb->ram_size - 1 && gb->mbc_ram_size) {
77 new_data = gb->mbc_ram;
78 }
79 else if (new_data == gb->mbc_ram + gb->mbc_ram_size - 1) {
80 new_data = gb->hram;
81 }
82 else {
83 new_data++;
84 }
85 mask <<= 1;
86 if (mask == 0) {
87 mask = 1;
88 bitmap++;
89 }
90 }
91
92 return true;
93 }
94
95 size_t GB_cheat_search_result_count(GB_gameboy_t *gb)
96 {
97 return gb->cheat_search_count;
98 }
99
100 void GB_cheat_search_get_results(GB_gameboy_t *gb, GB_cheat_search_result_t *results)
101 {
102 uint8_t mask = 1;
103 uint8_t *old_data = gb->cheat_search_data;
104 uint8_t *bitmap = gb->cheat_search_bitmap;
105 size_t count = gb->cheat_search_count;
106 while (count) {
107 if (!(*bitmap & mask)) {
108 count--;
109 if (gb->cheat_search_data_type & GB_CHEAT_SEARCH_DATA_TYPE_16BIT) {
110 // Do not check for end of section, data_type is required to be the same as the last filter call
111 uint16_t old = old_data[0] | (old_data[1] << 8);
112 if (gb->cheat_search_data_type & GB_CHEAT_SEARCH_DATA_TYPE_BE_BIT) {
113 old = __builtin_bswap16(old);
114 }
115 results->value = old;
116 }
117 else {
118 results->value = *old_data;
119 }
120 size_t offset = old_data - gb->cheat_search_data;
121 if (offset < gb->ram_size) {
122 results->bank = offset / 0x1000;
123 results->addr = (offset & 0xfff) + (results->bank? 0xd000 : 0xc000);
124 }
125 else if (offset < gb->ram_size + gb->mbc_ram_size) {
126 results->addr = (offset & 0x1fff) + 0xa000;
127 results->bank = (offset - gb->ram_size) / 0x2000;
128 }
129 else {
130 results->addr = (offset & 0x7f) + 0xff80;
131 results->bank = 0;
132 }
133 results++;
134 }
135 old_data++;
136 mask <<= 1;
137 if (mask == 0) {
138 mask = 1;
139 bitmap++;
140 }
141 }
142 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.