content: /*
   * HalfNES by Andrew Hoffman
   * Licensed under the GNU GPL Version 3. See LICENSE file
   */
  package com.grapeshot.halfnes.mappers;
  
  import com.grapeshot.halfnes.utils;
  
  /**
   *
   * @author Andrew
   */
  public class Action52Mapper extends Mapper {
  
      int[] ram = new int[4];
      int prgchip = 0;
      int prgpage = 0;
      int chrpage = 0;
      boolean prgmode = false;
  
      @Override
      public void loadrom() throws BadMapperException {
          super.loadrom();
          cartWrite(0x8000, 0);
      }
  
      @Override
      public final void cartWrite(final int addr, final int data) {
          if (addr <= 0x5fff) {
              ram[addr & 3] = data & 0xf;
          } else if (addr >= 0x8000) {
              chrpage = ((addr & 0xf) << 2) + (data & 3);
              prgmode = ((addr & (utils.BIT5)) != 0);
              prgpage = (addr >> 6) & 0x1f;
              prgchip = (addr >> 11) & 3;
              setmirroring((((addr & (utils.BIT13)) != 0)) ? MirrorType.H_MIRROR : MirrorType.V_MIRROR);
              for (int i = 0; i < 8; ++i) {
                  chr_map[i] = (1024 * (chrpage * 8 + i)) % chrsize;
              }
              int off = 0;
              switch (prgchip) {
                  case 0:
                      off = 0;
                      break;
                  case 1:
                      off = 0x080000;
                      break;
                  case 3:
                      off = 0x100000;
                      break;
                  default:
                      System.err.println("Who knows.");
              }
              if (prgmode) {
                  for (int i = 0; i < 16; ++i) {
                      prg_map[i] = ((1024 * ((16 * prgpage) + i)) + off) % prgsize;
                      prg_map[i + 16] = ((1024 * ((16 * prgpage) + i)) + off) % prgsize;
                  }
              } else {
                  for (int i = 0; i < 32; ++i) {
                      prg_map[i] = ((1024 * ((32 * (prgpage >> 1)) + i)) + off) % prgsize;
                  }
              }
          }
      }
  
      @Override
      public final int cartRead(final int addr) {
          // by default has wram at 0x6000 and cartridge at 0x8000-0xfff
          // but some mappers have different so override for those
          if (addr >= 0x8000) {
              return prg[prg_map[((addr & 0x7fff)) >> 10] + (addr & 1023)];
          } else if (addr < 0x6000) {
              return ram[addr & 3] & 0xf;
          }
          return addr >> 8; //open bus
      }
  
      public void reset() {
          cartWrite(0x8000, 0);
      }
  }
  