Skip to content

Commit e2100f6

Browse files
committed
Add support for the mGBA logging system.
This uses IO registers to allow a game to log in the emulator's console.
1 parent ebec335 commit e2100f6

File tree

9 files changed

+128
-27
lines changed

9 files changed

+128
-27
lines changed

accuracy/suite.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class TestRoms(Enum):
137137
key a true
138138
frame 20
139139
key a false
140-
frame 100
140+
frame 220
141141
142142
screenshot ./.tests_screenshots/mgba_suite_memory.png
143143
''',
@@ -169,7 +169,7 @@ class TestRoms(Enum):
169169
key a true
170170
frame 20
171171
key a false
172-
frame 200
172+
frame 290
173173
174174
screenshot ./.tests_screenshots/mgba_suite_timing.png
175175
''',
@@ -185,7 +185,7 @@ class TestRoms(Enum):
185185
key a true
186186
frame 20
187187
key a false
188-
frame 150
188+
frame 200
189189
190190
screenshot ./.tests_screenshots/mgba_suite_timer_count_up.png
191191
''',
@@ -214,7 +214,7 @@ class TestRoms(Enum):
214214
frame 70
215215
key down false
216216
key a true
217-
frame 20
217+
frame 30
218218
key a false
219219
220220
screenshot ./.tests_screenshots/mgba_suite_shifter.png
@@ -244,7 +244,7 @@ class TestRoms(Enum):
244244
frame 85
245245
key down false
246246
key a true
247-
frame 20
247+
frame 30
248248
key a false
249249
250250
screenshot ./.tests_screenshots/mgba_suite_multiply_long.png
@@ -259,7 +259,7 @@ class TestRoms(Enum):
259259
frame 95
260260
key down false
261261
key a true
262-
frame 20
262+
frame 80
263263
key a false
264264
265265
screenshot ./.tests_screenshots/mgba_suite_bios.png
@@ -276,7 +276,7 @@ class TestRoms(Enum):
276276
key a true
277277
frame 20
278278
key a false
279-
frame 130
279+
frame 250
280280
281281
screenshot ./.tests_screenshots/mgba_suite_dma.png
282282
''',

include/gba/io.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,28 @@ enum io_regs {
170170
IO_REG_HALTCNT = 0x04000301,
171171
IO_REG_UNKNOWN_3 = 0x04000302,
172172

173+
#ifdef WITH_DEBUGGER
174+
IO_REG_MGBA_LOG_BUFFER = 0x04FFF600,
175+
IO_REG_MGBA_LOG_BUFFER_END = 0x04FFF700,
176+
IO_REG_MGBA_LOG_FLAGS = 0x04FFF700,
177+
IO_REG_MGBA_LOG_ENABLE = 0x04FFF780,
178+
#endif
179+
173180
IO_REG_END,
174181
};
175182

183+
#ifdef WITH_DEBUGGER
184+
#define MGBA_LOG_BUFFER_SIZE (IO_REG_MGBA_LOG_BUFFER_END - IO_REG_MGBA_LOG_BUFFER)
185+
186+
enum mgba_log_level {
187+
MGBA_LOG_FATAL = 0x01,
188+
MGBA_LOG_ERROR = 0x02,
189+
MGBA_LOG_WARN = 0x04,
190+
MGBA_LOG_INFO = 0x08,
191+
MGBA_LOG_DEBUG = 0x10,
192+
};
193+
#endif
194+
176195
/*
177196
** A DMA channel and the content of the different IO registers associated with it.
178197
*/
@@ -856,6 +875,27 @@ struct io {
856875
uint8_t bytes[2];
857876
} ime;
858877
} pending;
878+
879+
#ifdef WITH_DEBUGGER
880+
struct {
881+
union {
882+
uint16_t raw;
883+
uint8_t bytes[2];
884+
} enable;
885+
886+
union {
887+
struct {
888+
uint16_t level: 4;
889+
uint16_t : 4;
890+
uint16_t send: 1;
891+
} __packed;
892+
uint16_t raw;
893+
uint8_t bytes[2];
894+
} flags;
895+
896+
uint8_t buffer[MGBA_LOG_BUFFER_SIZE + 1];
897+
} mgba_log ;
898+
#endif
859899
};
860900

861901
static_assert(sizeof(((struct io *)NULL)->dispcnt) == sizeof(uint16_t));

include/log.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ enum modules {
1616
HS_INFO = 0,
1717

1818
HS_ERROR,
19-
HS_WARNING,
19+
HS_WARN,
2020

2121
HS_CORE,
2222
HS_IO,
@@ -60,7 +60,7 @@ extern bool g_verbose_global;
6060
static char const * const modules_str[] = {
6161
[HS_INFO] = " INFO ",
6262
[HS_ERROR] = " ERROR ",
63-
[HS_WARNING] = " WARN ",
63+
[HS_WARN] = " WARN ",
6464
[HS_CORE] = " CORE ",
6565
[HS_IO] = " IO ",
6666
[HS_VIDEO] = " VIDEO ",

source/app/dbg/cmd/verbose.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct verbosity_arg verbosities[] = {
2121
{ "global", &g_verbose_global },
2222

2323
{ "info", g_verbose + HS_INFO },
24-
{ "warn", g_verbose + HS_WARNING },
24+
{ "warn", g_verbose + HS_WARN },
2525
{ "err", g_verbose + HS_ERROR },
2626

2727
{ "io", g_verbose + HS_IO },

source/app/emulator.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -469,15 +469,15 @@ app_emulator_configure_backup_storage(
469469
read_len = fread(data, 1, file_len, app->emulation.backup_file);
470470

471471
if (read_len != file_len) {
472-
logln(HS_WARNING, "Failed to read the save file. Is it corrupted?");
472+
logln(HS_WARN, "Failed to read the save file. Is it corrupted?");
473473
} else {
474474
logln(HS_INFO, "Save file successfully read.");
475475
}
476476

477477
app->emulation.launch_config->backup_storage.data = data;
478478
app->emulation.launch_config->backup_storage.size = file_len;
479479
} else {
480-
logln(HS_WARNING, "Failed to open the save file. A new one will be created instead.");
480+
logln(HS_WARN, "Failed to open the save file. A new one will be created instead.");
481481

482482
app->emulation.backup_file = hs_fopen(backup_path, "wb+");
483483

@@ -529,7 +529,7 @@ app_emulator_import_backup_storage(
529529
read_len = fread(data, 1, file_len, backup);
530530

531531
if (read_len != file_len) {
532-
logln(HS_WARNING, "Failed to import the save file. Is it corrupted?");
532+
logln(HS_WARN, "Failed to import the save file. Is it corrupted?");
533533
} else {
534534
app_new_notification(
535535
app,
@@ -545,7 +545,7 @@ app_emulator_import_backup_storage(
545545
app->emulation.backup_file = hs_fopen(backup_path, "rb+");
546546

547547
if (!app->emulation.backup_file) {
548-
logln(HS_WARNING, "Failed to open the save file. A new one will be created instead.");
548+
logln(HS_WARN, "Failed to open the save file. A new one will be created instead.");
549549

550550
app->emulation.backup_file = hs_fopen(backup_path, "wb+");
551551

@@ -637,11 +637,9 @@ app_emulator_configure_and_run(
637637
);
638638
} else {
639639
logln(
640-
HS_WARNING,
641-
"No game with the code \"%s%.3s%s\" could be found in the Hades game database.",
642-
g_light_magenta,
643-
code,
644-
g_reset
640+
HS_WARN,
641+
"No game with the code \"%.3s\" could be found in the Hades game database.",
642+
code
645643
);
646644

647645
app->emulation.game_entry = db_autodetect_game_features(app->emulation.launch_config->rom.data, app->emulation.launch_config->rom.size);
@@ -1011,7 +1009,7 @@ app_emulator_quickload(
10111009
size_t size;
10121010

10131011
if (app->emulation.quickload_request.enabled) {
1014-
logln(HS_WARNING, "A saved state is already being loaded by the emulator, ignoring the new request.");
1012+
logln(HS_WARN, "A saved state is already being loaded by the emulator, ignoring the new request.");
10151013
return;
10161014
}
10171015

source/gba/db.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ db_autodetect_game_features(
17921792

17931793
if (array_search(rom, rom_size, "EEPROM_V", 7)) {
17941794
logln(HS_INFO, "Detected EEPROM 64K memory.");
1795-
logln(HS_WARNING, "If you are having issues with corrupted saves, try EEPROM 8K instead.");
1795+
logln(HS_WARN, "If you are having issues with corrupted saves, try EEPROM 8K instead.");
17961796
entry->storage = BACKUP_EEPROM_64K;
17971797
} else if (
17981798
array_search(rom, rom_size, "SRAM_V", 5)

source/gba/memory/io.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
**
88
\******************************************************************************/
99

10+
#include "gba/io.h"
11+
#include "gba/io.h"
12+
#include "gba/io.h"
13+
#include "gba/io.h"
14+
#include "gba/io.h"
15+
#include "gba/io.h"
16+
#include "gba/io.h"
17+
#include "gba/io.h"
18+
1019
#include <string.h>
1120
#include "memory.h"
1221
#include "gba/gba.h"
@@ -355,6 +364,12 @@ mem_io_read8(
355364

356365
/* System */
357366
case IO_REG_POSTFLG: return (io->postflg);
367+
368+
/* mGBA logging system */
369+
#ifdef WITH_DEBUGGER
370+
case IO_REG_MGBA_LOG_ENABLE: return (io->mgba_log.enable.bytes[0]);
371+
case IO_REG_MGBA_LOG_ENABLE + 1: return (io->mgba_log.enable.bytes[1]);
372+
#endif
358373
}
359374
return (mem_openbus_read(gba, addr));
360375
}
@@ -821,6 +836,50 @@ mem_io_write8(
821836
}
822837
break;
823838
};
839+
840+
/* mGBA logging system */
841+
#ifdef WITH_DEBUGGER
842+
case IO_REG_MGBA_LOG_BUFFER ... IO_REG_MGBA_LOG_BUFFER_END - 1: {
843+
io->mgba_log.buffer[addr - IO_REG_MGBA_LOG_BUFFER] = val;
844+
break;
845+
}
846+
case IO_REG_MGBA_LOG_FLAGS: io->mgba_log.flags.bytes[0] = val; break;
847+
case IO_REG_MGBA_LOG_FLAGS + 1: {
848+
io->mgba_log.flags.bytes[1] = val;
849+
850+
if (io->mgba_log.flags.send) {
851+
enum modules module;
852+
int level;
853+
854+
level = 1 << io->mgba_log.flags.level;
855+
level &= 0x1F;
856+
857+
switch (level) {
858+
case MGBA_LOG_FATAL:
859+
case MGBA_LOG_ERROR: module = HS_ERROR; break;
860+
case MGBA_LOG_WARN: module = HS_WARN; break;
861+
case MGBA_LOG_INFO: module = HS_INFO; break;
862+
case MGBA_LOG_DEBUG: module = HS_DEBUG; break;
863+
default: module = HS_INFO; break;
864+
}
865+
866+
io->mgba_log.buffer[MGBA_LOG_BUFFER_SIZE] = 0x0;
867+
logln(module, "%s", io->mgba_log.buffer);
868+
memset(io->mgba_log.buffer, 0, MGBA_LOG_BUFFER_SIZE);
869+
870+
io->mgba_log.flags.send = false;
871+
}
872+
break;
873+
}
874+
case IO_REG_MGBA_LOG_ENABLE:
875+
case IO_REG_MGBA_LOG_ENABLE + 1: {
876+
io->mgba_log.enable.bytes[addr - IO_REG_MGBA_LOG_ENABLE] = val;
877+
if (io->mgba_log.enable.raw == 0xC0DE) {
878+
io->mgba_log.enable.raw = 0x1DEA;
879+
}
880+
break;
881+
}
882+
#endif
824883
}
825884
}
826885

source/gba/scheduler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ sched_run_for(
167167

168168
if (!elapsed) {
169169
if (gba->core.state != CORE_STOP) {
170-
logln(HS_WARNING, "No cycles elapsed during `core_next()`.");
170+
logln(HS_WARN, "No cycles elapsed during `core_next()`.");
171171
}
172172
break;
173173
}

source/log.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
bool g_verbose_global = true;
1818
bool g_verbose[HS_END] = {
1919
[HS_INFO] = true,
20-
[HS_WARNING] = true,
20+
[HS_WARN] = true,
2121
[HS_ERROR] = true,
2222
};
2323

@@ -84,14 +84,18 @@ logln(
8484

8585
printf("[%s] ", modules_str[module]);
8686

87-
if (module == HS_ERROR) {
88-
printf("%s%s", g_bold, g_light_red);
87+
switch (module) {
88+
case HS_ERROR: printf("%s%s", g_bold, g_light_red); break;
89+
case HS_WARN: printf("%s%s", g_bold, g_light_yellow); break;
90+
default: break;
8991
}
9092

9193
vprintf(fmt, va);
9294

93-
if (module == HS_ERROR) {
94-
printf("%s", g_reset);
95+
switch (module) {
96+
case HS_ERROR:
97+
case HS_WARN: printf("%s", g_reset); break;
98+
default: break;
9599
}
96100

97101
printf("\n");

0 commit comments

Comments
 (0)