Skip to content

Commit

Permalink
Adding memory access counting, but currently not counting IO access
Browse files Browse the repository at this point in the history
  • Loading branch information
indigodarkwolf committed May 26, 2024
1 parent 08f3109 commit 5f3ab1f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 68 deletions.
2 changes: 2 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ void main_shutdown() {
nvram_dirty = false;
}

memory_dump_usage_counts();

boxmon_system_shutdown();
sdcard_shutdown();
audio_close();
Expand Down
189 changes: 121 additions & 68 deletions src/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "memory.h"

#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
Expand Down Expand Up @@ -35,7 +36,13 @@ uint8_t rom_bank_register;
#define RAM_WRITE_BLOCKS (((RAM_SIZE) + 0x3f) >> 6)
static uint64_t *RAM_written;

static uint8_t addr_ym = 0;
static uint64_t *RAM_read_counts;
static uint64_t *RAM_write_counts;

static uint64_t *ROM_read_counts;
static uint64_t *ROM_write_counts;

static uint8_t addr_ym = 0;
static uint64_t clock_snap = 0UL;
static uint64_t clock_base = 0UL;

Expand Down Expand Up @@ -117,17 +124,27 @@ void memory_init(const memory_init_params &init_params)
RAM = new uint8_t[ram_size];
if (Memory_params.randomize) {
srand((uint32_t)SDL_GetPerformanceCounter());
for (uint32_t i = 0; i < RAM_SIZE; ++i) {
for (uint32_t i = 0; i < ram_size; ++i) {
RAM[i] = rand();
}
} else {
memset(RAM, 0, RAM_SIZE);
memset(RAM, 0, ram_size);
}

const uint32_t ram_write_blocks = RAM_WRITE_BLOCKS;
RAM_written = new uint64_t[RAM_WRITE_BLOCKS];
memset(RAM_written, 0, RAM_WRITE_BLOCKS * sizeof(uint64_t));

RAM_read_counts = new uint64_t[RAM_SIZE];
RAM_write_counts = new uint64_t[RAM_SIZE];
ROM_read_counts = new uint64_t[ROM_SIZE];
ROM_write_counts = new uint64_t[ROM_SIZE];

memset(RAM_read_counts, 0, RAM_SIZE * sizeof(uint64_t));
memset(RAM_write_counts, 0, RAM_SIZE * sizeof(uint64_t));
memset(ROM_read_counts, 0, ROM_SIZE * sizeof(uint64_t));
memset(ROM_write_counts, 0, ROM_SIZE * sizeof(uint64_t));

build_memory_map(memmap_table_hi, memory_map_hi);
build_memory_map(memmap_table_io, memory_map_io);

Expand Down Expand Up @@ -170,7 +187,7 @@ static uint8_t real_ram_read(uint16_t address)
if ((RAM_written[real_address >> 6] & ((uint64_t)1 << (real_address & 0x3f))) == 0 && Memory_params.enable_uninitialized_access_warning) {
printf("Warning: %02X:%04X accessed uninitialized RAM address %02X:%04X\n", bank6502(debug_state6502.pc), debug_state6502.pc, address < 0xa000 ? 0 : ramBank, address);
}

++RAM_read_counts[real_address];
return RAM[real_address];
}

Expand All @@ -186,10 +203,12 @@ static void real_ram_write(uint16_t address, uint8_t value)

RAM_written[real_address >> 6] |= (uint64_t)1 << (real_address & 0x3f);

++RAM_write_counts[real_address];
RAM[real_address] = value;

if (address == 1)
if (address == 1) {
ROM_BANK = value;
}
}

//
Expand All @@ -204,22 +223,25 @@ static uint8_t debug_rom_read(uint16_t address, uint8_t bank)

static uint8_t real_rom_read(uint16_t address)
{
return ROM[(ROM_BANK << 14) + address - 0xc000];
const int real_address = (ROM_BANK << 14) + address - 0xc000;
++ROM_read_counts[real_address];
return ROM[real_address];
}

static void debug_rom_write(uint16_t address, uint8_t bank, uint8_t value)
{
if (bank >= NUM_ROM_BANKS) {
if (bank <= NUM_ROM_BANKS) {
ROM[((uint32_t)bank << 14) + address - 0xc000] = value;
}
}

static void real_rom_write(uint16_t address, uint8_t value)
{
const int romBank = effective_rom_bank();
if (romBank >= NUM_ROM_BANKS) {
if (romBank <= NUM_ROM_BANKS) {
const int real_address = (romBank << 14) + address - 0xc000;

++ROM_write_counts[real_address];
ROM[real_address] = value;

// printf("Writing to hidden ram at addr: $%hx, bank $%hhx\n", address, romBank);
Expand All @@ -241,7 +263,7 @@ uint8_t debug_emu_read(uint8_t reg)
case 5: return gif_recorder_get_state();
case 6: return wav_recorder_get_state();
case 7: return Options.no_keybinds ? 1 : 0;
case 8: return (clock_snap >> 0) & 0xff; // don't do snapshotting here because no state should be changed
case 8: return (clock_snap >> 0) & 0xff; // don't do snapshotting here because no state should be changed
case 9: return (clock_snap >> 8) & 0xff;
case 10: return (clock_snap >> 16) & 0xff;
case 11: return (clock_snap >> 24) & 0xff;
Expand All @@ -264,9 +286,9 @@ uint8_t real_emu_read(uint8_t reg)
case 5: return gif_recorder_get_state();
case 6: return wav_recorder_get_state();
case 7: return Options.no_keybinds ? 1 : 0;
case 8:
clock_snap = clockticks6502 - clock_base;
return (clock_snap >> 0) & 0xff;
case 8:
clock_snap = clockticks6502 - clock_base;
return (clock_snap >> 0) & 0xff;
case 9: return (clock_snap >> 8) & 0xff;
case 10: return (clock_snap >> 16) & 0xff;
case 11: return (clock_snap >> 24) & 0xff;
Expand Down Expand Up @@ -299,15 +321,15 @@ void emu_write(uint8_t reg, uint8_t value)
case 9: printf("User debug 1: $%02x\n", value); break;
case 10: printf("User debug 2: $%02x\n", value); break;
case 11: {
if (value == 0x09 || value == 0x0a || value == 0x0d || (value >= 0x20 && value < 0x7f)) {
putchar(value);
} else if (value >= 0xa1) {
print_iso8859_15_char((char) value);
} else {
printf("\xef\xbf\xbd"); //
}
fflush(stdout);
break;
if (value == 0x09 || value == 0x0a || value == 0x0d || (value >= 0x20 && value < 0x7f)) {
putchar(value);
} else if (value >= 0xa1) {
print_iso8859_15_char((char)value);
} else {
printf("\xef\xbf\xbd"); //
}
fflush(stdout);
break;
}
default: break; // printf("WARN: Invalid register %x\n", DEVICE_EMULATOR + reg);
}
Expand Down Expand Up @@ -362,7 +384,13 @@ static uint8_t real_read(uint16_t address)
{
switch (MAP[(address >> (BYTE * 8)) & 0xff]) {
case MEMMAP_NULL: return 0;
case MEMMAP_DIRECT: return RAM[address];
case MEMMAP_DIRECT: {
if ((RAM_written[address >> 6] & ((uint64_t)1 << (address & 0x3f))) == 0 && Memory_params.enable_uninitialized_access_warning) {
printf("Warning: %02X:%04X accessed uninitialized RAM address %02X:%04X\n", bank6502(debug_state6502.pc), debug_state6502.pc, 0, address);
}
++RAM_read_counts[address];
return RAM[address];
}
case MEMMAP_RAMBANK: return real_ram_read(address); break;
case MEMMAP_ROMBANK: return real_rom_read(address); break;
case MEMMAP_IO: return real_read<memory_map_io, 0>(address);
Expand Down Expand Up @@ -403,6 +431,8 @@ static void real_write(uint16_t address, uint8_t value)
switch (MAP[(address >> (BYTE * 8)) & 0xff]) {
case MEMMAP_NULL: break;
case MEMMAP_DIRECT:
RAM_written[address >> 6] |= (uint64_t)1 << (address & 0x3f);
++RAM_write_counts[address];
RAM[address] = value;
if (address == 1)
ROM_BANK = value;
Expand Down Expand Up @@ -480,54 +510,9 @@ void memory_save(x16file *f, bool dump_ram, bool dump_bank)
{
if (dump_ram) {
x16write_memdump(f, "LOMEM", RAM, 0, 0xa000);

//std::stringstream ss;
//ss << "[LOMEM]";
//ss << std::hex;
//for (int i = 0; i < 0xa000; ++i) {
// if ((i & 0xf) == 0) {
// ss << std::setw(0) << "\n";
// ss << std::setw(4) << std::setfill('0') << i;
// ss << std::setw(0) << " ";
// } else if ((i & 0x7) == 0) {
// ss << std::setw(0) << " ";
// } else {
// ss << std::setw(0) << " ";
// }
// ss << std::setw(2) << std::setfill('0') << static_cast<int>(RAM[i]);
//}
//ss << std::setw(0) << "\n\n";
//x16write(f, ss.str());

// x16write(f, &RAM[0], sizeof(uint8_t), 0xa000);
}
if (dump_bank) {
x16write_bankdump(f, "BANKMEM", RAM + 0xa000, 0xa000, 0xc000, Options.num_ram_banks);

//std::stringstream ss;
//ss << "[BANKMEM]";
//ss << std::hex;

//for (int b = 0; b < Options.num_ram_banks; ++b) {
// for (int i = 0xa000; i <= 0xffff; ++i) {
// if ((i & 0xf) == 0) {
// ss << std::setw(0) << "\n";
// ss << std::setw(2) << std::setfill('0') << 0;
// ss << std::setw(0) << ":";
// ss << std::setw(4) << std::setfill('0') << i;
// ss << std::setw(0) << " ";
// } else if ((i & 0x7) == 0) {
// ss << std::setw(0) << " ";
// } else {
// ss << std::setw(0) << " ";
// }
// ss << std::setw(2) << std::setfill('0') << static_cast<int>(debug_read6502(static_cast<uint16_t>(i), static_cast<uint8_t>(b)));
// }
//}
//ss << std::setw(0) << "\n\n";
//x16write(f, ss.str());

// x16write(f, &RAM[0xa000], sizeof(uint8_t), (Options.num_ram_banks * 8192));
}
}

Expand All @@ -539,7 +524,7 @@ void memory_set_bank(uint16_t address, uint8_t bank)
{
if (address >= 0xc000) {
memory_set_rom_bank(bank);
} else if(address >= 0xa000) {
} else if (address >= 0xa000) {
memory_set_ram_bank(bank);
}
}
Expand Down Expand Up @@ -574,3 +559,71 @@ uint8_t memory_get_current_bank(uint16_t address)
return 0;
}
}

void memory_dump_usage_counts()
{
x16file *dumpfile = x16open("memory_dump.txt", "w");
if (dumpfile == nullptr) {
printf("Warning: Could not dump memory to memory_dump.txt.\n");
return;
}
x16write(dumpfile, "--- begin of memory usage statistics dump ---\n");
x16write(dumpfile, "Usage counts of all memory locations. Locations not printed have count zero.\n");
x16write(dumpfile, "Tip: use 'sort -r -n -k 3' to sort it so it shows the most used at the top.\n");
x16write(dumpfile, "system RAM reads:\n");
int addr;
for (addr = 0; addr < 0xa000; ++addr) {
if (RAM_read_counts[addr] > 0) {
x16write(dumpfile, std::format("r {0:04x} {1}\n", addr, RAM_read_counts[addr]));
}
}
x16write(dumpfile, "\nsystem RAM writes:\n");
for (addr = 0; addr < 0xa000; ++addr) {
if (RAM_write_counts[addr] > 0) {
x16write(dumpfile, std::format("w {0:04x} {1}\n", addr, RAM_write_counts[addr]));
}
}
x16write(dumpfile, "\nbanked RAM reads:\n");
int bank;
for (bank = 0; bank < 256; ++bank) {
for (addr = 0xa000; addr < 0xc000; ++addr) {
const int ramBank = bank % Options.num_ram_banks;
const int real_address = (ramBank << 13) + addr;
if (RAM_read_counts[real_address] > 0) {
x16write(dumpfile, std::format("r {0:02x}:{1:04x} {2}\n", bank, addr, RAM_read_counts[real_address]));
}
}
}
x16write(dumpfile, "\nbanked RAM writes:\n");
for (bank = 0; bank < 256; ++bank) {
for (addr = 0xa000; addr < 0xc000; ++addr) {
const int ramBank = bank % Options.num_ram_banks;
const int real_address = (ramBank << 13) + addr;
if (RAM_write_counts[real_address] > 0) {
x16write(dumpfile, std::format("w {0:02x}:{1:04x} {2}\n", bank, addr, RAM_write_counts[real_address]));
}
}
}
x16write(dumpfile, "\nbanked ROM reads:\n");
for (bank = 0; bank < 256; ++bank) {
for (addr = 0xc000; addr < 0x10000; ++addr) {
const int romBank = bank % TOTAL_ROM_BANKS;
const int real_address = (romBank << 14) + addr - 0xc000;
if (ROM_read_counts[real_address] > 0) {
x16write(dumpfile, std::format("r {0:02x}:{1:04x} {2}\n", bank, addr, ROM_read_counts[real_address]));
}
}
}
x16write(dumpfile, "\nbanked ROM / 'Bonk RAM' writes:\n");
for (bank = 0; bank < 256; ++bank) {
for (addr = 0xc000; addr < 0x10000; ++addr) {
const int romBank = bank % TOTAL_ROM_BANKS;
const int real_address = (romBank << 14) + addr - 0xc000;
if (ROM_write_counts[real_address] > 0) {
x16write(dumpfile, std::format("w {0:02x}:{1:04x} {2}\n", bank, addr, ROM_write_counts[real_address]));
}
}
}
x16write(dumpfile, "--- end of memory usage statistics dump ---\n");
x16close(dumpfile);
}
2 changes: 2 additions & 0 deletions src/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ uint8_t memory_get_rom_bank();

uint8_t memory_get_current_bank(uint16_t address);

void memory_dump_usage_counts();

#endif

0 comments on commit 5f3ab1f

Please sign in to comment.