Advertisement
Chiddix

ROM v0.01

Apr 6th, 2014
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.70 KB | None | 0 0
  1. package com.nintendo.gameboy;
  2.  
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.nio.charset.Charset;
  8.  
  9. /**
  10.  * Represents a single Gameboy or Gameboy Color ROM.
  11.  *
  12.  * @author Ryan Greene
  13.  *
  14.  */
  15. public final class ROM {
  16.  
  17.     /**
  18.      * These bytes define the bitmap of the Nintendo logo that is displayed when
  19.      * the Gameboy gets turned on.
  20.      *
  21.      * The Gameboy's boot procedure verifies the content of this bitmap (after
  22.      * it has displayed it), and LOCKS ITSELF UP if these bytes are incorrect. A
  23.      * CGB verifies only the first 18h bytes of the bitmap, but others (for
  24.      * example a Pocket Gameboy) verify all 30h bytes. We currently only verify
  25.      * the first and last bytes of the bitmap because I'm lazy.
  26.      */
  27.     private static final int[] NINTENDO_LOGO = new int[] { 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89,
  28.             0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99, 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E };
  29.  
  30.     /**
  31.      * The file where the ROM is located.
  32.      */
  33.     private final File file;
  34.  
  35.     /**
  36.      * The input stream used to read the ROM.
  37.      */
  38.     private final InputStream input;
  39.  
  40.     /**
  41.      * The bytes which make up the ROM.
  42.      */
  43.     private final byte[] data;
  44.  
  45.     /**
  46.      * Whether or not the ROM paseed the Nintendo logo checksum.
  47.      */
  48.     private final boolean nintendoLogoChecksum;
  49.  
  50.     /**
  51.      * Title of the game in UPPER CASE ASCII. If it is less than 16 characters
  52.      * then the remaining bytes are filled with 00's. When inventing the CGB,
  53.      * Nintendo has reduced the length of this area to 15 characters, and some
  54.      * months later they had the fantastic idea to reduce it to 11 characters
  55.      * only.
  56.      */
  57.     private final String title;
  58.  
  59.     /**
  60.      * In older cartridges this area has been part of the Title, in newer
  61.      * cartridges this area contains an 4 character uppercase manufacturer code.
  62.      * Purpose and Deeper Meaning unknown.
  63.      */
  64.     private final String manufacturerCode;
  65.  
  66.     /**
  67.      * In older cartridges this byte has been part of the Title. In CGB
  68.      * cartridges the upper bit is used to enable CGB functions. This is
  69.      * required, otherwise the CGB switches itself into Non-CGB-Mode.
  70.      */
  71.     private final boolean cgb;
  72.  
  73.     /**
  74.      * Specifies a two character ASCII licensee code, indicating the company or
  75.      * publisher of the game. These two bytes are used in newer games only
  76.      * (games that have been released after the SGB has been invented). Older
  77.      * games are using the header entry at 014B instead.
  78.      */
  79.     private final String newLicenseeCode;
  80.  
  81.     /**
  82.      * Specifies whether the game supports SGB functions.
  83.      */
  84.     private final boolean sgb;
  85.  
  86.     /**
  87.      * Specifies which Memory Bank Controller (if any) is used in the cartridge,
  88.      * and if further external hardware exists in the cartridge.
  89.      */
  90.     private final byte cartridgeType; // TODO: handle
  91.  
  92.     /**
  93.      * Specifies the ROM Size of the cartridge.
  94.      */
  95.     private final int romSize;
  96.  
  97.     /**
  98.      * Specifies the size of the external RAM in the cartridge (if any). When
  99.      * using a MBC2 chip 00h must be specified in this entry, even though the
  100.      * MBC2 includes a built-in RAM of 512 x 4 bits.
  101.      */
  102.     private final int ramSize;
  103.  
  104.     /**
  105.      * Specifies if this version of the game is supposed to be sold in Japan, or
  106.      * anywhere else.
  107.      */
  108.     private final boolean destinationCode;
  109.  
  110.     /**
  111.      * Specifies the games company/publisher code in range 00-FFh. A value of
  112.      * 33h signalizes that the New License Code in header bytes 0144-0145 is
  113.      * used instead.
  114.      */
  115.     private final int oldLicenseeCode;
  116.  
  117.     /**
  118.      * Specifies the version number of the game. That is usually 00h.
  119.      */
  120.     private final int maskRomVersionNumber;
  121.  
  122.     /**
  123.      * Constructs a new ROM from the specified directory.
  124.      *
  125.      * @param directory
  126.      *            The directory the ROM is located.
  127.      * @throws IOException
  128.      *             If an exception occurs while constructing the ROM.
  129.      */
  130.     public ROM(final String directory) throws IOException {
  131.         file = new File(directory);
  132.         input = new FileInputStream(file);
  133.         data = new byte[(int) file.length()];
  134.         input.read(data);
  135.  
  136.         nintendoLogoChecksum = (data[0x104] & 0xFF) == NINTENDO_LOGO[0] && (data[0x133] & 0xFF) == NINTENDO_LOGO[47];
  137.  
  138.         title = new String(data, 0x134, 11, Charset.forName("US-ASCII"));
  139.         manufacturerCode = new String(data, 0x13F, 4);
  140.         cgb = data[0x143] == 0xC0 ? true : false;
  141.         newLicenseeCode = new String(data, 0x144, 2, Charset.forName("US-ASCII"));
  142.         sgb = data[0x164] == 0x3 ? true : false;
  143.         cartridgeType = data[0x147];
  144.  
  145.         final byte romType = data[0x148];
  146.         if (romType == 0x52) {
  147.             romSize = 0x120000;
  148.         } else if (romType == 0x53) {
  149.             romSize = 0x140000;
  150.         } else if (romType == 0x54) {
  151.             romSize = 0x180000;
  152.         } else {
  153.             romSize = 32 * 1024 << romType;
  154.         }
  155.  
  156.         final byte ramType = data[0x149];
  157.         if (ramType == 0x1) {
  158.             ramSize = 0x800;
  159.         } else if (ramType == 0x2) {
  160.             ramSize = 0x2000;
  161.         } else if (ramType == 0x3) {
  162.             ramSize = 0x8000;
  163.         } else {
  164.             ramSize = -1;
  165.         }
  166.  
  167.         destinationCode = data[0x14A] == 0x0 ? true : false;
  168.         oldLicenseeCode = data[0x14B];
  169.         maskRomVersionNumber = data[0x14C];
  170.     }
  171.  
  172.     @Override
  173.     public String toString() {
  174.         return "[nintendoLogoChecksum=" + nintendoLogoChecksum + ", title=" + title + ", manufacturerCode=" + manufacturerCode + ", cgb=" + cgb + ", newLicenseeCode=" + newLicenseeCode
  175.                 + ", sgb=" + sgb + ", cartridgeType=" + cartridgeType + ", romSize=" + romSize + ", ramSize=" + ramSize + ", destinationCode=" + destinationCode + ", oldLicenseeCode="
  176.                 + oldLicenseeCode + ", maskRomVersionNumber=" + maskRomVersionNumber + "]";
  177.     }
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement