Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Mupen64plus - pif.c *
- * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
- * Copyright (C) 2002 Hacktarux *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- #include <stdint.h>
- #include "memory.h"
- #include "pif.h"
- #include "n64_cic_nus_6105.h"
- #include "r4300/r4300.h"
- #include "r4300/interupt.h"
- //hack
- #include "r4300/recomp.h"
- #include "api/m64p_types.h"
- #include "api/callbacks.h"
- #include "api/debugger.h"
- #include "main/main.h"
- #include "main/rom.h"
- #include "main/util.h"
- #include "plugin/plugin.h"
- int file_init=0;
- int iCurrentBankNo=0, iCurrentRamBankNo=0;
- int bRamEnableState=0;
- int iCurrentRomBankNo=0;
- int iNumRamBanks=4, iNumRomBanks=999;
- int bMBC1RAMbanking=0;
- int iEnableState=1;
- int iCurrentAccessMode=0;
- int bHasTimer=0;
- int iAccessModeChanged=0;
- int bHasRam=1;
- uint8_t Data[32];
- #define true 1
- #define false 0
- uint8_t *RomData;
- uint8_t *RamData;
- int ReadCartMBC5(uint16_t dwAddress, uint8_t *Data);
- void ZeroMemory(uint8_t *Data, int s){
- memset(Data, 0, s);
- }
- void CopyMemory(uint8_t *dst, uint8_t *src, int s){
- memset(dst, 0, s);
- memcpy(dst, src, s);
- }
- int read_Rom(void){
- FILE *fp_rom;
- //fp_rom=fopen("/home/tt/ed64/tp_emulator/golf_e.gbc", "rb");
- fp_rom=fopen("/home/tt/ed64/tp_emulator/yellow.gb", "rb");
- long fileSize;
- long lCurPos, lEndPos;
- lCurPos = ftell(fp_rom);
- fseek(fp_rom, 0, 2);
- lEndPos = ftell(fp_rom);
- fseek(fp_rom, lCurPos, 0);
- fileSize = lEndPos;
- RomData = (uint8_t *)malloc(fileSize);
- // fread(buffer (from offset 0), Amount to read, Amount of times to read it, Pointer to file);
- fread(&RomData[0], fileSize, 1, fp_rom);
- // Output the bytes in the file as hex
- //for (int i = 0; i < fileSize; i ++)
- /*
- int i=0;
- for (i = 0; i < 32; i ++)
- printf("%X ", rom_buffer[i]);
- */
- fclose(fp_rom);
- return 0;
- }
- int read_Ram(void){
- FILE *fp_ram;
- //fp_ram=fopen("/home/tt/ed64/tp_emulator/golf.srm", "rb");
- fp_ram=fopen("/home/tt/ed64/tp_emulator/yellow.srm", "rb");
- long fileSize;
- long lCurPos, lEndPos;
- lCurPos = ftell(fp_ram);
- fseek(fp_ram, 0, 2);
- lEndPos = ftell(fp_ram);
- fseek(fp_ram, lCurPos, 0);
- fileSize = lEndPos;
- RamData = (uint8_t *)malloc(fileSize);
- // fread(buffer (from offset 0), Amount to read, Amount of times to read it, Pointer to file);
- fread(&RamData[0], fileSize, 1, fp_ram);
- // Output the bytes in the file as hex
- //for (int i = 0; i < fileSize; i ++)
- fclose(fp_ram);
- return 0;
- }
- int WriteCartMBC5(uint16_t dwAddress, uint8_t *Data)
- {
- switch (dwAddress >> 13)
- {
- case 0: // if ((dwAddress <= 0x1FFF)) // We shouldn't be able to read/write to RAM unless this is toggled on
- bRamEnableState = (Data[0] == 0x0A);
- printf("Set RAM enable: %d\n", bRamEnableState);
- break;
- case 1: // else if ((dwAddress >= 0x2000) && (dwAddress <= 0x2FFF)) // ROM bank select, low bits
- iCurrentRomBankNo &= 0xFF00;
- iCurrentRomBankNo |= Data[0];
- // iCurrentRomBankNo = ((int) Data[0]) | (iCurrentRomBankNo & 0x100);
- printf("Set ROM Bank: %02X\n", iCurrentRomBankNo);
- break;
- case 2: // else if ((dwAddress >= 0x3000) && (dwAddress <= 0x3FFF)) // ROM bank select, high bit
- iCurrentRomBankNo &= 0x00FF;
- iCurrentRomBankNo |= (Data[0] & 0x01) << 8;
- // iCurrentRomBankNo = (iCurrentRomBankNo & 0xFF) | ((((int) Data[0]) & 1) * 0x100);
- printf("Set ROM Bank: %02X\n", iCurrentRomBankNo);
- break;
- case 3: // if ((dwAddress >= 0x4000) && (dwAddress <= 0x5FFF)) // RAM bank select
- if (bHasRam) {
- iCurrentRamBankNo = Data[0] & 0x0F;
- printf("Set RAM Bank: %02X\n", iCurrentRamBankNo);
- }
- break;
- case 5: // else if ((dwAddress >= 0xA000) && (dwAddress <= 0xBFFF)) // Write to RAM
- if (bHasRam) {
- if (iCurrentRamBankNo >= iNumRamBanks) {
- printf("RAM write: Buffer error on ");
- printf("%02X", iCurrentRamBankNo);
- printf("\n");
- } else {
- printf("RAM write: Bank %02X\n", iCurrentRamBankNo);
- CopyMemory(&RamData[dwAddress - 0xA000 + (iCurrentRamBankNo << 13)], Data, 32);
- }
- }
- break;
- default:
- printf("Bad write to MBC5 cart, address %04X\n", dwAddress);
- }
- return true;
- }
- void stageW(int mapper, int dwAddress){
- if(file_init==0){
- printf("\n");
- printf("Rom:\n");
- read_Rom();
- int i=0;
- for (i = 0; i < 32; i ++)
- printf("%X ", RomData[i]);
- printf("\nRam:\n");
- read_Ram();
- printf("\n");
- file_init=1;
- }
- printf( "TPak Write:\n" );
- printf( " Address: %04X\n", dwAddress );
- switch (dwAddress >> 12)
- {
- case 0x8: // if ((dwAddress >= 0x8000) && (dwAddress <= 0x8FFF))
- if (Data[0] == 0xFE) {
- printf("Cart Disable\n" );
- iEnableState = false;
- }
- else if (Data[0] == 0x84) {
- printf("Cart Enable\n" );
- iEnableState = true;
- }
- else {
- printf("WARNING: Unusual Cart Enable/Disable\n" );
- printf(" Address: " );
- printf("%04X", dwAddress);
- printf("\n" );
- printf(" Data: " );
- printf("%02X", Data[0]);
- printf("\n" );
- }
- break;
- case 0xA: // if ((dwAddress >= 0xA000) && (dwAddress <= 0xAFFF))
- if (iEnableState == true) {
- iCurrentBankNo = Data[0];
- printf("Set TPak Bank No:%02X\n", Data[0] );
- }
- break;
- case 0xB: // if ((dwAddress >= 0xB000) && (dwAddress <= 0xBFFF))
- if (iEnableState == true) {
- iCurrentAccessMode = Data[0] & 1;
- /*
- if(iCurrentAccessMode)
- access=1;
- else access=0;
- */
- iAccessModeChanged = 4;
- printf("Set TPak Access Mode: %04X\n", iCurrentAccessMode);
- if ((Data[0] != 1) && (Data[0] != 0)) {
- printf("WARNING: Unusual Access Mode Change\n" );
- printf(" Address: " );
- printf("%04X",dwAddress);
- printf("\n" );
- printf(" Data: " );
- printf("%02X",Data[0]);
- printf("\n" );
- }
- }
- break;
- case 0xC:
- case 0xD:
- case 0xE:
- case 0xF: // if (dwAddress >= 0xC000)
- //WriteCartMBC1(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data);
- printf( "### Cart Write: Bank:%i\n", iCurrentBankNo );
- printf( "### Address:%04X\n", ((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000) );
- switch(mapper){
- // case 1: WriteCartMBC1(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- // case 2: WriteCartMBC2(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- // case 3: WriteCartMBC3(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- case 5: WriteCartMBC5(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- default: break;
- }
- break;
- default:
- printf("WARNING: Unusual Pak Write\n" );
- printf(" Address: %04X\n", dwAddress);
- } // end switch (dwAddress >> 12)
- Data[32] = 0x00; //DataCRC( Data, 32 );
- // Data[32] = DataCRC( Data, 32 );
- //bReturn = 0;
- }
- void stageR(int mapper, int dwAddress){
- if(file_init==0){
- printf("\n");
- printf("Rom:\n");
- read_Rom();
- int i=0;
- for (i = 0; i < 32; i ++)
- printf("%X ", RomData[i]);
- printf("\nRam:\n");
- read_Ram();
- printf("\n");
- file_init=1;
- }
- printf( "TPak Read:\n" );
- printf( " Address: %04X\n", dwAddress );
- switch (dwAddress >> 12)
- {
- case 0x8: // if ((dwAddress >= 0x8000) && (dwAddress <= 0x8FFF))
- printf( "Query Enable State: " );
- if(iEnableState==true){
- memset(&Data, 0x84, 0x20); //32 byte 00 <- mempak 0x84 tpak power on
- printf( "1\n" );
- }else if(iEnableState==false){
- memset(&Data, 0x00, 0x20);
- printf( "0\n" );
- }
- break;
- case 0xB: // if ((dwAddress >= 0xB000) && (dwAddress <= 0xBFFF))
- printf( "Query Cart. State:" );
- printf( " Inserted, Access Mode " );
- if(iCurrentAccessMode){
- memset(&Data, 0x89, 0x20);
- printf( "1\n" );
- }else {
- memset(&Data, 0x80, 0x20);
- printf( "0\n" );
- }
- Data[0] = Data[0] | (uint8_t)iAccessModeChanged;
- iAccessModeChanged = 0;
- break;
- case 0xC:
- case 0xD:
- case 0xE:
- case 0xF: // if ((dwAddress >= 0xC000))
- printf( "Cart Read: Bank:%i\n", iCurrentBankNo );
- printf( " Address:%04X\n", ((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000) );
- switch(mapper){
- // case 1: ReadCartMBC1(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- // case 2: ReadCartMBC2(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- // case 3: ReadCartMBC3(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- case 5: ReadCartMBC5(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
- default: break;
- }
- break;
- default:
- printf("WARNING: Unusual Pak Read\n" );
- printf(" Address: %04X\n", dwAddress);
- } // end switch (dwAddress >> 12)
- }
- int ReadCartMBC5(uint16_t dwAddress, uint8_t *Data)
- {
- switch (dwAddress >> 13)
- {
- case 0:
- case 1: // if ((dwAddress <= 0x3FFF))
- CopyMemory(Data, &RomData[dwAddress], 32);
- printf("Nonbanked ROM read - MBC5\n");
- break;
- case 2:
- case 3: // else if ((dwAddress >= 0x4000) && (dwAddress <= 0x7FFF))
- iCurrentRomBankNo=iCurrentBankNo; //stupid test
- if (iCurrentRomBankNo >= iNumRomBanks) {
- ZeroMemory(Data, 32);
- printf("Banked ROM read: (Banking Error)");
- printf("%02X",iCurrentRomBankNo);
- printf(" (int=%d)\n",iCurrentRomBankNo);
- } else {
- CopyMemory(Data, &RomData[dwAddress - 0x4000 + (iCurrentRomBankNo << 14)], 32);
- printf("Banked ROM read: Bank=");
- printf("%02X",iCurrentRomBankNo);
- printf(" (int=%d)\n",iCurrentRomBankNo);
- }
- break;
- case 5: // else if ((dwAddress >= 0xA000) && (dwAddress <= 0xBFFF))
- // iCurrentRamBankNo=iCurrentBankNo; //stupid test
- if (bHasRam) {
- if (iCurrentRamBankNo >= iNumRamBanks) {
- ZeroMemory(Data, 32);
- printf("Failed RAM read: (Banking Error) %02X\n", iCurrentRamBankNo);
- } else {
- CopyMemory(Data, &RamData[dwAddress - 0xA000 + (iCurrentRamBankNo << 13)], 32);
- printf("RAM read: Bank %02X\n", iCurrentRamBankNo);
- }
- } else {
- ZeroMemory(Data, 32);
- printf("Failed RAM read: (RAM Not Present)\n");
- }
- break;
- default:
- printf("Bad read from MBC5 cart, address %04X\n", dwAddress);
- }
- return true;
- }
- //hack
- extern precomp_instr *PC;
- int power=0;
- int access=0;
- int tmp=0;
- static unsigned char eeprom[0x800];
- static unsigned char mempack[4][0x8000];
- static char *get_eeprom_path(void)
- {
- return formatstr("%s%s.eep", get_savesrampath(), ROM_SETTINGS.goodname);
- }
- static void eeprom_format(void)
- {
- memset(eeprom, 0xff, sizeof(eeprom));
- }
- static void eeprom_read_file(void)
- {
- char *filename = get_eeprom_path();
- switch (read_from_file(filename, eeprom, sizeof(eeprom)))
- {
- case file_open_error:
- DebugMessage(M64MSG_VERBOSE, "couldn't open eeprom file '%s' for reading", filename);
- eeprom_format();
- break;
- case file_read_error:
- DebugMessage(M64MSG_WARNING, "fread() failed for 2kb eeprom file '%s'", filename);
- break;
- default: break;
- }
- free(filename);
- }
- static void eeprom_write_file(void)
- {
- char *filename = get_eeprom_path();
- switch (write_to_file(filename, eeprom, sizeof(eeprom)))
- {
- case file_open_error:
- DebugMessage(M64MSG_WARNING, "couldn't open eeprom file '%s' for writing", filename);
- break;
- case file_write_error:
- DebugMessage(M64MSG_WARNING, "fwrite() failed for 2kb eeprom file '%s'", filename);
- break;
- default: break;
- }
- free(filename);
- }
- static char *get_mempack_path(void)
- {
- return formatstr("%s%s.mpk", get_savesrampath(), ROM_SETTINGS.goodname);
- }
- static void mempack_format(void)
- {
- unsigned char init[] =
- {
- 0x81,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
- 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
- 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
- 0x00,0x71,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03
- };
- int i,j;
- for (i=0; i<4; i++)
- {
- for (j=0; j<0x8000; j+=2)
- {
- mempack[i][j] = 0;
- mempack[i][j+1] = 0x03;
- }
- memcpy(mempack[i], init, 272);
- }
- }
- static void mempack_read_file(void)
- {
- char *filename = get_mempack_path();
- switch (read_from_file(filename, mempack, sizeof(mempack)))
- {
- case file_open_error:
- DebugMessage(M64MSG_VERBOSE, "couldn't open memory pack file '%s' for reading", filename);
- mempack_format();
- break;
- case file_read_error:
- DebugMessage(M64MSG_WARNING, "fread() failed for 128kb mempack file '%s'", filename);
- break;
- default: break;
- }
- free(filename);
- }
- static void mempack_write_file(void)
- {
- char *filename = get_mempack_path();
- switch (write_to_file(filename, mempack, sizeof(mempack)))
- {
- case file_open_error:
- DebugMessage(M64MSG_WARNING, "couldn't open memory pack file '%s' for writing", filename);
- break;
- case file_write_error:
- DebugMessage(M64MSG_WARNING, "fwrite() failed for 128kb mempack file '%s'", filename);
- break;
- default: break;
- }
- free(filename);
- }
- //#define DEBUG_PIF
- #ifdef DEBUG_PIF
- void print_pif(void)
- {
- int i;
- for (i=0; i<(64/8); i++)
- DebugMessage(M64MSG_INFO, "%x %x %x %x | %x %x %x %x",
- PIF_RAMb[i*8+0], PIF_RAMb[i*8+1],PIF_RAMb[i*8+2], PIF_RAMb[i*8+3],
- PIF_RAMb[i*8+4], PIF_RAMb[i*8+5],PIF_RAMb[i*8+6], PIF_RAMb[i*8+7]);
- }
- #endif
- static unsigned char byte2bcd(int n)
- {
- n %= 100;
- return ((n / 10) << 4) | (n % 10);
- }
- static void EepromCommand(unsigned char *Command)
- {
- time_t curtime_time;
- struct tm *curtime;
- switch (Command[2])
- {
- case 0: // check
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "EepromCommand() check size");
- #endif
- if (Command[1] != 3)
- {
- Command[1] |= 0x40;
- if ((Command[1] & 3) > 0)
- Command[3] = 0;
- if ((Command[1] & 3) > 1)
- Command[4] = (ROM_SETTINGS.savetype != EEPROM_16KB) ? 0x80 : 0xc0;
- if ((Command[1] & 3) > 2)
- Command[5] = 0;
- }
- else
- {
- Command[3] = 0;
- Command[4] = (ROM_SETTINGS.savetype != EEPROM_16KB) ? 0x80 : 0xc0;
- Command[5] = 0;
- }
- break;
- case 4: // read
- {
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "EepromCommand() read 8-byte block %i", Command[3]);
- #endif
- eeprom_read_file();
- memcpy(&Command[4], eeprom + Command[3]*8, 8);
- }
- break;
- case 5: // write
- {
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "EepromCommand() write 8-byte block %i", Command[3]);
- #endif
- eeprom_read_file();
- memcpy(eeprom + Command[3]*8, &Command[4], 8);
- eeprom_write_file();
- }
- break;
- case 6:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "EepromCommand() RTC status query");
- #endif
- // RTCstatus query
- Command[3] = 0x00;
- Command[4] = 0x10;
- Command[5] = 0x00;
- break;
- case 7:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "EepromCommand() read RTC block %i", Command[3]);
- #endif
- // read RTC block
- switch (Command[3]) { // block number
- case 0:
- Command[4] = 0x00;
- Command[5] = 0x02;
- Command[12] = 0x00;
- break;
- case 1:
- DebugMessage(M64MSG_ERROR, "RTC command in EepromCommand(): read block %d", Command[2]);
- break;
- case 2:
- time(&curtime_time);
- curtime = localtime(&curtime_time);
- Command[4] = byte2bcd(curtime->tm_sec);
- Command[5] = byte2bcd(curtime->tm_min);
- Command[6] = 0x80 + byte2bcd(curtime->tm_hour);
- Command[7] = byte2bcd(curtime->tm_mday);
- Command[8] = byte2bcd(curtime->tm_wday);
- Command[9] = byte2bcd(curtime->tm_mon + 1);
- Command[10] = byte2bcd(curtime->tm_year);
- Command[11] = byte2bcd(curtime->tm_year / 100);
- Command[12] = 0x00; // status
- break;
- }
- break;
- case 8:
- // write RTC block
- DebugMessage(M64MSG_ERROR, "RTC write in EepromCommand(): %d not yet implemented", Command[2]);
- break;
- default:
- DebugMessage(M64MSG_ERROR, "unknown command in EepromCommand(): %x", Command[2]);
- }
- }
- static unsigned char mempack_crc(unsigned char *data)
- {
- int i;
- unsigned char CRC = 0;
- for (i=0; i<=0x20; i++)
- {
- int mask;
- for (mask = 0x80; mask >= 1; mask >>= 1)
- {
- int xor_tap = (CRC & 0x80) ? 0x85 : 0x00;
- CRC <<= 1;
- if (i != 0x20 && (data[i] & mask)) CRC |= 1;
- CRC ^= xor_tap;
- }
- }
- return CRC;
- }
- static void internal_ReadController(int Control, unsigned char *Command)
- {
- switch (Command[2])
- {
- case 1:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 1 read buttons", Control);
- #endif
- if (Controls[Control].Present)
- {
- BUTTONS Keys;
- input.getKeys(Control, &Keys);
- *((unsigned int *)(Command + 3)) = Keys.Value;
- #ifdef COMPARE_CORE
- CoreCompareDataSync(4, Command+3);
- #endif
- }
- break;
- case 2: // read controller pack
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 2 read controller pack (in Input plugin)", Control);
- #endif
- if (Controls[Control].Present)
- {
- if (Controls[Control].Plugin == PLUGIN_RAW)
- if (input.readController)
- input.readController(Control, Command);
- }
- break;
- case 3: // write controller pack
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 3 write controller pack (in Input plugin)", Control);
- #endif
- if (Controls[Control].Present)
- {
- if (Controls[Control].Plugin == PLUGIN_RAW)
- if (input.readController)
- input.readController(Control, Command);
- }
- break;
- }
- }
- static void internal_ControllerCommand(int Control, unsigned char *Command)
- {
- switch (Command[2])
- {
- case 0x00: // read status
- case 0xFF: // reset
- if ((Command[1] & 0x80))
- break;
- //#ifdef DEBUG_PIF
- // DebugMessage(M64MSG_STATUS, "internal_ControllerCommand() Channel %i Command %02x check pack present", Control, Command[2]);
- //#endif
- if (Controls[Control].Present)
- {
- Command[3] = 0x05;
- Command[4] = 0x00;
- switch (Controls[Control].Plugin)
- {
- case PLUGIN_MEMPAK:
- Command[5] = 1;
- DebugMessage(M64MSG_INFO, "0xFF reset");
- break;
- case PLUGIN_RAW:
- Command[5] = 1;
- break;
- default:
- Command[5] = 0;
- break;
- }
- }
- else
- Command[1] |= 0x80;
- break;
- case 0x01:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 1 check controller present", Control);
- #endif
- if (!Controls[Control].Present)
- Command[1] |= 0x80;
- break;
- case 0x02: // read controller pack
- if (Controls[Control].Present)
- {
- switch (Controls[Control].Plugin)
- {
- case PLUGIN_MEMPAK:
- {
- int address = (Command[3] << 8) | Command[4];
- //#ifdef DEBUG_PIF
- //if 0x8001 = 0x00 mem/tppak if 0x80 rumble
- DebugMessage(M64MSG_INFO, "-----------------------------------------------------");
- DebugMessage(M64MSG_INFO, "last addr: %x", last_addr);
- DebugMessage(M64MSG_INFO, "PC: %x", PC->addr);
- //DebugMessage(M64MSG_INFO, "cpu_byte: %x", cpu_byte);
- // DebugMessage(M64MSG_INFO, "cpu_byte: %x", cpu_byte);
- /*
- if(cpu_byte==0x84 && address==0x8001)
- DebugMessage(M64MSG_INFO, "tpak: set power on");
- else if(cpu_byte==0xFE && address==0x8001)
- DebugMessage(M64MSG_INFO, "tpak: set power off");
- if(cpu_byte==0x00 && address==0xB010)
- DebugMessage(M64MSG_INFO, "tpak: set accessmode off");
- else if(cpu_byte==0x01 && address==0xB010)
- DebugMessage(M64MSG_INFO, "tpak: set accessmode on");
- */
- DebugMessage(M64MSG_INFO, "game read mempack address %04x", address);
- //#endif
- if (address == 0x8001)
- {
- if(iEnableState==true){
- // memset(&Command[5], 0x84, 0x20); //32 byte 00 <- mempak 0x84 tpak power on
- DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak power on");
- } else if(iEnableState==false){
- // memset(&Command[5], 0x00, 0x20);
- DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak power off");
- }
- Command[0x25] = mempack_crc(&Command[5]);
- }
- else
- if (address == 0xb010)
- {
- if(iCurrentAccessMode){
- // memset(&Command[5], 0x89, 0x20); //mode1
- DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak mode 1 (89)");
- }else {
- // memset(&Command[5], 0x80, 0x20); //mode1
- DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak mode 0 (80)");
- }
- Command[0x25] = mempack_crc(&Command[5]);
- }
- else
- {
- address &= 0xFFE0;
- if (address <= 0x7FE0)
- {
- mempack_read_file();
- memcpy(&Command[5], &mempack[Control][address], 0x20);
- }
- else
- {
- memset(&Command[5], 0, 0x20);
- }
- Command[0x25] = mempack_crc(&Command[5]);
- }
- DebugMessage(M64MSG_INFO, "Command[5]=%x", Command[5]);
- //read tp
- stageR(5, address);
- CopyMemory(Command+5,Data,32);
- // CopyMemory(Command, Data, 32);
- printf("StageR Data:\n");
- int i=0;
- for (i = 0; i < 32; i ++)
- printf("%X ", Data[i]);
- printf("\n");
- i=0;
- for (i = 0; i < 32; i ++)
- {
- char p = Data[i];
- if(p>31 && p<127)
- printf("%c ", p);
- else
- printf(" ");
- }
- printf("\n");
- Command[0x25] = mempack_crc(&Command[5]);
- }
- break;
- case PLUGIN_RAW:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 2 controllerCommand (in Input plugin)", Control);
- #endif
- if (input.controllerCommand)
- input.controllerCommand(Control, Command);
- break;
- default:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 2 (no pack plugged in)", Control);
- #endif
- memset(&Command[5], 0, 0x20);
- Command[0x25] = 0;
- }
- }
- else
- Command[1] |= 0x80;
- break;
- case 0x03: // write controller pack
- if (Controls[Control].Present)
- {
- switch (Controls[Control].Plugin)
- {
- case PLUGIN_MEMPAK:
- {
- int address = (Command[3] << 8) | Command[4];
- //#ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "-----------------------------------------------------");
- DebugMessage(M64MSG_INFO, "last addr: %x", last_addr);
- DebugMessage(M64MSG_INFO, "PC: %x", PC->addr);
- DebugMessage(M64MSG_INFO, "Command[5]=%x", Command[5]);
- DebugMessage(M64MSG_INFO, "game write mempack address %04x", address);
- //#endif
- if(Command[5]==0x84 && address==0x8001){
- DebugMessage(M64MSG_INFO, "tpak: game set power on");
- // power=1;
- }
- else if(Command[5]==0xFE && address==0x8001){
- DebugMessage(M64MSG_INFO, "tpak: game set power off");
- // power=0;
- }
- if(Command[5]==0x00 && address==0xB010){
- DebugMessage(M64MSG_INFO, "tpak: game set accessmode off");
- // exit(0);
- //access=0;
- }
- else if(Command[5]==0x01 && address==0xB010){
- DebugMessage(M64MSG_INFO, "tpak: game set accessmode on");
- // access=1;
- }
- if(address==0xA00C){
- DebugMessage(M64MSG_INFO, "tpak: game set bank to %i", Command[5]);
- }
- CopyMemory(Data,Command+5,32);
- stageW(5, address);
- printf("StageW Data:\n");
- int i=0;
- for (i = 0; i < 32; i ++){
- printf("%X ", Data[i]);
- }
- printf("\n");
- if (address == 0x8001)
- Command[0x25] = mempack_crc(&Command[5]);
- else
- {
- address &= 0xFFE0;
- if (address <= 0x7FE0)
- {
- mempack_read_file();
- memcpy(&mempack[Control][address], &Command[5], 0x20);
- mempack_write_file();
- }
- Command[0x25] = mempack_crc(&Command[5]);
- }
- }
- break;
- case PLUGIN_RAW:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 3 controllerCommand (in Input plugin)", Control);
- #endif
- if (input.controllerCommand)
- input.controllerCommand(Control, Command);
- break;
- default:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 3 (no pack plugged in)", Control);
- #endif
- Command[0x25] = mempack_crc(&Command[5]);
- }
- }
- else
- Command[1] |= 0x80;
- break;
- }
- }
- void update_pif_write(void)
- {
- char challenge[30], response[30];
- int i=0, channel=0;
- if (PIF_RAMb[0x3F] > 1)
- {
- switch (PIF_RAMb[0x3F])
- {
- case 0x02:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "update_pif_write() pif_ram[0x3f] = 2 - CIC challenge");
- #endif
- // format the 'challenge' message into 30 nibbles for X-Scale's CIC code
- for (i = 0; i < 15; i++)
- {
- challenge[i*2] = (PIF_RAMb[48+i] >> 4) & 0x0f;
- challenge[i*2+1] = PIF_RAMb[48+i] & 0x0f;
- }
- // calculate the proper response for the given challenge (X-Scale's algorithm)
- n64_cic_nus_6105(challenge, response, CHL_LEN - 2);
- PIF_RAMb[46] = 0;
- PIF_RAMb[47] = 0;
- // re-format the 'response' into a byte stream
- for (i = 0; i < 15; i++)
- {
- PIF_RAMb[48+i] = (response[i*2] << 4) + response[i*2+1];
- }
- // the last byte (2 nibbles) is always 0
- PIF_RAMb[63] = 0;
- break;
- case 0x08:
- #ifdef DEBUG_PIF
- DebugMessage(M64MSG_INFO, "update_pif_write() pif_ram[0x3f] = 8");
- #endif
- PIF_RAMb[0x3F] = 0;
- break;
- default:
- DebugMessage(M64MSG_ERROR, "error in update_pif_write(): %x", PIF_RAMb[0x3F]);
- }
- return;
- }
- while (i<0x40)
- {
- switch (PIF_RAMb[i])
- {
- case 0x00:
- channel++;
- if (channel > 6) i=0x40;
- break;
- case 0xFF:
- break;
- default:
- if (!(PIF_RAMb[i] & 0xC0))
- {
- if (channel < 4)
- {
- if (Controls[channel].Present &&
- Controls[channel].RawData)
- input.controllerCommand(channel, &PIF_RAMb[i]);
- else
- internal_ControllerCommand(channel, &PIF_RAMb[i]);
- }
- else if (channel == 4)
- EepromCommand(&PIF_RAMb[i]);
- else
- DebugMessage(M64MSG_ERROR, "channel >= 4 in update_pif_write");
- i += PIF_RAMb[i] + (PIF_RAMb[(i+1)] & 0x3F) + 1;
- channel++;
- }
- else
- i=0x40;
- }
- i++;
- }
- //PIF_RAMb[0x3F] = 0;
- input.controllerCommand(-1, NULL);
- }
- void update_pif_read(void)
- {
- // DebugMessage(M64MSG_INFO, "test");
- int i=0, channel=0;
- while (i<0x40)
- {
- switch (PIF_RAMb[i])
- {
- case 0x00:
- channel++;
- if (channel > 6) i=0x40;
- break;
- case 0xFE:
- i = 0x40;
- break;
- case 0xFF:
- break;
- case 0xB4:
- case 0x56:
- case 0xB8:
- break;
- default:
- if (!(PIF_RAMb[i] & 0xC0))
- {
- if (channel < 4)
- {
- if (Controls[channel].Present &&
- Controls[channel].RawData)
- input.readController(channel, &PIF_RAMb[i]);
- else
- internal_ReadController(channel, &PIF_RAMb[i]);
- }
- i += PIF_RAMb[i] + (PIF_RAMb[(i+1)] & 0x3F) + 1;
- channel++;
- }
- else
- i=0x40;
- }
- i++;
- }
- input.readController(-1, NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment