Skip to content

Commit 5f60058

Browse files
committed
Support banks in memory editor
1 parent 6b64116 commit 5f60058

File tree

2 files changed

+58
-32
lines changed

2 files changed

+58
-32
lines changed

src/ui/ui_memedit.h

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
## zlib/libpng license
3434
3535
Copyright (c) 2018 Andre Weissflog
36+
Copyright (c) 2025 Tomasz Sterna
3637
This software is provided 'as-is', without any express or implied warranty.
3738
In no event will the authors be held liable for any damages arising from the
3839
use of this software.
@@ -64,16 +65,18 @@ typedef void MemoryEditor;
6465
#define UI_MEMEDIT_MAX_LAYERS (16)
6566

6667
/* callbacks for reading and writing bytes */
67-
typedef uint8_t (*ui_memedit_read_t)(int layer, uint32_t addr, void* user_data);
68-
typedef void (*ui_memedit_write_t)(int layer, uint32_t addr, uint8_t data, void* user_data);
68+
typedef uint8_t (*ui_memedit_read_t)(int layer, int bank, uint16_t addr, void* user_data);
69+
typedef void (*ui_memedit_write_t)(int layer, int bank, uint16_t addr, uint8_t data, void* user_data);
6970

7071
/* setup parameters for ui_memedit_init()
7172
7273
NOTE: all strings must be static!
7374
*/
7475
typedef struct {
7576
const char* title; /* window title */
76-
const char* layers[UI_MEMEDIT_MAX_LAYERS]; /* memory system layer names */
77+
int banks;
78+
const char* layers[UI_MEMEDIT_MAX_LAYERS]; /* memory system layer names */
79+
int layer_banks[UI_MEMEDIT_MAX_LAYERS]; /* banks in layer */
7780
ui_memedit_read_t read_cb;
7881
ui_memedit_write_t write_cb;
7982
size_t max_addr;
@@ -238,6 +241,9 @@ struct MemoryEditor
238241
int NumLayers;
239242
int CurLayer;
240243
const char* Layers[UI_MEMEDIT_MAX_LAYERS];
244+
int NumBanks;
245+
int CurBank;
246+
int LayerBanks[UI_MEMEDIT_MAX_LAYERS];
241247
bool OptShowAddrInput; // = true
242248
/*--- END ui_memedit.h changes ---*/
243249

@@ -316,6 +322,8 @@ struct MemoryEditor
316322

317323
/*--- BEGIN ui_memedit.h changes ---*/
318324
OptShowAddrInput = true;
325+
NumBanks = 0;
326+
CurBank = 0;
319327
NumLayers = 0;
320328
CurLayer = 0;
321329
for (int i = 0; i < UI_MEMEDIT_MAX_LAYERS; i++) {
@@ -708,7 +716,9 @@ struct MemoryEditor
708716
{
709717
IM_UNUSED(mem_data);
710718
ImGuiStyle& style = ImGui::GetStyle();
711-
const char* format_range = OptUpperCaseHex ? "Range %0*" _PRISizeT "X..%0*" _PRISizeT "X" : "Range %0*" _PRISizeT "x..%0*" _PRISizeT "x";
719+
/*--- BEGIN ui_memedit.h changes ---*/
720+
const char* format_range = OptUpperCaseHex ? "Range %02X:%0*" _PRISizeT "X..%0*" _PRISizeT "X" : "Range %02X:%0*" _PRISizeT "x..%0*" _PRISizeT "x";
721+
/*--- END ui_memedit.h changes ---*/
712722

713723
// Options menu
714724
if (ImGui::Button("Options"))
@@ -718,7 +728,17 @@ struct MemoryEditor
718728
if (OptShowAddrInput) {
719729
/*--- END ui_memedit.h changes ---*/
720730
ImGui::SameLine();
721-
ImGui::Text(format_range, s.AddrDigitsCount, base_display_addr, s.AddrDigitsCount, base_display_addr + mem_size - 1);
731+
ImGui::Text(format_range, CurBank, s.AddrDigitsCount, base_display_addr, s.AddrDigitsCount, base_display_addr + mem_size - 1);
732+
/*--- BEGIN ui_memedit.h changes */
733+
if (NumBanks > 1) {
734+
ImGui::SameLine();
735+
ImGui::SetNextItemWidth(2 * s.GlyphWidth + 2 * ImGui::GetFrameHeight() + style.FramePadding.x * 4.0f);
736+
static const int step = 0x1, step_fast = 0x10;
737+
ImGui::InputScalar(":", ImGuiDataType_U8, &CurBank, &step, &step_fast, "%02X", ImGuiInputTextFlags_CharsHexadecimal|ImGuiInputTextFlags_CharsUppercase);
738+
if (CurBank < 0) CurBank = 0;
739+
if (CurBank > NumBanks-1) CurBank = NumBanks-1;
740+
}
741+
/*--- END ui_memedit.h changes */
722742
ImGui::SameLine();
723743
ImGui::SetNextItemWidth((s.AddrDigitsCount + 1) * s.GlyphWidth + style.FramePadding.x * 2.0f);
724744
if (ImGui::InputText("##addr", AddrInputBuf, IM_ARRAYSIZE(AddrInputBuf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue))
@@ -739,6 +759,7 @@ struct MemoryEditor
739759
ImGui::SameLine();
740760
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
741761
ImGui::Combo("##layer", &CurLayer, Layers, NumLayers);
762+
NumBanks = LayerBanks[CurLayer];
742763
ImGui::PopItemWidth();
743764
}
744765
/*--- END ui_memedit.h changes */
@@ -1011,7 +1032,7 @@ static uint8_t _ui_memedit_readfn(const uint8_t* ptr, size_t off, void* user_dat
10111032
const ui_memedit_t* win = (ui_memedit_t*) user_data;
10121033
CHIPS_ASSERT(win && win->ed);
10131034
if (win->read_cb) {
1014-
return win->read_cb(win->ed->CurLayer, (uint16_t)off, win->user_data);
1035+
return win->read_cb(win->ed->CurLayer, win->ed->CurBank, (uint16_t)off, win->user_data);
10151036
}
10161037
else {
10171038
return 0;
@@ -1022,7 +1043,7 @@ static void _ui_memedit_writefn(uint8_t* ptr, size_t off, uint8_t val, void* use
10221043
const ui_memedit_t* win = (ui_memedit_t*) user_data;
10231044
CHIPS_ASSERT(win && win->ed);
10241045
if (win->write_cb) {
1025-
win->write_cb(win->ed->CurLayer, (uint16_t)off, val, win->user_data);
1046+
win->write_cb(win->ed->CurLayer, win->ed->CurBank, (uint16_t)off, val, win->user_data);
10261047
}
10271048
}
10281049

@@ -1051,10 +1072,12 @@ void ui_memedit_init(ui_memedit_t* win, const ui_memedit_desc_t* desc) {
10511072
win->ed->WriteFn = _ui_memedit_writefn;
10521073
win->ed->UserData = win;
10531074
win->ed->OptAddrDigitsCount = 4;
1075+
win->ed->NumBanks = desc->banks;
10541076
for (int i = 0; i < UI_MEMEDIT_MAX_LAYERS; i++) {
10551077
if (desc->layers[i]) {
10561078
win->ed->NumLayers++;
10571079
win->ed->Layers[i] = desc->layers[i];
1080+
win->ed->LayerBanks[i] = desc->layer_banks[i];
10581081
}
10591082
else {
10601083
break;

src/ui/ui_x65.cc

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -213,45 +213,47 @@ static void _ui_x65_draw_about(ui_x65_t* ui) {
213213
}
214214

215215
/* keep disassembler layer at the start */
216-
#define _UI_X65_MEMLAYER_CPU (0) /* CPU visible mapping */
217-
#define _UI_X65_MEMLAYER_RAM00 (1) /* RAM blocks */
218-
#define _UI_X65_MEMLAYER_RAM01 (2) /* RAM blocks */
219-
#define _UI_X65_MEMLAYER_RAMFF (3) /* RAM blocks */
220-
#define _UI_X65_MEMLAYER_VRAM0 (4) /* CGIA VRAM bank 0 */
221-
#define _UI_X65_MEMLAYER_VRAM1 (5) /* CGIA VRAM bank 1 */
222-
#define _UI_X65_CODELAYER_NUM (3) /* number of valid layers for disassembler */
223-
#define _UI_X65_MEMLAYER_NUM (6)
216+
#define _UI_X65_MEMLAYER_CPU (0) /* CPU visible mapping */
217+
#define _UI_X65_MEMLAYER_RAM (1) /* RAM banks */
218+
#define _UI_X65_MEMLAYER_VRAM (2) /* CGIA VRAM banks */
219+
#define _UI_X65_MEMLAYER_NUM (3)
220+
#define _UI_X65_CODELAYER_NUM (3) /* number of valid layers for disassembler */
224221

225222
static const char* _ui_x65_memlayer_names[_UI_X65_MEMLAYER_NUM] = {
226-
"CPU Mapped", "RAM Bank 00", "RAM Bank 01", "RAM Bank FF", "VRAM0", "VRAM1",
223+
"CPU Mapped",
224+
"RAM Bank",
225+
"VRAM Cache Bank",
226+
};
227+
static const int _ui_x65_memlayer_banks[_UI_X65_MEMLAYER_NUM] = {
228+
256,
229+
256,
230+
2,
227231
};
228232

229-
static uint8_t _ui_x65_mem_read(int layer, uint32_t addr, void* user_data) {
233+
static uint8_t _ui_x65_mem_read(int layer, int bank, uint16_t addr, void* user_data) {
230234
CHIPS_ASSERT(user_data);
231235
ui_x65_t* ui = (ui_x65_t*)user_data;
232236
x65_t* x65 = ui->x65;
233237
switch (layer) {
234-
case _UI_X65_MEMLAYER_CPU: return mem_rd(x65, (addr >> 16) & 0xFF, addr & 0xFFFF);
235-
case _UI_X65_MEMLAYER_RAM00: return x65->ram[(0x00 << 16) + addr];
236-
case _UI_X65_MEMLAYER_RAM01: return x65->ram[(0x01 << 16) + addr];
237-
case _UI_X65_MEMLAYER_RAMFF: return x65->ram[(0xFF << 16) + addr];
238-
case _UI_X65_MEMLAYER_VRAM0: return x65->cgia.vram[0][addr];
239-
case _UI_X65_MEMLAYER_VRAM1: return x65->cgia.vram[1][addr];
238+
case _UI_X65_MEMLAYER_CPU: return mem_rd(x65, (uint8_t)bank, addr);
239+
case _UI_X65_MEMLAYER_RAM: return x65->ram[((bank & 0xFF) << 16) | addr];
240+
case _UI_X65_MEMLAYER_VRAM: return x65->cgia.vram[bank & 0x1][addr];
240241
default: return 0xFF;
241242
}
242243
}
243244

244-
static void _ui_x65_mem_write(int layer, uint32_t addr, uint8_t data, void* user_data) {
245+
static uint8_t _ui_x65_mem_read32(int layer, uint32_t addr, void* user_data) {
246+
return _ui_x65_mem_read(layer, (uint8_t)(addr >> 16), (uint16_t)addr, user_data);
247+
}
248+
249+
static void _ui_x65_mem_write(int layer, int bank, uint16_t addr, uint8_t data, void* user_data) {
245250
CHIPS_ASSERT(user_data);
246251
ui_x65_t* ui = (ui_x65_t*)user_data;
247252
x65_t* x65 = ui->x65;
248253
switch (layer) {
249-
case _UI_X65_MEMLAYER_CPU: mem_wr(x65, (addr >> 16) & 0xFF, addr & 0xFFFF, data); break;
250-
case _UI_X65_MEMLAYER_RAM00: x65->ram[(0x00 << 16) + addr] = data; break;
251-
case _UI_X65_MEMLAYER_RAM01: x65->ram[(0x01 << 16) + addr] = data; break;
252-
case _UI_X65_MEMLAYER_RAMFF: x65->ram[(0xFF << 16) + addr] = data; break;
253-
case _UI_X65_MEMLAYER_VRAM0: x65->cgia.vram[0][addr] = data; break;
254-
case _UI_X65_MEMLAYER_VRAM1: x65->cgia.vram[1][addr] = data; break;
254+
case _UI_X65_MEMLAYER_CPU: mem_wr(x65, (uint8_t)bank, addr, data); break;
255+
case _UI_X65_MEMLAYER_RAM: x65->ram[((bank & 0xFF) << 16) | addr] = data; break;
256+
case _UI_X65_MEMLAYER_VRAM: x65->cgia.vram[bank & 0x1][addr] = data; break;
255257
}
256258
}
257259

@@ -452,7 +454,7 @@ void ui_x65_init(ui_x65_t* ui, const ui_x65_desc_t* ui_desc) {
452454
desc.freq_hz = X65_FREQUENCY;
453455
desc.scanline_ticks = ui->x65->cgia.h_period / CGIA_FIXEDPOINT_SCALE;
454456
desc.frame_ticks = MODE_V_TOTAL_LINES * ui->x65->cgia.h_period / CGIA_FIXEDPOINT_SCALE;
455-
desc.read_cb = _ui_x65_mem_read;
457+
desc.read_cb = _ui_x65_mem_read32;
456458
desc.break_cb = _ui_x65_eval_bp;
457459
desc.texture_cbs = ui_desc->dbg_texture;
458460
desc.debug_cbs = ui_desc->dbg_debug;
@@ -561,6 +563,7 @@ void ui_x65_init(ui_x65_t* ui, const ui_x65_desc_t* ui_desc) {
561563
ui_memedit_desc_t desc = { 0 };
562564
for (int i = 0; i < _UI_X65_MEMLAYER_NUM; i++) {
563565
desc.layers[i] = _ui_x65_memlayer_names[i];
566+
desc.layer_banks[i] = _ui_x65_memlayer_banks[i];
564567
}
565568
desc.read_cb = _ui_x65_mem_read;
566569
desc.write_cb = _ui_x65_mem_write;
@@ -588,7 +591,7 @@ void ui_x65_init(ui_x65_t* ui, const ui_x65_desc_t* ui_desc) {
588591
desc.cpu_type = UI_DASM_CPUTYPE_W65C816S;
589592
desc.cpu = &ui->cpu;
590593
desc.start_addr = mem_rd16(ui->x65, 0, 0xFFFC);
591-
desc.read_cb = _ui_x65_mem_read;
594+
desc.read_cb = _ui_x65_mem_read32;
592595
desc.user_data = ui;
593596
desc.labels = ui_desc->labels;
594597
static const char* titles[4] = { "Disassembler #1", "Disassembler #2", "Disassembler #2", "Dissassembler #3" };

0 commit comments

Comments
 (0)