static void controller_status_command(struct game_controller* cont, uint8_t* cmd)
{
    enum pak_type pak;
    int connected = game_controller_is_connected(cont, &pak);

    if (cmd[1] & 0x80)
        return;

    if (!connected)
    {
        cmd[1] |= 0x80;
        return;
    }

    cmd[3] = 0x05;
    cmd[4] = 0x00;

    switch(pak)
    {
    case PAK_MEM:
    case PAK_RUMBLE:
    case PAK_TRANSFER:
        cmd[5] = 1;
        break;

    case PAK_NONE:
    default:
        cmd[5] = 0;
    }
}
static void controller_read_buttons_command(struct game_controller* cont, uint8_t* cmd)
{
    enum pak_type pak;
    int connected = game_controller_is_connected(cont, &pak);

    if (!connected)
        cmd[1] |= 0x80;

    /* NOTE: buttons reading is done in read_controller_read_buttons instead */
}
static void read_controller_read_buttons(struct game_controller* cont, uint8_t* cmd)
{
    enum pak_type pak;
    int connected = game_controller_is_connected(cont, &pak);

    if (!connected)
        return;

    *((uint32_t*)(cmd + 3)) = game_controller_get_input(cont);
}
static void read_controller_read_buttons(struct game_controller* cont, uint8_t* cmd)
{
    enum pak_type pak;
    int connected = game_controller_is_connected(cont, &pak);

    if (!connected)
        return;

    *((uint32_t*)(cmd + 3)) = game_controller_get_input(cont);

#ifdef COMPARE_CORE
    CoreCompareDataSync(4, cmd + 3);
#endif
}
static void controller_write_pak_command(struct game_controller* cont, uint8_t* cmd)
{
    enum pak_type pak;
    int connected = game_controller_is_connected(cont, &pak);

    if (!connected)
    {
        cmd[1] |= 0x80;
        return;
    }

    switch (pak)
    {
    case PAK_NONE: /* do nothing */ break;
    case PAK_MEM: mempak_write_command(&cont->mempak, cmd); break;
    case PAK_RUMBLE: rumblepak_write_command(&cont->rumblepak, cmd); break;
    case PAK_TRANSFER: /* TODO */ break;
    default:
        DebugMessage(M64MSG_WARNING, "Unknown plugged pak %d", (int)pak);
    }

    cmd[0x25] = pak_data_crc(&cmd[5]);
}
static void controller_write_pak_command(struct game_controller* cont, uint8_t* cmd)
{
    enum pak_type pak;
    uint16_t address;
    const uint8_t *data = NULL;
    int       connected = game_controller_is_connected(cont, &pak);

    if (!connected)
    {
        cmd[1] |= 0x80;
        return;
    }

    address = (cmd[3] << 8) | (cmd[4] & 0xe0);
    data    = &cmd[5];

    switch (pak)
    {
       case PAK_NONE:
          /* do nothing */
          break;
       case PAK_MEM:
          mempak_write_command(&cont->mempak, address, data);
          break;
       case PAK_RUMBLE:
          rumblepak_write_command(&cont->rumblepak, address, data);
          break;
       case PAK_TRANSFER:
          transferpak_write_command(&cont->transferpak, address, data);
          break;
       default:
          DebugMessage(M64MSG_WARNING, "Unknown plugged pak %d", (int)pak);
    }

    cmd[0x25] = pak_data_crc((uint8_t*)data);
}