Guest User

mupen64plus_patch

a guest
Jun 23rd, 2014
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 33.47 KB | None | 0 0
  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2.  *   Mupen64plus - pif.c                                                   *
  3.  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
  4.  *   Copyright (C) 2002 Hacktarux                                          *
  5.  *                                                                         *
  6.  *   This program is free software; you can redistribute it and/or modify  *
  7.  *   it under the terms of the GNU General Public License as published by  *
  8.  *   the Free Software Foundation; either version 2 of the License, or     *
  9.  *   (at your option) any later version.                                   *
  10.  *                                                                         *
  11.  *   This program is distributed in the hope that it will be useful,       *
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  14.  *   GNU General Public License for more details.                          *
  15.  *                                                                         *
  16.  *   You should have received a copy of the GNU General Public License     *
  17.  *   along with this program; if not, write to the                         *
  18.  *   Free Software Foundation, Inc.,                                       *
  19.  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
  20.  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <time.h>
  26. #include <stdint.h>
  27.  
  28. #include "memory.h"
  29. #include "pif.h"
  30. #include "n64_cic_nus_6105.h"
  31.  
  32. #include "r4300/r4300.h"
  33. #include "r4300/interupt.h"
  34.  
  35. //hack
  36. #include "r4300/recomp.h"
  37.  
  38. #include "api/m64p_types.h"
  39. #include "api/callbacks.h"
  40. #include "api/debugger.h"
  41. #include "main/main.h"
  42. #include "main/rom.h"
  43. #include "main/util.h"
  44. #include "plugin/plugin.h"
  45.  
  46.  
  47. int file_init=0;
  48.  
  49. int iCurrentBankNo=0, iCurrentRamBankNo=0;
  50. int bRamEnableState=0;
  51. int iCurrentRomBankNo=0;
  52. int iNumRamBanks=4, iNumRomBanks=999;
  53. int bMBC1RAMbanking=0;
  54. int iEnableState=1;
  55. int iCurrentAccessMode=0;
  56. int bHasTimer=0;
  57. int iAccessModeChanged=0;
  58. int bHasRam=1;
  59. uint8_t Data[32];
  60.  
  61. #define true 1
  62. #define false 0
  63.  
  64. uint8_t *RomData;
  65. uint8_t *RamData;
  66.  
  67.  
  68.  
  69. int ReadCartMBC5(uint16_t dwAddress, uint8_t *Data);
  70.  
  71. void ZeroMemory(uint8_t *Data, int s){
  72.  
  73. memset(Data, 0, s);
  74. }
  75.  
  76. void CopyMemory(uint8_t *dst, uint8_t *src, int s){
  77.  
  78. memset(dst, 0, s);
  79. memcpy(dst, src, s);
  80. }
  81.  
  82.  
  83. int read_Rom(void){
  84.  
  85.  
  86.     FILE *fp_rom;
  87.     //fp_rom=fopen("/home/tt/ed64/tp_emulator/golf_e.gbc", "rb");
  88.     fp_rom=fopen("/home/tt/ed64/tp_emulator/yellow.gb", "rb");
  89.     long fileSize;
  90.     long lCurPos, lEndPos;
  91.     lCurPos = ftell(fp_rom);
  92.  
  93.    
  94.     fseek(fp_rom, 0, 2);
  95.     lEndPos = ftell(fp_rom);
  96.     fseek(fp_rom, lCurPos, 0);
  97.     fileSize = lEndPos;
  98.  
  99.     RomData = (uint8_t *)malloc(fileSize);
  100.  
  101.     // fread(buffer (from offset 0), Amount to read, Amount of times to read it, Pointer to file);
  102.     fread(&RomData[0], fileSize, 1, fp_rom);  
  103.  
  104.     // Output the bytes in the file as hex
  105.  
  106.     //for (int i = 0; i < fileSize; i ++)
  107.     /*
  108.     int i=0;
  109.     for (i = 0; i < 32; i ++)    
  110.     printf("%X ", rom_buffer[i]);
  111. */
  112.  fclose(fp_rom);
  113.  
  114. return 0;
  115. }
  116.  
  117. int read_Ram(void){
  118.  
  119.  
  120.     FILE *fp_ram;
  121.     //fp_ram=fopen("/home/tt/ed64/tp_emulator/golf.srm", "rb");
  122.     fp_ram=fopen("/home/tt/ed64/tp_emulator/yellow.srm", "rb");
  123.     long fileSize;
  124.     long lCurPos, lEndPos;
  125.     lCurPos = ftell(fp_ram);
  126.  
  127.    
  128.     fseek(fp_ram, 0, 2);
  129.     lEndPos = ftell(fp_ram);
  130.     fseek(fp_ram, lCurPos, 0);
  131.     fileSize = lEndPos;
  132.  
  133.     RamData = (uint8_t *)malloc(fileSize);
  134.  
  135.     // fread(buffer (from offset 0), Amount to read, Amount of times to read it, Pointer to file);
  136.     fread(&RamData[0], fileSize, 1, fp_ram);  
  137.  
  138.     // Output the bytes in the file as hex
  139.  
  140.     //for (int i = 0; i < fileSize; i ++)
  141.  
  142.  fclose(fp_ram);
  143.  
  144. return 0;
  145. }
  146.  
  147.  
  148. int WriteCartMBC5(uint16_t dwAddress, uint8_t *Data)
  149. {
  150.     switch (dwAddress >> 13)
  151.     {
  152.     case 0: //  if ((dwAddress <= 0x1FFF)) // We shouldn't be able to read/write to RAM unless this is toggled on
  153.         bRamEnableState = (Data[0] == 0x0A);
  154.         printf("Set RAM enable: %d\n", bRamEnableState);
  155.         break;
  156.     case 1: //  else if ((dwAddress >= 0x2000) && (dwAddress <= 0x2FFF)) // ROM bank select, low bits
  157.         iCurrentRomBankNo &= 0xFF00;
  158.         iCurrentRomBankNo |= Data[0];
  159.         // iCurrentRomBankNo = ((int) Data[0]) | (iCurrentRomBankNo & 0x100);
  160.         printf("Set ROM Bank: %02X\n", iCurrentRomBankNo);
  161.         break;
  162.     case 2: //  else if ((dwAddress >= 0x3000) && (dwAddress <= 0x3FFF)) // ROM bank select, high bit
  163.         iCurrentRomBankNo &= 0x00FF;
  164.         iCurrentRomBankNo |= (Data[0] & 0x01) << 8;
  165.         // iCurrentRomBankNo = (iCurrentRomBankNo & 0xFF) | ((((int) Data[0]) & 1) * 0x100);
  166.         printf("Set ROM Bank: %02X\n", iCurrentRomBankNo);
  167.         break;
  168.     case 3: //  if ((dwAddress >= 0x4000) && (dwAddress <= 0x5FFF)) // RAM bank select
  169.         if (bHasRam) {
  170.             iCurrentRamBankNo = Data[0] & 0x0F;
  171.             printf("Set RAM Bank: %02X\n", iCurrentRamBankNo);
  172.         }
  173.         break;
  174.     case 5: //  else if ((dwAddress >= 0xA000) && (dwAddress <= 0xBFFF)) // Write to RAM
  175.         if (bHasRam) {
  176.             if (iCurrentRamBankNo >= iNumRamBanks) {
  177.                 printf("RAM write: Buffer error on ");
  178.                 printf("%02X", iCurrentRamBankNo);
  179.                 printf("\n");
  180.             } else {
  181.                 printf("RAM write: Bank %02X\n", iCurrentRamBankNo);
  182.                 CopyMemory(&RamData[dwAddress - 0xA000 + (iCurrentRamBankNo << 13)], Data, 32);
  183.             }
  184.         }
  185.         break;
  186.     default:
  187.         printf("Bad write to MBC5 cart, address %04X\n", dwAddress);
  188.     }
  189.  
  190.     return true;
  191. }
  192.  
  193.  
  194. void stageW(int mapper, int dwAddress){
  195.  
  196. if(file_init==0){
  197. printf("\n");
  198.  
  199. printf("Rom:\n");
  200. read_Rom();
  201.  
  202.     int i=0;
  203.     for (i = 0; i < 32; i ++)    
  204.     printf("%X ", RomData[i]);
  205.  
  206.  
  207. printf("\nRam:\n");
  208. read_Ram();
  209. printf("\n");
  210.  
  211. file_init=1;
  212. }
  213.    
  214.        
  215.             printf( "TPak Write:\n" );
  216.             printf( "  Address: %04X\n", dwAddress );
  217.  
  218.  
  219.             switch (dwAddress >> 12)
  220.             {
  221.             case 0x8: //    if ((dwAddress >= 0x8000) && (dwAddress <= 0x8FFF))
  222.                 if (Data[0] == 0xFE) {
  223.                     printf("Cart Disable\n" );
  224.                     iEnableState = false;
  225.                    
  226.                 }
  227.                 else if (Data[0] == 0x84) {
  228.                     printf("Cart Enable\n" );
  229.                     iEnableState = true;
  230.                    
  231.                 }
  232.                 else {
  233.                     printf("WARNING: Unusual Cart Enable/Disable\n" );
  234.                     printf("  Address: " );
  235.                     printf("%04X", dwAddress);
  236.                     printf("\n" );
  237.                     printf("  Data: " );
  238.                     printf("%02X", Data[0]);
  239.                     printf("\n" );
  240.                 }
  241.                 break;
  242.             case 0xA: //    if ((dwAddress >= 0xA000) && (dwAddress <= 0xAFFF))
  243.                 if (iEnableState == true) {
  244.                     iCurrentBankNo = Data[0];
  245.                     printf("Set TPak Bank No:%02X\n", Data[0] );
  246.                 }
  247.                 break;
  248.             case 0xB: //    if ((dwAddress >= 0xB000) && (dwAddress <= 0xBFFF))
  249.                 if (iEnableState == true) {
  250.                    
  251.                    
  252.                     iCurrentAccessMode = Data[0] & 1;
  253.                    
  254.                     /*
  255.                     if(iCurrentAccessMode)
  256.                     access=1;
  257.                     else access=0;
  258.                     */
  259.                     iAccessModeChanged = 4;
  260.                     printf("Set TPak Access Mode: %04X\n", iCurrentAccessMode);
  261.                     if ((Data[0] != 1) && (Data[0] != 0)) {
  262.                         printf("WARNING: Unusual Access Mode Change\n" );
  263.                         printf("  Address: " );
  264.                         printf("%04X",dwAddress);
  265.                         printf("\n" );
  266.                         printf("  Data: " );
  267.                         printf("%02X",Data[0]);
  268.                         printf("\n" );
  269.                     }
  270.                 }
  271.                 break;
  272.             case 0xC:
  273.             case 0xD:
  274.             case 0xE:
  275.             case 0xF: //    if (dwAddress >= 0xC000)
  276.                 //WriteCartMBC1(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data);
  277.  
  278.                     printf( "### Cart Write: Bank:%i\n", iCurrentBankNo );
  279.                     printf( "###    Address:%04X\n", ((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000) );
  280.  
  281.  
  282.                     switch(mapper){
  283.                 //  case 1: WriteCartMBC1(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  284.                 //  case 2: WriteCartMBC2(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  285.                 //  case 3: WriteCartMBC3(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  286.                     case 5: WriteCartMBC5(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  287.                     default: break;
  288.                     }
  289.            
  290.                 break;
  291.             default:
  292.                 printf("WARNING: Unusual Pak Write\n" );
  293.                 printf("  Address: %04X\n", dwAddress);
  294.             } // end switch (dwAddress >> 12)
  295.  
  296.             Data[32] = 0x00; //DataCRC( Data, 32 );
  297.         //  Data[32] = DataCRC( Data, 32 );
  298.                
  299.             //bReturn = 0;
  300.         }
  301.  
  302.  
  303.  
  304. void stageR(int mapper, int dwAddress){
  305.  
  306.  
  307. if(file_init==0){
  308. printf("\n");
  309.  
  310. printf("Rom:\n");
  311. read_Rom();
  312.  
  313.     int i=0;
  314.     for (i = 0; i < 32; i ++)    
  315.     printf("%X ", RomData[i]);
  316.  
  317.  
  318. printf("\nRam:\n");
  319. read_Ram();
  320. printf("\n");
  321.  
  322. file_init=1;
  323. }
  324.  
  325.  
  326.    
  327.             printf( "TPak Read:\n" );
  328.             printf( "  Address: %04X\n", dwAddress );
  329.  
  330.             switch (dwAddress >> 12)
  331.             {
  332.             case 0x8: //    if ((dwAddress >= 0x8000) && (dwAddress <= 0x8FFF))
  333.                 printf( "Query Enable State: " );
  334.  
  335.                         if(iEnableState==true){
  336.                           memset(&Data, 0x84, 0x20); //32 byte 00 <- mempak 0x84 tpak power on
  337.                           printf( "1\n" );
  338.                         }else if(iEnableState==false){
  339.                        
  340.                           memset(&Data, 0x00, 0x20);
  341.                            printf( "0\n" );
  342.                         }
  343.                         break;
  344.             case 0xB: //    if ((dwAddress >= 0xB000) && (dwAddress <= 0xBFFF))
  345.  
  346.                     printf( "Query Cart. State:" );
  347.                     printf( " Inserted, Access Mode " );
  348.                    
  349.                         if(iCurrentAccessMode){
  350.                           memset(&Data, 0x89, 0x20);
  351.                           printf( "1\n" );
  352.                         }else {
  353.                        
  354.                           memset(&Data, 0x80, 0x20);
  355.                            printf( "0\n" );
  356.                         }
  357.                    
  358.                         Data[0] = Data[0] | (uint8_t)iAccessModeChanged;
  359.                         iAccessModeChanged = 0;
  360.                 break;
  361.             case 0xC:
  362.             case 0xD:
  363.             case 0xE:
  364.             case 0xF: //    if ((dwAddress >= 0xC000))
  365.  
  366.                     printf( "Cart Read: Bank:%i\n", iCurrentBankNo );
  367.                     printf( "    Address:%04X\n", ((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000) );
  368.  
  369.                     switch(mapper){
  370.             //      case 1: ReadCartMBC1(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  371.             //      case 2: ReadCartMBC2(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  372.             //      case 3: ReadCartMBC3(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  373.                     case 5: ReadCartMBC5(((dwAddress & 0xFFE0) - 0xC000) + ((iCurrentBankNo & 3) * 0x4000), Data); break;
  374.                     default: break;
  375.                     }
  376.                
  377.                 break;
  378.             default:
  379.                 printf("WARNING: Unusual Pak Read\n" );
  380.                 printf("  Address: %04X\n", dwAddress);
  381.             } // end switch (dwAddress >> 12)
  382.  
  383.  
  384.  
  385. }
  386.  
  387.  
  388.  
  389. int ReadCartMBC5(uint16_t dwAddress, uint8_t *Data)
  390. {
  391.     switch (dwAddress >> 13)
  392.     {
  393.     case 0:
  394.     case 1: //  if ((dwAddress <= 0x3FFF))
  395.         CopyMemory(Data, &RomData[dwAddress], 32);
  396.         printf("Nonbanked ROM read - MBC5\n");
  397.         break;
  398.     case 2:
  399.     case 3: //  else if ((dwAddress >= 0x4000) && (dwAddress <= 0x7FFF))
  400.        
  401.         iCurrentRomBankNo=iCurrentBankNo;  //stupid test
  402.    
  403.         if (iCurrentRomBankNo >= iNumRomBanks) {
  404.             ZeroMemory(Data, 32);
  405.             printf("Banked ROM read: (Banking Error)");
  406.             printf("%02X",iCurrentRomBankNo);
  407.             printf(" (int=%d)\n",iCurrentRomBankNo);
  408.         } else {
  409.             CopyMemory(Data, &RomData[dwAddress - 0x4000 + (iCurrentRomBankNo << 14)], 32);
  410.             printf("Banked ROM read: Bank=");
  411.             printf("%02X",iCurrentRomBankNo);
  412.             printf(" (int=%d)\n",iCurrentRomBankNo);
  413.         }
  414.         break;
  415.     case 5: //  else if ((dwAddress >= 0xA000) && (dwAddress <= 0xBFFF))
  416.     //  iCurrentRamBankNo=iCurrentBankNo;  //stupid test
  417.        
  418.         if (bHasRam) {
  419.             if (iCurrentRamBankNo >= iNumRamBanks) {
  420.                 ZeroMemory(Data, 32);
  421.                 printf("Failed RAM read: (Banking Error) %02X\n", iCurrentRamBankNo);
  422.             } else {
  423.                 CopyMemory(Data, &RamData[dwAddress - 0xA000 + (iCurrentRamBankNo << 13)], 32);
  424.                 printf("RAM read: Bank %02X\n", iCurrentRamBankNo);
  425.             }
  426.         } else {
  427.             ZeroMemory(Data, 32);
  428.             printf("Failed RAM read: (RAM Not Present)\n");
  429.         }
  430.         break;
  431.     default:
  432.         printf("Bad read from MBC5 cart, address %04X\n", dwAddress);
  433.     }
  434.  
  435.     return true;
  436. }
  437.  
  438.  
  439. //hack
  440. extern precomp_instr *PC;
  441.  
  442. int power=0;
  443. int access=0;
  444. int tmp=0;
  445.  
  446. static unsigned char eeprom[0x800];
  447. static unsigned char mempack[4][0x8000];
  448.  
  449. static char *get_eeprom_path(void)
  450. {
  451.     return formatstr("%s%s.eep", get_savesrampath(), ROM_SETTINGS.goodname);
  452. }
  453.  
  454. static void eeprom_format(void)
  455. {
  456.     memset(eeprom, 0xff, sizeof(eeprom));
  457. }
  458.  
  459. static void eeprom_read_file(void)
  460. {
  461.     char *filename = get_eeprom_path();
  462.  
  463.     switch (read_from_file(filename, eeprom, sizeof(eeprom)))
  464.     {
  465.         case file_open_error:
  466.             DebugMessage(M64MSG_VERBOSE, "couldn't open eeprom file '%s' for reading", filename);
  467.             eeprom_format();
  468.             break;
  469.         case file_read_error:
  470.             DebugMessage(M64MSG_WARNING, "fread() failed for 2kb eeprom file '%s'", filename);
  471.             break;
  472.         default: break;
  473.     }
  474.  
  475.     free(filename);
  476. }
  477.  
  478. static void eeprom_write_file(void)
  479. {
  480.     char *filename = get_eeprom_path();
  481.  
  482.     switch (write_to_file(filename, eeprom, sizeof(eeprom)))
  483.     {
  484.         case file_open_error:
  485.             DebugMessage(M64MSG_WARNING, "couldn't open eeprom file '%s' for writing", filename);
  486.             break;
  487.         case file_write_error:
  488.             DebugMessage(M64MSG_WARNING, "fwrite() failed for 2kb eeprom file '%s'", filename);
  489.             break;
  490.         default: break;
  491.     }
  492.  
  493.     free(filename);
  494. }
  495.  
  496. static char *get_mempack_path(void)
  497. {
  498.     return formatstr("%s%s.mpk", get_savesrampath(), ROM_SETTINGS.goodname);
  499. }
  500.  
  501. static void mempack_format(void)
  502. {
  503.     unsigned char init[] =
  504.     {
  505.         0x81,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
  506.         0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
  507.         0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  508.         0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
  509.         0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  510.         0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  511.         0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  512.         0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
  513.         0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  514.         0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
  515.         0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  516.         0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  517.         0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  518.         0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
  519.         0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  520.         0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  521.         0x00,0x71,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03, 0x00,0x03,0x00,0x03
  522.     };
  523.     int i,j;
  524.     for (i=0; i<4; i++)
  525.     {
  526.         for (j=0; j<0x8000; j+=2)
  527.         {
  528.             mempack[i][j] = 0;
  529.             mempack[i][j+1] = 0x03;
  530.         }
  531.         memcpy(mempack[i], init, 272);
  532.     }
  533. }
  534.  
  535. static void mempack_read_file(void)
  536. {
  537.     char *filename = get_mempack_path();
  538.  
  539.     switch (read_from_file(filename, mempack, sizeof(mempack)))
  540.     {
  541.         case file_open_error:
  542.             DebugMessage(M64MSG_VERBOSE, "couldn't open memory pack file '%s' for reading", filename);
  543.             mempack_format();
  544.             break;
  545.         case file_read_error:
  546.             DebugMessage(M64MSG_WARNING, "fread() failed for 128kb mempack file '%s'", filename);
  547.             break;
  548.         default: break;
  549.     }
  550.  
  551.     free(filename);
  552. }
  553.  
  554. static void mempack_write_file(void)
  555. {
  556.     char *filename = get_mempack_path();
  557.  
  558.     switch (write_to_file(filename, mempack, sizeof(mempack)))
  559.     {
  560.         case file_open_error:
  561.             DebugMessage(M64MSG_WARNING, "couldn't open memory pack file '%s' for writing", filename);
  562.             break;
  563.         case file_write_error:
  564.             DebugMessage(M64MSG_WARNING, "fwrite() failed for 128kb mempack file '%s'", filename);
  565.             break;
  566.         default: break;
  567.     }
  568.  
  569.     free(filename);
  570. }
  571.  
  572. //#define DEBUG_PIF
  573. #ifdef DEBUG_PIF
  574. void print_pif(void)
  575. {
  576.     int i;
  577.     for (i=0; i<(64/8); i++)
  578.         DebugMessage(M64MSG_INFO, "%x %x %x %x | %x %x %x %x",
  579.                      PIF_RAMb[i*8+0], PIF_RAMb[i*8+1],PIF_RAMb[i*8+2], PIF_RAMb[i*8+3],
  580.                      PIF_RAMb[i*8+4], PIF_RAMb[i*8+5],PIF_RAMb[i*8+6], PIF_RAMb[i*8+7]);
  581. }
  582. #endif
  583.  
  584. static unsigned char byte2bcd(int n)
  585. {
  586.     n %= 100;
  587.     return ((n / 10) << 4) | (n % 10);
  588. }
  589.  
  590. static void EepromCommand(unsigned char *Command)
  591. {
  592.     time_t curtime_time;
  593.     struct tm *curtime;
  594.  
  595.     switch (Command[2])
  596.     {
  597.     case 0: // check
  598. #ifdef DEBUG_PIF
  599.         DebugMessage(M64MSG_INFO, "EepromCommand() check size");
  600. #endif
  601.         if (Command[1] != 3)
  602.         {
  603.             Command[1] |= 0x40;
  604.             if ((Command[1] & 3) > 0)
  605.                 Command[3] = 0;
  606.             if ((Command[1] & 3) > 1)
  607.                 Command[4] = (ROM_SETTINGS.savetype != EEPROM_16KB) ? 0x80 : 0xc0;
  608.             if ((Command[1] & 3) > 2)
  609.                 Command[5] = 0;
  610.         }
  611.         else
  612.         {
  613.             Command[3] = 0;
  614.             Command[4] = (ROM_SETTINGS.savetype != EEPROM_16KB) ? 0x80 : 0xc0;
  615.             Command[5] = 0;
  616.         }
  617.         break;
  618.     case 4: // read
  619.     {
  620. #ifdef DEBUG_PIF
  621.         DebugMessage(M64MSG_INFO, "EepromCommand() read 8-byte block %i", Command[3]);
  622. #endif
  623.         eeprom_read_file();
  624.         memcpy(&Command[4], eeprom + Command[3]*8, 8);
  625.     }
  626.     break;
  627.     case 5: // write
  628.     {
  629. #ifdef DEBUG_PIF
  630.         DebugMessage(M64MSG_INFO, "EepromCommand() write 8-byte block %i", Command[3]);
  631. #endif
  632.         eeprom_read_file();
  633.         memcpy(eeprom + Command[3]*8, &Command[4], 8);
  634.         eeprom_write_file();
  635.     }
  636.     break;
  637.     case 6:
  638. #ifdef DEBUG_PIF
  639.         DebugMessage(M64MSG_INFO, "EepromCommand() RTC status query");
  640. #endif
  641.         // RTCstatus query
  642.         Command[3] = 0x00;
  643.         Command[4] = 0x10;
  644.         Command[5] = 0x00;
  645.         break;
  646.     case 7:
  647. #ifdef DEBUG_PIF
  648.         DebugMessage(M64MSG_INFO, "EepromCommand() read RTC block %i", Command[3]);
  649. #endif
  650.         // read RTC block
  651.         switch (Command[3]) {   // block number
  652.         case 0:
  653.             Command[4] = 0x00;
  654.             Command[5] = 0x02;
  655.             Command[12] = 0x00;
  656.             break;
  657.         case 1:
  658.             DebugMessage(M64MSG_ERROR, "RTC command in EepromCommand(): read block %d", Command[2]);
  659.             break;
  660.         case 2:
  661.             time(&curtime_time);
  662.             curtime = localtime(&curtime_time);
  663.             Command[4] = byte2bcd(curtime->tm_sec);
  664.             Command[5] = byte2bcd(curtime->tm_min);
  665.             Command[6] = 0x80 + byte2bcd(curtime->tm_hour);
  666.             Command[7] = byte2bcd(curtime->tm_mday);
  667.             Command[8] = byte2bcd(curtime->tm_wday);
  668.             Command[9] = byte2bcd(curtime->tm_mon + 1);
  669.             Command[10] = byte2bcd(curtime->tm_year);
  670.             Command[11] = byte2bcd(curtime->tm_year / 100);
  671.             Command[12] = 0x00; // status
  672.             break;
  673.         }
  674.         break;
  675.     case 8:
  676.         // write RTC block
  677.         DebugMessage(M64MSG_ERROR, "RTC write in EepromCommand(): %d not yet implemented", Command[2]);
  678.         break;
  679.     default:
  680.         DebugMessage(M64MSG_ERROR, "unknown command in EepromCommand(): %x", Command[2]);
  681.     }
  682. }
  683.  
  684. static unsigned char mempack_crc(unsigned char *data)
  685. {
  686.     int i;
  687.     unsigned char CRC = 0;
  688.     for (i=0; i<=0x20; i++)
  689.     {
  690.         int mask;
  691.         for (mask = 0x80; mask >= 1; mask >>= 1)
  692.         {
  693.             int xor_tap = (CRC & 0x80) ? 0x85 : 0x00;
  694.             CRC <<= 1;
  695.             if (i != 0x20 && (data[i] & mask)) CRC |= 1;
  696.             CRC ^= xor_tap;
  697.         }
  698.     }
  699.     return CRC;
  700. }
  701.  
  702. static void internal_ReadController(int Control, unsigned char *Command)
  703. {
  704.     switch (Command[2])
  705.     {
  706.     case 1:
  707. #ifdef DEBUG_PIF
  708.         DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 1 read buttons", Control);
  709. #endif
  710.         if (Controls[Control].Present)
  711.         {
  712.             BUTTONS Keys;
  713.             input.getKeys(Control, &Keys);
  714.             *((unsigned int *)(Command + 3)) = Keys.Value;
  715. #ifdef COMPARE_CORE
  716.             CoreCompareDataSync(4, Command+3);
  717. #endif
  718.         }
  719.         break;
  720.     case 2: // read controller pack
  721. #ifdef DEBUG_PIF
  722.         DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 2 read controller pack (in Input plugin)", Control);
  723. #endif
  724.         if (Controls[Control].Present)
  725.         {
  726.             if (Controls[Control].Plugin == PLUGIN_RAW)
  727.                 if (input.readController)
  728.                     input.readController(Control, Command);
  729.         }
  730.         break;
  731.     case 3: // write controller pack
  732. #ifdef DEBUG_PIF
  733.         DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 3 write controller pack (in Input plugin)", Control);
  734. #endif
  735.         if (Controls[Control].Present)
  736.         {
  737.             if (Controls[Control].Plugin == PLUGIN_RAW)
  738.                 if (input.readController)
  739.                     input.readController(Control, Command);
  740.         }
  741.         break;
  742.     }
  743. }
  744.  
  745. static void internal_ControllerCommand(int Control, unsigned char *Command)
  746. {
  747.     switch (Command[2])
  748.     {
  749.     case 0x00: // read status
  750.     case 0xFF: // reset
  751.         if ((Command[1] & 0x80))
  752.             break;
  753. //#ifdef DEBUG_PIF
  754.  //       DebugMessage(M64MSG_STATUS, "internal_ControllerCommand() Channel %i Command %02x check pack present", Control, Command[2]);
  755. //#endif
  756.         if (Controls[Control].Present)
  757.         {
  758.             Command[3] = 0x05;
  759.             Command[4] = 0x00;
  760.             switch (Controls[Control].Plugin)
  761.             {
  762.             case PLUGIN_MEMPAK:
  763.                 Command[5] = 1;
  764.                  DebugMessage(M64MSG_INFO, "0xFF reset");
  765.                 break;
  766.             case PLUGIN_RAW:
  767.                 Command[5] = 1;
  768.                 break;
  769.             default:
  770.                 Command[5] = 0;
  771.                 break;
  772.             }
  773.         }
  774.         else
  775.             Command[1] |= 0x80;
  776.         break;
  777.     case 0x01:
  778. #ifdef DEBUG_PIF
  779.         DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 1 check controller present", Control);
  780. #endif
  781.         if (!Controls[Control].Present)
  782.             Command[1] |= 0x80;
  783.         break;
  784.     case 0x02: // read controller pack
  785.         if (Controls[Control].Present)
  786.         {
  787.             switch (Controls[Control].Plugin)
  788.             {
  789.             case PLUGIN_MEMPAK:
  790.             {
  791.                 int address = (Command[3] << 8) | Command[4];
  792. //#ifdef DEBUG_PIF
  793.  
  794.                 //if 0x8001 = 0x00 mem/tppak if 0x80 rumble
  795.                   DebugMessage(M64MSG_INFO, "-----------------------------------------------------");  
  796.                  DebugMessage(M64MSG_INFO, "last addr: %x", last_addr);
  797.                  DebugMessage(M64MSG_INFO, "PC: %x", PC->addr);
  798.                    //DebugMessage(M64MSG_INFO, "cpu_byte: %x", cpu_byte);
  799.                  //   DebugMessage(M64MSG_INFO, "cpu_byte: %x", cpu_byte);
  800. /*                 
  801.                    if(cpu_byte==0x84 && address==0x8001)
  802.                    DebugMessage(M64MSG_INFO, "tpak: set power on");
  803.                    else  if(cpu_byte==0xFE && address==0x8001)
  804.                    DebugMessage(M64MSG_INFO, "tpak: set power off");
  805.  
  806.                    if(cpu_byte==0x00 && address==0xB010)
  807.                    DebugMessage(M64MSG_INFO, "tpak: set accessmode off");
  808.                    else  if(cpu_byte==0x01 && address==0xB010)
  809.                    DebugMessage(M64MSG_INFO, "tpak: set accessmode on");                   
  810.     */             
  811.                    
  812.                 DebugMessage(M64MSG_INFO, "game read mempack address %04x", address);
  813. //#endif
  814.                 if (address == 0x8001)
  815.                 {
  816.                     if(iEnableState==true){
  817.                            
  818.                //     memset(&Command[5], 0x84, 0x20); //32 byte 00 <- mempak 0x84 tpak power on
  819.  
  820.                    
  821.                      DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak power on");
  822.                    } else if(iEnableState==false){
  823.                  //    memset(&Command[5], 0x00, 0x20);
  824.                       DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak power off");
  825.                      }
  826.                     Command[0x25] = mempack_crc(&Command[5]);
  827.                    
  828.                      
  829.                 }
  830.                 else
  831.                 if (address == 0xb010)
  832.                 {
  833.                     if(iCurrentAccessMode){
  834.                
  835.                  //   memset(&Command[5], 0x89, 0x20); //mode1
  836.                      DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak mode 1 (89)");
  837.                      }else {
  838.                    //   memset(&Command[5], 0x80, 0x20); //mode1
  839.                        DebugMessage(M64MSG_INFO, "tpak: emulator fake tpak mode 0 (80)");
  840.                      }
  841.                     Command[0x25] = mempack_crc(&Command[5]);
  842.                    
  843.                      
  844.                 }
  845.                 else
  846.                 {
  847.                     address &= 0xFFE0;
  848.                     if (address <= 0x7FE0)
  849.                     {
  850.                         mempack_read_file();
  851.                         memcpy(&Command[5], &mempack[Control][address], 0x20);
  852.                     }
  853.                     else
  854.                     {
  855.                         memset(&Command[5], 0, 0x20);
  856.                     }
  857.                     Command[0x25] = mempack_crc(&Command[5]);
  858.                 }
  859.                  DebugMessage(M64MSG_INFO, "Command[5]=%x", Command[5]);
  860.                  
  861.                  //read tp
  862.                  stageR(5, address);  
  863.                  
  864.                  CopyMemory(Command+5,Data,32);
  865.                  
  866.               //   CopyMemory(Command, Data, 32);
  867.                  printf("StageR Data:\n");
  868.                 int i=0;
  869.                 for (i = 0; i < 32; i ++)    
  870.                 printf("%X ", Data[i]);
  871.                     printf("\n");
  872.                    
  873.                 i=0;
  874.                 for (i = 0; i < 32; i ++)    
  875.                 {
  876.                     char p = Data[i];
  877.                     if(p>31 && p<127)
  878.                         printf("%c ", p);
  879.                     else
  880.                         printf("  ");
  881.                 }
  882.                
  883.    
  884.                     printf("\n");
  885.                                        
  886.                    
  887.                 Command[0x25] = mempack_crc(&Command[5]);
  888.                    
  889.             }
  890.             break;
  891.             case PLUGIN_RAW:
  892. #ifdef DEBUG_PIF
  893.                 DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 2 controllerCommand (in Input plugin)", Control);
  894. #endif
  895.                 if (input.controllerCommand)
  896.                     input.controllerCommand(Control, Command);
  897.                 break;
  898.             default:
  899. #ifdef DEBUG_PIF
  900.                 DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 2 (no pack plugged in)", Control);
  901. #endif
  902.                 memset(&Command[5], 0, 0x20);
  903.                 Command[0x25] = 0;
  904.             }
  905.         }
  906.         else
  907.             Command[1] |= 0x80;
  908.         break;
  909.     case 0x03: // write controller pack
  910.         if (Controls[Control].Present)
  911.         {
  912.             switch (Controls[Control].Plugin)
  913.             {
  914.             case PLUGIN_MEMPAK:
  915.             {
  916.                 int address = (Command[3] << 8) | Command[4];
  917. //#ifdef DEBUG_PIF
  918.   DebugMessage(M64MSG_INFO, "-----------------------------------------------------");  
  919.  DebugMessage(M64MSG_INFO, "last addr: %x", last_addr);
  920.  DebugMessage(M64MSG_INFO, "PC: %x", PC->addr);
  921.   DebugMessage(M64MSG_INFO, "Command[5]=%x", Command[5]);
  922.                 DebugMessage(M64MSG_INFO, "game write mempack address %04x", address);
  923. //#endif
  924.                    if(Command[5]==0x84 && address==0x8001){
  925.                    DebugMessage(M64MSG_INFO, "tpak: game set power on");
  926.                 //  power=1;
  927.                     }
  928.                    else  if(Command[5]==0xFE && address==0x8001){
  929.                    DebugMessage(M64MSG_INFO, "tpak: game set power off");
  930.                 //  power=0;
  931.                     }
  932.  
  933.                    if(Command[5]==0x00 && address==0xB010){
  934.                    DebugMessage(M64MSG_INFO, "tpak: game set accessmode off");
  935.            
  936.                 //   exit(0);
  937.                     //access=0;
  938.                     }
  939.                    else  if(Command[5]==0x01 && address==0xB010){
  940.                    DebugMessage(M64MSG_INFO, "tpak: game set accessmode on");  
  941.                 //  access=1;
  942.                     }
  943.  
  944.                    if(address==0xA00C){
  945.                    DebugMessage(M64MSG_INFO, "tpak: game set bank to %i", Command[5]);
  946.                    
  947.                     }
  948.                    
  949.                     CopyMemory(Data,Command+5,32);
  950.                    
  951.                     stageW(5, address);  
  952.                  printf("StageW Data:\n");
  953.                 int i=0;
  954.                 for (i = 0; i < 32; i ++){    
  955.                
  956.                     printf("%X ", Data[i]);
  957.  
  958.                 }
  959.                     printf("\n");
  960.  
  961.  
  962.  
  963.  
  964.                 if (address == 0x8001)
  965.                     Command[0x25] = mempack_crc(&Command[5]);
  966.                 else
  967.                 {
  968.                     address &= 0xFFE0;
  969.                     if (address <= 0x7FE0)
  970.                     {
  971.                         mempack_read_file();
  972.                         memcpy(&mempack[Control][address], &Command[5], 0x20);
  973.                         mempack_write_file();
  974.                     }
  975.                     Command[0x25] = mempack_crc(&Command[5]);
  976.                 }
  977.             }
  978.             break;
  979.             case PLUGIN_RAW:
  980. #ifdef DEBUG_PIF
  981.                 DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 3 controllerCommand (in Input plugin)", Control);
  982. #endif
  983.                 if (input.controllerCommand)
  984.                     input.controllerCommand(Control, Command);
  985.                 break;
  986.             default:
  987. #ifdef DEBUG_PIF
  988.                 DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command 3 (no pack plugged in)", Control);
  989. #endif
  990.                 Command[0x25] = mempack_crc(&Command[5]);
  991.             }
  992.         }
  993.         else
  994.             Command[1] |= 0x80;
  995.         break;
  996.     }
  997. }
  998.  
  999. void update_pif_write(void)
  1000. {
  1001.     char challenge[30], response[30];
  1002.     int i=0, channel=0;
  1003.     if (PIF_RAMb[0x3F] > 1)
  1004.     {
  1005.         switch (PIF_RAMb[0x3F])
  1006.         {
  1007.         case 0x02:
  1008. #ifdef DEBUG_PIF
  1009.             DebugMessage(M64MSG_INFO, "update_pif_write() pif_ram[0x3f] = 2 - CIC challenge");
  1010. #endif
  1011.             // format the 'challenge' message into 30 nibbles for X-Scale's CIC code
  1012.             for (i = 0; i < 15; i++)
  1013.             {
  1014.                 challenge[i*2] =   (PIF_RAMb[48+i] >> 4) & 0x0f;
  1015.                 challenge[i*2+1] =  PIF_RAMb[48+i]       & 0x0f;
  1016.             }
  1017.             // calculate the proper response for the given challenge (X-Scale's algorithm)
  1018.             n64_cic_nus_6105(challenge, response, CHL_LEN - 2);
  1019.             PIF_RAMb[46] = 0;
  1020.             PIF_RAMb[47] = 0;
  1021.             // re-format the 'response' into a byte stream
  1022.             for (i = 0; i < 15; i++)
  1023.             {
  1024.                 PIF_RAMb[48+i] = (response[i*2] << 4) + response[i*2+1];
  1025.             }
  1026.             // the last byte (2 nibbles) is always 0
  1027.             PIF_RAMb[63] = 0;
  1028.             break;
  1029.         case 0x08:
  1030. #ifdef DEBUG_PIF
  1031.             DebugMessage(M64MSG_INFO, "update_pif_write() pif_ram[0x3f] = 8");
  1032. #endif
  1033.             PIF_RAMb[0x3F] = 0;
  1034.             break;
  1035.         default:
  1036.             DebugMessage(M64MSG_ERROR, "error in update_pif_write(): %x", PIF_RAMb[0x3F]);
  1037.         }
  1038.         return;
  1039.     }
  1040.     while (i<0x40)
  1041.     {
  1042.         switch (PIF_RAMb[i])
  1043.         {
  1044.         case 0x00:
  1045.             channel++;
  1046.             if (channel > 6) i=0x40;
  1047.             break;
  1048.         case 0xFF:
  1049.             break;
  1050.         default:
  1051.             if (!(PIF_RAMb[i] & 0xC0))
  1052.             {
  1053.                 if (channel < 4)
  1054.                 {
  1055.                     if (Controls[channel].Present &&
  1056.                             Controls[channel].RawData)
  1057.                         input.controllerCommand(channel, &PIF_RAMb[i]);
  1058.                     else
  1059.                         internal_ControllerCommand(channel, &PIF_RAMb[i]);
  1060.                 }
  1061.                 else if (channel == 4)
  1062.                     EepromCommand(&PIF_RAMb[i]);
  1063.                 else
  1064.                     DebugMessage(M64MSG_ERROR, "channel >= 4 in update_pif_write");
  1065.                 i += PIF_RAMb[i] + (PIF_RAMb[(i+1)] & 0x3F) + 1;
  1066.                 channel++;
  1067.             }
  1068.             else
  1069.                 i=0x40;
  1070.         }
  1071.         i++;
  1072.     }
  1073.     //PIF_RAMb[0x3F] = 0;
  1074.     input.controllerCommand(-1, NULL);
  1075. }
  1076.  
  1077. void update_pif_read(void)
  1078. {
  1079.     // DebugMessage(M64MSG_INFO, "test");
  1080.  
  1081.     int i=0, channel=0;
  1082.     while (i<0x40)
  1083.     {
  1084.         switch (PIF_RAMb[i])
  1085.         {
  1086.         case 0x00:
  1087.             channel++;
  1088.             if (channel > 6) i=0x40;
  1089.             break;
  1090.         case 0xFE:
  1091.             i = 0x40;
  1092.             break;
  1093.         case 0xFF:
  1094.             break;
  1095.         case 0xB4:
  1096.         case 0x56:
  1097.         case 0xB8:
  1098.             break;
  1099.         default:
  1100.             if (!(PIF_RAMb[i] & 0xC0))
  1101.             {
  1102.                 if (channel < 4)
  1103.                 {
  1104.                     if (Controls[channel].Present &&
  1105.                             Controls[channel].RawData)
  1106.                         input.readController(channel, &PIF_RAMb[i]);
  1107.                     else
  1108.                         internal_ReadController(channel, &PIF_RAMb[i]);
  1109.                 }
  1110.                 i += PIF_RAMb[i] + (PIF_RAMb[(i+1)] & 0x3F) + 1;
  1111.                 channel++;
  1112.             }
  1113.             else
  1114.                 i=0x40;
  1115.         }
  1116.         i++;
  1117.     }
  1118.     input.readController(-1, NULL);
  1119. }
Advertisement
Add Comment
Please, Sign In to add comment