shithub: zelda3

Download patch

ref: 85bfc5b6ea03f364b8b4f80bd1dc1340ba2fd111
parent: f0792741c2841e42c6288ea6f2826e0df50c734d
author: Snesrev <snesrev@protonmail.com>
date: Fri Sep 2 20:09:35 EDT 2022

Remove unused code

And try to speed up PPU implementation

--- a/ending.c
+++ b/ending.c
@@ -2403,7 +2403,8 @@
   music_control = 0x22;
   CGWSEL_copy = 0;
   CGADSUB_copy = 162;
-  zelda_ppu_write(BG2SC, 0x12);
+  // real zelda does 0x12 here but this seems to work too
+  zelda_ppu_write(BG2SC, 0x13);
   COLDATA_copy0 = 0x3f;
   COLDATA_copy1 = 0x5f;
   COLDATA_copy2 = 0x9f;
@@ -2437,8 +2438,10 @@
   nmi_disable_core_updates = 1;
   Credits_AnimateTheTriangles();
   if (!(frame_counter & 3)) {
-    if (++BG2HOFS_copy2 == 0xc00)
-      zelda_ppu_write_word(BG1SC, 0x1300);
+    if (++BG2HOFS_copy2 == 0xc00) {
+      // real zelda writes 0x00 to BG1SC here but that doesn't seem needed
+      zelda_ppu_write(BG2SC, 0x13);
+    }
     room_bounds_y.a1 = BG2HOFS_copy2 >> 1;
     room_bounds_y.a0 = room_bounds_y.a1 + BG2HOFS_copy2;
     room_bounds_y.b0 = room_bounds_y.a0 >> 1;
--- a/main.c
+++ b/main.c
@@ -313,7 +313,7 @@
 
 static void PlayAudio(Snes *snes, SDL_AudioDeviceID device, int16 *audioBuffer) {
   // generate enough samples
-  if (!kIsOrigEmu && snes) {
+  if (snes) {
     while (snes->apu->dsp->sampleOffset < 534)
       apu_cycle(snes->apu);
     snes->apu->dsp->sampleOffset = 0;
--- a/snes/ppu.c
+++ b/snes/ppu.c
@@ -5,6 +5,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <stddef.h>
+#include <assert.h>
 #include "ppu.h"
 #include "snes.h"
 
@@ -108,7 +109,7 @@
   memset(ppu->objPriorityBuffer, 0, sizeof(ppu->objPriorityBuffer));
   ppu->timeOver = false;
   ppu->rangeOver = false;
-  ppu->objInterlace = false;
+  ppu->objInterlace_always_zero = false;
   for(int i = 0; i < 4; i++) {
     ppu->bgLayer[i].hScroll = 0;
     ppu->bgLayer[i].vScroll = 0;
@@ -116,7 +117,7 @@
     ppu->bgLayer[i].tilemapHigher = false;
     ppu->bgLayer[i].tilemapAdr = 0;
     ppu->bgLayer[i].tileAdr = 0;
-    ppu->bgLayer[i].bigTiles = false;
+    ppu->bgLayer[i].bigTiles_always_zero = false;
     ppu->bgLayer[i].mosaicEnabled = false;
   }
   ppu->scrollPrev = 0;
@@ -135,7 +136,7 @@
   ppu->m7charFill = false;
   ppu->m7xFlip = false;
   ppu->m7yFlip = false;
-  ppu->m7extBg = false;
+  ppu->m7extBg_always_zero = false;
   ppu->m7startX = 0;
   ppu->m7startY = 0;
   for(int i = 0; i < 6; i++) {
@@ -163,10 +164,10 @@
   ppu->mode = 0;
   ppu->bg3priority = false;
   ppu->evenFrame = false;
-  ppu->pseudoHires = false;
-  ppu->overscan = false;
+  ppu->pseudoHires_always_zero = false;
+  ppu->overscan_always_zero = false;
   ppu->frameOverscan = false;
-  ppu->interlace = false;
+  ppu->interlace_always_zero = false;
   ppu->frameInterlace = false;
   ppu->directColor = false;
   ppu->hCount = 0;
@@ -185,7 +186,7 @@
 
 bool ppu_checkOverscan(Ppu* ppu) {
   // called at (0,225)
-  ppu->frameOverscan = ppu->overscan; // set if we have a overscan-frame
+  ppu->frameOverscan = ppu->overscan_always_zero; // set if we have a overscan-frame
   return ppu->frameOverscan;
 }
 
@@ -196,7 +197,7 @@
     ppu->oamInHigh = ppu->oamInHighWritten;
     ppu->oamSecondWrite = false;
   }
-  ppu->frameInterlace = ppu->interlace; // set if we have a interlaced frame
+  ppu->frameInterlace = ppu->interlace_always_zero; // set if we have a interlaced frame
 }
 
 void ppu_runLine(Ppu* ppu, int line) {
@@ -227,11 +228,7 @@
     int mainLayer = ppu_getPixel(ppu, x, y, false, &r, &g, &b);
 
     bool colorWindowState = ppu_getWindowState(ppu, 5, x);
-    if(
-      ppu->clipMode == 3 ||
-      (ppu->clipMode == 2 && colorWindowState) ||
-      (ppu->clipMode == 1 && !colorWindowState)
-    ) {
+    if(ppu->clipMode == 3 || (ppu->clipMode == 2 && colorWindowState) || (ppu->clipMode == 1 && !colorWindowState)) {
       r = g = b = 0;
     }
     int secondLayer = 5; // backdrop
@@ -240,7 +237,7 @@
       (ppu->preventMathMode == 2 && colorWindowState) ||
       (ppu->preventMathMode == 1 && !colorWindowState)
     );
-    if((mathEnabled && ppu->addSubscreen) || ppu->pseudoHires || ppu->mode == 5 || ppu->mode == 6) {
+    if(mathEnabled && ppu->addSubscreen) {
       secondLayer = ppu_getPixel(ppu, x, y, true, &r2, &g2, &b2);
     }
     // TODO: subscreen pixels can be clipped to black as well
@@ -267,17 +264,17 @@
       if(g < 0) g = 0;
       if(b < 0) b = 0;
     }
-    if(!(ppu->pseudoHires || ppu->mode == 5 || ppu->mode == 6)) {
-      r2 = r; g2 = g; b2 = b;
-    }
+    r2 = r; g2 = g; b2 = b;
   }
   int row = (y - 1) + (ppu->evenFrame ? 0 : 239);
-  ppu->pixelBuffer[row * 2048 + x * 8 + 1] = ((b2 << 3) | (b2 >> 2)) * ppu->brightness / 15;
-  ppu->pixelBuffer[row * 2048 + x * 8 + 2] = ((g2 << 3) | (g2 >> 2)) * ppu->brightness / 15;
-  ppu->pixelBuffer[row * 2048 + x * 8 + 3] = ((r2 << 3) | (r2 >> 2)) * ppu->brightness / 15;
-  ppu->pixelBuffer[row * 2048 + x * 8 + 5] = ((b << 3) | (b >> 2)) * ppu->brightness / 15;
-  ppu->pixelBuffer[row * 2048 + x * 8 + 6] = ((g << 3) | (g >> 2)) * ppu->brightness / 15;
-  ppu->pixelBuffer[row * 2048 + x * 8 + 7] = ((r << 3) | (r >> 2)) * ppu->brightness / 15;
+  uint8_t *dst = &ppu->pixelBuffer[row * 2048 + x * 8];
+  uint8_t ppu_brightness = ppu->brightness;
+  dst[1] = ((b2 << 3) | (b2 >> 2)) * ppu_brightness / 15;
+  dst[2] = ((g2 << 3) | (g2 >> 2)) * ppu_brightness / 15;
+  dst[3] = ((r2 << 3) | (r2 >> 2)) * ppu_brightness / 15;
+  dst[5] = ((b << 3) | (b >> 2)) * ppu_brightness / 15;
+  dst[6] = ((g << 3) | (g >> 2)) * ppu_brightness / 15;
+  dst[7] = ((r << 3) | (r >> 2)) * ppu_brightness / 15;
 }
 
 static int ppu_getPixel(Ppu* ppu, int x, int y, bool sub, int* r, int* g, int* b) {
@@ -284,7 +281,6 @@
   // figure out which color is on this location on main- or subscreen, sets it in r, g, b
   // returns which layer it is: 0-3 for bg layer, 4 or 6 for sprites (depending on palette), 5 for backdrop
   int actMode = ppu->mode == 1 && ppu->bg3priority ? 8 : ppu->mode;
-  actMode = ppu->mode == 7 && ppu->m7extBg ? 9 : actMode;
   int layer = 5;
   int pixel = 0;
   for(int i = 0; i < layerCountPerMode[actMode]; i++) {
@@ -313,18 +309,7 @@
           pixel = ppu_getPixelForMode7(ppu, lx, curLayer, curPriority);
         } else {
           lx += ppu->bgLayer[curLayer].hScroll;
-          if(ppu->mode == 5 || ppu->mode == 6) {
-            lx *= 2;
-            lx += (sub || ppu->bgLayer[curLayer].mosaicEnabled) ? 0 : 1;
-            if(ppu->interlace) {
-              ly *= 2;
-              ly += (ppu->evenFrame || ppu->bgLayer[curLayer].mosaicEnabled) ? 0 : 1;
-            }
-          }
           ly += ppu->bgLayer[curLayer].vScroll;
-          if(ppu->mode == 2 || ppu->mode == 4 || ppu->mode == 6) {
-            ppu_handleOPT(ppu, curLayer, &lx, &ly);
-          }
           pixel = ppu_getPixelForBgLayer(
             ppu, lx & 0x3ff, ly & 0x3ff,
             curLayer, curPriority
@@ -355,61 +340,16 @@
   return layer;
 }
 
-static void ppu_handleOPT(Ppu* ppu, int layer, int* lx, int* ly) {
-  int x = *lx;
-  int y = *ly;
-  int column = 0;
-  if(ppu->mode == 6) {
-    column = ((x - (x & 0xf)) - ((ppu->bgLayer[layer].hScroll * 2) & 0xfff0)) >> 4;
-  } else {
-    column = ((x - (x & 0x7)) - (ppu->bgLayer[layer].hScroll & 0xfff8)) >> 3;
-  }
-  if(column > 0) {
-    // fetch offset values from layer 3 tilemap
-    int valid = layer == 0 ? 0x2000 : 0x4000;
-    uint16_t hOffset = ppu_getOffsetValue(ppu, column - 1, 0);
-    uint16_t vOffset = 0;
-    if(ppu->mode == 4) {
-      if(hOffset & 0x8000) {
-        vOffset = hOffset;
-        hOffset = 0;
-      }
-    } else {
-      vOffset = ppu_getOffsetValue(ppu, column - 1, 1);
-    }
-    if(ppu->mode == 6) {
-      // TODO: not sure if correct
-      if(hOffset & valid) *lx = (((hOffset & 0x3f8) + (column * 8)) * 2) | (x & 0xf);
-    } else {
-      if(hOffset & valid) *lx = ((hOffset & 0x3f8) + (column * 8)) | (x & 0x7);
-    }
-    // TODO: not sure if correct for interlace
-    if(vOffset & valid) *ly = (vOffset & 0x3ff) + (y - ppu->bgLayer[layer].vScroll);
-  }
-}
-
-static uint16_t ppu_getOffsetValue(Ppu* ppu, int col, int row) {
-  int x = col * 8 + ppu->bgLayer[2].hScroll;
-  int y = row * 8 + ppu->bgLayer[2].vScroll;
-  int tileBits = ppu->bgLayer[2].bigTiles ? 4 : 3;
-  int tileHighBit = ppu->bgLayer[2].bigTiles ? 0x200 : 0x100;
-  uint16_t tilemapAdr = ppu->bgLayer[2].tilemapAdr + (((y >> tileBits) & 0x1f) << 5 | ((x >> tileBits) & 0x1f));
-  if((x & tileHighBit) && ppu->bgLayer[2].tilemapWider) tilemapAdr += 0x400;
-  if((y & tileHighBit) && ppu->bgLayer[2].tilemapHigher) tilemapAdr += ppu->bgLayer[2].tilemapWider ? 0x800 : 0x400;
-  return ppu->vram[tilemapAdr & 0x7fff];
-}
-
 static int ppu_getPixelForBgLayer(Ppu* ppu, int x, int y, int layer, bool priority) {
   BgLayer *layerp = &ppu->bgLayer[layer];
   // figure out address of tilemap word and read it
-  bool wideTiles = layerp->bigTiles || ppu->mode == 5 || ppu->mode == 6;
-  int tileBitsX = wideTiles ? 4 : 3;
-  int tileHighBitX = wideTiles ? 0x200 : 0x100;
-  int tileBitsY = layerp->bigTiles ? 4 : 3;
-  int tileHighBitY = layerp->bigTiles ? 0x200 : 0x100;
+  int tileBitsX = 3;
+  int tileHighBitX = 0x100;
+  int tileBitsY = 3;
+  int tileHighBitY = 0x100;
   uint16_t tilemapAdr = layerp->tilemapAdr + (((y >> tileBitsY) & 0x1f) << 5 | ((x >> tileBitsX) & 0x1f));
-  if((x & tileHighBitX) && layerp->tilemapWider) tilemapAdr += 0x400;
-  if((y & tileHighBitY) && layerp->tilemapHigher) tilemapAdr += layerp->tilemapWider ? 0x800 : 0x400;
+  if ((x & tileHighBitX) && layerp->tilemapWider) tilemapAdr += 0x400;
+  if ((y & tileHighBitY) && layerp->tilemapHigher) tilemapAdr += layerp->tilemapWider ? 0x800 : 0x400;
   uint16_t tile = ppu->vram[tilemapAdr & 0x7fff];
   // check priority, get palette
   if(((bool) (tile & 0x2000)) != priority) return 0; // wrong priority
@@ -418,14 +358,6 @@
   int row = (tile & 0x8000) ? 7 - (y & 0x7) : (y & 0x7);
   int col = (tile & 0x4000) ? (x & 0x7) : 7 - (x & 0x7);
   int tileNum = tile & 0x3ff;
-  if(wideTiles) {
-    // if unflipped right half of tile, or flipped left half of tile
-    if(((bool) (x & 8)) ^ ((bool) (tile & 0x4000))) tileNum += 1;
-  }
-  if(layerp->bigTiles) {
-    // if unflipped bottom half of tile, or flipped upper half of tile
-    if(((bool) (y & 8)) ^ ((bool) (tile & 0x8000))) tileNum += 0x10;
-  }
   // read tiledata, ajust palette for mode 0
   int bitDepth = bitDepthsPerMode[ppu->mode][layer];
   if(ppu->mode == 0) paletteNum += 8 * layer;
@@ -538,7 +470,7 @@
     // check if the sprite is on this line and get the sprite size
     uint8_t row = line - y;
     int spriteSize = spriteSizes[ppu->objSize][(ppu->highOam[index >> 3] >> ((index & 7) + 1)) & 1];
-    int spriteHeight = ppu->objInterlace ? spriteSize / 2 : spriteSize;
+    int spriteHeight = spriteSize;
     if(row < spriteHeight) {
       // in y-range, get the x location, using the high bit as well
       int x = ppu->oam[index] & 0xff;
@@ -552,8 +484,6 @@
           ppu->rangeOver = true;
           break;
         }
-        // update row according to obj-interlace
-        if(ppu->objInterlace) row = row * 2 + (ppu->evenFrame ? 0 : 1);
         // get some data for the sprite and y-flip row if needed
         int tile = ppu->oam[index + 1] & 0xff;
         int palette = (ppu->oam[index + 1] & 0xe00) >> 9;
@@ -786,10 +716,9 @@
     case 0x05: {
       ppu->mode = val & 0x7;
       ppu->bg3priority = val & 0x8;
-      ppu->bgLayer[0].bigTiles = val & 0x10;
-      ppu->bgLayer[1].bigTiles = val & 0x20;
-      ppu->bgLayer[2].bigTiles = val & 0x40;
-      ppu->bgLayer[3].bigTiles = val & 0x80;
+      assert(ppu->mode == 1 || ppu->mode == 7);
+      // bigTiles are never used
+      assert((val & 0xf0) == 0);
       break;
     }
     case 0x06: {
@@ -799,7 +728,7 @@
       ppu->bgLayer[2].mosaicEnabled = val & 0x4;
       ppu->bgLayer[3].mosaicEnabled = val & 0x8;
       ppu->mosaicSize = (val >> 4) + 1;
-      ppu->mosaicStartLine = 0;// ppu->snes->vPos;
+      ppu->mosaicStartLine = 0;
       break;
     }
     case 0x07:
@@ -806,6 +735,7 @@
     case 0x08:
     case 0x09:
     case 0x0a: {
+      // small tilemaps are used in attract intro
       ppu->bgLayer[adr - 7].tilemapWider = val & 0x1;
       ppu->bgLayer[adr - 7].tilemapHigher = val & 0x2;
       ppu->bgLayer[adr - 7].tilemapAdr = (val & 0xfc) << 8;
@@ -1014,11 +944,12 @@
       break;
     }
     case 0x33: {
-      ppu->interlace = val & 0x1;
-      ppu->objInterlace = val & 0x2;
-      ppu->overscan = val & 0x4;
-      ppu->pseudoHires = val & 0x8;
-      ppu->m7extBg = val & 0x40;
+      assert(val == 0);
+      ppu->interlace_always_zero = val & 0x1;
+      ppu->objInterlace_always_zero = val & 0x2;
+      ppu->overscan_always_zero = val & 0x4;
+      ppu->pseudoHires_always_zero = val & 0x8;
+      ppu->m7extBg_always_zero = val & 0x40;
       break;
     }
     default: {
--- a/snes/ppu.h
+++ b/snes/ppu.h
@@ -19,7 +19,7 @@
   bool tilemapHigher;
   uint16_t tilemapAdr;
   uint16_t tileAdr;
-  bool bigTiles;
+  bool bigTiles_always_zero;
   bool mosaicEnabled;
 } BgLayer;
 
@@ -70,7 +70,7 @@
   uint8_t objPriorityBuffer[256];
   bool timeOver;
   bool rangeOver;
-  bool objInterlace;
+  bool objInterlace_always_zero;
   // background layers
   BgLayer bgLayer[4];
   uint8_t scrollPrev;
@@ -86,7 +86,7 @@
   bool m7charFill;
   bool m7xFlip;
   bool m7yFlip;
-  bool m7extBg;
+  bool m7extBg_always_zero;
   // mode 7 internal
   int32_t m7startX;
   int32_t m7startY;
@@ -112,10 +112,10 @@
   uint8_t mode;
   bool bg3priority;
   bool evenFrame;
-  bool pseudoHires;
-  bool overscan;
+  bool pseudoHires_always_zero;
+  bool overscan_always_zero;
   bool frameOverscan; // if we are overscanning this frame (determined at 0,225)
-  bool interlace;
+  bool interlace_always_zero;
   bool frameInterlace; // if we are interlacing this frame (determined at start vblank)
   bool directColor;
   // latching
--- a/snes/snes.c
+++ b/snes/snes.c
@@ -20,7 +20,6 @@
 
 static const double apuCyclesPerMaster = (32040 * 32) / (1364 * 262 * 60.0);
 
-static void snes_runCycle(Snes* snes);
 static void snes_runCpu(Snes* snes);
 static void snes_catchupApu(Snes* snes);
 static uint8_t snes_readReg(Snes* snes, uint16_t adr);
@@ -107,16 +106,7 @@
 }
 
 static uint8_t g_last_module;
-bool didit;
 
-void snes_runFrame(Snes* snes) {
-  // runs a signle frame (run cycles until v/h pos is at 0,0)
-  do {
-    snes_runCycle(snes);
-  } while(!(snes->hPos == 0 && snes->vPos == 0));
-}
-
-
 void snes_printCpuLine(Snes *snes) {
   if (snes->debug_cycles) {
     static FILE *fout;
@@ -132,93 +122,6 @@
   }
 }
 
-void snes_runGfxCycles(Snes *snes) {
-  // check for h/v timer irq's
-  if(snes->vIrqEnabled && snes->hIrqEnabled) {
-    if(snes->vPos == snes->vTimer && snes->hPos == (4 * snes->hTimer)) {
-      snes->inIrq = true;
-      snes->cpu->irqWanted = true; // request IRQ on CPU
-    }
-  } else if(snes->vIrqEnabled && !snes->hIrqEnabled) {
-    if(snes->vPos == snes->vTimer && snes->hPos == 0) {
-      snes->inIrq = true;
-      snes->cpu->irqWanted = true; // request IRQ on CPU
-    }
-  } else if(!snes->vIrqEnabled && snes->hIrqEnabled) {
-    if(snes->hPos == (4 * snes->hTimer)) {
-      snes->inIrq = true;
-      snes->cpu->irqWanted = true; // request IRQ on CPU
-    }
-  }
-  // handle positional stuff
-  // TODO: better timing? (especially Hpos)
-  if(snes->hPos == 0) {
-    // end of hblank, do most vPos-tests
-    bool startingVblank = false;
-    if(snes->vPos == 0) {
-      // end of vblank
-      snes->inVblank = false;
-      snes->inNmi = false;
-      dma_initHdma(snes->dma);
-    } else if(snes->vPos == 225) {
-      // ask the ppu if we start vblank now or at vPos 240 (overscan)
-      startingVblank = !ppu_checkOverscan(snes->ppu);
-    } else if(snes->vPos == 240){
-      // if we are not yet in vblank, we had an overscan frame, set startingVblank
-      if(!snes->inVblank) startingVblank = true;
-    }
-    if(startingVblank) {
-      // if we are starting vblank
-      ppu_handleVblank(snes->ppu);
-      snes->inVblank = true;
-      snes->inNmi = true;
-      if(snes->autoJoyRead) {
-        // TODO: this starts a little after start of vblank
-        snes->autoJoyTimer = 4224;
-        snes_doAutoJoypad(snes);
-      }
-      if(snes->nmiEnabled) {
-        snes->cpu->nmiWanted = true; // request NMI on CPU
-      }
-    }
-  } else if(snes->hPos == 512) {
-    // render the line halfway of the screen for better compatibility
-    if(!snes->inVblank) ppu_runLine(snes->ppu, snes->vPos);
-  } else if(snes->hPos == 1024) {
-    // start of hblank
-    if(!snes->inVblank) dma_doHdma(snes->dma);
-  }
-  // handle autoJoyRead-timer
-  if(snes->autoJoyTimer > 0) snes->autoJoyTimer -= 2;
-  // increment position
-  // TODO: exact frame timing (line 240 on odd frame is 4 cycles shorter,
-  //   even frames in interlace is 1 extra line)
-  if (!snes->disableHpos || !(snes->hPos < 536 || snes->hPos >= 576) || snes->hPos == 0 || snes->vPos == 0)
-    snes->hPos += 2;
-  if(snes->hPos == 1364) {
-    snes->hPos = 0;
-    snes->vPos++;
-    if(snes->vPos == 262) {
-      snes->vPos = 0;
-      snes->frames++;
-      snes_catchupApu(snes); // catch up the apu at the end of the frame
-    }
-  }
-}
-
-static void snes_runCycle(Snes* snes) {
-  snes->apuCatchupCycles += apuCyclesPerMaster * 2.0;
-  input_cycle(snes->input1);
-  input_cycle(snes->input2);
-  // if not in dram refresh, if we are busy with hdma/dma, do that, else do cpu cycle
-  if(snes->hPos < 536 || snes->hPos >= 576) {
-    if(!dma_cycle(snes->dma)) {
-      snes_runCpu(snes);
-    }
-  }
- snes_runGfxCycles(snes);
-}
-
 static void snes_runCpu(Snes* snes) {
   if(snes->cpuCyclesLeft == 0) {
     snes->cpuMemOps = 0;
@@ -267,10 +170,7 @@
     return ppu_read(snes->ppu, adr);
   }
   if(adr < 0x80) {
-    if (kIsOrigEmu)
-      snes_catchupApu(snes); // catch up the apu before reading
-    else
-      apu_cycle(snes->apu);//spc_runOpcode(snes->apu->spc);
+    apu_cycle(snes->apu);//spc_runOpcode(snes->apu->spc);
     return snes->apu->outPorts[adr & 0x3];
   }
   if(adr == 0x80) {
@@ -481,7 +381,7 @@
 
 int g_bp_addr = 0;
 
-void PrintState();
+
 void snes_write(Snes* snes, uint32_t adr, uint8_t val) {
   snes->openBus = val;
   uint8_t bank = adr >> 16;
@@ -519,33 +419,6 @@
 static int snes_getAccessTime(Snes* snes, uint32_t adr) {
   // optimization
   return 6;
-
-  uint8_t bank = adr >> 16;
-  adr &= 0xffff;
-  if(bank >= 0x40 && bank < 0x80) {
-    return 8; // slow
-  }
-  if(bank >= 0xc0) {
-    return snes->fastMem ? 6 : 8; // depends on setting
-  }
-  // banks 0x00-0x3f and 0x80-0xcf
-  if(adr < 0x2000) {
-    return 8; // slow
-  }
-  if(adr < 0x4000) {
-    return 6; // fast
-  }
-  if(adr < 0x4200) {
-    return 12; // extra slow
-  }
-  if(adr < 0x6000) {
-    return 6; // fast
-  }
-  if(adr < 0x8000) {
-    return 8; // slow
-  }
-  // 0x8000-0xffff
-  return (snes->fastMem && bank >= 0x80) ? 6 : 8; // depends on setting in banks 80+
 }
 
 uint8_t snes_read(Snes* snes, uint32_t adr) {
@@ -568,19 +441,3 @@
 
 // debugging
 
-void snes_debugCycle(Snes* snes, bool* cpuNext, bool* spcNext) {
-  // runs a normal cycle, catches up the apu, then looks if the next cycle will execute a CPU and/or a SPC opcode
-  snes_runCycle(snes);
-  snes_catchupApu(snes);
-  if(snes->dma->hdmaTimer > 0 || snes->dma->dmaBusy || (snes->hPos >= 536 && snes->hPos < 576)) {
-    *cpuNext = false;
-  } else {
-    *cpuNext = snes->cpuCyclesLeft == 0;
-  }
-  if(snes->apuCatchupCycles + (apuCyclesPerMaster * 2.0) >= 1.0) {
-    // we will run a apu cycle next call, see if it also starts a opcode
-    *spcNext = snes->apu->cpuCyclesLeft == 0;
-  } else {
-    *spcNext = false;
-  }
-}
--- a/snes/snes.h
+++ b/snes/snes.h
@@ -17,11 +17,6 @@
 #include "cart.h"
 #include "input.h"
 
-enum {
-  kIsOrigEmu = 0
-};
-
-
 struct Snes {
   Cpu* cpu;
   Apu* apu;
@@ -75,7 +70,6 @@
 Snes* snes_init(uint8_t *ram);
 void snes_free(Snes* snes);
 void snes_reset(Snes* snes, bool hard);
-void snes_runFrame(Snes* snes);
 // used by dma, cpu
 uint8_t snes_readBBus(Snes* snes, uint8_t adr);
 void snes_writeBBus(Snes* snes, uint8_t adr, uint8_t val);
@@ -84,7 +78,6 @@
 uint8_t snes_cpuRead(Snes* snes, uint32_t adr);
 void snes_cpuWrite(Snes* snes, uint32_t adr, uint8_t val);
 // debugging
-void snes_debugCycle(Snes* snes, bool* cpuNext, bool* spcNext);
 void snes_printCpuLine(Snes *snes);
 void snes_doAutoJoypad(Snes *snes);
 // snes_other.c functions:
--- a/zelda_cpu_infra.c
+++ b/zelda_cpu_infra.c
@@ -689,11 +689,6 @@
 bool RunOneFrame(Snes *snes, int input_state, bool turbo) {
   frame_ctr++;
 
-  if (kIsOrigEmu) {
-    snes_runFrame(snes);
-    return false;
-  }
-
   // Either copy state or apply state
   if (state_recorder.replay_mode) {
     input_state = StateRecorder_ReadNextReplayState(&state_recorder);