home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / gbe / rom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-12  |  13.2 KB  |  486 lines

  1. /*
  2.  *  gbe - gameboy emulator
  3.  *  Copyright (C) 1999  Chuck Mason, Steven Fuller
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18.  *
  19.  *
  20.  *  Chuck Mason <chuckjr@sinclair.net>
  21.  *  Steven Fuller <relnev@atdot.org>
  22.  */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h> /* 092299 */
  26.  
  27. #ifdef WIN32
  28. #    define PATH_SEPARATOR '\\'
  29. #else
  30. #    define PATH_SEPARATOR '/'
  31. #endif
  32.  
  33. #include "rom.h"
  34. #include "mem.h"
  35. #include "data.h"
  36.  
  37. unsigned char  color_gameboy     = 0;
  38. unsigned char *cartridge_rom     = (char *)NULL;
  39. unsigned char *cartridge_ram     = (char *)NULL;
  40.          char *cartridge_fname   = (char *)NULL;
  41.  
  42. cartsize       cartridge_size    = SIZE_Unknown;
  43. carttype       cartridge_type    = TYPE_Unknown;
  44. mbc1type       cartridge_mbc1    = MBC1_Unused;
  45. ramsize        cartridge_ramsize = SIZE_Unknown;
  46.          
  47. int load_rom(char *filename)
  48. {
  49.      FILE *fp;
  50.      unsigned long file_length;
  51.      char *ptr;
  52.      
  53.      if((fp = fopen(filename, "r")) == NULL) 
  54.           return 0;
  55.      
  56.      if((ptr = (char *)strrchr(filename, '.')) != NULL) {
  57.           char *ptr2;
  58.           
  59.           
  60.           if((ptr2 = (char *)strrchr(filename, PATH_SEPARATOR)) != NULL) {
  61.                *ptr = '\0';
  62.                ptr2++;
  63.                cartridge_fname = (char *)strdup(ptr2);
  64.           } else {
  65.                *ptr = '\0';
  66.                cartridge_fname = (char *)strdup(filename);
  67.           }
  68.           *ptr = '.';
  69.      } else
  70.           cartridge_fname = (char *)strdup(filename);
  71.  
  72.      fseek(fp, 0, SEEK_END);
  73.      
  74.      file_length = ftell(fp);
  75.      rewind(fp);
  76.      
  77.      cartridge_rom = (char *)malloc(file_length);
  78.  
  79.      fread((char *)cartridge_rom, file_length, 1, fp);
  80.      fclose(fp);
  81.      
  82.      printf("Cartridge Name: [");
  83.      fwrite((char *)&cartridge_rom[0x134], 0x0F, 1, stdout);
  84.      printf("]\n");
  85.      
  86.      if(cartridge_rom[0x143] == 0x80)
  87.           color_gameboy = 1;
  88.  
  89.      if(force_system == REGULAR)
  90.           color_gameboy = 0;
  91.      else if(force_system == COLOR)
  92.           color_gameboy = 1;
  93.           
  94.      if(color_gameboy) {
  95.           printf("Color gameboy support is very preliminary.\n");
  96.      }
  97.      
  98.      printf("Cart Type: ");
  99.      switch(cartridge_rom[0x147]) {
  100.           case 0x00:
  101.                printf("ROM Only\n");
  102.                cartridge_type = TYPE_ROM_Only;
  103.                break;
  104.           case 0x01:     /* MBC1 used */
  105.                printf("ROM+MBC1\n");
  106.                cartridge_type = TYPE_ROM_MBC1;
  107.                cartridge_mbc1 = MBC1_16M_8K; /* Defaults .. */
  108.                break;
  109.           case 0x02:
  110.                printf("ROM+MBC1+RAM\n");
  111.                cartridge_type = TYPE_ROM_MBC1_RAM;
  112.                cartridge_mbc1 = MBC1_16M_8K;
  113.                break;
  114.           case 0x03:
  115.                printf("ROM+MBC1+RAM+BATTERY\n");
  116.                cartridge_type = TYPE_ROM_MBC1_RAM_BATTERY;
  117.                cartridge_mbc1 = MBC1_16M_8K;
  118.                break;
  119.           case 0x05:
  120.                printf("ROM+MBC2\n");
  121.                cartridge_type    = TYPE_ROM_MBC2;
  122.                cartridge_ramsize = RAM_SIZE_2KB;  /* really 256 bytes */
  123.                break;
  124.           case 0x06:
  125.                printf("ROM+MBC2+BATTERY\n");
  126.                cartridge_type    = TYPE_ROM_MBC2_BATTERY;
  127.                cartridge_ramsize = RAM_SIZE_2KB;
  128.                break;
  129.           case 0x11:
  130.                printf("ROM+MBC3\n");
  131.                cartridge_type = TYPE_ROM_MBC3;
  132.                break;
  133.           case 0x12:
  134.                printf("ROM+MBC3+RAM\n");
  135.                cartridge_type = TYPE_ROM_MBC3_RAM;
  136.                break;
  137.           case 0x13:
  138.                printf("ROM+MBC3+RAM+BATTERY\n");
  139.                cartridge_type = TYPE_ROM_MBC3_RAM_BATTERY;
  140.                break;
  141.           case 0x19:
  142.                printf("ROM+MBC5\n");
  143.                cartridge_type = TYPE_ROM_MBC5;
  144.                break;
  145.           case 0x1A:
  146.                printf("ROM+MBC5+RAM\n");
  147.                cartridge_type = TYPE_ROM_MBC5_RAM;
  148.                break;
  149.           case 0x1B:
  150.                printf("ROM+MBC5+RAM+BATTERY\n");
  151.                cartridge_type = TYPE_ROM_MBC5_RAM_BATTERY;
  152.                break;
  153.           default:
  154.                printf("Unknown!\n");
  155.                cartridge_type = TYPE_Unknown;
  156.                break;
  157.      }
  158.      
  159.      if(cartridge_type == TYPE_Unknown) {
  160.           printf("Error! Unknown cartridge type %d!\n", cartridge_rom[0x147]);
  161.           return 0;
  162.      }
  163.      
  164.      printf("Cart Size: ");
  165.      switch(cartridge_rom[0x148]) {
  166.           case 0x00:
  167.                printf("32K\n");
  168.                cartridge_size = SIZE_32k;
  169.                break;
  170.           case 0x01:
  171.                printf("64K\n");
  172.                cartridge_size = SIZE_64k;    /* This one's got 4 */
  173.                break;
  174.           case 0x02:
  175.                printf("128K\n");
  176.                cartridge_size = SIZE_128k;   /* This rom has 8 16 banks */
  177.                break;
  178.           case 0x03:
  179.                printf("256K\n");
  180.                cartridge_size = SIZE_256k;   /* This one's got 16 */
  181.                break;
  182.           case 0x04:
  183.                printf("512K\n");
  184.                cartridge_size = SIZE_512k;
  185.                break;
  186.           case 0x05:
  187.                printf("1MB\n");
  188.                cartridge_size = SIZE_1M;
  189.                break;
  190.           case 0x06:
  191.                printf("2MB\n");
  192.                cartridge_size = SIZE_2M;
  193.                break;
  194.           default:
  195.                cartridge_size = SIZE_Unknown;
  196.                printf("Unknown\n");
  197.      }
  198.      
  199.      if(cartridge_size == SIZE_Unknown) {
  200.           printf("Error! Unknown cartridge size!\n");
  201.           return 0;
  202.      }
  203.  
  204.      if(cartridge_rom[0x149] != 0x00) {
  205.           printf("Ram Size: ");
  206.           switch(cartridge_rom[0x149]) {
  207.                case RAM_SIZE_2KB:
  208.                     printf("2 KB\n");
  209.                     cartridge_ramsize = RAM_SIZE_2KB;
  210.                     break;
  211.                case RAM_SIZE_8KB:
  212.                     printf("8 KB\n");
  213.                     cartridge_ramsize = RAM_SIZE_8KB;
  214.                     break;
  215.                case RAM_SIZE_32KB:
  216.                     printf("32 KB\n");
  217.                     cartridge_ramsize = RAM_SIZE_32KB;
  218.                     break;
  219.                default:
  220.                     printf("Unknown (%d)\n", cartridge_rom[0x149]);
  221.                     cartridge_ramsize = SIZE_Unknown;
  222.                     break;
  223.           }
  224.           if(cartridge_ramsize == SIZE_Unknown) {
  225.                printf("Error! Unknown ram size!\n");
  226.                return 0;
  227.           }
  228.      }
  229.      
  230.      install_rom();
  231.      install_ram();
  232.           
  233.      return 1;
  234. }
  235.  
  236. void free_rom()
  237. {
  238.      if(cartridge_rom)
  239.           free(cartridge_rom);
  240.           
  241.      rom_save_ram();
  242.      if(cartridge_ram)
  243.           free(cartridge_ram);
  244.           
  245.      if(cartridge_fname)
  246.           free(cartridge_fname);
  247.                     
  248.      cartridge_type = TYPE_Unknown;
  249.      cartridge_size = cartridge_ramsize = SIZE_Unknown;
  250.      color_gameboy  = 0;
  251.      cartridge_rom  = (char *)NULL;
  252.      cartridge_ram  = (char *)NULL;
  253.      cartridge_fname= (char *)NULL;
  254.      
  255. }
  256.  
  257. void install_rom()
  258. {
  259.      int i;
  260.      
  261.      switch(cartridge_size) {
  262.           case SIZE_32k:
  263.                for(i = 0; i < 8; i++)
  264.                     install_memory(i, cartridge_rom + (i * 0x1000));
  265.                break;
  266.           case SIZE_64k:
  267.           case SIZE_128k:
  268.           case SIZE_256k:          
  269.           case SIZE_512k:          /* All these get bank 0 to $0-$3fff and 1 to $4000-$7fff */
  270.           case SIZE_1M:
  271.           case SIZE_2M:
  272.                rom_select_bank(0, 0);
  273.                rom_select_bank(1, 4);
  274.                break;
  275.           default:
  276.                return;
  277.      }
  278. }
  279.  
  280. void install_ram()
  281. {
  282.      if(cartridge_ramsize == SIZE_Unknown)
  283.           return;
  284.      
  285.      switch(cartridge_ramsize) {
  286.           case RAM_SIZE_8KB:
  287.                cartridge_ram = (char *)malloc(0x2000);
  288.                break;
  289.           case RAM_SIZE_2KB:
  290.                cartridge_ram = (char *)malloc(0x800);
  291.                break;
  292.           case RAM_SIZE_32KB:
  293.                cartridge_ram = (char *)malloc(0x2000 * 4);
  294.                break;
  295.           case RAM_SIZE_128KB:
  296.                cartridge_ram = (char *)malloc(0x2000 * 16);
  297.                break;
  298.           default:
  299.                return;
  300.      }
  301.      rom_load_ram();
  302.      rom_select_ram_bank(0);
  303. }
  304.  
  305. void rom_select_bank(int bank, int wbank)
  306. {
  307.      unsigned long b;
  308.      int i;
  309.      unsigned char *rptr;
  310.  
  311.      switch(cartridge_size) {
  312.           case SIZE_32k:
  313.                return;
  314.           case SIZE_64k:      /* banks 0 - 3 */
  315.                if(bank >= 4)
  316.                     return;
  317.                break;
  318.           case SIZE_128k:          /* banks 0 - 7 */
  319.                if(bank >= 8)
  320.                     return;
  321.                break;
  322.           case SIZE_256k:          /* banks 0 - 15 */
  323.                if(bank >= 16)
  324.                     return;
  325.                break;
  326.           case SIZE_512k:          /* banks 0 - 31 */
  327.                if(bank >= 32)
  328.                     return;
  329.                break;
  330.           case SIZE_1M:
  331.                if(bank >= 64)
  332.                     return;
  333.                break;
  334.           case SIZE_2M:
  335.                if(bank >= 128)
  336.                     return;
  337.                break;
  338.           default:
  339.                return;
  340.      }
  341.  
  342.      b = (bank) * 0x4000;
  343.      rptr = &cartridge_rom[b];
  344.      
  345.      for(i = 0; i < 4; i++) {
  346.           install_memory(i + wbank, rptr + (i * 0x1000));
  347.      }
  348. }
  349.  
  350. void rom_select_ram_bank(int bank)
  351. {
  352.      unsigned long b;
  353.      int i;
  354.  
  355.      if(cartridge_ramsize == SIZE_Unknown)
  356.           return;
  357.                     
  358.      b = bank * 0x2000;
  359.  
  360.      if(cartridge_ramsize == RAM_SIZE_2KB) {
  361.           install_memory(0x0A, cartridge_ram);
  362.           install_memory(0x0B, (char *)NULL);
  363.           return;
  364.      }
  365.  
  366.      for(i = 0; i < 2; i++) {
  367.           install_memory(0x0A + (i & 0x0F), cartridge_ram + (i * 0x1000) + b);
  368.      }
  369. }
  370.  
  371. void rom_create_sav_path(char *path)
  372. {
  373.      const char *GBEDIR = ".gbesav";
  374.      char *var;
  375.      
  376.      
  377.      if(!(var = getenv("HOME"))) {
  378.           if(!(var = getenv("USER"))) {
  379.                sprintf(path, ".%c", PATH_SEPARATOR);
  380.                return;
  381.           } else {
  382.                sprintf(path, "/home/%s/%s/", var, GBEDIR);
  383.           }
  384.      } else {
  385.           sprintf(path, "%s/%s/", var, GBEDIR);
  386.      }
  387.      return;
  388. }
  389.  
  390. void rom_save_ram()
  391. {
  392.      char filename[512];
  393.      FILE *fptr;
  394.  
  395.      /* Note all all these have 2 things in common:
  396.           RAM and BATTERY ..
  397.      */   
  398.      switch(cartridge_type) {
  399.           case TYPE_ROM_MBC1_RAM_BATTERY:
  400.           case TYPE_ROM_MBC2_BATTERY:        /* MBC2 has ram in it */
  401.           case TYPE_ROM_MBC3_RAM_BATTERY:
  402.           case TYPE_ROM_MBC5_RAM_BATTERY:
  403.                break;
  404.           default:
  405.                return;
  406.      }
  407.      
  408.      rom_create_sav_path(filename);
  409.      
  410.      strcat(filename, cartridge_fname);
  411.      strcat(filename, ".sav");
  412.      
  413.      if((fptr = fopen(filename, "w")) == NULL) {
  414.           printf("unable to open %s for saving\n", filename);
  415.           return;
  416.      }
  417.      
  418.      switch(cartridge_ramsize) {
  419.           case RAM_SIZE_2KB:
  420.                fwrite(cartridge_ram, 0x400, 2, fptr);
  421.                break;
  422.           case RAM_SIZE_8KB:
  423.                fwrite(cartridge_ram, 0x400, 8, fptr);
  424.                break;
  425.           case RAM_SIZE_32KB:
  426.                fwrite(cartridge_ram, 0x400, 32, fptr);
  427.                break;
  428.           case RAM_SIZE_128KB:
  429.                fwrite(cartridge_ram, 0x400, 128, fptr);
  430.                break;
  431.      }
  432.  
  433.      printf("saveram successfully saved to %s\n", filename);
  434.           
  435.      fflush(fptr);
  436.      fclose(fptr);
  437.      return;
  438. }
  439.  
  440. void rom_load_ram()
  441. {
  442.      char filename[512];
  443.      FILE *fptr;
  444.      
  445.      switch(cartridge_type) {
  446.           case TYPE_ROM_MBC1_RAM_BATTERY:
  447.           case TYPE_ROM_MBC2_BATTERY:
  448.           case TYPE_ROM_MBC3_RAM_BATTERY:
  449.           case TYPE_ROM_MBC5_RAM_BATTERY:
  450.                break;
  451.           default:
  452.                return;
  453.      }
  454.      
  455.      rom_create_sav_path(filename);
  456.      
  457.      strcat(filename, cartridge_fname);
  458.      strcat(filename, ".sav");
  459.      
  460.      if((fptr = fopen(filename, "r")) == NULL) {
  461.           printf("unable to open %s for saving\n", filename);
  462.           return;
  463.      }
  464.      
  465.      switch(cartridge_ramsize) {
  466.           case RAM_SIZE_2KB:
  467.                fread(cartridge_ram, 0x400, 2, fptr);
  468.                break;
  469.           case RAM_SIZE_8KB:
  470.                fread(cartridge_ram, 0x400, 8, fptr);
  471.                break;
  472.           case RAM_SIZE_32KB:
  473.                fread(cartridge_ram, 0x400, 32, fptr);
  474.                break;
  475.           case RAM_SIZE_128KB:
  476.                fread(cartridge_ram, 0x400, 128, fptr);
  477.                break;
  478.      }
  479.  
  480.      printf("saveram successfully read from %s\n", filename);
  481.           
  482.      fflush(fptr);
  483.      fclose(fptr);
  484.      return;
  485. }
  486.