Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions data/mupen64plus.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18352,19 +18352,35 @@ GoodName=64DD IPL (USA)

[8485643E5830CD67ED4C0A5FD49E2491]
GoodName=Mario Artist Paint Studio (J)
Transferpak=Yes

[B17771664DAF95D7E61D8549A8CEACC6]
GoodName=Mario Artist Paint Studio (J) [English v2.1]
Transferpak=Yes

[88228E990B58A94E9B3460BEFF632304]
GoodName=Mario Artist Talent Studio (J)
Transferpak=Yes

[F3767735B1610C2BCA3220B590D43232]
GoodName=Mario Artist Talent Studio (J) [English v2.1]
Transferpak=Yes

[114AF722029D6386C3BFEA4CC8FA603C]
GoodName=Mario Artist Communication Kit (J)

[DA23EE561578B7DAD77ED72728B46D30]
GoodName=Mario Artist Polygon Studio (J)

[7B94CB9AF6FE351CA7B47F59594AF96C]
GoodName=Mario Artist Polygon Studio (J) [English v3.0]

[EBBA03F20096FC2BC178FC3A1F4EC2B6]
GoodName=Sim City 64 (J)

[4372F74477FE54CD363FE4F14984625A]
GoodName=Sim City 64 (J) [English v0.6.38]

[9F797A9C704B5EBD04D6A2B036309AF2]
GoodName=Nihon Pro Golf Tour 64 (J)

Expand Down
78 changes: 43 additions & 35 deletions src/device/controllers/paks/transferpak.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@

#include <string.h>

#define RESET_MODE_CART_ENABLE_BIT UINT32_C(0x00000001)
#define RESET_MODE_PAK_ENABLE_BIT UINT32_C(0x00000080)

static uint16_t gb_cart_address(unsigned int bank, uint16_t address)
{
return (address & 0x3fff) | ((bank & 0x3) * 0x4000) ;
return (address & 0x3fff) | (bank * 0x4000);
}

void init_transferpak(struct transferpak* tpk, struct gb_cart* gb_cart)
Expand All @@ -49,10 +51,8 @@ void poweron_transferpak(struct transferpak* tpk)
{
tpk->enabled = 0;
tpk->bank = 0;
tpk->access_mode = (tpk->gb_cart == NULL)
? CART_NOT_INSERTED
: CART_ACCESS_MODE_0;
tpk->access_mode_changed = 0x44;
tpk->cart_enabled = 0;
tpk->reset_state = 3;

if (tpk->gb_cart != NULL) {
poweron_gb_cart(tpk->gb_cart);
Expand All @@ -62,16 +62,13 @@ void poweron_transferpak(struct transferpak* tpk)
void change_gb_cart(struct transferpak* tpk, struct gb_cart* gb_cart)
{
tpk->enabled = 0;
tpk->cart_enabled = 0;
tpk->reset_state = 3;
tpk->gb_cart = gb_cart;

if (gb_cart == NULL) {
tpk->access_mode = CART_NOT_INSERTED;
}
else {
tpk->access_mode = CART_ACCESS_MODE_0;
if (gb_cart != NULL) {
poweron_gb_cart(gb_cart);
}

tpk->gb_cart = gb_cart;
}

static void plug_transferpak(void* pak)
Expand All @@ -87,35 +84,44 @@ static void unplug_transferpak(void* pak)
static void read_transferpak(void* pak, uint16_t address, uint8_t* data, size_t size)
{
struct transferpak* tpk = (struct transferpak*)pak;
uint8_t value;
uint8_t value = 0;

DebugMessage(M64MSG_VERBOSE, "tpak read: %04x", address);

switch(address >> 12)
{
case 0x8:
/* get gb cart state (enabled/disabled) */
value = (tpk->enabled)
? 0x84
: 0x00;
value = (tpk->enabled) ? 0x84 : 0x00;

DebugMessage(M64MSG_VERBOSE, "tpak get cart state: %02x", value);
memset(data, value, size);
break;

case 0xb:
/* get gb cart access mode */
if (tpk->enabled)
{
DebugMessage(M64MSG_VERBOSE, "tpak get access mode: %02x", tpk->access_mode);
memset(data, tpk->access_mode, size);
if (tpk->access_mode != CART_NOT_INSERTED)
{
data[0] |= tpk->access_mode_changed;
}
tpk->access_mode_changed = 0;
{
if (tpk->gb_cart && tpk->cart_enabled) {
value |= RESET_MODE_CART_ENABLE_BIT;
}

value |= (uint8_t)((tpk->reset_state & 3) << 2);

if (tpk->enabled) {
value |= RESET_MODE_PAK_ENABLE_BIT;
}

if (tpk->cart_enabled && tpk->reset_state == 3) {
tpk->reset_state = 2;
} else if (!tpk->cart_enabled && tpk->reset_state == 2) {
tpk->reset_state = 1;
} else if (!tpk->cart_enabled && tpk->reset_state == 1) {
tpk->reset_state = 0;
}

DebugMessage(M64MSG_VERBOSE, "tpak read 0xB => %02x", value);
memset(data, value, size);
break;
}

case 0xc:
case 0xd:
Expand Down Expand Up @@ -155,6 +161,13 @@ static void write_transferpak(void* pak, uint16_t address, const uint8_t* data,
DebugMessage(M64MSG_VERBOSE, "tpak disabled");
break;
case 0x84:
if (!tpk->enabled)
{
tpk->bank = 3;
tpk->cart_enabled = 0;
tpk->reset_state = 0;
}

tpk->enabled = 1;
DebugMessage(M64MSG_VERBOSE, "tpak enabled");
break;
Expand All @@ -167,7 +180,7 @@ static void write_transferpak(void* pak, uint16_t address, const uint8_t* data,
/* set gb cart bank */
if (tpk->enabled)
{
tpk->bank = value;
tpk->bank = value > 3 ? 0 : value;
DebugMessage(M64MSG_VERBOSE, "tpak set bank %02x", tpk->bank);
}
break;
Expand All @@ -176,18 +189,13 @@ static void write_transferpak(void* pak, uint16_t address, const uint8_t* data,
/* set gb cart access mode */
if (tpk->enabled)
{
tpk->access_mode_changed = 0x04;

tpk->access_mode = ((value & 1) == 0)
? CART_ACCESS_MODE_0
: CART_ACCESS_MODE_1;
tpk->reset_state = 3;
tpk->cart_enabled = 1;

if ((value & 0xfe) != 0)
{
DebugMessage(M64MSG_WARNING, "Unknown tpak write: %04x <- %02x", address, value);
}

DebugMessage(M64MSG_VERBOSE, "tpak set access mode %02x", tpk->access_mode);
}
break;

Expand All @@ -196,7 +204,7 @@ static void write_transferpak(void* pak, uint16_t address, const uint8_t* data,
case 0xe:
case 0xf:
/* write gb cart */
// if (tpk->enabled)
if (tpk->enabled)
{
DebugMessage(M64MSG_VERBOSE, "tpak write gb: %04x <- %02x", address, value);

Expand Down
12 changes: 3 additions & 9 deletions src/device/controllers/paks/transferpak.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,13 @@

struct gb_cart;

enum cart_access_mode
{
CART_NOT_INSERTED = 0x40,
CART_ACCESS_MODE_0 = 0x80,
CART_ACCESS_MODE_1 = 0x89
};

struct transferpak
{
unsigned int enabled;
unsigned int bank;
unsigned int access_mode;
unsigned int access_mode_changed;

unsigned int cart_enabled;
unsigned int reset_state;

struct gb_cart* gb_cart;
};
Expand Down
4 changes: 2 additions & 2 deletions src/device/gb/gb_cart.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ enum gbcart_extra_devices
/* various helper functions for ram, rom, or MBC uses */


static void read_rom(const void* rom_storage, const struct storage_backend_interface* irom_storage, uint16_t address, uint8_t* data, size_t size)
static void read_rom(const void* rom_storage, const struct storage_backend_interface* irom_storage, uint32_t address, uint8_t* data, size_t size)
{
assert(size > 0);

Expand All @@ -68,7 +68,7 @@ static void read_rom(const void* rom_storage, const struct storage_backend_inter
}


static void read_ram(const void* ram_storage, const struct storage_backend_interface* iram_storage, unsigned int enabled, uint16_t address, uint8_t* data, size_t size, uint8_t mask)
static void read_ram(const void* ram_storage, const struct storage_backend_interface* iram_storage, unsigned int enabled, uint32_t address, uint8_t* data, size_t size, uint8_t mask)
{
size_t i;
assert(size > 0);
Expand Down
20 changes: 10 additions & 10 deletions src/main/savestates.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,8 @@ static int savestates_load_m64p(struct device* dev, char *filepath)

unsigned int enabled = ALIGNED_GETDATA(curr, uint32_t);
unsigned int bank = ALIGNED_GETDATA(curr, uint32_t);
unsigned int access_mode = ALIGNED_GETDATA(curr, uint32_t);
unsigned int access_mode_changed = ALIGNED_GETDATA(curr, uint32_t);
unsigned int cart_enabled = ALIGNED_GETDATA(curr, uint32_t);
unsigned int reset_state = ALIGNED_GETDATA(curr, uint32_t);
COPYARRAY(gb_fingerprint, curr, uint8_t, GB_CART_FINGERPRINT_SIZE);
if (gb_fingerprint[0] != 0) {
rom_bank = ALIGNED_GETDATA(curr, uint32_t);
Expand All @@ -572,8 +572,8 @@ static int savestates_load_m64p(struct device* dev, char *filepath)
/* init transferpak state if enabled and not controlled by input plugin */
dev->transferpaks[i].enabled = enabled;
dev->transferpaks[i].bank = bank;
dev->transferpaks[i].access_mode = access_mode;
dev->transferpaks[i].access_mode_changed = access_mode_changed;
dev->transferpaks[i].cart_enabled = cart_enabled;
dev->transferpaks[i].reset_state = reset_state;

/* if it holds a valid cartridge init gbcart */
if (dev->transferpaks[i].gb_cart != NULL
Expand Down Expand Up @@ -697,8 +697,8 @@ static int savestates_load_m64p(struct device* dev, char *filepath)

unsigned int enabled = GETDATA(curr, uint32_t);
unsigned int bank = GETDATA(curr, uint32_t);
unsigned int access_mode = GETDATA(curr, uint32_t);
unsigned int access_mode_changed = GETDATA(curr, uint32_t);
unsigned int cart_enabled = GETDATA(curr, uint32_t);
unsigned int reset_state = GETDATA(curr, uint32_t);
COPYARRAY(gb_fingerprint, curr, uint8_t, GB_CART_FINGERPRINT_SIZE);
if (gb_fingerprint[0] != 0) {
rom_bank = GETDATA(curr, uint32_t);
Expand All @@ -717,8 +717,8 @@ static int savestates_load_m64p(struct device* dev, char *filepath)
/* init transferpak state if enabled and not controlled by input plugin */
dev->transferpaks[i].enabled = enabled;
dev->transferpaks[i].bank = bank;
dev->transferpaks[i].access_mode = access_mode;
dev->transferpaks[i].access_mode_changed = access_mode_changed;
dev->transferpaks[i].cart_enabled = cart_enabled;
dev->transferpaks[i].reset_state = reset_state;

/* if it holds a valid cartridge init gbcart */
if (dev->transferpaks[i].gb_cart != NULL
Expand Down Expand Up @@ -1796,8 +1796,8 @@ static int savestates_save_m64p(const struct device* dev, char *filepath)
for (i = 0; i < GAME_CONTROLLERS_COUNT; ++i) {
PUTDATA(curr, uint32_t, dev->transferpaks[i].enabled);
PUTDATA(curr, uint32_t, dev->transferpaks[i].bank);
PUTDATA(curr, uint32_t, dev->transferpaks[i].access_mode);
PUTDATA(curr, uint32_t, dev->transferpaks[i].access_mode_changed);
PUTDATA(curr, uint32_t, dev->transferpaks[i].cart_enabled);
PUTDATA(curr, uint32_t, dev->transferpaks[i].reset_state);

if (dev->transferpaks[i].gb_cart == NULL) {
uint8_t gb_fingerprint[GB_CART_FINGERPRINT_SIZE];
Expand Down