/* THIS is the function you call from the MegaDrive or whatever. This figures
* out whether it's a genie or hex code, depunctuates it, and calls the proper
* decoder. */
-static void decode(const char* code, struct patch* result)
+void decode(const char* code, struct patch* result)
{
int len = strlen(code), i, j;
char code_to_pass[16], *x;
unsigned int PicoRead16(unsigned int a);
void PicoWrite16(unsigned int a, unsigned short d);
-
+extern unsigned short m68k_read16(unsigned int a);
+extern void m68k_write16(int a, unsigned short d);
void PicoPatchUnload(void)
{
PicoPatches[i].addr &= ~1;
if (PicoPatches[i].addr < Pico.romsize)
PicoPatches[i].data_old = *(unsigned short *)(Pico.rom + PicoPatches[i].addr);
+ else
+ PicoPatches[i].data_old = (unsigned short) m68k_read16(PicoPatches[i].addr);
if (strstr(PicoPatches[i].name, "AUTO"))
PicoPatches[i].active = 1;
}
}
else
{
- /* TODO? */
+ if (PicoPatches[i].active)
+ m68k_write16(PicoPatches[i].addr,PicoPatches[i].data);
+ else {
+ // if current addr is not patched by older patch, write back original val
+ for (u = 0; u < i; u++)
+ if (PicoPatches[u].addr == addr) break;
+ if (u == i)
+ m68k_write16(PicoPatches[i].addr,PicoPatches[i].data_old);
+ }
}
}
}
#include <pico/pico_int.h>
#include <pico/state.h>
+#include <pico/patch.h>
#include "../common/input_pico.h"
#include "../common/version.h"
#include "libretro.h"
return ret == 0;
}
-/* cheats - TODO */
+typedef struct patch
+{
+ unsigned int addr;
+ unsigned short data;
+} patch;
+
+extern void decode(char *buff, patch *dest);
+extern uint16_t m68k_read16(uint32_t a);
+extern void m68k_write16(uint32_t a, uint16_t d);
+
void retro_cheat_reset(void)
{
+ int i=0;
+ unsigned int addr;
+
+ for (i = 0; i < PicoPatchCount; i++)
+ {
+ addr = PicoPatches[i].addr;
+ if (addr < Pico.romsize) {
+ if (PicoPatches[i].active)
+ *(unsigned short *)(Pico.rom + addr) = PicoPatches[i].data_old;
+ } else {
+ if (PicoPatches[i].active)
+ m68k_write16(PicoPatches[i].addr,PicoPatches[i].data_old);
+ }
+ }
+
+ PicoPatchUnload();
}
void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
+ patch pt;
+ int array_len = PicoPatchCount;
+ char codeCopy[256];
+ char *buff;
+ bool multiline=0;
+
+ strcpy(codeCopy,code);
+
+ if (strstr(code,"+")){
+ multiline=1;
+ buff = strtok(codeCopy,"+");
+ } else {
+ buff=codeCopy;
+ }
+
+ while (buff != NULL)
+ {
+ decode(buff, &pt);
+ if (pt.addr == (uint32_t) -1 || pt.data == (uint16_t) -1)
+ {
+ log_cb(RETRO_LOG_ERROR,"CHEATS: Invalid code: %s\n",buff);
+ return;
+ }
+
+ /* code was good, add it */
+ if (array_len < PicoPatchCount + 1)
+ {
+ void *ptr;
+ array_len *= 2;
+ array_len++;
+ ptr = realloc(PicoPatches, array_len * sizeof(PicoPatches[0]));
+ if (ptr == NULL) {
+ log_cb(RETRO_LOG_ERROR,"CHEATS: Failed to allocate memory for: %s\n",buff);
+ return;
+ }
+ PicoPatches = ptr;
+ }
+ strcpy(PicoPatches[PicoPatchCount].code, buff);
+
+ PicoPatches[PicoPatchCount].active = enabled;
+ PicoPatches[PicoPatchCount].addr = pt.addr;
+ PicoPatches[PicoPatchCount].data = pt.data;
+ if (PicoPatches[PicoPatchCount].addr < Pico.romsize)
+ PicoPatches[PicoPatchCount].data_old = *(uint16_t *)(Pico.rom + PicoPatches[PicoPatchCount].addr);
+ else
+ PicoPatches[PicoPatchCount].data_old = (uint16_t) m68k_read16(PicoPatches[PicoPatchCount].addr);
+ PicoPatchCount++;
+
+ if (!multiline)
+ break;
+ buff = strtok(NULL,"+");
+ }
}
/* multidisk support */
if (input_state_cb(pad, RETRO_DEVICE_JOYPAD, 0, i))
PicoPad[pad] |= retro_pico_map[i];
+ PicoPatchApply();
PicoFrame();
video_cb((short *)vout_buf + vout_offset,