diff --git a/bsnes/nall/snes/cartridge.hpp b/bsnes/nall/snes/cartridge.hpp
index 66398603..4c461b25 100755
--- a/bsnes/nall/snes/cartridge.hpp
+++ b/bsnes/nall/snes/cartridge.hpp
@@ -146,10 +146,8 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
     xml << "    <map mode='linear' address='80-ff:8000-ffff'/>\n";
     xml << "  </rom>\n";
     xml << "  <icd2 revision='1'>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='00-3f:6000-7fff'/>\n";
-    xml << "      <map address='80-bf:6000-7fff'/>\n";
-    xml << "    </mmio>\n";
+    xml << "    <map address='00-3f:6000-7fff'/>\n";
+    xml << "    <map address='80-bf:6000-7fff'/>\n";
     xml << "  </icd2>\n";
   } else if(type == TypeSuperGameBoy2Bios) {
     xml << "  <rom>\n";
@@ -157,10 +155,8 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
     xml << "    <map mode='linear' address='80-ff:8000-ffff'/>\n";
     xml << "  </rom>\n";
     xml << "  <icd2 revision='2'>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='00-3f:6000-7fff'/>\n";
-    xml << "      <map address='80-bf:6000-7fff'/>\n";
-    xml << "    </mmio>\n";
+    xml << "    <map address='00-3f:6000-7fff'/>\n";
+    xml << "    <map address='80-bf:6000-7fff'/>\n";
     xml << "  </icd2>\n";
   } else if(has_spc7110) {
     xml << "  <rom>\n";
@@ -379,10 +375,8 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
 
   if(has_srtc) {
     xml << "  <srtc>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='00-3f:2800-2801'/>\n";
-    xml << "      <map address='80-bf:2800-2801'/>\n";
-    xml << "    </mmio>\n";
+    xml << "    <map address='00-3f:2800-2801'/>\n";
+    xml << "    <map address='80-bf:2800-2801'/>\n";
     xml << "  </srtc>\n";
   }
 
@@ -400,10 +394,8 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
 
   if(has_cx4) {
     xml << "  <cx4>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='00-3f:6000-7fff'/>\n";
-    xml << "      <map address='80-bf:6000-7fff'/>\n";
-    xml << "    </mmio>\n";
+    xml << "    <map address='00-3f:6000-7fff'/>\n";
+    xml << "    <map address='80-bf:6000-7fff'/>\n";
     xml << "  </cx4>\n";
   }
 
@@ -481,36 +473,29 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
 
   if(has_obc1) {
     xml << "  <obc1>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='00-3f:6000-7fff'/>\n";
-    xml << "      <map address='80-bf:6000-7fff'/>\n";
-    xml << "    </mmio>\n";
+    xml << "    <map address='00-3f:6000-7fff'/>\n";
+    xml << "    <map address='80-bf:6000-7fff'/>\n";
     xml << "  </obc1>\n";
   }
 
   if(has_st010) {
-    xml << "  <upd96050 program='st0010.bin' sha256='55c697e864562445621cdf8a7bf6e84ae91361e393d382a3704e9aa55559041e'>\n";
-    xml << "    <map address='68-6f:0000-0fff'/>\n";
-    xml << "    <map address='e8-ef:0000-0fff'/>\n";
+    xml << "  <upd96050 program='st0010.bin' frequency='10000000' sha256='55c697e864562445621cdf8a7bf6e84ae91361e393d382a3704e9aa55559041e'>\n";
+    xml << "    <map address='60-6f:0000-0fff'/>\n";
+    xml << "    <map address='e0-ef:0000-0fff'/>\n";
     xml << "  </upd96050>\n";
   }
 
   if(has_st011) {
-    //ST-0011 addresses not verified; chip is unsupported
-    xml << "  <setadsp program='ST-0011'>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='68-6f:0000-0fff'/>\n";
-    xml << "      <map address='e8-ef:0000-0fff'/>\n";
-    xml << "    </mmio>\n";
-    xml << "  </setadsp>\n";
+    xml << "  <upd96050 program='st0011.bin' frequency='15000000' sha256='448e0deb0f580833ea878f4894a56124da18453d2d78e821388b6545909ba00a'>\n";
+    xml << "    <map address='60-6f:0000-0fff'/>\n";
+    xml << "    <map address='e0-ef:0000-0fff'/>\n";
+    xml << "  </upd96050>\n";
   }
 
   if(has_st018) {
     xml << "  <setarisc program='ST-0018'>\n";
-    xml << "    <mmio>\n";
-    xml << "      <map address='00-3f:3800-38ff'/>\n";
-    xml << "      <map address='80-bf:3800-38ff'/>\n";
-    xml << "    </mmio>\n";
+    xml << "    <map address='00-3f:3800-38ff'/>\n";
+    xml << "    <map address='80-bf:3800-38ff'/>\n";
     xml << "  </setarisc>\n";
   }
 
diff --git a/bsnes/snes/cartridge/cartridge.cpp b/bsnes/snes/cartridge/cartridge.cpp
index 2aa25a41..fb6c0713 100755
--- a/bsnes/snes/cartridge/cartridge.cpp
+++ b/bsnes/snes/cartridge/cartridge.cpp
@@ -43,7 +43,7 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
   has_serial     = false;
 
   parse_xml(xml_list);
-//foreach(xml_item, xml_list) print(xml_item, "\n\n");
+//print(xml_list[0], "\n\n");
 
   if(ram_size > 0) {
     memory::cartram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
diff --git a/bsnes/snes/cartridge/xml.cpp b/bsnes/snes/cartridge/xml.cpp
index e32f63b8..e57d224c 100755
--- a/bsnes/snes/cartridge/xml.cpp
+++ b/bsnes/snes/cartridge/xml.cpp
@@ -107,16 +107,12 @@ void Cartridge::xml_parse_icd2(xml_element &root) {
   }
 
   foreach(node, root.element) {
-    if(node.name == "mmio") {
-      foreach(leaf, node.element) {
-        if(leaf.name == "map") {
-          Mapping m((Memory&)icd2);
-          foreach(attr, leaf.attribute) {
-            if(attr.name == "address") xml_parse_address(m, attr.content);
-          }
-          mapping.append(m);
-        }
+    if(node.name == "map") {
+      Mapping m((Memory&)icd2);
+      foreach(attr, node.attribute) {
+        if(attr.name == "address") xml_parse_address(m, attr.content);
       }
+      mapping.append(m);
     }
   }
 }
@@ -330,7 +326,7 @@ void Cartridge::xml_parse_upd96050(xml_element &root) {
         for(unsigned n = 0; n < 16384; n++) {
           upd96050.programROM[n] = fp.readm(3);
         }
-        for(unsigned n = 0; n <  1024; n++) {
+        for(unsigned n = 0; n <  2048; n++) {
           upd96050.dataROM[n] = fp.readm(2);
         }
 
@@ -455,16 +451,12 @@ void Cartridge::xml_parse_srtc(xml_element &root) {
   has_srtc = true;
 
   foreach(node, root.element) {
-    if(node.name == "mmio") {
-      foreach(leaf, node.element) {
-        if(leaf.name == "map") {
-          Mapping m(srtc);
-          foreach(attr, leaf.attribute) {
-            if(attr.name == "address") xml_parse_address(m, attr.content);
-          }
-          mapping.append(m);
-        }
+    if(node.name == "map") {
+      Mapping m(srtc);
+      foreach(attr, node.attribute) {
+        if(attr.name == "address") xml_parse_address(m, attr.content);
       }
+      mapping.append(m);
     }
   }
 }
@@ -569,16 +561,12 @@ void Cartridge::xml_parse_cx4(xml_element &root) {
   has_cx4 = true;
 
   foreach(node, root.element) {
-    if(node.name == "mmio") {
-      foreach(leaf, node.element) {
-        if(leaf.name == "map") {
-          Mapping m(cx4);
-          foreach(attr, leaf.attribute) {
-            if(attr.name == "address") xml_parse_address(m, attr.content);
-          }
-          mapping.append(m);
-        }
+    if(node.name == "map") {
+      Mapping m(cx4);
+      foreach(attr, node.attribute) {
+        if(attr.name == "address") xml_parse_address(m, attr.content);
       }
+      mapping.append(m);
     }
   }
 }
@@ -587,16 +575,12 @@ void Cartridge::xml_parse_obc1(xml_element &root) {
   has_obc1 = true;
 
   foreach(node, root.element) {
-    if(node.name == "mmio") {
-      foreach(leaf, node.element) {
-        if(leaf.name == "map") {
-          Mapping m(obc1);
-          foreach(attr, leaf.attribute) {
-            if(attr.name == "address") xml_parse_address(m, attr.content);
-          }
-          mapping.append(m);
-        }
+    if(node.name == "map") {
+      Mapping m(obc1);
+      foreach(attr, node.attribute) {
+        if(attr.name == "address") xml_parse_address(m, attr.content);
       }
+      mapping.append(m);
     }
   }
 }
@@ -619,16 +603,12 @@ void Cartridge::xml_parse_setadsp(xml_element &root) {
   Memory *map[3] = { 0, &st0010, 0 };
 
   foreach(node, root.element) {
-    if(node.name == "mmio" && map[program]) {
-      foreach(leaf, node.element) {
-        if(leaf.name == "map") {
-          Mapping m(*map[program]);
-          foreach(attr, leaf.attribute) {
-            if(attr.name == "address") xml_parse_address(m, attr.content);
-          }
-          mapping.append(m);
-        }
+    if(node.name == "map" && map[program]) {
+      Mapping m(*map[program]);
+      foreach(attr, node.attribute) {
+        if(attr.name == "address") xml_parse_address(m, attr.content);
       }
+      mapping.append(m);
     }
   }
 }
@@ -648,16 +628,12 @@ void Cartridge::xml_parse_setarisc(xml_element &root) {
   MMIO *map[2] = { 0, &st0018 };
 
   foreach(node, root.element) {
-    if(node.name == "mmio" && map[program]) {
-      foreach(leaf, node.element) {
-        if(leaf.name == "map") {
-          Mapping m(*map[program]);
-          foreach(attr, leaf.attribute) {
-            if(attr.name == "address") xml_parse_address(m, attr.content);
-          }
-          mapping.append(m);
-        }
+    if(node.name == "map" && map[program]) {
+      Mapping m(*map[program]);
+      foreach(attr, node.attribute) {
+        if(attr.name == "address") xml_parse_address(m, attr.content);
       }
+      mapping.append(m);
     }
   }
 }
diff --git a/bsnes/snes/chip/icd2/icd2.cpp b/bsnes/snes/chip/icd2/icd2.cpp
index 27eab8ca..8c7ccfc5 100755
--- a/bsnes/snes/chip/icd2/icd2.cpp
+++ b/bsnes/snes/chip/icd2/icd2.cpp
@@ -13,6 +13,7 @@ void ICD2::Enter() { icd2.enter(); }
 void ICD2::enter() {
   while(true) {
     if(scheduler.sync == Scheduler::SynchronizeMode::All) {
+      GameBoy::system.runtosave();
       scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
     }
 
diff --git a/bsnes/snes/chip/icd2/serialization.cpp b/bsnes/snes/chip/icd2/serialization.cpp
index f97260ff..1931daa5 100755
--- a/bsnes/snes/chip/icd2/serialization.cpp
+++ b/bsnes/snes/chip/icd2/serialization.cpp
@@ -2,8 +2,6 @@
 
 void ICD2::serialize(serializer &s) {
   Processor::serialize(s);
-
-  GameBoy::system.runtosave();
   GameBoy::system.serialize_all(s);
 
   for(unsigned n = 0; n < 64; n++) s.array(packet[n].data);
diff --git a/bsnes/snes/chip/necdsp/core/core.cpp b/bsnes/snes/chip/necdsp/core/core.cpp
index bb634fef..4d98844c 100755
--- a/bsnes/snes/chip/necdsp/core/core.cpp
+++ b/bsnes/snes/chip/necdsp/core/core.cpp
@@ -7,6 +7,12 @@ namespace SNES {
 #include "serialization.cpp"
 
 void uPDcore::exec() {
+//static uint16 lastpc = 0xffff;
+//if(lastpc != regs.pc) {
+//  print("A:", hex<4>((uint16)regs.a), " B:", hex<4>((uint16)regs.b), " DR:", hex<4>(regs.dr), " SR:", hex<4>(regs.sr), " FA:", hex<2>(regs.flaga), " FB:", hex<2>(regs.flagb), "\n");
+//  print(disassemble(lastpc = regs.pc), "\n");
+//}
+
   uint24 opcode = programROM[regs.pc];
   regs.pc = regs.pc + 1;
   switch(opcode >> 22) {
@@ -43,8 +49,8 @@ void uPDcore::exec_op(uint24 opcode) {
     case  8: regs.idb = regs.dr; regs.sr.rqm = 1; break;
     case  9: regs.idb = regs.dr; break;
     case 10: regs.idb = regs.sr; break;
-  //case 11: regs.idb = regs.sim; break;
-  //case 12: regs.idb = regs.sil; break;
+    case 11: regs.idb = regs.si; break;  //MSB
+    case 12: regs.idb = regs.si; break;  //LSB
     case 13: regs.idb = regs.k; break;
     case 14: regs.idb = regs.l; break;
     case 15: regs.idb = dataRAM[regs.dp]; break;
@@ -152,54 +158,113 @@ void uPDcore::exec_rt(uint24 opcode) {
 void uPDcore::exec_jp(uint24 opcode) {
   uint9 brch = opcode >> 13;  //branch
   uint11 na  = opcode >>  2;  //next address
+  uint2 bank = opcode >>  0;  //bank address
 
-  bool r = false;
+  uint16 jps = (regs.pc & 0x3800) | (na << 0);
+  uint16 jpl = (regs.pc & 0x2000) | (bank << 11) | (na << 0);
+
+  bool lj = false;
+  ljmp:
 
   switch(brch) {
-    case 0x080: r = (regs.flaga.c == 0);      break;  //JNCA
-    case 0x082: r = (regs.flaga.c == 1);      break;  //JCA
-    case 0x084: r = (regs.flagb.c == 0);      break;  //JNCB
-    case 0x086: r = (regs.flagb.c == 1);      break;  //JCB
-    case 0x088: r = (regs.flaga.z == 0);      break;  //JNZA
-    case 0x08a: r = (regs.flaga.z == 1);      break;  //JZA
-    case 0x08c: r = (regs.flagb.z == 0);      break;  //JNZB
-    case 0x08e: r = (regs.flagb.z == 1);      break;  //JZB
-    case 0x090: r = (regs.flaga.ov0 == 0);    break;  //JNOVA0
-    case 0x092: r = (regs.flaga.ov0 == 1);    break;  //JOVA0
-    case 0x094: r = (regs.flagb.ov0 == 0);    break;  //JNOVB0
-    case 0x096: r = (regs.flagb.ov0 == 1);    break;  //JOVB0
-    case 0x098: r = (regs.flaga.ov1 == 0);    break;  //JNOVA1
-    case 0x09a: r = (regs.flaga.ov1 == 1);    break;  //JOVA1
-    case 0x09c: r = (regs.flagb.ov1 == 0);    break;  //JNOVB1
-    case 0x09e: r = (regs.flagb.ov1 == 1);    break;  //JOVB1
-    case 0x0a0: r = (regs.flaga.s0 == 0);     break;  //JNSA0
-    case 0x0a2: r = (regs.flaga.s0 == 1);     break;  //JSA0
-    case 0x0a4: r = (regs.flagb.s0 == 0);     break;  //JNSB0
-    case 0x0a6: r = (regs.flagb.s0 == 1);     break;  //JSB0
-    case 0x0a8: r = (regs.flaga.s1 == 0);     break;  //JNSA1
-    case 0x0aa: r = (regs.flaga.s1 == 1);     break;  //JSA1
-    case 0x0ac: r = (regs.flagb.s1 == 0);     break;  //JNSB1
-    case 0x0ae: r = (regs.flagb.s1 == 1);     break;  //JSB1
+    case 0x080: if(regs.flaga.c == 0) regs.pc = jps; return;  //JNCA
+    case 0x082: if(regs.flaga.c == 1) regs.pc = jps; return;  //JCA
+    case 0x084: if(regs.flagb.c == 0) regs.pc = jps; return;  //JNCB
+    case 0x086: if(regs.flagb.c == 1) regs.pc = jps; return;  //JCB
 
-    case 0x0b0: r = (regs.dp & 0x0f) == 0x00; break;  //JDPL0
-    case 0x0b1: r = (regs.dp & 0x0f) != 0x00; break;  //JDPLN0
-    case 0x0b2: r = (regs.dp & 0x0f) == 0x0f; break;  //JDPLF
-    case 0x0b3: r = (regs.dp & 0x0f) != 0x0f; break;  //JDPLNF
+    case 0x088: if(regs.flaga.z == 0) regs.pc = jps; return;  //JNZA
+    case 0x08a: if(regs.flaga.z == 1) regs.pc = jps; return;  //JZA
+    case 0x08c: if(regs.flagb.z == 0) regs.pc = jps; return;  //JNZB
+    case 0x08e: if(regs.flagb.z == 1) regs.pc = jps; return;  //JZB
 
-    case 0x0b4: r = (regs.siack == 0);        break;  //JNSIAK
-    case 0x0b6: r = (regs.siack == 1);        break;  //JSIAK
+    case 0x090: if(regs.flaga.ov0 == 0) regs.pc = jps; return;  //JNOVA0
+    case 0x092: if(regs.flaga.ov0 == 1) regs.pc = jps; return;  //JOVA0
+    case 0x094: if(regs.flagb.ov0 == 0) regs.pc = jps; return;  //JNOVB0
+    case 0x096: if(regs.flagb.ov0 == 1) regs.pc = jps; return;  //JOVB0
 
-    case 0x0b8: r = (regs.soack == 0);        break;  //JNSOAK
-    case 0x0ba: r = (regs.soack == 1);        break;  //JSOAK
+    case 0x098: if(regs.flaga.ov1 == 0) regs.pc = jps; return;  //JNOVA1
+    case 0x09a: if(regs.flaga.ov1 == 1) regs.pc = jps; return;  //JOVA1
+    case 0x09c: if(regs.flagb.ov1 == 0) regs.pc = jps; return;  //JNOVB1
+    case 0x09e: if(regs.flagb.ov1 == 1) regs.pc = jps; return;  //JOVB1
 
-    case 0x0bc: r = (regs.sr.rqm == 0);       break;  //JNRQM
-    case 0x0be: r = (regs.sr.rqm == 1);       break;  //JRQM
+    case 0x0a0: if(regs.flaga.s0 == 0) regs.pc = jps; return;  //JNSA0
+    case 0x0a2: if(regs.flaga.s0 == 1) regs.pc = jps; return;  //JSA0
+    case 0x0a4: if(regs.flagb.s0 == 0) regs.pc = jps; return;  //JNSB0
+    case 0x0a6: if(regs.flagb.s0 == 1) regs.pc = jps; return;  //JSB0
 
-    case 0x100: r = true;                     break;  //JMP
-    case 0x140: r = true; stack_push();       break;  //CALL
+    case 0x0a8: if(regs.flaga.s1 == 0) regs.pc = jps; return;  //JNSA1
+    case 0x0aa: if(regs.flaga.s1 == 1) regs.pc = jps; return;  //JSA1
+    case 0x0ac: if(regs.flagb.s1 == 0) regs.pc = jps; return;  //JNSB1
+    case 0x0ae: if(regs.flagb.s1 == 1) regs.pc = jps; return;  //JSB1
+
+    case 0x0b0: if((regs.dp & 0x0f) == 0x00) regs.pc = jps; return;  //JDPL0
+    case 0x0b1: if((regs.dp & 0x0f) != 0x00) regs.pc = jps; return;  //JDPLN0
+    case 0x0b2: if((regs.dp & 0x0f) == 0x0f) regs.pc = jps; return;  //JDPLF
+    case 0x0b3: if((regs.dp & 0x0f) != 0x0f) regs.pc = jps; return;  //JDPLNF
+
+    case 0x0bc: if(regs.sr.rqm == 0) regs.pc = jps; return;  //JNRQM
+    case 0x0be: if(regs.sr.rqm == 1) regs.pc = jps; return;  //JRQM
+
+    case 0x100: regs.pc = jps; return;                //JMP
+    case 0x140: stack_push(); regs.pc = jps; return;  //CALL
   }
 
-  if(r) regs.pc = na;
+  if(brch == 0x000) {
+    regs.pc = regs.so;
+    return;
+  }
+
+  if(lj == false) {
+    lj = true;
+    brch &= ~1;
+    jps = jpl;
+    goto ljmp;
+  }
+
+/*switch(brch) {
+    case 0x081: if(regs.flaga.c == 0) regs.pc = jpl; return;  //LJNCA
+
+    case 0x0bf: if(regs.sr.rqm == 1) regs.pc = jpl; return;  //LJRQM
+  }*/
+
+  print(hex<4>(regs.pc - 1), ": unknown jump ", hex<3>(brch), "\n");
+
+/*bool r = false;
+switch(brch) {
+  case 0x080: r = (regs.flaga.c == 0);      break;  //JNCA
+  case 0x082: r = (regs.flaga.c == 1);      break;  //JCA
+  case 0x084: r = (regs.flagb.c == 0);      break;  //JNCB
+  case 0x086: r = (regs.flagb.c == 1);      break;  //JCB
+  case 0x088: r = (regs.flaga.z == 0);      break;  //JNZA
+  case 0x08a: r = (regs.flaga.z == 1);      break;  //JZA
+  case 0x08c: r = (regs.flagb.z == 0);      break;  //JNZB
+  case 0x08e: r = (regs.flagb.z == 1);      break;  //JZB
+  case 0x090: r = (regs.flaga.ov0 == 0);    break;  //JNOVA0
+  case 0x092: r = (regs.flaga.ov0 == 1);    break;  //JOVA0
+  case 0x094: r = (regs.flagb.ov0 == 0);    break;  //JNOVB0
+  case 0x096: r = (regs.flagb.ov0 == 1);    break;  //JOVB0
+  case 0x098: r = (regs.flaga.ov1 == 0);    break;  //JNOVA1
+  case 0x09a: r = (regs.flaga.ov1 == 1);    break;  //JOVA1
+  case 0x09c: r = (regs.flagb.ov1 == 0);    break;  //JNOVB1
+  case 0x09e: r = (regs.flagb.ov1 == 1);    break;  //JOVB1
+  case 0x0a0: r = (regs.flaga.s0 == 0);     break;  //JNSA0
+  case 0x0a2: r = (regs.flaga.s0 == 1);     break;  //JSA0
+  case 0x0a4: r = (regs.flagb.s0 == 0);     break;  //JNSB0
+  case 0x0a6: r = (regs.flagb.s0 == 1);     break;  //JSB0
+  case 0x0a8: r = (regs.flaga.s1 == 0);     break;  //JNSA1
+  case 0x0aa: r = (regs.flaga.s1 == 1);     break;  //JSA1
+  case 0x0ac: r = (regs.flagb.s1 == 0);     break;  //JNSB1
+  case 0x0ae: r = (regs.flagb.s1 == 1);     break;  //JSB1
+  case 0x0b0: r = (regs.dp & 0x0f) == 0x00; break;  //JDPL0
+  case 0x0b1: r = (regs.dp & 0x0f) != 0x00; break;  //JDPLN0
+  case 0x0b2: r = (regs.dp & 0x0f) == 0x0f; break;  //JDPLF
+  case 0x0b3: r = (regs.dp & 0x0f) != 0x0f; break;  //JDPLNF
+  case 0x0bc: r = (regs.sr.rqm == 0);       break;  //JNRQM
+  case 0x0be: r = (regs.sr.rqm == 1);       break;  //JRQM
+  case 0x100: r = true;                     break;  //JMP
+  case 0x140: r = true; stack_push();       break;  //CALL
+}
+if(r) regs.pc = na;*/
 }
 
 void uPDcore::exec_ld(uint24 opcode) {
@@ -217,8 +282,8 @@ void uPDcore::exec_ld(uint24 opcode) {
     case  5: regs.rp = id; break;
     case  6: regs.dr = id; regs.sr.rqm = 1; break;
     case  7: regs.sr = (regs.sr & 0x907c) | (id & ~0x907c); break;
-  //case  8: regs.sol = id; break;
-  //case  9: regs.som = id; break;
+    case  8: regs.so = id; break;  //LSB
+    case  9: regs.so = id; break;  //MSB
     case 10: regs.k = id; break;
     case 11: regs.k = id; regs.l = dataROM[regs.rp]; break;
     case 12: regs.l = id; regs.k = dataRAM[regs.dp | 0x40]; break;
@@ -229,26 +294,14 @@ void uPDcore::exec_ld(uint24 opcode) {
 }
 
 void uPDcore::stack_push() {
-  regs.stack[7] = regs.stack[6];
-  regs.stack[6] = regs.stack[5];
-  regs.stack[5] = regs.stack[4];
-  regs.stack[4] = regs.stack[3];
-  regs.stack[3] = regs.stack[2];
-  regs.stack[2] = regs.stack[1];
-  regs.stack[1] = regs.stack[0];
+  for(unsigned r = 63; r >= 1; r--) regs.stack[r] = regs.stack[r - 1];
   regs.stack[0] = regs.pc;
 }
 
 void uPDcore::stack_pull() {
   regs.pc = regs.stack[0];
-  regs.stack[0] = regs.stack[1];
-  regs.stack[1] = regs.stack[2];
-  regs.stack[2] = regs.stack[3];
-  regs.stack[3] = regs.stack[4];
-  regs.stack[4] = regs.stack[5];
-  regs.stack[5] = regs.stack[6];
-  regs.stack[6] = regs.stack[7];
-  regs.stack[7] = 0x0000;
+  for(unsigned r = 0; r <= 62; r++) regs.stack[r] = regs.stack[r + 1];
+  regs.stack[63] = 0x0000;
 }
 
 uPDcore::uPDcore(unsigned pcbits, unsigned rpbits, unsigned dpbits) {
diff --git a/bsnes/snes/chip/necdsp/core/core.hpp b/bsnes/snes/chip/necdsp/core/core.hpp
index 6c8a362d..51e5e068 100755
--- a/bsnes/snes/chip/necdsp/core/core.hpp
+++ b/bsnes/snes/chip/necdsp/core/core.hpp
@@ -18,7 +18,7 @@ public:
   void stack_push();
   void stack_pull();
 
-  string disassemble(uint11 ip);
+  string disassemble(uint14 ip);
 
   void serialize(serializer&);
   uPDcore(unsigned pcbits, unsigned rpbits, unsigned dpbits);
diff --git a/bsnes/snes/chip/necdsp/core/disassembler.cpp b/bsnes/snes/chip/necdsp/core/disassembler.cpp
index d16f5bd7..1aae7c4c 100755
--- a/bsnes/snes/chip/necdsp/core/disassembler.cpp
+++ b/bsnes/snes/chip/necdsp/core/disassembler.cpp
@@ -1,6 +1,6 @@
 #ifdef UPDCORE_CPP
 
-string uPDcore::disassemble(uint11 ip) {
+string uPDcore::disassemble(uint14 ip) {
   string output = { hex<3>(ip), "  " };
   uint24 opcode = programROM[ip];
   uint2 type = opcode >> 22;
@@ -48,7 +48,7 @@ string uPDcore::disassemble(uint11 ip) {
       case 1: output << "b"; break;
     }
 
-    if(dst) {
+    if(1||dst) {
       output << "\n     mov     ";
 
       switch(src) {
diff --git a/bsnes/snes/chip/necdsp/core/registers.hpp b/bsnes/snes/chip/necdsp/core/registers.hpp
index 698f356c..256d8443 100755
--- a/bsnes/snes/chip/necdsp/core/registers.hpp
+++ b/bsnes/snes/chip/necdsp/core/registers.hpp
@@ -41,26 +41,24 @@ struct Status {
   }
 };
 
-//11,11,10,8 and 14,14,11,11
-
 struct Regs {
-  Pointer pc;       //program counter
-  Pointer rp;       //ROM pointer
-  Pointer dp;       //data pointer
-  uint16 stack[8];  //LIFO
+  Pointer pc;        //program counter
+  Pointer rp;        //ROM pointer
+  Pointer dp;        //data pointer
+  uint16 stack[64];  //LIFO
   int16 k;
   int16 l;
   int16 m;
   int16 n;
-  int16 a;          //accumulator
-  int16 b;          //accumulator
+  int16 a;           //accumulator
+  int16 b;           //accumulator
   Flag flaga;
   Flag flagb;
-  uint16 tr;        //temporary register
-  uint16 trb;       //temporary register
-  Status sr;        //status register
-  uint16 dr;        //data register
-  bool siack;
-  bool soack;
+  uint16 tr;         //temporary register
+  uint16 trb;        //temporary register
+  Status sr;         //status register
+  uint16 dr;         //data register
+  uint16 si;
+  uint16 so;
   uint16 idb;
 } regs;
diff --git a/bsnes/snes/chip/necdsp/core/serialization.cpp b/bsnes/snes/chip/necdsp/core/serialization.cpp
index 8128b40a..63253b1e 100755
--- a/bsnes/snes/chip/necdsp/core/serialization.cpp
+++ b/bsnes/snes/chip/necdsp/core/serialization.cpp
@@ -51,8 +51,6 @@ void uPDcore::serialize(serializer &s) {
   s.integer(regs.sr.p0);
 
   s.integer(regs.dr);
-  s.integer(regs.siack);
-  s.integer(regs.soack);
   s.integer(regs.idb);
 }
 
diff --git a/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp b/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp
index 72ceb44b..5992695d 100755
--- a/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp
+++ b/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp
@@ -86,8 +86,6 @@ void uPD7725::reset() {
   regs.flagb = 0x00;
   regs.sr = 0x0000;
   regs.rp = 0x3ff;
-  regs.siack = 0;
-  regs.soack = 0;
 }
 
 void uPD7725::serialize(serializer &s) {
@@ -97,7 +95,6 @@ void uPD7725::serialize(serializer &s) {
 
 uPD7725::uPD7725() : uPDcore(11, 10, 8) {
   //NEC uPD7725:
-  //8.192 MIPS (8.192MHz / 1)
   //11-bit ProgramROM (2048 x 24-bit) w/4-level stack
   //10-bit DataROM    (1024 x 16-bit)
   // 8-bit DataRAM    ( 256 x 16-bit)
diff --git a/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp b/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp
index efaaee51..58ece136 100755
--- a/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp
+++ b/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp
@@ -14,36 +14,87 @@ void uPD96050::enter() {
     }
 
     uPDcore::exec();
-    step(2);
+    step(1);
     synchronize_cpu();
   }
 }
 
 uint8 uPD96050::read(unsigned addr) {
   cpu.synchronize_coprocessor();
-  regs.sr.rqm = 0;
+  addr &= 0x8ffff;
 
-  bool hi = addr & 1;
-  addr = (addr >> 1) & 2047;
-
-  if(hi == false) {
-    return dataRAM[addr] >> 0;
-  } else {
-    return dataRAM[addr] >> 8;
+  if(addr == 0x00000) {
+    if(regs.sr.drc == 0) {
+      //16-bit
+      if(regs.sr.drs == 0) {
+        regs.sr.drs = 1;
+        return regs.dr >> 0;
+      } else {
+        regs.sr.rqm = 0;
+        regs.sr.drs = 0;
+        return regs.dr >> 8;
+      }
+    } else {
+      //8-bit
+      regs.sr.rqm = 0;
+      return regs.dr >> 0;
+    }
   }
+
+  if(addr == 0x00001) {
+    return regs.sr >> 8;
+  }
+
+  if(addr & 0x80000) {
+    bool hi = addr & 1;
+    addr = (addr >> 1) & 2047;
+
+    if(hi == false) {
+      return dataRAM[addr] >> 0;
+    } else {
+      return dataRAM[addr] >> 8;
+    }
+  }
+
+  return 0x00;
 }
 
 void uPD96050::write(unsigned addr, uint8 data) {
   cpu.synchronize_coprocessor();
-  regs.sr.rqm = 0;
+  addr &= 0x8ffff;
 
-  bool hi = addr & 1;
-  addr = (addr >> 1) & 2047;
+  if(addr == 0x00000) {
+  //print("DR = ", hex<2>(data), " @ ", hex<6>(cpu.regs.pc), "\n");
+    if(regs.sr.drc == 0) {
+      //16-bit
+      if(regs.sr.drs == 0) {
+        regs.sr.drs = 1;
+        regs.dr = (regs.dr & 0xff00) | (data << 0);
+      } else {
+        regs.sr.rqm = 0;
+        regs.sr.drs = 0;
+        regs.dr = (data << 8) | (regs.dr & 0x00ff);
+      }
+    } else {
+      //8-bit
+      regs.sr.rqm = 0;
+      regs.dr = (regs.dr & 0xff00) | (data << 0);
+    }
+  }
 
-  if(hi == false) {
-    dataRAM[addr] = (dataRAM[addr] & 0xff00) | (data << 0);
-  } else {
-    dataRAM[addr] = (dataRAM[addr] & 0x00ff) | (data << 8);
+  if(addr == 0x00001) {
+    return;
+  }
+
+  if(addr & 0x80000) {
+    bool hi = addr & 1;
+    addr = (addr >> 1) & 2047;
+
+    if(hi == false) {
+      dataRAM[addr] = (dataRAM[addr] & 0xff00) | (data << 0);
+    } else {
+      dataRAM[addr] = (dataRAM[addr] & 0x00ff) | (data << 8);
+    }
   }
 }
 
@@ -59,7 +110,7 @@ void uPD96050::power() {
 }
 
 void uPD96050::reset() {
-  create(uPD96050::Enter, 20 * 1000 * 1000);  //20MHz
+  create(uPD96050::Enter, 15 * 1000 * 1000);
 
   regs.pc = 0x0000;
   regs.stack[0] = 0x0000;
@@ -74,8 +125,6 @@ void uPD96050::reset() {
   regs.flagb = 0x00;
   regs.sr = 0x0000;
   regs.rp = 0x03ff;
-  regs.siack = 0;
-  regs.soack = 0;
 }
 
 void uPD96050::serialize(serializer &s) {
@@ -85,7 +134,6 @@ void uPD96050::serialize(serializer &s) {
 
 uPD96050::uPD96050() : uPDcore(14, 11, 11) {
   //NEC uPD96050:
-  //10MIPS (20MHz / 2)
   //14-bit ProgramROM (16384 x 24-bit) w/8-level stack
   //11-bit DataROM    ( 2048 x 16-bit)
   //11-bit DataRAM    ( 2048 x 16-bit) w/battery backup
diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp
index cefda2d6..3224925f 100755
--- a/bsnes/snes/snes.hpp
+++ b/bsnes/snes/snes.hpp
@@ -1,12 +1,12 @@
 namespace SNES {
   namespace Info {
     static const char Name[] = "bsnes";
-    static const char Version[] = "073.05";
+    static const char Version[] = "073.06";
     static const unsigned SerializerVersion = 16;
   }
 }
 
-//#define DEBUGGER
+#define DEBUGGER
 #define CHEAT_SYSTEM
 
 #include <libco/libco.h>