Advertisement
Chiddix

MemoryManagementUnit v0.01

Apr 7th, 2014
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.43 KB | None | 0 0
  1. package com.nintendo.gameboy;
  2.  
  3. public final class MemoryManagementUnit {
  4.  
  5.     private static final int[] BIOS = new int[] { 0x31, 0xFE, 0xFF, 0xAF, 0x21, 0xFF, 0x9F, 0x32, 0xCB, 0x7C, 0x20, 0xFB, 0x21, 0x26, 0xFF, 0x0E, 0x11, 0x3E, 0x80, 0x32, 0xE2, 0x0C, 0x3E, 0xF3,
  6.         0xE2, 0x32, 0x3E, 0x77, 0x77, 0x3E, 0xFC, 0xE0, 0x47, 0x11, 0x04, 0x01, 0x21, 0x10, 0x80, 0x1A, 0xCD, 0x95, 0x00, 0xCD, 0x96, 0x00, 0x13, 0x7B, 0xFE, 0x34, 0x20, 0xF3, 0x11, 0xD8,
  7.         0x00, 0x06, 0x08, 0x1A, 0x13, 0x22, 0x23, 0x05, 0x20, 0xF9, 0x3E, 0x19, 0xEA, 0x10, 0x99, 0x21, 0x2F, 0x99, 0x0E, 0x0C, 0x3D, 0x28, 0x08, 0x32, 0x0D, 0x20, 0xF9, 0x2E, 0x0F, 0x18,
  8.         0xF3, 0x67, 0x3E, 0x64, 0x57, 0xE0, 0x42, 0x3E, 0x91, 0xE0, 0x40, 0x04, 0x1E, 0x02, 0x0E, 0x0C, 0xF0, 0x44, 0xFE, 0x90, 0x20, 0xFA, 0x0D, 0x20, 0xF7, 0x1D, 0x20, 0xF2, 0x0E, 0x13,
  9.         0x24, 0x7C, 0x1E, 0x83, 0xFE, 0x62, 0x28, 0x06, 0x1E, 0xC1, 0xFE, 0x64, 0x20, 0x06, 0x7B, 0xE2, 0x0C, 0x3E, 0x87, 0xF2, 0xF0, 0x42, 0x90, 0xE0, 0x42, 0x15, 0x20, 0xD2, 0x05, 0x20,
  10.         0x4F, 0x16, 0x20, 0x18, 0xCB, 0x4F, 0x06, 0x04, 0xC5, 0xCB, 0x11, 0x17, 0xC1, 0xCB, 0x11, 0x17, 0x05, 0x20, 0xF5, 0x22, 0x23, 0x22, 0x23, 0xC9, 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D,
  11.         0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99, 0xBB, 0xBB, 0x67, 0x63,
  12.         0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E, 0x3c, 0x42, 0xB9, 0xA5, 0xB9, 0xA5, 0x42, 0x4C, 0x21, 0x04, 0x01, 0x11, 0xA8, 0x00, 0x1A, 0x13, 0xBE, 0x20,
  13.         0xFE, 0x23, 0x7D, 0xFE, 0x34, 0x20, 0xF5, 0x06, 0x19, 0x78, 0x86, 0x23, 0x05, 0x20, 0xFB, 0x86, 0x20, 0xFE, 0x3E, 0x01, 0xE0, 0x50 };
  14.  
  15.     private byte[] rom;
  16.  
  17.     private final byte[] externalRam;
  18.  
  19.     private final byte[] workRam;
  20.  
  21.     private final byte[] zeropageRam;
  22.  
  23.     private boolean inBios;
  24.  
  25.     public MemoryManagementUnit(final ReadOnlyMemory rom) {
  26.         workRam = new byte[8192];
  27.         externalRam = new byte[8192];
  28.         zeropageRam = new byte[128];
  29.         reset();
  30.     }
  31.  
  32.     public void loadReadOnlyMemory(final ReadOnlyMemory rom) {
  33.         this.rom = rom.getMemory();
  34.         reset();
  35.     }
  36.  
  37.     public int readByte(final int address) {
  38.         switch (address & 0xF000) {
  39.         case 0x0000: // ROM bank 0
  40.             if (inBios) {
  41.                 if (address < 0x0100) {
  42.                     return BIOS[address];
  43.                 } else if (null == null) { // TODO: Z80._r.pc == 0x0100
  44.                     inBios = false;
  45.                 }
  46.             } else {
  47.                 return rom[address];
  48.             }
  49.         case 0x1000:
  50.         case 0x2000:
  51.         case 0x3000:
  52.             return rom[address];
  53.         case 0x4000: // ROM bank 1
  54.         case 0x5000:
  55.         case 0x6000:
  56.         case 0x7000:
  57.             return rom[address];
  58.         case 0x8000: // VRAM
  59.         case 0x9000:
  60.             return 0; // TODO: GPU._vram[addr&0x1FFF];
  61.         case 0xA000: // External RAM
  62.         case 0xB000:
  63.             return externalRam[address & 0x1FFF];
  64.         case 0xC000: // Work RAM and echo
  65.         case 0xD000:
  66.         case 0xE000:
  67.             return workRam[address & 0x1FFF];
  68.         case 0xF000: // Everything else
  69.             switch (address & 0x0F00) {
  70.             case 0x000: // Echo RAM
  71.             case 0x100:
  72.             case 0x200:
  73.             case 0x300:
  74.             case 0x400:
  75.             case 0x500:
  76.             case 0x600:
  77.             case 0x700:
  78.             case 0x800:
  79.             case 0x900:
  80.             case 0xA00:
  81.             case 0xB00:
  82.             case 0xC00:
  83.             case 0xD00:
  84.                 return workRam[address & 0x1FFF];
  85.             case 0xE000: // OAM
  86.                 return (address & 0xFF) < 0xA0 ? 0 : 0; // TODO: ((address & 0xFF) < 0xA0) ? GPU._oam[address & 0xFF] : 0;
  87.             case 0xF00: // Zeropage RAM, I/O
  88.                 if (address > 0xFF7F) {
  89.                     return zeropageRam[address & 0x7F];
  90.                 } else {
  91.                     switch (address & 0xF0) {
  92.                     // TODO: ?
  93.                     }
  94.                 }
  95.             }
  96.         }
  97.         throw new OutOfMemoryError("Invalid address given while reading byte");
  98.     }
  99.  
  100.     public int readWord(final int address) {
  101.         return readByte(address) + (readByte(address + 1) << 8);
  102.     }
  103.  
  104.     public void writeByte(final int address, final int value) { // TODO: integer to byte?
  105.         switch (address & 0xF000) {
  106.         case 0x0000: // ROM bank 0
  107.             if (inBios && address < 0x0100) {
  108.                 return;
  109.             } // fall through
  110.         case 0x1000:
  111.         case 0x2000:
  112.         case 0x3000:
  113.             break;
  114.         case 0x4000: // ROM bank 1
  115.         case 0x5000:
  116.         case 0x6000:
  117.         case 0x7000:
  118.             break;
  119.         case 0x8000: // VRAM
  120.         case 0x9000:
  121.             // TODO: GPU._vram[address & 0x1FFF] = value;
  122.             // TODO: GPU.updatetile(address & 0x1FFF, value);
  123.             break;
  124.         case 0xA000: // External RAM
  125.         case 0xB000:
  126.             externalRam[address & 0x1FFF] = (byte) value;
  127.             break;
  128.         case 0xC000: // Work RAM and echo
  129.         case 0xD000:
  130.         case 0xE000:
  131.             workRam[address & 0x1FFF] = (byte) value;
  132.             break;
  133.         case 0xF000:
  134.             switch (address & 0x0F00) {
  135.             case 0x000: // Echo RAM
  136.             case 0x100:
  137.             case 0x200:
  138.             case 0x300:
  139.             case 0x400:
  140.             case 0x500:
  141.             case 0x600:
  142.             case 0x700:
  143.             case 0x800:
  144.             case 0x900:
  145.             case 0xA00:
  146.             case 0xB00:
  147.             case 0xC00:
  148.             case 0xD00:
  149.                 workRam[address & 0x1FFF] = (byte) value;
  150.                 break;
  151.             case 0xE00: // OAM
  152.                 if ((address & 0xFF) < 0xA0) {
  153.                     // TODO: GPU._oam[address & 0xFF] = value;
  154.                 }
  155.             case 0XF00: // Zeropage RAM, I/O
  156.                 if (address > 0xFF7F) {
  157.                     zeropageRam[address & 0x7F] = (byte) value;
  158.                 } else {
  159.                     switch (address & 0xF0) {
  160.                     // TODO: ?
  161.                     }
  162.                 }
  163.             }
  164.         }
  165.     }
  166.  
  167.     public void writeWord(final int address, final int value) { // TODO: integer to byte?
  168.         writeByte(address, value & 255);
  169.         writeByte(address + 1, value >> 8);
  170.     }
  171.  
  172.     public void reset() {
  173.         for (int i = 0; i < 8192; i++) {
  174.             workRam[i] = 0;
  175.             externalRam[i] = 0;
  176.         }
  177.         for (int i = 0; i < 128; i++) {
  178.             zeropageRam[i] = 0;
  179.         }
  180.         inBios = true;
  181.     }
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement